feat(editor): spell & grammar checking (Chunk #7)

Offline spellcheck via hunspell compiled to WASM (runs fully in-browser),
plus optional self-hostable LanguageTool grammar/style checking.

- hunspell-wasm spell engine with bundled en_US dictionary (base64-decoded
  browser-safe via atob + TextDecoder)
- LanguageTool engine (self-hostable, docker compose snippet under
  docker/languagetool/)
- single decoration pipeline: spell + grammar hits merge into one squiggle
  layer (red=spelling, blue=grammar) with a side panel to jump/apply/ignore
  and add-to-dictionary
- useCheckService hook wired into WritingView; check.css loaded in main.tsx
- spell + grammar unit tests (30 editor tests green)

PLAN.md and CHUNK#7.md updated to reflect completion.
This commit is contained in:
Schwitzz
2026-10-28 17:13:23 -05:00
parent 836d82113b
commit 5c28a94813
15 changed files with 957 additions and 12 deletions
+14
View File
@@ -18,6 +18,8 @@ export function fontFamilyCss(value: FontFamily): string {
return found?.css ?? FONT_FAMILIES.at(0)?.css ?? "";
}
export type GrammarProvider = "local" | "languagetool";
export interface AppSettings {
theme: ThemeId;
accentColor: string;
@@ -31,6 +33,12 @@ export interface AppSettings {
autoSave: boolean;
focusMode: boolean;
typewriterMode: boolean;
// Spell & grammar (Chunk #7)
enableSpellcheck: boolean;
enableGrammarCheck: boolean;
spellcheckLanguage: string;
grammarProvider: GrammarProvider;
grammarApiKey: string;
}
export const DEFAULT_SETTINGS: AppSettings = {
@@ -46,6 +54,12 @@ export const DEFAULT_SETTINGS: AppSettings = {
autoSave: true,
focusMode: false,
typewriterMode: false,
// Spell & grammar (Chunk #7)
enableSpellcheck: true,
enableGrammarCheck: false,
spellcheckLanguage: "en_US",
grammarProvider: "local",
grammarApiKey: "",
};
const STORAGE_KEY = "pubscript.settings.v1";