Skip to content

Commit

Permalink
feat(tables): add support for GFM tables
Browse files Browse the repository at this point in the history
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
  • Loading branch information
tivie committed Jul 11, 2015
1 parent 43e9448 commit 3a924e3
Show file tree
Hide file tree
Showing 26 changed files with 494 additions and 9 deletions.
115 changes: 113 additions & 2 deletions dist/showdown.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/showdown.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/showdown.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/showdown.min.js.map

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/converter.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ showdown.Converter = function (converterOptions) {
* @type {string[]}
*/
parserOrder = [
'tables',
'githubCodeBlocks',
'hashHTMLBlocks',
'stripLinkDefinitions',
Expand Down
3 changes: 2 additions & 1 deletion src/showdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ var showdown = {},
parseImgDimensions: false,
simplifiedAutoLink: false,
literalMidWordUnderscores: false,
strikethrough: false
strikethrough: false,
tables: false
},
globalOptions = JSON.parse(JSON.stringify(defaultOptions)); //clone default options out of laziness =P

Expand Down
2 changes: 1 addition & 1 deletion src/subParsers/blockGamut.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ showdown.subParser('blockGamut', function (text, options, globals) {
var key = showdown.subParser('hashBlock')('<hr />', options, globals);
text = text.replace(/^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$/gm, key);
text = text.replace(/^[ ]{0,2}([ ]?\-[ ]?){3,}[ \t]*$/gm, key);
text = text.replace(/^[ ]{0,2}([ ]?\_[ ]?){3,}[ \t]*$/gm, key);
text = text.replace(/^[ ]{0,2}([ ]?_[ ]?){3,}[ \t]*$/gm, key);

text = showdown.subParser('lists')(text, options, globals);
text = showdown.subParser('codeBlocks')(text, options, globals);
Expand Down
108 changes: 108 additions & 0 deletions src/subParsers/tables.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
showdown.subParser('tables', function (text, options, globals) {
'use strict';

var table = function () {

var tables = {},
style = 'text-align:left;',
filter;

tables.th = function (header) {
if (header.trim() === '') {
return '';
}
var id = header.trim().replace(/ /g, '_').toLowerCase();
return '<th id="' + id + '" style="' + style + '">' + header + '</th>';
};

tables.td = function (cell) {
var subText = showdown.subParser('blockGamut')(cell, options, globals);
return '<td style="' + style + '">' + subText + '</td>';
};

tables.ths = function () {
var out = '',
i = 0,
hs = [].slice.apply(arguments);
for (i; i < hs.length; i += 1) {
out += tables.th(hs[i]) + '\n';
}
return out;
};

tables.tds = function () {
var out = '', i = 0, ds = [].slice.apply(arguments);
for (i; i < ds.length; i += 1) {
out += tables.td(ds[i]) + '\n';
}
return out;
};

tables.thead = function () {
var out,
hs = [].slice.apply(arguments);
out = '<thead>\n';
out += '<tr>\n';
out += tables.ths.apply(this, hs);
out += '</tr>\n';
out += '</thead>\n';
return out;
};

tables.tr = function () {
var out,
cs = [].slice.apply(arguments);
out = '<tr>\n';
out += tables.tds.apply(this, cs);
out += '</tr>\n';
return out;
};

filter = function (text) {
var i = 0,
lines = text.split('\n'),
line,
hs,
out = [];
for (i; i < lines.length; i += 1) {
line = lines[i];
// looks like a table heading
if (line.trim().match(/^[|].*[|]$/)) {
line = line.trim();
var tbl = [];
tbl.push('<table>');
hs = line.substring(1, line.length - 1).split('|');
tbl.push(tables.thead.apply(this, hs));
line = lines[++i];
if (!line.trim().match(/^[|][-=|: ]+[|]$/)) {
// not a table rolling back
line = lines[--i];
} else {
line = lines[++i];
tbl.push('<tbody>');
while (line.trim().match(/^[|].*[|]$/)) {
line = line.trim();
tbl.push(tables.tr.apply(this, line.substring(1, line.length - 1).split('|')));
line = lines[++i];
}
tbl.push('</tbody>');
tbl.push('</table>');
// we are done with this table and we move along
out.push(tbl.join('\n'));
continue;
}
}
out.push(line);
}
return out.join('\n');
};
return {parse: filter};
};

if (options.tables) {
var tableParser = table();
return tableParser.parse(text);
} else {
return text;
}
});
21 changes: 21 additions & 0 deletions test/features/tables/basic-alignment.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<table>
<thead>
<tr>
<th id="first_header" style="text-align:left;"> First Header </th>
<th id="second_header" style="text-align:left;"> Second Header </th>
</tr>
</thead>

<tbody>
<tr>
<td style="text-align:left;"><p>Row 1 Cell 1 </p></td>
<td style="text-align:left;"><p>Row 1 Cell 2 </p></td>
</tr>

<tr>
<td style="text-align:left;"><p>Row 2 Cell 1 </p></td>
<td style="text-align:left;"><p>Row 2 Cell 2 </p></td>
</tr>

</tbody>
</table>
4 changes: 4 additions & 0 deletions test/features/tables/basic-alignment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
| First Header | Second Header |
| :------------ | :------------ |
| Row 1 Cell 1 | Row 1 Cell 2 |
| Row 2 Cell 1 | Row 2 Cell 2 |
21 changes: 21 additions & 0 deletions test/features/tables/basic.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<table>
<thead>
<tr>
<th id="first_header" style="text-align:left;"> First Header </th>
<th id="second_header" style="text-align:left;"> Second Header </th>
</tr>
</thead>

<tbody>
<tr>
<td style="text-align:left;"><p>Row 1 Cell 1 </p></td>
<td style="text-align:left;"><p>Row 1 Cell 2 </p></td>
</tr>

<tr>
<td style="text-align:left;"><p>Row 2 Cell 1 </p></td>
<td style="text-align:left;"><p>Row 2 Cell 2 </p></td>
</tr>

</tbody>
</table>
4 changes: 4 additions & 0 deletions test/features/tables/basic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
| First Header | Second Header |
| ------------- | ------------- |
| Row 1 Cell 1 | Row 1 Cell 2 |
| Row 2 Cell 1 | Row 2 Cell 2 |
48 changes: 48 additions & 0 deletions test/features/tables/large.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<table>
<thead>
<tr>
<th id="first_header" style="text-align:left;"> First Header </th>
<th id="second_header" style="text-align:left;"> Second Header </th>
<th id="third_header" style="text-align:left;"> Third Header </th>
<th id="fourth_header" style="text-align:left;"> Fourth Header </th>
</tr>
</thead>

<tbody>
<tr>
<td style="text-align:left;"><p>Row 1 Cell 1 </p></td>
<td style="text-align:left;"><p>Row 1 Cell 2 </p></td>
<td style="text-align:left;"><p>Row 1 Cell 3 </p></td>
<td style="text-align:left;"><p>Row 1 Cell 4 </p></td>
</tr>

<tr>
<td style="text-align:left;"><p>Row 2 Cell 1 </p></td>
<td style="text-align:left;"><p>Row 2 Cell 2 </p></td>
<td style="text-align:left;"><p>Row 2 Cell 3 </p></td>
<td style="text-align:left;"><p>Row 2 Cell 4 </p></td>
</tr>

<tr>
<td style="text-align:left;"><p>Row 3 Cell 1 </p></td>
<td style="text-align:left;"><p>Row 3 Cell 2 </p></td>
<td style="text-align:left;"><p>Row 3 Cell 3 </p></td>
<td style="text-align:left;"><p>Row 3 Cell 4 </p></td>
</tr>

<tr>
<td style="text-align:left;"><p>Row 4 Cell 1 </p></td>
<td style="text-align:left;"><p>Row 4 Cell 2 </p></td>
<td style="text-align:left;"><p>Row 4 Cell 3 </p></td>
<td style="text-align:left;"><p>Row 4 Cell 4 </p></td>
</tr>

<tr>
<td style="text-align:left;"><p>Row 5 Cell 1 </p></td>
<td style="text-align:left;"><p>Row 5 Cell 2 </p></td>
<td style="text-align:left;"><p>Row 5 Cell 3 </p></td>
<td style="text-align:left;"><p>Row 5 Cell 4 </p></td>
</tr>

</tbody>
</table>
7 changes: 7 additions & 0 deletions test/features/tables/large.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
| First Header | Second Header | Third Header | Fourth Header |
| ------------- | ------------- | ------------ | ------------- |
| Row 1 Cell 1 | Row 1 Cell 2 | Row 1 Cell 3 | Row 1 Cell 4 |
| Row 2 Cell 1 | Row 2 Cell 2 | Row 2 Cell 3 | Row 2 Cell 4 |
| Row 3 Cell 1 | Row 3 Cell 2 | Row 3 Cell 3 | Row 3 Cell 4 |
| Row 4 Cell 1 | Row 4 Cell 2 | Row 4 Cell 3 | Row 4 Cell 4 |
| Row 5 Cell 1 | Row 5 Cell 2 | Row 5 Cell 3 | Row 5 Cell 4 |
Loading

0 comments on commit 3a924e3

Please sign in to comment.