runic-reader-2 / code /runic_norm.py
kesha-humonen's picture
Add files using upload-large-folder tool
ed46c5d verified
Raw History Blame Contribute Delete
1.95 kB
"""Transliteration normalisation shared by the recognition target and the translation input.
Rundata-style editorial markup is stripped: section labels, word separators, lacunae and
Latin text in braces become token boundaries; brackets, parentheses, bind-rune carets and
uncertainty marks are deleted inside words. What remains is a lowercase string over the
transliteration alphabet, with R (yr) kept distinct from r.
"""
import re
import unicodedata
ALPHABET = set("abcdefghijklmnopqrstuvwxyzþðæøąïŋöåäR")
_BRACES = re.compile(r"\{[^}]*\}")
_SECTION = re.compile(r"§\s?[A-Za-z]{1,3}\b|\b[Ss]ide\s+[A-Za-z]\b|\$|¶|‖|\|")
_DELETE = re.compile(r"[\[\]()<>^?´`ˈ]")
_BOUNDARY = re.compile(r"[·•:;×÷+*'\"/\\=\-–—…!,.#°†¤_᛫᛬⁝│~0-9]")
def normalize(text):
if not isinstance(text, str):
return ""
s = unicodedata.normalize("NFC", text)
s = _BRACES.sub(" ", s)
s = _SECTION.sub(" ", s)
s = s.replace("ʀ", "R").replace("ᴀ", "a")
s = _DELETE.sub("", s)
s = _BOUNDARY.sub(" ", s)
tokens = []
for tok in s.split():
tok = "".join(ch if ch == "R" else ch.lower() for ch in tok)
if all(ch in ALPHABET for ch in tok):
tokens.append(tok)
return " ".join(tokens)
_T_CODES = re.compile(r"†\s?[$A-Z]?|§\s?[A-Z]{1,2}\b|[$¶|{}*]")
_T_UNCERTAIN = re.compile(r"\s?\(\?\)")
_T_BRACKETS = re.compile(r"[\[\]<>]")
_T_ELLIPSIS = re.compile(r"(?:\.\.\.|…)(?:\s*(?:\.\.\.|…))*")
def clean_translation(text):
"""Strip Rundata editorial markup from a translation, keeping its wording."""
if not isinstance(text, str):
return ""
s = unicodedata.normalize("NFC", text)
s = _T_CODES.sub(" ", s)
s = _T_UNCERTAIN.sub("", s)
s = _T_BRACKETS.sub("", s)
s = _T_ELLIPSIS.sub("...", s)
s = re.sub(r"\s+", " ", s).strip()
s = re.sub(r"\s+([,;:!?])", r"\1", s)
s = re.sub(r"\s+\.(?!\.)", ".", s)
return s