fix: Änderungsbericht erkennt Apostrophe im Wort; output/ ignorieren

- „Bahrs“ → „Bahr’s“ ist jetzt eine Änderung; ’ ' ` gelten als gleich,
  Anführungszeichen am Wortrand zählen weiterhin nicht
- Prüfmarken auch englisch: [check: …]
- output/ (eigene Ergebnisse und Testläufe) in .gitignore

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-10-10 20:33:04 +02:00
commit 95bdc660ca
3 changed files with 35 additions and 4 deletions

3
.gitignore vendored
View file

@ -9,3 +9,6 @@ __pycache__/
# Persönliche Claude-Code-Einstellungen
.claude/settings.local.json
# Eigene Ergebnisse und Testläufe
output/

View file

@ -11,9 +11,12 @@ import re
from vtt2txt import vtt_to_lines
REVIEW_MARK = re.compile(r"\[prüfen:[^\]]*\]")
TOKEN = re.compile(r"\[prüfen:[^\]]*\]|\S+")
# "[prüfen: …]" in German speeches, "[check: …]" in English ones
REVIEW_MARK = re.compile(r"\[(?:prüfen|check):[^\]]*\]")
TOKEN = re.compile(rf"{REVIEW_MARK.pattern}|\S+")
NON_WORD = re.compile(r"[^\w]+")
NON_WORD_KEEP_APOSTROPHE = re.compile(r"[^\w']+")
APOSTROPHES = str.maketrans("’‘`´", "''''")
ABBREVIATION = re.compile(r"\w\.") # one part of "z. B.", "d. h."
ABBREVIATION_END = re.compile(r"(?:^|\s)\w\.$")
EMPTY = "∅"
@ -32,8 +35,13 @@ def add_token(words, token):
def normalize(word):
"""Compare words without case and punctuation; those changes are expected."""
return NON_WORD.sub("", word.lower()) or word
"""Compare words without case and punctuation; those changes are expected.
Apostrophes inside a word count ("Bahr’s" is not "Bahrs"), quotes at its
edges do not.
"""
word = word.lower().translate(APOSTROPHES)
return NON_WORD_KEEP_APOSTROPHE.sub("", word).strip("'") or word
@dataclass

View file

@ -31,6 +31,26 @@ def test_expected_edits_are_no_changes(raw, corrected):
assert changes(raw, corrected) == []
@pytest.mark.parametrize("raw, corrected", [
("gibt's", "gibt’s"), # apostrophe variants
("er sagte Frieden", "Er sagte ‚Frieden‘."), # quotes at the edges
])
def test_apostrophes_and_quotes_unchanged(raw, corrected):
assert changes(raw, corrected) == []
def test_apostrophe_inside_word_is_a_change():
assert changes("Egon Bahrs Politik", "Egon Bahr’s Politik") == [
("replace", "Bahrs", "Bahr’s"),
]
def test_english_review_marks():
comparison = ae.compare("his name is Kocher", "His name is Kocher [check: Kocha].")
assert list(comparison.changes()) == []
assert sum(len(m) for m in comparison.marks.values()) == 1
def test_replace_insert_delete():
raw = "die gedeiliche Zusammenarbeit war das gut heute"
corrected = "die gedeihliche Zusammenarbeit war doch gut"