Skip to main content

Zero-dependency script & phoneme-notation core — ISO-15924 detection & metadata, IPA↔ARPABET/X-SAMPA/Lexique/Kirshenbaum/Cotovía/RFE, Buckwalter↔Arabic, Hangul→jamo, kana

Project description

scriptconv

License: Apache 2.0 Build Tests PyPI version

scriptconv is a zero-dependency Python library for written-script and phoneme-notation operations:

  • Script identification & metadata — ISO-15924 detection, character-range lookup, typological script_type, base direction, mixed-script segmentation (script_runs), and language ↔ script mapping.
  • Phoneme-notation transcoding — IPA ↔ ARPABET, X-SAMPA, Lexique, Kirshenbaum, Cotovía and RFE, routed through IPA, with queryable per-notation fidelity metadata (NOTATION_INFO) and a looks_like_ipa detector.
  • Script transliteration & decomposition — Buckwalter ↔ Arabic script, Hangul → jamo (compatibility or conjoining), Hiragana ↔ Katakana.

Every conversion is a pure data table or arithmetic operation — no phonemization, no linguistic rules, no external files, and no runtime dependencies beyond the Python standard library.

Transcoding is reversible where the target inventory permits — see Fidelity guarantees for the exact per-notation guarantees.

Scope

scriptconv is exclusively about written scripts: identification and metadata, transliteration between script representations, re-encoding of phoneme symbols between notation systems, and orthographic decomposition. It never phonemizes — anything that requires knowing how a language sounds (grapheme-to-phoneme rules, allophony, coarticulation, sandhi) is outside this library's scope.

Installation

pip install scriptconv

Development

uv pip install -e '.[test]'
pytest tests/

tests/test_examples.py runs the scripts under examples/, which import the installed package — install with -e first.

Quick start

from scriptconv import (
    detect_script, char_script, script_distribution, script_runs, base_direction,
    lang_to_script, script_to_langs, normalize_script_tag, SCRIPT_REGISTRY,
    arpa_to_ipa, ipa_to_arpa,
    xsampa_to_ipa, ipa_to_xsampa,
    buckwalter_to_arabic, arabic_to_buckwalter,
    lexique_to_ipa, ipa_to_lexique,
    kirshenbaum_to_ipa, ipa_to_kirshenbaum, cotovia_to_ipa, ipa_to_cotovia,
    rfe_to_ipa, ipa_to_rfe, looks_like_ipa,
    decompose_hangul, hira_to_kana, kana_to_hira,
    convert, can_convert, convert_batch, Notation, NOTATION_INFO,
)

detect_script("안녕하세요")           # "Hang"
char_script("ɑ")                    # "Latn" (IPA Extensions)
script_distribution("Hello مرحبا")   # {'Latn': 5, 'Arab': 5}
script_runs("привет hello")          # [('Cyrl', 'привет '), ('Latn', 'hello')]
base_direction("مرحبا بالعالم")      # "rtl"
SCRIPT_REGISTRY["Arab"].script_type  # "abjad"  (typological class)

lang_to_script("pt-BR")             # "Latn"
script_to_langs("Cyrl")             # ['av', 'ba', 'be', 'bg', ...]
normalize_script_tag("syllabics")   # "Cans"
normalize_script_tag("japanese")    # "Hira"

arpa_to_ipa("HH AH0 L OW1")        # "həloʊ"
ipa_to_arpa("həloʊ")               # "HH AX L OW"

xsampa_to_ipa("tS")                 # "tʃ"
ipa_to_xsampa("ɹ")                  # "r\\"

buckwalter_to_arabic("mrHbA")       # "مرحبا"
arabic_to_buckwalter("مرحبا")      # "mrHbA"

lexique_to_ipa("b§ZuR")            # "bɔ̃ʒuʁ"  (bonjour)
ipa_to_lexique("vɛ̃")               # "v5"  (vin)

kirshenbaum_to_ipa("S")             # "ʃ"   (espeak-ng ASCII-IPA)
ipa_to_kirshenbaum("ŋ")             # "N"

cotovia_to_ipa("karro")             # "karo"  (Galician Cotovía TTS notation)
ipa_to_cotovia("ʎ")                 # "L"

rfe_to_ipa("kaša")                  # "kaʃa"  (Spanish/Romance RFE alphabet)
ipa_to_rfe("ɲ")                     # "ñ"

looks_like_ipa("pʰɑtʃ")             # True  (heuristic: has IPA-distinctive symbols)
looks_like_ipa("hello")             # False

decompose_hangul("국민")             # "ㄱㅜㄱㅁㅣㄴ"  (orthographic jamo, no assimilation)
hira_to_kana("ひらがな")             # "ヒラガナ"
kana_to_hira("カタカナ")             # "かたかな"

convert("NG", Notation.ARPA, Notation.XSAMPA)  # "N"
convert("HH AH0 L OW1", "arpa", "kirshenbaum") # "h@loU"
can_convert("arpa", "x-sampa")                 # True
can_convert("buckwalter", "ipa")               # False
list(convert_batch(["HH AH0", "AY1"], "arpa", "ipa"))  # ['hə', 'aɪ']

NOTATION_INFO[Notation.ARPA].lossless_from_ipa  # False (restricted inventory)

CLI

python -m scriptconv convert arpa ipa "HH AH0 L OW1"
python -m scriptconv detect "안녕하세요"
python -m scriptconv distribution "Hello مرحبا"
python -m scriptconv direction "مرحبا بالعالم"
python -m scriptconv decompose "국민"
python -m scriptconv lang ko

Modules

Module Contents
scriptconv.scripts Script dataclass (with script_type), SCRIPT_REGISTRY (34 scripts), detect_script, char_script, script_distribution, script_runs, base_direction, lang_to_script, script_to_langs, normalize_script_tag
scriptconv.notation Notation enum, NotationInfo/NOTATION_INFO fidelity registry, convert facade, can_convert predicate, convert_batch generator, pair-wise converters (ARPABET ↔ IPA, X-SAMPA ↔ IPA, Buckwalter ↔ Arabic, Lexique ↔ IPA, Kirshenbaum ↔ IPA, Cotovía ↔ IPA, RFE ↔ IPA), looks_like_ipa detector
scriptconv.translit decompose_hangul (Hangul blocks → jamo, compatibility or conjoining), hira_to_kana/kana_to_hira — all orthographic only

Documentation

  • docs/scripts.md — Script registry, detection, language mapping, label normalisation
  • docs/notation.md — Notation enum, per-pair converter reference, round-trip guarantees
  • docs/translit.md — Hangul decomposition arithmetic and scope boundary

Examples

Runnable scripts in examples/:

File Demonstrates
01_detect_script.py Mixed-script text triage
02_lang_to_script.py Language tag → ISO-15924 mapping
03_arpabet_roundtrip.py CMUdict-style line → IPA and back
04_xsampa.py X-SAMPA ↔ IPA, multi-char longest-first cases
05_buckwalter.py Arabic ↔ Buckwalter both directions
06_lexique.py French Lexique codes → IPA
07_hangul_decompose.py Hangul syllable blocks → jamo letters
08_script_distribution.py Character counts per script + base direction
09_script_to_langs.py Reverse lookup: script → languages
10_new_labels.py New normalize_script_tag labels (japanese, jamo, cjk…)
11_cli.py CLI interface: detect, distribution, direction, decompose, lang
12_kirshenbaum.py Kirshenbaum (ASCII-IPA) ↔ IPA, and ARPABET → Kirshenbaum routing
13_script_runs.py Per-script segmentation of mixed-script text
14_kana_transliteration.py Hiragana ↔ Katakana
15_cotovia.py Cotovía (Galician TTS notation) ↔ IPA
16_rfe.py RFE (Spanish/Romance philology alphabet) ↔ IPA

Fidelity guarantees

Transcoding faithfulness depends on the target notation's inventory. IPA is the hub; notation↔notation goes through IPA. The table below states, for each notation, whether a round-trip is exact and what happens to a symbol the table does not know.

Notation to_ipafrom_ipa round-trip from_ipato_ipa round-trip Unknown-token behaviour
ARPABET Exact for base symbols; stress digits are dropped and AH0AX (schwa) is not distinguished Lossy — ARPABET is an English-only inventory, so any IPA symbol outside it becomes the unknown placeholder arpa_to_ipa: passed through unchanged. ipa_to_arpa: diacritics and suprasegmentals (combining marks, length/stress modifiers) are dropped; other out-of-inventory symbols are replaced with ? by default (unknown= param; unknown="" drops)
X-SAMPA Exact for all canonical symbols Exact except aliases (f\→ɸ, &→æ) normalise to their canonical spelling Passed through unchanged
Buckwalter ↔ Arabic Exact (the ^ shadda alias normalises to canonical ~; precomposed lam-alef ligatures decompose to two chars, visually identical) Exact Passed through unchanged
Lexique ↔ IPA Exact except the °/3 schwa pair (both → ə; reverse always → °) Exact Passed through unchanged
Kirshenbaum ↔ IPA Exact Lossy — restricted ASCII inventory; IPA outside it passes through Passed through unchanged
Cotovía ↔ IPA Exact except the three L/Z/jj symbols for ʎ normalise to L Lossy — Galician/Spanish inventory; IPA outside it passes through Passed through unchanged
RFE ↔ IPA Exact except ñ/ for ɲ normalise to ñ Lossy — core Spanish/Romance inventory; IPA outside it passes through Passed through unchanged

This table is also available programmatically via NOTATION_INFO (NotationInfo records with lossless_to_ipa, lossless_from_ipa, token_separated, and a reference citation per notation).

Notes:

  • The voiced velar stop is stored as script ɡ (U+0261) across all tables; ipa_to_arpa also accepts ASCII g (U+0067) on input.
  • Only ipa_to_arpa substitutes for unknowns today (because ARPABET is a restricted inventory); every other converter passes unknowns through. See docs/notation.md for the per-symbol detail.

License and attribution

scriptconv is released under the Apache-2.0 license.

Derived tables used internally:

Table Source License
ARPABET ↔ IPA chorusai/arpa2ipa Apache-2.0
Buckwalter ↔ Arabic Tim Buckwalter's Arabic transliteration scheme — (factual 1:1 mapping)
Lexique phoneme codes New, B. & Pallier, C. — Manuel de Lexique 3 v3.11, Tableau 2; chrplr/openlexicon CC BY-SA 4.0
Kirshenbaum ↔ IPA Kirshenbaum 1993 ASCII-IPA standard (comp.speech), cross-checked against espeak-ng — (factual symbol mapping)
Cotovía ↔ IPA Universidade de Vigo GTM Cotovía TTS project (fonemas.cpp) — (factual symbol mapping)
RFE ↔ IPA RFE phonetic alphabet (Revista de Filología Española, 1915) — (factual symbol mapping)
Hangul jamo tables stannam/hangul_to_ipa

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

scriptconv-0.0.3a2.tar.gz (53.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

scriptconv-0.0.3a2-py3-none-any.whl (34.8 kB view details)

Uploaded Python 3

File details

Details for the file scriptconv-0.0.3a2.tar.gz.

File metadata

  • Download URL: scriptconv-0.0.3a2.tar.gz
  • Upload date:
  • Size: 53.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for scriptconv-0.0.3a2.tar.gz
Algorithm Hash digest
SHA256 2e0bb744e4c508ea7de85a56c6c1eaf20e0ab52bd70c77320d42fcf94991bd50
MD5 d4e215ccf7be496984cb74bc5536af71
BLAKE2b-256 fce6c26c98bc61fcbbc8e94a013a8e9c105bfe21f5e63b49a9cd4809f07a0c5a

See more details on using hashes here.

File details

Details for the file scriptconv-0.0.3a2-py3-none-any.whl.

File metadata

  • Download URL: scriptconv-0.0.3a2-py3-none-any.whl
  • Upload date:
  • Size: 34.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for scriptconv-0.0.3a2-py3-none-any.whl
Algorithm Hash digest
SHA256 d5cff8f673e9ac682c3996d4a097b0c202198f4f79dfb6381117498f106de176
MD5 3d9ddc7de2efdb7fedb0f44574d6dd25
BLAKE2b-256 59502f8773a0d902ec9c714258962503192cfb14ce89c35e259e2786eda4813c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page