Deterministic Serbian and Montenegrin script conversion, Cyrillic ↔ Latin. Case preservation, digraph handling, quoted-region protection, Roman-numeral and non-native-word filtering.
Both official scripts of Serbian (and Montenegrin) map one-to-one at the letter level: љ↔lj, њ↔nj, џ↔dž, plus с́↔ś, з́↔ź for Montenegrin. The library plays the pairing from a YAML table; there is no per-language code path in the engine.
The library is distributed as git tags (not published to PyPI). Install from GitHub:
# latest release
pip install git+https://github.com/apakabarlabs/serbian-translit-python.git
# pin a specific version (see releases: https://github.com/apakabarlabs/serbian-translit-python/releases)
pip install git+https://github.com/apakabarlabs/serbian-translit-python.git@vX.Y.Zfrom serbian_translit import srp, cnr
srp.to_cyr("Njujork") # 'Њујорк'
srp.to_cyr("LJUBAV") # 'ЉУБАВ'
srp.to_cyr("New York") # 'New York' (word skipped, has non-native letters)
srp.to_cyr('grupa „AC/DC"') # 'група „AC/DC"' (quoted region preserved)
srp.to_lat("Њујорк") # 'Njujork'
cnr.to_cyr("śever") # 'с́евер' (с + U+0301)
cnr.to_lat("с́евер") # 'śever'- Digraphs
lj,nj,dž(Latin) ↔љ,њ,џ(Cyrillic) with case preservation (Njin title-case position,NJinside all-caps). - Montenegrin extras
ś,ź↔с́,з́(base letter + combining acute U+0301; no precomposed codepoints exist). - Đ variants
Đ(U+0110),đ(U+0111),Ð(U+00D0 Eth),ð(U+00F0 eth) all map toЂ/ђ. - Roman numerals (
II,XIV,XX) stay in Latin regardless of direction. - Words with non-native letters (Latin
w,x,y,q) are skipped whole; treated as foreign inclusions. - Quoted regions (
"…",„…",“…”,«…») are preserved verbatim so brand names and foreign quotes survive round-trip. - Non-alphabetic content (numbers, punctuation, whitespace) is left unchanged.
Rules live in serbian_translit/data/rules.yaml; test cases in tests/tests.yaml. Both files are the source of truth shared with the Swift and (upcoming) Kotlin ports so behaviour stays identical across languages.