Merge pull request dart-lang/markdown#6 from dikmax/pandoc-code-blocks
Pandoc-style code blocks
diff --git a/pkgs/markdown/lib/src/markdown/block_parser.dart b/pkgs/markdown/lib/src/markdown/block_parser.dart
index 42b9353..d163e9c 100644
--- a/pkgs/markdown/lib/src/markdown/block_parser.dart
+++ b/pkgs/markdown/lib/src/markdown/block_parser.dart
@@ -19,8 +19,8 @@
/// A line indented four spaces. Used for code blocks and lists.
final _RE_INDENT = new RegExp(r'^(?: |\t)(.*)$');
-/// GitHub style triple quoted code block.
-final _RE_CODE = new RegExp(r'^```(.*)$');
+/// Fenced code block.
+final _RE_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,
@@ -97,7 +97,7 @@
new SetextHeaderSyntax(),
new HeaderSyntax(),
new CodeBlockSyntax(),
- new GitHubCodeBlockSyntax(),
+ new FencedCodeBlockSyntax(),
new BlockquoteSyntax(),
new HorizontalRuleSyntax(),
new UnorderedListSyntax(),
@@ -244,16 +244,17 @@
}
}
-/// Parses preformatted code blocks between two ``` sequences.
-class GitHubCodeBlockSyntax extends BlockSyntax {
+/// Parses preformatted code blocks between two ~~~ or ``` sequences.
+/// [Pandoc's markdown documentation](http://johnmacfarlane.net/pandoc/demo/example9/pandocs-markdown.html).
+class FencedCodeBlockSyntax extends BlockSyntax {
RegExp get pattern => _RE_CODE;
- List<String> parseChildLines(BlockParser parser) {
+ List<String> parseChildLines(BlockParser parser, String endBlock) {
final childLines = <String>[];
parser.advance();
while (!parser.isDone) {
var match = pattern.firstMatch(parser.current);
- if (match == null) {
+ if (match == null || !match[1].startsWith(endBlock)) {
childLines.add(parser.current);
parser.advance();
} else {
@@ -266,9 +267,11 @@
Node parse(BlockParser parser) {
// Get the syntax identifier, if there is one.
- var syntax = pattern.firstMatch(parser.current).group(1);
-
- final childLines = parseChildLines(parser);
+ 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('');
@@ -276,7 +279,15 @@
// Escape the code.
final escaped = escapeHtml(childLines.join('\n'));
- return new Element('pre', [new Element.text('code', escaped)]);
+ var element = new Element('pre', [new Element.text('code', escaped)]);
+ if (syntax != '') {
+ element.attributes['class'] = syntax;
+ }
+ return element;
+ }
+
+ void _addElementAttributes(Element element) {
+
}
}
diff --git a/pkgs/markdown/test/markdown_test.dart b/pkgs/markdown/test/markdown_test.dart
index 63ffb91..1e4b0c9 100644
--- a/pkgs/markdown/test/markdown_test.dart
+++ b/pkgs/markdown/test/markdown_test.dart
@@ -439,7 +439,7 @@
code
```
''', '''
- <pre><code>code
+ <pre class="dart"><code>code
</code></pre>
''');
@@ -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', () {