Meta Stack Exchange is where users like you discuss bugs, features, and support issues that affect the software powering all 155 Stack Exchange communities.

What is meta?
Here's how it works:
  1. Any Stack Exchange user can ask a question
  2. The community provides support, votes on ideas, and reports bugs
  3. Your voice helps shape the way Stack Exchange operates

How is the exact syntax of the <pre> tag? Can I put the closing </pre> tag on a new line? If I do, then the preview is completely messed up, but the final result is as expected. (I know that I can mark a code block by indenting it 4 spaces, but that method sometimes has drawbacks.)

To see the problem, hit the "edit" link and test the following: The messed-up preview can be fixed by any of the following three edits:

  • removing the </code> tag,
  • putting the </pre> tag on the same line as <pre>some more code,
  • indenting the line <pre><code>some code by one to three spaces.

Here's the test HTML code:

some code

Line followed by an empty line

Section title

Another line

some more code
share|improve this question
    
It seems the following bug is back, or maybe only in the preview? Newline before closing </pre> might break formatting in other parts of same post – Arjan Mar 22 '11 at 18:48
    
@Arjan: Looks very much like that indeed, thanks. – Hendrik Vogt Mar 22 '11 at 18:50
    
    
@Arjan: So what do you recommend? Not putting </pre> on a new line? (I don't like that so much, but if it's the only way out ...) – Hendrik Vogt Mar 22 '11 at 18:56
    
I don't know. You already figured out the workarounds; I guess these will continue to render fine if this is ever fixed? – Arjan Mar 22 '11 at 19:02
up vote 4 down vote accepted

The problem isn't so much that you put the closing </pre> tag on a new line, but rather that you have two sets of <pre> blocks with stuff in them, and you didn't write them in a way that the parser was hoping you would.

Essentially, what happens is that there's a set of regular expressions that attempt to temporarily remove raw HTML from the source prior to the Markdown syntax being parsed, and the first of these checks for something like the following:

<div>
    <!-- Possibly some content -->
</div>

Where it picks up the first tag (because it isn't indented), then attempts to find the closing tag by looking first for any number of lines, followed by the closing tag preceded only by a newline (i.e. the tag is not indented). The rationale for this in the original WMD source is that it avoids catching the closing tag of nested blocks, by imposing that they are indented:

<div>
    <div>
    inner block
    </div> <!-- This won't be considered the closing tag of the first div -->
</div>

Naturally, this isn't always how things work, so there's a more liberal <tag>...</tag> check after that. Unfortunately in this case, the damage is already done, because the parser has decided that the opening tag of your first block matches the closing tag of your second block, and has removed everything between them from being parsed as Markdown (since content inside of raw HTML is never parsed).

Of course, when the generated HTML is inserted into the preview, your <pre> blocks display correctly because the browser recognizes that they are how they're supposed to be. The pieces in between are still as you wrote them though, having not been parsed.

I'm not sure if there's any good way to go about fixing this, but I'll take a look. I suspect that the server-side parser is using a slightly more capable expression to do the nested block matching that isn't supported by the JavaScript regular expression engine, which would explain why it gets on a bit better here.

In your particular case, the most parser-friendly source would likely be the following:

<pre>
<code>some code</code>
</pre>

Line followed by an empty line

### Section title ###

Another line

<pre>
some more code
</pre>

Update:

I was able to come up with a modified expression that, while still not quite as good as the server-side parser, should handle cases like this more gracefully by scoping the non-indented closing tag to the closest non-indented opening tag. This would be a replacement for the first regex in _HashHTMLBlocks():

/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\b(?:[^\n\r]*\n(?!<\2>))*?<\/\2>[ \t]*(?=\n+))/gm
share|improve this answer
    
Wow, thanks a lot for this detailed explanation; I think now I finally understand what's happening. The only thing I don't like about your parser-friendly version is that the <code> and </code> tags both have to be on the same lines as the code. – Hendrik Vogt Jul 23 '11 at 22:00
    
Yeah, that is a bit annoying unfortunately. I feel like the parser should be able to do a little better with this case, but I'm worried that a more correct approach might end up being a bit expensive. I'm still playing around with it though. – Tim Stone Jul 25 '11 at 5:50
    
Thanks a lot for looking into it. If improving the parser makes the preview slower, then maybe it's not worth it as it's probably an edge case. I'm quite happy already since now you told me "the precise syntax of the <pre> tag" - put it on a line of its own, without indentation. – Hendrik Vogt Jul 25 '11 at 16:03
    
Thanks for the update! I can't say I fully understand it, but that's not important. What I'm wondering about: in my posts, I can't use most of those HTML blocks anyway, can I? – Hendrik Vogt Jul 26 '11 at 9:13
    
Yep, that's right. What happens is that those blocks are permitted by the Markdown parser, but because Stack Exchange has stricter criteria for post entry there's another external step that removes all of the stuff that isn't allowed here. – Tim Stone Jul 26 '11 at 15:22
    
Hmm, I guess I'm being completely ignorant here, but why don't you removed all that stuff first? – Hendrik Vogt Jul 26 '11 at 16:11
    
There are some sanitation steps involving links and images (in particular, their URLs) that can only be easily performed after the Markdown parser has run. I imagine it's just easier to run all of the filtering at once, when you know all you have left in the post is the converted HTML. – Tim Stone Jul 26 '11 at 16:39
    
Ah, I think I understand - thanks! – Hendrik Vogt Jul 27 '11 at 8:20

You could just indent the code you want for format by four spaces instead. You can even select it and click the {} button or use the Ctrl-K shortcut to have it indented automatically.

This also has the advantage to escape special characters in the code block, so that for example special characters like < and html tags contained in the code are displayed correctly.

share|improve this answer
    
Thanks, but well, I know that. I struggled with the strange preview when writing that post. – Hendrik Vogt Mar 22 '11 at 18:38
1  
It can be a disadvantage of the 4 space indentation method that special characters are escaped: I can't use <b>...</b> anymore. See also this nice answer. – Hendrik Vogt Mar 22 '11 at 18:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .