js-markdown
Version:
A markdown language js compiler.
178 lines (151 loc) • 4.08 kB
JavaScript
/**
* match a table
*
* syntax like this:
*
* First Header | Second Header
* ------------- | -------------
* Content Cell | Content Cell
* Content Cell | Content Cell
*
* or
*
* | First Header | Second Header |
* | ------------- | ------------- |
* | Content Cell | Content Cell |
* | Content Cell | Content Cell |
*
* and the separator line may control align, like this:
*
* | Left Aligned | Center Aligned | Right Aligned |
* |:------------- |:---------------:| -------------:|
* | left | center | right |
*
*/
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _Str = _interopRequireDefault(require("../../utils/Str"));
/**
* get the initial table render tree that includes headers
* @param head
* @param separator
* @returns {{type: string, children: [*]}}
*/
function generateTableTree(head, separator) {
return {
type: 'Table',
children: [{
type: 'TableHead',
children: [{
type: 'TableRow',
children: head.map(function (rawValue, index) {
return {
type: 'TableHeadCell',
align: separator[index],
rawValue: rawValue
};
})
}]
}]
};
}
/**
* return a table body root node
* @returns {{type: string, children: Array}}
*/
function generateTableBodyNode() {
return {
type: 'TableBody',
children: []
};
}
/**
* split a table row line
* @param str
* @returns {*|Array}
*/
function calRow(str) {
str = _Str["default"].trim(str, ' \t|');
return str.split(/\s*\|\s*/);
}
/**
* return a table row that includes table data cells
* @param line
* @param separator
* @returns {{type: string, children}}
*/
function generateTableRowNode(line, separator) {
var tableRow = {
type: 'TableRow',
children: separator.map(function (align) {
return {
type: 'TableDataCell',
align: align
};
})
};
for (var i = 0, data = calRow(line), len = data.length; i < len; i++) {
tableRow.children[i].rawValue = data[i];
}
return tableRow;
}
/**
* parse the separator line, and return a align info
* @param str
* @returns {Array}
*/
function calSeparator(str) {
return calRow(str).map(function (item) {
if (item.startsWith(':') && item.endsWith(':')) {
return 'center';
} else if (item.startsWith(':')) {
return 'left';
} else if (item.endsWith(':')) {
return 'right';
} else if (item.endsWith(':')) {
return '';
}
});
}
function parse(line, index, lines, renderTree) {
var reg = /^ {0,3}(\S(?:\\.|[^\\|])*\|.*)(?:\n|$)/,
separatorReg = /^ {0,3}\|?(\s*((\-{3,})|(:\-{2,})|(\-{2,}:)|(:\-{1,}:))\s*\|)+\s*((\-{3,})|(:\-{2,})|(\-{2,}:)|(:\-{1,}:))\s*\|?(?:\n|$)/,
linesLen = lines.length; // if the line is the last line
if (index + 1 >= linesLen) {
return;
}
var separatorLine = lines[index + 1]; // the second line does not like separator
if (!line.match(reg) || !separatorLine.match(separatorReg)) {
return;
}
var head = calRow(line),
separator = calSeparator(separatorLine);
if (head.length !== separator.length) {
return;
}
var block = generateTableTree(head, separator),
tableBody = generateTableBodyNode();
for (index += 2; index < linesLen; index++) {
if (!lines[index].match(reg)) {
index--;
break;
}
tableBody.children.push(generateTableRowNode(lines[index], separator));
} // append table body to table render tree if there are table rows
tableBody.children.length > 0 && block.children.push(tableBody);
return [block, index];
}
function render() {
var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var node = arguments.length > 1 ? arguments[1] : undefined;
return "<table>".concat(data, "</table>");
}
var _default = {
parse: parse,
render: render
};
exports["default"] = _default;