scriptconv 0.0.3a18__tar.gz → 0.0.3a20__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 (80) hide show
  1. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/PKG-INFO +1 -1
  2. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/notation.py +26 -8
  3. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/ar.py +35 -10
  4. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/ko.py +22 -11
  5. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/version.py +1 -1
  6. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv.egg-info/PKG-INFO +1 -1
  7. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/tests/test_notation.py +14 -1
  8. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/tests/test_phonemizers_cjk_ar.py +19 -2
  9. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/LICENSE +0 -0
  10. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/README.md +0 -0
  11. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/pyproject.toml +0 -0
  12. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/requirements.txt +0 -0
  13. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/__init__.py +0 -0
  14. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/__main__.py +0 -0
  15. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/cangjie.py +0 -0
  16. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/conventions.py +0 -0
  17. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/data/__init__.py +0 -0
  18. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/data/cangjie5_tc.tsv.gz +0 -0
  19. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/graph.py +0 -0
  20. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/__init__.py +0 -0
  21. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/_thirdparty/__init__.py +0 -0
  22. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/_thirdparty/bw2ipa.py +0 -0
  23. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/_thirdparty/hangul2ipa.py +0 -0
  24. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/_thirdparty/ko_tables/aspiration.csv +0 -0
  25. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/_thirdparty/ko_tables/assimilation.csv +0 -0
  26. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/_thirdparty/ko_tables/double_coda.csv +0 -0
  27. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/_thirdparty/ko_tables/hanja.tsv +0 -0
  28. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/_thirdparty/ko_tables/ipa.csv +0 -0
  29. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/_thirdparty/ko_tables/neutralization.csv +0 -0
  30. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/_thirdparty/ko_tables/tensification.csv +0 -0
  31. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/_thirdparty/ko_tables/yale.csv +0 -0
  32. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/_thirdparty/shami/__init__.py +0 -0
  33. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/_thirdparty/shami/codeswitch.py +0 -0
  34. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/_thirdparty/shami/diacritize.py +0 -0
  35. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/_thirdparty/shami/dialectal.py +0 -0
  36. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/_thirdparty/shami/english_g2p.py +0 -0
  37. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/_thirdparty/shami/espeak.py +0 -0
  38. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/_thirdparty/shami/frontend.py +0 -0
  39. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/_thirdparty/shami/levantine_g2p.py +0 -0
  40. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/_thirdparty/shami/normalize.py +0 -0
  41. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/_thirdparty/shami/phoneme_inventory.py +0 -0
  42. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/_thirdparty/zh_num.py +0 -0
  43. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/base.py +0 -0
  44. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/en.py +0 -0
  45. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/enums.py +0 -0
  46. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/eu.py +0 -0
  47. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/fa.py +0 -0
  48. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/gl.py +0 -0
  49. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/he.py +0 -0
  50. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/ja.py +0 -0
  51. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/mul.py +0 -0
  52. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/mwl.py +0 -0
  53. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/o2ipa.py +0 -0
  54. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/pt.py +0 -0
  55. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/registry.py +0 -0
  56. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/shami.py +0 -0
  57. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/vi.py +0 -0
  58. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/phonemizers/zh.py +0 -0
  59. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/py.typed +0 -0
  60. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/readings.py +0 -0
  61. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/scripts.py +0 -0
  62. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv/translit.py +0 -0
  63. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv.egg-info/SOURCES.txt +0 -0
  64. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv.egg-info/dependency_links.txt +0 -0
  65. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv.egg-info/requires.txt +0 -0
  66. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/scriptconv.egg-info/top_level.txt +0 -0
  67. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/setup.cfg +0 -0
  68. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/tests/test_arpa_stress.py +0 -0
  69. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/tests/test_cangjie.py +0 -0
  70. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/tests/test_cli.py +0 -0
  71. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/tests/test_conventions.py +0 -0
  72. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/tests/test_errors_policy.py +0 -0
  73. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/tests/test_examples.py +0 -0
  74. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/tests/test_graph.py +0 -0
  75. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/tests/test_phonemizers_base.py +0 -0
  76. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/tests/test_readings.py +0 -0
  77. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/tests/test_readings_zh.py +0 -0
  78. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/tests/test_scripts.py +0 -0
  79. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/tests/test_scripts_stressonnx_compat.py +0 -0
  80. {scriptconv-0.0.3a18 → scriptconv-0.0.3a20}/tests/test_translit.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scriptconv
3
- Version: 0.0.3a18
3
+ Version: 0.0.3a20
4
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
5
  License: Apache-2.0
6
6
  Project-URL: Homepage, https://github.com/TigreGotico/scriptconv
@@ -1034,7 +1034,8 @@ _MANTOQ_VOWELS: dict[str, str] = {
1034
1034
  "u": "u", "uu": "uː",
1035
1035
  }
1036
1036
 
1037
- _MANTOQ_MULTI = ("_dbl_", "_+_", "aaaa", "aa", "ii", "uu")
1037
+ _MANTOQ_MULTI = ("_dbl_", "_+_", "_sil_", "_eos_", "_pad_",
1038
+ "aaaa", "aa", "ii", "uu")
1038
1039
 
1039
1040
 
1040
1041
  def _tokenize_mantoq(text: str) -> list[str]:
@@ -1052,7 +1053,7 @@ def _tokenize_mantoq(text: str) -> list[str]:
1052
1053
  return tokens
1053
1054
 
1054
1055
 
1055
- def mantoq_to_ipa(mantoq: str, errors: str = "pass") -> str:
1056
+ def mantoq_to_ipa(mantoq, errors: str = "pass") -> str:
1056
1057
  """Convert a Mantoq phoneme string to IPA.
1057
1058
 
1058
1059
  ``_dbl_`` lengthens/geminates the preceding symbol (``ː``), ``_+_``
@@ -1065,16 +1066,33 @@ def mantoq_to_ipa(mantoq: str, errors: str = "pass") -> str:
1065
1066
  's a l aː m'
1066
1067
  >>> mantoq_to_ipa("b_dbl_a")
1067
1068
  'bːa'
1069
+
1070
+ The inventory's special tokens are honoured: ``_sil_`` becomes a space,
1071
+ ``_eos_``/``_pad_`` are dropped.
1068
1072
  """
1073
+ # a pre-tokenized sequence (as returned by the mantoq package's g2p)
1074
+ # is consumed directly — joining tokens into a string is ambiguous
1075
+ # ("a"+"aa" and "aa"+"a" both join to "aaa")
1076
+ tokens = _tokenize_mantoq(mantoq) if isinstance(mantoq, str) else mantoq
1069
1077
  out: list[str] = []
1070
1078
  last_tok = None
1071
- for pos, tok in enumerate(_tokenize_mantoq(mantoq)):
1079
+ for pos, tok in enumerate(tokens):
1072
1080
  if tok == "_dbl_":
1073
- # vowels lengthen cumulatively (aa + _dbl_ -> aːː); consonants
1074
- # geminate once
1075
- if out and last_tok is not None:
1076
- if last_tok in _MANTOQ_VOWELS or not out[-1].endswith("ː"):
1077
- out[-1] += "ː"
1081
+ # upstream emits _dbl_ only by splitting a doubled CONSONANT
1082
+ # (mantoq buck/tokenization.py: `phon not in vowels and
1083
+ # phon[0] == phon[1]`); geminate it with a length mark. A
1084
+ # vowel+_dbl_ sequence does not occur in genuine mantoq output
1085
+ # and is left unchanged.
1086
+ if out and last_tok in _MANTOQ_CONSONANTS \
1087
+ and not out[-1].endswith("ː"):
1088
+ out[-1] += "ː"
1089
+ continue
1090
+ if tok == "_sil_":
1091
+ out.append(" ")
1092
+ last_tok = None
1093
+ continue
1094
+ if tok in ("_eos_", "_pad_"):
1095
+ last_tok = None
1078
1096
  continue
1079
1097
  if tok == "_+_":
1080
1098
  out.append(" ")
@@ -5,21 +5,46 @@ from scriptconv.phonemizers.base import BasePhonemizer
5
5
 
6
6
 
7
7
  class MantoqPhonemizer(BasePhonemizer):
8
- """mantoq-backed Arabic phonemizer NOT distributable with scriptconv.
8
+ """Arabic phonemizer wrapping the external ``mantoq`` package.
9
9
 
10
- mantoq's phonetise_buckwalter is CC BY-NC 4.0 (non-commercial) and its
11
- vendored pyarabic is GPLboth incompatible with this library's
12
- Apache-2.0 distribution, so the implementation is not vendored here.
13
- Use :class:`ArbtokPhonemizer` (the Arabic default) instead.
10
+ mantoq (github.com/mush42/mantoq) bundles Nawar Halabi's Arabic-Phonetiser,
11
+ whose phonetisation core is CC BY-NC 4.0 a license incompatible with
12
+ vendoring in this Apache-2.0 library, so the package is imported at
13
+ runtime and must be installed separately by a user who accepts its terms:
14
+
15
+ pip install git+https://github.com/mush42/mantoq
16
+
17
+ Kept for compatibility with published models trained on mantoq phoneme
18
+ sequences; the Arabic default is :class:`ArbtokPhonemizer`. Output is
19
+ IPA (via :func:`scriptconv.notation.mantoq_to_ipa`) or the raw mantoq
20
+ inventory with ``alphabet=Alphabet.MANTOQ``.
14
21
  """
15
22
 
16
- def __init__(self, *args, **kwargs):
17
- raise ImportError(
18
- "mantoq is CC BY-NC / GPL licensed and not vendored in "
19
- "scriptconv — use ArbtokPhonemizer (the Arabic default)")
23
+ def __init__(self, alphabet: Alphabet = Alphabet.IPA):
24
+ if alphabet not in (Alphabet.IPA, Alphabet.MANTOQ):
25
+ raise ValueError("MantoqPhonemizer outputs IPA or MANTOQ")
26
+ super().__init__(alphabet)
27
+ try:
28
+ import mantoq
29
+ except ImportError:
30
+ raise ImportError(
31
+ "the mantoq package is not installed (and not vendored here: "
32
+ "its phonetisation core is CC BY-NC 4.0). Install it "
33
+ "separately, accepting its license terms: "
34
+ "pip install git+https://github.com/mush42/mantoq") from None
35
+ self._g2p = mantoq.g2p
36
+
37
+ @classmethod
38
+ def get_lang(cls, target_lang: str) -> str:
39
+ return cls.match_lang(target_lang, ["ar"])
20
40
 
21
41
  def phonemize_string(self, text: str, lang: str) -> str:
22
- raise NotImplementedError
42
+ _, tokens = self._g2p(text)
43
+ if self.alphabet == Alphabet.MANTOQ:
44
+ return " ".join(tokens)
45
+ from scriptconv.notation import mantoq_to_ipa
46
+ return mantoq_to_ipa(tokens)
47
+
23
48
 
24
49
 
25
50
  class ArbtokPhonemizer(BasePhonemizer):
@@ -47,19 +47,30 @@ class G2PKPhonemizer(BasePhonemizer):
47
47
 
48
48
 
49
49
  class KoG2PPhonemizer(BasePhonemizer):
50
- """KoG2P-backed Korean phonemizer NOT distributable with scriptconv.
50
+ """Korean phonemizer wrapping an external ``kog2p`` distribution.
51
51
 
52
- Upstream KoG2P (github.com/scarletcho/KoG2P) is GPL-3.0, incompatible
53
- with this library's Apache-2.0 distribution, so the implementation is not
54
- vendored here. Use :class:`G2PKPhonemizer` or the hangul2ipa-backed
55
- pipeline instead, or a GPL-compatible package that ships KoG2P itself.
52
+ Upstream KoG2P (github.com/scarletcho/KoG2P) is GPL-3.0 — a license
53
+ incompatible with vendoring in this Apache-2.0 library, so a ``kog2p``
54
+ module providing ``runKoG2P`` must be installed separately by a user who
55
+ accepts its terms. :class:`G2PKPhonemizer` is the unencumbered
56
+ alternative.
56
57
  """
57
58
 
58
- def __init__(self, *args, **kwargs):
59
- raise ImportError(
60
- "KoG2P is GPL-3.0 and not vendored in scriptconv — use "
61
- "G2PKPhonemizer, or install a GPL-licensed distribution that "
62
- "provides it")
59
+ def __init__(self, alphabet: Alphabet = Alphabet.IPA):
60
+ super().__init__(alphabet)
61
+ try:
62
+ from kog2p import runKoG2P
63
+ except ImportError:
64
+ raise ImportError(
65
+ "no kog2p module installed (KoG2P is GPL-3.0 and not "
66
+ "vendored here). Install a distribution providing it, "
67
+ "accepting its license, or use G2PKPhonemizer") from None
68
+ self.g2p = runKoG2P
69
+
70
+ @classmethod
71
+ def get_lang(cls, target_lang: str) -> str:
72
+ return cls.match_lang(target_lang, ["ko"])
63
73
 
64
74
  def phonemize_string(self, text: str, lang: str) -> str:
65
- raise NotImplementedError
75
+ # contract: the installed module's runKoG2P(text) -> phoneme string
76
+ return self.g2p(text)
@@ -2,7 +2,7 @@
2
2
  VERSION_MAJOR = 0
3
3
  VERSION_MINOR = 0
4
4
  VERSION_BUILD = 3
5
- VERSION_ALPHA = 18
5
+ VERSION_ALPHA = 20
6
6
  # END_VERSION_BLOCK
7
7
 
8
8
  VERSION_STR = f"{VERSION_MAJOR}.{VERSION_MINOR}.{VERSION_BUILD}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scriptconv
3
- Version: 0.0.3a18
3
+ Version: 0.0.3a20
4
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
5
  License: Apache-2.0
6
6
  Project-URL: Homepage, https://github.com/TigreGotico/scriptconv
@@ -1168,7 +1168,20 @@ def test_mantoq_theta_is_caret_not_shadda():
1168
1168
 
1169
1169
  def test_mantoq_gemination_marker():
1170
1170
  assert mantoq_to_ipa("b_dbl_a") == "bːa"
1171
- assert mantoq_to_ipa("aa_dbl_") == "aːː"
1171
+
1172
+
1173
+ def test_mantoq_dbl_after_vowel_is_inert():
1174
+ # upstream only emits _dbl_ after consonants (tokenization.py splits
1175
+ # doubled consonant phonemes); a vowel+_dbl_ input is left unchanged
1176
+ assert mantoq_to_ipa("aa_dbl_") == "aː"
1177
+
1178
+
1179
+ def test_mantoq_special_tokens():
1180
+ # inventory special tokens: _sil_ -> pause (space), _eos_/_pad_ dropped —
1181
+ # and never shredded into letter phonemes
1182
+ assert mantoq_to_ipa("m_sil_n") == "m n"
1183
+ assert mantoq_to_ipa("m a_eos_") == "m a"
1184
+ assert mantoq_to_ipa("_pad_b") == "b"
1172
1185
 
1173
1186
 
1174
1187
  def test_mantoq_word_separator_and_glottal():
@@ -41,13 +41,13 @@ class TestShamiFrontend(unittest.TestCase):
41
41
 
42
42
 
43
43
  class TestLicensingStubs(unittest.TestCase):
44
- def test_mantoq_stub_explains_licensing(self):
44
+ def test_mantoq_wrapper_requires_external_package(self):
45
45
  cls = get_phonemizer_class(Phonemizer.MANTOQ)
46
46
  with self.assertRaises(ImportError) as ctx:
47
47
  cls()
48
48
  self.assertIn("BY-NC", str(ctx.exception).replace("CC BY-NC", "BY-NC"))
49
49
 
50
- def test_kog2p_stub_explains_licensing(self):
50
+ def test_kog2p_wrapper_requires_external_package(self):
51
51
  cls = get_phonemizer_class(Phonemizer.KOG2PK)
52
52
  with self.assertRaises(ImportError) as ctx:
53
53
  cls()
@@ -67,3 +67,20 @@ class TestLicensingStubs(unittest.TestCase):
67
67
 
68
68
  if __name__ == "__main__":
69
69
  unittest.main()
70
+
71
+
72
+ class TestMantoqTokensToIpa(unittest.TestCase):
73
+ def test_pretokenized_sequence_accepted(self):
74
+ # the mantoq package's g2p returns a token LIST; joining is ambiguous
75
+ # so mantoq_to_ipa consumes sequences directly
76
+ from scriptconv.notation import mantoq_to_ipa
77
+ tokens = ["m", "a", "r", "H", "a", "b", "a", "n", "aa",
78
+ "_+_", "b", "i", "l", "E", "aa", "l", "a", "m", "i"]
79
+ out = mantoq_to_ipa(tokens)
80
+ self.assertIn("ħ", out)
81
+ self.assertIn(" ", out)
82
+ self.assertNotIn("_", out)
83
+
84
+ def test_pretokenized_dbl_geminate(self):
85
+ from scriptconv.notation import mantoq_to_ipa
86
+ self.assertEqual(mantoq_to_ipa(["b", "_dbl_", "a"]), "bːa")
File without changes
File without changes
File without changes