function extendedTables({ interruptPatterns = [], skipEmptyRows = true } = {}) { return { extensions: [{ name: 'spanTable', level: 'block', // Is this a block-level or inline-level tokenizer? start(src) { return src.match(/\n *([^\n ].*\|.*)\n/m)?.index; }, // Hint to Marked.js to stop and check for a match tokenizer(src, tokens) { // const regex = this.tokenizer.rules.block.table; let regexString = '^ *([^\\n ].*\\|.*\\n(?: *[^\\s].*\\n)*?)' // Header + ' {0,3}(?:\\| *)?(:?-+(?: *(?:100|[1-9][0-9]?%) *-+)?:? *(?:\\| *:?-+(?: *(?:100|[1-9][0-9]?%) *-+)?:? *)*)(?:\\| *)?' // Align + '(?:\\n((?:(?! *\\n| {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})' // Cells + '(?:\\n+|$)| {0,3}#{1,6}(?:\\s|$)| {0,3}>| {4}[^\\n]| {0,3}(?:`{3,}' + '(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n| {0,3}(?:[*+-]|1[.)]) |' + '<\\/?(?:address|article|aside|base|basefont|blockquote|body' + '|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt' + '|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]' + '|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem' + '|meta|nav|noframes|ol|optgroup|option|p|param|section|source' + '|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul)' + '(?: +|\\n|\\/?>)|<(?:script|pre|style|textarea|!--)endRegex).*(?:\\n|$))*)\\n*|$)'; // Cells regexString = regexString.replace('endRegex', interruptPatterns.map(str => `|(?:${str})`).join('')); const widthRegex = / *(?:100|[1-9][0-9]?%) */g; const regex = new RegExp(regexString); const cap = regex.exec(src); if (cap) { const item = { type: 'spanTable', header: cap[1].replace(/\n$/, '').split('\n'), align: cap[2].replace(widthRegex, '').replace(/^ *|\| *$/g, '').split( / *\| */), rows: cap[3]?.trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : [], width: cap[2].replace(/:/g, '').replace(/-+| /g, '').split('|') }; // Get first header row to determine how many columns item.header[0] = splitCells(item.header[0]); const colCount = item.header[0].reduce((length, header) => { return length + header.colspan; }, 0); if (colCount === item.align.length) { item.raw = cap[0]; let i, j, k, row; // Get alignment row (:---:) let l = item.align.length; for (i = 0; i < l; i++) { if (/^ *-+: *$/.test(item.align[i])) { item.align[i] = 'right'; } else if (/^ *:-+: *$/.test(item.align[i])) { item.align[i] = 'center'; } else if (/^ *:-+ *$/.test(item.align[i])) { item.align[i] = 'left'; } else { item.align[i] = null; } } // Get any remaining header rows l = item.header.length; for (i = 1; i < l; i++) { item.header[i] = splitCells(item.header[i], colCount, item.header[i - 1], skipEmptyRows); } // Get main table cells l = item.rows.length; for (i = 0; i < l; i++) { item.rows[i] = splitCells(item.rows[i], colCount, item.rows[i - 1], skipEmptyRows); } // header child tokens l = item.header.length; for (j = 0; j < l; j++) { row = item.header[j]; for (k = 0; k < row.length; k++) { row[k].tokens = []; this.lexer.inline(row[k].text, row[k].tokens); } } // cell child tokens l = item.rows.length; for (j = 0; j < l; j++) { row = item.rows[j]; for (k = 0; k < row.length; k++) { row[k].tokens = []; this.lexer.inline(row[k].text, row[k].tokens); } } return item; } } }, renderer(token) { let i, j, row, cell, col, text; let output = '