scriptconv 0.0.3a21__tar.gz → 0.0.3a23__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- scriptconv-0.0.3a23/PKG-INFO +434 -0
- scriptconv-0.0.3a23/README.md +315 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/ar.py +50 -29
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/version.py +1 -1
- scriptconv-0.0.3a23/scriptconv.egg-info/PKG-INFO +434 -0
- scriptconv-0.0.3a21/PKG-INFO +0 -334
- scriptconv-0.0.3a21/README.md +0 -215
- scriptconv-0.0.3a21/scriptconv.egg-info/PKG-INFO +0 -334
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/LICENSE +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/pyproject.toml +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/requirements.txt +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/__init__.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/__main__.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/cangjie.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/conventions.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/data/__init__.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/data/cangjie5_tc.tsv.gz +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/graph.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/notation.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/__init__.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_thirdparty/__init__.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_thirdparty/bw2ipa.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_thirdparty/hangul2ipa.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_thirdparty/ko_tables/aspiration.csv +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_thirdparty/ko_tables/assimilation.csv +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_thirdparty/ko_tables/double_coda.csv +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_thirdparty/ko_tables/hanja.tsv +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_thirdparty/ko_tables/ipa.csv +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_thirdparty/ko_tables/neutralization.csv +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_thirdparty/ko_tables/tensification.csv +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_thirdparty/ko_tables/yale.csv +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_thirdparty/shami/__init__.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_thirdparty/shami/codeswitch.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_thirdparty/shami/diacritize.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_thirdparty/shami/dialectal.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_thirdparty/shami/english_g2p.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_thirdparty/shami/espeak.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_thirdparty/shami/frontend.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_thirdparty/shami/levantine_g2p.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_thirdparty/shami/normalize.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_thirdparty/shami/phoneme_inventory.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_thirdparty/zh_num.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_vendored/__init__.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_vendored/kog2p/LICENSE.md +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_vendored/kog2p/__init__.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_vendored/kog2p/rulebook.txt +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_vendored/mantoq/LICENSE.md +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_vendored/mantoq/__init__.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_vendored/mantoq/buck/__init__.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_vendored/mantoq/buck/phonetise_buckwalter.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_vendored/mantoq/buck/symbols.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_vendored/mantoq/buck/tokenization.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_vendored/mantoq/num2words.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/_vendored/mantoq/unicode_symbol2label.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/base.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/en.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/enums.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/eu.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/fa.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/gl.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/he.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/ja.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/ko.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/mul.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/mwl.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/o2ipa.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/pt.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/registry.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/shami.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/vi.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/phonemizers/zh.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/py.typed +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/readings.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/scripts.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv/translit.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv.egg-info/SOURCES.txt +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv.egg-info/dependency_links.txt +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv.egg-info/requires.txt +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/scriptconv.egg-info/top_level.txt +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/setup.cfg +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/tests/test_arpa_stress.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/tests/test_cangjie.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/tests/test_cli.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/tests/test_conventions.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/tests/test_errors_policy.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/tests/test_examples.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/tests/test_graph.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/tests/test_notation.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/tests/test_phonemizers_base.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/tests/test_phonemizers_cjk_ar.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/tests/test_readings.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/tests/test_readings_zh.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/tests/test_scripts.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/tests/test_scripts_stressonnx_compat.py +0 -0
- {scriptconv-0.0.3a21 → scriptconv-0.0.3a23}/tests/test_translit.py +0 -0
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: scriptconv
|
|
3
|
+
Version: 0.0.3a23
|
|
4
|
+
Summary: Zero-dependency script & phoneme-notation core — ISO-15924 detection & metadata, IPA↔ARPABET/X-SAMPA/Lexique/Kirshenbaum/Cotovía/RFE, Buckwalter↔Arabic, Hangul→jamo, kana
|
|
5
|
+
License: Apache-2.0
|
|
6
|
+
Project-URL: Homepage, https://github.com/TigreGotico/scriptconv
|
|
7
|
+
Project-URL: Issues, https://github.com/TigreGotico/scriptconv/issues
|
|
8
|
+
Keywords: ipa,arpabet,x-sampa,kirshenbaum,cotovia,rfe,lexique,buckwalter,hangul,jamo,kana,transliteration,notation,phoneme,phonetic-alphabet,script,iso15924,unicode,tts,g2p
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: Topic :: Text Processing :: Linguistic
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
19
|
+
Classifier: Operating System :: OS Independent
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Provides-Extra: ja
|
|
24
|
+
Requires-Dist: pykakasi<3,>=2.3; extra == "ja"
|
|
25
|
+
Provides-Extra: zh
|
|
26
|
+
Requires-Dist: pypinyin<1,>=0.50; extra == "zh"
|
|
27
|
+
Provides-Extra: phonemizers
|
|
28
|
+
Requires-Dist: quebra-frases; extra == "phonemizers"
|
|
29
|
+
Requires-Dist: langcodes; extra == "phonemizers"
|
|
30
|
+
Provides-Extra: espeak
|
|
31
|
+
Requires-Dist: scriptconv[phonemizers]; extra == "espeak"
|
|
32
|
+
Requires-Dist: espyak; extra == "espeak"
|
|
33
|
+
Provides-Extra: gruut
|
|
34
|
+
Requires-Dist: scriptconv[phonemizers]; extra == "gruut"
|
|
35
|
+
Requires-Dist: gruut; extra == "gruut"
|
|
36
|
+
Provides-Extra: goruut
|
|
37
|
+
Requires-Dist: scriptconv[phonemizers]; extra == "goruut"
|
|
38
|
+
Requires-Dist: pygoruut; extra == "goruut"
|
|
39
|
+
Provides-Extra: epitran
|
|
40
|
+
Requires-Dist: scriptconv[phonemizers]; extra == "epitran"
|
|
41
|
+
Requires-Dist: epitran; extra == "epitran"
|
|
42
|
+
Provides-Extra: transphone
|
|
43
|
+
Requires-Dist: scriptconv[phonemizers]; extra == "transphone"
|
|
44
|
+
Requires-Dist: transphone; extra == "transphone"
|
|
45
|
+
Provides-Extra: misaki
|
|
46
|
+
Requires-Dist: scriptconv[phonemizers]; extra == "misaki"
|
|
47
|
+
Requires-Dist: misaki; extra == "misaki"
|
|
48
|
+
Provides-Extra: byt5
|
|
49
|
+
Requires-Dist: scriptconv[phonemizers]; extra == "byt5"
|
|
50
|
+
Requires-Dist: onnxruntime; extra == "byt5"
|
|
51
|
+
Requires-Dist: numpy; extra == "byt5"
|
|
52
|
+
Provides-Extra: o2i
|
|
53
|
+
Requires-Dist: scriptconv[phonemizers]; extra == "o2i"
|
|
54
|
+
Requires-Dist: orthography2ipa; extra == "o2i"
|
|
55
|
+
Provides-Extra: eu
|
|
56
|
+
Requires-Dist: scriptconv[phonemizers]; extra == "eu"
|
|
57
|
+
Requires-Dist: euskaphone; extra == "eu"
|
|
58
|
+
Requires-Dist: ahotts_g2p; extra == "eu"
|
|
59
|
+
Provides-Extra: pt-phonemizers
|
|
60
|
+
Requires-Dist: scriptconv[phonemizers]; extra == "pt-phonemizers"
|
|
61
|
+
Requires-Dist: tugaphone; extra == "pt-phonemizers"
|
|
62
|
+
Requires-Dist: g2p_barranquenho; extra == "pt-phonemizers"
|
|
63
|
+
Provides-Extra: mwl
|
|
64
|
+
Requires-Dist: scriptconv[phonemizers]; extra == "mwl"
|
|
65
|
+
Requires-Dist: mwl_phonemizer; extra == "mwl"
|
|
66
|
+
Provides-Extra: gl
|
|
67
|
+
Requires-Dist: scriptconv[phonemizers]; extra == "gl"
|
|
68
|
+
Requires-Dist: pycotovia; extra == "gl"
|
|
69
|
+
Provides-Extra: he
|
|
70
|
+
Requires-Dist: scriptconv[phonemizers]; extra == "he"
|
|
71
|
+
Requires-Dist: phonikud-onnx; extra == "he"
|
|
72
|
+
Provides-Extra: fa
|
|
73
|
+
Requires-Dist: scriptconv[phonemizers]; extra == "fa"
|
|
74
|
+
Requires-Dist: persian_phonemizer; extra == "fa"
|
|
75
|
+
Provides-Extra: vi
|
|
76
|
+
Requires-Dist: scriptconv[phonemizers]; extra == "vi"
|
|
77
|
+
Requires-Dist: viphoneme; extra == "vi"
|
|
78
|
+
Provides-Extra: tashkeel
|
|
79
|
+
Requires-Dist: scriptconv[phonemizers]; extra == "tashkeel"
|
|
80
|
+
Requires-Dist: text2tashkeel; extra == "tashkeel"
|
|
81
|
+
Provides-Extra: ja-phonemizers
|
|
82
|
+
Requires-Dist: scriptconv[phonemizers]; extra == "ja-phonemizers"
|
|
83
|
+
Requires-Dist: pyopenjtalk; extra == "ja-phonemizers"
|
|
84
|
+
Requires-Dist: cutlet; extra == "ja-phonemizers"
|
|
85
|
+
Requires-Dist: pykakasi<3,>=2.3; extra == "ja-phonemizers"
|
|
86
|
+
Provides-Extra: ko
|
|
87
|
+
Requires-Dist: scriptconv[phonemizers]; extra == "ko"
|
|
88
|
+
Requires-Dist: g2pk; extra == "ko"
|
|
89
|
+
Requires-Dist: regex; extra == "ko"
|
|
90
|
+
Provides-Extra: zh-phonemizers
|
|
91
|
+
Requires-Dist: scriptconv[phonemizers]; extra == "zh-phonemizers"
|
|
92
|
+
Requires-Dist: jieba; extra == "zh-phonemizers"
|
|
93
|
+
Requires-Dist: pypinyin<1,>=0.50; extra == "zh-phonemizers"
|
|
94
|
+
Requires-Dist: xpinyin; extra == "zh-phonemizers"
|
|
95
|
+
Requires-Dist: g2pM; extra == "zh-phonemizers"
|
|
96
|
+
Requires-Dist: pinyin_to_ipa; extra == "zh-phonemizers"
|
|
97
|
+
Provides-Extra: en-phonemizers
|
|
98
|
+
Requires-Dist: scriptconv[phonemizers]; extra == "en-phonemizers"
|
|
99
|
+
Requires-Dist: g2p_en; extra == "en-phonemizers"
|
|
100
|
+
Requires-Dist: openphonemizer; extra == "en-phonemizers"
|
|
101
|
+
Requires-Dist: deep-phonemizer; extra == "en-phonemizers"
|
|
102
|
+
Provides-Extra: ar-phonemizers
|
|
103
|
+
Requires-Dist: scriptconv[phonemizers]; extra == "ar-phonemizers"
|
|
104
|
+
Requires-Dist: arbtok; extra == "ar-phonemizers"
|
|
105
|
+
Requires-Dist: ovos-number-parser; extra == "ar-phonemizers"
|
|
106
|
+
Provides-Extra: shami
|
|
107
|
+
Requires-Dist: scriptconv[phonemizers]; extra == "shami"
|
|
108
|
+
Requires-Dist: regex; extra == "shami"
|
|
109
|
+
Provides-Extra: test
|
|
110
|
+
Requires-Dist: pytest; extra == "test"
|
|
111
|
+
Requires-Dist: pytest-timeout; extra == "test"
|
|
112
|
+
Requires-Dist: pykakasi<3,>=2.3; extra == "test"
|
|
113
|
+
Requires-Dist: pypinyin<1,>=0.50; extra == "test"
|
|
114
|
+
Requires-Dist: quebra-frases; extra == "test"
|
|
115
|
+
Requires-Dist: langcodes; extra == "test"
|
|
116
|
+
Requires-Dist: regex; extra == "test"
|
|
117
|
+
Requires-Dist: ovos-number-parser; extra == "test"
|
|
118
|
+
Dynamic: license-file
|
|
119
|
+
|
|
120
|
+
<div align="center">
|
|
121
|
+
|
|
122
|
+
# scriptconv
|
|
123
|
+
|
|
124
|
+
**Every way text is written, and every path between them.**
|
|
125
|
+
|
|
126
|
+
[](LICENSE)
|
|
127
|
+
[](https://github.com/TigreGotico/scriptconv/actions/workflows/build-tests.yml)
|
|
128
|
+
[](https://pypi.org/project/scriptconv/)
|
|
129
|
+
|
|
130
|
+
</div>
|
|
131
|
+
|
|
132
|
+
Text arrives in many representations: scripts (Cyrillic, Hangul, kana),
|
|
133
|
+
romanizations (pinyin, Buckwalter), phoneme notations (IPA, ARPABET, X-SAMPA),
|
|
134
|
+
input codes (Cangjie), and decorated or undecorated spellings (Arabic with or
|
|
135
|
+
without vowel marks, pinyin with tone marks or with digits). scriptconv
|
|
136
|
+
identifies which representation a piece of text is in, converts between them,
|
|
137
|
+
and tells you *programmatically* how faithful each conversion is.
|
|
138
|
+
|
|
139
|
+
The core is **zero-dependency** pure Python. Heavier capabilities —
|
|
140
|
+
dictionary-backed readings, phonemizer engines — live behind optional extras
|
|
141
|
+
and never load unless asked for.
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
pip install scriptconv
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Five lines to get the idea
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
from scriptconv import detect_script, convert, strip, restyle, to_pinyin
|
|
151
|
+
|
|
152
|
+
detect_script("Здравствуйте") # 'Cyrl'
|
|
153
|
+
convert("HH AH0 L OW1", "arpa", "ipa") # 'həloʊ'
|
|
154
|
+
strip("مُحَمَّد", "tashkeel") # 'محمد'
|
|
155
|
+
restyle("zhong1 guo2", "pinyin-tone", "mark") # 'zhōng guó'
|
|
156
|
+
to_pinyin("中国人") # 'zhōng guó rén' (zh extra)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Everything is also a command:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
python -m scriptconv detect "안녕하세요" # Hang
|
|
163
|
+
python -m scriptconv convert arpa ipa "K AE1 T" # kæt
|
|
164
|
+
python -m scriptconv strip tashkeel "مُحَمَّد" # محمد
|
|
165
|
+
python -m scriptconv route mantoq x-sampa # the conversion path, hop by hop
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## The mental model
|
|
169
|
+
|
|
170
|
+
scriptconv is organized around four ideas, layered from identity to sound:
|
|
171
|
+
|
|
172
|
+
1. **Scripts are identity.** A character belongs to a writing system
|
|
173
|
+
(ISO 15924: `Latn`, `Cyrl`, `Arab`, …). Identity is detectable from the
|
|
174
|
+
text itself and never changes what the text *means*.
|
|
175
|
+
2. **Representations are nodes; conversions are edges.** IPA, ARPABET,
|
|
176
|
+
hiragana, pinyin, Cangjie codes — each is a node in one conversion graph.
|
|
177
|
+
Asking for `mantoq → x-sampa` finds the cheapest path
|
|
178
|
+
(`mantoq → ipa → x-sampa`), preferring lossless edges by construction.
|
|
179
|
+
3. **Conventions are decorations, not identities.** Arabic vowel marks,
|
|
180
|
+
Hebrew points, Japanese word spacing, pinyin tone spelling — a script's
|
|
181
|
+
text can carry or omit them. They are parameters (`strip`, `restyle`,
|
|
182
|
+
`apply`), never graph nodes.
|
|
183
|
+
4. **Fidelity is data.** Whether a conversion round-trips, and what happens
|
|
184
|
+
to a symbol a table doesn't know, is queryable (`NOTATION_INFO`, the
|
|
185
|
+
`errors=` policy) — not folklore buried in docstrings.
|
|
186
|
+
|
|
187
|
+
The one thing the core never does is *invent pronunciation*:
|
|
188
|
+
grapheme-to-phoneme inference needs language knowledge beyond symbol tables.
|
|
189
|
+
When you do need it, the `phonemizers` subpackage wraps real G2P engines
|
|
190
|
+
behind extras — the same graph, one more kind of edge, explicitly opted into.
|
|
191
|
+
|
|
192
|
+
## A guided tour
|
|
193
|
+
|
|
194
|
+
### What script is this? — `scripts`
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
from scriptconv import detect_script, script_runs, lang_to_script, base_direction
|
|
198
|
+
|
|
199
|
+
detect_script("Здравствуйте") # 'Cyrl'
|
|
200
|
+
script_runs("привет hello") # [('Cyrl', 'привет '), ('Latn', 'hello')]
|
|
201
|
+
base_direction("مرحبا hello") # 'mixed'
|
|
202
|
+
lang_to_script("uzb_cyr") # 'Cyrl' — 639-1/2/3 codes, BCP-47 tags,
|
|
203
|
+
# informal _cyr/_lat variants
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
The returned ISO 15924 tags are **stable API** — downstream code compares
|
|
207
|
+
against them directly. `script_runs` follows the UAX #24 model: combining
|
|
208
|
+
marks and neutral characters attach to the run they qualify, so accented
|
|
209
|
+
Cyrillic never splits. Details: [docs/scripts.md](docs/scripts.md).
|
|
210
|
+
|
|
211
|
+
### Same sounds, different symbols — `notation`
|
|
212
|
+
|
|
213
|
+
Nine phoneme notations transcode through an IPA hub: ARPABET, X-SAMPA,
|
|
214
|
+
Kirshenbaum, Lexique, Cotovía, RFE, Buckwalter ↔ Arabic, and mantoq.
|
|
215
|
+
|
|
216
|
+
```python
|
|
217
|
+
from scriptconv import convert, arpa_to_ipa, ipa_to_arpa
|
|
218
|
+
|
|
219
|
+
convert("HH AH0 L OW1", "arpa", "ipa") # 'həloʊ'
|
|
220
|
+
convert("kˈæt", "ipa", "x-sampa") # 'k"{t'
|
|
221
|
+
arpa_to_ipa("HH AH0 L OW1", stress=True) # 'həlˈoʊ'
|
|
222
|
+
ipa_to_arpa("həlˈoʊ", stress=True) # 'HH AH0 L OW1' — exact round-trip
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Two contracts make this trustworthy:
|
|
226
|
+
|
|
227
|
+
- **`errors=`, codecs-style.** Every converter takes
|
|
228
|
+
`errors="pass" | "replace" | "strict" | "ignore"` for symbols outside its
|
|
229
|
+
table. `"strict"` raises `UnknownSymbolError(symbol, position, notation)`;
|
|
230
|
+
the defaults preserve each converter's long-standing behavior.
|
|
231
|
+
- **Stress is preserved, not discarded.** With `stress=True`, ARPABET stress
|
|
232
|
+
digits become IPA `ˈ`/`ˌ` placed before the stressed vowel — reversible by
|
|
233
|
+
construction, no syllabification involved. Round-trips are exact up to
|
|
234
|
+
IPA-equivalence; the [fidelity table](#fidelity-guarantees) states every
|
|
235
|
+
residue.
|
|
236
|
+
|
|
237
|
+
Buckwalter is an independent implementation of the published transliteration
|
|
238
|
+
scheme, including alef wasla and the dagger alef (رحمٰن ↔ ``rHm`n``). Mantoq
|
|
239
|
+
is the phonetic alphabet of the Halabi Arabic-Phonetiser — text in it
|
|
240
|
+
converts one-way to IPA (`mantoq_to_ipa("mrHbaa")` → `'mrħbaː'`) and onward
|
|
241
|
+
through the graph. Details: [docs/notation.md](docs/notation.md).
|
|
242
|
+
|
|
243
|
+
### Rewriting the writing — `translit`, `readings`, `cangjie`
|
|
244
|
+
|
|
245
|
+
Deterministic, table-driven operations on the writing system itself:
|
|
246
|
+
|
|
247
|
+
```python
|
|
248
|
+
from scriptconv import decompose_hangul, hira_to_kana
|
|
249
|
+
|
|
250
|
+
decompose_hangul("한국") # 'ㅎㅏㄴㄱㅜㄱ'
|
|
251
|
+
hira_to_kana("こんにちは") # 'コンニチハ'
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Where a respelling needs a *dictionary* — because the answer is lexical, not
|
|
255
|
+
mechanical — it lives behind an extra and raises a clear `ImportError` when
|
|
256
|
+
the dictionary isn't installed:
|
|
257
|
+
|
|
258
|
+
```python
|
|
259
|
+
from scriptconv import to_hiragana, to_katakana, to_pinyin, to_bopomofo, to_cangjie
|
|
260
|
+
|
|
261
|
+
to_hiragana("東京タワー") # 'とうきょうたわー' pip install scriptconv[ja]
|
|
262
|
+
to_katakana("日本語") # 'ニホンゴ'
|
|
263
|
+
to_pinyin("中国人") # 'zhōng guó rén' pip install scriptconv[zh]
|
|
264
|
+
to_bopomofo("中国") # 'ㄓㄨㄥ ㄍㄨㄛˊ'
|
|
265
|
+
to_cangjie("倉頡") # 'oiar grmbc' vendored table, no extra
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
`readings.tokens()` exposes the per-token stream underneath for consumers
|
|
269
|
+
that need word boundaries; the Cangjie table (103,601 glyphs) ships inside
|
|
270
|
+
the wheel, so shape-code conversion needs no download and no dependency.
|
|
271
|
+
Details: [docs/translit.md](docs/translit.md),
|
|
272
|
+
[docs/readings.md](docs/readings.md).
|
|
273
|
+
|
|
274
|
+
### Marked or unmarked — `conventions`
|
|
275
|
+
|
|
276
|
+
A convention is a decoration a script's orthography can carry or omit. Each
|
|
277
|
+
one declares its *styles* and the transitions between them; `strip`/`apply`
|
|
278
|
+
are sugar for transitions to and from `"none"`.
|
|
279
|
+
|
|
280
|
+
```python
|
|
281
|
+
from scriptconv import strip, restyle, detect_convention, conventions_for
|
|
282
|
+
|
|
283
|
+
strip("مُحَمَّد", "tashkeel") # 'محمد'
|
|
284
|
+
strip("שָׁלוֹם", "niqqud") # 'שלום'
|
|
285
|
+
strip("わたし は がくせい です", "wakachigaki") # 'わたしはがくせいです'
|
|
286
|
+
restyle("zhōng guó", "pinyin-tone", "number", frm="mark") # 'zhong1 guo2'
|
|
287
|
+
detect_convention("مُحَمَّد", "tashkeel") # 'marked'
|
|
288
|
+
[c.id for c in conventions_for("Arab")] # ['tashkeel', 'kashida', 'quranic-marks']
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
The registered set: Arabic `tashkeel`, `kashida`, `quranic-marks`; Hebrew
|
|
292
|
+
`niqqud` and `teamim` (vocalization and cantillation are separate layers);
|
|
293
|
+
Japanese `wakachigaki` (spacing is stripped only between Japanese characters —
|
|
294
|
+
"きょうは good day" keeps its space); `pinyin-tone` (mark ↔ number ↔ none,
|
|
295
|
+
deterministic both ways for standard apostrophized pinyin); and `jamo-form`
|
|
296
|
+
(compatibility ↔ conjoining repertoires).
|
|
297
|
+
|
|
298
|
+
Which transitions exist follows one criterion: stripping and deterministic
|
|
299
|
+
re-spelling are always available; transitions needing a dictionary lookup
|
|
300
|
+
(applying wakachigaki = word segmentation) sit behind an extra; transitions
|
|
301
|
+
needing contextual *prediction* (restoring tashkeel) are out of scope
|
|
302
|
+
entirely — that is diacritization, a modelling problem — and their absence is
|
|
303
|
+
queryable data rather than a runtime surprise.
|
|
304
|
+
|
|
305
|
+
The codepoint sets are curated, not naive: stripping tashkeel **excludes**
|
|
306
|
+
U+0653–0655 because in decomposed text those combining marks *are* the
|
|
307
|
+
letters آ/أ/إ — a blanket strip corrupts the consonantal skeleton.
|
|
308
|
+
Details: [docs/conventions.md](docs/conventions.md).
|
|
309
|
+
|
|
310
|
+
### One graph over everything — `graph`
|
|
311
|
+
|
|
312
|
+
Every notation and orthography is a node; every converter an edge; routing
|
|
313
|
+
finds the cheapest path and prefers lossless edges, so a lossless two-hop
|
|
314
|
+
beats a lossy shortcut:
|
|
315
|
+
|
|
316
|
+
```python
|
|
317
|
+
from scriptconv import DEFAULT_GRAPH
|
|
318
|
+
|
|
319
|
+
DEFAULT_GRAPH.convert("こんにちは", "hira", "kana") # 'コンニチハ'
|
|
320
|
+
[f"{e.src}->{e.dst}" for e in DEFAULT_GRAPH.route("arpa", "x-sampa")]
|
|
321
|
+
# ['arpa->ipa', 'ipa->x-sampa']
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Edges are `fn(text, **context)` — routing context like `lang=` passes through
|
|
325
|
+
opaquely. Extension is explicit: `graph.extend(register_fn)` returns an
|
|
326
|
+
extended copy, and a graph's contents never depend on what happens to be
|
|
327
|
+
installed. `DEFAULT_GRAPH` itself contains orthographic and notation edges
|
|
328
|
+
only. Details: [docs/graph.md](docs/graph.md).
|
|
329
|
+
|
|
330
|
+
### From spelling to sound — `phonemizers`
|
|
331
|
+
|
|
332
|
+
Wrappers over real G2P engines — espeak, gruut, epitran, ByT5, and
|
|
333
|
+
specialized per-language engines — behind per-capability extras, with a
|
|
334
|
+
default per language and full override:
|
|
335
|
+
|
|
336
|
+
```python
|
|
337
|
+
from scriptconv.phonemizers import phonemize, Phonemizer
|
|
338
|
+
|
|
339
|
+
phonemize("kaixo mundua", "eu") # 'kai̯ʃo mundua' (euskaphone)
|
|
340
|
+
phonemize("hello", "en", override=Phonemizer.GRUUT)
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
Defaults resolve in-house engines first: an explicit per-language chain
|
|
344
|
+
(Arabic → arbtok, Basque → euskaphone, Mirandese, Portuguese → tugaphone,
|
|
345
|
+
Hebrew → phonikud, Galician → Cotovía for its own notation), then
|
|
346
|
+
orthography2ipa wherever it has a language spec, then espeak as the last
|
|
347
|
+
resort. Arabic never falls back past arbtok — a missing engine raises rather
|
|
348
|
+
than silently degrading. Every backend resolves lazily; a missing package
|
|
349
|
+
raises an `ImportError` naming the extra to install.
|
|
350
|
+
|
|
351
|
+
Phonemization joins the graph only on request:
|
|
352
|
+
|
|
353
|
+
```python
|
|
354
|
+
from scriptconv import DEFAULT_GRAPH
|
|
355
|
+
from scriptconv import phonemizers
|
|
356
|
+
|
|
357
|
+
g = DEFAULT_GRAPH.extend(phonemizers.register)
|
|
358
|
+
g.convert("bom dia", "text", "ipa", lang="pt") # 'ˈbõ ˈdʒiɐ'
|
|
359
|
+
g.can_convert("text", "arpa") # True — chains through IPA
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
Two design points worth knowing:
|
|
363
|
+
|
|
364
|
+
- **Normalization is injectable.** TTS stacks expand numbers and dates before
|
|
365
|
+
phonemizing; that needs language resources scriptconv doesn't ship. Pass
|
|
366
|
+
`normalizer=` (a `(text, lang) -> str` callable) to run yours inside the
|
|
367
|
+
pipeline; without it, text is phonemized as-is.
|
|
368
|
+
- **Model-backed engines never download.** ByT5/Charsiu require an explicit
|
|
369
|
+
local `model=` path; resolving and caching model files is the caller's
|
|
370
|
+
concern.
|
|
371
|
+
|
|
372
|
+
Details: [docs/phonemizers.md](docs/phonemizers.md).
|
|
373
|
+
|
|
374
|
+
## Fidelity guarantees
|
|
375
|
+
|
|
376
|
+
Transcoding faithfulness depends on the target notation's inventory. IPA is
|
|
377
|
+
the hub; notation↔notation goes through IPA. The table below states, for each
|
|
378
|
+
notation, whether a round-trip is exact and what happens to a symbol the
|
|
379
|
+
table does not know.
|
|
380
|
+
|
|
381
|
+
Every converter (and `convert()`) accepts a codecs-style `errors=` policy for
|
|
382
|
+
symbols outside its table: `"pass"` keeps the symbol (the default everywhere
|
|
383
|
+
except `ipa_to_arpa`), `"replace"` substitutes the notation's placeholder
|
|
384
|
+
(`?`; the historical `ipa_to_arpa` default, tunable via `unknown=`),
|
|
385
|
+
`"ignore"` drops it, and `"strict"` raises `UnknownSymbolError` naming the
|
|
386
|
+
symbol, its position, and the notation. The "Unknown-token behaviour" column
|
|
387
|
+
below describes the per-converter default.
|
|
388
|
+
|
|
389
|
+
| Notation | `to_ipa` → `from_ipa` round-trip | `from_ipa` → `to_ipa` round-trip | Unknown-token behaviour |
|
|
390
|
+
|----------|----------------------------------|----------------------------------|-------------------------|
|
|
391
|
+
| **ARPABET** | **Lossless with `stress=True`** (digits ↔ IPA `ˈ`/`ˌ` before the stressed vowel; residues: extended-ARPABET `AX` normalises to CMUdict's `AH0` spelling, and `AH0 R` fuses to the r-colored `AXR0` — stable from the IPA side). Default `stress=False` drops digits and merges `AH0`↔`AX` | **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 are dropped; other out-of-inventory symbols follow `errors=` (default `"replace"` → `?`) |
|
|
392
|
+
| **X-SAMPA** | Exact for all canonical symbols | Exact except aliases (`f\`→ɸ, `&`→æ) normalise to their canonical spelling | Passed through unchanged |
|
|
393
|
+
| **Buckwalter ↔ Arabic** | Exact (precomposed lam-alef ligatures decompose to two chars, visually identical) | Exact | Follows `errors=` (default: passed through) |
|
|
394
|
+
| **Mantoq → IPA** | One-directional (gemination/word markers consumed; no IPA→Mantoq) | — | Follows `errors=` (default: passed through) |
|
|
395
|
+
| **Lexique ↔ IPA** | Exact except the `°`/`3` schwa pair (both → `ə`; reverse always → `°`) | Exact | Passed through unchanged |
|
|
396
|
+
| **Kirshenbaum ↔ IPA** | Exact | **Lossy** — restricted ASCII inventory; IPA outside it passes through | Passed through unchanged |
|
|
397
|
+
| **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 |
|
|
398
|
+
| **RFE ↔ IPA** | Exact except `ñ`/`n̮` for `ɲ` normalise to `ñ` | **Lossy** — core Spanish/Romance inventory; IPA outside it passes through | Passed through unchanged |
|
|
399
|
+
|
|
400
|
+
Every row is backed by a test; `NOTATION_INFO` exposes the same facts to
|
|
401
|
+
code, so a program can branch on whether a conversion is safe before making
|
|
402
|
+
it.
|
|
403
|
+
|
|
404
|
+
## Extras
|
|
405
|
+
|
|
406
|
+
The core installs with zero dependencies. Capabilities opt in:
|
|
407
|
+
|
|
408
|
+
| Extra | Enables |
|
|
409
|
+
|---|---|
|
|
410
|
+
| `ja` / `zh` | Dictionary readings: kanji→kana (pykakasi), hanzi→pinyin/bopomofo (pypinyin) |
|
|
411
|
+
| `phonemizers` | The phonemizer base layer (sentence chunking, language matching) |
|
|
412
|
+
| `espeak`, `gruut`, `goruut`, `epitran`, `transphone`, `misaki`, `byt5` | Multilingual phonemizer backends |
|
|
413
|
+
| `en-phonemizers`, `ja-phonemizers`, `zh-phonemizers`, `ko`, `ar-phonemizers`, `eu`, `pt-phonemizers`, `gl`, `he`, `fa`, `vi`, `mwl`, `shami`, `o2i` | Per-language phonemizer backends |
|
|
414
|
+
| `tashkeel` | Arabic diacritization for the phonemizer pipeline (text2tashkeel) |
|
|
415
|
+
|
|
416
|
+
## Licensing
|
|
417
|
+
|
|
418
|
+
scriptconv is Apache-2.0, with one deliberate, clearly-bounded exception:
|
|
419
|
+
`scriptconv/phonemizers/_vendored/` quarantines two unpublished third-party
|
|
420
|
+
G2P implementations under **their own licenses** — mantoq's phonetisation
|
|
421
|
+
core (CC BY-NC 4.0, non-commercial) and KoG2P (GPL-3.0) — each with its
|
|
422
|
+
LICENSE.md in the directory and in the wheel. Nothing imports them at package
|
|
423
|
+
import time; they load only when a caller explicitly requests those
|
|
424
|
+
phonemizers, and unencumbered defaults (arbtok for Arabic, g2pk for Korean)
|
|
425
|
+
exist for both.
|
|
426
|
+
|
|
427
|
+
## Development
|
|
428
|
+
|
|
429
|
+
```bash
|
|
430
|
+
uv venv && uv pip install -e '.[test]'
|
|
431
|
+
pytest tests/
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
The documentation lives in [`docs/`](docs/index.md), one page per module.
|