mirror of
https://github.com/storytold/craft-libs.git
synced 2026-11-14 14:32:14 +00:00
The language-independent spelling mechanism from WordCraft's wordcraft-proof (storytold/craft-libs#30): the affix engine (AffixDict, with its compact serialized form), finding and loading an installed Hunspell .aff/.dic pair, and BCP 47 tag normalization. What was WordCraft policy is now a parameter: hunspell::Search carries the app's dictionaries-folder setting, its environment variable and its Windows folder name, instead of a global and hard-coded WordCraft names. Which languages an app proofs, suggestion ranking, grammar rules and user dictionaries stay in the apps. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
craft-proof
Spelling mechanism shared by the Craft apps: read a Hunspell .aff/.dic pair installed on the
system and check words against it. Seeded from WordCraft's wordcraft-proof; GridCraft,
DeckCraft and PdfCraft are the next consumers (storytold/craft-libs#30). No dependency on any
app or UI framework. Requires Rust 1.95.
let search = craft_proof::hunspell::Search::for_app("WordCraft");
if let Some((aff, dic)) = search.find(&["pl_PL", "pl"]) {
let dict = craft_proof::hunspell::load(&aff, &dic)?;
assert!(dict.check("kotami"));
}
# Ok::<(), String>(())
- Dictionaries are not bundled. Apps read what the OS, a package manager or LibreOffice installed; without one a language simply has no spelling check.
- Search order (
Search): the app's dictionaries folder setting,<APP>_DICTIONARIES, the app's folder under the Windows application-data folders, then the usual Hunspell and LibreOffice locations for the platform. Nothing on wasm. - Affix engine (
AffixDict): the Hunspell subset real dictionaries such as SJP.PL (Polish) and VERO (Brazilian Portuguese) use: one-character orFLAG UTF-8flags, prefixes and suffixes with conditions and cross products, continuation classes,FORBIDDENWORD, and theTRY/MAP/REPsuggestion tables. Compounding and long or numeric flags are rejected with an error rather than misread. - Compact form:
AffixDict::to_bytes/from_bytesstore a loaded dictionary deflated (Polish is under 1 MB), so an app can cache it instead of parsing the.aff/.diceach start.
What stays in each app: which languages it proofs, suggestion ranking and grammar rules per language, the user dictionary, and how marks are shown.