Pandoc-style fenced block syntax.
diff --git a/pkgs/markdown/lib/src/markdown/block_parser.dart b/pkgs/markdown/lib/src/markdown/block_parser.dart index 42b9353..14ddf86 100644 --- a/pkgs/markdown/lib/src/markdown/block_parser.dart +++ b/pkgs/markdown/lib/src/markdown/block_parser.dart
@@ -22,6 +22,9 @@ /// GitHub style triple quoted code block. final _RE_CODE = new RegExp(r'^```(.*)$'); +/// Pandoc style code block. +final _RE_PANDOC_CODE = new RegExp(r'^(`{3,}|~{3,})(.*)$'); + /// 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. @@ -98,6 +101,7 @@ new HeaderSyntax(), new CodeBlockSyntax(), new GitHubCodeBlockSyntax(), + new PandocCodeBlockSyntax(), new BlockquoteSyntax(), new HorizontalRuleSyntax(), new UnorderedListSyntax(), @@ -280,6 +284,53 @@ } } +/// Parses preformatted code blocks between two ~~~ or ``` sequences. +/// [Pandoc's markdown documentation](http://johnmacfarlane.net/pandoc/demo/example9/pandocs-markdown.html). +class PandocCodeBlockSyntax extends BlockSyntax { + RegExp get pattern => _RE_PANDOC_CODE; + + List<String> parseChildLines(BlockParser parser, String endBlock) { + final childLines = <String>[]; + parser.advance(); + while (!parser.isDone) { + var match = pattern.firstMatch(parser.current); + if (match == null || !match[1].startsWith(endBlock)) { + childLines.add(parser.current); + parser.advance(); + } else { + parser.advance(); + break; + } + } + return childLines; + } + + Node parse(BlockParser parser) { + // Get the syntax identifier, if there is one. + var match = pattern.firstMatch(parser.current); + var endBlock = match.group(1); + var syntax = match.group(2); + + final childLines = parseChildLines(parser, endBlock); + + // The Markdown tests expect a trailing newline. + childLines.add(''); + + // Escape the code. + final escaped = escapeHtml(childLines.join('\n')); + + var element = new Element('pre', [new Element.text('code', escaped)]); + if (syntax != '') { + element.attributes['class'] = syntax; + } + return element; + } + + void _addElementAttributes(Element element) { + + } +} + /// Parses horizontal rules like `---`, `_ _ _`, `* * *`, etc. class HorizontalRuleSyntax extends BlockSyntax { RegExp get pattern => _RE_HR;
diff --git a/pkgs/markdown/test/markdown_test.dart b/pkgs/markdown/test/markdown_test.dart index fcf76d1..6416278 100644 --- a/pkgs/markdown/test/markdown_test.dart +++ b/pkgs/markdown/test/markdown_test.dart
@@ -451,6 +451,37 @@ <pre><code><&> </code></pre> '''); + + validate('Pandoc style without language identifier', ''' + ~~~~~ + code + ~~~~~ + ''', ''' + <pre><code>code + </code></pre> + '''); + + validate('Pandoc style with language identifier', ''' + ~~~~~dart + code + ~~~~~ + ''', ''' + <pre class="dart"><code>code + </code></pre> + '''); + + validate('Pandoc style with inner tildes row', ''' + ~~~~~ + ~~~ + code + ~~~ + ~~~~~ + ''', ''' + <pre><code>~~~ + code + ~~~ + </code></pre> + '''); }); group('Horizontal rules', () {