Improve BlockquoteSyntax (dart-lang/markdown#479)

* Improve BlockquoteSyntax

* Fix a comment

* Fix a FencedCodeBlockSyntax issue

It was not an issue until merged this updated FencedCodeBlockSyntax into current branch
diff --git a/pkgs/markdown/lib/src/block_syntaxes/blockquote_syntax.dart b/pkgs/markdown/lib/src/block_syntaxes/blockquote_syntax.dart
index 00b7560..813cb2d 100644
--- a/pkgs/markdown/lib/src/block_syntaxes/blockquote_syntax.dart
+++ b/pkgs/markdown/lib/src/block_syntaxes/blockquote_syntax.dart
@@ -4,7 +4,9 @@
 
 import '../ast.dart';
 import '../block_parser.dart';
+import '../charcode.dart';
 import '../patterns.dart';
+import '../util.dart';
 import 'block_syntax.dart';
 import 'code_block_syntax.dart';
 import 'paragraph_syntax.dart';
@@ -21,17 +23,29 @@
     // Grab all of the lines that form the blockquote, stripping off the ">".
     final childLines = <String>[];
 
-    var encounteredCodeBlock = false;
     while (!parser.isDone) {
+      final currentLine = parser.current;
       final match = pattern.firstMatch(parser.current);
       if (match != null) {
-        final line = match[1]!;
-        childLines.add(line);
-        encounteredCodeBlock = indentPattern.hasMatch(line);
+        // A block quote marker consists of a `>` together with an optional
+        // following space of indentation, see
+        // https://spec.commonmark.org/0.30/#block-quote-marker.
+        final markerStart = match.match.indexOf('>');
+        int markerEnd;
+        if (currentLine.length > 1) {
+          final nextChar = currentLine.codeUnitAt(markerStart + 1);
+          final hasSpace = nextChar == $tab || nextChar == $space;
+          markerEnd = markerStart + (hasSpace ? 2 : 1);
+        } else {
+          markerEnd = markerStart + 1;
+        }
+        childLines.add(currentLine.substring(markerEnd));
         parser.advance();
         continue;
       }
 
+      final lastLine = childLines.last;
+
       // A paragraph continuation is OK. This is content that cannot be parsed
       // as any other syntax except Paragraph, and it doesn't match the bar in
       // a Setext header.
@@ -39,8 +53,11 @@
       // matched CodeBlockSyntax is also paragraph continuation text.
       final otherMatched =
           parser.blockSyntaxes.firstWhere((s) => s.canParse(parser));
-      if (otherMatched is ParagraphSyntax ||
-          (!encounteredCodeBlock && otherMatched is CodeBlockSyntax)) {
+      if ((otherMatched is ParagraphSyntax &&
+              lastLine.isNotEmpty &&
+              !codeFencePattern.hasMatch(lastLine)) ||
+          (otherMatched is CodeBlockSyntax &&
+              !indentPattern.hasMatch(lastLine))) {
         childLines.add(parser.current);
         parser.advance();
       } else {
diff --git a/pkgs/markdown/lib/src/block_syntaxes/fenced_code_block_syntax.dart b/pkgs/markdown/lib/src/block_syntaxes/fenced_code_block_syntax.dart
index f9713ef..931fb88 100644
--- a/pkgs/markdown/lib/src/block_syntaxes/fenced_code_block_syntax.dart
+++ b/pkgs/markdown/lib/src/block_syntaxes/fenced_code_block_syntax.dart
@@ -83,7 +83,9 @@
 
     // https://spec.commonmark.org/0.30/#example-127
     // https://spec.commonmark.org/0.30/#example-128
-    if (closingFence == null && childLines.last.trim().isEmpty) {
+    if (closingFence == null &&
+        childLines.isNotEmpty &&
+        childLines.last.trim().isEmpty) {
       childLines.removeLast();
     }
 
diff --git a/pkgs/markdown/lib/src/patterns.dart b/pkgs/markdown/lib/src/patterns.dart
index 86531ba..a99cc5e 100644
--- a/pkgs/markdown/lib/src/patterns.dart
+++ b/pkgs/markdown/lib/src/patterns.dart
@@ -15,7 +15,7 @@
 final headerPattern = RegExp(r'^ {0,3}(#{1,6})[ \x09\x0b\x0c](.*?)#*$');
 
 /// The line starts with `>` with one optional space after.
-final blockquotePattern = RegExp(r'^[ ]{0,3}>[ ]?(.*)$');
+final blockquotePattern = RegExp(r'^[ ]{0,3}>[ \t]?.*$');
 
 /// A line indented four spaces. Used for code blocks and lists.
 final indentPattern = RegExp(r'^(?:    | {0,3}\t)(.*)$');
diff --git a/pkgs/markdown/test/common_mark/block_quotes.unit b/pkgs/markdown/test/common_mark/block_quotes.unit
index f223442..9931044 100644
--- a/pkgs/markdown/test/common_mark/block_quotes.unit
+++ b/pkgs/markdown/test/common_mark/block_quotes.unit
@@ -93,9 +93,9 @@
 ```
 <<<
 <blockquote>
-<pre><code>foo
-</code></pre>
+<pre><code></code></pre>
 </blockquote>
+<p>foo</p>
 <pre><code></code></pre>
 >>> Block quotes - 238
 > foo
@@ -197,8 +197,8 @@
 <<<
 <blockquote>
 <p>bar</p>
-<p>baz</p>
 </blockquote>
+<p>baz</p>
 >>> Block quotes - 250
 > > > foo
 bar
diff --git a/pkgs/markdown/test/common_mark/tabs.unit b/pkgs/markdown/test/common_mark/tabs.unit
index 2796403..cee429d 100644
--- a/pkgs/markdown/test/common_mark/tabs.unit
+++ b/pkgs/markdown/test/common_mark/tabs.unit
@@ -42,7 +42,7 @@
 >		foo
 <<<
 <blockquote>
-<pre><code>	foo
+<pre><code>foo
 </code></pre>
 </blockquote>
 >>> Tabs - 7
diff --git a/pkgs/markdown/test/gfm/block_quotes.unit b/pkgs/markdown/test/gfm/block_quotes.unit
index 30e1ef9..50d8757 100644
--- a/pkgs/markdown/test/gfm/block_quotes.unit
+++ b/pkgs/markdown/test/gfm/block_quotes.unit
@@ -93,9 +93,9 @@
 ```
 <<<
 <blockquote>
-<pre><code>foo
-</code></pre>
+<pre><code></code></pre>
 </blockquote>
+<p>foo</p>
 <pre><code></code></pre>
 >>> Block quotes - 216
 > foo
@@ -197,8 +197,8 @@
 <<<
 <blockquote>
 <p>bar</p>
-<p>baz</p>
 </blockquote>
+<p>baz</p>
 >>> Block quotes - 228
 > > > foo
 bar
diff --git a/pkgs/markdown/test/gfm/tabs.unit b/pkgs/markdown/test/gfm/tabs.unit
index 2796403..cee429d 100644
--- a/pkgs/markdown/test/gfm/tabs.unit
+++ b/pkgs/markdown/test/gfm/tabs.unit
@@ -42,7 +42,7 @@
 >		foo
 <<<
 <blockquote>
-<pre><code>	foo
+<pre><code>foo
 </code></pre>
 </blockquote>
 >>> Tabs - 7
diff --git a/pkgs/markdown/tool/common_mark_stats.json b/pkgs/markdown/tool/common_mark_stats.json
index 47935d8..4e814d3 100644
--- a/pkgs/markdown/tool/common_mark_stats.json
+++ b/pkgs/markdown/tool/common_mark_stats.json
@@ -68,7 +68,7 @@
   "234": "strict",
   "235": "strict",
   "236": "strict",
-  "237": "fail",
+  "237": "strict",
   "238": "strict",
   "239": "strict",
   "240": "strict",
@@ -80,7 +80,7 @@
   "246": "strict",
   "247": "strict",
   "248": "strict",
-  "249": "fail",
+  "249": "strict",
   "250": "strict",
   "251": "strict",
   "252": "strict"
diff --git a/pkgs/markdown/tool/common_mark_stats.txt b/pkgs/markdown/tool/common_mark_stats.txt
index 27d1105..4b6f751 100644
--- a/pkgs/markdown/tool/common_mark_stats.txt
+++ b/pkgs/markdown/tool/common_mark_stats.txt
@@ -2,7 +2,7 @@
   19 of   19 – 100.0%  Autolinks
   13 of   13 – 100.0%  Backslash escapes
    1 of    1 – 100.0%  Blank lines
-  23 of   25 –  92.0%  Block quotes
+  25 of   25 – 100.0%  Block quotes
   22 of   22 – 100.0%  Code spans
  130 of  131 –  99.2%  Emphasis and strong emphasis
   15 of   17 –  88.2%  Entity and numeric character references
@@ -24,5 +24,5 @@
   11 of   11 – 100.0%  Tabs
    3 of    3 – 100.0%  Textual content
   19 of   19 – 100.0%  Thematic breaks
- 624 of  652 –  95.7%  TOTAL
- 571 of  624 –  91.5%  TOTAL Strict
+ 626 of  652 –  96.0%  TOTAL
+ 573 of  626 –  91.5%  TOTAL Strict
diff --git a/pkgs/markdown/tool/gfm_stats.json b/pkgs/markdown/tool/gfm_stats.json
index 01e91ab..ff4d34a 100644
--- a/pkgs/markdown/tool/gfm_stats.json
+++ b/pkgs/markdown/tool/gfm_stats.json
@@ -81,7 +81,7 @@
   "212": "strict",
   "213": "strict",
   "214": "strict",
-  "215": "fail",
+  "215": "strict",
   "216": "strict",
   "217": "strict",
   "218": "strict",
@@ -93,7 +93,7 @@
   "224": "strict",
   "225": "strict",
   "226": "strict",
-  "227": "fail",
+  "227": "strict",
   "228": "strict",
   "229": "strict",
   "230": "strict"
diff --git a/pkgs/markdown/tool/gfm_stats.txt b/pkgs/markdown/tool/gfm_stats.txt
index eff6bbc..5cb3981 100644
--- a/pkgs/markdown/tool/gfm_stats.txt
+++ b/pkgs/markdown/tool/gfm_stats.txt
@@ -3,7 +3,7 @@
   11 of   11 – 100.0%  Autolinks (extension)
   13 of   13 – 100.0%  Backslash escapes
    1 of    1 – 100.0%  Blank lines
-  23 of   25 –  92.0%  Block quotes
+  25 of   25 – 100.0%  Block quotes
   22 of   22 – 100.0%  Code spans
    0 of    1 –   0.0%  Disallowed Raw HTML (extension)
  130 of  131 –  99.2%  Emphasis and strong emphasis
@@ -28,5 +28,5 @@
   11 of   11 – 100.0%  Tabs
    3 of    3 – 100.0%  Textual content
   19 of   19 – 100.0%  Thematic breaks
- 642 of  671 –  95.7%  TOTAL
- 587 of  642 –  91.4%  TOTAL Strict
+ 644 of  671 –  96.0%  TOTAL
+ 589 of  644 –  91.5%  TOTAL Strict