| 136 | * well-formed table (header + delimiter + zero or more body rows). |
| 137 | */ |
| 138 | export function parseTable(block: string): MarkdownTable | null { |
| 139 | const lines = block.replace(/\n+$/, '').split('\n') |
| 140 | if (lines.length < 2) return null |
| 141 | if (!isDelimiterRow(lines[1])) return null |
| 142 | |
| 143 | const headers = splitRow(lines[0]) |
| 144 | const alignCells = splitRow(lines[1]) |
| 145 | const colCount = headers.length |
| 146 | if (colCount === 0) return null |
| 147 | |
| 148 | const aligns: ColumnAlign[] = [] |
| 149 | for (let c = 0; c < colCount; c++) aligns.push(parseAlign(alignCells[c] ?? '')) |
| 150 | |
| 151 | const rows: string[][] = [] |
| 152 | for (let i = 2; i < lines.length; i++) { |
| 153 | if (lines[i].trim() === '') continue |
| 154 | rows.push(normalizeRow(splitRow(lines[i]), colCount)) |
| 155 | } |
| 156 | |
| 157 | return { headers, rows, aligns } |
| 158 | } |
| 159 | |
| 160 | function normalizeRow(cells: string[], colCount: number): string[] { |
| 161 | const out = cells.slice(0, colCount) |