Browse Source

Markdown.pl: process lists, code blocks and blockquotes together

When processing something like this:

    * first
    > quoted
    * second

It's imperative that the list tags and blockquote tags do not
become intermingled resulting in invalid output like so:

    <p><ul>
    <li>first</p>
    <blockquote>
    <p>quoted</li>
    <li>second</li>
    </ul></p>
    </blockquote>

Instead, process the lists together with code blocks and
blockquotes so that cannot happen and instead we get the
correct output like so:

    <ul>
    <li>first
    <blockquote>
    <p>quoted</p>
    </blockquote>
    </li>
    <li>second</li>
    </ul>

Signed-off-by: Kyle J. McKay <mackyle@gmail.com>
master
Kyle J. McKay 6 years ago
parent
commit
a125798c27
  1. 52
      Markdown.pl

52
Markdown.pl

@ -850,11 +850,7 @@ sub _RunBlockGamut {
$text =~ s{^ {0,3}\_(?: {0,2}\_){2,}[ ]*$}{\n<hr$opt{empty_element_suffix}\n}gm; $text =~ s{^ {0,3}\_(?: {0,2}\_){2,}[ ]*$}{\n<hr$opt{empty_element_suffix}\n}gm;
$text =~ s{^ {0,3}\-(?: {0,2}\-){2,}[ ]*$}{\n<hr$opt{empty_element_suffix}\n}gm; $text =~ s{^ {0,3}\-(?: {0,2}\-){2,}[ ]*$}{\n<hr$opt{empty_element_suffix}\n}gm;
$text = _DoLists($text); $text = _DoListsAndBlocks($text);
$text = _DoCodeBlocks($text);
$text = _DoBlockQuotes($text);
$text = _DoTables($text); $text = _DoTables($text);
@ -870,6 +866,11 @@ sub _RunBlockGamut {
} }
sub _DoListBlocks {
return _DoBlockQuotes(_DoCodeBlocks($_[0])) if $_[0] ne "";
}
sub _RunSpanGamut { sub _RunSpanGamut {
# #
# These are all the transformations that occur *within* block-level # These are all the transformations that occur *within* block-level
@ -1620,7 +1621,7 @@ sub _IncrList {
} }
sub _DoLists { sub _DoListsAndBlocks {
# #
# Form HTML ordered (numbered) and unordered (bulleted) lists. # Form HTML ordered (numbered) and unordered (bulleted) lists.
# #
@ -1711,15 +1712,23 @@ sub _DoLists {
# two cases much easier to grok all at once. # two cases much easier to grok all at once.
if ($g_list_level) { if ($g_list_level) {
$text =~ s{ my $parse = $text;
^ $text = "";
$whole_list pos($parse) = 0;
}{ while ($parse =~ /\G(?s:.)*?^$whole_list/gmc) {
&$list_item_sub($1, $2, $3, $4); my @captures = ($1, $2, $3, $4);
}egmx; if ($-[1] > $-[0]) {
$text .= _DoListBlocks(substr($parse, $-[0], $-[1] - $-[0]));
}
$text .= &$list_item_sub(@captures);
}
$text .= _DoListBlocks(substr($parse, pos($parse))) if pos($parse) < length($parse);
} }
else { else {
$text =~ s{ my $parse = $text;
$text = "";
pos($parse) = 0;
while ($parse =~ m{\G(?s:.)*?
(?: (?<=\n\n) | (?: (?<=\n\n) |
\A\n? | \A\n? |
(?<=:\n) | (?<=:\n) |
@ -1733,9 +1742,14 @@ sub _DoLists {
[ ]{$indent,$less_than_double_indent}$marker_any[ ])) [ ]{$indent,$less_than_double_indent}$marker_any[ ]))
) )
$whole_list $whole_list
}{ }gmcx) {
&$list_item_sub($1, $2, $3, $4); my @captures = ($1, $2, $3, $4);
}egmx; if ($-[1] > $-[0]) {
$text .= _DoListBlocks(substr($parse, $-[0], $-[1] - $-[0]));
}
$text .= &$list_item_sub(@captures);
}
$text .= _DoListBlocks(substr($parse, pos($parse))) if pos($parse) < length($parse);
} }
return $text; return $text;
@ -1895,7 +1909,7 @@ sub _ProcessListItems {
} }
else { else {
# Recursion for sub-lists: # Recursion for sub-lists:
$item = _DoLists(_Outdent($item)); $item = _DoListsAndBlocks(_Outdent($item));
chomp $item; chomp $item;
$item = _RunSpanGamut($item); $item = _RunSpanGamut($item);
} }
@ -1916,7 +1930,7 @@ sub _ProcessListItems {
} }
# Anything left over (similar to $') goes into result, but this should always be empty # Anything left over (similar to $') goes into result, but this should always be empty
$result .= _RunBlockGamut(substr($list_str, pos($list_str))); $result .= _RunBlockGamut(substr($list_str, pos($list_str))) if pos($list_str) < length($list_str);
$g_list_level--; $g_list_level--;
@ -2101,7 +2115,7 @@ sub _DoBlockQuotes {
$bq =~ s/^[ ]+$//mg; # trim whitespace-only lines $bq =~ s/^[ ]+$//mg; # trim whitespace-only lines
$bq = _RunBlockGamut($bq); # recurse $bq = _RunBlockGamut($bq); # recurse
$bq =~ s/^/ /mg; $bq =~ s/^/\027/mg;
"<blockquote>\n$bq\n</blockquote>\n\n"; "<blockquote>\n$bq\n</blockquote>\n\n";
}egmx; }egmx;

Loading…
Cancel
Save