From a7a605161d2decd59cb6588af68da08e5c1f1611 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Fri, 2 Jul 2021 17:02:12 -0400 Subject: [PATCH 1/2] Remove nptable tokenizer nptable is 95% identical to table, except for handling a weird special case. Special case now handled in splitCells() --- src/Lexer.js | 7 ------ src/Tokenizer.js | 43 +++------------------------------ src/helpers.js | 4 +++ test/specs/new/table_cells.html | 2 +- 4 files changed, 8 insertions(+), 48 deletions(-) diff --git a/src/Lexer.js b/src/Lexer.js index 9686e4624c..5ddea67d42 100644 --- a/src/Lexer.js +++ b/src/Lexer.js @@ -176,13 +176,6 @@ module.exports = class Lexer { continue; } - // table no leading pipe (gfm) - if (token = this.tokenizer.nptable(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } - // hr if (token = this.tokenizer.hr(src)) { src = src.substring(token.raw.length); diff --git a/src/Tokenizer.js b/src/Tokenizer.js index 0177551af7..30b31dc39b 100644 --- a/src/Tokenizer.js +++ b/src/Tokenizer.js @@ -134,42 +134,6 @@ module.exports = class Tokenizer { } } - nptable(src) { - const cap = this.rules.block.nptable.exec(src); - if (cap) { - const item = { - type: 'table', - header: splitCells(cap[1].replace(/^ *| *\| *$/g, '')), - align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), - cells: cap[3] ? cap[3].replace(/\n$/, '').split('\n') : [], - raw: cap[0] - }; - - if (item.header.length === item.align.length) { - let l = item.align.length; - let i; - for (i = 0; i < l; 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; - } - } - - l = item.cells.length; - for (i = 0; i < l; i++) { - item.cells[i] = splitCells(item.cells[i], item.header.length); - } - - return item; - } - } - } - hr(src) { const cap = this.rules.block.hr.exec(src); if (cap) { @@ -357,7 +321,8 @@ module.exports = class Tokenizer { } table(src) { - const cap = this.rules.block.table.exec(src); + const cap = this.rules.block.table.exec(src) + || this.rules.block.nptable.exec(src); if (cap) { const item = { type: 'table', @@ -385,9 +350,7 @@ module.exports = class Tokenizer { l = item.cells.length; for (i = 0; i < l; i++) { - item.cells[i] = splitCells( - item.cells[i].replace(/^ *\| *| *\| *$/g, ''), - item.header.length); + item.cells[i] = splitCells(item.cells[i], item.header.length); } return item; diff --git a/src/helpers.js b/src/helpers.js index 93c75a1b2e..e0b48d74ea 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -160,6 +160,10 @@ function splitCells(tableRow, count) { cells = row.split(/ \|/); let i = 0; + // First/last cell in a row cannot be empty if it has no leading/trailing pipe + if (!cells[0].trim()) { cells.shift(); } + if (!cells[cells.length - 1].trim()) { cells.pop(); } + if (cells.length > count) { cells.splice(count); } else { diff --git a/test/specs/new/table_cells.html b/test/specs/new/table_cells.html index 694f7dddea..5b35bcc3cb 100644 --- a/test/specs/new/table_cells.html +++ b/test/specs/new/table_cells.html @@ -16,7 +16,7 @@
12
1|\2|\
-
12
2
+
12
2
12
12|
From 79cde34ec94f9fcafd2626558c6f56a1f0b40fa5 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Fri, 2 Jul 2021 22:34:39 -0400 Subject: [PATCH 2/2] Remove rules.js for nptable --- src/Tokenizer.js | 3 +-- src/rules.js | 19 ++----------------- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/Tokenizer.js b/src/Tokenizer.js index 30b31dc39b..29ac3d4e14 100644 --- a/src/Tokenizer.js +++ b/src/Tokenizer.js @@ -321,8 +321,7 @@ module.exports = class Tokenizer { } table(src) { - const cap = this.rules.block.table.exec(src) - || this.rules.block.nptable.exec(src); + const cap = this.rules.block.table.exec(src); if (cap) { const item = { type: 'table', diff --git a/src/rules.js b/src/rules.js index 58751f0770..13961f2251 100644 --- a/src/rules.js +++ b/src/rules.js @@ -26,7 +26,6 @@ const block = { + '|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag + ')', def: /^ {0,3}\[(label)\]: *\n? *]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/, - nptable: noopTest, table: noopTest, lheading: /^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/, // regex template, placeholders will be replaced according to different paragraph @@ -97,25 +96,11 @@ block.normal = merge({}, block); */ block.gfm = merge({}, block.normal, { - nptable: '^ *([^|\\n ].*\\|.*)\\n' // Header - + ' {0,3}([-:]+ *\\|[-| :]*)' // Align - + '(?:\\n((?:(?!\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)', // Cells - table: '^ *\\|(.+)\\n' // Header - + ' {0,3}\\|?( *[-:]+[-| :]*)' // Align + table: '^ *([^\\n ].*\\|.*)\\n' // Header + + ' {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)\\|?' // Align + '(?:\\n *((?:(?!\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)' // Cells }); -block.gfm.nptable = edit(block.gfm.nptable) - .replace('hr', block.hr) - .replace('heading', ' {0,3}#{1,6} ') - .replace('blockquote', ' {0,3}>') - .replace('code', ' {4}[^\\n]') - .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n') - .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt - .replace('html', ')|<(?:script|pre|style|textarea|!--)') - .replace('tag', block._tag) // tables can be interrupted by type (6) html blocks - .getRegex(); - block.gfm.table = edit(block.gfm.table) .replace('hr', block.hr) .replace('heading', ' {0,3}#{1,6} ')