The Python leg of the Interscript deterministic transliteration engines
(siblings: interscript-ruby, interscript-js). Parity matters: a map must
produce identical output in every engine, and maps that need the
phonological layer dispatch to a secryst
crystal (pip install secryst).
Implemented against the real interscript/maps corpus (289 .imp maps):
.impDSL parsing: metadata (incl.|block scalars), embeddedtests,dependency, stages.- Executor:
parallel { sub }with longest-match-wins AND the interscript-ruby casing convention (uppercase result inside ALL-CAPS words:БЯГА→BYAGA,Бяга→Byaga),substregex,run,compose/decompose,downcase/upcase/titlecase. - Unsupported constructs (
subwithafter:/before:contexts,any(),boundary,secryst/rababa) raiseExecutionErrorby default, or are recorded inengine.skipped_unsupportedwithon_unsupported="skip".
Expression layer (v0.2): any("…") char classes, any("a".."z")
ranges, any(["x","y"]) alternations, maybe("…"), space,
boundary, line_start/line_end, + concatenation, and
before:/after: context guards compiled to lookarounds.
Dependency-aliased dotted run map.<alias>.stage.<name> targets
resolve through the map's own dependency …, as: … table.
Measured against the maps' own embedded tests (2026-08-20):
| map | result | remaining gap |
|---|---|---|
| un-bul-Cyrl-Latn-1977 | 98/98 | none |
| un-ell-Grek-Latn-1987-ts | 206/242 | posix letter-class guards (libs aliases) |
| bgnpcgn-prs-Arab-Latn-2007 | loads, runs | proper-noun capitalization + diphthong context rules |
Roadmap: posix alias resolution (libs/*.iml) → capitalization
semantics for caseless scripts → .isc YAML front-end (shares this
executor) → golden parity vs interscript-ruby across all 289 maps.
importinterscriptinterscript.add_load_path(".../interscript/maps/maps")
interscript.transliterate("un-bul-Cyrl-Latn-1977", "нос Бяга БЯГА")
# -> "nos Byaga BYAGA"python3 -m pytest tests
License: BSD-3-Clause.