Skip to content

Commit cceb54c

Browse files
committed
fix(pdf): drop overprinted duplicate glyphs (kashida) — right_to_left_02 8→6
The scanned-garbled Arabic in right_to_left_02 re-stamps a waw elongation segment offset by far less than its width (an overprint for visual weight), so the parser emitted ~25 extra `و` (`قويووووة` vs docling's `قويوووة`). The line sanitizer's ligature-recompose was appending the duplicate because its box overlaps the previous glyph within tolerance. `line_cells` now drops a same-character glyph re-stamped at an *offset* overlapping box (offset > 0.1). The offset guard preserves ligature expansion, which decomposes one glyph into several chars at the *identical* box (`ff`→`ff`, offset ≈ 0) — verified 2305.03393v1-pg9 stays byte-exact. The whole garbled paragraph now matches docling; the conformance exact count is unchanged at 5/14 (the remaining right_to_left_02 diff is the page-number `11` layout/reading order). Parser-path only (`euclidean`). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QYCj8stK1TzKcy6crtTfha
1 parent e70cdfd commit cceb54c

3 files changed

Lines changed: 31 additions & 10 deletions

File tree

PDF_PARSER_NOTES.md

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,14 +109,24 @@ Diff: `up to 1 / 4` / `from 1 / 4` have a **double** space; `1 / 6` and
109109
box-geometry layer has to match docling globally, not per-case. Left for a
110110
dedicated font-metrics effort; a magic-number nudge is too fragile to ship.
111111

112-
## Blocker C — right_to_left_02 (open, two parts)
113-
1. Layout: the top `11` page number is classified as a picture (`<!-- image -->`);
114-
the recovered orphan lands at the bottom. docling labels it `text`, first.
115-
This is an RT-DETR layout-model classification difference, not a text issue.
116-
2. Text: the parser emits ~25 extra `و` (waw) on the scanned-garbled Arabic
117-
(`قويووووة` vs `قويوووة`) — a kashida/tatweel elongation the parser renders as
118-
repeated glyphs where docling collapses them. Needs the parser to match
119-
docling's tatweel handling.
112+
## Blocker C — right_to_left_02 (text half DONE; layout half open)
113+
114+
`right_to_left_02` went 8 → **6** diff-lines. Two independent diffs; one fixed:
115+
116+
1. ~~**Kashida over-emission**~~ — DONE. The parser emitted ~25 extra `و`
117+
(`قويووووة` vs `قويوووة`): the scanned-garbled Arabic re-stamps a waw
118+
elongation segment offset by ≪ its width (overprint for weight), and the line
119+
sanitizer's ligature-recompose was appending the duplicate. `line_cells` now
120+
drops a same-character glyph re-stamped at an *offset* overlapping box (>0.1
121+
offset so a ligature expansion at the *identical* box — ```ff` — is still
122+
recomposed; verified 2305-pg9 stays exact). The whole garbled paragraph now
123+
matches docling byte-for-byte.
124+
2. **Layout/reading-order (open).** The bottom-left page number `11` is emitted
125+
by docling as a *text* item, **first** in reading order, with no picture. Our
126+
pipeline false-detects a picture at the top (`<!-- image -->`) and orders the
127+
orphan-recovered `11` last. Matching needs docling's picture-suppression +
128+
page-number-first reading order for this page — a layout-model/ordering
129+
change with cross-fixture risk, deferred.
120130

121131
## Future improvements (validated by the completeness pass)
122132

crates/fleischwolf-pdf/src/dp_lines.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,17 @@ pub(crate) fn line_cells(glyphs: &[Glyph], page_h: f32, euclidean: bool) -> Vec<
228228
// into one cell so the contraction never inserts a space inside it.
229229
if let Some(last) = cells.last_mut() {
230230
if (last.rx0 - g.ll as f64).abs() < 0.5 && (last.rx1 - g.lr as f64).abs() < 0.5 {
231+
// Overprint duplicate: the *same* character re-stamped, offset by a
232+
// fraction of its width (a kashida/elongation segment re-drawn for
233+
// weight). docling-parse drops it; appending over-counts
234+
// (right_to_left_02's `قويووووة` vs `قويوووة`). Require a real offset
235+
// (> 0.1) so a ligature expansion — which decomposes one glyph into
236+
// several chars at the *identical* box (`ff`→`ff`, diff ≈ 0) — is still
237+
// recomposed; real doubled letters sit a full advance apart (> 0.5).
238+
let offset = (g.ll as f64 - last.rx0).abs();
239+
if euclidean && offset > 0.1 && last.text.chars().next_back() == Some(g.ch) {
240+
continue;
241+
}
231242
last.text.push(g.ch);
232243
last.ltr = !is_right_to_left(&last.text);
233244
continue;
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<!-- image -->
22

3-
وعليه، فإن الحكومة المصرية تضع صوو عييهاوخ لوال المر اوة الم باوة تكايف السيد رئيس الجماورية لاخ بخلعمل ياى تح يق يدد من الأ هودا ياى رعساخ : وضع ماف بهخء الإنسخن المصري ياى رعس قخئموة الأولويوخت، لخصووة فووا مجووخحت الصووحة واللعاوويل، العموول ياووى تح يووق معوودحت نمووو قويووووة ومسوووولدامة و ووووخماة فووووا عذاووووف ال لخيووووخت، و وووو ا الح ووووخ ياووووى محووددات الأموون ال وووما المصووري فووا ضوووء اللحووديخت الإقايميووة والدولي ووة، ومواصوواة واووود تلوووير الماووخر ة السيخسووية، واسوولمرار ملخبعووة ما و وخت الأمووون واحسووول رار ومكخفحوووة الإرهوووخ ، تلووووير ما وووخت ال خفوووة والوووويا الوووو،ها، والبلوووخ الوووديها المعلووودل ياوووى الهحوووو الووو ي يرسووو م وووخهيل الموا،هة والسام المجلمعا.
3+
وعليه، فإن الحكومة المصرية تضع صوو عييهاوخ لوال المر اوة الم باوة تكايف السيد رئيس الجماورية لاخ بخلعمل ياى تح يق يدد من الأ هودا ياى رعساخ : وضع ماف بهخء الإنسخن المصري ياى رعس قخئموة الأولويوخت، لخصووة فووا مجووخحت الصووحة واللعاوويل، العموول ياووى تح يووق معوودحت نمووو قويوووة ومسووولدامة و وووخماة فوووا عذاوووف ال لخيوووخت، و ووو ا الح وووخ ياوووى محوددات الأمون ال ووما المصوري فوا ضووء اللحوديخت الإقايميوة والدوليوة، ومواصوواة واووود تلوووير الماووخر ة السيخسووية، واسوولمرار ملخبعووة ما و وخت الأمووون واحسووول رار ومكخفحوووة الإرهوووخ ، تلووووير ما وووخت ال خفوووة والوووويا الوووو،ها، والبلوووخ الوووديها المعلووودل ياوووى الهحوووو الووو ي يرسووو م وووخهيل الموا،هة والسام المجلمعا.
44

55
ووف ًخ لمخ سبق، يسولاد برنوخما الحكوموة المصورية لوال ال لور ( - 2024 )2026 تح يق عربعة عهدا اسلراتيجية رئيسة، وها ياى الهحو الآتا:
66

77
<!-- formula-not-decoded -->
88

9-
تجدر الإ خر إلى عنه قد تل تحديد مسولادفخت البرنوخما بخحسولهخد باوكل رئووويس ياوووى مسووولادفخت ر يوووة مصووور 2023 ، وتوصووويخت واسوووخت الحووووار الووو،ها، ومسوولادفخت الووو ارات، والبرنووخما الووو،ها ليصووا خت الايكايووة، ومبلاف احسلراتيجيخت الو،هية.
9+
تجدر الإ خر إلى عنه قد تل تحديد مسولادفخت البرنوخما بخحسولهخد باوكل رئووويس ياوووى مسووولادفخت ر يوووة مصووور 2023 ، وتوصووويخت واسوووخت الحووووار الوو،ها، ومسولادفخت الوو ارات، والبرنوخما الوو،ها ليصوا خت الايكايوة، ومبلاف احسلراتيجيخت الو،هية.
1010

1111
11

0 commit comments

Comments
 (0)