Files
strans/map/libhangul2hanja
Hojun-Cho 2e53627b7d data(hanja): words, not only syllables
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.
2026-08-17 12:50:05 +09:00

79 lines
2.1 KiB
Python
Executable File

#!/usr/bin/env python3
"""Extract Hanja readings from libhangul data."""
import sys
from pathlib import Path
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 extract(src, name):
comments = []
entries = []
seen = set()
leading = True
for lineno, raw in enumerate(src, 1):
line = raw.rstrip("\r\n")
if not line:
continue
if line.startswith("#"):
if leading:
comments.append(line.rstrip())
continue
leading = False
fields = line.split(":")
if len(fields) != 3:
raise ValueError(f"{name}:{lineno}: need key:value:comment")
reading, hanja, _ = fields
if not ishangul(reading) or not ishanja(hanja):
continue
pair = (hanja, reading)
if pair in seen:
raise ValueError(f"{name}:{lineno}: duplicate Hanja reading")
seen.add(pair)
entries.append(pair)
if not entries:
raise ValueError(f"{name}: no Hanja readings")
return comments, entries
def main():
sys.stdin.reconfigure(encoding="utf-8")
sys.stdout.reconfigure(encoding="utf-8")
sys.stderr.reconfigure(encoding="utf-8")
if len(sys.argv) > 2:
print(f"usage: {sys.argv[0]} [libhangul-hanja.txt]", file=sys.stderr)
return 2
src = sys.stdin
name = "<stdin>"
try:
if len(sys.argv) == 2:
name = sys.argv[1]
src = Path(name).open(encoding="utf-8")
comments, entries = extract(src, name)
for line in comments:
print(line)
if comments:
print()
for hanja, reading in entries:
print(f"{hanja}\t{reading}")
except (OSError, UnicodeError, ValueError) as error:
print(error, file=sys.stderr)
return 1
finally:
if src is not sys.stdin:
src.close()
return 0
if __name__ == "__main__":
sys.exit(main())