lipimala 1.0.0__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.
Files changed (32) hide show
  1. lipimala-1.0.0/.gitignore +62 -0
  2. lipimala-1.0.0/LICENSE +21 -0
  3. lipimala-1.0.0/PKG-INFO +207 -0
  4. lipimala-1.0.0/README.md +182 -0
  5. lipimala-1.0.0/lipimala/__init__.py +1 -0
  6. lipimala-1.0.0/lipimala/_forward.py +756 -0
  7. lipimala-1.0.0/lipimala/brahmic_to_latn_iast.py +595 -0
  8. lipimala-1.0.0/lipimala/deva_gujr_converter.py +431 -0
  9. lipimala-1.0.0/lipimala/latn_iast_to_deva.py +381 -0
  10. lipimala-1.0.0/lipimala/latn_iast_to_gujr.py +379 -0
  11. lipimala-1.0.0/lipimala/latn_iast_transcription.py +782 -0
  12. lipimala-1.0.0/lipimala/transliteration_core.py +390 -0
  13. lipimala-1.0.0/lipimala/transliteration_result.py +136 -0
  14. lipimala-1.0.0/pyproject.toml +120 -0
  15. lipimala-1.0.0/tests/__init__.py +0 -0
  16. lipimala-1.0.0/tests/oracle_data.py +4036 -0
  17. lipimala-1.0.0/tests/test_dart_parity.py +63 -0
  18. lipimala-1.0.0/tests/test_deva_gujr_converter.py +69 -0
  19. lipimala-1.0.0/tests/test_profiles_and_options.py +158 -0
  20. lipimala-1.0.0/tests/test_transliteration.py +80 -0
  21. lipimala-1.0.0/tools/fixtures/__init__.py +0 -0
  22. lipimala-1.0.0/tools/fixtures/example_deva.py +506 -0
  23. lipimala-1.0.0/tools/fixtures/example_gujr.py +506 -0
  24. lipimala-1.0.0/tools/fixtures/example_latn_iast.py +634 -0
  25. lipimala-1.0.0/tools/latn_iast_transliteration_verification/deva_to_gujr_test.py +20 -0
  26. lipimala-1.0.0/tools/latn_iast_transliteration_verification/deva_to_latn_iast_test.py +17 -0
  27. lipimala-1.0.0/tools/latn_iast_transliteration_verification/gujr_to_deva_test.py +20 -0
  28. lipimala-1.0.0/tools/latn_iast_transliteration_verification/gujr_to_latn_iast_test.py +17 -0
  29. lipimala-1.0.0/tools/latn_iast_transliteration_verification/latn_iast_to_deva_test.py +143 -0
  30. lipimala-1.0.0/tools/latn_iast_transliteration_verification/latn_iast_to_gujr_test.py +77 -0
  31. lipimala-1.0.0/tools/latn_iast_transliteration_verification/latn_iast_transcription_test.py +83 -0
  32. lipimala-1.0.0/tools/latn_iast_transliteration_verification/run_all.py +23 -0
@@ -0,0 +1,62 @@
1
+ # Python bytecode
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # Virtual environments
7
+ .venv/
8
+ venv/
9
+ env/
10
+ ENV/
11
+
12
+ # Packaging / build
13
+ build/
14
+ dist/
15
+ *.egg-info/
16
+ .eggs/
17
+ wheels/
18
+ pip-wheel-metadata/
19
+
20
+ # Test / coverage
21
+ .pytest_cache/
22
+ .coverage
23
+ .coverage.*
24
+ htmlcov/
25
+ coverage.xml
26
+ *.cover
27
+ .hypothesis/
28
+
29
+ # Ruff
30
+ .ruff_cache/
31
+
32
+ # Mypy / type checker caches
33
+ .mypy_cache/
34
+ .pyright/
35
+ .pytype/
36
+
37
+ # IDEs / Editors
38
+ .idea/
39
+ .vscode/
40
+
41
+ # OS files
42
+ .DS_Store
43
+ Thumbs.db
44
+
45
+ # Logs / temporary files
46
+ *.log
47
+ *.tmp
48
+ *.temp
49
+ *.bak
50
+ *.swp
51
+ *.swo
52
+
53
+ # Local environment / secrets
54
+ .env
55
+ .env.*
56
+ !.env.example
57
+
58
+ # Generated verification outputs
59
+ *_output.txt
60
+
61
+ # Local scratch / grabbed content
62
+ grabbed_stuffs/
lipimala-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jayesh Mepani
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,207 @@
1
+ Metadata-Version: 2.4
2
+ Name: lipimala
3
+ Version: 1.0.0
4
+ Summary: Exact Round-Trip IAST/extended Indic transliteration for Devanagari, Gujarati, plain English and canonical reverse conversion.
5
+ Project-URL: Homepage, https://github.com/jayeshmepani/indic-script-converter
6
+ Project-URL: Source, https://github.com/jayeshmepani/indic-script-converter
7
+ Project-URL: Issues, https://github.com/jayeshmepani/indic-script-converter/issues
8
+ Author-email: Jayesh Mepani <jayeshmepani777@gmail.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: devanagari,exact round-trip,gujarati,iast,indic,sanskrit,transliteration,vedic
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Requires-Python: >=3.12
19
+ Provides-Extra: dev
20
+ Requires-Dist: build>=1.0.0; extra == 'dev'
21
+ Requires-Dist: pytest>=8.3.0; extra == 'dev'
22
+ Requires-Dist: ruff>=0.9.0; extra == 'dev'
23
+ Requires-Dist: twine>=4.0.0; extra == 'dev'
24
+ Description-Content-Type: text/markdown
25
+
26
+ # Exact Round-Trip Indic Transliteration — Python 3.12+ port
27
+
28
+ This directory is a Python port of the supplied Dart implementation. It keeps the Dart package's default **`extendedIndic`** behavior and ports all public conversion directions:
29
+
30
+ - Latin/IAST → Devanagari
31
+ - Latin/IAST → Gujarati
32
+ - Latin/IAST → plain English/Hunterian
33
+ - Devanagari → canonical Latin/IAST
34
+ - Gujarati → canonical Latin/IAST
35
+ - metadata-backed exact source recovery
36
+ - exact round-trip result envelopes and JSON serialization
37
+
38
+ The runtime has no third-party dependency. Python's standard `unicodedata` module supplies NFC/NFD normalization and Unicode mark categories.
39
+
40
+ ## Install
41
+
42
+ ```bash
43
+ cd python
44
+ python3.12 -m venv .venv
45
+ source .venv/bin/activate
46
+ python -m pip install -e .
47
+ ```
48
+
49
+ For tests:
50
+
51
+ ```bash
52
+ python -m pip install -e '.[dev]'
53
+ python -m pytest
54
+ ```
55
+
56
+ ## Basic conversions
57
+
58
+ ```python
59
+ from lipimala import (
60
+ to_devanagari_from_iast,
61
+ to_gujarati_from_iast,
62
+ to_plain_english_from_iast,
63
+ to_canonical_iast_from_devanagari,
64
+ to_canonical_iast_from_gujarati,
65
+ )
66
+
67
+ assert to_devanagari_from_iast('Kṛṣṇa') == 'कृष्ण'
68
+ assert to_gujarati_from_iast('Kṛṣṇa') == 'કૃષ્ણ'
69
+ assert to_plain_english_from_iast('Kṛṣṇa') == 'Krishna'
70
+ assert to_canonical_iast_from_devanagari('कृष्ण') == 'kṛṣṇa'
71
+ assert to_canonical_iast_from_gujarati('કૃષ્ણ') == 'kṛṣṇa'
72
+ ```
73
+
74
+ ## Exact original-key recovery
75
+
76
+ Visible Brahmic output is many-to-one. For example, aliases, case, and NFC/NFD forms can render identically. Exact recovery therefore uses the same checksummed invisible Unicode-tag trailer as the Dart implementation.
77
+
78
+ ```python
79
+ from lipimala import (
80
+ IastToDevanagariOptions,
81
+ IastToGujaratiOptions,
82
+ to_devanagari_from_iast,
83
+ to_gujarati_from_iast,
84
+ to_exact_iast_from_devanagari,
85
+ to_exact_iast_from_gujarati,
86
+ )
87
+
88
+ source = 'Kṛṣṇa / Kr̥ṣṇa / ḫāna / ṣ́akti'
89
+
90
+ devanagari = to_devanagari_from_iast(
91
+ source,
92
+ IastToDevanagariOptions(embed_exact_source_metadata=True),
93
+ )
94
+ gujarati = to_gujarati_from_iast(
95
+ source,
96
+ IastToGujaratiOptions(embed_exact_source_metadata=True),
97
+ )
98
+
99
+ assert to_exact_iast_from_devanagari(devanagari) == source
100
+ assert to_exact_iast_from_gujarati(gujarati) == source
101
+ ```
102
+
103
+ The metadata stores the exact UTF-16LE code-unit sequence and preserves:
104
+
105
+ - case
106
+ - precomposed versus decomposed spelling
107
+ - combining-mark order
108
+ - aliases
109
+ - punctuation and whitespace
110
+ - supplementary Unicode characters
111
+ - unpaired UTF-16 surrogates through Python's `surrogatepass` handling
112
+
113
+ The trailer is rejected if either the visible rendering or encoded source payload is modified.
114
+
115
+ ## Exact Round-Trip envelope
116
+
117
+ ```python
118
+ import json
119
+
120
+ from lipimala import (
121
+ TransliterationResult,
122
+ to_plain_english,
123
+ )
124
+
125
+ result = to_plain_english('Kṛṣṇa ā́tman ḷa')
126
+ assert result.restore_original() == 'Kṛṣṇa ā́tman ḷa'
127
+
128
+ encoded = json.dumps(result.to_json(), ensure_ascii=False)
129
+ restored = TransliterationResult.from_json(json.loads(encoded))
130
+ assert restored.restore_original() == result.original
131
+ ```
132
+
133
+ ## Devanagari ↔ Gujarati Direct Converter
134
+
135
+ This package includes a direct converter between Devanagari and Gujarati.
136
+
137
+ ### Canonical visible conversion
138
+ ```python
139
+ from lipimala.deva_gujr_converter import (
140
+ to_canonical_gujarati_from_devanagari,
141
+ to_canonical_devanagari_from_gujarati,
142
+ )
143
+
144
+ print(to_canonical_gujarati_from_devanagari('कृष्ण')) # કૃષ્ણ
145
+ print(to_canonical_devanagari_from_gujarati('કૃષ્ણ')) # कृष्ण
146
+ ```
147
+
148
+ ### Exact exact round-trip round trip
149
+ The visible Gujarati and Devanagari repertoires are not one-to-one. Therefore, exact round-trip recovery uses a checksummed Unicode-tag trailer.
150
+
151
+ ```python
152
+ from lipimala.deva_gujr_converter import (
153
+ IndicScriptConversionOptions,
154
+ to_canonical_gujarati_from_devanagari,
155
+ to_exact_devanagari_from_gujarati,
156
+ )
157
+
158
+ source = 'ऄ ऎ ऍ ॲ ऒ ऑ ॵ ळ ऴ ग़ ॻ ड़ ॸ ॾ'
159
+
160
+ tagged_gujarati = to_canonical_gujarati_from_devanagari(
161
+ source,
162
+ IndicScriptConversionOptions(embed_exact_source_metadata=True),
163
+ )
164
+
165
+ assert to_exact_devanagari_from_gujarati(tagged_gujarati) == source
166
+ ```
167
+
168
+ The opposite Gujarati → Devanagari → exact Gujarati direction uses `to_exact_gujarati_from_devanagari`.
169
+
170
+ ### Smart exact-or-canonical APIs
171
+ These recover a correctly typed exact source trailer if present, and otherwise fall back to canonical visible conversion:
172
+ - `to_devanagari_from_gujarati(text, options)`
173
+ - `to_gujarati_from_devanagari(text, options)`
174
+
175
+ Strict exact APIs throw when typed metadata is absent or damaged:
176
+ - `to_exact_devanagari_from_gujarati(text)`
177
+ - `to_exact_gujarati_from_devanagari(text)`
178
+
179
+ ## Generate the verification outputs
180
+
181
+ Run from this directory after installation:
182
+
183
+ ```bash
184
+ python3 -m tools.latn_iast_transliteration_verification.latn_iast_to_deva_test > latn_iast_to_deva_output.txt
185
+ python3 -m tools.latn_iast_transliteration_verification.latn_iast_to_gujr_test > latn_iast_to_gujr_output.txt
186
+ python3 -m tools.latn_iast_transliteration_verification.latn_iast_transcription_test > latn_iast_transcription_output.txt
187
+ python3 -m tools.latn_iast_transliteration_verification.deva_to_latn_iast_test > deva_to_latn_iast_output.txt
188
+ python3 -m tools.latn_iast_transliteration_verification.gujr_to_latn_iast_test > gujr_to_latn_iast_output.txt
189
+ python3 -m tools.latn_iast_transliteration_verification.deva_to_gujr_test > deva_to_gujr_output.txt
190
+ python3 -m tools.latn_iast_transliteration_verification.gujr_to_deva_test > gujr_to_deva_output.txt
191
+ ```
192
+
193
+ ## Verification performed
194
+
195
+ The automated parity suite compares the Python implementation against the five supplied Dart-generated output files:
196
+
197
+ - 497 Latin → Devanagari cases
198
+ - 497 Latin → Gujarati cases
199
+ - 497 Latin → plain-English cases
200
+ - 497 Devanagari → canonical IAST cases
201
+ - 497 Gujarati → canonical IAST cases
202
+
203
+ That is **2,485 exact result comparisons**, including the complete supplied Vedic corpus. Additional tests cover exact metadata recovery, normalization distinctions, combining-mark order, supplementary characters, JSON envelopes, and tamper rejection.
204
+
205
+ ## Important distinction
206
+
207
+ `to_canonical_iast_from_devanagari()` and `to_canonical_iast_from_gujarati()` generate canonical reverse transliteration from visible text. They cannot infer the exact original alias or case. Use `embed_exact_source_metadata=True` plus `to_exact_iast_from_*()` when the exact original key must be recovered.
@@ -0,0 +1,182 @@
1
+ # Exact Round-Trip Indic Transliteration — Python 3.12+ port
2
+
3
+ This directory is a Python port of the supplied Dart implementation. It keeps the Dart package's default **`extendedIndic`** behavior and ports all public conversion directions:
4
+
5
+ - Latin/IAST → Devanagari
6
+ - Latin/IAST → Gujarati
7
+ - Latin/IAST → plain English/Hunterian
8
+ - Devanagari → canonical Latin/IAST
9
+ - Gujarati → canonical Latin/IAST
10
+ - metadata-backed exact source recovery
11
+ - exact round-trip result envelopes and JSON serialization
12
+
13
+ The runtime has no third-party dependency. Python's standard `unicodedata` module supplies NFC/NFD normalization and Unicode mark categories.
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ cd python
19
+ python3.12 -m venv .venv
20
+ source .venv/bin/activate
21
+ python -m pip install -e .
22
+ ```
23
+
24
+ For tests:
25
+
26
+ ```bash
27
+ python -m pip install -e '.[dev]'
28
+ python -m pytest
29
+ ```
30
+
31
+ ## Basic conversions
32
+
33
+ ```python
34
+ from lipimala import (
35
+ to_devanagari_from_iast,
36
+ to_gujarati_from_iast,
37
+ to_plain_english_from_iast,
38
+ to_canonical_iast_from_devanagari,
39
+ to_canonical_iast_from_gujarati,
40
+ )
41
+
42
+ assert to_devanagari_from_iast('Kṛṣṇa') == 'कृष्ण'
43
+ assert to_gujarati_from_iast('Kṛṣṇa') == 'કૃષ્ણ'
44
+ assert to_plain_english_from_iast('Kṛṣṇa') == 'Krishna'
45
+ assert to_canonical_iast_from_devanagari('कृष्ण') == 'kṛṣṇa'
46
+ assert to_canonical_iast_from_gujarati('કૃષ્ણ') == 'kṛṣṇa'
47
+ ```
48
+
49
+ ## Exact original-key recovery
50
+
51
+ Visible Brahmic output is many-to-one. For example, aliases, case, and NFC/NFD forms can render identically. Exact recovery therefore uses the same checksummed invisible Unicode-tag trailer as the Dart implementation.
52
+
53
+ ```python
54
+ from lipimala import (
55
+ IastToDevanagariOptions,
56
+ IastToGujaratiOptions,
57
+ to_devanagari_from_iast,
58
+ to_gujarati_from_iast,
59
+ to_exact_iast_from_devanagari,
60
+ to_exact_iast_from_gujarati,
61
+ )
62
+
63
+ source = 'Kṛṣṇa / Kr̥ṣṇa / ḫāna / ṣ́akti'
64
+
65
+ devanagari = to_devanagari_from_iast(
66
+ source,
67
+ IastToDevanagariOptions(embed_exact_source_metadata=True),
68
+ )
69
+ gujarati = to_gujarati_from_iast(
70
+ source,
71
+ IastToGujaratiOptions(embed_exact_source_metadata=True),
72
+ )
73
+
74
+ assert to_exact_iast_from_devanagari(devanagari) == source
75
+ assert to_exact_iast_from_gujarati(gujarati) == source
76
+ ```
77
+
78
+ The metadata stores the exact UTF-16LE code-unit sequence and preserves:
79
+
80
+ - case
81
+ - precomposed versus decomposed spelling
82
+ - combining-mark order
83
+ - aliases
84
+ - punctuation and whitespace
85
+ - supplementary Unicode characters
86
+ - unpaired UTF-16 surrogates through Python's `surrogatepass` handling
87
+
88
+ The trailer is rejected if either the visible rendering or encoded source payload is modified.
89
+
90
+ ## Exact Round-Trip envelope
91
+
92
+ ```python
93
+ import json
94
+
95
+ from lipimala import (
96
+ TransliterationResult,
97
+ to_plain_english,
98
+ )
99
+
100
+ result = to_plain_english('Kṛṣṇa ā́tman ḷa')
101
+ assert result.restore_original() == 'Kṛṣṇa ā́tman ḷa'
102
+
103
+ encoded = json.dumps(result.to_json(), ensure_ascii=False)
104
+ restored = TransliterationResult.from_json(json.loads(encoded))
105
+ assert restored.restore_original() == result.original
106
+ ```
107
+
108
+ ## Devanagari ↔ Gujarati Direct Converter
109
+
110
+ This package includes a direct converter between Devanagari and Gujarati.
111
+
112
+ ### Canonical visible conversion
113
+ ```python
114
+ from lipimala.deva_gujr_converter import (
115
+ to_canonical_gujarati_from_devanagari,
116
+ to_canonical_devanagari_from_gujarati,
117
+ )
118
+
119
+ print(to_canonical_gujarati_from_devanagari('कृष्ण')) # કૃષ્ણ
120
+ print(to_canonical_devanagari_from_gujarati('કૃષ્ણ')) # कृष्ण
121
+ ```
122
+
123
+ ### Exact exact round-trip round trip
124
+ The visible Gujarati and Devanagari repertoires are not one-to-one. Therefore, exact round-trip recovery uses a checksummed Unicode-tag trailer.
125
+
126
+ ```python
127
+ from lipimala.deva_gujr_converter import (
128
+ IndicScriptConversionOptions,
129
+ to_canonical_gujarati_from_devanagari,
130
+ to_exact_devanagari_from_gujarati,
131
+ )
132
+
133
+ source = 'ऄ ऎ ऍ ॲ ऒ ऑ ॵ ळ ऴ ग़ ॻ ड़ ॸ ॾ'
134
+
135
+ tagged_gujarati = to_canonical_gujarati_from_devanagari(
136
+ source,
137
+ IndicScriptConversionOptions(embed_exact_source_metadata=True),
138
+ )
139
+
140
+ assert to_exact_devanagari_from_gujarati(tagged_gujarati) == source
141
+ ```
142
+
143
+ The opposite Gujarati → Devanagari → exact Gujarati direction uses `to_exact_gujarati_from_devanagari`.
144
+
145
+ ### Smart exact-or-canonical APIs
146
+ These recover a correctly typed exact source trailer if present, and otherwise fall back to canonical visible conversion:
147
+ - `to_devanagari_from_gujarati(text, options)`
148
+ - `to_gujarati_from_devanagari(text, options)`
149
+
150
+ Strict exact APIs throw when typed metadata is absent or damaged:
151
+ - `to_exact_devanagari_from_gujarati(text)`
152
+ - `to_exact_gujarati_from_devanagari(text)`
153
+
154
+ ## Generate the verification outputs
155
+
156
+ Run from this directory after installation:
157
+
158
+ ```bash
159
+ python3 -m tools.latn_iast_transliteration_verification.latn_iast_to_deva_test > latn_iast_to_deva_output.txt
160
+ python3 -m tools.latn_iast_transliteration_verification.latn_iast_to_gujr_test > latn_iast_to_gujr_output.txt
161
+ python3 -m tools.latn_iast_transliteration_verification.latn_iast_transcription_test > latn_iast_transcription_output.txt
162
+ python3 -m tools.latn_iast_transliteration_verification.deva_to_latn_iast_test > deva_to_latn_iast_output.txt
163
+ python3 -m tools.latn_iast_transliteration_verification.gujr_to_latn_iast_test > gujr_to_latn_iast_output.txt
164
+ python3 -m tools.latn_iast_transliteration_verification.deva_to_gujr_test > deva_to_gujr_output.txt
165
+ python3 -m tools.latn_iast_transliteration_verification.gujr_to_deva_test > gujr_to_deva_output.txt
166
+ ```
167
+
168
+ ## Verification performed
169
+
170
+ The automated parity suite compares the Python implementation against the five supplied Dart-generated output files:
171
+
172
+ - 497 Latin → Devanagari cases
173
+ - 497 Latin → Gujarati cases
174
+ - 497 Latin → plain-English cases
175
+ - 497 Devanagari → canonical IAST cases
176
+ - 497 Gujarati → canonical IAST cases
177
+
178
+ That is **2,485 exact result comparisons**, including the complete supplied Vedic corpus. Additional tests cover exact metadata recovery, normalization distinctions, combining-mark order, supplementary characters, JSON envelopes, and tamper rejection.
179
+
180
+ ## Important distinction
181
+
182
+ `to_canonical_iast_from_devanagari()` and `to_canonical_iast_from_gujarati()` generate canonical reverse transliteration from visible text. They cannot infer the exact original alias or case. Use `embed_exact_source_metadata=True` plus `to_exact_iast_from_*()` when the exact original key must be recovered.
@@ -0,0 +1 @@
1
+ from .transliteration_result import *