Fix parsing of inline code blocks with multiple backticks (dart-lang/markdown#260)
Fix parsing of inline code blocks with multiple backticks
diff --git a/pkgs/markdown/CHANGELOG.md b/pkgs/markdown/CHANGELOG.md
index 7962de8..5b3dc7b 100644
--- a/pkgs/markdown/CHANGELOG.md
+++ b/pkgs/markdown/CHANGELOG.md
@@ -7,6 +7,7 @@
* Improve strict spec compliance for `code` elements defined with "\`".
* Properly encode `<`, `>`, and `"` as their respective HTML entities when
interpreted as text.
+* Improve inline code parsing when using multiple backticks.
## 2.0.3
diff --git a/pkgs/markdown/lib/src/block_parser.dart b/pkgs/markdown/lib/src/block_parser.dart
index 8153004..ba07218 100644
--- a/pkgs/markdown/lib/src/block_parser.dart
+++ b/pkgs/markdown/lib/src/block_parser.dart
@@ -2,6 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:charcode/charcode.dart';
+
import 'ast.dart';
import 'document.dart';
import 'util.dart';
@@ -25,7 +27,7 @@
final _indentPattern = RegExp(r'^(?: | {0,3}\t)(.*)$');
/// Fenced code block.
-final _codePattern = RegExp(r'^[ ]{0,3}(`{3,}|~{3,})(.*)$');
+final _codeFencePattern = RegExp(r'^[ ]{0,3}(`{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,
@@ -265,7 +267,7 @@
bool _interperableAsParagraph(String line) =>
!(_indentPattern.hasMatch(line) ||
- _codePattern.hasMatch(line) ||
+ _codeFencePattern.hasMatch(line) ||
_headerPattern.hasMatch(line) ||
_blockquotePattern.hasMatch(line) ||
_hrPattern.hasMatch(line) ||
@@ -404,12 +406,25 @@
/// Parses preformatted code blocks between two ~~~ or ``` sequences.
///
-/// See [Pandoc's documentation](http://pandoc.org/README.html#fenced-code-blocks).
+/// See the CommonMark spec: https://spec.commonmark.org/0.29/#fenced-code-blocks
class FencedCodeBlockSyntax extends BlockSyntax {
- RegExp get pattern => _codePattern;
+ RegExp get pattern => _codeFencePattern;
const FencedCodeBlockSyntax();
+ bool canParse(BlockParser parser) {
+ final match = pattern.firstMatch(parser.current);
+ if (match == null) return false;
+ final codeFence = match.group(1);
+ final infoString = match.group(2);
+ // From the CommonMark spec:
+ //
+ // > If the info string comes after a backtick fence, it may not contain
+ // > any backtick characters.
+ return (codeFence.codeUnitAt(0) != $backquote ||
+ !infoString.codeUnits.contains($backquote));
+ }
+
List<String> parseChildLines(BlockParser parser, [String endBlock]) {
if (endBlock == null) endBlock = '';
diff --git a/pkgs/markdown/test/common_mark/code_spans.unit b/pkgs/markdown/test/common_mark/code_spans.unit
index 069bd88..6864bf7 100644
--- a/pkgs/markdown/test/common_mark/code_spans.unit
+++ b/pkgs/markdown/test/common_mark/code_spans.unit
@@ -86,8 +86,7 @@
>>> Code spans - 347
```foo``
<<<
-<pre><code class="language-foo``">
-</code></pre>
+<p>```foo``</p>
>>> Code spans - 348
`foo
<<<
diff --git a/pkgs/markdown/test/common_mark/fenced_code_blocks.unit b/pkgs/markdown/test/common_mark/fenced_code_blocks.unit
index 2e30524..11ab448 100644
--- a/pkgs/markdown/test/common_mark/fenced_code_blocks.unit
+++ b/pkgs/markdown/test/common_mark/fenced_code_blocks.unit
@@ -166,9 +166,8 @@
``` ```
aaa
<<<
-<pre><code class="language-```">aaa
-
-</code></pre>
+<p><code></code>
+aaa</p>
>>> Fenced code blocks - 109
~~~~~~
aaa
@@ -232,9 +231,8 @@
``` aa ```
foo
<<<
-<pre><code class="language-aa">foo
-
-</code></pre>
+<p><code>aa</code>
+foo</p>
>>> Fenced code blocks - 116
~~~ aa ``` ~~~
foo
diff --git a/pkgs/markdown/test/gfm/code_spans.unit b/pkgs/markdown/test/gfm/code_spans.unit
index 6789f57..f620371 100644
--- a/pkgs/markdown/test/gfm/code_spans.unit
+++ b/pkgs/markdown/test/gfm/code_spans.unit
@@ -86,8 +86,7 @@
>>> Code spans - 357
```foo``
<<<
-<pre><code class="language-foo``">
-</code></pre>
+<p>```foo``</p>
>>> Code spans - 358
`foo
<<<
diff --git a/pkgs/markdown/test/gfm/fenced_code_blocks.unit b/pkgs/markdown/test/gfm/fenced_code_blocks.unit
index 2e30524..11ab448 100644
--- a/pkgs/markdown/test/gfm/fenced_code_blocks.unit
+++ b/pkgs/markdown/test/gfm/fenced_code_blocks.unit
@@ -166,9 +166,8 @@
``` ```
aaa
<<<
-<pre><code class="language-```">aaa
-
-</code></pre>
+<p><code></code>
+aaa</p>
>>> Fenced code blocks - 109
~~~~~~
aaa
@@ -232,9 +231,8 @@
``` aa ```
foo
<<<
-<pre><code class="language-aa">foo
-
-</code></pre>
+<p><code>aa</code>
+foo</p>
>>> Fenced code blocks - 116
~~~ aa ``` ~~~
foo
diff --git a/pkgs/markdown/tool/common_mark_stats.json b/pkgs/markdown/tool/common_mark_stats.json
index a250f90..26f32eb 100644
--- a/pkgs/markdown/tool/common_mark_stats.json
+++ b/pkgs/markdown/tool/common_mark_stats.json
@@ -105,7 +105,7 @@
"344": "strict",
"345": "strict",
"346": "strict",
- "347": "fail",
+ "347": "strict",
"348": "strict",
"349": "strict"
},
@@ -281,14 +281,14 @@
"105": "strict",
"106": "strict",
"107": "loose",
- "108": "fail",
+ "108": "loose",
"109": "loose",
"110": "strict",
"111": "strict",
"112": "strict",
"113": "strict",
"114": "strict",
- "115": "fail",
+ "115": "strict",
"116": "strict",
"117": "fail"
},
diff --git a/pkgs/markdown/tool/common_mark_stats.txt b/pkgs/markdown/tool/common_mark_stats.txt
index 249ed10..4bbd5af 100644
--- a/pkgs/markdown/tool/common_mark_stats.txt
+++ b/pkgs/markdown/tool/common_mark_stats.txt
@@ -3,10 +3,10 @@
12 of 13 – 92.3% Backslash escapes
1 of 1 – 100.0% Blank lines
22 of 25 – 88.0% Block quotes
- 21 of 22 – 95.5% Code spans
+ 22 of 22 – 100.0% Code spans
125 of 131 – 95.4% Emphasis and strong emphasis
14 of 17 – 82.4% Entity and numeric character references
- 26 of 29 – 89.7% Fenced code blocks
+ 28 of 29 – 96.6% Fenced code blocks
15 of 15 – 100.0% Hard line breaks
43 of 43 – 100.0% HTML blocks
21 of 22 – 95.5% Images
@@ -24,5 +24,5 @@
11 of 11 – 100.0% Tabs
3 of 3 – 100.0% Textual content
19 of 19 – 100.0% Thematic breaks
- 598 of 649 – 92.1% TOTAL
- 525 of 598 – 87.8% TOTAL Strict
+ 601 of 649 – 92.6% TOTAL
+ 527 of 601 – 87.7% TOTAL Strict
diff --git a/pkgs/markdown/tool/gfm_stats.json b/pkgs/markdown/tool/gfm_stats.json
index 243cd6c..0abf0c3 100644
--- a/pkgs/markdown/tool/gfm_stats.json
+++ b/pkgs/markdown/tool/gfm_stats.json
@@ -118,7 +118,7 @@
"354": "strict",
"355": "strict",
"356": "strict",
- "357": "fail",
+ "357": "strict",
"358": "strict",
"359": "strict"
},
@@ -297,14 +297,14 @@
"105": "strict",
"106": "strict",
"107": "loose",
- "108": "fail",
+ "108": "loose",
"109": "loose",
"110": "strict",
"111": "strict",
"112": "strict",
"113": "strict",
"114": "strict",
- "115": "fail",
+ "115": "strict",
"116": "strict",
"117": "fail"
},
diff --git a/pkgs/markdown/tool/gfm_stats.txt b/pkgs/markdown/tool/gfm_stats.txt
index ab2fb17..d471838 100644
--- a/pkgs/markdown/tool/gfm_stats.txt
+++ b/pkgs/markdown/tool/gfm_stats.txt
@@ -4,11 +4,11 @@
12 of 13 – 92.3% Backslash escapes
1 of 1 – 100.0% Blank lines
22 of 25 – 88.0% Block quotes
- 21 of 22 – 95.5% Code spans
+ 22 of 22 – 100.0% Code spans
0 of 1 – 0.0% Disallowed Raw HTML (extension)
125 of 131 – 95.4% Emphasis and strong emphasis
14 of 17 – 82.4% Entity and numeric character references
- 26 of 29 – 89.7% Fenced code blocks
+ 28 of 29 – 96.6% Fenced code blocks
15 of 15 – 100.0% Hard line breaks
43 of 43 – 100.0% HTML blocks
21 of 22 – 95.5% Images
@@ -28,5 +28,5 @@
11 of 11 – 100.0% Tabs
3 of 3 – 100.0% Textual content
19 of 19 – 100.0% Thematic breaks
- 613 of 671 – 91.4% TOTAL
- 531 of 613 – 86.6% TOTAL Strict
+ 616 of 671 – 91.8% TOTAL
+ 533 of 616 – 86.5% TOTAL Strict