diff --git a/lib/marked.js b/lib/marked.js
index fce4f4c4..d48997c8 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*/,
@@ -53,12 +55,16 @@ block.paragraph = replace(block.paragraph)
block.normal = {
fences: block.fences,
- paragraph: block.paragraph
+ paragraph: block.paragraph,
+ table: block.table,
+ nptable: block.nptable
};
block.gfm = {
fences: /^ *(`{3,}|~{3,}) *(\w+)? *\n([\s\S]+?)\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)
@@ -126,6 +132,44 @@ block.token = function(src, tokens, top) {
continue;
}
+ // table (gfm)
+ 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 (gfm)
+ 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);
@@ -300,7 +344,7 @@ block.token = function(src, tokens, top) {
*/
var inline = {
- escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
+ escape: /^\\([\\`*{}\[\]()#+\-.!_>|])/,
autolink: /^<([^ >]+(@|:\/)[^ >]+)>/,
url: noop,
tag: /^|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,
@@ -559,6 +603,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 = '';
@@ -740,11 +826,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/gfm_tables.html b/test/new/gfm_tables.html
new file mode 100644
index 00000000..1dd37334
--- /dev/null
+++ b/test/new/gfm_tables.html
@@ -0,0 +1,38 @@
+
+
+ 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/new/gfm_tables.text b/test/new/gfm_tables.text
new file mode 100644
index 00000000..5fd6321c
--- /dev/null
+++ b/test/new/gfm_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/gfm_tables.html b/test/tests/gfm_tables.html
new file mode 100644
index 00000000..1dd37334
--- /dev/null
+++ b/test/tests/gfm_tables.html
@@ -0,0 +1,38 @@
+
+
+ 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/gfm_tables.text b/test/tests/gfm_tables.text
new file mode 100644
index 00000000..5fd6321c
--- /dev/null
+++ b/test/tests/gfm_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