From cb1c9a29633530146a1c8623a6d314f2c1b75ce6 Mon Sep 17 00:00:00 2001 From: Torben Nehmer Date: Wed, 14 Oct 2026 21:20:00 +0200 Subject: [PATCH] =?UTF-8?q?raw=20derive=20PDF:=20Durchstreichung=20und=20T?= =?UTF-8?q?extmarker=20lassen=20Programmtext=20aus,=20wie=20Vertrag=20und?= =?UTF-8?q?=20Body=20von=20#231=20sagen;=20am=20Korpus=20unver=C3=A4ndert?= =?UTF-8?q?=20(#231);=2010.1.0-beta.6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Files changed: - CHANGES.md - VERSION - tools/chemenu/filters/pdf_layout.py - tools/chemenu/tests/test_raw_derive_binary.py Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01SnAJ7Z3CpVD3PRbN73QtU2 --- CHANGES.md | 3 ++- VERSION | 2 +- tools/chemenu/filters/pdf_layout.py | 12 ++++++------ tools/chemenu/tests/test_raw_derive_binary.py | 8 ++++---- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index f42135a..6ce89c0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -14,7 +14,7 @@ place only: `instructions/dev/version-parts.md` § The candidate model. --- -## 10.1.0-beta.5 - 2026-10-14 - raw derive PDF: Auszeichnungen auf ein Minimum - Struktur zuerst, ~~ ** * nur wo eindeutig, Bildseiten-CHECK nur für Inhaltsbilder +## 10.1.0-beta.6 - 2026-10-14 - raw derive PDF: Durchstreichung und Textmarker lassen Programmtext aus, wie der Vertrag sagt (#231) **Author:** Torben Nehmer @@ -27,6 +27,7 @@ place only: `instructions/dev/version-parts.md` § The candidate model. **Low impact** - instructions/dev: Konverter-Vergleich – eigene Ableitung gegen Referenzwerkzeuge am privaten Korpus, mit Grundlinie - instructions/dev: converter-comparison nennt harness/compare/README.md als Ort der Einrichtung +- raw derive PDF: Durchstreichung und Textmarker lassen Programmtext aus, wie der Vertrag sagt (#231) ### Konverter-Tests gegen echte Dokumente im privaten Repository diff --git a/VERSION b/VERSION index 040658f..9a6b25b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -10.1.0-beta.5 +10.1.0-beta.6 diff --git a/tools/chemenu/filters/pdf_layout.py b/tools/chemenu/filters/pdf_layout.py index ce2b3a7..765c4d6 100644 --- a/tools/chemenu/filters/pdf_layout.py +++ b/tools/chemenu/filters/pdf_layout.py @@ -491,7 +491,7 @@ def context(layouts: list[PageLayout]) -> Context: return Context(body_size, body_colour, templates(layouts)) -def _struck(layout: PageLayout, grid: Grid, template: Templates, table: set[int]) -> set[int]: +def _struck(layout: PageLayout, grid: Grid, template: Templates, left_alone: set[int]) -> set[int]: """Rule 2: a thin line through the middle of at least STRIKE_MIN_CHARS characters that does not reach further than STRIKE_OVERHANG past them, measured in the characters' own frame (so text turned by a quarter is struck by a vertical line). Not a table's ruling, not a @@ -505,7 +505,7 @@ def _struck(layout: PageLayout, grid: Grid, template: Templates, table: set[int] along = [ (_centre(layout.chars[i].box)[0 if horizontal else 1], i) for i in range(len(layout.chars)) - if layout.chars[i].direction in ((0, 180) if horizontal else (90, 270)) and i not in table + if layout.chars[i].direction in ((0, 180) if horizontal else (90, 270)) and i not in left_alone ] along.sort() keys = [key for key, _ in along] @@ -536,7 +536,7 @@ def _struck(layout: PageLayout, grid: Grid, template: Templates, table: set[int] return found -def _highlighted(layout: PageLayout, template: Templates, table: set[int]) -> dict[int, str]: +def _highlighted(layout: PageLayout, template: Templates, left_alone: set[int]) -> dict[int, str]: """Rule 3: a bright, saturated fill drawn under the text, about as high as a line and no wider than the text it covers plus HIGHLIGHT_MAX_EXTRA type heights. The colour per character.""" found: dict[int, str] = {} @@ -552,7 +552,7 @@ def _highlighted(layout: PageLayout, template: Templates, table: set[int]) -> di continue covered = [ i for i, char in enumerate(layout.chars) - if char.order > fill.order and i not in table and _inside(fill.box, *_centre(char.box)) + if char.order > fill.order and i not in left_alone and _inside(fill.box, *_centre(char.box)) ] if not covered: continue @@ -604,9 +604,9 @@ def page_glyphs(layout: PageLayout, ctx: Context) -> list[Glyph]: strong[i] = "bold" if _is_italic(char): italic.add(i) - for i, colour in _highlighted(layout, ctx.template, table).items(): + for i, colour in _highlighted(layout, ctx.template, table | code).items(): strong[i] = colour - struck = _struck(layout, grid, ctx.template, table) + struck = _struck(layout, grid, ctx.template, table | code) return [ Glyph(char.text, strong[i] is not None, i in struck, i in italic, strong[i] if strong[i] not in (None, "bold") else None) for i, char in enumerate(layout.chars) diff --git a/tools/chemenu/tests/test_raw_derive_binary.py b/tools/chemenu/tests/test_raw_derive_binary.py index a472d4b..3a24dc9 100644 --- a/tools/chemenu/tests/test_raw_derive_binary.py +++ b/tools/chemenu/tests/test_raw_derive_binary.py @@ -299,12 +299,12 @@ def test_text_turned_by_a_quarter_is_struck_by_a_line_in_its_own_direction_only( def test_program_text_is_left_alone(tree): code = [ [("if", {"bold": True, "color": BLUE}), " (x == 1) {"], - [" ", ("return", {"bold": True, "color": BLUE}), " f(a, b);"], - [" y = g(x) + h[0];"], + [" ", ("return", {"bold": True, "color": BLUE, "highlight": (1, 1, 0)}), " f(a, b);"], + [" ", ("y = g(x)", {"strike": True}), " + h[0];"], ["}"], ] - _header, text = _derive_pdf(tree, build_styled_pdf([StyledPage(code)])) - assert "*" not in text + header, text = _derive_pdf(tree, build_styled_pdf([StyledPage(code)])) + assert "*" not in text and "~" not in text and "markings" not in header @needs_pypdf