#!/usr/bin/env python3 """Write emoji.dict to stdout from a result-first UTF-8 TSV file.""" import sys import unicodedata from pathlib import Path SOURCE = Path(__file__).with_name("emoji.src") def fold(s): s = "".join(chr(ord(c) + 32) if "A" <= c <= "Z" else c for c in s) return unicodedata.normalize("NFC", s) def read(path): entries = [] with path.open(encoding="utf-8") as src: for lineno, raw in enumerate(src, 1): line = raw.rstrip("\r\n") if not line.strip() or line.lstrip().startswith("#"): continue fields = line.split("\t") if len(fields) < 2: raise ValueError(f"{path}:{lineno}: need a result and an alias") result = unicodedata.normalize("NFC", fields[0]) if not result or any(c.isspace() for c in result): raise ValueError(f"{path}:{lineno}: bad result") for field in fields[1:]: alias = fold(field) if not alias or alias != alias.strip(): raise ValueError(f"{path}:{lineno}: bad alias") entries.append((result, alias)) return entries def add(table, key, result): values = table.setdefault(key, []) if result not in values: values.append(result) def build(entries): exact = {} prefix = {} for result, alias in entries: for n in range(1, len(alias) + 1): add(exact if n == len(alias) else prefix, alias[:n], result) for key in sorted(exact.keys() | prefix.keys()): values = exact.get(key, []) + prefix.get(key, []) values = list(dict.fromkeys(values)) yield f"{key}\t{' '.join(values)}" def main(): if len(sys.argv) > 2: print(f"usage: {sys.argv[0]} [emoji.src]", file=sys.stderr) return 2 path = Path(sys.argv[1]) if len(sys.argv) == 2 else SOURCE try: for line in build(read(path)): print(line) except (OSError, UnicodeError, ValueError) as error: print(error, file=sys.stderr) return 1 return 0 if __name__ == "__main__": sys.exit(main())