[kramdown-users] RFC: Lazy syntax / blank line usage

Shawn Van Ittersum svicalifornia at gmail.com
Sun Sep 5 05:07:00 EDT 2010


Hi Thomas,

Yes, I thought about this too and came to the conclusion that the clearest way to separate blocks is with blank lines, so my preference is for option two.  An exception can be safely made for list items and nested lists; see below.

# List Items and Nested Lists

I've shown before how wrapping followed by more blockquoting can result in line fragments starting with '>'.  So if a wrapped line fragment starts with '>' followed by some content text, it should be interpreted as a continuation of the previous line's block.

However, email clients do not introduce new list item markers when wrapping or quoting text.  Also, it is very rare for list item and blockquote markers ('1.', '*', '>', etc.) to appear in the middle of a line.

Therefore, it would be very strange for line wrapping or other automatic email handling to result in a wrapped line fragment that starts with a list item marker.  We can safely infer that a list item marker at the start of a line (with optional leading whitespace) is intentional, and should yield a new list item block.

Any whitespace before a list item marker should also be considered intentional, and should determine the indentation level of the list item:

a. Same amount of whitespace as before previous list item marker => same list element (ol/ul)
b. More whitespace => new list element (ol/ul) contained inside previous line's list item
c. Less whitespace => close previous line's list element (ol/ul)

This should allow you to parse list items and nested lists without requiring blank lines between the list items.

# Nested Blockquotes

While parsing line-by-line, kramdown should keep track of the degree of nesting in the current block.

A line starting with more blockquote markers than the previous degree of nesting should start a new nested blockquote.

A line starting with blockquote markers but containing no other content should close a more deeply nested previous list or blockquote.

Input:

> This is a double-nested blockquote.
>
> New paragraph in the same blockquote.
> 
> > This line has two blockquote markers, starting a
> > nested blockquote element inside first blockquote.
This is part of the nested blockquote (wrapped line).
> > This is the last line of nested blockquote.
>
> Previous line was blank except for single > marker,
> and that closed the nested blockquote, so this part 
> is a continuation of the original blockquote.
>
> 1. Here's a list nested in the first blockquote
> 2. And a second list item
>
> Previous line was blank except for single > marker,
> and that closed the nested list.

Previous blank line ended the first blockquote.

Result:

<blockquote>
  <p>This is a double-nested blockquote.</p>
  <p>New paragraph in the same blockquote.</p>
  <blockquote>
    <p>This line has two blockquote markers, starting a nested blockquote element inside first blockquote. This is part of the nested blockquote (wrapped line). This is the last line of nested blockquote.</p>
  </blockquote>
  <p>Previous line was blank except for single &gt; marker, and that closed the nested blockquote, so this part is a continuation of the original blockquote.</p>
  <ol>
    <li>Here's a list nested in the first blockquote</li>
    <li> And a second list item</li>
  </ol>
  <p>Previous line was blank except for single &gt; marker, and that closed the nested list.</p>
</blockquote>
<p>Previous blank line ended the first blockquote.</p>

Shawn

On Sun, 5 Sep 2010 08:52:26 +0200, Thomas Leitner wrote:
> Hi,
> 
> I have just started implementing the lazy syntax and I've come across a
> problem of how to implement them.
> 
> You see if it is not allowed to use lazy syntax, basically every block
> level element can follow another block level element except if they use
> the same syntax (as with lists followed by a code block).
> 
> However, this breaks down once we allow the lazy syntax... Since
> blockquotes and lists start with a special character at the beginning
> of a line, it is possible that such a character appears at the
> beginning of a line due to line wrapping. Then we have an ambiguous
> situation. Let's look at the examples given in my previous email:
> 
>> PA1. First example:
>> 
>>     * this is list item
>>> * this item is in a block quote  
>>     more block quoting?
> 
> In the previous mail I said that this would be a list followed by a
> blockquote. However, if we strictly follow the line wrapping approach
> it would need to be a list with a single item (PHP Markdown, Pandoc
> extended interpret it this way)...
> 
>> PA4. Fourth example:
>> 
>>> * foo
>>>> bar
>>>> baz 
> 
> And this would need to be a list with a single item inside a blockquote
> (again, PHP Markdown, Pandoc extended interpret it this way).
> 
> Here are some problematic examples and how they are interpreted by
> different Markdown implementations:
> 
> http://babelmark.bobtfish.net/?markdown=++++Some+text%0D%0Afollowed%0D%0A%0D%0A*+*+*%0D%0A%0D%0A%3E+++++Some+text%0D%0A%3E%0D%0ASome+other+text%0D%0A%0D%0Awill+be+codeb+and+para+inside+bq%0D%0A%0D%0A*+*+*%0D%0A%0D%0A%3E+++++Some+text%0D%0ASome+other+text%0D%0A%0D%0Awill+be+codeb+(undo+line+wrapping)+inside+bq%0D%0A%0D%0A*+*+*%0D%0A%0D%0A*+this+is+list+item%0D%0A%3E+*+this+item+is+in+a+block+quote++%0D%0Amore+block+quoting%3F%0D%0A%0D%0A*+*+*%0D%0A%0D%0A%3E+quote%0D%0A*+list%0D%0A%0D%0A*+*+*%0D%0A%0D%0A*+list%0D%0A%3E+quote%0D%0A%0D%0A*+*+*%0D%0A%0D%0Afor%0D%0A%3E+bar%0D%0Abaz%0D%0A%0D%0A*+*+*%0D%0A%0D%0A%3E+for%0D%0A%3E+%3E+bar%0D%0A%3E+baz%0D%0A%0D%0A*+*+*%0D%0A%0D%0A%3E+*+foo%0D%0A%3E+%3E+bar%0D%0A%3E+%3E+baz%0D%0A&normalize=on&src=1&dest=2
> 
> So what do about this? I have come to think of two choices:
> 
> 1. Do it like Markdown: It allows certain block level elements directly
>    after another one but not all, for example
> 
>    - paragraph followed directly by blockquote|header|hr
>      results in a paragraph and a blockquote|header|hr
> 
>    - paragraph followed directly by list|codeblock
>      results in just a paragraph
> 
>    And the output of a blockquote after a list or vice versa is also not
>    very intuitive.
> 
> 2. Require the use blank lines between all block level elements, with
>    special provisions for compact lists. This would further break
>    compatibility with Markdown but kramdown already breaks it. And this
>    change should not affect too much documents, only such edge cases
>    as mentioned above... or so I think.
> 
>    John Gruber once said in the Markdown ML:
> 
>    > So while we're fixing Setext-style headings, here are my thoughts
>    > on how to make them less ambiguous. One overall problem in
>    > Markdown 1.0's syntax is that it isn't clear when you need
>    > blank lines to separate block-level constructs.
>    >
>    > I feel strongly now that this was a mistake, and that the rules
>    > should be tightened such that all (or nearly all -- there may be
>    > worthwhile exceptions I haven't considered) block level
>    > constructs must be both preceded and succeeded by a blank line.
>    > (Or they must occur at the start or end of the document, of
>    > course.)
> 
> I would personally go for option two - what do you think?
> 
> 
> Another edge case with code blocks I would like to mention. In my
> previous email I said that code blocks should probably not support line
> wrapping. But why shouldn't they? If there are long lines inside a code
> block they are surely wrapped as with long lines in paragraphs. Since
> one should probably surround a code block with blank lines anyway, why
> not allow a lazy syntax:
> 
>         Some text
>     Some code block other text
> 
> This would be a code block with one long line, equivalent to this:
> 
>         Some text Some code block other text
> 
> I would like to it this way to avoid having this as special case
> regarding line wrapping.
> 
> Thanks for your help!
> 
> Best regards,
>   Thomas
> _______________________________________________
> kramdown-users mailing list
> kramdown-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/kramdown-users


More information about the kramdown-users mailing list