Support multiline Setext headers
diff --git a/pkgs/markdown/lib/src/block_parser.dart b/pkgs/markdown/lib/src/block_parser.dart index a809947..1211b81 100644 --- a/pkgs/markdown/lib/src/block_parser.dart +++ b/pkgs/markdown/lib/src/block_parser.dart
@@ -12,7 +12,7 @@ final _emptyPattern = new RegExp(r'^(?:[ \t]*)$'); /// A series of `=` or `-` (on the next line) define setext-style headers. -final _setextPattern = new RegExp(r'^(=+|-+)$'); +final _setextPattern = new RegExp(r'^[ ]{0,3}(=+|-+)\s*$'); /// Leading (and trailing) `#` define atx-style headers. /// @@ -221,28 +221,56 @@ const SetextHeaderSyntax(); bool canParse(BlockParser parser) { - // Note: matches *next* line, not the current one. We're looking for the - // underlining after this line. - return parser.matchesNext(_setextPattern) && - // The current line must look like a paragraph. - !(parser.matches(_codePattern) || - parser.matches(_headerPattern) || - parser.matches(_blockquotePattern) || - parser.matches(_hrPattern) || - parser.matches(_ulPattern) || - parser.matches(_olPattern)); + if (!_interperableAsParagraph(parser.current)) return false; + int i = 1; + while (true) { + var nextLine = parser.peek(i); + if (nextLine == null) { + // We never reached an underline. + return false; + } + if (_setextPattern.hasMatch(nextLine)) { + return true; + } + // Ensure that we're still in something like paragraph text. + if (!_interperableAsParagraph(nextLine)) { + return false; + } + i++; + } } Node parse(BlockParser parser) { - var match = _setextPattern.firstMatch(parser.next); + var lines = <String>[]; + var tag; + while (!parser.isDone) { + var match = _setextPattern.firstMatch(parser.current); + if (match == null) { + // More text. + lines.add(parser.current); + parser.advance(); + continue; + } else { + // The underline. + tag = (match[1][0] == '=') ? 'h1' : 'h2'; + parser.advance(); + break; + } + } - var tag = (match[1][0] == '=') ? 'h1' : 'h2'; - var contents = new UnparsedContent(parser.current); - parser.advance(); - parser.advance(); + var contents = new UnparsedContent(lines.join('\n')); return new Element(tag, [contents]); } + + bool _interperableAsParagraph(line) => !(_indentPattern.hasMatch(line) || + _codePattern.hasMatch(line) || + _headerPattern.hasMatch(line) || + _blockquotePattern.hasMatch(line) || + _hrPattern.hasMatch(line) || + _ulPattern.hasMatch(line) || + _olPattern.hasMatch(line) || + _emptyPattern.hasMatch(line)); } /// Parses setext-style headers, and adds generated IDs to the generated
diff --git a/pkgs/markdown/test/original/paragraphs.unit b/pkgs/markdown/test/original/paragraphs.unit index b4bb334..cd9181d 100644 --- a/pkgs/markdown/test/original/paragraphs.unit +++ b/pkgs/markdown/test/original/paragraphs.unit
@@ -12,14 +12,6 @@ <<< <p>para</p> <h1>header</h1> ->>> are terminated by a setext header -para -header -== - -<<< -<p>para</p> -<h1>header</h1> >>> are terminated by a hr para ___
diff --git a/pkgs/markdown/test/original/setext_headers.unit b/pkgs/markdown/test/original/setext_headers.unit index 7e34d9d..7760d45 100644 --- a/pkgs/markdown/test/original/setext_headers.unit +++ b/pkgs/markdown/test/original/setext_headers.unit
@@ -20,3 +20,11 @@ <<< <ul><li></li></ul> +>>> can be multiline +header +on two lines +== + +<<< +<h1>header +on two lines</h1>
diff --git a/pkgs/markdown/tool/common_mark_stats.json b/pkgs/markdown/tool/common_mark_stats.json index 9bf5b30..44ba651 100644 --- a/pkgs/markdown/tool/common_mark_stats.json +++ b/pkgs/markdown/tool/common_mark_stats.json
@@ -370,7 +370,7 @@ "81": "strict", "82": "loose", "83": "strict", - "84": "fail", + "84": "strict", "85": "strict", "86": "loose", "87": "strict" @@ -600,11 +600,11 @@ }, "Setext headings": { "50": "strict", - "51": "fail", + "51": "strict", "52": "strict", - "53": "fail", + "53": "loose", "54": "strict", - "55": "fail", + "55": "strict", "56": "loose", "57": "strict", "58": "loose", @@ -613,12 +613,12 @@ "61": "loose", "62": "fail", "63": "loose", - "64": "fail", + "64": "strict", "65": "strict", "66": "strict", "67": "strict", "68": "loose", - "69": "fail", + "69": "strict", "70": "loose", "71": "loose", "72": "strict",
diff --git a/pkgs/markdown/tool/common_mark_stats.txt b/pkgs/markdown/tool/common_mark_stats.txt index 14d9d68..f18d195 100644 --- a/pkgs/markdown/tool/common_mark_stats.txt +++ b/pkgs/markdown/tool/common_mark_stats.txt
@@ -10,7 +10,7 @@ 15 of 15 – 100.0% Hard line breaks 42 of 42 – 100.0% HTML blocks 21 of 22 – 95.5% Images - 10 of 12 – 83.3% Indented code blocks + 11 of 12 – 91.7% Indented code blocks 1 of 1 – 100.0% Inlines 20 of 23 – 87.0% Link reference definitions 53 of 81 – 65.4% Links @@ -19,9 +19,9 @@ 8 of 8 – 100.0% Paragraphs 1 of 1 – 100.0% Precedence 15 of 21 – 71.4% Raw HTML - 20 of 26 – 76.9% Setext headings + 25 of 26 – 96.2% Setext headings 2 of 2 – 100.0% Soft line breaks 6 of 11 – 54.5% Tabs 3 of 3 – 100.0% Textual content 17 of 19 – 89.5% Thematic breaks - 484 of 618 – 78.3% TOTAL + 490 of 618 – 79.3% TOTAL