summaryrefslogtreecommitdiff
path: root/node_modules/markdown-it/lib/rules_block/table.js
diff options
context:
space:
mode:
authorMinteck <contact@minteck.org>2022-01-20 13:43:34 +0100
committerMinteck <contact@minteck.org>2022-01-20 13:43:34 +0100
commitc2aa7bf38fb30de2d04f87f8e7780e4c768ae6b1 (patch)
tree226598e8d17d20e3721358f7c60b1cc6b851163a /node_modules/markdown-it/lib/rules_block/table.js
downloadcobalt-c2aa7bf38fb30de2d04f87f8e7780e4c768ae6b1.tar.gz
cobalt-c2aa7bf38fb30de2d04f87f8e7780e4c768ae6b1.tar.bz2
cobalt-c2aa7bf38fb30de2d04f87f8e7780e4c768ae6b1.zip
Initial commit
Diffstat (limited to 'node_modules/markdown-it/lib/rules_block/table.js')
-rw-r--r--node_modules/markdown-it/lib/rules_block/table.js221
1 files changed, 221 insertions, 0 deletions
diff --git a/node_modules/markdown-it/lib/rules_block/table.js b/node_modules/markdown-it/lib/rules_block/table.js
new file mode 100644
index 0000000..7d9208f
--- /dev/null
+++ b/node_modules/markdown-it/lib/rules_block/table.js
@@ -0,0 +1,221 @@
+// GFM table, https://github.github.com/gfm/#tables-extension-
+
+'use strict';
+
+var isSpace = require('../common/utils').isSpace;
+
+
+function getLine(state, line) {
+ var pos = state.bMarks[line] + state.tShift[line],
+ max = state.eMarks[line];
+
+ return state.src.substr(pos, max - pos);
+}
+
+function escapedSplit(str) {
+ var result = [],
+ pos = 0,
+ max = str.length,
+ ch,
+ isEscaped = false,
+ lastPos = 0,
+ current = '';
+
+ ch = str.charCodeAt(pos);
+
+ while (pos < max) {
+ if (ch === 0x7c/* | */) {
+ if (!isEscaped) {
+ // pipe separating cells, '|'
+ result.push(current + str.substring(lastPos, pos));
+ current = '';
+ lastPos = pos + 1;
+ } else {
+ // escaped pipe, '\|'
+ current += str.substring(lastPos, pos - 1);
+ lastPos = pos;
+ }
+ }
+
+ isEscaped = (ch === 0x5c/* \ */);
+ pos++;
+
+ ch = str.charCodeAt(pos);
+ }
+
+ result.push(current + str.substring(lastPos));
+
+ return result;
+}
+
+
+module.exports = function table(state, startLine, endLine, silent) {
+ var ch, lineText, pos, i, l, nextLine, columns, columnCount, token,
+ aligns, t, tableLines, tbodyLines, oldParentType, terminate,
+ terminatorRules, firstCh, secondCh;
+
+ // should have at least two lines
+ if (startLine + 2 > endLine) { return false; }
+
+ nextLine = startLine + 1;
+
+ if (state.sCount[nextLine] < state.blkIndent) { return false; }
+
+ // if it's indented more than 3 spaces, it should be a code block
+ if (state.sCount[nextLine] - state.blkIndent >= 4) { return false; }
+
+ // first character of the second line should be '|', '-', ':',
+ // and no other characters are allowed but spaces;
+ // basically, this is the equivalent of /^[-:|][-:|\s]*$/ regexp
+
+ pos = state.bMarks[nextLine] + state.tShift[nextLine];
+ if (pos >= state.eMarks[nextLine]) { return false; }
+
+ firstCh = state.src.charCodeAt(pos++);
+ if (firstCh !== 0x7C/* | */ && firstCh !== 0x2D/* - */ && firstCh !== 0x3A/* : */) { return false; }
+
+ if (pos >= state.eMarks[nextLine]) { return false; }
+
+ secondCh = state.src.charCodeAt(pos++);
+ if (secondCh !== 0x7C/* | */ && secondCh !== 0x2D/* - */ && secondCh !== 0x3A/* : */ && !isSpace(secondCh)) {
+ return false;
+ }
+
+ // if first character is '-', then second character must not be a space
+ // (due to parsing ambiguity with list)
+ if (firstCh === 0x2D/* - */ && isSpace(secondCh)) { return false; }
+
+ while (pos < state.eMarks[nextLine]) {
+ ch = state.src.charCodeAt(pos);
+
+ if (ch !== 0x7C/* | */ && ch !== 0x2D/* - */ && ch !== 0x3A/* : */ && !isSpace(ch)) { return false; }
+
+ pos++;
+ }
+
+ lineText = getLine(state, startLine + 1);
+
+ columns = lineText.split('|');
+ aligns = [];
+ for (i = 0; i < columns.length; i++) {
+ t = columns[i].trim();
+ if (!t) {
+ // allow empty columns before and after table, but not in between columns;
+ // e.g. allow ` |---| `, disallow ` ---||--- `
+ if (i === 0 || i === columns.length - 1) {
+ continue;
+ } else {
+ return false;
+ }
+ }
+
+ if (!/^:?-+:?$/.test(t)) { return false; }
+ if (t.charCodeAt(t.length - 1) === 0x3A/* : */) {
+ aligns.push(t.charCodeAt(0) === 0x3A/* : */ ? 'center' : 'right');
+ } else if (t.charCodeAt(0) === 0x3A/* : */) {
+ aligns.push('left');
+ } else {
+ aligns.push('');
+ }
+ }
+
+ lineText = getLine(state, startLine).trim();
+ if (lineText.indexOf('|') === -1) { return false; }
+ if (state.sCount[startLine] - state.blkIndent >= 4) { return false; }
+ columns = escapedSplit(lineText);
+ if (columns.length && columns[0] === '') columns.shift();
+ if (columns.length && columns[columns.length - 1] === '') columns.pop();
+
+ // header row will define an amount of columns in the entire table,
+ // and align row should be exactly the same (the rest of the rows can differ)
+ columnCount = columns.length;
+ if (columnCount === 0 || columnCount !== aligns.length) { return false; }
+
+ if (silent) { return true; }
+
+ oldParentType = state.parentType;
+ state.parentType = 'table';
+
+ // use 'blockquote' lists for termination because it's
+ // the most similar to tables
+ terminatorRules = state.md.block.ruler.getRules('blockquote');
+
+ token = state.push('table_open', 'table', 1);
+ token.map = tableLines = [ startLine, 0 ];
+
+ token = state.push('thead_open', 'thead', 1);
+ token.map = [ startLine, startLine + 1 ];
+
+ token = state.push('tr_open', 'tr', 1);
+ token.map = [ startLine, startLine + 1 ];
+
+ for (i = 0; i < columns.length; i++) {
+ token = state.push('th_open', 'th', 1);
+ if (aligns[i]) {
+ token.attrs = [ [ 'style', 'text-align:' + aligns[i] ] ];
+ }
+
+ token = state.push('inline', '', 0);
+ token.content = columns[i].trim();
+ token.children = [];
+
+ token = state.push('th_close', 'th', -1);
+ }
+
+ token = state.push('tr_close', 'tr', -1);
+ token = state.push('thead_close', 'thead', -1);
+
+ for (nextLine = startLine + 2; nextLine < endLine; nextLine++) {
+ if (state.sCount[nextLine] < state.blkIndent) { break; }
+
+ terminate = false;
+ for (i = 0, l = terminatorRules.length; i < l; i++) {
+ if (terminatorRules[i](state, nextLine, endLine, true)) {
+ terminate = true;
+ break;
+ }
+ }
+
+ if (terminate) { break; }
+ lineText = getLine(state, nextLine).trim();
+ if (!lineText) { break; }
+ if (state.sCount[nextLine] - state.blkIndent >= 4) { break; }
+ columns = escapedSplit(lineText);
+ if (columns.length && columns[0] === '') columns.shift();
+ if (columns.length && columns[columns.length - 1] === '') columns.pop();
+
+ if (nextLine === startLine + 2) {
+ token = state.push('tbody_open', 'tbody', 1);
+ token.map = tbodyLines = [ startLine + 2, 0 ];
+ }
+
+ token = state.push('tr_open', 'tr', 1);
+ token.map = [ nextLine, nextLine + 1 ];
+
+ for (i = 0; i < columnCount; i++) {
+ token = state.push('td_open', 'td', 1);
+ if (aligns[i]) {
+ token.attrs = [ [ 'style', 'text-align:' + aligns[i] ] ];
+ }
+
+ token = state.push('inline', '', 0);
+ token.content = columns[i] ? columns[i].trim() : '';
+ token.children = [];
+
+ token = state.push('td_close', 'td', -1);
+ }
+ token = state.push('tr_close', 'tr', -1);
+ }
+
+ if (tbodyLines) {
+ token = state.push('tbody_close', 'tbody', -1);
+ tbodyLines[1] = nextLine;
+ }
+
+ token = state.push('table_close', 'table', -1);
+ tableLines[1] = nextLine;
+
+ state.parentType = oldParentType;
+ state.line = nextLine;
+ return true;
+};