mirror of
https://github.com/showdownjs/showdown.git
synced 2024-03-22 13:30:55 +08:00
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
This commit is contained in:
parent
43e9448d6e
commit
3a924e3c7e
BIN
dist/showdown.js
vendored
BIN
dist/showdown.js
vendored
Binary file not shown.
BIN
dist/showdown.js.map
vendored
BIN
dist/showdown.js.map
vendored
Binary file not shown.
BIN
dist/showdown.min.js
vendored
BIN
dist/showdown.min.js
vendored
Binary file not shown.
BIN
dist/showdown.min.js.map
vendored
BIN
dist/showdown.min.js.map
vendored
Binary file not shown.
|
@ -44,6 +44,7 @@ showdown.Converter = function (converterOptions) {
|
|||
* @type {string[]}
|
||||
*/
|
||||
parserOrder = [
|
||||
'tables',
|
||||
'githubCodeBlocks',
|
||||
'hashHTMLBlocks',
|
||||
'stripLinkDefinitions',
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
108
src/subParsers/tables.js
Normal file
108
src/subParsers/tables.js
Normal file
|
@ -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
test/features/tables/basic-alignment.html
Normal file
21
test/features/tables/basic-alignment.html
Normal file
|
@ -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
test/features/tables/basic-alignment.md
Normal file
4
test/features/tables/basic-alignment.md
Normal file
|
@ -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
test/features/tables/basic.html
Normal file
21
test/features/tables/basic.html
Normal file
|
@ -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
test/features/tables/basic.md
Normal file
4
test/features/tables/basic.md
Normal file
|
@ -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
test/features/tables/large.html
Normal file
48
test/features/tables/large.html
Normal file
|
@ -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
test/features/tables/large.md
Normal file
7
test/features/tables/large.md
Normal file
|
@ -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 |
|
43
test/features/tables/multiple-tables.html
Normal file
43
test/features/tables/multiple-tables.html
Normal file
|
@ -0,0 +1,43 @@
|
|||
<h1 id="tabletest">Table Test</h1>
|
||||
|
||||
<h2 id="section1">section 1</h2>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th id="header1" style="text-align:left;">header1 </th>
|
||||
<th id="header2" style="text-align:left;">header2 </th>
|
||||
<th id="header3" style="text-align:left;">header3</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="text-align:left;"><p>Value1 </p></td>
|
||||
<td style="text-align:left;"><p>Value2 </p></td>
|
||||
<td style="text-align:left;"><p>Value3 </p></td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h2 id="section2">section 2</h2>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th id="headera" style="text-align:left;">headerA </th>
|
||||
<th id="headerb" style="text-align:left;">headerB </th>
|
||||
<th id="headerc" style="text-align:left;">headerC</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="text-align:left;"><p>ValueA </p></td>
|
||||
<td style="text-align:left;"><p>ValueB </p></td>
|
||||
<td style="text-align:left;"><p>ValueC </p></td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
17
test/features/tables/multiple-tables.md
Normal file
17
test/features/tables/multiple-tables.md
Normal file
|
@ -0,0 +1,17 @@
|
|||
Table Test
|
||||
============
|
||||
|
||||
section 1
|
||||
------------
|
||||
|
||||
|header1 |header2 |header3|
|
||||
|-----------|-----------|---------|
|
||||
|Value1 |Value2 |Value3 |
|
||||
|
||||
|
||||
section 2
|
||||
-----------
|
||||
|
||||
|headerA |headerB |headerC|
|
||||
|-----------|-----------|---------|
|
||||
|ValueA |ValueB |ValueC |
|
21
test/features/tables/with-equals.html
Normal file
21
test/features/tables/with-equals.html
Normal file
|
@ -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
test/features/tables/with-equals.md
Normal file
4
test/features/tables/with-equals.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
| First Header | Second Header |
|
||||
| ============= | ============= |
|
||||
| Row 1 Cell 1 | Row 1 Cell 2 |
|
||||
| Row 2 Cell 1 | Row 2 Cell 2 |
|
33
test/features/tables/with-surroundings.html
Normal file
33
test/features/tables/with-surroundings.html
Normal file
|
@ -0,0 +1,33 @@
|
|||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent nisi est,
|
||||
ullamcorper euismod iaculis sed, tristique at neque. Nullam metus risus,
|
||||
malesuada vitae imperdiet ac, tincidunt eget lacus. Proin ullamcorper
|
||||
vulputate dictum. Vestibulum consequat ultricies nibh, sed tempus nisl mattis a.</p>
|
||||
|
||||
<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>
|
||||
|
||||
<p>Phasellus ac porttitor quam. Integer cursus accumsan mauris nec interdum.
|
||||
Etiam iaculis urna vitae risus facilisis faucibus eu quis risus. Sed aliquet
|
||||
rutrum dictum. Vivamus pulvinar malesuada ultricies. Pellentesque in commodo
|
||||
nibh. Maecenas justo erat, sodales vel bibendum a, dignissim in orci. Duis
|
||||
blandit ornare mi non facilisis. Aliquam rutrum fringilla lacus in semper.
|
||||
Sed vel pretium lorem.</p>
|
16
test/features/tables/with-surroundings.md
Normal file
16
test/features/tables/with-surroundings.md
Normal file
|
@ -0,0 +1,16 @@
|
|||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent nisi est,
|
||||
ullamcorper euismod iaculis sed, tristique at neque. Nullam metus risus,
|
||||
malesuada vitae imperdiet ac, tincidunt eget lacus. Proin ullamcorper
|
||||
vulputate dictum. Vestibulum consequat ultricies nibh, sed tempus nisl mattis a.
|
||||
|
||||
| First Header | Second Header |
|
||||
| ------------- | ------------- |
|
||||
| Row 1 Cell 1 | Row 1 Cell 2 |
|
||||
| Row 2 Cell 1 | Row 2 Cell 2 |
|
||||
|
||||
Phasellus ac porttitor quam. Integer cursus accumsan mauris nec interdum.
|
||||
Etiam iaculis urna vitae risus facilisis faucibus eu quis risus. Sed aliquet
|
||||
rutrum dictum. Vivamus pulvinar malesuada ultricies. Pellentesque in commodo
|
||||
nibh. Maecenas justo erat, sodales vel bibendum a, dignissim in orci. Duis
|
||||
blandit ornare mi non facilisis. Aliquam rutrum fringilla lacus in semper.
|
||||
Sed vel pretium lorem.
|
11
test/features/tables/without-body.html
Normal file
11
test/features/tables/without-body.html
Normal file
|
@ -0,0 +1,11 @@
|
|||
<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>
|
||||
</tbody>
|
||||
</table>
|
2
test/features/tables/without-body.md
Normal file
2
test/features/tables/without-body.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
| First Header | Second Header |
|
||||
| ------------- | ------------- |
|
1
test/features/tables/without-header-delimiter.html
Normal file
1
test/features/tables/without-header-delimiter.html
Normal file
|
@ -0,0 +1 @@
|
|||
<p>| First Header | Second Header |</p>
|
1
test/features/tables/without-header-delimiter.md
Normal file
1
test/features/tables/without-header-delimiter.md
Normal file
|
@ -0,0 +1 @@
|
|||
| First Header | Second Header |
|
|
@ -25,7 +25,8 @@ describe('showdown.options', function () {
|
|||
parseImgDimensions: false,
|
||||
simplifiedAutoLink: false,
|
||||
literalMidWordUnderscores: false,
|
||||
strikethrough: false
|
||||
strikethrough: false,
|
||||
tables: false
|
||||
};
|
||||
expect(showdown.getDefaultOptions()).to.be.eql(opts);
|
||||
});
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
var showdown = require('../../dist/showdown.js'),
|
||||
bootstrap = require('../bootstrap.js'),
|
||||
assertion = bootstrap.assertion,
|
||||
testsuite = bootstrap.getTestSuite('test/features/');
|
||||
testsuite = bootstrap.getTestSuite('test/features/'),
|
||||
tableSuite = bootstrap.getTestSuite('test/features/tables/');
|
||||
|
||||
describe('makeHtml() features testsuite', function () {
|
||||
'use strict';
|
||||
|
@ -25,4 +26,12 @@ describe('makeHtml() features testsuite', function () {
|
|||
}
|
||||
it(testsuite[i].name, assertion(testsuite[i], converter));
|
||||
}
|
||||
|
||||
describe('table support', function () {
|
||||
var converter = new showdown.Converter({tables: true});
|
||||
for (var i = 0; i < tableSuite.length; ++i) {
|
||||
it(tableSuite[i].name, assertion(tableSuite[i], converter));
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue
Block a user