Merge branch 'gfm_tables_again' into just_proto_table

Conflicts:
	lib/marked.js
This commit is contained in:
Christopher Jeffrey 2013-01-03 01:44:42 -06:00
commit 262f8797ff
5 changed files with 246 additions and 4 deletions

View File

@ -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*/,
@ -58,16 +60,24 @@ 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: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*\n)*)\n*/,
nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*\n)*)\n*/
};
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
+ '|')
();
/**
@ -86,6 +96,14 @@ function Lexer(options) {
block.fences = block.normal.fences;
block.paragraph = block.normal.paragraph;
}
if (this.options.gfm && this.options.tables) {
block.table = block.gfm.table;
block.nptable = block.gfm.nptable;
} else {
block.table = block.normal.table;
block.nptable = block.normal.nptable;
}
}
Lexer.rules = block;
@ -159,6 +177,38 @@ Lexer.prototype.token = function(src, top) {
continue;
}
// table no leading pipe (gfm)
if (top && (cap = block.nptable.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++) {
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] = item.cells[i].split(/ *\| */);
}
this.tokens.push(item);
continue;
}
// lheading
if (cap = block.lheading.exec(src)) {
src = src.substring(cap[0].length);
@ -287,6 +337,40 @@ Lexer.prototype.token = function(src, 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++) {
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] = item.cells[i]
.replace(/(^ *\| *| *\| *$)/g, '')
.split(/ *\| */);
}
this.tokens.push(item);
continue;
}
// top-level paragraph
if (top && (cap = block.paragraph.exec(src))) {
src = src.substring(cap[0].length);
@ -322,7 +406,7 @@ Lexer.prototype.token = function(src, top) {
*/
var inline = {
escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
escape: /^\\([\\`*{}\[\]()#+\-.!_>|])/,
autolink: /^<([^ >]+(@|:\/)[^ >]+)>/,
url: noop,
tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,
@ -660,6 +744,45 @@ Parser.prototype.tok = function() {
+ this.token.text
+ '</code></pre>\n';
}
case 'table': {
var thead
, heading
, i
, tbody
, row
, cell
, j;
// header
thead = '<thead>\n<tr>\n';
for (i = 0; i < this.token.header.length; i++) {
heading = this.inline.output(this.token.header[i]);
thead += this.token.align[i]
? '<th align="' + this.token.align[i] + '">' + heading + '</th>\n'
: '<th>' + heading + '</th>\n';
}
thead += '</tr>\n</thead>\n';
// body
tbody = '<tbody>\n'
for (i = 0; i < this.token.cells.length; i++) {
row = this.token.cells[i];
tbody += '<tr>\n';
for (j = 0; j < row.length; j++) {
cell = this.inline.output(row[j]);
tbody += this.token.align[j]
? '<td align="' + this.token.align[j] + '">' + cell + '</td>\n'
: '<td>' + cell + '</td>\n';
}
tbody += '</tr>\n';
}
tbody += '</tbody>\n';
return '<table>\n'
+ thead
+ tbody
+ '</table>\n'
}
case 'blockquote_start': {
var body = '';
@ -785,6 +908,7 @@ marked.setOptions = function(opt) {
marked.defaults = {
gfm: true,
tables: true,
pedantic: false,
sanitize: false,
silent: false,

38
test/new/gfm_tables.html Normal file
View File

@ -0,0 +1,38 @@
<table>
<thead>
<tr><th>Heading 1</th><th>Heading 2</th></tr>
</thead>
<tbody>
<tr><td>Cell 1</td><td>Cell 2</td></tr>
<tr><td>Cell 3</td><td>Cell 4</td></tr>
</tbody>
</table>
<table>
<thead>
<tr><th align="center">Header 1</th><th align="right">Header 2</th><th align="left">Header 3</th><th>Header 4</th></tr>
</thead>
<tbody>
<tr><td align="center">Cell 1</td><td align="right">Cell 2</td><td align="left">Cell 3</td><td>Cell 4</td></tr>
<tr><td align="center">Cell 5</td><td align="right">Cell 6</td><td align="left">Cell 7</td><td>Cell 8</td></tr>
</tbody>
</table>
<pre><code>Test code</code></pre>
<table>
<thead>
<tr><th>Header 1</th><th>Header 2</th></tr>
</thead>
<tbody>
<tr><td>Cell 1</td><td>Cell 2</td></tr>
<tr><td>Cell 3</td><td>Cell 4</td></tr>
</tbody>
</table>
<table>
<thead>
<tr><th align="left">Header 1</th><th align="center">Header 2</th><th align="right">Header 3</th><th>Header 4</th></tr>
</thead>
<tbody>
<tr><td align="left">Cell 1</td><td align="center">Cell 2</td><td align="right">Cell 3</td><td>Cell 4</td></tr>
<tr><td align="left"><em>Cell 5</em></td><td align="center">Cell 6</td><td align="right">Cell 7</td><td>Cell 8</td></tr>
</tbody>
</table>

21
test/new/gfm_tables.text Normal file
View File

@ -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

View File

@ -0,0 +1,38 @@
<table>
<thead>
<tr><th>Heading 1</th><th>Heading 2</th></tr>
</thead>
<tbody>
<tr><td>Cell 1</td><td>Cell 2</td></tr>
<tr><td>Cell 3</td><td>Cell 4</td></tr>
</tbody>
</table>
<table>
<thead>
<tr><th align="center">Header 1</th><th align="right">Header 2</th><th align="left">Header 3</th><th>Header 4</th></tr>
</thead>
<tbody>
<tr><td align="center">Cell 1</td><td align="right">Cell 2</td><td align="left">Cell 3</td><td>Cell 4</td></tr>
<tr><td align="center">Cell 5</td><td align="right">Cell 6</td><td align="left">Cell 7</td><td>Cell 8</td></tr>
</tbody>
</table>
<pre><code>Test code</code></pre>
<table>
<thead>
<tr><th>Header 1</th><th>Header 2</th></tr>
</thead>
<tbody>
<tr><td>Cell 1</td><td>Cell 2</td></tr>
<tr><td>Cell 3</td><td>Cell 4</td></tr>
</tbody>
</table>
<table>
<thead>
<tr><th align="left">Header 1</th><th align="center">Header 2</th><th align="right">Header 3</th><th>Header 4</th></tr>
</thead>
<tbody>
<tr><td align="left">Cell 1</td><td align="center">Cell 2</td><td align="right">Cell 3</td><td>Cell 4</td></tr>
<tr><td align="left"><em>Cell 5</em></td><td align="center">Cell 6</td><td align="right">Cell 7</td><td>Cell 8</td></tr>
</tbody>
</table>

View File

@ -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