Fix Step 5h: reject grammar patterns in slash-IPA, convert trailing variants
- Reject /.../ matches containing spaces, parens, or commas (e.g. sb/sth up) - Second pass converts trailing /ipa2/ after [ipa1] (double pronunciation) - Validate standalone /ipa/ at start against same reject pattern Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -823,26 +823,44 @@ class TestSlashIpaConversion:
|
||||
r"(/[^/]{2,}/)"
|
||||
)
|
||||
_STANDALONE_SLASH_IPA_RE = re.compile(r'^/([^/]{2,})/')
|
||||
_SLASH_IPA_REJECT_RE = re.compile(r'[\s(),]')
|
||||
|
||||
def _replace(m):
|
||||
headword = m.group(1)
|
||||
ocr_ipa = m.group(2)
|
||||
inner_raw = ocr_ipa.strip("/").strip()
|
||||
if _SLASH_IPA_REJECT_RE.search(inner_raw):
|
||||
return m.group(0)
|
||||
clean_hw = re.sub(r'[²³¹\d]', '', headword).strip()
|
||||
ipa = _lookup_ipa(clean_hw, "british") if clean_hw else None
|
||||
if ipa:
|
||||
return f"{headword} [{ipa}]"
|
||||
inner = ocr_ipa.strip("/").strip().lstrip("'").strip()
|
||||
inner = inner_raw.lstrip("'").strip()
|
||||
if inner:
|
||||
return f"{headword} [{inner}]"
|
||||
return m.group(0)
|
||||
|
||||
new_text = _SLASH_IPA_RE.sub(_replace, text)
|
||||
|
||||
# Second pass: trailing /ipa/ after [ipa]
|
||||
_AFTER_BRACKET_SLASH = re.compile(r'(?<=\])\s*(/[^/]{2,}/)')
|
||||
def _replace_trailing(m):
|
||||
inner = m.group(1).strip("/").strip().lstrip("'").strip()
|
||||
if _SLASH_IPA_REJECT_RE.search(inner):
|
||||
return m.group(0)
|
||||
if inner:
|
||||
return f" [{inner}]"
|
||||
return m.group(0)
|
||||
new_text = _AFTER_BRACKET_SLASH.sub(_replace_trailing, new_text)
|
||||
|
||||
if new_text == text:
|
||||
m = _STANDALONE_SLASH_IPA_RE.match(text)
|
||||
if m:
|
||||
inner = m.group(1).strip().lstrip("'").strip()
|
||||
if inner:
|
||||
new_text = "[" + inner + "]" + text[m.end():]
|
||||
inner = m.group(1).strip()
|
||||
if not _SLASH_IPA_REJECT_RE.search(inner):
|
||||
inner = inner.lstrip("'").strip()
|
||||
if inner:
|
||||
new_text = "[" + inner + "]" + text[m.end():]
|
||||
return new_text
|
||||
|
||||
def test_tiger_dict_lookup(self):
|
||||
@@ -865,21 +883,19 @@ class TestSlashIpaConversion:
|
||||
assert "/und/" not in result
|
||||
|
||||
def test_sb_sth_not_matched(self):
|
||||
"""sb/sth should NOT be treated as IPA (too short or grammar)."""
|
||||
"""sb/sth should NOT be treated as IPA (contains space/parens)."""
|
||||
text = "(tie sb/sth up) jdn/etwas anbinden"
|
||||
result = self._run_step_5h(text)
|
||||
# /sth up) jdn/ has length > 2 but the headword is "sb" which is
|
||||
# not a real word — the regex would match, but "sb" won't be in dict
|
||||
# and the inner text would contain grammar, not IPA.
|
||||
# Key assertion: "jdn/etwas" is not corrupted
|
||||
assert "etwas" in result
|
||||
# The inner content "sth up) jdn" has spaces and parens → rejected
|
||||
assert result == text # unchanged
|
||||
|
||||
def test_double_ipa(self):
|
||||
"""times/taimz/ /tamz/ → both converted."""
|
||||
def test_double_ipa_both_converted(self):
|
||||
"""times/taimz/ /tamz/ → times [tˈaɪmz] [tamz] (both converted)."""
|
||||
result = self._run_step_5h("times/taimz/ /tamz/ Präp")
|
||||
assert "[tˈaɪmz]" in result
|
||||
# Second /tamz/ is standalone after first replacement
|
||||
assert "[tamz]" in result
|
||||
assert "/taimz/" not in result
|
||||
assert "/tamz/" not in result
|
||||
|
||||
def test_standalone_slash_ipa_at_start(self):
|
||||
"""/tam/ Nomen → [tam] Nomen (no headword in cell)."""
|
||||
|
||||
Reference in New Issue
Block a user