Improve GFM Table support (#205)
diff --git a/lib/src/block_parser.dart b/lib/src/block_parser.dart
index 25d74f8..e41770a 100644
--- a/lib/src/block_parser.dart
+++ b/lib/src/block_parser.dart
@@ -793,18 +793,35 @@
/// * many body rows of body cells (`<td>` cells)
Node parse(BlockParser parser) {
var alignments = parseAlignments(parser.next);
- var head = new Element('thead', [parseRow(parser, alignments, 'th')]);
+ var columnCount = alignments.length;
+ var headRow = parseRow(parser, alignments, 'th');
+ if (headRow.children.length != columnCount) {
+ return null;
+ }
+ var head = new Element('thead', [headRow]);
// Advance past the divider of hyphens.
parser.advance();
var rows = <Element>[];
- while (!parser.isDone && !parser.matches(_emptyPattern)) {
- rows.add(parseRow(parser, alignments, 'td'));
+ while (!parser.isDone && !BlockSyntax.isAtBlockEnd(parser)) {
+ var row = parseRow(parser, alignments, 'td');
+ while (row.children.length < columnCount) {
+ // Insert synthetic empty cells.
+ row.children.add(new Element.empty('td'));
+ }
+ while (row.children.length > columnCount) {
+ row.children.removeLast();
+ }
+ rows.add(row);
}
- var body = new Element('tbody', rows);
+ if (rows.isEmpty) {
+ return new Element('table', [head]);
+ } else {
+ var body = new Element('tbody', rows);
- return new Element('table', [head, body]);
+ return new Element('table', [head, body]);
+ }
}
List<String> parseAlignments(String line) {
diff --git a/test/extensions/tables.unit b/test/extensions/tables.unit
index 9abc3c6..ab069b4 100644
--- a/test/extensions/tables.unit
+++ b/test/extensions/tables.unit
@@ -35,10 +35,10 @@
<table><thead><tr><th>head <code>code</code></th><th><em>cells</em></th></tr></thead><tbody><tr><td><em>text</em></td><td><span>text</span></td></tr></tbody></table>
>>> cells are parsed before inline syntax
header | _foo | bar_
--------|------------
+-------|------------|---
text | text
<<<
-<table><thead><tr><th>header</th><th>_foo</th><th>bar_</th></tr></thead><tbody><tr><td>text</td><td>text</td></tr></tbody></table>
+<table><thead><tr><th>header</th><th>_foo</th><th>bar_</th></tr></thead><tbody><tr><td>text</td><td>text</td><td /></tr></tbody></table>
>>> cells contain reference links
header | header
-------|--------
@@ -49,17 +49,17 @@
<table><thead><tr><th>header</th><th>header</th></tr></thead><tbody><tr><td>text</td><td><a href="http://url">link</a></td></tr></tbody></table>
>>> one column tables
head
------|-----
+-----|
body
<<<
<table><thead><tr><th>head</th></tr></thead><tbody><tr><td>body</td></tr></tbody></table>
>>> varying cells per row
head | foo | bar
------|-----
+-----|-----|-----
body
row with | two cells
<<<
-<table><thead><tr><th>head</th><th>foo</th><th>bar</th></tr></thead><tbody><tr><td>body</td></tr><tr><td>row with</td><td>two cells</td></tr></tbody></table>
+<table><thead><tr><th>head</th><th>foo</th><th>bar</th></tr></thead><tbody><tr><td>body</td><td /><td /></tr><tr><td>row with</td><td>two cells</td><td /></tr></tbody></table>
>>> left, center, and right alignment
head | cells | here
:----|:-----:|----:
@@ -67,7 +67,7 @@
too | many | cells | here
<<<
-<table><thead><tr><th style="text-align: left;">head</th><th style="text-align: center;">cells</th><th style="text-align: right;">here</th></tr></thead><tbody><tr><td style="text-align: left;">body</td><td style="text-align: center;">cells</td><td style="text-align: right;">here</td></tr><tr><td style="text-align: left;">too</td><td style="text-align: center;">many</td><td style="text-align: right;">cells</td><td>here</td></tr></tbody></table>
+<table><thead><tr><th style="text-align: left;">head</th><th style="text-align: center;">cells</th><th style="text-align: right;">here</th></tr></thead><tbody><tr><td style="text-align: left;">body</td><td style="text-align: center;">cells</td><td style="text-align: right;">here</td></tr><tr><td style="text-align: left;">too</td><td style="text-align: center;">many</td><td style="text-align: right;">cells</td></tr></tbody></table>
>>> left, center, and right alignment, with whitespace
head | cells | here
:-- | :---: | ---:
@@ -75,7 +75,7 @@
too | many | cells | here
<<<
-<table><thead><tr><th style="text-align: left;">head</th><th style="text-align: center;">cells</th><th style="text-align: right;">here</th></tr></thead><tbody><tr><td style="text-align: left;">body</td><td style="text-align: center;">cells</td><td style="text-align: right;">here</td></tr><tr><td style="text-align: left;">too</td><td style="text-align: center;">many</td><td style="text-align: right;">cells</td><td>here</td></tr></tbody></table>
+<table><thead><tr><th style="text-align: left;">head</th><th style="text-align: center;">cells</th><th style="text-align: right;">here</th></tr></thead><tbody><tr><td style="text-align: left;">body</td><td style="text-align: center;">cells</td><td style="text-align: right;">here</td></tr><tr><td style="text-align: left;">too</td><td style="text-align: center;">many</td><td style="text-align: right;">cells</td></tr></tbody></table>
>>> escape pipe
| Name | Character |
| --- | --- |
@@ -83,4 +83,4 @@
| Pipe | \| |
<<<
-<table><thead><tr><th>Name</th><th>Character</th></tr></thead><tbody><tr><td>Backtick</td><td>`</td></tr><tr><td>Pipe</td><td>|</td></tr></tbody></table>
\ No newline at end of file
+<table><thead><tr><th>Name</th><th>Character</th></tr></thead><tbody><tr><td>Backtick</td><td>`</td></tr><tr><td>Pipe</td><td>|</td></tr></tbody></table>
diff --git a/tool/gfm_stats.json b/tool/gfm_stats.json
index ffa7b1c..e1f9f43 100644
--- a/tool/gfm_stats.json
+++ b/tool/gfm_stats.json
@@ -661,11 +661,11 @@
"191": "loose",
"192": "fail",
"193": "loose",
- "194": "fail",
- "195": "fail",
- "196": "fail",
- "197": "fail",
- "198": "fail"
+ "194": "loose",
+ "195": "loose",
+ "196": "loose",
+ "197": "loose",
+ "198": "loose"
},
"Tabs": {
"1": "strict",
diff --git a/tool/gfm_stats.txt b/tool/gfm_stats.txt
index 0c472ca..68fd77e 100644
--- a/tool/gfm_stats.txt
+++ b/tool/gfm_stats.txt
@@ -24,8 +24,8 @@
25 of 26 – 96.2% Setext headings
2 of 2 – 100.0% Soft line breaks
3 of 3 – 100.0% Strikethrough (extension)
- 2 of 8 – 25.0% Tables (extension)
+ 7 of 8 – 87.5% Tables (extension)
11 of 11 – 100.0% Tabs
3 of 3 – 100.0% Textual content
19 of 19 – 100.0% Thematic breaks
- 566 of 647 – 87.5% TOTAL
+ 571 of 647 – 88.3% TOTAL