Repository navigation
fix(documents.js): read text set in columns one column at a time - #1700
Merged
Merged
Conversation
Line clustering merged every item sharing a baseline into one line across the full page width, so two prose columns whose baselines line up read as "left line, right line" for every line, interleaving the page. Split a page's text at the column gutters its own geometry states before clustering lines: a strip no item touches over a run of consecutive lines, with text on both sides that reads as running prose (a measure of at least twenty characters, lines that wrap, word gaps narrower than the strip). Lines crossing the strip, such as a full-width heading, form their own bands read in page order. Each side is split again, so three columns read correctly too. Tables keep their rows: their columns fail the prose test, being a few characters wide or holding cells ragged by more than a word. A page with no gutter is one flow holding exactly the items it was given. Images, recovered tables and drawings are placed by the band and column their position falls in, then by height, in both the wordprocessing and the presentation directions.
…n both sides Its label column was narrower than the prose measure, so the measure alone kept it whole and the line-wrap test it was meant to exercise never decided anything.
Mearman
marked this pull request as ready for review
October 25, 2026 23:01
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
This security review couldn’t start because the paying account has exhausted its Codex allowance and has insufficient available credits. The payer can check their balance and add credits in the Codex usage dashboard, then try again. If you do not manage the paying account, contact this repository's admins. |
Contributor
|
🎉 This PR is included in version 14.6.1 🎉 The release is available on: Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PDF reconstruction read two-column pages interleaved.
clusterIntoLinesmerges every item sharing a baseline into one line across the full page width, so when two prose columns have the same leading (HSE's HSG141 guidance is an example: 12pt on 15pt leading, columns at x 56.7 and 303, baselines a twentieth of a point apart) every line came out as "left-column line, right-column line", and a sentence's subject and predicate ended up separated by text from the other column. The presentation direction had the same problem, and on pages whose column baselines do not line up the y sort interleaved the columns line by line instead.The page's text is now split into reading-order flows before any line or paragraph clustering (
src/layout/reading-order.ts). A gutter is a vertical strip that no item touches over a run of consecutive lines, wider than the natural word space of those lines, with text on both sides. It splits only when the text on each side reads as running prose: at least three lines, a measure of at least twenty of its own average character advances (half the lower end of Bringhurst's 40 to 50 characters for multi-column work), word gaps narrower than the strip, and a majority of lines that wrap, meaning each stops short of the column's right edge by less than the next line's first word plus a space. Lines crossing the strip (a full-width heading, a boxed passage spanning both columns) end the band and are read in page order before or after it, and each side and each remaining band is split again, so three columns work too. Images, recovered tables and the page's drawing are placed by the band and column their position falls in, then by height.Tables keep their rows. A table's columns also leave empty strips with shared baselines, but a column of codes or figures is a few characters wide, and a column of short cells is ragged by far more than a word, so neither passes as prose and the page keeps its full-width lines. A page with no gutter, or with an item whose horizontal extent the reader did not report (no width, vertical writing, rotation), is one flow holding exactly the items it was given, so its output is unchanged.
The new tests build pages from plain
LayoutTextdata: two prose columns (one item per line and one per word), a full-width heading above two columns, a spanning passage between two column bands, uneven column lengths, an image in the right column, the presentation direction, a single column, and three table shapes (an equal-width grid of figures, wide columns of short ragged cells, short codes beside long descriptions). On the code before this change the seven column tests fail with the interleaved text and the four single-column and table tests pass; with the prose test disabled the three table tests fail, and with only the wrap test disabled the ragged-cell table fails. The README's PDF reconstruction paragraph describes the behaviour.