myst-to-typst
Version:
Export from MyST mdast to Typst
68 lines (67 loc) • 3.03 kB
JavaScript
import { fileError } from 'myst-common';
function countColumns(table) {
var _a, _b;
const firstRow = (_a = table.children) === null || _a === void 0 ? void 0 : _a.find((child) => child.type === 'tableRow');
const columns = (_b = firstRow === null || firstRow === void 0 ? void 0 : firstRow.children) === null || _b === void 0 ? void 0 : _b.filter((cell) => cell.type === 'tableCell').reduce((val, cell) => { var _a; return val + ((_a = cell.colspan) !== null && _a !== void 0 ? _a : 1); }, 0);
return columns;
}
function isHeaderRow(node) {
var _a;
if (node.type !== 'tableRow')
return false;
return (_a = node.children) === null || _a === void 0 ? void 0 : _a.filter((child) => child.type === 'tableCell').every((child) => child.header);
}
function countHeaderRows(table) {
var _a, _b;
const headerRows = (_a = table.children) === null || _a === void 0 ? void 0 : _a.filter((child) => isHeaderRow(child));
return (_b = headerRows === null || headerRows === void 0 ? void 0 : headerRows.length) !== null && _b !== void 0 ? _b : 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) => {
var _a, _b;
if (node.rowspan || node.colspan || node.align || ((_a = node.style) === null || _a === void 0 ? void 0 : _a.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 ((_b = node.style) === null || _b === void 0 ? void 0 : _b.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');
};