Skip to content

Commit 3a924e3

Browse files
committed
feat(tables): add support for GFM tables
Github Flavored Markdown supports a specific table syntax. Table support was already available as an extension. With this commit, the feature was moved to core, adding this feature to showdown through an option called "tables". Related to #164
1 parent 43e9448 commit 3a924e3

26 files changed

+494
-9
lines changed

dist/showdown.js

Lines changed: 113 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/showdown.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/showdown.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/showdown.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/converter.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ showdown.Converter = function (converterOptions) {
4444
* @type {string[]}
4545
*/
4646
parserOrder = [
47+
'tables',
4748
'githubCodeBlocks',
4849
'hashHTMLBlocks',
4950
'stripLinkDefinitions',

src/showdown.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ var showdown = {},
1414
parseImgDimensions: false,
1515
simplifiedAutoLink: false,
1616
literalMidWordUnderscores: false,
17-
strikethrough: false
17+
strikethrough: false,
18+
tables: false
1819
},
1920
globalOptions = JSON.parse(JSON.stringify(defaultOptions)); //clone default options out of laziness =P
2021

src/subParsers/blockGamut.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ showdown.subParser('blockGamut', function (text, options, globals) {
1111
var key = showdown.subParser('hashBlock')('<hr />', options, globals);
1212
text = text.replace(/^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$/gm, key);
1313
text = text.replace(/^[ ]{0,2}([ ]?\-[ ]?){3,}[ \t]*$/gm, key);
14-
text = text.replace(/^[ ]{0,2}([ ]?\_[ ]?){3,}[ \t]*$/gm, key);
14+
text = text.replace(/^[ ]{0,2}([ ]?_[ ]?){3,}[ \t]*$/gm, key);
1515

1616
text = showdown.subParser('lists')(text, options, globals);
1717
text = showdown.subParser('codeBlocks')(text, options, globals);

src/subParsers/tables.js

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
showdown.subParser('tables', function (text, options, globals) {
2+
'use strict';
3+
4+
var table = function () {
5+
6+
var tables = {},
7+
style = 'text-align:left;',
8+
filter;
9+
10+
tables.th = function (header) {
11+
if (header.trim() === '') {
12+
return '';
13+
}
14+
var id = header.trim().replace(/ /g, '_').toLowerCase();
15+
return '<th id="' + id + '" style="' + style + '">' + header + '</th>';
16+
};
17+
18+
tables.td = function (cell) {
19+
var subText = showdown.subParser('blockGamut')(cell, options, globals);
20+
return '<td style="' + style + '">' + subText + '</td>';
21+
};
22+
23+
tables.ths = function () {
24+
var out = '',
25+
i = 0,
26+
hs = [].slice.apply(arguments);
27+
for (i; i < hs.length; i += 1) {
28+
out += tables.th(hs[i]) + '\n';
29+
}
30+
return out;
31+
};
32+
33+
tables.tds = function () {
34+
var out = '', i = 0, ds = [].slice.apply(arguments);
35+
for (i; i < ds.length; i += 1) {
36+
out += tables.td(ds[i]) + '\n';
37+
}
38+
return out;
39+
};
40+
41+
tables.thead = function () {
42+
var out,
43+
hs = [].slice.apply(arguments);
44+
out = '<thead>\n';
45+
out += '<tr>\n';
46+
out += tables.ths.apply(this, hs);
47+
out += '</tr>\n';
48+
out += '</thead>\n';
49+
return out;
50+
};
51+
52+
tables.tr = function () {
53+
var out,
54+
cs = [].slice.apply(arguments);
55+
out = '<tr>\n';
56+
out += tables.tds.apply(this, cs);
57+
out += '</tr>\n';
58+
return out;
59+
};
60+
61+
filter = function (text) {
62+
var i = 0,
63+
lines = text.split('\n'),
64+
line,
65+
hs,
66+
out = [];
67+
for (i; i < lines.length; i += 1) {
68+
line = lines[i];
69+
// looks like a table heading
70+
if (line.trim().match(/^[|].*[|]$/)) {
71+
line = line.trim();
72+
var tbl = [];
73+
tbl.push('<table>');
74+
hs = line.substring(1, line.length - 1).split('|');
75+
tbl.push(tables.thead.apply(this, hs));
76+
line = lines[++i];
77+
if (!line.trim().match(/^[|][-=|: ]+[|]$/)) {
78+
// not a table rolling back
79+
line = lines[--i];
80+
} else {
81+
line = lines[++i];
82+
tbl.push('<tbody>');
83+
while (line.trim().match(/^[|].*[|]$/)) {
84+
line = line.trim();
85+
tbl.push(tables.tr.apply(this, line.substring(1, line.length - 1).split('|')));
86+
line = lines[++i];
87+
}
88+
tbl.push('</tbody>');
89+
tbl.push('</table>');
90+
// we are done with this table and we move along
91+
out.push(tbl.join('\n'));
92+
continue;
93+
}
94+
}
95+
out.push(line);
96+
}
97+
return out.join('\n');
98+
};
99+
return {parse: filter};
100+
};
101+
102+
if (options.tables) {
103+
var tableParser = table();
104+
return tableParser.parse(text);
105+
} else {
106+
return text;
107+
}
108+
});
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<table>
2+
<thead>
3+
<tr>
4+
<th id="first_header" style="text-align:left;"> First Header </th>
5+
<th id="second_header" style="text-align:left;"> Second Header </th>
6+
</tr>
7+
</thead>
8+
9+
<tbody>
10+
<tr>
11+
<td style="text-align:left;"><p>Row 1 Cell 1 </p></td>
12+
<td style="text-align:left;"><p>Row 1 Cell 2 </p></td>
13+
</tr>
14+
15+
<tr>
16+
<td style="text-align:left;"><p>Row 2 Cell 1 </p></td>
17+
<td style="text-align:left;"><p>Row 2 Cell 2 </p></td>
18+
</tr>
19+
20+
</tbody>
21+
</table>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| First Header | Second Header |
2+
| :------------ | :------------ |
3+
| Row 1 Cell 1 | Row 1 Cell 2 |
4+
| Row 2 Cell 1 | Row 2 Cell 2 |

0 commit comments

Comments
 (0)