From c4bec1ee0cbdf2c07610ad8f03992edbeedb79b2 Mon Sep 17 00:00:00 2001 From: "Kyle J. McKay" Date: Mon, 9 Jan 2017 19:02:27 -0800 Subject: [PATCH] Markdown.pl: handle non-backticks-delimited code blocks properly The regular, indented-by-four-spaces, code blocks do not nest nor should they. But they were nesting if they were located inside a list. Fix this by hashifying them and not unhashifying them until the very end. Also there's a kludge in the code that says: # Turn double returns into triple returns, so that we can make a # paragraph for the last item in a list, if necessary Unfortunately that perverts blank lines inside a code block. Fix this by changing the perversion so that it accomplishes the same thing but has an exact inverse and apply that inverse before formatting code blocks. Code blocks inside lists should now format correctly (and this does fix the example in the README that was previously formatted incorrectly). Finally, a code block at the very beginning of the file preceded by a single blank line would not have been recognized (but if it were preceded by none or two or more it would have). Now it will be recognized properly. And one more thing. Since we're in there tweaking code blocks, wrap the output in a
...
section and insert a null
right after the opening
tag. This makes sure the displayed code block will not end up getting mashed up against something it shouldn't be mashed up against. Signed-off-by: Kyle J. McKay --- Markdown.pl | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/Markdown.pl b/Markdown.pl index c1ffd9f..790094a 100755 --- a/Markdown.pl +++ b/Markdown.pl @@ -66,6 +66,7 @@ my %g_urls; my %g_titles; my %g_block_ids; my %g_html_blocks; +my %g_code_blocks; my %opt; # Return a "block id" to use to identify the block that does not contain @@ -344,6 +345,7 @@ sub Markdown { %g_titles = (); %g_block_ids = (); %g_html_blocks = (); + %g_code_blocks = (); $g_list_level = 0; # Standardize line endings: @@ -373,6 +375,9 @@ sub Markdown { $text = _RunBlockGamut($text); + # Unhashify code blocks + $text =~ s/(\005\d+\006)/$g_code_blocks{$1}/g; + $text = _UnescapeSpecialChars($text); return $text . "\n"; @@ -402,7 +407,7 @@ sub _HashBTCodeBlocks { $codeblock =~ s/\A\n+//; # trim leading newlines $codeblock =~ s/\s+\z//; # trim trailing whitespace $codeblock = _EncodeCode($codeblock); # or run highlighter here - $codeblock = "
" . $codeblock . "\n
"; + $codeblock = "
" . $codeblock . "\n
"; my $key = block_id($codeblock); $g_html_blocks{$key} = $codeblock; @@ -980,7 +985,7 @@ sub _DoLists { my $list_type = ($3 =~ m/$marker_ul/) ? "ul" : "ol"; # Turn double returns into triple returns, so that we can make a # paragraph for the last item in a list, if necessary: - $list =~ s/\n{2,}/\n\n\n/g; + $list =~ s/\n\n/\n\n\n/g; my $result = _ProcessListItems($list, $marker_any); $result = "<$list_type>\n" . $result . "\n"; $result; @@ -1006,7 +1011,7 @@ sub _DoLists { my $list_type = ($3 =~ m/$marker_ul/) ? "ul" : "ol"; # Turn double returns into triple returns, so that we can make a # paragraph for the last item in a list, if necessary: - $list =~ s/\n{2,}/\n\n\n/g; + $list =~ s/\n\n/\n\n\n/g; my $result = _ProcessListItems($list, $marker_any); $result = "<$list_type>\n" . $result . "\n"; $result; @@ -1094,7 +1099,7 @@ sub _DoCodeBlocks { my $text = shift; $text =~ s{ - (?:\n\n|\A) + (?:\n\n|\A\n?) ( # $1 = the code block -- one or more lines, starting with indent_width spaces (?: (?:[ ]{$opt{indent_width}}) # Lines must start with indent_width of spaces @@ -1104,15 +1109,16 @@ sub _DoCodeBlocks { ((?=^[ ]{0,$opt{indent_width}}\S)|\Z) # Lookahead for non-space at line-start, or end of doc }{ my $codeblock = $1; - my $result; # return value + $codeblock =~ s/\n\n\n/\n\n/g; # undo "paragraph for last list item" change $codeblock = _EncodeCode(_Outdent($codeblock)); $codeblock =~ s/\A\n+//; # trim leading newlines $codeblock =~ s/\s+\z//; # trim trailing whitespace - $result = "\n\n
" . $codeblock . "\n
\n\n"; - - $result; + my $result = "
" . $codeblock . "\n
"; + my $key = block_id($result); + $g_code_blocks{$key} = $result; + "\n\n" . $key . "\n\n"; }egmx; return $text; @@ -1232,15 +1238,6 @@ sub _DoBlockQuotes { $bq = _RunBlockGamut($bq); # recurse $bq =~ s/^/ /mg; - # These leading spaces screw with
 content, so we need to fix that:
-	    $bq =~ s{
-		    (\s*)(
.+?
) - }{ - my ($indent, $pre) = ($1, $2); - $pre =~ s/^ //mg; - $indent.$pre; - }egsx; - "
\n$bq\n
\n\n"; }egmx; @@ -1266,7 +1263,7 @@ sub _FormParagraphs { # Wrap

tags. # foreach (@grafs) { - unless (defined( $g_html_blocks{$_} )) { + unless (defined($g_html_blocks{$_}) || defined($g_code_blocks{$_})) { $_ = _RunSpanGamut($_); s/^([ \t]*)/

/; $_ .= "

";