raw derive PDF: Durchstreichung und Textmarker lassen Programmtext aus, wie Vertrag und Body von #231 sagen; am Korpus unverändert (#231); 10.1.0-beta.6
CI / verify (push) Successful in 8m2s
CI / pwsh (push) Successful in 2m48s
Converters / converters (push) Successful in 9m30s
Release / converters (push) Successful in 26s
Release / release (push) Successful in 36s
Release / wiki-mirror (push) Skipped

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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SnAJ7Z3CpVD3PRbN73QtU2
This commit is contained in:
torbenandClaude Opus 5.5 committed 2026-10-14 21:20:00 +02:00
1 parent a581271165
commit cb1c9a2963
4 files changed
+13 -12

No files matched your search

+2 -1
View File
@@ -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 **Author:** Torben Nehmer
@@ -27,6 +27,7 @@ place only: `instructions/dev/version-parts.md` § The candidate model.
**Low impact** **Low impact**
- instructions/dev: Konverter-Vergleich – eigene Ableitung gegen Referenzwerkzeuge am privaten Korpus, mit Grundlinie - 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 - 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)
<!-- /wikitool:bumps --> <!-- /wikitool:bumps -->
### Konverter-Tests gegen echte Dokumente im privaten Repository ### Konverter-Tests gegen echte Dokumente im privaten Repository
+1 -1
View File
@@ -1 +1 @@
10.1.0-beta.5 10.1.0-beta.6
+6 -6
View File
@@ -491,7 +491,7 @@ def context(layouts: list[PageLayout]) -> Context:
return Context(body_size, body_colour, templates(layouts)) 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 """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 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 (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 = [ along = [
(_centre(layout.chars[i].box)[0 if horizontal else 1], i) (_centre(layout.chars[i].box)[0 if horizontal else 1], i)
for i in range(len(layout.chars)) 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() along.sort()
keys = [key for key, _ in along] keys = [key for key, _ in along]
@@ -536,7 +536,7 @@ def _struck(layout: PageLayout, grid: Grid, template: Templates, table: set[int]
return found 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 """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.""" wider than the text it covers plus HIGHLIGHT_MAX_EXTRA type heights. The colour per character."""
found: dict[int, str] = {} found: dict[int, str] = {}
@@ -552,7 +552,7 @@ def _highlighted(layout: PageLayout, template: Templates, table: set[int]) -> di
continue continue
covered = [ covered = [
i for i, char in enumerate(layout.chars) 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: if not covered:
continue continue
@@ -604,9 +604,9 @@ def page_glyphs(layout: PageLayout, ctx: Context) -> list[Glyph]:
strong[i] = "bold" strong[i] = "bold"
if _is_italic(char): if _is_italic(char):
italic.add(i) 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 strong[i] = colour
struck = _struck(layout, grid, ctx.template, table) struck = _struck(layout, grid, ctx.template, table | code)
return [ 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) 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) for i, char in enumerate(layout.chars)
@@ -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): def test_program_text_is_left_alone(tree):
code = [ code = [
[("if", {"bold": True, "color": BLUE}), " (x == 1) {"], [("if", {"bold": True, "color": BLUE}), " (x == 1) {"],
[" ", ("return", {"bold": True, "color": BLUE}), " f(a, b);"], [" ", ("return", {"bold": True, "color": BLUE, "highlight": (1, 1, 0)}), " f(a, b);"],
[" y = g(x) + h[0];"], [" ", ("y = g(x)", {"strike": True}), " + h[0];"],
["}"], ["}"],
] ]
_header, text = _derive_pdf(tree, build_styled_pdf([StyledPage(code)])) header, text = _derive_pdf(tree, build_styled_pdf([StyledPage(code)]))
assert "*" not in text assert "*" not in text and "~" not in text and "markings" not in header
@needs_pypdf @needs_pypdf