Support GitLab flavored fenced blockquote (dart-lang/markdown#403)
diff --git a/pkgs/markdown/lib/src/block_parser.dart b/pkgs/markdown/lib/src/block_parser.dart index f8645e4..256ff1e 100644 --- a/pkgs/markdown/lib/src/block_parser.dart +++ b/pkgs/markdown/lib/src/block_parser.dart
@@ -29,6 +29,9 @@ /// Fenced code block. final _codeFencePattern = RegExp(r'^[ ]{0,3}(`{3,}|~{3,})(.*)$'); +/// Fenced blockquotes. +final _blockquoteFencePattern = RegExp(r'^>{3}\s*$'); + /// Three or more hyphens, asterisks or underscores by themselves. Note that /// a line like `----` is valid as both HR and SETEXT. In case of a tie, /// SETEXT should win. @@ -328,6 +331,42 @@ } } +/// Parses lines fenced by `>>>` to blockquotes +class FencedBlockquoteSyntax extends BlockSyntax { + const FencedBlockquoteSyntax(); + + @override + RegExp get pattern => _blockquoteFencePattern; + + @override + List<String> parseChildLines(BlockParser parser) { + final childLines = <String>[]; + parser.advance(); + + while (!parser.isDone) { + final match = pattern.hasMatch(parser.current); + if (!match) { + childLines.add(parser.current); + parser.advance(); + } else { + parser.advance(); + break; + } + } + + return childLines; + } + + @override + Node? parse(BlockParser parser) { + final childLines = parseChildLines(parser); + + // Recursively parse the contents of the blockquote. + final children = BlockParser(childLines, parser.document).parseLines(); + return Element('blockquote', children); + } +} + /// Parses email-style blockquotes: `> quote`. class BlockquoteSyntax extends BlockSyntax { @override
diff --git a/pkgs/markdown/test/extensions/fenced_blockquotes.unit b/pkgs/markdown/test/extensions/fenced_blockquotes.unit new file mode 100644 index 0000000..8124ad4 --- /dev/null +++ b/pkgs/markdown/test/extensions/fenced_blockquotes.unit
@@ -0,0 +1,70 @@ +>>> simple block quote +>>> +# Foo +bar +baz +>>> + +<<< +<blockquote> +<h1>Foo</h1> +<p>bar +baz</p> +</blockquote> +>>> has blank lines +>>> + +foo + + + + +bar + + +>>> + +<<< +<blockquote> +<p>foo</p> +<p>bar</p> +</blockquote> +>>> with nested block quote +>>> +foo +> bar +>>> + +<<< +<blockquote> +<p>foo</p> +<blockquote> +<p>bar</p> +</blockquote> +</blockquote> +>>> with nested indented clode block +>>> + foo + bar +>>> + +<<< +<blockquote> +<pre><code>foo +bar +</code></pre> +</blockquote> +>>> with nested fenced clode block +>>> +``` +foo +bar +``` +>>> + +<<< +<blockquote> +<pre><code>foo +bar +</code></pre> +</blockquote> \ No newline at end of file
diff --git a/pkgs/markdown/test/markdown_test.dart b/pkgs/markdown/test/markdown_test.dart index 1abe941..945b904 100644 --- a/pkgs/markdown/test/markdown_test.dart +++ b/pkgs/markdown/test/markdown_test.dart
@@ -18,6 +18,8 @@ testFile('extensions/setext_headers_with_ids.unit', blockSyntaxes: [const SetextHeaderWithIdSyntax()]); testFile('extensions/tables.unit', blockSyntaxes: [const TableSyntax()]); + testFile('extensions/fenced_blockquotes.unit', + blockSyntaxes: [const FencedBlockquoteSyntax()]); // Inline syntax extensions testFile('extensions/emojis.unit', inlineSyntaxes: [EmojiSyntax()]);