Skip to content

fix: table parser honors escaped pipes; JS renderMarkdown matches heading offset - #563

Merged
yakew7 merged 1 commit into
yakew7:mainfrom
propcgamer20-png:fix/table-pipe-escaping-and-heading-parity
Sep 10, 2026
Merged

fix: table parser honors escaped pipes; JS renderMarkdown matches heading offset#563
yakew7 merged 1 commit into
yakew7:mainfrom
propcgamer20-png:fix/table-pipe-escaping-and-heading-parity

Conversation

@propcgamer20-png

Copy link
Copy Markdown
Collaborator

Two build_explainers.py <-> explainers-ui.js parity bugs.

#552 - table parser breaks on a literal pipe in a cell (2 pages already misrendered)

scripts/build_explainers.py's split_row and assets/explainers-ui.js's parseTable both did row.split("|"), with no support for GFM's \| escape. A literal pipe inside a cell started a spurious column:

  • explainers/reject-inference.html - the IPW row (w(X) = P(S = 1 | X)) rendered 6 <td> for a 4-column table, misaligning every later column
  • explainers/base-rate-fallacy.html - PPV (P(Y = 1 | Ŷ = 1)) split into two separate <th>

Both parsers now split on (?<!\)\| (unescaped pipe only) and unescape \| -> | in each cell. reject-inference.md's two bare pipes are escaped as \| in source (base-rate-fallacy.md already had them escaped - the parser just wasn't honoring it). Pages regenerated; the IPW row is now 4 <td>, the PPV header one <th>.

#553 - explainers-ui.js renderMarkdown drifted out of heading-offset parity

A prior fix offset build_explainers.py's markdown headings by +1 (the page hero already renders a real <h1>). explainers-ui.js's renderMarkdown was never updated - it still emitted # X -> <h1>. It now applies Math.min(level + 1, 6), matching Python (# X -> <h2>, ###### X -> <h6>). This path isn't reached in production today (no explainer page loads explainers-ui.js), but a later "fix" assuming parity would have reintroduced the duplicate-<h1> bug.

Tests

  • test_parse_table_honors_escaped_pipe_inside_a_cell
  • test_render_markdown_offsets_heading_levels_by_one
  • test_explainers_ui_js_stays_in_render_parity_with_build_explainers - source-level guard that both fixes are mirrored in the JS

pytest tests/test_build_explainers.py -> 7 passed. check_em_dash / check_broken_links / check_generated_files_current pass. ruff clean.

Closes #552
Closes #553

…ding offset

yakew7#552: build_explainers.py's split_row and explainers-ui.js's parseTable
both did a naive split("|") on every pipe in a table row, with no support
for GFM's "\|" escape. A literal pipe inside a cell (e.g. "P(S = 1 | X)")
started a spurious column, shifting every later column - already visibly
misrendering explainers/reject-inference.html (an IPW row with 6 <td> for
a 4-column table) and explainers/base-rate-fallacy.html (a "PPV
(P(Y = 1 | Ŷ = 1))" header split into two <th>). Both parsers now split
on unescaped "|" only and unescape "\|" -> "|" in each cell.
reject-inference.md's source pipes are now escaped as "\|"
(base-rate-fallacy.md already had them escaped); pages regenerated.

yakew7#553: a prior fix offset build_explainers.py's markdown headings by +1
(the page hero already renders a real <h1>), but explainers-ui.js's
renderMarkdown was never updated and still emitted raw levels. It now
applies the same Math.min(level + 1, 6). This path isn't reached in
production today, but "fixing" it later under the assumption it matched
the server renderer would have reintroduced the duplicate-<h1> bug.

Closes yakew7#552
Closes yakew7#553
@vercel

vercel Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

@propcgamer20-png is attempting to deploy a commit to the yashkewlani2020-gmailcom's projects Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown

@yakew7 @Shreyash0712 @ahmdkaml - new PR touching a path you own, please review.

@yakew7
yakew7 merged commit 48f8b45 into yakew7:main Sep 10, 2026
18 of 19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants