Skip to content

Flash embedded-TOC merge: dissolve duplicated headings, place new sections at their level - #391

Open
rejojer wants to merge 14 commits into
mainfrom
fix/flash-toc-merge
Open

rejojer wants to merge 14 commits into
mainfrom
fix/flash-toc-merge

Conversation

@rejojer

@rejojer rejojer commented Aug 8, 2026 •

Copy link
Copy Markdown
Member

The FULL-tier bookmark merge in pageindex/flash/embedded_toc.py drops thousands of duplicated headings, files unbookmarked subsections under their own numbered section, puts a heading printed above a bookmark's own heading in the section before it, and moves unbookmarked References out of the last chapter, without cutting any other bookmark section short. On 325 local PDFs (295 with FULL-tier bookmarks), 101 bookmark sections in 100 PDFs end earlier than on main, every one of them a tail section (References, Limitations, Acknowledgments, Index, ...) leaving the last chapter or an unbookmarked peer taking its place; none ends later.

Main grafts every detected heading under the deepest bookmark open at its page and checks only that one bookmark for a duplicate. Duplicates of shallower same-page bookmarks survive (a numbered 5 Experiments inside bookmark Experiments, often with its children), a subsection printed above the next bookmark lands inside that bookmark (7.2.1 under 7.3), an unbookmarked References lands inside Conclusion, so Conclusion runs to the end of the paper, and a heading printed above a bookmark's own heading on the same page lands inside that bookmark (Abstract under Introduction, Acknowledgments under References).

Changes

  • Duplicates: a detected heading dissolves into any bookmark starting on its page that it matches (equal, letter spacing aside; apart by a numbering prefix such as 5, IV, Item 7, 第三章, letter-spaced or not (M e tho do logy under 3 Methodology); or garbled at fuzzy ≥ 0.9 under the same section number, letter-spaced too unless the two end in different numbers, as Part I and Part II do), or into one starting on the page before with an equal title. A bookmark that has no heading on its own page also takes its title behind numbering from the next page (9 Conclusion on the page after bookmark Conclusion), while one that has (4.1.1 User factual memory) leaves the next page's I. User factual Memory alone; it still takes a next-page copy under the same section number (a running header, 1.1. WHAT IS A GRAPH? after 1.1 What is a graph?) and its title carried on with a parenthetical (J15ZJ (15 Ton) (Continued)). fix(flash): a running "Table of Contents" link no longer hides headings #577 pinned A. Appendix there as a child because main's looser match (ends-with, fuzzy 0.7) swallowed real subsections; numbering alone keeps them. Its children are then placed one by one. Extra words that are not numbering do not count: 5.2 Ablation Results and Executive Results stay under bookmark Results, and 13.6.1 does not fold into 13.6. The SKELETON tier shares this matcher.
  • Printed headings that differ from the bookmark: a bookmark that nothing has matched yet takes the first heading on its page that prints its title after a header (JPMorgan Chase & Co. Consolidated balance sheets; for a numbered bookmark any text before its number, as in Chapter 2 My second chapter or a merged 4 SYSTEM OVERVIEW 4.1 DOT), before a parenthetical (Revenue (dollars in millions)), cut short (Derivatives netting for Derivatives netting and collateral, or without its number: DO THE RIGHT THING FOR CONSUMERS for 2. “Do the Right Thing” for consumers: ...), with words inserted inside it (Line of business and Corporate equity), with a number for its label word (A. Proofs for Appendix Proofs), with a short reference resolved where the bookmark kept a LaTeX label (E. WordNet: Table 1 Visualizations for WordNet: tab:wordnet-results Visualizations), continued in lowercase (Financial Performance Summary for Fiscal 2015, while an enumerator such as a. Nomenclature stays a merged subheading), followed by a short remark (Item 4. Mine Safety Disclosures. Not applicable.), or in other words under the same label and number (Note 26 – Restricted cash ... for Note 26 - Restrictions on cash ..., 2. Defined Terms for 2. Detailed Terms, 2.1 Reasonably long section title for LaTeX's short title 2.1 Short title, a doubled 第十二条 不可抗力 第 十 二 条 ... or 二、 邻里公 约 二 、 邻 里 公 约 ...). Any other line that starts with the whole bookmark title is a merged subheading and stays (Note 18 - Leases Firm as lessee), list items and table rows without a label word never match, and a bookmark takes at most one, so Assets measured at fair value stays under Fair value.
  • Reading order: a heading read before the heading of a bookmark that starts on its page (or on the page before, for a bookmark that targets the page above its title) belongs to the bookmark before it, when that one starts there too, and goes ahead of the later bookmark among its siblings. The order comes from the detected tree, not from vertical position, because in two columns the top of the right column is read after the bottom of the left one. 522 headings in 166 PDFs move this way, and none of them changes the length of a bookmark section.
  • Numbered subsections: a heading whose number belongs to a section ending on its page (the page shared with the next bookmark) joins that section, so 7.2.1 printed above bookmark 7.3 goes under 7.2.
  • Other placement: an unbookmarked heading climbs from its anchor along the open sections on positive evidence that it is a peer. The evidence is a section number outside the candidate's and after it in the same scheme, or the same style fingerprint, with at least 0.15 page heights below a same-page candidate. A climb must reach a numbering parent or the top level (just below the root when one root bookmark titles the whole document, so Authors and Affiliations leaves References). Stopped halfway (missing evidence, an earlier number, a same-style detected heading numbered like it already under the candidate, or a candidate with content after the heading's page), the heading stays at its anchor, because at the halfway level it would cut that level's last section short. Numbered like it means both open with a section number, or both with a 一、-style one, so an unnumbered Acknowledgements still leaves a Conclusion that holds another tail section.
  • Closed sections: a bookmark section that a climb passes is closed, and a later heading that anchors in it starts from its nearest open ancestor, so the prompt templates printed after an unbookmarked References no longer go back into Conclusion ahead of it. Detected headings out of reading order drop to 0 (2 in the corpus and 1 in the holdout before).
  • Section numbers are at most three digits and end at a break, so 3D, 2.5D, 10-K and 2019 Survey are words.
  • Spanning sections: a detected section without a bookmark that runs past the next bookmark still becomes a leaf, but its children numbered directly under it (9.3.2.1 under 9.3.2) stay with it while no bookmark starts in between, instead of landing beside it.
  • Recurring sections: the noise filter that drops a title recurring three or more times keeps one printed in the style of a bookmark's own heading and never on adjacent pages, a section each chapter repeats (a textbook's Notes and Study Problems, a 10-K's Loan modifications in each portfolio). On main these were deleted with the running labels; 251 come back in 12 PDFs, 15 of them stray API-documentation labels in one manual.
  • Detection exports each heading's style and position as _style/_y, and extract_toc strips them from the result.

Known differences from main

  • About 6 headings that a climb would place well follow main's nesting instead: chapter-end Study Questions and Additional resources (three in one book), and mid-level peers such as JPM's Economic Value Sensitivity inside Earnings-at-risk. Unnumbered headings between consecutive numbers (Autoregressive Model between 1.1.1 and 1.1.2) also stay inside the previous subsection, which the missing number supports, and an AIR paper's References stays under 10 Conclusions because its bookmarks put the appendix there too. Every extra signal tried to place them also moves real subsections: keeping halfway climbs for headings in the second half of the section cuts 13 bookmark sections short ((Continued) pages, table captions), and following the detector's own nesting agrees with misplaced JPM regulation subsections and CMC sub-items.
  • 4 copies that main folds at its 0.7 fuzzy bar stay as leaves: two form code names (headershealth for Health), where the readable print is worth keeping, other words (timer state for Timer status), and a hyphen plus a qualifier (Non-Operating Income (Expense), Net (dollars in millions) for Nonoperating Income (Expense)). At that bar main also deletes real headings (Daily inspections into Weekly inspections, 16.1.2 into 16.2.2), which this PR keeps.
  • A heading without a bookmark printed in the top-level style mid-document climbs to the top level, as a References after Conclusion should: in one university catalog Residence Accommodations leaves Student Life and Housing, and the six housing sections printed after it follow it to the top level. Stopping such a climb when headings in a smaller style follow (the section has subsections) fixes it but puts References back into the last chapter in 3 corpus papers whose appendix follows, so it is not done.

Verification

  • 25 tests in tests/test_flash_embedded_toc.py. Each rule above has one that fails when the rule is removed, and main's test_bookmark_title_printed_a_page_after_its_target_is_no_child now expects A. Appendix to fold and pins the bookmark that already has its heading.
  • Corpus: detection ran once per PDF, and main and this branch merged the same detected tree. Every bookmark section that ends earlier, every title gone with no copy left, every node this branch keeps that main drops, and every moved subsection was checked by hand.
  • Holdout: 10 bookmarked PDFs never used for tuning (textbooks of 640 to 1,100 pages, four university catalogs, a 1,300-page manual). No bookmark section ends later than on main; 3 end earlier (PRML's exercise pages leave 7.2.3, numbered like sections, and the catalog case above); the 5 titles gone are copies of their bookmark; numbered headings outside their numbering parent drop from 132 to 2.
  • Full suite: 1221 passed, 7 skipped.

@BukeLy

BukeLy commented Aug 31, 2026

Copy link
Copy Markdown
Member

Thanks for the contribution. Closing this PR because the relevant indexing behavior has been superseded by the current Flash pipeline, PageIndex File System direction, or the later documentation/assets implementation. The branch is no longer suitable to merge as-is.

@BukeLy BukeLy closed this Aug 31, 2026
@rejojer rejojer reopened this Oct 1, 2026
… frame chain

The FULL-tier merge compared each detected node only against its single
deepest anchor, so a numbering-prefixed variant of a shallower same-page
bookmark ('5 Experiments' under frame 'Experiments' > 'Scaling Laws')
was treated as new and grafted inside its own subsection. Dissolved
parents also raw-inserted their children without any duplicate check.
Dissolve now walks the whole same-page frame chain and re-places
children individually.

The dissolve match is equal / numbering-prefix / 0.9-garble. Reusing the
0.7 repair bar would false-match wordy-overlapping titles of distinct
sections (2023-annual-report: 'Reserve Bank and Branch Directors' vs
'Federal Reserve Banks and Branches', 0.746) and a false dissolve
deletes a real heading, while an escaped garbled duplicate only leaves a
stray leaf.

Across the nine example PDFs: 40 duplicate nodes removed (attention 7,
PRML 16, Regulation 8, annual report 9), zero other structure changes;
the four detected-tier trees are byte-identical.
…chain

The FULL-tier merge hung every non-duplicate detected node under the
deepest bookmark section active at its page, so a tail section the
bookmarks lack (Conclusion, References after the last numbered section)
was buried inside the preceding section. A new node now climbs its
anchor's ancestor chain -- the only parents page containment allows --
on positive evidence that it is a peer, not a child: a numbering prefix
outside the candidate's numbering, or the same style fingerprint (face,
weight and size as one hash; detection exports _style/_y and extract_toc
strips them after the merge). Frame nodes learn style and position from
the duplicates that dissolve into them.

Two guards keep noise contained. Raw size is never compared across
faces: PRML margin-box titles run 13pt regular against 11.5pt bold
subsection headings and must not outrank them. A same-page climb must
leave the candidate real content below its heading; climbing on a
near-zero gap would claim the section is empty, the signature of a
margin box rather than a tail section.

Across the nine example PDFs: attention-residuals gains top-level
Conclusion/References (the target); PRML chapter-7 exercise items move
from inside 7.2.3 to their chapter per their numbering, correcting the
7.2/7.2.3 end pages; the Interpretive release's Federal Register tail
matter leaves section B. All other trees byte-identical.
…s the bookmark-a-page-early rule, and folds a heading into its bookmark only when the extra text is numbering, spacing or a header

- dissolve_target calls _same_heading at the dissolve bar instead of a
  copy of it, so the rule that a bookmark can target the page before its
  printed title holds here too, for every frame on the node's page and
  the page before.
- An ends-with match counts only when the extra words are numbering
  ("5", "IV", "Item 7", "第三章"): "5.2 Ablation Results" and "Executive
  Results" no longer fold into a bookmark "Results". The SKELETON tier
  shares _same_heading and gets the same rule.
- A fuzzy match never folds two different section numbers ("13.6.1"
  into "13.6"), and letter-spaced text ("R E F E R E N C E S") equals
  its bookmark.
- A bookmark no node has matched yet takes the first node on its page
  that ends with its title, a parenthetical aside: "JPMorgan Chase & Co.
  Consolidated balance sheets", "Revenue (dollars in millions)". Words
  after the title keep the node, as they are a merged subheading ("Note
  18 - Leases Firm as lessee"); once matched, a bookmark takes no more,
  so "Assets measured at fair value" stays under "Fair value".
- A section number is at most three digits and ends at a break: "3D",
  "2.5D", "10-K" and "2019 Survey" are words.
- A numbering climb needs a number after the candidate's in the same
  scheme: "3.2.2" printed above bookmark "3.3" stays under it.
- A climb must reach a numbering parent or the top level. Stopped
  halfway (missing evidence, an earlier number, a same-style detected
  heading already under the candidate, or a candidate with content after
  the node's page) the node stays at its anchor; placed at the halfway
  level it cut that level's last section short: Amazon 2023's "Item 1A.
  Risk Factors" shrank from pages 18-28 to page 18.

Corpus: 325 local PDFs, 295 with FULL-tier bookmarks; detection ran
once per PDF and main, the PR before this commit and this commit merged
the same detected tree.
- Bookmark sections ending earlier than on main: 289 in 162 PDFs before,
  88 in 87 PDFs now, each a tail section (References, Limitations,
  Acknowledgments, Index, ...) leaving the last chapter or an unbookmarked
  numbered peer (2.3.2, 5.5). None ends later.
- Titles gone with no copy left: 32, each a garbled or qualified copy of
  a bookmark that stays.
- Given up: about 15 placements the climb got right now follow main
  (References next to a same-style Acknowledgements kept under
  Conclusion; a chapter-end "Study Questions" inside the last
  subsection), and about 30 copies that main's 0.7 bar folded stay as
  leaves (truncated lines, footnote marks, "... Not applicable.").
@rejojer
rejojer force-pushed the fix/flash-toc-merge branch from c9b9220 to 765017f Compare November 5, 2026 14:02
…ins that section, References leaves the last chapter past a same-style Acknowledgements, and cut-off or renumbered copies fold into their bookmark

- A numbered heading whose number belongs to a section that ends on its
  page (the page shared with the next bookmark) joins that section:
  "7.2.1" printed above bookmark "7.3" goes under 7.2, not 7.3 or
  chapter 7. On the corpus 150 subsections move, every one under a
  section whose number is a prefix of its own, and no bookmark section
  changes.
- A references heading (main's REFERENCES_KEYWORDS, read as
  find_references reads one) is not stopped by a same-style detected
  heading already under the candidate, so References leaves a Conclusion
  that kept a same-style Acknowledgements on its first page. 6 papers.
- A bookmark nothing has matched yet also takes the first node on its
  page whose words are the start of its title ("Removing the crisper
  and", printed "Derivatives netting" for bookmark "Derivatives netting
  and collateral") or that carries the same label and number in other
  words ("Note 26 – Restricted cash ..." for "Note 26 - Restrictions on
  cash ..."). A label word is required, so list items and table rows
  ("4 温烨", "1.") never match, and a line starting with the whole
  bookmark title stays a merged subheading. 26 folds, each a printed
  copy of its bookmark.

Tried and left out: a halfway style climb kept when the heading sits in
the second half of the section it leaves (recovers about 10 placements,
but cuts 13 bookmark sections short: "(Continued)" pages, table
captions), and fuzzy matching on space-stripped text ("Part I" and
"Part II" score 0.91).
…imb, so tail sections leave the last chapter, and "2."-numbered or remark-tailed copies fold into their bookmark

- A same-style detected heading under the candidate stops a climb only
  when it is enumerated like the climbing heading: both open with a
  section number, or both with a "一、"-style enumerator. "二、" after
  "一、" under 第十二节 and "3.2. S.4." after "3.2. S." under APPENDIX
  still stay, while an unnumbered tail (Acknowledgements, Appendix,
  Ethical Considerations, Author Contributions, References) now leaves a
  Conclusion that kept another tail on its first page. This replaces the
  references-keyword exemption, which the corpus shows is then redundant,
  so embedded_toc no longer imports from main.
- The same-section-key match also takes a bare dotted number ("2.
  Defined Terms" for bookmark "2. Detailed Terms"); without the dot
  ("4 温烨" against "4、") table rows never match.
- A heading printing the whole bookmark title plus a remark of at most
  three digit-free words ending in a period ("Item 4. Mine Safety
  Disclosures. Not applicable.") folds; any other text after the title
  stays a merged subheading ("Note 6 - Leases 6.1 Rent.").

Corpus: 4 more tail sections placed, 8 more copies folded, no other node
moves. Tried and left out: following the detector's own nesting for
halfway climbs (it agrees with the misplaced JPM regulation subsections
and CMC sub-items), alone or combined with the second-half position
(still moves 13 JPM regulation subsections and 6 table captions out of
their sections).
…a merged line, and doubled or letter-spaced copies fold into it

- A bookmark no detected heading has matched yet takes, from the page
  after its target, the heading that prints its title behind numbering
  ("9 Conclusion" on page 29 for bookmark "Conclusion" on page 28).
  Until now only an exactly equal title folded there, so the numbered
  print stayed, often with a copy of the bookmark's own subsections
  under it. A bookmark that already took a heading on its own page takes
  none from the next page, so "I. User factual Memory" after
  "4.1.1 User factual memory" stays. This moves the next-page boundary
  #577 pinned with "A. Appendix": #577 rejected main's looser match
  there (ends-with and 0.7 fuzzy swallowed "Taxonomy of Agent Tools",
  "Environment factual Memory" and "A.5.3.1"), and a match on numbering
  alone keeps all three.
- For a numbered bookmark, text before its number is a header, as it
  already was for an unnumbered one: "Chapter 2 My second chapter" and a
  merged "4 SYSTEM OVERVIEW 4.1 DOT" fold, with the copies under them.
  An unnumbered bookmark still keeps a numbered heading that ends in its
  title ("5.2 Ablation Results" under "Results").
- "第十二条"-style article numbers are section keys, so a doubled print
  ("第十二条 不可抗力 第 十 二 条 不 可 抗 力 ...") folds into its bookmark.
- A letter-spaced heading matches a numbered bookmark behind its number
  ("M e tho do logy" for "3 Methodology").

Corpus, against the previous commit: 131 duplicate nodes go in 36 PDFs,
each a copy of its bookmark (95 next-page prints and the copies under
them in 23 PDFs, 27 merged-line copies in 9, 6 doubled CJK prints in 3,
3 letter-spaced copies in 1). 4 bookmark sections end earlier, all
rightly: 3 References leave Conclusion or Acknowledgements, and
"2.1 Short title" ends where the unbookmarked "2.2 Hidden section"
starts. Without the already-matched guard the next-page rule also
deleted the real "I. User factual Memory".
…below a lone root bookmark

- A dotted number of two or more levels ("2.1", "6.3.4") is a section
  key without a trailing dot too, so a bookmark not yet matched takes the
  heading printed under its number in other words: "2.1 Reasonably long
  section title" for bookmark "2.1 Short title" (LaTeX's short title),
  "6.3.4 Seed the Base" for a garbled "6.3.4 Seed seed the Base", and
  "3.2.1 SaaS" for a sentence-long bookmark 3.2.1. A bare "4" still is no
  key, so table rows ("4 温烨") never match.
- When one root bookmark titles the whole document, the level just below
  it is the top level: a tail section climbing out of the last section
  ends there instead of stopping halfway, so "Authors and Affiliations"
  after References becomes its peer.

Corpus, against the previous commit: 4 copies go in 3 PDFs, and one
bookmark section ends earlier, rightly (References, at "Authors and
Affiliations"). Tried and left out: a print that drops the bookmark's
leading label ("Failure Case" for "Case 5b: Failure Case", no effect on
the corpus) and a fuzzy match on letter-spaced text ("Har d hea d an d
soft heart s", one copy, at the cost of a letter-spacing threshold).
…ber for the label word still match the bookmark

- The garble match also compares the titles with their spaces removed,
  so "Har d hea d an d soft heart s" dissolves into "Hard Heads and Soft
  Hearts" and "5 Evaluation of Queries in C lin and C poly" into
  "Evaluation of Queries in Clin and Cpoly". Squeezing turns "Part I"
  and "Part II" into "parti"/"partii", so this comparison refuses two
  titles that end in different numbers. Applying that guard to the
  existing comparison would stop "Native Advertising ... 2015 13" (a
  footnote mark) from folding, so it stays on the squeezed one only.
- A cut-short print may drop the bookmark's number too: "DO THE RIGHT
  THING FOR CONSUMERS" for "2. “Do the Right Thing” for consumers: The
  law and rising above it". The number guard still keeps a numbered
  print out of an unnumbered bookmark ("5.2 Ablation Results").
- A print with words inserted inside the bookmark title, its first and
  last words kept, is that bookmark: "Line of business and Corporate
  equity" for "Line of business equity". A line that starts with the
  whole title is still a merged subheading, so this is checked after
  that case: "Setting a PIN 1 Set a PIN." and "1. General Information
  (3.2.S.1) a. Nomenclature (3.2.S.1.1)" stay.
- A print that swaps the bookmark's leading label word for a number is
  that bookmark: "A. Proofs" for "Appendix Proofs".

Corpus, against the previous commit: 13 copies go in 7 PDFs, each the
print of its bookmark (8 of them appendix titles in two papers); no
bookmark section changes. Tried and left out: folding a remark that
starts lowercase ("Financial Performance Summary for Fiscal 2015")
also deleted the real "a. Nomenclature" item.
…s its title in lowercase, is the bookmark's heading

- A bookmark built from a LaTeX title can keep a reference unresolved
  ("WordNet: tab:wordnet-results Visualizations", "Missing Proofs in
  Section Enumeration") where the print shows its number ("E. WordNet:
  Table 1 Visualizations", "D Missing Proofs in section 4"). A print
  that shares the title's opening and closing words with the bookmark
  (at least two, after its own leading number) and has, in place of the
  bookmark's digit-free words, at most three words ending in a number is
  that bookmark. The three-word cap keeps a contents line ("7.4 How we
  assess financeability 136 7.5 Setting a fairer price control 140")
  out of "How we'll finance the plan", which shares only "How we".
- A print that continues the whole bookmark title with a lowercase word
  ("Financial Performance Summary for Fiscal 2015") is that bookmark. A
  one-letter or dotted enumerator does not count, so "1. General
  Information (3.2.S.1) a. Nomenclature (3.2.S.1.1)" stays a merged
  subheading.

Corpus, against the previous commit: 7 copies go in 4 PDFs, each the
print of its bookmark; no bookmark section changes.
…ngs to the section before it

Every detected heading was anchored to the deepest bookmark open at its
page, including one that starts lower on that page. So a heading printed
above a bookmark's own heading landed inside that bookmark: Abstract and
Keywords under Introduction, Acknowledgments under References, the last
subsections of Related Work under a Conclusion whose bookmark targets
the page before its title. Main does the same.

A pass in reading order (the order of the detected tree) first finds
where each bookmark's own heading is read, matching it as the merge
does. A heading read before the heading of a bookmark that starts on
its page, or on the page before, anchors to the bookmark before it, if
that one starts there too. Among siblings on the same page it goes
ahead of a bookmark whose heading is read after it. Reading order, not
the vertical position, decides "before": in two columns the top of the
right column comes after the bottom of the left one.

The previous bookmark must start on the node's page or the page before.
Further back, a detected section (an unbookmarked References that
climbed to the top) can sit between the two bookmarks, and anchoring to
the earlier one would grow it over that section: refrag's Appendix,
printed above Additional Discussion on page 16, would have stretched
Acknowledgements from 11-12 to 11-16.

Corpus, against the previous commit: 522 headings in 166 PDFs change
parent, each checked: Abstract, Keywords and CCS Concepts leave
Introduction, Acknowledgments sit between Conclusion and References,
10-K items land under their own Item, glossary terms under Glossary
rather than References, Related Work subsections leave Conclusion. A few
labels move between two equally wrong places (chapter-number labels in
a manual, cross-reference rows in the 10-Ks). 28 copies now reach their
bookmark and fold. No bookmark section changes length.
…d into their bookmark

- A bookmark that already took its heading still takes, from the next
  page, a numbered print under the same section number: a running
  header ("1.1. WHAT IS A GRAPH?" at the top of the page after "1.1 What
  is a graph?"). The bookmark remembers the section number of the
  heading it took, so a next-page item under another number stays: "I.
  User factual Memory" after "4.1.1 User factual memory".
- A next-page print of the bookmark title with a parenthetical added
  carries the section on ("J15ZJ (15 Ton) (Continued)") and folds too.
- A bare "二、"-style enumerator is a section key, so a doubled print
  ("二、 邻里公 约 二 、 邻 里 公 约 2. Neighborhood Convention 2 . N e i g h
  ...") and a title cut by a line break ("五、 发行人技术先进性、...以及")
  fold into their bookmark. "(一)" is no key: every parent has its own.

Corpus, against the previous commit: 52 copies go in 7 PDFs (25 running
headers in two books and a manual, 14 "(Continued)" pages, 13 Chinese
prints), each the print or a repeat of its bookmark; one formula line
moves from a removed header copy to its bookmark; no bookmark section
changes length.
…y with it

A detected section without a bookmark that runs across several pages
is dissolved into a leaf, and its children were placed one by one, so
they could only land under a bookmark: "9.3.2.1" to "9.3.2.5" went
under bookmark "9.3" beside "9.3.2 Qualitative engagement" instead of
inside it. A child numbered directly under the leaf now stays with it
while no bookmark starts in between.

Only numbering decides: following the detector's own nesting moved 208
headings, many wrongly (an Amazon risk factor under a sibling risk
factor, report sections under a bullet or a box, JPM sections under
table titles), and any deeper number ("3.2.2" under "3.") would skip
the closer bookmark "3.2".

Corpus, against the previous commit: the five 9.3.2.x subsections move
under 9.3.2; nothing else changes.
The noise filter spliced out every title that recurs three or more times
across the detected tree, which took real per-chapter sections with the
running labels: a textbook's Notes, Notebooks and Study Problems in every
chapter, a 10-K's Loan modifications in each loan portfolio, a report's
Addendum in each policy report. A recurring title now stays when it is
printed in the style of a bookmark's own heading and never on adjacent
pages. A running label repeats on consecutive pages ("ACME Corp" on
pages 2 and 3) or in a style no bookmark heading uses ("Note:"), and is
still removed. The styles come from a pass that matches each detected
heading to its bookmark the way the merge does, before the filter runs.

Corpus, against the previous commit: 251 nodes come back in 12 PDFs:
39 chapter sections in one textbook, 181 repeated subsections and
exhibit sections across four 10-Ks, 8 in two copies of a report, 6 in
three filings, 2 in a manual, and 15 API documentation labels in
another manual (stray leaves, nothing lost). In one book a kept
"Conclusion" lets reading order place the three items printed above it
under the section before, where the detector nests them. No bookmark
section changes length.
…e headings after it

Every heading anchors at the bookmark open at its page. After one heading
climbed out of a section, the next heading on a later page anchored in
that same section again and, with no evidence to climb, stayed inside it,
ahead of the heading that had already left. In GAM, References climbs out
of Conclusion on page 9, and the prompt templates on pages 11 to 17 went
back into Conclusion, so Conclusion ran to page 17 and the tree read the
prompts before References. In 2503.20757, Acknowledgments and Limitations
climbed out of Conclusion on page 7 while References stayed in it, so
Limitations took the reference pages.

A bookmark section that a climb passes is now closed: a later heading that
anchors in it starts from its nearest open ancestor.

Corpus, against the previous commit: only those two papers change (GAM's
Conclusion ends at page 9 instead of 17; References follows Limitations
in 2503.20757), and detected headings out of reading order drop from 2
to 0. Holdout: one change, in the university catalog where Residence
Accommodations climbs to the top level. The six housing sections printed
after it now follow it there instead of returning into Student Life and
Housing, which ends at page 44 instead of 45; out-of-order headings drop
from 1 to 0.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants