Where: scripts/build_explainers.py's parse_table/split_row (around lines 132-149), mirrored in assets/explainers-ui.js's parseTable (lines 99-122).
The gap: both table parsers naively split("|") on every pipe character in a row, with no support for an escaped \| inside a cell's own text (standard GFM table syntax). A literal, unescaped pipe used as ordinary punctuation inside a cell (not intended as a column separator) also breaks the split, since there's no escaping mechanism to fall back on either way.
Repro (already broken in committed, currently-published HTML - no rebuild needed):
$ grep -o '<tr><td><strong>Inverse Probability[^<]*</strong></td>.\{0,400\}' explainers/reject-inference.html
<tr><td><strong>Inverse Probability Weighting (IPW)</strong></td><td>Estimate selection propensity w(X) = P(S = 1</td><td>X); weight approved cases by 1 / w(X) during training.</td>...
The source cell contains P(S = 1 | X); the table declares only 4 <th> columns, but this row renders 6 <td>s because the pipe inside P(S = 1 | X) gets treated as a column separator - shifting every later column out of alignment. The same root cause already shipped in explainers/base-rate-fallacy.html too (a PPV (P(Y = 1 | Ŷ = 1)) header splitting into two separate <th> cells).
Why it matters: this is a currently-visible rendering defect on two published explainer pages right now, not a hypothetical edge case - confirmed directly against the checked-in generated output.
Suggested fix: support standard GFM pipe-escaping (\|) in table cells - split rows on | characters not preceded by \, then unescape \| → | in the resulting cell text - applied identically in both parse_table (Python) and parseTable (JS) to keep the two renderers in parity.
Where:
scripts/build_explainers.py'sparse_table/split_row(around lines 132-149), mirrored inassets/explainers-ui.js'sparseTable(lines 99-122).The gap: both table parsers naively
split("|")on every pipe character in a row, with no support for an escaped\|inside a cell's own text (standard GFM table syntax). A literal, unescaped pipe used as ordinary punctuation inside a cell (not intended as a column separator) also breaks the split, since there's no escaping mechanism to fall back on either way.Repro (already broken in committed, currently-published HTML - no rebuild needed):
The source cell contains
P(S = 1 | X); the table declares only 4<th>columns, but this row renders 6<td>s because the pipe insideP(S = 1 | X)gets treated as a column separator - shifting every later column out of alignment. The same root cause already shipped inexplainers/base-rate-fallacy.htmltoo (aPPV (P(Y = 1 | Ŷ = 1))header splitting into two separate<th>cells).Why it matters: this is a currently-visible rendering defect on two published explainer pages right now, not a hypothetical edge case - confirmed directly against the checked-in generated output.
Suggested fix: support standard GFM pipe-escaping (
\|) in table cells - split rows on|characters not preceded by\, then unescape\|→|in the resulting cell text - applied identically in bothparse_table(Python) andparseTable(JS) to keep the two renderers in parity.