The import kept only readings of one syllable, so the Hanja search could convert 한 but never 한자, 학교, or 대한민국 — the conversion every other Korean input method offers. libhangul's table has 187k readings; both scripts now keep them all, and the search finds a word as readily as a syllable. The daemon pays for it: 24 MB instead of 12, and 170 ms to start instead of 30.
78 lines
2.3 KiB
Python
Executable File
78 lines
2.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Write hanja.dict from a Hanja-per-row UTF-8 source."""
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
SOURCE = Path(__file__).with_name("hanja.src")
|
|
MAXCANDIDATES = 128
|
|
|
|
|
|
def ishangul(s):
|
|
return s != "" and all(0xAC00 <= ord(c) <= 0xD7A3 for c in s)
|
|
|
|
|
|
def ishanja(s):
|
|
return s != "" and all(0x3400 <= ord(c) <= 0x4DBF
|
|
or 0x4E00 <= ord(c) <= 0x9FFF
|
|
or 0xF900 <= ord(c) <= 0xFAFF for c in s)
|
|
|
|
|
|
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 BMP Hanja")
|
|
if not ishangul(reading):
|
|
raise ValueError(f"{path}:{lineno}: need Hangul syllables")
|
|
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():
|
|
sys.stdout.reconfigure(encoding="utf-8")
|
|
sys.stderr.reconfigure(encoding="utf-8")
|
|
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())
|