Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTML blocks within nested ordered list items do not get rendered within the <ol> element #305

Open
lacymorrow opened this issue Jun 4, 2018 · 5 comments

Comments

@lacymorrow
Copy link

lacymorrow commented Jun 4, 2018

In the following:

1. List 1 item 1
    1. List 2 item 1
    2. <div class="foo">
    List 2 item 2
    </div>
    3. List 2 item 3

The div breaks the <ol> and is rendered as a new line.

I am following this rule listed here

When the block element is found inside a list, all its content should be indented with the same amount of space as the list item is indented. (More indentation won’t do any harm as long as the first opening tag is not indented too much and then become a code block — see first rule.)

@michelf
Copy link
Owner

michelf commented Jun 5, 2018

Thank you for reporting this.

For completeness, here's what I get with Markdown Extra:

<ol>
<li>List 1 item 1

<ol>
<li>List 2 item 1</li>
<li></li>
</ol></li>
</ol>

<div class="foo">
    List 2 item 2
    </div>

<pre><code>3. List 2 item 3
</code></pre>

Whereas plain Markdown (not Extra) gives a better result:

<ol>
<li>List 1 item 1

<ol>
<li>List 2 item 1</li>
<li><div class="foo">
List 2 item 2
</div></li>
<li>List 2 item 3</li>
</ol></li>
</ol>

And here's how every other implementation are parsing this (most outputs are the same as plain PHP Markdown).

There is definitely something to fix here. I wonder how Markdown Extra's complex HTML block parser might make that a bit difficult to fix without tighter integration with parsing of the other block-level constructs. Some refactoring might be needed.

@lacymorrow
Copy link
Author

FWIW, the parser does not close the <ol> tag if I use a <span> rather than a <div>, although it isn't valid HTML. I'm assuming it has something to do with how the parser treats block vs inline elements.

@ricklecoat
Copy link

ricklecoat commented Feb 18, 2019

I've been wrestling with this for a while, trying to figure out whether there's a bug or whether I was just misunderstanding how to structure the syntax. I was trying to insert a div into a simple (non-nested) list, and the line:

When the block element is found inside a list, all its content should be indented with the same amount of space as the list item is indented.

confused me, because my list in markdown isn't indented. Taking the guide as-written, then, this implies that block level items can ONLY be inserted into a nested list — ie. a list that is the child of another list. Is that correct? If not, to what does the 'indenting' apply, given that a simple list contains no indenting?

In any case, I can't get it to work with a nested list either, and this issue suggests that it's not me being inept (well, not just that, anyway). Here is some code that doesn't place a div inside a list item, although the rules seems to suggest that it should work:

- list 1 item1
- list 1 item 2
    - list 2 item A
    - list 2 item B
    <div>THIS IS THE DIV</div>
    -list 2 item C
- list 1 item3

The result is this:

<ul>
    <li>list 1 item1</li>
    <li>list 1 item 2
        <ul>
            <li>list 2 item A</li>
            <li>list 2 item B</li>
        </ul>
    </li>
</ul>
<div>THIS IS THE DIV</div>
<pre><code>-list 2 item C
</code></pre>
<p>- list 1 item3</p>

For my own education, could somebody please tell me what the correct syntax for placing a div inside a list item should be, at least in theory, for both a nested and un-nested list? (Even if there is a bug that's currently stopping it from working, it'd be really helpful to know what the syntax should theoretically be).

[EDIT: I now realise that I can insert a div into a list item, but only if it is below at least one indented paragraph, because the indentation of that paragraph gives something to indent the div against. Also, unless I want at least two paragraphs before the div, I have to use the following syntax:

- 

    Paragraph inside list item 1
    <div>THIS IS THE DIV</div>
- list item 2

…which gives the following output (I've rejigged the lining-off to make it clearer what's nesting in what):

<ul>
    <li>
        <p>Paragraph inside list item 1</p>
        <div>THIS IS THE DIV</div>
    </li>
    <li>list item 2</li>
</ul>

That syntax (with just the list marker in the first line and then the empty second line) is a terribly kludgy and not very intuitive. But the only way around that it to have two paragraphs (minimum) before the nested div. Which may not be what's desired.

@michelf
Copy link
Owner

michelf commented Feb 18, 2019

The rule is that for block-level content to be present, you need to have a blank line either within a list item or between list items. This works fine:

-   Paragraph inside list item 1

    <div>THIS IS THE DIV</div>

-   list item 2

@ricklecoat
Copy link

Thanks enormously for the pointer Michel. Much is now significantly clearer. I think one of the things that I found confusing is that the Markdown Extra docs page first quotes John Gruber's Markdown rules:

Block-level HTML elements […] must be separated from surrounding content by blank lines…

Then goes on to say:

These restrictions have been lifted in Markdown Extra […] When the block element is found inside a list, all its content should be indented with the same amount of space as the list item is indented.

I think that threw me a bit because it suggested that the rules about separator lines no longer applied.

Some additional confusion, however, came from the fact that I think your rules for placing block elements in lists assume that list content will always always indented in multiples of 4 spaces (or a tab) (including the marker character(s)), regardless of whether or not it has paragraphs. But the general rules for lists don't necessarily require that.

What I discovered through trial and error is that the block element not only needs to have spaces before and after, like a paragraph, but it MUST be indented by a multiple of 4 spaces (or tabs). That rule in the Markdown Extra docs about

When the block element is found inside a list, all its content should be indented with the same amount of space as the list item is indented

…is only true if the list item follows that 'total-indent-including-the list-marker = 4' rule. Your example code above works perfectly because it follows that assumption, which means that your div is aligned with a 4-space indent.

But John Gruber's original rules for lists simply say “List markers must be followed by one or more spaces or a tab.” (Emphasis mine). It's only subsequent paragraphs that MUST be indented by 4 spaces or a tab. If one follows those rules and only uses a single space, then the "indented with the same amount of space as the list item is indented" rule fails.
Your example above works. But this one fails, for the reasons stated:

- Paragraph inside list item 1

  <div>THIS IS THE DIV</div>

- list item 2

So maybe the documentation could be updated to clarify that point (ie. that it's not about matching the indent, it's about making sure the indent is the same indent required for a (subsequent) paragraph)?

Sorry, that got waaaay longer than I intended when I started ;-)

Oh, one last thing: I realised that as long as the indent is correct, there's no need for a leading paragraph at all:

-   <div>THIS IS THE DIV</div>

Gives:

<ul>
<li><div>THIS IS THE DIV</div></li>
</ul>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants