From be922cecdd825350421be969777f7052c4cbc9e9 Mon Sep 17 00:00:00 2001 From: Tom Theisen Date: Mon, 30 Apr 2018 20:11:01 -0700 Subject: [PATCH 1/2] GFM table compliance --- lib/marked.js | 101 +++++++++++++++++++---------------- test/new/gfm_tables.html | 12 ++--- test/specs/gfm/gfm-spec.js | 2 +- test/specs/gfm/gfm.0.28.json | 2 +- 4 files changed, 64 insertions(+), 53 deletions(-) diff --git a/lib/marked.js b/lib/marked.js index 55b06b4aff..759b903956 100644 --- a/lib/marked.js +++ b/lib/marked.js @@ -107,8 +107,8 @@ block.gfm.paragraph = edit(block.paragraph) */ block.tables = merge({}, block.gfm, { - nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/, - table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/ + nptable: /^ *([^|\n ].*\|.*)\n *([-:]+ *\|[-| :]*)(?:\n((?:.*[^>\n ].*(?:\n|$))*)\n*|$)/, + table: /^ *\|(.+)\n *\|?( *[-:]+[-| :]*)(?:\n((?: *[^>\n ].*(?:\n|$))*)\n*|$)/ }); /** @@ -245,34 +245,36 @@ Lexer.prototype.token = function(src, top) { // table no leading pipe (gfm) if (top && (cap = this.rules.nptable.exec(src))) { - src = src.substring(cap[0].length); - item = { type: 'table', header: splitCells(cap[1].replace(/^ *| *\| *$/g, '')), align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), - cells: cap[3].replace(/\n$/, '').split('\n') + cells: cap[3] ? cap[3].replace(/\n$/, '').split('\n') : [] }; - for (i = 0; i < item.align.length; i++) { - if (/^ *-+: *$/.test(item.align[i])) { - item.align[i] = 'right'; - } else if (/^ *:-+: *$/.test(item.align[i])) { - item.align[i] = 'center'; - } else if (/^ *:-+ *$/.test(item.align[i])) { - item.align[i] = 'left'; - } else { - item.align[i] = null; + if (item.header.length === item.align.length) { + src = src.substring(cap[0].length); + + for (i = 0; i < item.align.length; i++) { + if (/^ *-+: *$/.test(item.align[i])) { + item.align[i] = 'right'; + } else if (/^ *:-+: *$/.test(item.align[i])) { + item.align[i] = 'center'; + } else if (/^ *:-+ *$/.test(item.align[i])) { + item.align[i] = 'left'; + } else { + item.align[i] = null; + } } + + for (i = 0; i < item.cells.length; i++) { + item.cells[i] = splitCells(item.cells[i], item.header.length); + } + + this.tokens.push(item); + + continue; } - - for (i = 0; i < item.cells.length; i++) { - item.cells[i] = splitCells(item.cells[i]); - } - - this.tokens.push(item); - - continue; } // hr @@ -412,35 +414,38 @@ Lexer.prototype.token = function(src, top) { // table (gfm) if (top && (cap = this.rules.table.exec(src))) { - src = src.substring(cap[0].length); - item = { type: 'table', header: splitCells(cap[1].replace(/^ *| *\| *$/g, '')), align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), - cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n') + cells: cap[3] ? cap[3].replace(/(?: *\| *)?\n$/, '').split('\n') : [] }; - for (i = 0; i < item.align.length; i++) { - if (/^ *-+: *$/.test(item.align[i])) { - item.align[i] = 'right'; - } else if (/^ *:-+: *$/.test(item.align[i])) { - item.align[i] = 'center'; - } else if (/^ *:-+ *$/.test(item.align[i])) { - item.align[i] = 'left'; - } else { - item.align[i] = null; + if (item.header.length === item.align.length) { + src = src.substring(cap[0].length); + + for (i = 0; i < item.align.length; i++) { + if (/^ *-+: *$/.test(item.align[i])) { + item.align[i] = 'right'; + } else if (/^ *:-+: *$/.test(item.align[i])) { + item.align[i] = 'center'; + } else if (/^ *:-+ *$/.test(item.align[i])) { + item.align[i] = 'left'; + } else { + item.align[i] = null; + } } - } - for (i = 0; i < item.cells.length; i++) { - item.cells[i] = splitCells( - item.cells[i].replace(/^ *\| *| *\| *$/g, '')); - } + for (i = 0; i < item.cells.length; i++) { + item.cells[i] = splitCells( + item.cells[i].replace(/^ *\| *| *\| *$/g, ''), + item.header.length); + } - this.tokens.push(item); + this.tokens.push(item); - continue; + continue; + } } // lheading @@ -927,13 +932,13 @@ Renderer.prototype.paragraph = function(text) { }; Renderer.prototype.table = function(header, body) { + if (body) body = '' + body + ''; + return '\n' + '\n' + header + '\n' - + '\n' + body - + '\n' + '
\n'; }; @@ -944,7 +949,7 @@ Renderer.prototype.tablerow = function(content) { Renderer.prototype.tablecell = function(content, flags) { var type = flags.header ? 'th' : 'td'; var tag = flags.align - ? '<' + type + ' style="text-align:' + flags.align + '">' + ? '<' + type + ' align="' + flags.align + '">' : '<' + type + '>'; return tag + content + '\n'; }; @@ -1310,10 +1315,16 @@ function merge(obj) { return obj; } -function splitCells(tableRow) { +function splitCells(tableRow, count) { var cells = tableRow.replace(/([^\\])\|/g, '$1 |').split(/ +\| */), i = 0; + if (cells.length > count) { + cells.splice(count); + } else { + while (cells.length < count) cells.push(""); + } + for (; i < cells.length; i++) { cells[i] = cells[i].replace(/\\\|/g, '|'); } diff --git a/test/new/gfm_tables.html b/test/new/gfm_tables.html index 70bec827e3..1c596573c9 100644 --- a/test/new/gfm_tables.html +++ b/test/new/gfm_tables.html @@ -9,11 +9,11 @@ - + - - + +
Header 1Header 2Header 3Header 4
Header 1Header 2Header 3Header 4
Cell 1Cell 2Cell 3Cell 4
Cell 5Cell 6Cell 7Cell 8
Cell 1Cell 2Cell 3Cell 4
Cell 5Cell 6Cell 7Cell 8
Test code
@@ -28,10 +28,10 @@ - + - - + +
Header 1Header 2Header 3Header 4
Header 1Header 2Header 3Header 4
Cell 1Cell 2Cell 3Cell 4
Cell 5Cell 6Cell 7Cell 8
Cell 1Cell 2Cell 3Cell 4
Cell 5Cell 6Cell 7Cell 8
diff --git a/test/specs/gfm/gfm-spec.js b/test/specs/gfm/gfm-spec.js index 3589a5f3e5..bf768bda8c 100644 --- a/test/specs/gfm/gfm-spec.js +++ b/test/specs/gfm/gfm-spec.js @@ -28,7 +28,7 @@ var messenger = new Messenger(); describe('GFM 0.28 Tables', function() { var section = 'Tables'; - var shouldPassButFails = [192, 195, 196, 197]; + var shouldPassButFails = []; var willNotBeAttemptedByCoreTeam = []; diff --git a/test/specs/gfm/gfm.0.28.json b/test/specs/gfm/gfm.0.28.json index 87d12d35ee..d045f8af62 100644 --- a/test/specs/gfm/gfm.0.28.json +++ b/test/specs/gfm/gfm.0.28.json @@ -45,7 +45,7 @@ "section": "Tables", "html": "\n\n\n\n\n\n
abcdef
", "markdown": "| abc | def |\n| --- | --- |", - "example": 197 + "example": 198 }, { "section": "Task list items", From b78deebfcf4420427832acd749e8ebecf67c8778 Mon Sep 17 00:00:00 2001 From: Tom Theisen Date: Mon, 30 Apr 2018 20:11:43 -0700 Subject: [PATCH 2/2] lint --- lib/marked.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/marked.js b/lib/marked.js index 759b903956..05be0b5dfc 100644 --- a/lib/marked.js +++ b/lib/marked.js @@ -266,13 +266,13 @@ Lexer.prototype.token = function(src, top) { item.align[i] = null; } } - + for (i = 0; i < item.cells.length; i++) { item.cells[i] = splitCells(item.cells[i], item.header.length); } - + this.tokens.push(item); - + continue; } } @@ -932,7 +932,7 @@ Renderer.prototype.paragraph = function(text) { }; Renderer.prototype.table = function(header, body) { - if (body) body = '' + body + ''; + if (body) body = '' + body + ''; return '\n' + '\n' @@ -1322,7 +1322,7 @@ function splitCells(tableRow, count) { if (cells.length > count) { cells.splice(count); } else { - while (cells.length < count) cells.push(""); + while (cells.length < count) cells.push(''); } for (; i < cells.length; i++) {