emoji: add one-shot candidate search

This commit is contained in:
2026-08-11 22:24:59 +09:00
parent 82276bf37f
commit 0fff17c8b8
14 changed files with 891 additions and 346 deletions

View File

@@ -1,39 +1,71 @@
#!/bin/sh
#!/usr/bin/env python3
"""Write emoji.dict to stdout from a result-first UTF-8 TSV file."""
awk '
BEGIN { FS = "\t" }
/^$/ { next }
{
key = $1
val = $2
map[key] = val
for(i = 1; i < length(key); i++){
p = substr(key, 1, i)
if(!(p in map))
map[p] = p
}
}
END {
for(k in map)
print k "\t" map[k]
}
' $1 | sort -k1,1 > emoji.map
import sys
import unicodedata
from pathlib import Path
awk '
BEGIN { FS = "\t" }
/^$/ { next }
{
key = $1
val = $2
for(i = 1; i <= length(key); i++){
p = substr(key, 1, i)
dict[p] = dict[p] " " val
}
}
END {
for(p in dict){
sub(/^ /, "", dict[p])
print p "\t" dict[p]
}
}
' $1 | sort -k1,1 > emoji.dict
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())