script-aware-romanization-pipeline
A script-aware romanization pipeline
One entry point takes a line of text and a set of enabled languages, and returns a Latin-script
reading of that line or null:
// adapted — LyricsRomanizer.romanize's multi-line signature, collapsed to one line here
fun romanize(line: String, enabled: Set<RomanizationLanguage>): String?
Everything interesting is in how it decides which of several very different transliteration
strategies to run, per line, not per song: a lyric sheet routinely interleaves an original-script
line with a plain-English one, and romanizing the English half produces nonsense. Detection therefore
runs fresh on every line, and the twelve supported languages split cleanly into two families —
arithmetic/table scripts that need nothing beyond commonMain, and two scripts (Japanese, Chinese)
whose readings genuinely depend on surrounding words and therefore need a real dictionary behind an
expect/actual boundary. Getting that boundary as narrow as possible is most of the design.