UNPKG

js-markdown

Version:
178 lines (151 loc) 4.08 kB
/** * 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 | * */ 'use strict'; 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;