hanja: add single-character dictionary data
This commit is contained in:
78
map/mkhanja
Executable file
78
map/mkhanja
Executable file
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Write hanja.dict from a one-Hanja-per-row UTF-8 source."""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
SOURCE = Path(__file__).with_name("hanja.src")
|
||||
MAXCANDIDATES = 32
|
||||
|
||||
|
||||
def ishangul(s):
|
||||
return len(s) == 1 and 0xAC00 <= ord(s) <= 0xD7A3
|
||||
|
||||
|
||||
def ishanja(s):
|
||||
if len(s) != 1:
|
||||
return False
|
||||
c = ord(s)
|
||||
return (0x3400 <= c <= 0x4DBF
|
||||
or 0x4E00 <= c <= 0x9FFF
|
||||
or 0xF900 <= c <= 0xFAFF)
|
||||
|
||||
|
||||
def read(path):
|
||||
comments = []
|
||||
table = {}
|
||||
seen = set()
|
||||
leading = True
|
||||
with path.open(encoding="utf-8") as src:
|
||||
for lineno, raw in enumerate(src, 1):
|
||||
line = raw.rstrip("\r\n")
|
||||
if not line:
|
||||
continue
|
||||
if line.startswith("#"):
|
||||
if leading:
|
||||
comments.append(";;" + line[1:])
|
||||
continue
|
||||
leading = False
|
||||
fields = line.split("\t")
|
||||
if len(fields) != 2:
|
||||
raise ValueError(f"{path}:{lineno}: need Hanja<TAB>reading")
|
||||
hanja, reading = fields
|
||||
if not ishanja(hanja):
|
||||
raise ValueError(f"{path}:{lineno}: need one BMP Hanja character")
|
||||
if not ishangul(reading):
|
||||
raise ValueError(f"{path}:{lineno}: need one Hangul syllable")
|
||||
pair = (hanja, reading)
|
||||
if pair in seen:
|
||||
raise ValueError(f"{path}:{lineno}: duplicate Hanja reading")
|
||||
seen.add(pair)
|
||||
table.setdefault(reading, []).append(hanja)
|
||||
if not seen:
|
||||
raise ValueError(f"{path}: no Hanja readings")
|
||||
return comments, table
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) > 2:
|
||||
print(f"usage: {sys.argv[0]} [hanja.src]", file=sys.stderr)
|
||||
return 2
|
||||
path = Path(sys.argv[1]) if len(sys.argv) == 2 else SOURCE
|
||||
try:
|
||||
comments, table = read(path)
|
||||
for line in comments:
|
||||
print(line)
|
||||
if comments:
|
||||
print()
|
||||
for reading, candidates in table.items():
|
||||
print(f"{reading}\t{' '.join(candidates[:MAXCANDIDATES])}")
|
||||
except (OSError, UnicodeError, ValueError) as error:
|
||||
print(error, file=sys.stderr)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user