2
\$\begingroup\$

Official documentation here

I'm not sure how to make nested lists work. It looks like the provided syntax shouldn't work, because it conflicts with code-spans (also signaled by 4 space indenting). This indeed appears to be what happens, unless there is no intervening text:

  • this is a list item

    • this is a nested list item, processed correctly
  • this is a list item

Here is some text

+ I want this to line up with the other nested list item, but it doesn't 'cause it's a code span.  

+ It's not even a list anymore so + this doesn't work.

What am I doing wrong?

\$\endgroup\$
  • 3
    \$\begingroup\$ Note that Daring Fireball's documentation is for the vanilla/reference-standard implementation of Markdown, which is quite ancient these days. SE has its own flavour of markdown (sorta related to Github-flavoured markdown) and its own official documentation. StackExchange Markdown's early evolution (it's changed a bit since) is discussed in the 2009 blog post Markdown, One Year Later. In fact, the lack of standard led to SE co-founding a group to standardise it. \$\endgroup\$ – SevenSidedDie Dec 9 '14 at 0:59
3
\$\begingroup\$

What's happening is that when you include an empty line and don’t indent the next one, Markdown treats that as starting a new paragraph (specifically, whatever block tag you are currently in is closed, and then a <p> tag is inserted). Thus, in your case, it ends the list (which is a <ul>; putting a blank line triggers </ul> followed by <p>).

As pointed out in doppelgreener’s answer, indentation saves you. By indenting lines that are supposed to be part of the same bullet-point so the text lines up, it will remain part of the same bullet point. This works even with things like block quotes indicated with >, but it doesn’t work with code boxes because, as you notice, those are normally indicated by indentation – in a list, that behavior is overridden and so codeboxes won’t happen. To force a codebox, you’ll have to use the HTML tag <pre>.

Example:

* this is a list item

    * this is a nested list item, processed correctly

* this is a list item

  Here is some text, now part of the previous bullet point

    + I want this to line up with the other nested list item, and it does.

      > A block quote, for example

  <pre>I *want* this one to be a codebox</pre>

* This is still part of the list

    This won’t be a code box even though the line starts with 4 spaces

<pre>So I had to not indent to end the list and use &lt;pre&gt; to get the code box.</pre>

Which produces:

  • this is a list item

    • this is a nested list item, processed correctly
  • this is a list item

    Here is some text, now part of the previous bullet point

    • I want this to line up with the other nested list item, and it does.

      A block quote, for example

    I *want* this one to be a codebox
  • This is still part of the list

    This won’t be a codebox even though the line starts with 4 spaces

So I had to not indent to end the list and use <pre> to get the code box.
\$\endgroup\$
  • \$\begingroup\$ Oh, whoops. I misread your code example - the p/pre elements are inside a list item of their own. (I somehow misread the <li> just prior to them as a </li>, meaning the p/pre elements would be direct descendents of the <ul>, which is what I was saying was not good.) \$\endgroup\$ – doppelgreener Dec 9 '14 at 0:06
  • \$\begingroup\$ @doppelgreener Indeed. Per HTML5, li is one of the tags where closing is optional -- putting another <li> or ending the list with </ul> implicitly closes the li. And the result is, in fact, exactly what your blank line + indent is doing, internally (I didn't actually know Markdown supported that, though, that's nifty). \$\endgroup\$ – KRyan Dec 9 '14 at 0:07
  • \$\begingroup\$ @thedarkwanderer Turns out you (mostly) don’t need HTML for this. Updated, with thanks to doppelgreener. \$\endgroup\$ – KRyan Dec 9 '14 at 14:06
  • 1
    \$\begingroup\$ You don't even need <pre> for code blocks inside lists, as long as you indent them by an extra four spaces for each nesting level. (It looks more consistent if you indent all your nested lists and multi-paragraph list items by four spaces.) For a code block after (not inside) a list, though, you do seem to need either <pre> or something else to break out of "list mode" (an HTML comment will do). \$\endgroup\$ – Ilmari Karonen Dec 10 '14 at 23:39
4
\$\begingroup\$

What you're doing wrong is trying to start a new list already nested. That's not an option, there's no other list for them to be nested inside yet!

You're right that the list indentation syntax conflicts with code indentation, but that's sorted out by the list indentation syntax taking precedence.

  • You can start a list out at the first list level.
  • It can even have spaces before it, which would usually make it nested if there were less-indented list items above it.

    • You can make a list item a second-level list with more indentation.

      Or have a new line belonging to the previous list item.

But you can't then break the list

  • and start a new list item at the nesting level as before.

Code for the above (all whitespace in this code block is 100% deliberate):

Take note that the first list level starts with a space before it.

 * You can start a list out at the first list level.
 * It can even have spaces before it, which would usually make it nested if there were less-indented list items above it.
   * You can make a list item a second-level list with more indentation.

     Or have a new line belonging to the previous list item.

But you can't then break the list

   * and start a new list item at the nesting level as before.
\$\endgroup\$
4
\$\begingroup\$

Actually, you can even include code blocks inside lists without <pre>, as long as you indent them by an extra four spaces (or one tab) for each level of nesting.

It looks best if you also consistently indent your nested lists by four spaces; while the Markdown parser is generally forgiving and allows you to use any number of spaces to indent lists, code blocks are a special case and require more rigor.

Example:

  * This is a list item.

    This is another paragraph inside the same list item.

        This is a code block inside the list item.

      * This is a nested list item.

            This is a code block inside the nested list item.

  * This is another list item.

Produces:

  • This is a list item.

    This is another paragraph inside the same list item.

    This is a code block inside the list item.
    
    • This is a nested list item.

      This is a code block inside the nested list item.
      
  • This is another list item.


A problem does occur if you want a code block to immediately follow a list item, but not be nested inside it. One solution is to reset the nesting level e.g. by placing a dummy HTML comment (<!-- comment -->) before the code block. (On sites that have syntax highlighting enabled, like SO, you can also use the comment to specify the correct language for the highlighter.)

For example:

  * This is a list item.

    This is some normal text inside the list item.

<!-- this is an invisible comment -->

    This is a code block outside the list.

Produces:

  • This is a list item.

    This is some normal text inside the list item.

This is a code block outside the list.

Of course, all this also works with numbered lists (1., 2., etc.) and block quotes (>) just like it works with bulleted lists (* / + / -).


One thing you cannot do, however, is briefly "pop out" of a list back to a lower indentation level, and then later return to the higher indentation without a new bullet point / item number. That is to say, this will not work, and cannot be made to work:

  * This is a list item.

This is some normal, non-indented text.

    This is supposed to be a continuation of the previous list item
    (but will actually be parsed as a code block).

Alas, there's really nothing you can do about that, except to rethink the structure of your post. Markdown simply does not support this.

(In fact, it's kind of tricky to achieve this even in raw HTML, although there are a couple of more or less klugy solutions, like setting a negative CSS margin on the "outdented" block, or making the continuation a separate list item with an invisible bullet. None of those work on SE, though.)

\$\endgroup\$
3
\$\begingroup\$

(For optimum effect, your mental voice for this answer should read in William Shatner's voice.)

  • Kind of

    • Like this.
      • The important bit
        • Is 4 spaces per indent (maybe 3, but 4=tab, so is good).
      • If you break out of a UL,
        • You have to start over.
  • testing

    • the
    • one space indent.
    • the one-space indent only goes out by one, not unlimited nesting.
      • the t... okay, I've got no model for how this works.
      • what?
\$\endgroup\$
  • \$\begingroup\$ Even just one space of indent before the bullet character works, which is good to know if you're writing it by hand without a tab-to-spaces replacer running. For hand-written sources' readability though, two-space indents is a nice middle ground. \$\endgroup\$ – SevenSidedDie Dec 9 '14 at 0:38
  • \$\begingroup\$ I've actually had trouble with two space indents here. \$\endgroup\$ – Brian Ballsun-Stanton Dec 9 '14 at 0:42
  • \$\begingroup\$ @SevenSidedDie take a look at the source above. \$\endgroup\$ – Brian Ballsun-Stanton Dec 9 '14 at 0:43
  • \$\begingroup\$ Huh! I was just going to say that two-space indents also work great (they do, with no weirdness), then noticed one-space indents worked as well and modified my comment. But clearly my brief test totally failed to go far enough. I have no idea what's going on with the parser there... \$\endgroup\$ – SevenSidedDie Dec 9 '14 at 0:46
  • \$\begingroup\$ On further testing, even 2-space indents don't work at those nesting levels, unless the top-level item has a 1-space indent. And then breaks at nesting=4 again. The parser must be looking for a minimum indent for each nesting level to count it as a new level. \$\endgroup\$ – SevenSidedDie Dec 9 '14 at 0:49
  • 1
    \$\begingroup\$ List levels get quirky. You can start first level anywhere below 4 spaces (because otherwise it will be a code block), second level just needs any different level of indentation (including less indentation), third level and higher only works after you indent by at least four spaces. (But then if you build a staircase of 10 list items, and indent a lower level by 4 spaces... things get really weird. I try to just avoid the edge cases.) \$\endgroup\$ – doppelgreener Dec 9 '14 at 0:58
  • \$\begingroup\$ I found a discussion of exactly this weirdness. Basically, original Markdown failed to implement nesting indents correctly, and later implementations inherited the problem of whether to write to the spec (four space indents) or write to be compatible with the implementation & existing MD documents (various indents allowed depending on nesting level). \$\endgroup\$ – SevenSidedDie Dec 11 '14 at 20:11

You must log in to answer this question.

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