character-encoding-utils 0.0.2__tar.gz → 0.0.4__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.
- {character-encoding-utils-0.0.2 → character-encoding-utils-0.0.4}/PKG-INFO +3 -3
- {character-encoding-utils-0.0.2 → character-encoding-utils-0.0.4}/README.md +1 -1
- {character-encoding-utils-0.0.2 → character-encoding-utils-0.0.4}/pyproject.toml +2 -2
- {character-encoding-utils-0.0.2 → character-encoding-utils-0.0.4}/src/character_encoding_utils/big5.py +43 -42
- {character-encoding-utils-0.0.2 → character-encoding-utils-0.0.4}/src/character_encoding_utils/gb2312.py +20 -22
- {character-encoding-utils-0.0.2 → character-encoding-utils-0.0.4}/src/character_encoding_utils/ksx1001.py +37 -30
- {character-encoding-utils-0.0.2 → character-encoding-utils-0.0.4}/src/character_encoding_utils/shiftjis.py +28 -33
- {character-encoding-utils-0.0.2 → character-encoding-utils-0.0.4}/src/character_encoding_utils.egg-info/PKG-INFO +3 -3
- {character-encoding-utils-0.0.2 → character-encoding-utils-0.0.4}/tests/test_big5.py +42 -0
- {character-encoding-utils-0.0.2 → character-encoding-utils-0.0.4}/tests/test_gb2312.py +26 -0
- {character-encoding-utils-0.0.2 → character-encoding-utils-0.0.4}/tests/test_ksx1001.py +30 -0
- {character-encoding-utils-0.0.2 → character-encoding-utils-0.0.4}/tests/test_shiftjis.py +34 -0
- {character-encoding-utils-0.0.2 → character-encoding-utils-0.0.4}/LICENSE +0 -0
- {character-encoding-utils-0.0.2 → character-encoding-utils-0.0.4}/setup.cfg +0 -0
- {character-encoding-utils-0.0.2 → character-encoding-utils-0.0.4}/src/character_encoding_utils/__init__.py +0 -0
- {character-encoding-utils-0.0.2 → character-encoding-utils-0.0.4}/src/character_encoding_utils.egg-info/SOURCES.txt +0 -0
- {character-encoding-utils-0.0.2 → character-encoding-utils-0.0.4}/src/character_encoding_utils.egg-info/dependency_links.txt +0 -0
- {character-encoding-utils-0.0.2 → character-encoding-utils-0.0.4}/src/character_encoding_utils.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: character-encoding-utils
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4
|
|
4
4
|
Summary: Some character encoding utils.
|
|
5
5
|
Author: TakWolf
|
|
6
6
|
Maintainer: TakWolf
|
|
@@ -8,7 +8,7 @@ License: MIT License
|
|
|
8
8
|
Project-URL: homepage, https://github.com/TakWolf/character-encoding-utils
|
|
9
9
|
Project-URL: source, https://github.com/TakWolf/character-encoding-utils
|
|
10
10
|
Project-URL: issues, https://github.com/TakWolf/character-encoding-utils/issues
|
|
11
|
-
Keywords: encoding
|
|
11
|
+
Keywords: encoding,gb2312,big5,shift-jis,ksx1001
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
13
13
|
Classifier: License :: OSI Approved :: MIT License
|
|
14
14
|
Classifier: Operating System :: OS Independent
|
|
@@ -60,7 +60,7 @@ assert big5.decode(bs) == 'abc中國'
|
|
|
60
60
|
```python
|
|
61
61
|
from character_encoding_utils import shiftjis
|
|
62
62
|
|
|
63
|
-
bs =
|
|
63
|
+
bs = shiftjis.encode('abc日本')
|
|
64
64
|
assert shiftjis.decode(bs) == 'abc日本'
|
|
65
65
|
```
|
|
66
66
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "character-encoding-utils"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.4"
|
|
4
4
|
description = "Some character encoding utils."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = { text = "MIT License" }
|
|
@@ -11,7 +11,7 @@ authors = [
|
|
|
11
11
|
maintainers = [
|
|
12
12
|
{ name = "TakWolf" },
|
|
13
13
|
]
|
|
14
|
-
keywords = ["encoding"]
|
|
14
|
+
keywords = ["encoding", "gb2312", "big5", "shift-jis", "ksx1001"]
|
|
15
15
|
classifiers = [
|
|
16
16
|
"Programming Language :: Python :: 3",
|
|
17
17
|
"License :: OSI Approved :: MIT License",
|
|
@@ -16,88 +16,89 @@ class Big5DecodeError(Big5Exception):
|
|
|
16
16
|
self.object = obj
|
|
17
17
|
self.position = position
|
|
18
18
|
self.reason = reason
|
|
19
|
-
|
|
19
|
+
if len(obj) <= 1:
|
|
20
|
+
super().__init__(f"'big5' codec can't decode byte 0x{obj[0]:x} in position {position}: {reason}")
|
|
21
|
+
else:
|
|
22
|
+
super().__init__(f"'big5' codec can't decode bytes in position {position}-{position + len(obj) - 1}: {reason}")
|
|
20
23
|
|
|
21
24
|
|
|
22
25
|
def encode(cs: str) -> bytes:
|
|
23
26
|
bs = bytearray()
|
|
24
27
|
for position, c in enumerate(cs):
|
|
25
|
-
# 此处默认编码器映射错误
|
|
26
28
|
if c == '〸': # 0x3038
|
|
27
29
|
bs.extend(b'\xa2\xcc')
|
|
28
|
-
continue
|
|
29
30
|
elif c == '〹': # 0x3039
|
|
30
31
|
bs.extend(b'\xa2\xcd')
|
|
31
|
-
continue
|
|
32
32
|
elif c == '〺': # 0x303A
|
|
33
33
|
bs.extend(b'\xa2\xce')
|
|
34
|
-
continue
|
|
35
34
|
elif c == '十': # 0x5341
|
|
36
35
|
bs.extend(b'\xa4\x51')
|
|
37
|
-
continue
|
|
38
36
|
elif c == '卄': # 0x5344
|
|
39
37
|
# Big5 不包含汉字的 '卄'
|
|
40
38
|
raise Big5EncodeError(c, position, 'illegal multibyte sequence')
|
|
41
39
|
elif c == '卅': # 0x5345
|
|
42
40
|
bs.extend(b'\xa4\xca')
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
bs.extend(
|
|
47
|
-
|
|
48
|
-
|
|
41
|
+
elif c == '/': # 0xFF0F
|
|
42
|
+
bs.extend(b'\xa1\xfe')
|
|
43
|
+
elif c == '\': # 0xFF3C
|
|
44
|
+
bs.extend(b'\xa2\x40')
|
|
45
|
+
elif c == '∕': # 0x2215
|
|
46
|
+
bs.extend(b'\xa2\x41')
|
|
47
|
+
elif c == '﹨': # 0xFE68
|
|
48
|
+
bs.extend(b'\xa2\x42')
|
|
49
|
+
else:
|
|
50
|
+
try:
|
|
51
|
+
bs.extend(c.encode('big5'))
|
|
52
|
+
except UnicodeEncodeError as e:
|
|
53
|
+
raise Big5EncodeError(c, position, e.reason) from e
|
|
49
54
|
return bytes(bs)
|
|
50
55
|
|
|
51
56
|
|
|
52
|
-
def decode(bs: bytes) -> str:
|
|
57
|
+
def decode(bs: bytes | bytearray) -> str:
|
|
53
58
|
cs = []
|
|
54
|
-
|
|
55
|
-
|
|
59
|
+
cursor = 0
|
|
60
|
+
passed = 0
|
|
56
61
|
while True:
|
|
57
|
-
|
|
58
|
-
b1 = next(bs)
|
|
59
|
-
position += 1
|
|
60
|
-
except StopIteration:
|
|
62
|
+
if cursor >= len(bs):
|
|
61
63
|
break
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if b2 is None:
|
|
70
|
-
bc = bytes([b1])
|
|
71
|
-
else:
|
|
72
|
-
bc = bytes([b1, b2])
|
|
64
|
+
bc = bytearray([bs[cursor]])
|
|
65
|
+
cursor += 1
|
|
66
|
+
|
|
67
|
+
if bc[0] > 0x7F:
|
|
68
|
+
if cursor < len(bs):
|
|
69
|
+
bc.append(bs[cursor])
|
|
70
|
+
cursor += 1
|
|
73
71
|
|
|
74
|
-
# 此处默认编码器映射错误
|
|
75
72
|
if bc == b'\xa2\xcc':
|
|
76
73
|
cs.append('〸') # 0x3038
|
|
77
|
-
continue
|
|
78
74
|
elif bc == b'\xa2\xcd':
|
|
79
75
|
cs.append('〹') # 0x3039
|
|
80
|
-
continue
|
|
81
76
|
elif bc == b'\xa2\xce':
|
|
82
77
|
cs.append('〺') # 0x303A
|
|
83
|
-
continue
|
|
84
78
|
elif bc == b'\xa4\x51':
|
|
85
79
|
cs.append('十') # 0x5341
|
|
86
|
-
continue
|
|
87
80
|
elif bc == b'\xa4\xca':
|
|
88
81
|
cs.append('卅') # 0x5345
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
cs.append(
|
|
93
|
-
|
|
94
|
-
|
|
82
|
+
elif bc == b'\xa1\xfe':
|
|
83
|
+
cs.append('/') # 0xFF0F
|
|
84
|
+
elif bc == b'\xa2\x40':
|
|
85
|
+
cs.append('\') # 0xFF3C
|
|
86
|
+
elif bc == b'\xa2\x41':
|
|
87
|
+
cs.append('∕') # 0x2215
|
|
88
|
+
elif bc == b'\xa2\x42':
|
|
89
|
+
cs.append('﹨') # 0xFE68
|
|
90
|
+
else:
|
|
91
|
+
try:
|
|
92
|
+
cs.append(bc.decode('big5'))
|
|
93
|
+
except UnicodeDecodeError as e:
|
|
94
|
+
raise Big5DecodeError(bc, passed, e.reason) from e
|
|
95
|
+
passed += len(bc)
|
|
95
96
|
return ''.join(cs)
|
|
96
97
|
|
|
97
98
|
|
|
98
99
|
def query_code(c: str) -> int:
|
|
99
100
|
if len(c) != 1:
|
|
100
|
-
raise Big5Exception('
|
|
101
|
+
raise Big5Exception('Must be one character')
|
|
101
102
|
try:
|
|
102
103
|
bs = encode(c)
|
|
103
104
|
except Big5EncodeError as e:
|
|
@@ -19,7 +19,10 @@ class GB2312DecodeError(GB2312Exception):
|
|
|
19
19
|
self.object = obj
|
|
20
20
|
self.position = position
|
|
21
21
|
self.reason = reason
|
|
22
|
-
|
|
22
|
+
if len(obj) <= 1:
|
|
23
|
+
super().__init__(f"'gb2312' codec can't decode byte 0x{obj[0]:x} in position {position}: {reason}")
|
|
24
|
+
else:
|
|
25
|
+
super().__init__(f"'gb2312' codec can't decode bytes in position {position}-{position + len(obj) - 1}: {reason}")
|
|
23
26
|
|
|
24
27
|
|
|
25
28
|
def encode(cs: str) -> bytes:
|
|
@@ -32,37 +35,32 @@ def encode(cs: str) -> bytes:
|
|
|
32
35
|
return bytes(bs)
|
|
33
36
|
|
|
34
37
|
|
|
35
|
-
def decode(bs: bytes) -> str:
|
|
38
|
+
def decode(bs: bytes | bytearray) -> str:
|
|
36
39
|
cs = []
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
cursor = 0
|
|
41
|
+
passed = 0
|
|
39
42
|
while True:
|
|
40
|
-
|
|
41
|
-
b1 = next(bs)
|
|
42
|
-
position += 1
|
|
43
|
-
except StopIteration:
|
|
43
|
+
if cursor >= len(bs):
|
|
44
44
|
break
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
bc = bytes([b1])
|
|
54
|
-
else:
|
|
55
|
-
bc = bytes([b1, b2])
|
|
45
|
+
bc = bytearray([bs[cursor]])
|
|
46
|
+
cursor += 1
|
|
47
|
+
|
|
48
|
+
if bc[0] > 0x7F:
|
|
49
|
+
if cursor < len(bs):
|
|
50
|
+
bc.append(bs[cursor])
|
|
51
|
+
cursor += 1
|
|
52
|
+
|
|
56
53
|
try:
|
|
57
54
|
cs.append(bc.decode('gb2312'))
|
|
58
55
|
except UnicodeDecodeError as e:
|
|
59
|
-
raise GB2312DecodeError(bc,
|
|
56
|
+
raise GB2312DecodeError(bc, passed, e.reason) from e
|
|
57
|
+
passed += len(bc)
|
|
60
58
|
return ''.join(cs)
|
|
61
59
|
|
|
62
60
|
|
|
63
61
|
def query_coord(c: str) -> tuple[int, int]:
|
|
64
62
|
if len(c) != 1:
|
|
65
|
-
raise GB2312Exception('
|
|
63
|
+
raise GB2312Exception('Must be one character')
|
|
66
64
|
try:
|
|
67
65
|
bs = encode(c)
|
|
68
66
|
except GB2312EncodeError as e:
|
|
@@ -99,7 +97,7 @@ def query_category(c: str) -> str | None:
|
|
|
99
97
|
elif 56 <= row <= 87:
|
|
100
98
|
return 'level-2'
|
|
101
99
|
else:
|
|
102
|
-
|
|
100
|
+
return None
|
|
103
101
|
|
|
104
102
|
|
|
105
103
|
def _build_alphabet_by_rows_between(row_start: int, row_end: int) -> list[str]:
|
|
@@ -19,7 +19,10 @@ class KSX1001DecodeError(KSX1001Exception):
|
|
|
19
19
|
self.object = obj
|
|
20
20
|
self.position = position
|
|
21
21
|
self.reason = reason
|
|
22
|
-
|
|
22
|
+
if len(obj) <= 1:
|
|
23
|
+
super().__init__(f"'ksx1001' codec can't decode byte 0x{obj[0]:x} in position {position}: {reason}")
|
|
24
|
+
else:
|
|
25
|
+
super().__init__(f"'ksx1001' codec can't decode bytes in position {position}-{position + len(obj) - 1}: {reason}")
|
|
23
26
|
|
|
24
27
|
|
|
25
28
|
def encode(cs: str) -> bytes:
|
|
@@ -32,50 +35,54 @@ def encode(cs: str) -> bytes:
|
|
|
32
35
|
return bytes(bs)
|
|
33
36
|
|
|
34
37
|
|
|
35
|
-
def decode(bs: bytes) -> str:
|
|
38
|
+
def decode(bs: bytes | bytearray) -> str:
|
|
36
39
|
cs = []
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
cursor = 0
|
|
41
|
+
passed = 0
|
|
39
42
|
while True:
|
|
40
|
-
|
|
41
|
-
b1 = next(bs)
|
|
42
|
-
position += 1
|
|
43
|
-
except StopIteration:
|
|
43
|
+
if cursor >= len(bs):
|
|
44
44
|
break
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
45
|
+
bc = bytearray([bs[cursor]])
|
|
46
|
+
cursor += 1
|
|
47
|
+
|
|
48
|
+
if bc[0] > 0x7F:
|
|
49
|
+
if cursor < len(bs):
|
|
50
|
+
bc.append(bs[cursor])
|
|
51
|
+
cursor += 1
|
|
52
|
+
|
|
53
|
+
if bc == b'\xa4\xd4' and cursor + 5 < len(bs):
|
|
54
|
+
if bs[cursor] == 0xA4 and bs[cursor + 2] == 0xA4 and bs[cursor + 4] == 0xA4:
|
|
55
|
+
if 0xA1 <= bs[cursor + 1] <= 0xD4 and 0xA1 <= bs[cursor + 3] <= 0xD4 and 0xA1 <= bs[cursor + 5] <= 0xD4:
|
|
56
|
+
bc.append(bs[cursor])
|
|
57
|
+
bc.append(bs[cursor + 1])
|
|
58
|
+
bc.append(bs[cursor + 2])
|
|
59
|
+
bc.append(bs[cursor + 3])
|
|
60
|
+
bc.append(bs[cursor + 4])
|
|
61
|
+
bc.append(bs[cursor + 5])
|
|
62
|
+
cursor += 6
|
|
56
63
|
|
|
57
|
-
# 'euc_kr' 编码器对字符 'Hangul Filler (0x3164, row = 4, col= 52)' 的处理不正确,但是官方开发者并不认为这是一个错误
|
|
58
|
-
# 问题详情见: https://github.com/python/cpython/issues/101863
|
|
59
64
|
if bc == b'\xa4\xd4':
|
|
60
|
-
cs.append(chr(0x3164))
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
cs.append(chr(0x3164)) # Hangul Filler
|
|
66
|
+
else:
|
|
67
|
+
try:
|
|
68
|
+
cs.append(bc.decode('ksx1001'))
|
|
69
|
+
except UnicodeDecodeError as e:
|
|
70
|
+
raise KSX1001DecodeError(bc, passed, e.reason) from e
|
|
71
|
+
passed += len(bc)
|
|
67
72
|
return ''.join(cs)
|
|
68
73
|
|
|
69
74
|
|
|
70
75
|
def query_coord(c: str) -> tuple[int, int]:
|
|
71
76
|
if len(c) != 1:
|
|
72
|
-
raise KSX1001Exception('
|
|
77
|
+
raise KSX1001Exception('Must be one character')
|
|
73
78
|
try:
|
|
74
79
|
bs = encode(c)
|
|
75
80
|
except KSX1001EncodeError as e:
|
|
76
81
|
raise KSX1001Exception(f"'{c}' is not a 'ksx1001' character") from e
|
|
77
82
|
if len(bs) == 1:
|
|
78
83
|
raise KSX1001Exception(f"'{c}' is a ascii character")
|
|
84
|
+
elif bs.startswith(b'\xa4\xd4') and len(bs) > 2:
|
|
85
|
+
raise KSX1001Exception(f"'{c}' is not a 'ksx1001' character")
|
|
79
86
|
row = bs[0] - _euc_offset
|
|
80
87
|
col = bs[1] - _euc_offset
|
|
81
88
|
return row, col
|
|
@@ -106,7 +113,7 @@ def query_category(c: str) -> str | None:
|
|
|
106
113
|
elif 42 <= row <= 93:
|
|
107
114
|
return 'hanja'
|
|
108
115
|
else:
|
|
109
|
-
|
|
116
|
+
return None
|
|
110
117
|
|
|
111
118
|
|
|
112
119
|
def _build_alphabet_by_rows_between(row_start: int, row_end: int) -> list[str]:
|
|
@@ -18,7 +18,10 @@ class ShiftJISDecodeError(ShiftJISException):
|
|
|
18
18
|
self.object = obj
|
|
19
19
|
self.position = position
|
|
20
20
|
self.reason = reason
|
|
21
|
-
|
|
21
|
+
if len(obj) <= 1:
|
|
22
|
+
super().__init__(f"'shift-jis' codec can't decode byte 0x{obj[0]:x} in position {position}: {reason}")
|
|
23
|
+
else:
|
|
24
|
+
super().__init__(f"'shift-jis' codec can't decode bytes in position {position}-{position + len(obj) - 1}: {reason}")
|
|
22
25
|
|
|
23
26
|
|
|
24
27
|
def encode(cs: str) -> bytes:
|
|
@@ -28,47 +31,39 @@ def encode(cs: str) -> bytes:
|
|
|
28
31
|
raise ShiftJISEncodeError(c, position, f"in 'shift-jis' the character '\\' is replaced with '¥'")
|
|
29
32
|
elif c == '~':
|
|
30
33
|
raise ShiftJISEncodeError(c, position, f"in 'shift-jis' the character '~' is replaced with '‾'")
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
else:
|
|
35
|
+
try:
|
|
36
|
+
bs.extend(c.encode('shift-jis'))
|
|
37
|
+
except UnicodeEncodeError as e:
|
|
38
|
+
raise ShiftJISEncodeError(c, position, e.reason) from e
|
|
36
39
|
return bytes(bs)
|
|
37
40
|
|
|
38
41
|
|
|
39
|
-
def decode(bs: bytes) -> str:
|
|
42
|
+
def decode(bs: bytes | bytearray) -> str:
|
|
40
43
|
cs = []
|
|
41
|
-
|
|
42
|
-
|
|
44
|
+
cursor = 0
|
|
45
|
+
passed = 0
|
|
43
46
|
while True:
|
|
44
|
-
|
|
45
|
-
b1 = next(bs)
|
|
46
|
-
position += 1
|
|
47
|
-
except StopIteration:
|
|
47
|
+
if cursor >= len(bs):
|
|
48
48
|
break
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if b2 is None:
|
|
57
|
-
bc = bytes([b1])
|
|
58
|
-
else:
|
|
59
|
-
bc = bytes([b1, b2])
|
|
49
|
+
bc = bytearray([bs[cursor]])
|
|
50
|
+
cursor += 1
|
|
51
|
+
|
|
52
|
+
if not (bc[0] <= 0x7F or 0xA1 <= bc[0] <= 0xDF):
|
|
53
|
+
if cursor < len(bs):
|
|
54
|
+
bc.append(bs[cursor])
|
|
55
|
+
cursor += 1
|
|
60
56
|
|
|
61
57
|
if bc == b'\\':
|
|
62
58
|
cs.append('¥')
|
|
63
|
-
continue
|
|
64
59
|
elif bc == b'~':
|
|
65
60
|
cs.append('‾')
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
61
|
+
else:
|
|
62
|
+
try:
|
|
63
|
+
cs.append(bc.decode('shift-jis'))
|
|
64
|
+
except UnicodeDecodeError as e:
|
|
65
|
+
raise ShiftJISDecodeError(bc, passed, e.reason) from e
|
|
66
|
+
passed += len(bc)
|
|
72
67
|
return ''.join(cs)
|
|
73
68
|
|
|
74
69
|
|
|
@@ -96,7 +91,7 @@ def query_category(c: str) -> str | None:
|
|
|
96
91
|
elif 0xA1 <= first_byte <= 0xDF:
|
|
97
92
|
return 'single-byte-half-width-katakana'
|
|
98
93
|
else:
|
|
99
|
-
|
|
94
|
+
return None
|
|
100
95
|
else:
|
|
101
96
|
second_byte = bs[1]
|
|
102
97
|
if 0x81 <= first_byte <= 0x87 or (first_byte == 0x88 and second_byte <= 0x9E):
|
|
@@ -104,7 +99,7 @@ def query_category(c: str) -> str | None:
|
|
|
104
99
|
elif (first_byte == 0x88 and second_byte >= 0x9F) or 0x89 <= first_byte <= 0x9F or 0xE0 <= first_byte <= 0xEF:
|
|
105
100
|
return 'double-byte-kanji'
|
|
106
101
|
else:
|
|
107
|
-
|
|
102
|
+
return None
|
|
108
103
|
|
|
109
104
|
|
|
110
105
|
def _build_alphabet_single_byte(byte_start: int, byte_end: int) -> list[str]:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: character-encoding-utils
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4
|
|
4
4
|
Summary: Some character encoding utils.
|
|
5
5
|
Author: TakWolf
|
|
6
6
|
Maintainer: TakWolf
|
|
@@ -8,7 +8,7 @@ License: MIT License
|
|
|
8
8
|
Project-URL: homepage, https://github.com/TakWolf/character-encoding-utils
|
|
9
9
|
Project-URL: source, https://github.com/TakWolf/character-encoding-utils
|
|
10
10
|
Project-URL: issues, https://github.com/TakWolf/character-encoding-utils/issues
|
|
11
|
-
Keywords: encoding
|
|
11
|
+
Keywords: encoding,gb2312,big5,shift-jis,ksx1001
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
13
13
|
Classifier: License :: OSI Approved :: MIT License
|
|
14
14
|
Classifier: Operating System :: OS Independent
|
|
@@ -60,7 +60,7 @@ assert big5.decode(bs) == 'abc中國'
|
|
|
60
60
|
```python
|
|
61
61
|
from character_encoding_utils import shiftjis
|
|
62
62
|
|
|
63
|
-
bs =
|
|
63
|
+
bs = shiftjis.encode('abc日本')
|
|
64
64
|
assert shiftjis.decode(bs) == 'abc日本'
|
|
65
65
|
```
|
|
66
66
|
|
|
@@ -45,6 +45,22 @@ def test_codec():
|
|
|
45
45
|
assert ord(c) == 0x5345
|
|
46
46
|
assert big5.decode(big5.encode(c)) == c
|
|
47
47
|
|
|
48
|
+
c = '/'
|
|
49
|
+
assert ord(c) == 0xFF0F
|
|
50
|
+
assert big5.decode(big5.encode(c)) == c
|
|
51
|
+
|
|
52
|
+
c = '\'
|
|
53
|
+
assert ord(c) == 0xFF3C
|
|
54
|
+
assert big5.decode(big5.encode(c)) == c
|
|
55
|
+
|
|
56
|
+
c = '∕'
|
|
57
|
+
assert ord(c) == 0x2215
|
|
58
|
+
assert big5.decode(big5.encode(c)) == c
|
|
59
|
+
|
|
60
|
+
c = '﹨'
|
|
61
|
+
assert ord(c) == 0xFE68
|
|
62
|
+
assert big5.decode(big5.encode(c)) == c
|
|
63
|
+
|
|
48
64
|
|
|
49
65
|
def test_query_code():
|
|
50
66
|
assert big5.query_code(' ') == 0xA140
|
|
@@ -129,3 +145,29 @@ def test_count():
|
|
|
129
145
|
assert big5.get_level_1_count() == 5401
|
|
130
146
|
assert big5.get_level_2_count() == 7652
|
|
131
147
|
assert big5.get_count() == 13461
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def test_unicode():
|
|
151
|
+
alphabet_other = []
|
|
152
|
+
alphabet_level_1 = []
|
|
153
|
+
alphabet_level_2 = []
|
|
154
|
+
alphabet = []
|
|
155
|
+
|
|
156
|
+
for code_point in range(0, 0x10FFFF + 1):
|
|
157
|
+
c = chr(code_point)
|
|
158
|
+
category = big5.query_category(c)
|
|
159
|
+
|
|
160
|
+
if category == 'other':
|
|
161
|
+
alphabet_other.append(c)
|
|
162
|
+
elif category == 'level-1':
|
|
163
|
+
alphabet_level_1.append(c)
|
|
164
|
+
elif category == 'level-2':
|
|
165
|
+
alphabet_level_2.append(c)
|
|
166
|
+
|
|
167
|
+
if category is not None:
|
|
168
|
+
alphabet.append(c)
|
|
169
|
+
|
|
170
|
+
assert len(alphabet_other) == big5.get_other_count()
|
|
171
|
+
assert len(alphabet_level_1) == big5.get_level_1_count()
|
|
172
|
+
assert len(alphabet_level_2) == big5.get_level_2_count()
|
|
173
|
+
assert len(alphabet) == big5.get_count()
|
|
@@ -103,3 +103,29 @@ def test_count():
|
|
|
103
103
|
assert gb2312.get_level_1_count() == 3755
|
|
104
104
|
assert gb2312.get_level_2_count() == 3008
|
|
105
105
|
assert gb2312.get_count() == 7445
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def test_unicode():
|
|
109
|
+
alphabet_other = []
|
|
110
|
+
alphabet_level_1 = []
|
|
111
|
+
alphabet_level_2 = []
|
|
112
|
+
alphabet = []
|
|
113
|
+
|
|
114
|
+
for code_point in range(0, 0x10FFFF + 1):
|
|
115
|
+
c = chr(code_point)
|
|
116
|
+
category = gb2312.query_category(c)
|
|
117
|
+
|
|
118
|
+
if category == 'other':
|
|
119
|
+
alphabet_other.append(c)
|
|
120
|
+
elif category == 'level-1':
|
|
121
|
+
alphabet_level_1.append(c)
|
|
122
|
+
elif category == 'level-2':
|
|
123
|
+
alphabet_level_2.append(c)
|
|
124
|
+
|
|
125
|
+
if category is not None:
|
|
126
|
+
alphabet.append(c)
|
|
127
|
+
|
|
128
|
+
assert len(alphabet_other) == gb2312.get_other_count()
|
|
129
|
+
assert len(alphabet_level_1) == gb2312.get_level_1_count()
|
|
130
|
+
assert len(alphabet_level_2) == gb2312.get_level_2_count()
|
|
131
|
+
assert len(alphabet) == gb2312.get_count()
|
|
@@ -22,6 +22,10 @@ def test_codec():
|
|
|
22
22
|
|
|
23
23
|
assert ksx1001.decode(ksx1001.encode(chr(0x3164))) == chr(0x3164)
|
|
24
24
|
|
|
25
|
+
for code_point in range(0xAC00, 0xD7A4):
|
|
26
|
+
c = chr(code_point)
|
|
27
|
+
assert ksx1001.decode(ksx1001.encode(c)) == c
|
|
28
|
+
|
|
25
29
|
|
|
26
30
|
def test_query_coord():
|
|
27
31
|
assert ksx1001.query_coord('ㆌ') == (4, 92)
|
|
@@ -107,3 +111,29 @@ def test_count():
|
|
|
107
111
|
assert ksx1001.get_syllable_count() == 2350
|
|
108
112
|
assert ksx1001.get_hanja_count() == 4888
|
|
109
113
|
assert ksx1001.get_count() == 8226
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def test_unicode():
|
|
117
|
+
alphabet_other = []
|
|
118
|
+
alphabet_syllable = []
|
|
119
|
+
alphabet_hanja = []
|
|
120
|
+
alphabet = []
|
|
121
|
+
|
|
122
|
+
for code_point in range(0, 0x10FFFF + 1):
|
|
123
|
+
c = chr(code_point)
|
|
124
|
+
category = ksx1001.query_category(c)
|
|
125
|
+
|
|
126
|
+
if category == 'other':
|
|
127
|
+
alphabet_other.append(c)
|
|
128
|
+
elif category == 'syllable':
|
|
129
|
+
alphabet_syllable.append(c)
|
|
130
|
+
elif category == 'hanja':
|
|
131
|
+
alphabet_hanja.append(c)
|
|
132
|
+
|
|
133
|
+
if category is not None:
|
|
134
|
+
alphabet.append(c)
|
|
135
|
+
|
|
136
|
+
assert len(alphabet_other) == ksx1001.get_other_count()
|
|
137
|
+
assert len(alphabet_syllable) == ksx1001.get_syllable_count()
|
|
138
|
+
assert len(alphabet_hanja) == ksx1001.get_hanja_count()
|
|
139
|
+
assert len(alphabet) == ksx1001.get_count()
|
|
@@ -94,3 +94,37 @@ def test_count():
|
|
|
94
94
|
assert shiftjis.get_double_byte_other_count() == 524
|
|
95
95
|
assert shiftjis.get_double_byte_kanji_count() == 6355
|
|
96
96
|
assert shiftjis.get_count() == 7070
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def test_unicode():
|
|
100
|
+
alphabet_single_byte_ascii_control = []
|
|
101
|
+
alphabet_single_byte_ascii_printable = []
|
|
102
|
+
alphabet_single_byte_half_width_katakana = []
|
|
103
|
+
alphabet_double_byte_other = []
|
|
104
|
+
alphabet_double_byte_kanji = []
|
|
105
|
+
alphabet = []
|
|
106
|
+
|
|
107
|
+
for code_point in range(0, 0x10FFFF + 1):
|
|
108
|
+
c = chr(code_point)
|
|
109
|
+
category = shiftjis.query_category(c)
|
|
110
|
+
|
|
111
|
+
if category == 'single-byte-ascii-control':
|
|
112
|
+
alphabet_single_byte_ascii_control.append(c)
|
|
113
|
+
elif category == 'single-byte-ascii-printable':
|
|
114
|
+
alphabet_single_byte_ascii_printable.append(c)
|
|
115
|
+
elif category == 'single-byte-half-width-katakana':
|
|
116
|
+
alphabet_single_byte_half_width_katakana.append(c)
|
|
117
|
+
elif category == 'double-byte-other':
|
|
118
|
+
alphabet_double_byte_other.append(c)
|
|
119
|
+
elif category == 'double-byte-kanji':
|
|
120
|
+
alphabet_double_byte_kanji.append(c)
|
|
121
|
+
|
|
122
|
+
if category is not None:
|
|
123
|
+
alphabet.append(c)
|
|
124
|
+
|
|
125
|
+
assert len(alphabet_single_byte_ascii_control) == shiftjis.get_single_byte_ascii_control_count()
|
|
126
|
+
assert len(alphabet_single_byte_ascii_printable) == shiftjis.get_single_byte_ascii_printable_count()
|
|
127
|
+
assert len(alphabet_single_byte_half_width_katakana) == shiftjis.get_single_byte_half_width_katakana_count()
|
|
128
|
+
assert len(alphabet_double_byte_other) == shiftjis.get_double_byte_other_count()
|
|
129
|
+
assert len(alphabet_double_byte_kanji) == shiftjis.get_double_byte_kanji_count()
|
|
130
|
+
assert len(alphabet) == shiftjis.get_count()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|