From 9c7c5a0c116de2faac3f9a37595656a648c5a99e Mon Sep 17 00:00:00 2001 From: "Kyle J. McKay" Date: Fri, 4 Jun 2021 22:38:38 -0700 Subject: [PATCH] Markdown.pl: do not mistake table for code block When making a nice looking table such as this: Term | Detail -------------- | -------------- First term | number one Second term | number two There is a potential to misinterpret the header line as the beginning of a code block (the indented type) since it begins with 5 spaces. Of course this could be addressed either by moving the "Term" string to the left at least 2 spaces or by adding the optional leading "|" to the beginning of the column, but that's unnecessarily ugly. Instead, when parsing a code block, check to see if the code block consists of exactly one line and when combined with the next line represents a valid table start. A valid table start specifies a header row and a separator row with exactly the same (positive integer) number of columns. If a valid table start is found, avoid making it into a code block and instead allow the table code to grab it and make it into a table. Signed-off-by: Kyle J. McKay --- Markdown.pl | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/Markdown.pl b/Markdown.pl index 2d0de93..0d4385c 100755 --- a/Markdown.pl +++ b/Markdown.pl @@ -3015,16 +3015,20 @@ sub _DoCodeBlocks { my $less_than_indent = $opt{indent_width} - 1; $text =~ s{ - (?:\n\n|\A\n?) - ( # $1 = the code block -- one or more lines, starting with indent_width spaces + (\n\n|\A\n?) + ( # $2 = the code block -- one or more lines, starting with indent_width spaces (?: (?:[ ]{$opt{indent_width}}) # Lines must start with indent_width of spaces .*\n+ )+ ) - (?:(?=^[ ]{0,$less_than_indent}\S)|\Z) # Lookahead for non-space at line-start, or end of doc - }{ - my $codeblock = $1; + (?:(?=(^[ ]{0,$less_than_indent}\S.*))|\Z) # Lookahead for non-space at line-start, or end of doc + }{&{sub{ + my ($prefix, $codeblock, $n) = ($1, $2, $3); + + if (defined($n) && length($n) && (()=($codeblock =~ /\n/g)) == 1 && _IsTableStart($codeblock.$n."\n")) { + return $prefix.$codeblock; + } $codeblock =~ s/\n\n\n/\n\n/g; # undo "paragraph for last list item" change $codeblock = _EncodeCode(_Outdent($codeblock)); @@ -3036,7 +3040,7 @@ sub _DoCodeBlocks { my $key = block_id($result, 2); $g_code_blocks{$key} = $result; "\n\n" . $key . "\n\n"; - }egmx; + }}}egmx; return $text; } @@ -3192,6 +3196,29 @@ BEGIN { $SEP = qr/[ ]*:?-+:?[ ]*/o; } +sub _IsTableStart { + my $text = shift; + my $ans = 0; + + if ($text =~ m{ + ^( # Header line + $LEADBAR \| [^\n]* | + $LEADBAR $COLPL [^\n]* | + $LEADSP $COLPL \| [^\n]* + )\n + ( # Separator line + $LEADBAR $SEP (?: \| $SEP )* (?: \| [ ]*)? | + $SEP (?: \| $SEP )+ (?: \| [ ]*)? | + $SEP \| [ ]* + )\n + }mx) { + my ($h, $s) = ($1, $2); + _SplitTableRow($h) == _SplitTableRow($s) and $ans = 1; + } + + return $ans; +} + sub _DoTables { my $text = shift;