(table: MarkdownTable)
| 189 | } |
| 190 | |
| 191 | export function serializeTable(table: MarkdownTable): string { |
| 192 | const colCount = table.headers.length |
| 193 | const widths: number[] = [] |
| 194 | for (let c = 0; c < colCount; c++) { |
| 195 | let w = cellWidth(escapeCell(table.headers[c] ?? '')) |
| 196 | for (const row of table.rows) w = Math.max(w, cellWidth(escapeCell(row[c] ?? ''))) |
| 197 | // Delimiter needs room for `:` markers and at least one dash. |
| 198 | const align = table.aligns[c] ?? 'none' |
| 199 | const minDelim = align === 'center' ? 3 : align === 'none' ? 1 : 2 |
| 200 | widths.push(Math.max(3, w, minDelim)) |
| 201 | } |
| 202 | |
| 203 | const renderRow = (cells: string[]): string => { |
| 204 | const padded = cells.map((cell, c) => |
| 205 | padCell(escapeCell(cell ?? ''), widths[c], table.aligns[c] ?? 'none') |
| 206 | ) |
| 207 | return `| ${padded.join(' | ')} |` |
| 208 | } |
| 209 | |
| 210 | const header = renderRow(table.headers) |
| 211 | const delim = `| ${table.aligns |
| 212 | .map((a, c) => delimiterCell(widths[c], a)) |
| 213 | .join(' | ')} |` |
| 214 | const body = table.rows.map(renderRow) |
| 215 | const tableMd = [header, delim, ...body].join('\n') |
| 216 | const cols = serializeColWidthsComment(table.colWidths) |
| 217 | return cols ? `${tableMd}\n${cols}` : tableMd |
| 218 | } |
| 219 | |
| 220 | // A trailing `<!-- zen:cols=120,auto,90 -->` line persists explicit per-column |
| 221 | // pixel widths (#294). A plain HTML comment is invisible in every other |
no test coverage detected