From 39c6687c19e1c100ab2d4bfc896e71e27ca91502 Mon Sep 17 00:00:00 2001 From: Kitson Kelly Date: Fri, 24 Aug 2012 07:26:12 +0100 Subject: [PATCH 1/3] 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 2/3] 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 3/3] 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+(?:"[^"]*"|'[^']*'|[^'">])*?>/,