Better list item parsing
diff --git a/pkgs/markdown/lib/src/block_parser.dart b/pkgs/markdown/lib/src/block_parser.dart index c26056a..a809947 100644 --- a/pkgs/markdown/lib/src/block_parser.dart +++ b/pkgs/markdown/lib/src/block_parser.dart
@@ -575,6 +575,9 @@ var listMarker = null; var indent; + // In case the first number in an ordered list is not 1, use it as the + // "start". + var startNumber; while (!parser.isDone) { if (tryMatch(_emptyPattern)) { @@ -591,11 +594,14 @@ } else if (tryMatch(_ulPattern) || tryMatch(_olPattern)) { var precedingWhitespace = match[1]; var digits = match[2] ?? ''; + if (startNumber == null && digits.isNotEmpty) { + startNumber = int.parse(digits); + } var marker = match[3]; - var isBlank = match[4] == null; var firstWhitespace = match[5] ?? ''; var restWhitespace = match[6] ?? ''; var content = match[7] ?? ''; + var isBlank = content.isEmpty; if (listMarker != null && listMarker != marker) { // Changing the bullet or ordered list delimiter starts a new list. break; @@ -609,7 +615,7 @@ // 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) { + } else if (restWhitespace.length >= 4) { // See http://spec.commonmark.org/0.26/#list-items under "2. Item // starting with indented code." // @@ -631,7 +637,10 @@ } else { // If the previous item is a blank line, this means we're done with the // list and are starting a new top-level paragraph. - if ((childLines.isNotEmpty) && (childLines.last == '')) break; + if ((childLines.isNotEmpty) && (childLines.last == '')) { + parser.encounteredBlankLine = true; + break; + } // Anything else is paragraph continuation text. var continuedLine = childLines.last + parser.current; @@ -645,6 +654,7 @@ endItem(); var itemNodes = <Element>[]; + items.forEach(removeLeadingEmptyLine); var anyEmptyLines = removeTrailingEmptyLines(items); var anyEmptyLinesBetweenBlocks = false; @@ -674,7 +684,18 @@ } } - return new Element(listTag, itemNodes); + if (listTag == 'ol' && startNumber != 1) { + return new Element(listTag, itemNodes) + ..attributes['start'] = '$startNumber'; + } else { + return new Element(listTag, itemNodes); + } + } + + void removeLeadingEmptyLine(ListItem item) { + if (item.lines.isNotEmpty && _emptyPattern.hasMatch(item.lines.first)) { + item.lines.removeAt(0); + } } /// Removes any trailing empty lines and notes whether any items are separated @@ -682,6 +703,7 @@ bool removeTrailingEmptyLines(List items) { var anyEmpty = false; for (var i = 0; i < items.length; i++) { + if (items[i].lines.length == 1) continue; while (items[i].lines.isNotEmpty && _emptyPattern.hasMatch(items[i].lines.last)) { if (i < items.length - 1) {
diff --git a/pkgs/markdown/test/original/ordered_lists.unit b/pkgs/markdown/test/original/ordered_lists.unit index 7c52652..060b701 100644 --- a/pkgs/markdown/test/original/ordered_lists.unit +++ b/pkgs/markdown/test/original/ordered_lists.unit
@@ -18,7 +18,7 @@ 4. four 5. five <<< -<ol><li>one</li><li>two<ol><li>three</li><li>four</li></ol></li><li>five</li></ol> +<ol><li>one</li><li>two<ol start="3"><li>three</li><li>four</li></ol></li><li>five</li></ol> >>> new list markers start new lists 1. a * b
diff --git a/pkgs/markdown/tool/common_mark_stats.json b/pkgs/markdown/tool/common_mark_stats.json index 1f83594..9bf5b30 100644 --- a/pkgs/markdown/tool/common_mark_stats.json +++ b/pkgs/markdown/tool/common_mark_stats.json
@@ -499,25 +499,25 @@ "223": "fail", "224": "loose", "225": "fail", - "226": "fail", + "226": "loose", "227": "strict", - "228": "fail", - "229": "fail", + "228": "loose", + "229": "loose", "230": "strict", "231": "loose", - "232": "fail", + "232": "loose", "233": "strict", - "234": "fail", - "235": "fail", + "234": "loose", + "235": "loose", "236": "loose", "237": "loose", "238": "loose", - "239": "fail", - "240": "fail", + "239": "loose", + "240": "loose", "241": "fail", - "242": "fail", - "243": "fail", - "244": "fail", + "242": "loose", + "243": "loose", + "244": "loose", "245": "loose", "246": "fail", "247": "loose", @@ -530,15 +530,15 @@ "254": "loose", "255": "loose", "256": "loose", - "257": "fail", - "258": "fail", + "257": "loose", + "258": "loose", "259": "loose", - "260": "fail", + "260": "loose", "261": "loose" }, "Lists": { "262": "loose", - "263": "fail", + "263": "loose", "264": "loose", "265": "fail", "266": "loose", @@ -559,7 +559,7 @@ "281": "loose", "282": "loose", "283": "loose", - "284": "fail", + "284": "loose", "285": "loose" }, "Paragraphs": {
diff --git a/pkgs/markdown/tool/common_mark_stats.txt b/pkgs/markdown/tool/common_mark_stats.txt index c638008..14d9d68 100644 --- a/pkgs/markdown/tool/common_mark_stats.txt +++ b/pkgs/markdown/tool/common_mark_stats.txt
@@ -14,8 +14,8 @@ 1 of 1 – 100.0% Inlines 20 of 23 – 87.0% Link reference definitions 53 of 81 – 65.4% Links - 30 of 48 – 62.5% List items - 16 of 24 – 66.7% Lists + 44 of 48 – 91.7% List items + 18 of 24 – 75.0% Lists 8 of 8 – 100.0% Paragraphs 1 of 1 – 100.0% Precedence 15 of 21 – 71.4% Raw HTML @@ -24,4 +24,4 @@ 6 of 11 – 54.5% Tabs 3 of 3 – 100.0% Textual content 17 of 19 – 89.5% Thematic breaks - 468 of 618 – 75.7% TOTAL + 484 of 618 – 78.3% TOTAL