Fix various list bugs (dart-lang/markdown#102)

* Fix various list bugs
* Update CommonMark status; not worrying about Tabs
diff --git a/pkgs/markdown/lib/src/block_parser.dart b/pkgs/markdown/lib/src/block_parser.dart
index bc53d03..6635271 100644
--- a/pkgs/markdown/lib/src/block_parser.dart
+++ b/pkgs/markdown/lib/src/block_parser.dart
@@ -37,11 +37,16 @@
 /// A line starting with one of these markers: `-`, `*`, `+`. May have up to
 /// three leading spaces before the marker and any number of spaces or tabs
 /// after.
-final _ulPattern = new RegExp(r'^[ ]{0,3}[*+-][ \t]+(.*)$');
+///
+/// Contains a dummy group at [2], so that the groups in [_ulPattern] and
+/// [_olPattern] match up; in both, [2] is the length of the number that begins
+/// the list marker.
+final _ulPattern = new RegExp(r'^([ ]{0,3})()([*+-])(([ \t])([ \t]*)(.*))?$');
 
 /// A line starting with a number like `123.`. May have up to three leading
 /// spaces before the marker and any number of spaces or tabs after.
-final _olPattern = new RegExp(r'^[ ]{0,3}\d+\.[ \t]+(.*)$');
+final _olPattern =
+    new RegExp(r'^([ ]{0,3})(\d{1,9})([\.)])(([ \t])([ \t]*)(.*))?$');
 
 /// Maintains the internal state needed to parse a series of lines into blocks
 /// of Markdown suitable for further inline parsing.
@@ -569,17 +574,58 @@
       return match != null;
     }
 
+    var listMarker = null;
+    var indent;
+
     while (!parser.isDone) {
       if (tryMatch(_emptyPattern)) {
+        if (_emptyPattern.firstMatch(parser.next ?? '') != null) {
+          // Two blank lines ends a list.
+          break;
+        }
         // Add a blank line to the current list item.
         childLines.add('');
+      } else if (indent != null && parser.current.startsWith(indent)) {
+        // Strip off indent and add to current item.
+        var line = parser.current.replaceFirst(indent, '');
+        childLines.add(line);
       } else if (tryMatch(_ulPattern) || tryMatch(_olPattern)) {
+        var precedingWhitespace = match[1];
+        var digits = match[2] ?? '';
+        var marker = match[3];
+        var isBlank = match[4] == null;
+        var firstWhitespace = match[5] ?? '';
+        var restWhitespace = match[6] ?? '';
+        var content = match[7] ?? '';
+        if (listMarker != null && listMarker != marker) {
+          // Changing the bullet or ordered list delimiter starts a new list.
+          break;
+        }
+        listMarker = marker;
+        var markerAsSpaces = ' ' * (digits.length + marker.length);
+        if (isBlank) {
+          // See http://spec.commonmark.org/0.25/#list-items under "3. Item
+          // starting with a blank line."
+          //
+          // If the list item starts with a blank line, the final piece of the
+          // indentation is just a single space.
+          indent = precedingWhitespace + markerAsSpaces + ' ';
+        } else if (match[5].length >= 4) {
+          // See http://spec.commonmark.org/0.25/#list-items under "2. Item
+          // starting with indented code."
+          //
+          // If the list item starts with indented code, we need to _not_ count
+          // any indentation past the required whitespace character.
+          indent = precedingWhitespace + markerAsSpaces + firstWhitespace;
+        } else {
+          indent = precedingWhitespace +
+              markerAsSpaces +
+              firstWhitespace +
+              restWhitespace;
+        }
         // End the current list item and start a new one.
         endItem();
-        childLines.add(match[1]);
-      } else if (tryMatch(_indentPattern)) {
-        // Strip off indent and add to current item.
-        childLines.add(match[1]);
+        childLines.add(restWhitespace + content);
       } else if (BlockSyntax.isAtBlockEnd(parser)) {
         // Done with the list.
         break;
@@ -637,7 +683,8 @@
   bool removeTrailingEmptyLines(List items) {
     var anyEmpty = false;
     for (var i = 0; i < items.length; i++) {
-      while (_emptyPattern.hasMatch(items[i].lines.last)) {
+      while (items[i].lines.isNotEmpty &&
+          _emptyPattern.hasMatch(items[i].lines.last)) {
         if (i < items.length - 1) {
           anyEmpty = true;
         }
diff --git a/pkgs/markdown/test/original/ordered_lists.unit b/pkgs/markdown/test/original/ordered_lists.unit
index 277dba9..7c52652 100644
--- a/pkgs/markdown/test/original/ordered_lists.unit
+++ b/pkgs/markdown/test/original/ordered_lists.unit
@@ -1,13 +1,27 @@
->>> start with numbers
-1. one
+>>> ordered list with multiple items
+1.  one
+2.  two
+10. ten
+<<<
+<ol><li> one</li><li> two</li><li>ten</li></ol>
+>>> ordered list with almost nested item
+1.  one
 45.  two
    12345. three
 
 <<<
-<ol><li>one</li><li>two</li><li>three</li></ol>
->>> allow unordered lines after first
+<ol><li> one</li><li> two</li><li>three</li></ol>
+>>> nested ordered lists
+1. one
+2. two
+   3. three
+   4. four
+5. five
+<<<
+<ol><li>one</li><li>two<ol><li>three</li><li>four</li></ol></li><li>five</li></ol>
+>>> new list markers start new lists
 1. a
 * b
 
 <<<
-<ol><li>a</li><li>b</li></ol>
+<ol><li>a</li></ol><ul><li>b</li></ul>
diff --git a/pkgs/markdown/test/original/setext_headers.unit b/pkgs/markdown/test/original/setext_headers.unit
index 65038f0..7e34d9d 100644
--- a/pkgs/markdown/test/original/setext_headers.unit
+++ b/pkgs/markdown/test/original/setext_headers.unit
@@ -10,13 +10,13 @@
 
 <<<
 <h2>text</h2>
->>> h1 on first line becomes text
+>>> h1 bar on first line becomes text
 ===
 
 <<<
 <p>===</p>
->>> h2 on first line becomes text
+>>> h2 bar on first line becomes list
 -
 
 <<<
-<p>-</p>
+<ul><li></li></ul>
diff --git a/pkgs/markdown/test/original/unordered_lists.unit b/pkgs/markdown/test/original/unordered_lists.unit
index 4729287..44ab70e 100644
--- a/pkgs/markdown/test/original/unordered_lists.unit
+++ b/pkgs/markdown/test/original/unordered_lists.unit
@@ -4,21 +4,19 @@
 + plus
 
 <<<
-<ul><li>star</li><li>dash</li><li>plus</li></ul>
->>> allow numbered lines after first
+<ul><li>star</li></ul><ul><li>dash</li></ul><ul><li>plus</li></ul>
+>>> new markers begin new lists
 * a
 1. b
 
 <<<
-<ul><li>a</li><li>b</li></ul>
+<ul><li>a</li></ul><ol><li>b</li></ol>
 >>> allow a tab after the marker
-* a
-+ b
-- c
-1.  d
+*	a
+1.	b
 
 <<<
-<ul><li>a</li><li>b</li><li>c</li><li>d</li></ul>
+<ul><li>a</li></ul><ol><li>b</li></ol>
 >>> wrap items in paragraphs if blank lines separate
 * one
 
@@ -29,10 +27,10 @@
 <p>one</p></li><li>
 <p>two</p></li></ul>
 >>> force paragraph on item before and after blank lines
-*   one
-*   two
+* one
+* two
 
-*   three
+* three
 
 <<<
 <ul><li>
@@ -50,11 +48,11 @@
 <p>quote</p></blockquote></li><li>
 <h1>header</h1></li></ul>
 >>> can contain multiple paragraphs
-*   one
+* one
 
-    two
+  two
 
-*   three
+* three
 
 <<<
 <ul><li>
@@ -62,19 +60,19 @@
 <p>two</p></li><li>
 <p>three</p></li></ul>
 >>> can span newlines
-*   one
-    two
-*   three
+* one
+  two
+* three
 
 <<<
 <ul><li>one
 two</li><li>three</li></ul>
 >>> can nest lists
-*   one
-    * nested one
-    * nested two
+* one
+  * nested one
+  * nested two
 
-*   two
+* two
 
 <<<
 <ul><li>
diff --git a/pkgs/markdown/tool/common_mark_stats.json b/pkgs/markdown/tool/common_mark_stats.json
index c07aa12..7eea678 100644
--- a/pkgs/markdown/tool/common_mark_stats.json
+++ b/pkgs/markdown/tool/common_mark_stats.json
@@ -120,7 +120,7 @@
   "338": true,
   "339": true,
   "340": false,
-  "341": false,
+  "341": true,
   "342": false,
   "343": false,
   "344": true,
@@ -491,35 +491,35 @@
   "213": true,
   "214": true,
   "215": true,
-  "216": false,
-  "217": false,
+  "216": true,
+  "217": true,
   "218": true,
   "219": true,
   "220": true,
   "221": true,
   "222": false,
   "223": true,
-  "224": false,
-  "225": false,
+  "224": true,
+  "225": true,
   "226": false,
-  "227": false,
+  "227": true,
   "228": false,
   "229": false,
   "230": true,
-  "231": false,
+  "231": true,
   "232": false,
   "233": true,
   "234": false,
   "235": false,
   "236": true,
   "237": true,
-  "238": false,
+  "238": true,
   "239": false,
   "240": false,
   "241": false,
   "242": false,
   "243": false,
-  "244": false,
+  "244": true,
   "245": true,
   "246": true,
   "247": true,
@@ -528,39 +528,39 @@
   "250": true,
   "251": true,
   "252": true,
-  "253": false,
+  "253": true,
   "254": true,
   "255": false,
   "256": false,
   "257": true,
   "258": false,
-  "259": false
+  "259": true
  },
  "Lists": {
-  "260": false,
+  "260": true,
   "261": false,
   "262": true,
   "263": false,
-  "264": false,
+  "264": true,
   "265": true,
-  "266": false,
-  "267": false,
-  "268": false,
+  "266": true,
+  "267": true,
+  "268": true,
   "269": false,
   "270": false,
   "271": true,
-  "272": false,
-  "273": false,
-  "274": true,
+  "272": true,
+  "273": true,
+  "274": false,
   "275": false,
-  "276": false,
-  "277": false,
-  "278": false,
+  "276": true,
+  "277": true,
+  "278": true,
   "279": true,
-  "280": false,
-  "281": false,
+  "280": true,
+  "281": true,
   "282": false,
-  "283": false
+  "283": true
  },
  "Paragraphs": {
   "179": true,
@@ -634,10 +634,10 @@
   "1": true,
   "2": false,
   "3": true,
-  "4": true,
-  "5": true,
+  "4": false,
+  "5": false,
   "6": true,
-  "7": false,
+  "7": true,
   "8": true,
   "9": false
  },
diff --git a/pkgs/markdown/tool/common_mark_stats.txt b/pkgs/markdown/tool/common_mark_stats.txt
index 0c10a61..37235da 100644
--- a/pkgs/markdown/tool/common_mark_stats.txt
+++ b/pkgs/markdown/tool/common_mark_stats.txt
@@ -4,7 +4,7 @@
    1 of    1 – 100.0%  Blank lines
   22 of   25 –  88.0%  Block quotes
   13 of   15 –  86.7%  Code spans
-  81 of  129 –  62.8%  Emphasis and strong emphasis
+  82 of  129 –  63.6%  Emphasis and strong emphasis
   10 of   12 –  83.3%  Entity and numeric character references
   24 of   27 –  88.9%  Fenced code blocks
   15 of   15 – 100.0%  Hard line breaks
@@ -14,14 +14,14 @@
    1 of    1 – 100.0%  Inlines
   11 of   23 –  47.8%  Link reference definitions
   52 of   81 –  64.2%  Links
-  22 of   47 –  46.8%  List items
-   5 of   24 –  20.8%  Lists
+  32 of   47 –  68.1%  List items
+  17 of   24 –  70.8%  Lists
    8 of    8 – 100.0%  Paragraphs
    1 of    1 – 100.0%  Precedence
   15 of   21 –  71.4%  Raw HTML
   20 of   26 –  76.9%  Setext headings
    2 of    2 – 100.0%  Soft line breaks
-   6 of    9 –  66.7%  Tabs
+   5 of    9 –  55.6%  Tabs
    3 of    3 – 100.0%  Textual content
   17 of   19 –  89.5%  Thematic breaks
- 427 of  616 –  69.3%  TOTAL
+ 449 of  616 –  72.9%  TOTAL