import type { TableBlock, TableTone } from "#types/block.types"; import { appendChildren, createElement } from "#core/factories/element.factory"; import { fillMarkup } from "#presentation/renderers/text.renderer"; const KEYWORD_COLUMNS: ReadonlyMap = new Map([ ["keyword", 1], ["contrast", 2], ]); const renderCell = function renderCell(cell: string, index: number, tone: TableTone | undefined): Element { const element = createElement("td", {}); if (tone === "role" && index === 0) { element.append(fillMarkup(createElement("strong", {}), cell)); return element; } if (tone !== undefined && index < (KEYWORD_COLUMNS.get(tone) ?? 0)) { element.append(createElement("code", { className: "keyword", text: cell })); return element; } return fillMarkup(element, cell); }; const renderHead = function renderHead(headers: readonly string[]): Element { const row = createElement("tr", {}); appendChildren( row, headers.map((header) => fillMarkup(createElement("th", {}), header)), ); return createElement("thead", { children: [row] }); }; const renderBody = function renderBody(block: TableBlock): Element { const body = createElement("tbody", {}); for (const cells of block.rows) { const row = createElement("tr", {}); appendChildren( row, cells.map((cell, index) => renderCell(cell, index, block.tone)), ); body.append(row); } return body; }; export const renderTable = function renderTable(block: TableBlock): Element { const className = block.tone === undefined ? "block-table" : `block-table ${block.tone}`; const table = createElement("table", { children: [renderHead(block.headers), renderBody(block)] }); return createElement("div", { children: [table], className }); };