82 lines
2.1 KiB
Python
Executable File
82 lines
2.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Extract single-character Hanja readings from libhangul data."""
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
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 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 single-character 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())
|