From 39c6687c19e1c100ab2d4bfc896e71e27ca91502 Mon Sep 17 00:00:00 2001 From: Kitson Kelly Date: Fri, 24 Aug 2012 07:26:12 +0100 Subject: [PATCH 01/15] add support for Markdown Extra Tables --- lib/marked.js | 82 ++++++++++++++++++++++++++++++++++++ test/new/extra_tables.html | 38 +++++++++++++++++ test/new/extra_tables.text | 21 +++++++++ test/tests/extra_tables.html | 38 +++++++++++++++++ test/tests/extra_tables.text | 21 +++++++++ 5 files changed, 200 insertions(+) create mode 100644 test/new/extra_tables.html create mode 100644 test/new/extra_tables.text create mode 100644 test/tests/extra_tables.html create mode 100644 test/tests/extra_tables.text diff --git a/lib/marked.js b/lib/marked.js index c445c079..ac87ee59 100644 --- a/lib/marked.js +++ b/lib/marked.js @@ -20,6 +20,8 @@ var block = { list: /^( *)(bull) [^\0]+?(?:hr|\n{2,}(?! )(?!\1bull )\n*|\s*$)/, html: /^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/, def: /^ *\[([^\]]+)\]: *([^\s]+)(?: +["(]([^\n]+)[")])? *(?:\n+|$)/, + table: /^ {0,3}[|](.+)\n {0,3}[|]( *[-:]+[-| :]*)\n((?: *[|].*\n)*)\n*/, + nptable: /^ {0,3}(\S.*[|].*)\n {0,3}([-:]+ *[|][-| :]*)\n((?:.*[|].*\n)*)\n*/, paragraph: /^([^\n]+\n?(?!body))+\n*/, text: /^[^\n]+/ }; @@ -137,6 +139,44 @@ block.token = function(src, tokens, top) { continue; } + // table (extra) + if (cap = block.table.exec(src)) { + src = src.substring(cap[0].length); + tokens.push({ + type: 'table', + header: cap[1].replace(/(^ *| *[|] *$)/g, '').split(/ *[|] */), + align: cap[2].replace(/(^ *|[|] *$)/g, '').split(/ *[|] */).map(function(row){ + return row.match(/^ *-+: *$/) ? "right" + : row.match(/^ *:-+: *$/) ? "center" + : row.match(/^ *:-+ *$/) ? "left" + : false; + }), + cells: cap[3].replace(/( *[|] *)?\n$/, '').split("\n").map(function(row){ + return row.replace(/(^ *[|] *| *[|] *$)/g, '').split(/ *[|] */); + }) + }); + continue; + } + + // table no leading pipe (extra) + if (cap = block.nptable.exec(src)) { + src = src.substring(cap[0].length); + tokens.push({ + type: 'table', + header: cap[1].replace(/(^ *| *[|] *$)/g, '').split(/ *[|] */), + align: cap[2].replace(/(^ *|[|] *$)/g, '').split(/ *[|] */).map(function(row){ + return row.match(/^ *-+: *$/) ? "right" + : row.match(/^ *:-+: *$/) ? "center" + : row.match(/^ *:-+ *$/) ? "left" + : false; + }), + cells: cap[3].replace(/\n$/, '').split("\n").map(function(row){ + return row.split(/ *[|] */); + }) + }); + continue; + } + // heading if (cap = block.heading.exec(src)) { src = src.substring(cap[0].length); @@ -558,6 +598,48 @@ function tok() { + token.text + '\n'; } + case 'table': { + var thead = '\t\n\t\t'; + token.header.forEach(function(heading, i){ + heading = inline.lexer(heading); + var align = i < token.align.length ? token.align[i] : false; + switch(align){ + case "left": + case "right": + case "center": + thead += '' + heading + ''; + break; + default: + thead += '' + heading + ''; + } + }); + thead += '\n\t\n'; + + var tbody = '\t\n'; + token.cells.forEach(function(row){ + tbody += '\t\t'; + row.forEach(function(cell, i){ + cell = inline.lexer(cell); + var align = i < token.align.length ? token.align[i] : false; + switch(align){ + case "left": + case "right": + case "center": + tbody += '' + cell + ''; + break; + default: + tbody += '' + cell + ''; + } + }); + tbody += '\n'; + }); + tbody += '\t\n'; + + return '\n' + + thead + + tbody + + '
\n' + } case 'blockquote_start': { var body = ''; diff --git a/test/new/extra_tables.html b/test/new/extra_tables.html new file mode 100644 index 00000000..1dd37334 --- /dev/null +++ b/test/new/extra_tables.html @@ -0,0 +1,38 @@ + + + + + + + + +
Heading 1Heading 2
Cell 1Cell 2
Cell 3Cell 4
+ + + + + + + + +
Header 1Header 2Header 3Header 4
Cell 1Cell 2Cell 3Cell 4
Cell 5Cell 6Cell 7Cell 8
+
Test code
+ + + + + + + + +
Header 1Header 2
Cell 1Cell 2
Cell 3Cell 4
+ + + + + + + + +
Header 1Header 2Header 3Header 4
Cell 1Cell 2Cell 3Cell 4
Cell 5Cell 6Cell 7Cell 8
+ diff --git a/test/new/extra_tables.text b/test/new/extra_tables.text new file mode 100644 index 00000000..5fd6321c --- /dev/null +++ b/test/new/extra_tables.text @@ -0,0 +1,21 @@ +| Heading 1 | Heading 2 +| --------- | --------- +| Cell 1 | Cell 2 +| Cell 3 | Cell 4 + +| Header 1 | Header 2 | Header 3 | Header 4 | +| :------: | -------: | :------- | -------- | +| Cell 1 | Cell 2 | Cell 3 | Cell 4 | +| Cell 5 | Cell 6 | Cell 7 | Cell 8 | + + Test code + +Header 1 | Header 2 +-------- | -------- +Cell 1 | Cell 2 +Cell 3 | Cell 4 + +Header 1|Header 2|Header 3|Header 4 +:-------|:------:|-------:|-------- +Cell 1 |Cell 2 |Cell 3 |Cell 4 +*Cell 5*|Cell 6 |Cell 7 |Cell 8 diff --git a/test/tests/extra_tables.html b/test/tests/extra_tables.html new file mode 100644 index 00000000..1dd37334 --- /dev/null +++ b/test/tests/extra_tables.html @@ -0,0 +1,38 @@ + + + + + + + + +
Heading 1Heading 2
Cell 1Cell 2
Cell 3Cell 4
+ + + + + + + + +
Header 1Header 2Header 3Header 4
Cell 1Cell 2Cell 3Cell 4
Cell 5Cell 6Cell 7Cell 8
+
Test code
+ + + + + + + + +
Header 1Header 2
Cell 1Cell 2
Cell 3Cell 4
+ + + + + + + + +
Header 1Header 2Header 3Header 4
Cell 1Cell 2Cell 3Cell 4
Cell 5Cell 6Cell 7Cell 8
+ diff --git a/test/tests/extra_tables.text b/test/tests/extra_tables.text new file mode 100644 index 00000000..5fd6321c --- /dev/null +++ b/test/tests/extra_tables.text @@ -0,0 +1,21 @@ +| Heading 1 | Heading 2 +| --------- | --------- +| Cell 1 | Cell 2 +| Cell 3 | Cell 4 + +| Header 1 | Header 2 | Header 3 | Header 4 | +| :------: | -------: | :------- | -------- | +| Cell 1 | Cell 2 | Cell 3 | Cell 4 | +| Cell 5 | Cell 6 | Cell 7 | Cell 8 | + + Test code + +Header 1 | Header 2 +-------- | -------- +Cell 1 | Cell 2 +Cell 3 | Cell 4 + +Header 1|Header 2|Header 3|Header 4 +:-------|:------:|-------:|-------- +Cell 1 |Cell 2 |Cell 3 |Cell 4 +*Cell 5*|Cell 6 |Cell 7 |Cell 8 From ac99b517ded5d16fcc3a16656038c64464a82862 Mon Sep 17 00:00:00 2001 From: Kitson Kelly Date: Mon, 3 Sep 2012 17:28:06 +0100 Subject: [PATCH 02/15] Migrate table support as part of GFM support --- lib/marked.js | 20 +++++++++++++------ .../{extra_tables.html => gfm_tables.html} | 0 .../{extra_tables.text => gfm_tables.text} | 0 .../{extra_tables.html => gfm_tables.html} | 0 .../{extra_tables.text => gfm_tables.text} | 0 5 files changed, 14 insertions(+), 6 deletions(-) rename test/new/{extra_tables.html => gfm_tables.html} (100%) rename test/new/{extra_tables.text => gfm_tables.text} (100%) rename test/tests/{extra_tables.html => gfm_tables.html} (100%) rename test/tests/{extra_tables.text => gfm_tables.text} (100%) diff --git a/lib/marked.js b/lib/marked.js index ac87ee59..9ac7dba2 100644 --- a/lib/marked.js +++ b/lib/marked.js @@ -13,6 +13,8 @@ var block = { newline: /^\n+/, code: /^( {4}[^\n]+\n*)+/, fences: noop, + table: noop, + nptable: noop, hr: /^( *[-*_]){3,} *(?:\n+|$)/, heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/, lheading: /^([^\n]+)\n *(=|-){3,} *\n*/, @@ -20,8 +22,6 @@ var block = { list: /^( *)(bull) [^\0]+?(?:hr|\n{2,}(?! )(?!\1bull )\n*|\s*$)/, html: /^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/, def: /^ *\[([^\]]+)\]: *([^\s]+)(?: +["(]([^\n]+)[")])? *(?:\n+|$)/, - table: /^ {0,3}[|](.+)\n {0,3}[|]( *[-:]+[-| :]*)\n((?: *[|].*\n)*)\n*/, - nptable: /^ {0,3}(\S.*[|].*)\n {0,3}([-:]+ *[|][-| :]*)\n((?:.*[|].*\n)*)\n*/, paragraph: /^([^\n]+\n?(?!body))+\n*/, text: /^[^\n]+/ }; @@ -66,12 +66,16 @@ block.paragraph = (function() { block.normal = { fences: block.fences, - paragraph: block.paragraph + paragraph: block.paragraph, + table: block.table, + nptable: block.nptable }; block.gfm = { fences: /^ *(```|~~~) *(\w+)? *\n([^\0]+?)\s*\1 *(?:\n+|$)/, - paragraph: /^/ + paragraph: /^/, + table: /^ {0,3}[|](.+)\n {0,3}[|]( *[-:]+[-| :]*)\n((?: *[|].*\n)*)\n*/, + nptable: /^ {0,3}(\S.*[|].*)\n {0,3}([-:]+ *[|][-| :]*)\n((?:.*[|].*\n)*)\n*/ }; block.gfm.paragraph = replace(block.paragraph) @@ -139,7 +143,7 @@ block.token = function(src, tokens, top) { continue; } - // table (extra) + // table (gfm) if (cap = block.table.exec(src)) { src = src.substring(cap[0].length); tokens.push({ @@ -158,7 +162,7 @@ block.token = function(src, tokens, top) { continue; } - // table no leading pipe (extra) + // table no leading pipe (gfm) if (cap = block.nptable.exec(src)) { src = src.substring(cap[0].length); tokens.push({ @@ -814,11 +818,15 @@ function setOptions(opt) { if (options.gfm) { block.fences = block.gfm.fences; block.paragraph = block.gfm.paragraph; + block.table = block.gfm.table; + block.nptable = block.gfm.nptable; inline.text = inline.gfm.text; inline.url = inline.gfm.url; } else { block.fences = block.normal.fences; block.paragraph = block.normal.paragraph; + block.table = block.normal.table; + block.nptable = block.normal.table; inline.text = inline.normal.text; inline.url = inline.normal.url; } diff --git a/test/new/extra_tables.html b/test/new/gfm_tables.html similarity index 100% rename from test/new/extra_tables.html rename to test/new/gfm_tables.html diff --git a/test/new/extra_tables.text b/test/new/gfm_tables.text similarity index 100% rename from test/new/extra_tables.text rename to test/new/gfm_tables.text diff --git a/test/tests/extra_tables.html b/test/tests/gfm_tables.html similarity index 100% rename from test/tests/extra_tables.html rename to test/tests/gfm_tables.html diff --git a/test/tests/extra_tables.text b/test/tests/gfm_tables.text similarity index 100% rename from test/tests/extra_tables.text rename to test/tests/gfm_tables.text From fd9066c145cc4c7390394f319c6daafe4777c858 Mon Sep 17 00:00:00 2001 From: Kitson Kelly Date: Fri, 24 Aug 2012 07:55:49 +0100 Subject: [PATCH 03/15] add ability to escape | --- lib/marked.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/marked.js b/lib/marked.js index 9ac7dba2..f5368406 100644 --- a/lib/marked.js +++ b/lib/marked.js @@ -348,7 +348,7 @@ block.token = function(src, tokens, top) { */ var inline = { - escape: /^\\([\\`*{}\[\]()#+\-.!_>])/, + escape: /^\\([\\`*{}\[\]()#+\-.!_>|])/, autolink: /^<([^ >]+(@|:\/)[^ >]+)>/, url: noop, tag: /^|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/, From a412613f0678ad5007bc522dea915b521a41562c Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Wed, 2 Jan 2013 14:34:19 -0600 Subject: [PATCH 04/15] refactor table implementation. --- lib/marked.js | 76 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 31 deletions(-) diff --git a/lib/marked.js b/lib/marked.js index d48997c8..aa9df030 100644 --- a/lib/marked.js +++ b/lib/marked.js @@ -63,8 +63,8 @@ block.normal = { block.gfm = { fences: /^ *(`{3,}|~{3,}) *(\w+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/, paragraph: /^/, - table: /^ {0,3}[|](.+)\n {0,3}[|]( *[-:]+[-| :]*)\n((?: *[|].*\n)*)\n*/, - nptable: /^ {0,3}(\S.*[|].*)\n {0,3}([-:]+ *[|][-| :]*)\n((?:.*[|].*\n)*)\n*/ + table: /^ {0,3}\|(.+)\n {0,3}\|( *[-:]+[-| :]*)\n((?: *\|.*\n)*)\n*/, + nptable: /^ {0,3}(\S.*\|.*)\n {0,3}([-:]+ *\|[-| :]*)\n((?:.*\|.*\n)*)\n*/ }; block.gfm.paragraph = replace(block.paragraph) @@ -137,15 +137,18 @@ block.token = function(src, tokens, top) { src = src.substring(cap[0].length); tokens.push({ type: 'table', - header: cap[1].replace(/(^ *| *[|] *$)/g, '').split(/ *[|] */), - align: cap[2].replace(/(^ *|[|] *$)/g, '').split(/ *[|] */).map(function(row){ - return row.match(/^ *-+: *$/) ? "right" - : row.match(/^ *:-+: *$/) ? "center" - : row.match(/^ *:-+ *$/) ? "left" - : false; + header: cap[1].replace(/(^ *| *\| *$)/g, '').split(/ *\| */), + align: cap[2].replace(/(^ *|\| *$)/g, '').split(/ *\| */).map(function(row) { + return /^ *-+: *$/.test(row) + ? 'right' + : /^ *:-+: *$/.test(row) + ? 'center' + : /^ *:-+ *$/.test(row) + ? 'left' + : false; }), - cells: cap[3].replace(/( *[|] *)?\n$/, '').split("\n").map(function(row){ - return row.replace(/(^ *[|] *| *[|] *$)/g, '').split(/ *[|] */); + cells: cap[3].replace(/( *\| *)?\n$/, '').split('\n').map(function(row) { + return row.replace(/(^ *\| *| *\| *$)/g, '').split(/ *\| */); }) }); continue; @@ -156,15 +159,18 @@ block.token = function(src, tokens, top) { src = src.substring(cap[0].length); tokens.push({ type: 'table', - header: cap[1].replace(/(^ *| *[|] *$)/g, '').split(/ *[|] */), - align: cap[2].replace(/(^ *|[|] *$)/g, '').split(/ *[|] */).map(function(row){ - return row.match(/^ *-+: *$/) ? "right" - : row.match(/^ *:-+: *$/) ? "center" - : row.match(/^ *:-+ *$/) ? "left" - : false; + header: cap[1].replace(/(^ *| *\| *$)/g, '').split(/ *\| */), + align: cap[2].replace(/(^ *|\| *$)/g, '').split(/ *\| */).map(function(row) { + return /^ *-+: *$/.test(row) + ? 'right' + : /^ *:-+: *$/.test(row) + ? 'center' + : /^ *:-+ *$/.test(row) + ? 'left' + : false; }), - cells: cap[3].replace(/\n$/, '').split("\n").map(function(row){ - return row.split(/ *[|] */); + cells: cap[3].replace(/\n$/, '').split('\n').map(function(row) { + return row.split(/ *\| */); }) }); continue; @@ -605,13 +611,17 @@ function tok() { } case 'table': { var thead = '\t\n\t\t'; - token.header.forEach(function(heading, i){ + token.header.forEach(function(heading, i) { heading = inline.lexer(heading); - var align = i < token.align.length ? token.align[i] : false; - switch(align){ - case "left": - case "right": - case "center": + + var align = i < token.align.length + ? token.align[i] + : false; + + switch (align) { + case 'left': + case 'right': + case 'center': thead += '' + heading + ''; break; default: @@ -621,15 +631,19 @@ function tok() { thead += '\n\t\n'; var tbody = '\t\n'; - token.cells.forEach(function(row){ + token.cells.forEach(function(row) { tbody += '\t\t'; - row.forEach(function(cell, i){ + row.forEach(function(cell, i) { cell = inline.lexer(cell); - var align = i < token.align.length ? token.align[i] : false; - switch(align){ - case "left": - case "right": - case "center": + + var align = i < token.align.length + ? token.align[i] + : false; + + switch (align) { + case 'left': + case 'right': + case 'center': tbody += '' + cell + ''; break; default: From ec47218dd976daa8e1ad6ee4a6aa2bf1b009c74d Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Wed, 2 Jan 2013 14:53:10 -0600 Subject: [PATCH 05/15] fix misnested TH tags. --- lib/marked.js | 2 +- test/new/gfm_tables.html | 4 ++-- test/tests/gfm_tables.html | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/marked.js b/lib/marked.js index aa9df030..24e2543b 100644 --- a/lib/marked.js +++ b/lib/marked.js @@ -622,7 +622,7 @@ function tok() { case 'left': case 'right': case 'center': - thead += '' + heading + ''; + thead += '' + heading + ''; break; default: thead += '' + heading + ''; diff --git a/test/new/gfm_tables.html b/test/new/gfm_tables.html index 1dd37334..315e1548 100644 --- a/test/new/gfm_tables.html +++ b/test/new/gfm_tables.html @@ -9,7 +9,7 @@ - + @@ -28,7 +28,7 @@
Header 1Header 2Header 3Header 4
Header 1Header 2Header 3Header 4
Cell 1Cell 2Cell 3Cell 4
- + diff --git a/test/tests/gfm_tables.html b/test/tests/gfm_tables.html index 1dd37334..315e1548 100644 --- a/test/tests/gfm_tables.html +++ b/test/tests/gfm_tables.html @@ -9,7 +9,7 @@
Header 1Header 2Header 3Header 4
Header 1Header 2Header 3Header 4
Cell 1Cell 2Cell 3Cell 4
- + @@ -28,7 +28,7 @@
Header 1Header 2Header 3Header 4
Header 1Header 2Header 3Header 4
Cell 1Cell 2Cell 3Cell 4
- + From 68c014c310b71ab433e9200b891aad48b9de796c Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Wed, 2 Jan 2013 15:07:58 -0600 Subject: [PATCH 06/15] avoid using ES5 methods for tables. --- lib/marked.js | 110 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 71 insertions(+), 39 deletions(-) diff --git a/lib/marked.js b/lib/marked.js index 24e2543b..9ec7af35 100644 --- a/lib/marked.js +++ b/lib/marked.js @@ -135,44 +135,62 @@ block.token = function(src, tokens, top) { // table (gfm) if (cap = block.table.exec(src)) { src = src.substring(cap[0].length); - tokens.push({ + + item = { type: 'table', header: cap[1].replace(/(^ *| *\| *$)/g, '').split(/ *\| */), - align: cap[2].replace(/(^ *|\| *$)/g, '').split(/ *\| */).map(function(row) { - return /^ *-+: *$/.test(row) - ? 'right' - : /^ *:-+: *$/.test(row) - ? 'center' - : /^ *:-+ *$/.test(row) - ? 'left' - : false; - }), - cells: cap[3].replace(/( *\| *)?\n$/, '').split('\n').map(function(row) { - return row.replace(/(^ *\| *| *\| *$)/g, '').split(/ *\| */); - }) - }); + align: cap[2].replace(/(^ *|\| *$)/g, '').split(/ *\| */), + cells: cap[3].replace(/( *\| *)?\n$/, '').split('\n') + }; + + for (i = 0; i < item.align.length; i++) { + item.align[i] = /^ *-+: *$/.test(item.align[i]) + ? 'right' + : /^ *:-+: *$/.test(item.align[i]) + ? 'center' + : /^ *:-+ *$/.test(item.align[i]) + ? 'left' + : false; + } + + for (i = 0; i < item.cells.length; i++) { + item.cells[i] = item.cells[i] + .replace(/(^ *\| *| *\| *$)/g, '') + .split(/ *\| */); + } + + tokens.push(item); + continue; } // table no leading pipe (gfm) if (cap = block.nptable.exec(src)) { src = src.substring(cap[0].length); - tokens.push({ + + item = { type: 'table', header: cap[1].replace(/(^ *| *\| *$)/g, '').split(/ *\| */), - align: cap[2].replace(/(^ *|\| *$)/g, '').split(/ *\| */).map(function(row) { - return /^ *-+: *$/.test(row) - ? 'right' - : /^ *:-+: *$/.test(row) - ? 'center' - : /^ *:-+ *$/.test(row) - ? 'left' - : false; - }), - cells: cap[3].replace(/\n$/, '').split('\n').map(function(row) { - return row.split(/ *\| */); - }) - }); + align: cap[2].replace(/(^ *|\| *$)/g, '').split(/ *\| */), + cells: cap[3].replace(/\n$/, '').split('\n') + }; + + for (i = 0; i < item.align.length; i++) { + item.align[i] = /^ *-+: *$/.test(item.align[i]) + ? 'right' + : /^ *:-+: *$/.test(item.align[i]) + ? 'center' + : /^ *:-+ *$/.test(item.align[i]) + ? 'left' + : false; + } + + for (i = 0; i < item.cells.length; i++) { + item.cells[i] = item.cells[i].split(/ *\| */); + } + + tokens.push(item); + continue; } @@ -610,11 +628,20 @@ function tok() { + '\n'; } case 'table': { - var thead = '\t\n\t\t'; - token.header.forEach(function(heading, i) { + var thead = '\t\n\t\t' + , align + , heading + , i + , tbody + , row + , cell + , j; + + for (i = 0; i < token.header.length; i++) { + heading = token.header[i]; heading = inline.lexer(heading); - var align = i < token.align.length + align = i < token.align.length ? token.align[i] : false; @@ -626,18 +653,22 @@ function tok() { break; default: thead += ''; + break; } - }); + } thead += '\n\t\n'; - var tbody = '\t\n'; - token.cells.forEach(function(row) { + tbody = '\t\n' + + for (i = 0; i < token.cells.length; i++) { + row = token.cells[i]; tbody += '\t\t'; - row.forEach(function(cell, i) { + for (j = 0; j < row.length; j++) { + cell = row[j]; cell = inline.lexer(cell); - var align = i < token.align.length - ? token.align[i] + align = j < token.align.length + ? token.align[j] : false; switch (align) { @@ -648,10 +679,11 @@ function tok() { break; default: tbody += ''; + break; } - }); + } tbody += '\n'; - }); + } tbody += '\t\n'; return '
Header 1Header 2Header 3Header 4
Header 1Header 2Header 3Header 4
Cell 1Cell 2Cell 3Cell 4
' + heading + '
' + cell + '
\n' From dd38370f043dc73839ed5b510d1a2922939097fb Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Wed, 2 Jan 2013 15:13:18 -0600 Subject: [PATCH 07/15] fix gfm paragraph rule to account for tables. --- lib/marked.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/marked.js b/lib/marked.js index 9ec7af35..f7736985 100644 --- a/lib/marked.js +++ b/lib/marked.js @@ -68,7 +68,11 @@ block.gfm = { }; block.gfm.paragraph = replace(block.paragraph) - ('(?!', '(?!' + block.gfm.fences.source.replace('\\1', '\\2') + '|') + ('(?!', '(?!' + + block.gfm.fences.source.replace('\\1', '\\2') + + '|' + block.gfm.table.source + + '|' + block.gfm.nptable.source + + '|') (); /** @@ -880,7 +884,7 @@ function setOptions(opt) { block.fences = block.normal.fences; block.paragraph = block.normal.paragraph; block.table = block.normal.table; - block.nptable = block.normal.table; + block.nptable = block.normal.nptable; inline.text = inline.normal.text; inline.url = inline.normal.url; } From c35964259bea5d96cbd968acdf2fc1cdd868c4e1 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Wed, 2 Jan 2013 15:21:01 -0600 Subject: [PATCH 08/15] optimize gfm tables. see --patience diff. --- lib/marked.js | 80 +++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/lib/marked.js b/lib/marked.js index f7736985..54ca59ba 100644 --- a/lib/marked.js +++ b/lib/marked.js @@ -136,40 +136,19 @@ block.token = function(src, tokens, top) { continue; } - // table (gfm) - if (cap = block.table.exec(src)) { + // heading + if (cap = block.heading.exec(src)) { src = src.substring(cap[0].length); - - item = { - type: 'table', - header: cap[1].replace(/(^ *| *\| *$)/g, '').split(/ *\| */), - align: cap[2].replace(/(^ *|\| *$)/g, '').split(/ *\| */), - cells: cap[3].replace(/( *\| *)?\n$/, '').split('\n') - }; - - for (i = 0; i < item.align.length; i++) { - item.align[i] = /^ *-+: *$/.test(item.align[i]) - ? 'right' - : /^ *:-+: *$/.test(item.align[i]) - ? 'center' - : /^ *:-+ *$/.test(item.align[i]) - ? 'left' - : false; - } - - for (i = 0; i < item.cells.length; i++) { - item.cells[i] = item.cells[i] - .replace(/(^ *\| *| *\| *$)/g, '') - .split(/ *\| */); - } - - tokens.push(item); - + tokens.push({ + type: 'heading', + depth: cap[1].length, + text: cap[2] + }); continue; } // table no leading pipe (gfm) - if (cap = block.nptable.exec(src)) { + if (top && (cap = block.nptable.exec(src))) { src = src.substring(cap[0].length); item = { @@ -198,17 +177,6 @@ block.token = function(src, tokens, top) { continue; } - // heading - if (cap = block.heading.exec(src)) { - src = src.substring(cap[0].length); - tokens.push({ - type: 'heading', - depth: cap[1].length, - text: cap[2] - }); - continue; - } - // lheading if (cap = block.lheading.exec(src)) { src = src.substring(cap[0].length); @@ -337,6 +305,38 @@ block.token = function(src, tokens, top) { continue; } + // table (gfm) + if (top && (cap = block.table.exec(src))) { + src = src.substring(cap[0].length); + + item = { + type: 'table', + header: cap[1].replace(/(^ *| *\| *$)/g, '').split(/ *\| */), + align: cap[2].replace(/(^ *|\| *$)/g, '').split(/ *\| */), + cells: cap[3].replace(/( *\| *)?\n$/, '').split('\n') + }; + + for (i = 0; i < item.align.length; i++) { + item.align[i] = /^ *-+: *$/.test(item.align[i]) + ? 'right' + : /^ *:-+: *$/.test(item.align[i]) + ? 'center' + : /^ *:-+ *$/.test(item.align[i]) + ? 'left' + : false; + } + + for (i = 0; i < item.cells.length; i++) { + item.cells[i] = item.cells[i] + .replace(/(^ *\| *| *\| *$)/g, '') + .split(/ *\| */); + } + + tokens.push(item); + + continue; + } + // top-level paragraph if (top && (cap = block.paragraph.exec(src))) { src = src.substring(cap[0].length); From 91a44f66846fd4ff69600ce046d310eb093777d5 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Wed, 2 Jan 2013 15:23:50 -0600 Subject: [PATCH 09/15] remove tabs in table output. --- lib/marked.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/marked.js b/lib/marked.js index 54ca59ba..63f192ee 100644 --- a/lib/marked.js +++ b/lib/marked.js @@ -632,7 +632,7 @@ function tok() { + '\n'; } case 'table': { - var thead = '\t\n\t\t' + var thead = '\n' , align , heading , i @@ -660,13 +660,13 @@ function tok() { break; } } - thead += '\n\t\n'; + thead += '\n\n'; - tbody = '\t\n' + tbody = '\n' for (i = 0; i < token.cells.length; i++) { row = token.cells[i]; - tbody += '\t\t'; + tbody += ''; for (j = 0; j < row.length; j++) { cell = row[j]; cell = inline.lexer(cell); @@ -688,7 +688,7 @@ function tok() { } tbody += '\n'; } - tbody += '\t\n'; + tbody += '\n'; return '
\n' + thead From 51bc60a33141cbb16c70e7beccc6d70b2c47d253 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Wed, 2 Jan 2013 15:25:10 -0600 Subject: [PATCH 10/15] minor --- lib/marked.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/marked.js b/lib/marked.js index 63f192ee..bd2b8578 100644 --- a/lib/marked.js +++ b/lib/marked.js @@ -632,7 +632,7 @@ function tok() { + '\n'; } case 'table': { - var thead = '\n' + var thead , align , heading , i @@ -641,6 +641,8 @@ function tok() { , cell , j; + // header + thead = '\n'; for (i = 0; i < token.header.length; i++) { heading = token.header[i]; heading = inline.lexer(heading); @@ -662,8 +664,8 @@ function tok() { } thead += '\n\n'; + // body tbody = '\n' - for (i = 0; i < token.cells.length; i++) { row = token.cells[i]; tbody += ''; From 4e9398d123baa842eec1454922a25aeb58938cf3 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Wed, 2 Jan 2013 15:26:54 -0600 Subject: [PATCH 11/15] whitespace output. --- lib/marked.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/marked.js b/lib/marked.js index bd2b8578..50718a77 100644 --- a/lib/marked.js +++ b/lib/marked.js @@ -642,7 +642,7 @@ function tok() { , j; // header - thead = '\n'; + thead = '\n\n'; for (i = 0; i < token.header.length; i++) { heading = token.header[i]; heading = inline.lexer(heading); @@ -655,10 +655,10 @@ function tok() { case 'left': case 'right': case 'center': - thead += ''; + thead += '\n'; break; default: - thead += ''; + thead += '\n'; break; } } @@ -668,7 +668,7 @@ function tok() { tbody = '\n' for (i = 0; i < token.cells.length; i++) { row = token.cells[i]; - tbody += ''; + tbody += '\n'; for (j = 0; j < row.length; j++) { cell = row[j]; cell = inline.lexer(cell); @@ -681,10 +681,10 @@ function tok() { case 'left': case 'right': case 'center': - tbody += ''; + tbody += '\n'; break; default: - tbody += ''; + tbody += '\n'; break; } } From c07e160849c13375c98ae0e480f21c03f7e42138 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Wed, 2 Jan 2013 15:29:57 -0600 Subject: [PATCH 12/15] refactor again. --- lib/marked.js | 37 ++++++------------------------------- 1 file changed, 6 insertions(+), 31 deletions(-) diff --git a/lib/marked.js b/lib/marked.js index 50718a77..0b701949 100644 --- a/lib/marked.js +++ b/lib/marked.js @@ -633,7 +633,6 @@ function tok() { } case 'table': { var thead - , align , heading , i , tbody @@ -646,21 +645,9 @@ function tok() { for (i = 0; i < token.header.length; i++) { heading = token.header[i]; heading = inline.lexer(heading); - - align = i < token.align.length - ? token.align[i] - : false; - - switch (align) { - case 'left': - case 'right': - case 'center': - thead += '\n'; - break; - default: - thead += '\n'; - break; - } + thead += token.align[i] + ? '\n' + : '\n'; } thead += '\n\n'; @@ -672,21 +659,9 @@ function tok() { for (j = 0; j < row.length; j++) { cell = row[j]; cell = inline.lexer(cell); - - align = j < token.align.length - ? token.align[j] - : false; - - switch (align) { - case 'left': - case 'right': - case 'center': - tbody += '\n'; - break; - default: - tbody += '\n'; - break; - } + tbody += token.align[j] + ? '\n' + : '\n'; } tbody += '\n'; } From d8af0af8e86b0560bbfdb300025d8e7c9d241222 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Wed, 2 Jan 2013 15:35:51 -0600 Subject: [PATCH 13/15] minor refactor. --- lib/marked.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/marked.js b/lib/marked.js index 0b701949..c9ebe818 100644 --- a/lib/marked.js +++ b/lib/marked.js @@ -643,8 +643,7 @@ function tok() { // header thead = '\n\n'; for (i = 0; i < token.header.length; i++) { - heading = token.header[i]; - heading = inline.lexer(heading); + heading = inline.lexer(token.header[i]); thead += token.align[i] ? '\n' : '\n'; @@ -657,8 +656,7 @@ function tok() { row = token.cells[i]; tbody += '\n'; for (j = 0; j < row.length; j++) { - cell = row[j]; - cell = inline.lexer(cell); + cell = inline.lexer(row[j]); tbody += token.align[j] ? '\n' : '\n'; From 29eacfdee3d5a06a6b8b44f32432c3814af98269 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Wed, 2 Jan 2013 22:04:56 -0600 Subject: [PATCH 14/15] refactor. --- lib/marked.js | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/lib/marked.js b/lib/marked.js index c9ebe818..da6e072f 100644 --- a/lib/marked.js +++ b/lib/marked.js @@ -159,13 +159,15 @@ block.token = function(src, tokens, top) { }; for (i = 0; i < item.align.length; i++) { - item.align[i] = /^ *-+: *$/.test(item.align[i]) - ? 'right' - : /^ *:-+: *$/.test(item.align[i]) - ? 'center' - : /^ *:-+ *$/.test(item.align[i]) - ? 'left' - : false; + 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++) { @@ -317,13 +319,15 @@ block.token = function(src, tokens, top) { }; for (i = 0; i < item.align.length; i++) { - item.align[i] = /^ *-+: *$/.test(item.align[i]) - ? 'right' - : /^ *:-+: *$/.test(item.align[i]) - ? 'center' - : /^ *:-+ *$/.test(item.align[i]) - ? 'left' - : false; + 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++) { From e715bd18a0c537ad522d2b910dc3b901bb942d99 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Wed, 2 Jan 2013 22:10:53 -0600 Subject: [PATCH 15/15] simplify table regexes. possibly use backreferences for leading whitespace. --- lib/marked.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/marked.js b/lib/marked.js index da6e072f..b5733ff0 100644 --- a/lib/marked.js +++ b/lib/marked.js @@ -63,8 +63,8 @@ block.normal = { block.gfm = { fences: /^ *(`{3,}|~{3,}) *(\w+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/, paragraph: /^/, - table: /^ {0,3}\|(.+)\n {0,3}\|( *[-:]+[-| :]*)\n((?: *\|.*\n)*)\n*/, - nptable: /^ {0,3}(\S.*\|.*)\n {0,3}([-:]+ *\|[-| :]*)\n((?:.*\|.*\n)*)\n*/ + table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*\n)*)\n*/, + nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*\n)*)\n*/ }; block.gfm.paragraph = replace(block.paragraph)
' + heading + '' + heading + '' + heading + '' + heading + '
' + cell + '' + cell + '' + cell + '' + cell + '' + heading + '' + heading + '' + heading + '' + heading + '
' + cell + '' + cell + '' + cell + '' + cell + '
' + heading + '' + heading + '
' + cell + '' + cell + '