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
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:
1 parent
a581271165
commit
cb1c9a2963
4 files changed
+13
-12
No files matched your search
+2
-1
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in new issue
Block a user