UNPKG

cli-html

Version:
126 lines (92 loc) 3.49 kB
import ansiAlign from 'ansi-align'; import chalk from 'chalk'; import Table from 'cli-table3'; import styleParser from 'inline-style-parser'; import longestLine from 'longest-line'; import { blockTag } from '../tag-helpers/block-tag.js'; import { getAttribute } from '../utils.js'; import { concatTwoBlockTags } from '../utils/concat-block-tags.js'; const { bold, } = chalk; const td = blockTag(); const th = blockTag((value) => bold.red(value)); export const caption = blockTag(); const captions = (tag, context) => blockTag((value) => bold.blue(value))(tag, context); const trVals = (context) => (tr) => { const theadTds = !tr || !tr.childNodes ? null : tr.childNodes.filter((tag) => ['td', 'th'].includes(tag.nodeName)); const theadTdsValue = theadTds ? theadTds.map((tag) => { const det = tag.nodeName === 'td' ? td(tag, context) : th(tag, context); const parsedStyle = styleParser(getAttribute(tag, 'style', '')); const hAlign = getAttribute(tag, 'align') || parsedStyle.find((element) => element.property === 'text-align')?.value; const vAlign = getAttribute(tag, 'valign') || parsedStyle.find((element) => element.property === 'vertical-align')?.value; const colSpan = Number.parseInt(getAttribute(tag, 'colspan', '1'), 10); const rowSpan = Number.parseInt(getAttribute(tag, 'rowspan', '1'), 10); return { content: det && det.value ? det.value : '', hAlign, vAlign, colSpan, rowSpan, }; }) : null; return theadTdsValue; }; const tbodyVals = (context) => (tbody) => { const theadTrs = tbody ? tbody.childNodes.filter((tag) => ['tr'].includes(tag.nodeName)) : null; const theadTrsVals = theadTrs.map(trVals(context)); return theadTrsVals; }; export const table = (tag, context) => { if (!tag.childNodes) { return null; } const captionTag = { ...tag, childNodes: tag.childNodes.filter((child) => child.nodeName === 'caption'), }; const captionsValue = captions(captionTag, context); const tableArray = []; const thead = tag.childNodes.find((child) => child.nodeName === 'thead'); const theadTr = !thead || !thead.childNodes ? null : thead.childNodes.find((child) => child.nodeName === 'tr'); const theadsValue = theadTr ? trVals(context)(theadTr) : null; if (theadsValue && theadsValue[0]) { tableArray.push(theadsValue); } const trs = tag.childNodes.filter((child) => ['tbody'].includes(child.nodeName)); trs.map(tbodyVals(context)).map((value) => tableArray.push(...value)); const tfoot = tag.childNodes.find((child) => child.nodeName === 'tfoot'); const tfootTr = !tfoot || !tfoot.childNodes ? null : tfoot.childNodes.find((child) => child.nodeName === 'tr'); const tfootdsValue = tfootTr ? trVals(context)(tfootTr) : null; if (tfootdsValue && tfootdsValue[0]) { tableArray.push(tfootdsValue); } const tableRender = new Table({}); tableRender.push(...tableArray); const tableString = tableRender.toString(); const longestLineInTable = longestLine(tableString); if (captionsValue && captionsValue.value) { captionsValue.value = `${captionsValue.value}\n${' '.repeat( longestLineInTable, )}`; captionsValue.value = ansiAlign(captionsValue.value); } return { marginTop: 1, value: concatTwoBlockTags(captionsValue, { value: tableString }).value, marginBottom: 1, type: 'block', }; };