New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

markdown-it-multimd-table

Package Overview
Dependencies
Maintainers
1
Versions
26
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

markdown-it-multimd-table - npm Package Compare versions

Comparing version 1.0.2 to 2.0.1

328

index.js

@@ -1,10 +0,4 @@

// Process definition lists
//
'use strict';
module.exports = function multimd_table_plugin(md) {
function isFilledArray(array) {
return typeof array !== 'undefined' && array.length > 0;
}
function getLine(state, line) {

@@ -21,41 +15,30 @@ var pos = state.bMarks[line] + state.blkIndent,

max = str.length,
escapes = 0,
lastPos = 0,
backTicked = false,
lastBackTick = 0;
escaped = false,
backTicked = false;
while (pos < max) {
for (pos = 0; pos < max; pos++) {
switch (str.charCodeAt(pos)) {
case 0x5c/* \ */:
escapes++;
escaped = true;
break;
case 0x60/* ` */:
if (backTicked || ((escapes & 1) === 0)) {
if (backTicked || !escaped) {
// make \` close code sequence, but not open it;
// the reason is: `\` is correct code block
backTicked = !backTicked;
lastBackTick = pos;
}
escapes = 0;
escaped = false;
break;
case 0x7c/* | */:
if ((escapes & 1) === 0 && !backTicked) {
if (!backTicked && !escaped) {
result.push(str.slice(lastPos, pos));
lastPos = pos + 1;
}
escapes = 0;
escaped = false;
break;
default:
escapes = 0;
escaped = false;
break;
}
pos++;
// If there was an un-closed backtick, go back to just after
// the last backtick, but as if it was a normal character
if (pos === max && backTicked) {
backTicked = false;
pos = lastBackTick + 1;
}
}

@@ -88,203 +71,198 @@

function table(state, startLine, endLine, silent, captionInfo) {
var lineText, i, col, captionLine, headerLine, seperatorLine, nextLine,
columns, columnCount, token, aligns, wraps, colspans, t, tableLines,
tbodyLines, emptyTableBody;
function caption(state, lineText, lineNum, silent) {
var captionInfo, result, token;
// should have at least two lines
if (startLine + 2 > endLine) { return false; }
result = lineText.match(/^\[([^[\]]+)\](\[([^[\]]+)\])?\s*$/);
if (!result) { return false; }
if (silent) { return true; }
seperatorLine = startLine + 1;
if (state.sCount[seperatorLine] < state.blkIndent) { return false; }
// if it's indented more than 3 spaces, it should be a code block
if (state.sCount[seperatorLine] - state.blkIndent >= 4) { return false; }
captionInfo = { caption: null, label: null };
captionInfo.content = result[1];
captionInfo.label = result[2] || result[1];
while (!isFilledArray(aligns)) {
lineText = getLine(state, seperatorLine);
columns = lineText.split('|');
if (columns.length === 1 && !/^\||[^\\]\|$/.test(lineText)) { return false; }
aligns = [];
wraps = [];
for (i = 0; i < columns.length; i++) {
t = columns[i].trim();
if (!t && (i === 0 || i === columns.length - 1)) {
continue;
} else if (!/^:?(-+|=+):?\+?$/.test(t)) {
// might be another header line, so initialize
seperatorLine++;
aligns = [];
wraps = [];
break;
}
token = state.push('caption_open', 'caption', 1);
token.map = [ lineNum, lineNum + 1 ];
token.attrs = [ [ 'id', captionInfo.label.toLowerCase().replace(/\W+/g, '') ] ];
// pushed as wraps[i]
wraps.push(t.charCodeAt(t.length - 1) === 0x2B/* + */);
if (wraps[i]) { t = t.slice(0, -1); }
token = state.push('inline', '', 0);
token.content = captionInfo.content;
token.map = [ lineNum, lineNum + 1 ];
token.children = [];
switch (((t.charCodeAt(0) === 0x3A/* : */) << 4) +
(t.charCodeAt(t.length - 1) === 0x3A/* : */)) {
case 0x00: aligns.push(''); break;
case 0x01: aligns.push('right'); break;
case 0x10: aligns.push('left'); break;
case 0x11: aligns.push('center'); break;
}
}
}
token = state.push('caption_close', 'caption', -1);
for (headerLine = startLine; headerLine < seperatorLine; headerLine++) {
lineText = getLine(state, headerLine).trim();
if (lineText.indexOf('|') === -1) { return false; }
if (state.sCount[startLine] - state.blkIndent >= 4) { return false; }
return captionInfo;
}
// header row will define an amount of columns in the entire table,
// and align row shouldn't be smaller than that (the rest of the rows can)
columnCount = escapedSplit(lineText.replace(/^\||\|$/g, '')).length;
if (columnCount > aligns.length) { return false; }
if (columnCount === 1 && !/^\||[^\\]\|$/.test(lineText)) { return false; }
}
function tableRow(state, lineText, lineNum, silent, seperatorInfo, rowType) {
var rowInfo, columns, token, i, col;
columns = escapedSplit(lineText.replace(/^\||([^\\])\|$/g, '$1'));
// lineText does not contain valid pipe character
if (columns.length === 1 && !/^\||[^\\]\|$/.test(lineText)) { return false; }
if (silent) { return true; }
// console.log(lineText + ': ' + columns.length);
token = state.push('table_open', 'table', 1);
token.map = tableLines = [ startLine, 0 ];
rowInfo = { colspans: null, columns: null };
rowInfo.columns = columns.filter(Boolean);
rowInfo.colspans = countColspan(columns);
if (captionInfo[0]) {
captionLine = (captionInfo[2] & 0x10) ? startLine - 1 : endLine + 1;
token = state.push('tr_open', 'tr', 1);
token.map = [ lineNum, lineNum + 1 ];
token = state.push('caption_open', 'caption', 1);
token.map = [ captionLine, captionLine + 1 ];
token.attrs = [ [ 'id', captionInfo[1].toLowerCase().replace(/\W+/g, '') ] ];
for (i = 0, col = 0; i < rowInfo.columns.length && col < seperatorInfo.aligns.length;
col += rowInfo.colspans[i], i++) {
// console.log(col)
token = state.push(rowType + '_open', rowType, 1);
token.map = [ lineNum, lineNum + 1 ];
token.attrs = [];
if (seperatorInfo.aligns[col]) {
token.attrs.push([ 'style', 'text-align:' + seperatorInfo.aligns[col] ]);
}
if (seperatorInfo.wraps[col]) {
token.attrs.push([ 'class', 'extend' ]);
}
if (rowInfo.colspans[i] > 1) {
token.attrs.push([ 'colspan', rowInfo.colspans[i] ]);
}
token = state.push('inline', '', 0);
token.content = captionInfo[0];
token.map = [ captionLine, captionLine + 1 ];
token.content = rowInfo.columns[i].trim();
token.map = [ lineNum, lineNum + 1 ];
token.children = [];
token = state.push('caption_close', 'caption', -1);
token = state.push(rowType + '_close', rowType, -1);
}
token = state.push('thead_open', 'thead', 1);
token.map = [ startLine, seperatorLine - 1 ];
token = state.push('tr_close', 'tr', -1);
for (headerLine = startLine; headerLine < seperatorLine; headerLine++) {
lineText = getLine(state, headerLine).trim();
columns = escapedSplit(lineText.replace(/^\||\|$/g, ''));
colspans = countColspan(columns);
return rowInfo;
}
token = state.push('tr_open', 'tr', 1);
token.map = [ startLine, startLine + 1 ];
function seperator(state, lineText, lineNum, silent) {
var columns, seperatorInfo, i, t;
for (i = 0, col = 0; col < columns.length; i++) {
token = state.push('th_open', 'th', 1);
token.map = [ headerLine, headerLine + 1 ];
token.attrs = [];
if (aligns[col]) { token.attrs.push([ 'style', 'text-align:' + aligns[col] ]); }
if (wraps[col]) { token.attrs.push([ 'class', 'extend' ]); }
if (colspans[i] > 1) { token.attrs.push([ 'colspan', colspans[i] ]); }
columns = escapedSplit(lineText.replace(/^\||([^\\])\|$/g, '$1'));
// lineText does not contain valid pipe character
if (columns.length === 1 && !/^\||[^\\]\|$/.test(lineText)) { return false; }
token = state.push('inline', '', 0);
token.content = columns[i].trim();
token.map = [ headerLine, headerLine + 1 ];
token.children = [];
seperatorInfo = { aligns: [], wraps: [] };
token = state.push('th_close', 'th', -1);
for (i = 0; i < columns.length; i++) {
t = columns[i].trim();
// console.log(t);
if (!/^:?(-+|=+):?\+?$/.test(t)) { return false; }
col += colspans[i] || 1;
seperatorInfo.wraps.push(t.charCodeAt(t.length - 1) === 0x2B/* + */);
if (seperatorInfo.wraps[i]) { t = t.slice(0, -1); }
switch (((t.charCodeAt(0) === 0x3A/* : */) << 4) +
(t.charCodeAt(t.length - 1) === 0x3A/* : */)) {
case 0x00: seperatorInfo.aligns.push(''); break;
case 0x01: seperatorInfo.aligns.push('right'); break;
case 0x10: seperatorInfo.aligns.push('left'); break;
case 0x11: seperatorInfo.aligns.push('center'); break;
}
token = state.push('tr_close', 'tr', -1);
}
token = state.push('thead_close', 'thead', -1);
return silent || seperatorInfo;
}
token = state.push('tbody_open', 'tbody', 1);
token.map = tbodyLines = [ seperatorLine + 1, 0 ];
function table(state, startLine, endLine, silent) {
// Regex pseudo code for table:
// caption? tableRow+ seperator (tableRow+ | empty)* caption?
var seperatorLine, captionAtFirst, captionAtLast, lineText, nextLine,
seperatorInfo, token, tableLines,
tbodyLines, emptyTBody;
emptyTableBody = true;
if (startLine + 2 > endLine) { return false; }
if (state.sCount[startLine] - state.blkIndent >= 4) { return false; }
for (nextLine = seperatorLine + 1; nextLine < endLine; nextLine++) {
if (state.sCount[nextLine] < state.blkIndent) { break; }
captionAtFirst = captionAtLast = false;
// first line
lineText = getLine(state, startLine).trim();
if (caption(state, lineText, startLine, true)) {
captionAtFirst = true;
} else if (!tableRow(state, lineText, startLine, true, null, 'tr')) {
return false;
}
// second line ~ seperator line
for (nextLine = startLine + 1; nextLine < endLine; nextLine++) {
if (state.sCount[nextLine] - state.blkIndent >= 4) { return false; }
lineText = getLine(state, nextLine).trim();
// HACK: avoid outer while loop
if (!lineText && !emptyTableBody) {
tbodyLines[1] = nextLine - 1;
token = state.push('tbody_close', 'tbody', -1);
token = state.push('tbody_open', 'tbody', 1);
token.map = tbodyLines = [ nextLine + 1, 0 ];
emptyTableBody = true;
if (seperator(state, lineText, nextLine, true)) {
seperatorLine = nextLine;
break;
} else if (tableRow(state, lineText, nextLine, true, null, 'th')) {
continue;
} else if (!lineText) {
break;
} else {
return false;
}
}
if (!seperatorLine) { return false; }
if (silent) { return true; }
if (lineText.indexOf('|') === -1) { break; }
if (state.sCount[nextLine] - state.blkIndent >= 4) { break; }
columns = escapedSplit(lineText.replace(/^\||\|$/g, ''));
if (columns.length === 1 && !/^\||[^\\]\|$/.test(lineText)) { break; }
colspans = countColspan(columns);
token = state.push('table_open', 'table', 1);
token.map = tableLines = [ startLine, 0 ];
emptyTableBody = false;
seperatorInfo = seperator(state, lineText, seperatorLine, false);
token = state.push('tr_open', 'tr', 1);
for (i = 0, col = 0; col < columnCount; i++) {
token = state.push('td_open', 'td', 1);
token.attrs = [];
if (aligns[col]) { token.attrs.push([ 'style', 'text-align:' + aligns[col] ]); }
if (wraps[col]) { token.attrs.push([ 'class', 'extend' ]); }
if (colspans[i] > 1) { token.attrs.push([ 'colspan', colspans[i] ]); }
if (captionAtFirst) {
lineText = getLine(state, startLine).trim();
caption(state, lineText, startLine, false);
}
token = state.push('inline', '', 0);
token.content = columns[i] ? columns[i].trim() : '';
token.children = [];
token = state.push('thead_open', 'thead', 1);
token.map = [ startLine + captionAtFirst, seperatorLine ];
token = state.push('td_close', 'td', -1);
for (nextLine = startLine + captionAtFirst; nextLine < seperatorLine; nextLine++) {
col += colspans[i] || 1;
}
token = state.push('tr_close', 'tr', -1);
lineText = getLine(state, nextLine).trim();
tableRow(state, lineText, nextLine, false, seperatorInfo, 'th');
}
token = state.push('tbody_close', 'tbody', -1);
token = state.push('table_close', 'table', -1);
tableLines[1] = tbodyLines[1] = nextLine;
state.line = nextLine;
return true;
}
token = state.push('thead_close', 'thead', -1);
function tableWithCaption(state, startLine, endLine, silent) {
var lineText, result, captionInfo;
emptyTBody = true;
// captionInfo: [ caption, label, captionLinePos ]
captionInfo = [ null, null, 0 ];
token = state.push('tbody_open', 'tbody', 1);
token.map = tbodyLines = [ seperatorLine + 1, 0 ];
lineText = getLine(state, endLine - 1);
result = lineText.match(/^\[([^[\]]+)\](\[([^[\]]+)\])?\s*$/);
if (result) {
captionInfo = [ result[1],
result[2] || result[1],
captionInfo[2] | 0x01 ];
}
for (nextLine = seperatorLine + 1; nextLine < endLine; nextLine++) {
lineText = getLine(state, nextLine).trim();
lineText = getLine(state, startLine);
result = lineText.match(/^\[([^[\]]+)\](\[([^[\]]+)\])?\s*$/);
if (result) {
captionInfo = [ result[1],
result[2] || result[1],
captionInfo[2] | 0x10 ];
if (state.sCount[nextLine] - state.blkIndent >= 4) {
break;
} else if (!captionAtFirst && caption(state, lineText, nextLine, true)) {
captionAtLast = true;
break;
} else if (tableRow(state, lineText, nextLine, false, seperatorInfo, 'td')) {
emptyTBody = false;
} else if (!emptyTBody && !lineText) {
tbodyLines[1] = nextLine - 1;
token = state.push('tbody_close', 'tbody', -1);
token = state.push('tbody_open', 'tbody', 1);
token.map = tbodyLines = [ nextLine + 1, 0 ];
emptyTBody = true;
} else {
break;
}
}
token = state.push('tbody_close', 'tbody', -1);
result = table(state,
startLine + ((captionInfo[2] & 0x10) === 0x10),
endLine - ((captionInfo[2] & 0x01) === 0x01),
silent, captionInfo);
if (result && !silent) {
state.line += (captionInfo[2] & 0x01);
if (captionAtLast) {
caption(state, lineText, nextLine, false);
nextLine++;
}
return result;
token = state.push('table_close', 'table', -1);
tableLines[1] = tbodyLines[1] = nextLine;
state.line = nextLine;
return true;
}
md.block.ruler.at('table', tableWithCaption, { alt: [ 'paragraph', 'reference' ] });
md.block.ruler.at('table', table, { alt: [ 'paragraph', 'reference' ] });
};
{
"name": "markdown-it-multimd-table",
"version": "1.0.2",
"version": "2.0.1",
"description": "Multimarkdown table syntax plugin for markdown-it markdown parser",

@@ -5,0 +5,0 @@ "keywords": [

@@ -33,3 +33,3 @@ [![NPM version](https://img.shields.io/npm/v/markdown-it-multimd-table.svg?style=flat)](https://www.npmjs.org/package/markdown-it-multimd-table)

var md = require('markdown-it')()
.use(require('./markdown-it-multimd-table'));
.use(require('markdown-it-multimd-table'));
const exampleTable =

@@ -36,0 +36,0 @@ "| | Grouping || \n" +

@@ -209,3 +209,3 @@ {

],
"object-property-newline": "error",
"object-property-newline": "off",
"object-shorthand": "error",

@@ -222,3 +222,3 @@ "one-var": "error",

"prefer-const": "error",
"prefer-destructuring": "error",
"prefer-destructuring": "off",
"prefer-numeric-literals": "error",

@@ -225,0 +225,0 @@ "prefer-promise-reject-errors": "error",

@@ -1,10 +0,4 @@

// Process definition lists
//
'use strict';
module.exports = function multimd_table_plugin(md) {
function isFilledArray(array) {
return typeof array !== 'undefined' && array.length > 0;
}
function getLine(state, line) {

@@ -21,41 +15,30 @@ var pos = state.bMarks[line] + state.blkIndent,

max = str.length,
escapes = 0,
lastPos = 0,
backTicked = false,
lastBackTick = 0;
escaped = false,
backTicked = false;
while (pos < max) {
for (pos = 0; pos < max; pos++) {
switch (str.charCodeAt(pos)) {
case 0x5c/* \ */:
escapes++;
escaped = true;
break;
case 0x60/* ` */:
if (backTicked || ((escapes & 1) === 0)) {
if (backTicked || !escaped) {
// make \` close code sequence, but not open it;
// the reason is: `\` is correct code block
backTicked = !backTicked;
lastBackTick = pos;
}
escapes = 0;
escaped = false;
break;
case 0x7c/* | */:
if ((escapes & 1) === 0 && !backTicked) {
if (!backTicked && !escaped) {
result.push(str.slice(lastPos, pos));
lastPos = pos + 1;
}
escapes = 0;
escaped = false;
break;
default:
escapes = 0;
escaped = false;
break;
}
pos++;
// If there was an un-closed backtick, go back to just after
// the last backtick, but as if it was a normal character
if (pos === max && backTicked) {
backTicked = false;
pos = lastBackTick + 1;
}
}

@@ -88,203 +71,198 @@

function table(state, startLine, endLine, silent, captionInfo) {
var lineText, i, col, captionLine, headerLine, seperatorLine, nextLine,
columns, columnCount, token, aligns, wraps, colspans, t, tableLines,
tbodyLines, emptyTableBody;
function caption(state, lineText, lineNum, silent) {
var captionInfo, result, token;
// should have at least two lines
if (startLine + 2 > endLine) { return false; }
result = lineText.match(/^\[([^[\]]+)\](\[([^[\]]+)\])?\s*$/);
if (!result) { return false; }
if (silent) { return true; }
seperatorLine = startLine + 1;
if (state.sCount[seperatorLine] < state.blkIndent) { return false; }
// if it's indented more than 3 spaces, it should be a code block
if (state.sCount[seperatorLine] - state.blkIndent >= 4) { return false; }
captionInfo = { caption: null, label: null };
captionInfo.content = result[1];
captionInfo.label = result[2] || result[1];
while (!isFilledArray(aligns)) {
lineText = getLine(state, seperatorLine);
columns = lineText.split('|');
if (columns.length === 1 && !/^\||[^\\]\|$/.test(lineText)) { return false; }
aligns = [];
wraps = [];
for (i = 0; i < columns.length; i++) {
t = columns[i].trim();
if (!t && (i === 0 || i === columns.length - 1)) {
continue;
} else if (!/^:?(-+|=+):?\+?$/.test(t)) {
// might be another header line, so initialize
seperatorLine++;
aligns = [];
wraps = [];
break;
}
token = state.push('caption_open', 'caption', 1);
token.map = [ lineNum, lineNum + 1 ];
token.attrs = [ [ 'id', captionInfo.label.toLowerCase().replace(/\W+/g, '') ] ];
// pushed as wraps[i]
wraps.push(t.charCodeAt(t.length - 1) === 0x2B/* + */);
if (wraps[i]) { t = t.slice(0, -1); }
token = state.push('inline', '', 0);
token.content = captionInfo.content;
token.map = [ lineNum, lineNum + 1 ];
token.children = [];
switch (((t.charCodeAt(0) === 0x3A/* : */) << 4) +
(t.charCodeAt(t.length - 1) === 0x3A/* : */)) {
case 0x00: aligns.push(''); break;
case 0x01: aligns.push('right'); break;
case 0x10: aligns.push('left'); break;
case 0x11: aligns.push('center'); break;
}
}
}
token = state.push('caption_close', 'caption', -1);
for (headerLine = startLine; headerLine < seperatorLine; headerLine++) {
lineText = getLine(state, headerLine).trim();
if (lineText.indexOf('|') === -1) { return false; }
if (state.sCount[startLine] - state.blkIndent >= 4) { return false; }
return captionInfo;
}
// header row will define an amount of columns in the entire table,
// and align row shouldn't be smaller than that (the rest of the rows can)
columnCount = escapedSplit(lineText.replace(/^\||\|$/g, '')).length;
if (columnCount > aligns.length) { return false; }
if (columnCount === 1 && !/^\||[^\\]\|$/.test(lineText)) { return false; }
}
function tableRow(state, lineText, lineNum, silent, seperatorInfo, rowType) {
var rowInfo, columns, token, i, col;
columns = escapedSplit(lineText.replace(/^\||([^\\])\|$/g, '$1'));
// lineText does not contain valid pipe character
if (columns.length === 1 && !/^\||[^\\]\|$/.test(lineText)) { return false; }
if (silent) { return true; }
// console.log(lineText + ': ' + columns.length);
token = state.push('table_open', 'table', 1);
token.map = tableLines = [ startLine, 0 ];
rowInfo = { colspans: null, columns: null };
rowInfo.columns = columns.filter(Boolean);
rowInfo.colspans = countColspan(columns);
if (captionInfo[0]) {
captionLine = (captionInfo[2] & 0x10) ? startLine - 1 : endLine + 1;
token = state.push('tr_open', 'tr', 1);
token.map = [ lineNum, lineNum + 1 ];
token = state.push('caption_open', 'caption', 1);
token.map = [ captionLine, captionLine + 1 ];
token.attrs = [ [ 'id', captionInfo[1].toLowerCase().replace(/\W+/g, '') ] ];
for (i = 0, col = 0; i < rowInfo.columns.length && col < seperatorInfo.aligns.length;
col += rowInfo.colspans[i], i++) {
// console.log(col)
token = state.push(rowType + '_open', rowType, 1);
token.map = [ lineNum, lineNum + 1 ];
token.attrs = [];
if (seperatorInfo.aligns[col]) {
token.attrs.push([ 'style', 'text-align:' + seperatorInfo.aligns[col] ]);
}
if (seperatorInfo.wraps[col]) {
token.attrs.push([ 'class', 'extend' ]);
}
if (rowInfo.colspans[i] > 1) {
token.attrs.push([ 'colspan', rowInfo.colspans[i] ]);
}
token = state.push('inline', '', 0);
token.content = captionInfo[0];
token.map = [ captionLine, captionLine + 1 ];
token.content = rowInfo.columns[i].trim();
token.map = [ lineNum, lineNum + 1 ];
token.children = [];
token = state.push('caption_close', 'caption', -1);
token = state.push(rowType + '_close', rowType, -1);
}
token = state.push('thead_open', 'thead', 1);
token.map = [ startLine, seperatorLine - 1 ];
token = state.push('tr_close', 'tr', -1);
for (headerLine = startLine; headerLine < seperatorLine; headerLine++) {
lineText = getLine(state, headerLine).trim();
columns = escapedSplit(lineText.replace(/^\||\|$/g, ''));
colspans = countColspan(columns);
return rowInfo;
}
token = state.push('tr_open', 'tr', 1);
token.map = [ startLine, startLine + 1 ];
function seperator(state, lineText, lineNum, silent) {
var columns, seperatorInfo, i, t;
for (i = 0, col = 0; col < columns.length; i++) {
token = state.push('th_open', 'th', 1);
token.map = [ headerLine, headerLine + 1 ];
token.attrs = [];
if (aligns[col]) { token.attrs.push([ 'style', 'text-align:' + aligns[col] ]); }
if (wraps[col]) { token.attrs.push([ 'class', 'extend' ]); }
if (colspans[i] > 1) { token.attrs.push([ 'colspan', colspans[i] ]); }
columns = escapedSplit(lineText.replace(/^\||([^\\])\|$/g, '$1'));
// lineText does not contain valid pipe character
if (columns.length === 1 && !/^\||[^\\]\|$/.test(lineText)) { return false; }
token = state.push('inline', '', 0);
token.content = columns[i].trim();
token.map = [ headerLine, headerLine + 1 ];
token.children = [];
seperatorInfo = { aligns: [], wraps: [] };
token = state.push('th_close', 'th', -1);
for (i = 0; i < columns.length; i++) {
t = columns[i].trim();
// console.log(t);
if (!/^:?(-+|=+):?\+?$/.test(t)) { return false; }
col += colspans[i] || 1;
seperatorInfo.wraps.push(t.charCodeAt(t.length - 1) === 0x2B/* + */);
if (seperatorInfo.wraps[i]) { t = t.slice(0, -1); }
switch (((t.charCodeAt(0) === 0x3A/* : */) << 4) +
(t.charCodeAt(t.length - 1) === 0x3A/* : */)) {
case 0x00: seperatorInfo.aligns.push(''); break;
case 0x01: seperatorInfo.aligns.push('right'); break;
case 0x10: seperatorInfo.aligns.push('left'); break;
case 0x11: seperatorInfo.aligns.push('center'); break;
}
token = state.push('tr_close', 'tr', -1);
}
token = state.push('thead_close', 'thead', -1);
return silent || seperatorInfo;
}
token = state.push('tbody_open', 'tbody', 1);
token.map = tbodyLines = [ seperatorLine + 1, 0 ];
function table(state, startLine, endLine, silent) {
// Regex pseudo code for table:
// caption? tableRow+ seperator (tableRow+ | empty)* caption?
var seperatorLine, captionAtFirst, captionAtLast, lineText, nextLine,
seperatorInfo, token, tableLines,
tbodyLines, emptyTBody;
emptyTableBody = true;
if (startLine + 2 > endLine) { return false; }
if (state.sCount[startLine] - state.blkIndent >= 4) { return false; }
for (nextLine = seperatorLine + 1; nextLine < endLine; nextLine++) {
if (state.sCount[nextLine] < state.blkIndent) { break; }
captionAtFirst = captionAtLast = false;
// first line
lineText = getLine(state, startLine).trim();
if (caption(state, lineText, startLine, true)) {
captionAtFirst = true;
} else if (!tableRow(state, lineText, startLine, true, null, 'tr')) {
return false;
}
// second line ~ seperator line
for (nextLine = startLine + 1; nextLine < endLine; nextLine++) {
if (state.sCount[nextLine] - state.blkIndent >= 4) { return false; }
lineText = getLine(state, nextLine).trim();
// HACK: avoid outer while loop
if (!lineText && !emptyTableBody) {
tbodyLines[1] = nextLine - 1;
token = state.push('tbody_close', 'tbody', -1);
token = state.push('tbody_open', 'tbody', 1);
token.map = tbodyLines = [ nextLine + 1, 0 ];
emptyTableBody = true;
if (seperator(state, lineText, nextLine, true)) {
seperatorLine = nextLine;
break;
} else if (tableRow(state, lineText, nextLine, true, null, 'th')) {
continue;
} else if (!lineText) {
break;
} else {
return false;
}
}
if (!seperatorLine) { return false; }
if (silent) { return true; }
if (lineText.indexOf('|') === -1) { break; }
if (state.sCount[nextLine] - state.blkIndent >= 4) { break; }
columns = escapedSplit(lineText.replace(/^\||\|$/g, ''));
if (columns.length === 1 && !/^\||[^\\]\|$/.test(lineText)) { break; }
colspans = countColspan(columns);
token = state.push('table_open', 'table', 1);
token.map = tableLines = [ startLine, 0 ];
emptyTableBody = false;
seperatorInfo = seperator(state, lineText, seperatorLine, false);
token = state.push('tr_open', 'tr', 1);
for (i = 0, col = 0; col < columnCount; i++) {
token = state.push('td_open', 'td', 1);
token.attrs = [];
if (aligns[col]) { token.attrs.push([ 'style', 'text-align:' + aligns[col] ]); }
if (wraps[col]) { token.attrs.push([ 'class', 'extend' ]); }
if (colspans[i] > 1) { token.attrs.push([ 'colspan', colspans[i] ]); }
if (captionAtFirst) {
lineText = getLine(state, startLine).trim();
caption(state, lineText, startLine, false);
}
token = state.push('inline', '', 0);
token.content = columns[i] ? columns[i].trim() : '';
token.children = [];
token = state.push('thead_open', 'thead', 1);
token.map = [ startLine + captionAtFirst, seperatorLine ];
token = state.push('td_close', 'td', -1);
for (nextLine = startLine + captionAtFirst; nextLine < seperatorLine; nextLine++) {
col += colspans[i] || 1;
}
token = state.push('tr_close', 'tr', -1);
lineText = getLine(state, nextLine).trim();
tableRow(state, lineText, nextLine, false, seperatorInfo, 'th');
}
token = state.push('tbody_close', 'tbody', -1);
token = state.push('table_close', 'table', -1);
tableLines[1] = tbodyLines[1] = nextLine;
state.line = nextLine;
return true;
}
token = state.push('thead_close', 'thead', -1);
function tableWithCaption(state, startLine, endLine, silent) {
var lineText, result, captionInfo;
emptyTBody = true;
// captionInfo: [ caption, label, captionLinePos ]
captionInfo = [ null, null, 0 ];
token = state.push('tbody_open', 'tbody', 1);
token.map = tbodyLines = [ seperatorLine + 1, 0 ];
lineText = getLine(state, endLine - 1);
result = lineText.match(/^\[([^[\]]+)\](\[([^[\]]+)\])?\s*$/);
if (result) {
captionInfo = [ result[1],
result[2] || result[1],
captionInfo[2] | 0x01 ];
}
for (nextLine = seperatorLine + 1; nextLine < endLine; nextLine++) {
lineText = getLine(state, nextLine).trim();
lineText = getLine(state, startLine);
result = lineText.match(/^\[([^[\]]+)\](\[([^[\]]+)\])?\s*$/);
if (result) {
captionInfo = [ result[1],
result[2] || result[1],
captionInfo[2] | 0x10 ];
if (state.sCount[nextLine] - state.blkIndent >= 4) {
break;
} else if (!captionAtFirst && caption(state, lineText, nextLine, true)) {
captionAtLast = true;
break;
} else if (tableRow(state, lineText, nextLine, false, seperatorInfo, 'td')) {
emptyTBody = false;
} else if (!emptyTBody && !lineText) {
tbodyLines[1] = nextLine - 1;
token = state.push('tbody_close', 'tbody', -1);
token = state.push('tbody_open', 'tbody', 1);
token.map = tbodyLines = [ nextLine + 1, 0 ];
emptyTBody = true;
} else {
break;
}
}
token = state.push('tbody_close', 'tbody', -1);
result = table(state,
startLine + ((captionInfo[2] & 0x10) === 0x10),
endLine - ((captionInfo[2] & 0x01) === 0x01),
silent, captionInfo);
if (result && !silent) {
state.line += (captionInfo[2] & 0x01);
if (captionAtLast) {
caption(state, lineText, nextLine, false);
nextLine++;
}
return result;
token = state.push('table_close', 'table', -1);
tableLines[1] = tbodyLines[1] = nextLine;
state.line = nextLine;
return true;
}
md.block.ruler.at('table', tableWithCaption, { alt: [ 'paragraph', 'reference' ] });
md.block.ruler.at('table', table, { alt: [ 'paragraph', 'reference' ] });
};

@@ -36,6 +36,8 @@ # MultiMarkdown Tables: Other Notes

## It is optional whether you have | characters at the beginning and end of lines.
## Note 1
It is optional whether you have `|` characters at the beginning and end of lines.
> NOTE: Defined in PHP Markdown Extra. Test cases ignored.
## The “separator” line uses ---- or ==== to indicate the line between a header and cell. The length of the line doesn’t matter, but must have at least one character per cell.
## Note 2
The “separator” line uses `----` or `====` to indicate the line between a header and cell. The length of the line doesn’t matter, but must have at least one character per cell.

@@ -55,3 +57,4 @@ ```markdown

## To set alignment, you can use a colon to designate left or right alignment, or a colon at each end to designate center alignment, as above. If no colon is present, the default alignment of your system is selected (left in most cases). If the separator line ends with +, then cells in that column will be wrapped when exporting to LaTeX if they are long enough.
## Note 3
To set alignment, you can use a colon to designate left or right alignment, or a colon at each end to designate center alignment, as above. If no colon is present, the default alignment of your system is selected (left in most cases). If the separator line ends with +, then cells in that column will be wrapped when exporting to LaTeX if they are long enough.

@@ -88,3 +91,4 @@ ```markdown

## To indicate that a cell should span multiple columns, then simply add additional pipes (|) at the end of the cell, as shown in the example. If the cell in question is at the end of the row, then of course that means that pipes are not optional at the end of that row…. The number of pipes equals the number of columns the cell should span.
## Note 4
To indicate that a cell should span multiple columns, then simply add additional pipes (`|`) at the end of the cell, as shown in the example. If the cell in question is at the end of the row, then of course that means that pipes are not optional at the end of that row…. The number of pipes equals the number of columns the cell should span.

@@ -142,3 +146,2 @@ ```markdown

<td colspan="2"><em>Long Cell</em></td>
<td style="text-align:right"></td>
</tr>

@@ -151,6 +154,8 @@ <tr>

```
## You can use normal Markdown markup within the table cells.
## Note 5
You can use normal Markdown markup within the table cells.
> NOTE: From Definitions of PHP Markdown Extra, "normal" means "inline". If in this case, test cases are ignored.
## Captions are optional, but if present must be at the beginning of the line immediately preceding or following the table, start with [, and end with ]. If you have a caption before and after the table, only the first match will be used.
## Note 6
Captions are optional, but if present must be at the beginning of the line immediately preceding or following the table, start with `[`, and end with `]`. If you have a caption before and after the table, only the first match will be used.
> NOTE: Assumed that caption has higher priority than table content, as the next example

@@ -168,3 +173,2 @@

<table>
<caption id=""> | | </caption>
<thead>

@@ -192,2 +196,3 @@ <tr>

</tbody>
<caption id=""> | | </caption>
</table>

@@ -231,5 +236,7 @@ ```

</table>
<p>[Prototype table caption]</p>
```
## If you have a caption, you can also have a label, allowing you to create anchors pointing to the table. If there is no label, then the caption acts as the label
## Note 7
If you have a caption, you can also have a label, allowing you to create anchors pointing to the table. If there is no label, then the caption acts as the label

@@ -271,5 +278,7 @@ ```markdown

</table>
<p>[Prototype table caption][label2]</p>
```
## Cells can be empty.
## Note 8
Cells can be empty.
> Assumed must with pipe characters on its both side

@@ -287,3 +296,2 @@

<table>
<caption id="prototypetable">Prototype table</caption>
<thead>

@@ -311,6 +319,8 @@ <tr>

</tbody>
<caption id="prototypetable">Prototype table</caption>
</table>
```
## You can create multiple <tbody> tags (for HTML) within a table by having a single empty line between rows of the table. This allows your CSS to place horizontal borders to emphasize different sections of the table. This feature doesn’t work in all output formats (e.g. RTF and OpenDocument).
## Note 9
You can create multiple <tbody> tags (for HTML) within a table by having a single empty line between rows of the table. This allows your CSS to place horizontal borders to emphasize different sections of the table. This feature doesn’t work in all output formats (e.g. RTF and OpenDocument).
> NOTE: any empty tbody is not allowed

@@ -331,3 +341,2 @@

<table>
<caption id="prototypetable">Prototype table</caption>
<thead>

@@ -366,2 +375,3 @@ <tr>

</tbody>
<caption id="prototypetable">Prototype table</caption>
</table>

@@ -384,3 +394,2 @@ ```

<table>
<caption id="prototypetable">Prototype table</caption>
<thead>

@@ -387,0 +396,0 @@ <tr>

@@ -36,3 +36,3 @@ # MultiMarkdown Tables: Other Notes

## There must be at least one | per line
## Requirement 1: There must be at least one | per line
> NOTE: Assumed legal pipe chars, could be leading, tailing or both

@@ -59,4 +59,2 @@

<td>Content | <strong>Cell</strong> | Cell</td>
<td style="text-align:center"></td>
<td style="text-align:right"></td>
</tr>

@@ -82,3 +80,3 @@ </tbody>

## The “separator” line between headers and table content must contain only |,-, =, :,., +, or spaces
## Requirement 2: The “separator” line between headers and table content must contain only |,-, =, :,., +, or spaces
> NOTE: no implementation details about denoting wrappable, follows MultiMarkdown-5 `extend` class

@@ -116,3 +114,3 @@

## Cell content must be on one line only
## Requirement 3: Cell content must be on one line only

@@ -144,3 +142,2 @@ ```markdown

<td style="text-align:center">1. More</td>
<td style="text-align:right"></td>
</tr>

@@ -153,6 +150,6 @@ </tbody>

## Columns are separated by |
## Requirement 4: Columns are separated by |
> NOTE: Defined in PHP Markdown Extra. Test cases ignored.
## The first line of the table, and the alignment/divider line, must start at the beginning of the line
## Requirement 5: The first line of the table, and the alignment/divider line, must start at the beginning of the line
> NOTE: The example in MultiMarkdown breaks this requirement. I altered this rule as follows:

@@ -159,0 +156,0 @@ > The headers of the table, and the alignment/divider line, must start at the beginning of the line

@@ -5,2 +5,3 @@ # Markdown Table Basics

Simple:
.

@@ -33,2 +34,3 @@ First Header | Second Header

Leading and Tailing pipes:
.

@@ -61,2 +63,3 @@ | First Header | Second Header |

Alignments:
.

@@ -94,2 +97,3 @@ | Item | Value |

Span-level Formatting:
.

@@ -96,0 +100,0 @@ | Function name | Description |

@@ -6,2 +6,3 @@ # MultiMarkdown Tables: Other Notes

.

@@ -36,7 +37,10 @@ First Header | Second Header | Third Header |

It is optional whether you have | characters at the beginning and end of lines.:
Note 1:
It is optional whether you have `|` characters at the beginning and end of lines.
NOTE: Defined in PHP Markdown Extra. Test cases ignored.
The “separator” line uses ---- or ==== to indicate the line between a header and cell. The length of the line doesn’t matter, but must have at least one character per cell.:
Note 2:
The “separator” line uses `----` or `====` to indicate the line between a header and cell. The length of the line doesn’t matter, but must have at least one character per cell.
.

@@ -54,4 +58,6 @@ First Header | Second Header | Third Header |

To set alignment, you can use a colon to designate left or right alignment, or a colon at each end to designate center alignment, as above. If no colon is present, the default alignment of your system is selected (left in most cases). If the separator line ends with +, then cells in that column will be wrapped when exporting to LaTeX if they are long enough.:
Note 3:
To set alignment, you can use a colon to designate left or right alignment, or a colon at each end to designate center alignment, as above. If no colon is present, the default alignment of your system is selected (left in most cases). If the separator line ends with +, then cells in that column will be wrapped when exporting to LaTeX if they are long enough.
.

@@ -86,4 +92,6 @@ First Header | Second Header | Third Header |

To indicate that a cell should span multiple columns, then simply add additional pipes (|) at the end of the cell, as shown in the example. If the cell in question is at the end of the row, then of course that means that pipes are not optional at the end of that row…. The number of pipes equals the number of columns the cell should span.:
Note 4:
To indicate that a cell should span multiple columns, then simply add additional pipes (`|`) at the end of the cell, as shown in the example. If the cell in question is at the end of the row, then of course that means that pipes are not optional at the end of that row…. The number of pipes equals the number of columns the cell should span.
.

@@ -122,2 +130,3 @@ | | Grouping ||

.

@@ -139,3 +148,2 @@ | | Grouping ||

<td colspan="2"><em>Long Cell</em></td>
<td style="text-align:right"></td>
</tr>

@@ -148,8 +156,11 @@ <tr>

.
You can use normal Markdown markup within the table cells.:
Note 5:
You can use normal Markdown markup within the table cells.
NOTE: From Definitions of PHP Markdown Extra, "normal" means "inline". If in this case, test cases are ignored.
Captions are optional, but if present must be at the beginning of the line immediately preceding or following the table, start with [, and end with ]. If you have a caption before and after the table, only the first match will be used.:
Note 6:
Captions are optional, but if present must be at the beginning of the line immediately preceding or following the table, start with `[`, and end with `]`. If you have a caption before and after the table, only the first match will be used.
NOTE: Assumed that caption has higher priority than table content, as the next example
.

@@ -164,3 +175,2 @@ | | Grouping ||

<table>
<caption id=""> | | </caption>
<thead>

@@ -188,5 +198,7 @@ <tr>

</tbody>
<caption id=""> | | </caption>
</table>
.
.

@@ -226,6 +238,9 @@ [Prototype table]

</table>
<p>[Prototype table caption]</p>
.
If you have a caption, you can also have a label, allowing you to create anchors pointing to the table. If there is no label, then the caption acts as the label:
Note 7:
If you have a caption, you can also have a label, allowing you to create anchors pointing to the table. If there is no label, then the caption acts as the label
.

@@ -265,7 +280,10 @@ [Prototype table][label1]

</table>
<p>[Prototype table caption][label2]</p>
.
Cells can be empty.:
Note 8:
Cells can be empty.
Assumed must with pipe characters on its both side
.

@@ -280,3 +298,2 @@ | | ||

<table>
<caption id="prototypetable">Prototype table</caption>
<thead>

@@ -304,8 +321,11 @@ <tr>

</tbody>
<caption id="prototypetable">Prototype table</caption>
</table>
.
You can create multiple <tbody> tags (for HTML) within a table by having a single empty line between rows of the table. This allows your CSS to place horizontal borders to emphasize different sections of the table. This feature doesn’t work in all output formats (e.g. RTF and OpenDocument).:
Note 9:
You can create multiple <tbody> tags (for HTML) within a table by having a single empty line between rows of the table. This allows your CSS to place horizontal borders to emphasize different sections of the table. This feature doesn’t work in all output formats (e.g. RTF and OpenDocument).
NOTE: any empty tbody is not allowed
.

@@ -323,3 +343,2 @@ | | Grouping ||

<table>
<caption id="prototypetable">Prototype table</caption>
<thead>

@@ -358,5 +377,7 @@ <tr>

</tbody>
<caption id="prototypetable">Prototype table</caption>
</table>
.
.

@@ -375,3 +396,2 @@ | | Grouping ||

<table>
<caption id="prototypetable">Prototype table</caption>
<thead>

@@ -378,0 +398,0 @@ <tr>

@@ -6,2 +6,3 @@ # MultiMarkdown Tables: Other Notes

.

@@ -36,6 +37,7 @@ First Header | Second Header | Third Header |

There must be at least one | per line:
Requirement 1: There must be at least one | per line:
NOTE: Assumed legal pipe chars, could be leading, tailing or both
(Against at line 4)
.

@@ -58,4 +60,2 @@ First Header | Second Header | Third Header |

<td>Content | <strong>Cell</strong> | Cell</td>
<td style="text-align:center"></td>
<td style="text-align:right"></td>
</tr>

@@ -68,2 +68,3 @@ </tbody>

(Against at line 1)
.

@@ -81,5 +82,6 @@ First Header \| Second Header`|`Third Header\|

The “separator” line between headers and table content must contain only |,-, =, :,., +, or spaces:
Requirement 2: The “separator” line between headers and table content must contain only |,-, =, :,., +, or spaces:
NOTE: no implementation details about denoting wrappable, follows MultiMarkdown-5 `extend` class
.

@@ -114,4 +116,5 @@ First Header | Second Header | Third Header |

Cell content must be on one line only:
Requirement 3: Cell content must be on one line only:
.

@@ -141,3 +144,2 @@ First Header | Second Header | Third Header |

<td style="text-align:center">1. More</td>
<td style="text-align:right"></td>
</tr>

@@ -150,6 +152,6 @@ </tbody>

Columns are separated by |:
Requirement 4: Columns are separated by |:
NOTE: Defined in PHP Markdown Extra. Test cases ignored.
The first line of the table, and the alignment/divider line, must start at the beginning of the line:
Requirement 5: The first line of the table, and the alignment/divider line, must start at the beginning of the line:
NOTE: The example in MultiMarkdown breaks this requirement. I altered this rule as follows:

@@ -159,2 +161,3 @@ The headers of the table, and the alignment/divider line, must start at the beginning of the line

.

@@ -201,2 +204,3 @@ | | Grouping | |

.

@@ -243,2 +247,3 @@ | | Grouping | |

.

@@ -245,0 +250,0 @@ | | Grouping | |

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc