UNPKG

myst-to-typst

Version:
68 lines (67 loc) 2.53 kB
import { fileError } from 'myst-common'; function countColumns(table) { const firstRow = table.children?.find((child) => child.type === 'tableRow'); const columns = firstRow?.children ?.filter((cell) => cell.type === 'tableCell') .reduce((val, cell) => val + (cell.colspan ?? 1), 0); return columns; } function isHeaderRow(node) { if (node.type !== 'tableRow') return false; return node.children ?.filter((child) => child.type === 'tableCell') .every((child) => child.header); } function countHeaderRows(table) { const headerRows = table.children?.filter((child) => isHeaderRow(child)); return headerRows?.length ?? 0; } export const tableHandler = (node, state) => { const prevState = state.data.isInTable; state.data.isInTable = true; const command = state.data.isInFigure ? 'tablex' : '#tablex'; const columns = countColumns(node); if (!columns) { fileError(state.file, 'Unable to count table columns', { node, source: 'myst-to-typst', }); return; } state.useMacro('#import "@preview/tablex:0.0.9": tablex, cellx, hlinex, vlinex'); // These two separate style hooks are somewhat redundant, but they allow defining // article-wide styles and single-table styles separately state.useMacro('#let tableStyle = (:)'); state.useMacro('#let columnStyle = (:)'); state.write(`${command}(columns: ${columns}, header-rows: ${countHeaderRows(node)}, repeat-header: true, ..tableStyle, ..columnStyle,\n`); state.renderChildren(node, 1); state.write(')\n'); state.data.isInTable = prevState; }; export const tableRowHandler = (node, state) => { state.renderChildren(node, 1); }; export const tableCellHandler = (node, state) => { if (node.rowspan || node.colspan || node.align || node.style?.backgroundColor) { state.write('cellx('); if (node.rowspan) { state.write(`rowspan: ${node.rowspan}, `); } if (node.colspan) { state.write(`colspan: ${node.colspan}, `); } if (node.align) { state.write(`align: ${node.align}, `); } if (node.style?.backgroundColor) { const fill = node.style.backgroundColor; const rgb = fill.startsWith('#'); state.write(`fill: ${rgb ? `rgb("${fill}")` : fill}, `); } state.write(')'); } state.write('[\n'); state.renderChildren(node, 1); state.write('],\n'); };