Repo: github.com/mova-ITS/cangjie-dictionary
(crate name stays cangjie).
A CangJie (CJ5) dictionary: bidirectional lookup, code ↔ hieroglyph.
- hi→co: given a character, return its Cangjie code(s) and provenance. A char can
have more than one core code — ~10.6% do (e.g.
丅→mlandxml). - co→hi: given a code, return the character(s) that produce it.
Both directions are one-to-many. Built over a hardened, cross-verified CJ5 table
(~20.9k CJK-BMP chars). Source: data/cangjie_bmp.tsv.
Packed hi+co for the browser: data/cangjie.bin (cargo run --bin pack).
| IN | TSV text: char␉code␉trust␉sources (one row per core code) |
| OUT (hi→co) | &[Entry] — hi, co, trust, sources |
| OUT (co→hi) | &[char] |
| Query | one non-ASCII glyph → codes; otherwise → characters |
trust / sources explain why a code is in the core table (CJ5 consensus first;
Unihan corroborates, never overrides). The variants sidecar is not loaded here.
use cangjie::{bundled_tsv, Dict};
let dict = Dict::load(bundled_tsv())?;
let _ = dict.codes_of('一'); // hi → co (&[Entry])
let _ = dict.chars_for("m"); // co → hi (&[char])
let _ = dict.query("一"); // Hits::Codes / Hits::Chars
let _ = dict.codes_matching("v-c"); // pattern over codesDict::parse(&str) builds from TSV. Dict::from_bytes / load_bin load the packed indexes.
Whole code is 1–5 letters. Not edit-distance.
| Atom | Meaning |
|---|---|
| letter | that unit, that place |
- |
exactly one letter |
* |
zero or more letters |
Examples: A* starts with A · *A ends with A · V-C is exactly V + one + C · A-* is A + one + rest · A-*-B is the same atoms composed.
Plain letters with no -/* are an exact code (mg ≠ prefix; use mg*).
cargo run -- 一
cargo run -- m
cargo run --features brand -- m # green mova.page wordmarkExpect 一 → ["m"] and m → ['一'] (plus other chars that share the code).
Optional second argument: path to another TSV.
Feature wasm (no std::fs in the module). JS fetches cangjie.bin, then WasmDict.parse_bin.
cargo run --bin pack
wasm-pack build --target web --features wasmpkg/ is generated — do not commit it. JS API: parse_bin, parse (TSV), codes_of, chars_for, codes_matching, mask_for.
- Dual index:
char → Vec<Entry>andcode → Vec<char>, built once. - Parse is pure;
loadis a thinread_to_stringwrapper. - Core table: CJ5 consensus first (Jack Chow · RIME · base). Unihan corroborates, never overrides. Variants sidecar is not loaded.