kamaalg commited on
Commit
a2fd844
·
verified ·
1 Parent(s): cd16d9b

Upload aztext/alphabet.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. aztext/alphabet.py +66 -0
aztext/alphabet.py ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Canonical Azerbaijani (Latin script) alphabet constants and case helpers.
2
+
3
+ Modern North Azerbaijani (Republic of Azerbaijan) uses a 32-letter Latin
4
+ alphabet. Beyond ASCII it adds: ə Ə, ğ Ğ, ı I (dotless i), i İ (dotted i),
5
+ ö Ö, ş Ş, ç Ç, ü Ü.
6
+
7
+ The dotted/dotless ``i`` distinction is *semantically meaningful* and must
8
+ never be collapsed: i (U+0069) ≠ ı (U+0131) and İ (U+0130) ≠ I (U+0049).
9
+
10
+ Python's default ``str.lower``/``str.upper`` implement the *non-Turkic* rules
11
+ (``'i'.upper() == 'I'``), which is wrong for Azerbaijani. Use :func:`az_lower`
12
+ and :func:`az_upper` instead — they honour the Turkic i mappings:
13
+
14
+ upper('i') = 'İ' lower('I') = 'ı'
15
+ upper('ı') = 'I' lower('İ') = 'i'
16
+ """
17
+
18
+ # --- Vowels and consonants (lowercase) ---------------------------------------
19
+ # 9 vowels
20
+ AZ_VOWELS = "aeəıioöuü"
21
+ # 23 consonants (dotless/ordinary letters only; İ/I handled by the vowel i/ı)
22
+ AZ_CONSONANTS = "bcçdfgğhxjklmnpqrsştvyz"
23
+
24
+ # --- Full lowercase / uppercase alphabets (in canonical alphabet order) -------
25
+ # Alphabet order: a b c ç d e ə f g ğ h x ı i j k q l m n o ö p r s ş t u ü v y z
26
+ AZ_LOWER = "abcçdeəfgğhxıijkqlmnoöprsştuüvyz"
27
+ AZ_UPPER = "ABCÇDEƏFGĞHXIİJKQLMNOÖPRSŞTUÜVYZ"
28
+
29
+ # All Azerbaijani letters (both cases), for membership tests / regex classes.
30
+ AZ_LETTERS = AZ_LOWER + AZ_UPPER
31
+
32
+ # --- Turkic-aware case mappings for the i-family -----------------------------
33
+ # These four characters are the ones Python gets wrong for Azerbaijani.
34
+ # i U+0069 LATIN SMALL LETTER I -> upper İ U+0130
35
+ # İ U+0130 LATIN CAPITAL LETTER I WITH DOT -> lower i U+0069
36
+ # ı U+0131 LATIN SMALL LETTER DOTLESS I -> upper I U+0049
37
+ # I U+0049 LATIN CAPITAL LETTER I -> lower ı U+0131
38
+ _UPPER_I_MAP = {"i": "İ", "ı": "I"}
39
+ _LOWER_I_MAP = {"İ": "i", "I": "ı"}
40
+
41
+
42
+ def az_upper(text: str) -> str:
43
+ """Uppercase ``text`` with correct Azerbaijani i-mapping.
44
+
45
+ ``i`` -> ``İ`` and ``ı`` -> ``I`` are applied first so that the subsequent
46
+ plain ``str.upper()`` (which correctly handles ə→Ə, ç→Ç, ş→Ş, ğ→Ğ, ö→Ö,
47
+ ü→Ü, and all ASCII) never touches the dotted/dotless ``i`` incorrectly.
48
+ """
49
+ text = text.replace("i", "İ").replace("ı", "I")
50
+ return text.upper()
51
+
52
+
53
+ def az_lower(text: str) -> str:
54
+ """Lowercase ``text`` with correct Azerbaijani i-mapping.
55
+
56
+ ``İ`` -> ``i`` and ``I`` -> ``ı`` are applied first. This also avoids
57
+ Python's quirk where ``'İ'.lower()`` yields the two-character sequence
58
+ ``'i' + COMBINING DOT ABOVE`` instead of a plain ``'i'``.
59
+ """
60
+ text = text.replace("İ", "i").replace("I", "ı")
61
+ return text.lower()
62
+
63
+
64
+ def is_az_letter(ch: str) -> bool:
65
+ """True if ``ch`` is a single Azerbaijani alphabet letter."""
66
+ return len(ch) == 1 and ch in AZ_LETTERS