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