|
@@ -2357,164 +2357,129 @@ showdown.subParser('stripLinkDefinitions', function (text, options, globals) {
|
|
|
showdown.subParser('tables', function (text, options, globals) {
|
|
|
'use strict';
|
|
|
|
|
|
- var table = function () {
|
|
|
+ if (!options.tables) {
|
|
|
+ return text;
|
|
|
+ }
|
|
|
|
|
|
- var tables = {},
|
|
|
- filter;
|
|
|
+ var tableRgx = /^[ \t]{0,3}\|?.+\|.+\n[ \t]{0,3}\|?[ \t]*:?[ \t]*(?:-|=){3,}[ \t]*:?[ \t]*\|[ \t]*:?[ \t]*(?:-|=){3,}[^]+?(?:\n\n|~0)/gm;
|
|
|
|
|
|
- tables.th = function (header, style) {
|
|
|
- var id = '';
|
|
|
- header = header.trim();
|
|
|
- if (header === '') {
|
|
|
- return '';
|
|
|
- }
|
|
|
- if (options.tableHeaderId) {
|
|
|
- id = ' id="' + header.replace(/ /g, '_').toLowerCase() + '"';
|
|
|
- }
|
|
|
- header = showdown.subParser('spanGamut')(header, options, globals);
|
|
|
- if (!style || style.trim() === '') {
|
|
|
- style = '';
|
|
|
- } else {
|
|
|
- style = ' style="' + style + '"';
|
|
|
- }
|
|
|
- return '<th' + id + style + '>' + header + '</th>';
|
|
|
- };
|
|
|
+ function parseStyles(sLine) {
|
|
|
+ if (/^:[ \t]*---*$/.test(sLine)) {
|
|
|
+ return ' style="text-align:left;"';
|
|
|
+ } else if (/^---*[ \t]*:[ \t]*$/.test(sLine)) {
|
|
|
+ return ' style="text-align:right;"';
|
|
|
+ } else if (/^:[ \t]*---*[ \t]*:$/.test(sLine)) {
|
|
|
+ return ' style="text-align:center;"';
|
|
|
+ } else {
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- tables.td = function (cell, style) {
|
|
|
- var subText = showdown.subParser('spanGamut')(cell.trim(), options, globals);
|
|
|
- if (!style || style.trim() === '') {
|
|
|
- style = '';
|
|
|
- } else {
|
|
|
- style = ' style="' + style + '"';
|
|
|
+ function parseHeaders(header, style) {
|
|
|
+ var id = '';
|
|
|
+ header = header.trim();
|
|
|
+ if (options.tableHeaderId) {
|
|
|
+ id = ' id="' + header.replace(/ /g, '_').toLowerCase() + '"';
|
|
|
+ }
|
|
|
+ header = showdown.subParser('spanGamut')(header, options, globals);
|
|
|
+
|
|
|
+ return '<th' + id + style + '>' + header + '</th>';
|
|
|
+ }
|
|
|
+
|
|
|
+ function parseCells(cell, style) {
|
|
|
+ var subText = showdown.subParser('spanGamut')(cell, options, globals);
|
|
|
+ return '<td' + style + '>' + subText + '</td>';
|
|
|
+ }
|
|
|
+
|
|
|
+ function buildTable(headers, cells) {
|
|
|
+ var tb = '<table>\n<thead>\n<tr>\n',
|
|
|
+ tblLgn = headers.length;
|
|
|
+
|
|
|
+ for (var i = 0; i < tblLgn; ++i) {
|
|
|
+ tb += headers[i];
|
|
|
+ }
|
|
|
+ tb += '</tr>\n</thead>\n<tbody>\n';
|
|
|
+
|
|
|
+ for (i = 0; i < cells.length; ++i) {
|
|
|
+ tb += '<tr>';
|
|
|
+ for (var ii = 0; ii < tblLgn; ++ii) {
|
|
|
+ tb += cells[i][ii];
|
|
|
}
|
|
|
- return '<td' + style + '>' + subText + '</td>';
|
|
|
- };
|
|
|
+ tb += '</tr>';
|
|
|
+ }
|
|
|
+ tb += '</tbody></table>';
|
|
|
+ return tb;
|
|
|
+ }
|
|
|
|
|
|
- tables.ths = function () {
|
|
|
- var out = '',
|
|
|
- i = 0,
|
|
|
- hs = [].slice.apply(arguments[0]),
|
|
|
- style = [].slice.apply(arguments[1]);
|
|
|
+ text = globals.converter._dispatch('tables.before', text, options);
|
|
|
|
|
|
- for (i; i < hs.length; i += 1) {
|
|
|
- out += tables.th(hs[i], style[i]) + '\n';
|
|
|
+ text = text.replace(tableRgx, function (rawTable) {
|
|
|
+
|
|
|
+ var i, tableLines = rawTable.split('\n');
|
|
|
+
|
|
|
+ // strip wrong first and last column if wrapped tables are used
|
|
|
+ for (i = 0; i < tableLines.length; ++i) {
|
|
|
+ if (/^[ \t]{0,3}\|/.test(tableLines[i])) {
|
|
|
+ tableLines[i] = tableLines[i].replace(/^[ \t]{0,3}\|/, '');
|
|
|
+ }
|
|
|
+ if (/\|[ \t]*$/.test(tableLines[i])) {
|
|
|
+ tableLines[i] = tableLines[i].replace(/\|[ \t]*$/, '');
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- return out;
|
|
|
- };
|
|
|
+ var rawHeaders = tableLines[0].split('|').map(function (s) { return s.trim();}),
|
|
|
+ rawStyles = tableLines[1].split('|').map(function (s) { return s.trim();}),
|
|
|
+ rawCells = [],
|
|
|
+ headers = [],
|
|
|
+ styles = [],
|
|
|
+ cells = [];
|
|
|
|
|
|
- tables.tds = function () {
|
|
|
- var out = '',
|
|
|
- i = 0,
|
|
|
- ds = [].slice.apply(arguments[0]),
|
|
|
- style = [].slice.apply(arguments[1]);
|
|
|
+ tableLines.shift();
|
|
|
+ tableLines.shift();
|
|
|
|
|
|
- for (i; i < ds.length; i += 1) {
|
|
|
- out += tables.td(ds[i], style[i]) + '\n';
|
|
|
+ for (i = 0; i < tableLines.length; ++i) {
|
|
|
+ if (tableLines[i].trim() === '') {
|
|
|
+ continue;
|
|
|
}
|
|
|
- return out;
|
|
|
- };
|
|
|
+ rawCells.push(
|
|
|
+ tableLines[i]
|
|
|
+ .split('|')
|
|
|
+ .map(function (s) {
|
|
|
+ return s.trim();
|
|
|
+ })
|
|
|
+ );
|
|
|
+ }
|
|
|
|
|
|
- tables.thead = function () {
|
|
|
- var out,
|
|
|
- hs = [].slice.apply(arguments[0]),
|
|
|
- style = [].slice.apply(arguments[1]);
|
|
|
-
|
|
|
- out = '<thead>\n';
|
|
|
- out += '<tr>\n';
|
|
|
- out += tables.ths.apply(this, [hs, style]);
|
|
|
- out += '</tr>\n';
|
|
|
- out += '</thead>\n';
|
|
|
- return out;
|
|
|
- };
|
|
|
+ if (rawHeaders.length < rawStyles.length) {
|
|
|
+ return rawTable;
|
|
|
+ }
|
|
|
|
|
|
- tables.tr = function () {
|
|
|
- var out,
|
|
|
- cs = [].slice.apply(arguments[0]),
|
|
|
- style = [].slice.apply(arguments[1]);
|
|
|
+ for (i = 0; i < rawStyles.length; ++i) {
|
|
|
+ styles.push(parseStyles(rawStyles[i]));
|
|
|
+ }
|
|
|
|
|
|
- out = '<tr>\n';
|
|
|
- out += tables.tds.apply(this, [cs, style]);
|
|
|
- out += '</tr>\n';
|
|
|
- return out;
|
|
|
- };
|
|
|
+ for (i = 0; i < rawHeaders.length; ++i) {
|
|
|
+ if (showdown.helper.isUndefined(styles[i])) {
|
|
|
+ styles[i] = '';
|
|
|
+ }
|
|
|
+ headers.push(parseHeaders(rawHeaders[i], styles[i]));
|
|
|
+ }
|
|
|
|
|
|
- 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 = [],
|
|
|
- align = lines[i + 1].trim(),
|
|
|
- styles = [],
|
|
|
- j = 0;
|
|
|
-
|
|
|
- if (align.match(/^[|][-=|: ]+[|]$/)) {
|
|
|
- styles = align.substring(1, align.length - 1).split('|');
|
|
|
- for (j = 0; j < styles.length; ++j) {
|
|
|
- styles[j] = styles[j].trim();
|
|
|
- if (styles[j].match(/^[:][-=| ]+[:]$/)) {
|
|
|
- styles[j] = 'text-align:center;';
|
|
|
-
|
|
|
- } else if (styles[j].match(/^[-=| ]+[:]$/)) {
|
|
|
- styles[j] = 'text-align:right;';
|
|
|
-
|
|
|
- } else if (styles[j].match(/^[:][-=| ]+$/)) {
|
|
|
- styles[j] = 'text-align:left;';
|
|
|
- } else {
|
|
|
- styles[j] = '';
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- tbl.push('<table>');
|
|
|
- hs = line.substring(1, line.length - 1).split('|');
|
|
|
+ for (i = 0; i < rawCells.length; ++i) {
|
|
|
+ var row = [];
|
|
|
+ for (var ii = 0; ii < headers.length; ++ii) {
|
|
|
+ if (showdown.helper.isUndefined(rawCells[i][ii])) {
|
|
|
|
|
|
- if (styles.length === 0) {
|
|
|
- for (j = 0; j < hs.length; ++j) {
|
|
|
- styles.push('text-align:left');
|
|
|
- }
|
|
|
- }
|
|
|
- tbl.push(tables.thead.apply(this, [hs, styles]));
|
|
|
- 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('|'), styles]));
|
|
|
- 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);
|
|
|
+ row.push(parseCells(rawCells[i][ii], styles[ii]));
|
|
|
}
|
|
|
- return out.join('\n');
|
|
|
- };
|
|
|
- return {parse: filter};
|
|
|
- };
|
|
|
+ cells.push(row);
|
|
|
+ }
|
|
|
|
|
|
- if (options.tables) {
|
|
|
- text = globals.converter._dispatch('tables.before', text, options);
|
|
|
- var tableParser = table();
|
|
|
- text = tableParser.parse(text);
|
|
|
- text = globals.converter._dispatch('tables.after', text, options);
|
|
|
- }
|
|
|
+ return buildTable(headers, cells);
|
|
|
+ });
|
|
|
+
|
|
|
+ text = globals.converter._dispatch('tables.after', text, options);
|
|
|
|
|
|
return text;
|
|
|
});
|