168

Consider the following piece of Markdown code:

This is some regular text.

    >>> def factorial(n):
    ...     return 1 if n < 2 else n * factorial(n - 1)
    ... 

* This is a list item.

    >>> def factorial(n):
    ...     return 1 if n < 2 else n * factorial(n - 1)
    ... 

Notice that the second code block is preceded by a list item.

Why is the factorial code not properly formatted under these circumstances? To demonstrate the problem, I'll insert the Markdown code show above:


This is some regular text.

>>> def factorial(n):
...     return 1 if n < 2 else n * factorial(n - 1)
... 
  • This is a list item

    def factorial(n): ... return 1 if n < 2 else n * factorial(n - 1) ...


This applies to numbered as well as unnumbered lists.

6
  • 1
    I think you need to revisit this question and change the accepted answer. Commented Oct 3, 2012 at 15:12
  • @Mark: You're right. Balpha's answer is more informative and provides a more elegant work-around. So, changed it :)
    – Stephan202
    Commented Oct 3, 2012 at 16:27
  • Otiel's answer reflects the current documentation, so it should probably be the accepted answer, regardless of the current votes.
    – Mogsdad
    Commented May 13, 2013 at 1:53
  • 1
    @DonaldDuck: The accepted answer to this question explains why the bug is unfixable, a valuable and very distinct answer that cannot possibly be posted in any meaningful way to the other question. They are therefore not duplicates. Commented Jul 15, 2018 at 22:10
  • @DonaldDuck this question is older than the one being suggested as a dupe, so even if they are dupes of one-another, the other one should be duped for this one
    – James
    Commented Jul 15, 2018 at 22:58
  • @James The age doesn't matter. Besides, in this specific case, the other question is tagged [faq], and it doesn't really make sense to close the FAQ. Commented Jul 15, 2018 at 23:26

9 Answers 9

152

Unfortunately, this is an ambiguity in the Markdown specification. This markdown source:

42. list item

    more text

can mean two things. One of them is the one you're expecting: more text is following a blank line and indented by four spaces, making it a top-level (i.e. not part of the list) code block.

The second possible meaning is this:

List items may consist of multiple paragraphs. Each subsequent paragraph in a list item must be indented by either 4 spaces or one tab:

1.  This is a list item with two paragraphs. Lorem ipsum dolor
    sit amet, consectetuer adipiscing elit. Aliquam hendrerit
    mi posuere lectus.

    Vestibulum enim wisi, viverra nec, fringilla in, laoreet
    vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
    sit amet velit.

– in other words, more text is a regular second paragraph within the list item.

It's indistinguishable which of the two meanings is the intended one; both are correct. And what the Markdown converter (actually, all of them) chooses is the second meaning.

The only way to fix this would be adding an additional syntax to Markdown, enabling you to distinguish the two. I can, however, not think of any intutitive and unobtrusive thing to do, so using one of the workarounds here is as good as anything. My preferred workaround, by the way, would be an HTML comment like this:

* list item

<!-- -->

    code

turns into this:

  • list item

code

– but it doesn't really matter which one you use. Bottom line is: As sad as it is, this is unfixable.

12
  • 6
    Great explanation! Commented Jul 24, 2011 at 9:19
  • 2
    I've been throwing in &nbsp; inbetween when this became an issue. I'll be doing this from now on. Commented Jul 24, 2011 at 10:26
  • 2
    I guess Markdown converters choosing the second meaning is the best of the two, as then one could still use the above-mentioned workarounds to force it to not do that. If a converter would NOT add it to the list item itself, there would be no way to force it to do so? (Even two spaces at the end of the first line would not help, as then the next lines would not be formatted as code.)
    – Arjan
    Commented Jul 24, 2011 at 14:08
  • 7
    The <!-- --> fix was very helpful, thanks. :)
    – Shmiddty
    Commented Jan 18, 2013 at 22:20
  • This don't work when I put two ordered list items and code for them, even if you put number 1. to first and 2. to second, you got two items 1.
    – jcubic
    Commented Dec 4, 2013 at 7:18
  • 3
    @jcubic In that case (which is the usual case), you want the code to appear inside the list, not after it. That's absolutely possible by indenting the code eight spaces (four for the list and four to make it code). This question is only about the rare case that you want code to appear immediately below the list, but outside it.
    – balpha StaffMod
    Commented Dec 4, 2013 at 7:22
  • 1
    Maybe subjective, but: placing code snippet right after list seems as a sub-optimal writing practice (well, a "subset" of bad practice of using too much naked bullet point lists); It will almost always break the narrative of the text. Everytime I ever hit this, I eventually realized that best thing is adding "For example" or something anyway. So in fact, I never cared about the problem: it only reminded me of bad writing. Commented Mar 30, 2015 at 16:25
  • IOW, I have always accepted this as a hidden message that bullet point list and code snippet do not belong next to each other (they may belong inside each other though). Commented Mar 30, 2015 at 16:28
  • @AloisMahdal I can write code which satifies two conditions; (1) one and (2) two. echo "moo" ... I'm sure it can be paraphrased to avoid this pattern, but can you explain how exactly this is bad writing? (I'll readily admit that this particular example is not great writing.)
    – tripleee
    Commented Aug 4, 2016 at 12:47
  • @tripleee Sorry but I don't understand the example (is it even possible to show in a comment?) Commented Aug 5, 2016 at 1:03
  • It's a bit awkward in a comment, yes. But understanding the example is probably not a prerequisite for explaining why you think this construction is problematic.
    – tripleee
    Commented Aug 5, 2016 at 5:24
  • Interestingly Sublime Text 3 renders the code block. It’s the only editor I’ve found that does that. Commented Mar 15, 2018 at 13:11
78

I've noticed that I usually have to add 8 spaces before any code instead of 4 spaces when it's code that appears as part of a list item.

<- 4 spaces
  • A list item (one blank line after this):

    <- 8 spaces
    
12
  • 9
    Aha. So then Markdown treats the code as part of the list item. A slight semantic difference. Also, I suppose then that the functionality of ctrl-k should be upgraded such that it cycles between 0, 4 and 8 spaces (instead of only 0 and 4). Maybe also 12 spaces, for nested lists. Perhaps that could be a separate feature request?
    – Stephan202
    Commented Jul 7, 2009 at 19:08
  • 1
    This seems to be true even if you don't intend for the code to be part of a bullet. I was trying to post a question with 2 bulleted questions followed by the code.
    – IAbstract
    Commented Feb 14, 2010 at 5:00
  • 2
    It's not just 8 spaces, it's 4 spaces plus 4 per indentation level. (At least, that's how it is currently.)
    – badp
    Commented Jul 25, 2010 at 18:56
  • @Stephan202 - did you ever put in a separate feature request for this?
    – JoshDM
    Commented Aug 29, 2013 at 15:47
  • @JoshDM: Nope, I did not. Feel free to do so!
    – Stephan202
    Commented Aug 30, 2013 at 9:00
  • This workaround is just perfect.
    – Tomas
    Commented Mar 18, 2014 at 20:00
  • It worked perfectly. Commented Jul 21, 2014 at 9:33
  • 1
    @IAbstract Seems I beat you to that idea, even though 4 years later. :) meta.stackoverflow.com/questions/278228/… Fought with the same problem, but with balpha's fantastic workaround things worked out right. However, I left the "wrong" code in so people can see the difference. Commented Dec 2, 2014 at 1:30
  • @syntaxerror: better late than never.
    – IAbstract
    Commented Dec 2, 2014 at 13:27
  • @IAbstract Amen to that! :) But there is always one thing I will never understand: why do some people always have the urge to downvote a duplicate answer in meta? See, there are zillions of metas. And once someone posts the same question in SO meta, I will not necessarily see it because I'm much more active in *.SE.com metas. Commented Dec 2, 2014 at 13:34
  • @syntaxerror: I don't worry about them on meta sites (btw, I didn't down-vote it :) ).
    – IAbstract
    Commented Dec 2, 2014 at 13:37
  • Neither did I think you did! Commented Dec 2, 2014 at 13:53
14

The workaround which is to add 8 spaces instead of simply 4 is actually written in the markdown editing help:

  1. (...)
  2. (...)
  3. (...)
  4. Preformatted text in a list item:

    Skip a line and indent eight spaces.
    That's four spaces for the list
    and four to trigger the code block.
    
1
  • 5
    Adding 8 spaces turns it into a code block within the list. The desire is usually to end the list instead. Commented Oct 3, 2012 at 15:09
9

It's a crappy work-around, but you can do insert a backticked space to trick it. Put a space into those backticks and it should work:

  • This is a list item.

``

>>> def factorial(n):
...     return 1 if n < 2 else n * factorial(n - 1)
...

See?

  • This is a list item.

>>> def factorial(n):
...     return 1 if n < 2 else n * factorial(n - 1)
...
6
  • Aha, nice hack :)
    – Stephan202
    Commented Jul 7, 2009 at 19:09
  • 6
    This is only appropriate if the code block doesn't have anything to do with the list item. Commented Jul 21, 2009 at 16:21
  • +1 I was getting ready to ask a question about formatting R code when I saw this. The 8 spaces hack did it. Commented Nov 6, 2009 at 5:21
  • 2
    @Brad Gilbert - this is a common scenario if you want to have a list of points followed immediately by a code sample that is related to the answer in general and not to the final list item. (i.e. probably most of the time.) Commented Jun 29, 2010 at 15:09
  • 2
    I use a horizontal rule, which has the same effect but actually blends in a little better. Commented Jun 29, 2010 at 15:10
  • balpha's answer is better because it doesn't leave extra spacing or other undesired characters. Commented Oct 3, 2012 at 15:11
8

I'm glad there are workarounds for this, but this is really a bug that should be fixed. I just wasted altogether too much time trying to figure out why I couldn't put a code block after...

  1. Bullet 1.
  2. Bullet 2.
  3. Paste in the following code:

    this.IsCode = true;

So here's my attempt with 8 spaces.

  1. Bullet 1.
  2. Bullet 2.
  3. Paste in the following code:

    this.IsCode = true;
    this.IsAlsoCode = true;
    
  4. Okay, so every line of code needs to be proceded by 8 spaces (instead of the usual 4).

1
  • 1
    @user155609 Then please explain how to disambiguate a multi-paragraph bullet item from a bullet item followed by a code block, using the existing syntax?
    – tripleee
    Commented Aug 4, 2016 at 12:51
8

I just found a solution for this.

If you put a </ul> after the listed item. The issue will be fixed.

Issue fix

3
  • 5
    You can also put </foobar> there, it will have the same result. Or use a comment, as I said in my answer. Your version has the disadvantage that it can a) cause subtle errors, and b) it's totally non-obvious to someone editing your question.
    – balpha StaffMod
    Commented Jun 21, 2013 at 12:55
  • @balpha: yeah that is correct. Thanks for the comment.
    – Midhun MP
    Commented Jun 21, 2013 at 13:09
  • 1
    </list-codeblock-separator> makes it obvious
    – user134589
    Commented Nov 27, 2017 at 5:25
5

This just got bumped. I'm looking through the answers. All the workarounds are hacky. So you should probably go with the following if you want the most semantically benign workaround:

- A list item.

<!-- language: lang-c++ -->

    int k = 1;
    char *something = "example";

That is, use an explicit syntax highlighting override before the code block (use the appropriate language from that post, or use default). This would be acceptable anyways, so it isn't some strange hacky HTML tag or empty comment or whatever. Since it's the normal usage of this feature, it's not going to risk breaking anything or looking weird in the future, either.

The above produces the following:


  • A list item.
int k = 1;
char *something = "example";
1
  • This looks much more logical than the empty comment in the currently accepted answer.
    – fbmd
    Commented Aug 23, 2023 at 14:54
0
  • You can use a <pre><code> block around the code instead of indenting by 4 spaces or a tab. Certain characters may have to be escaped, such as <.
print "<code>"

The above line in markdown is <pre><code>print "&lt;code>"</code></pre>

0

I placed a <br\> after ordered List and code started working with same 4 space rule.

enter image description here

1
  • Do you mean <br />
    – bobobobo
    Commented Nov 11, 2021 at 17:45

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