diff --git a/lib/marked.js b/lib/marked.js
index 55b06b4aff..05be0b5dfc 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]);
- }
+ for (i = 0; i < item.cells.length; i++) {
+ item.cells[i] = splitCells(item.cells[i], item.header.length);
+ }
- this.tokens.push(item);
+ this.tokens.push(item);
- continue;
+ 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 + '' + type + '>\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 1 | Header 2 | Header 3 | Header 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 |
+ Cell 1 | Cell 2 | Cell 3 | Cell 4 |
+ Cell 5 | Cell 6 | Cell 7 | Cell 8 |
Test code
@@ -28,10 +28,10 @@
- Header 1 | Header 2 | Header 3 | Header 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 |
+ Cell 1 | Cell 2 | Cell 3 | Cell 4 |
+ Cell 5 | Cell 6 | Cell 7 | Cell 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": "",
"markdown": "| abc | def |\n| --- | --- |",
- "example": 197
+ "example": 198
},
{
"section": "Task list items",