Problem
collectAnchors (first_line anchor, entry-blocks.ts) rejects a header candidate when line.x > bulletMarkerX, where bulletMarkerX is the global min bullet-x of the section. This is correct for single-column sections (it strips marker-less wrapped-bullet tails), but it mis-fires on a two-column flatten where the section interleaves two bullet margins.
Concrete case
tests/fixtures/pdfs/unknown/weasyprint-cairo-two-column.pdf — the Achievements section flattens to:
x=249 bullet • Implemented authentication … (right column: experience bullet)
x=48 bullet • Globex Engineering Excellence, (left column: real award)
x=254 200-user admin tool. (right column: wrapped tail)
x=54 2021 (left column: award year)
x=249 bullet • Migrated legacy monolith … (right column)
x=48 bullet • Acme Innovation Prize, 2023 (left column: real award)
x=254 average response time by 55%. (right column: wrapped tail)
bulletMarkerX = min(249, 48) = 48, so the award's own "2021" (x=54) and the entire right column (x≈254) are all > markerX → rejected as wrapped continuations → 0 anchors → the Awards section is dropped entirely (achievementsCount 1→0 vs main).
Note: main's output here was also wrong — {title:"", year:"2021", description:"Acme Innovation Prize, 2023"}, an empty-title entry that mis-merges two distinct awards. So neither branch is correct; the section needs column-aware parsing.
Root cause
A single global bulletMarkerX can't represent a two-column layout that has two distinct bullet margins. The right fix is column-aware segmentation so each column's entries parse independently, rather than a per-section x-tolerance heuristic.
Relationship to other work
Acceptance
weasyprint-cairo-two-column Awards parse as two distinct achievements (Globex Engineering Excellence — 2021, Acme Innovation Prize — 2023), not 0 and not a mangled merge.
- No regression to the single-column wrapped-bullet-tail handling (e.g.
google-docs-skia-proxy-nonstandard projects stays 1).
Surfaced in review of #125.
Problem
collectAnchors(first_line anchor,entry-blocks.ts) rejects a header candidate whenline.x > bulletMarkerX, wherebulletMarkerXis the global min bullet-x of the section. This is correct for single-column sections (it strips marker-less wrapped-bullet tails), but it mis-fires on a two-column flatten where the section interleaves two bullet margins.Concrete case
tests/fixtures/pdfs/unknown/weasyprint-cairo-two-column.pdf— the Achievements section flattens to:bulletMarkerX = min(249, 48) = 48, so the award's own"2021"(x=54) and the entire right column (x≈254) are all> markerX→ rejected as wrapped continuations → 0 anchors → the Awards section is dropped entirely (achievementsCount1→0 vsmain).Root cause
A single global
bulletMarkerXcan't represent a two-column layout that has two distinct bullet margins. The right fix is column-aware segmentation so each column's entries parse independently, rather than a per-section x-tolerance heuristic.Relationship to other work
Acceptance
weasyprint-cairo-two-columnAwards parse as two distinct achievements (Globex Engineering Excellence — 2021,Acme Innovation Prize — 2023), not 0 and not a mangled merge.google-docs-skia-proxy-nonstandardprojects stays 1).Surfaced in review of #125.