English grammar and spell checking, backed by a Rustler NIF wrapping
Automattic Harper (harper-core).
Harper runs fully in-process: there is no server, no network call, and no
model to download. It is a pure, stateless function — text in, a list of
Harper.Lint structs out — so consuming apps link this library and call
lint/1 directly rather than going through a foundational RPC service.
(A Harper.Rpc.Behaviour remote seam exists for the rare app that would
rather offload linting to another node; the default is local.)
Harper is English only. Gate callers to English-authored content.
Offsets
Harper.Lint :start/:end are UTF-16 code-unit offsets into the
linted string, end-exclusive. UTF-16 (not Rust char / not byte) is chosen so
the offsets drop straight into JavaScript string indexing and editor APIs
(Quill, contenteditable ranges) without conversion on the client.
Dialects
English spelling/usage is dialect-sensitive ("colour" vs "color"). lint/2
takes a dialect (default :american, harper's own default). This is distinct
from a caller's i18n locale: the locale stays en, and the dialect only
selects the dictionary — see dialects/0 for the supported set.
Example
iex> Harper.lint("This is a clean sentence.")
[]
iex> Harper.lint("I love the colour blue.", :american) |> Enum.any?(&(&1.kind == "Spelling"))
true
iex> Harper.lint("I love the colour blue.", :british) |> Enum.any?(&(&1.kind == "Spelling"))
false
iex> Harper.lint("I write for tuhat daily.") |> Enum.any?(&(&1.kind == "Spelling"))
true
iex> Harper.lint("I write for tuhat daily.", :american, ["tuhat"]) |> Enum.any?(&(&1.kind == "Spelling"))
false
Summary
Functions
The English dialects harper supports, as atoms. First is the default.
Lints text as plain English prose and returns a list of Harper.Lint.
Functions
@spec dialects() :: [atom()]
The English dialects harper supports, as atoms. First is the default.
@spec lint(String.t(), atom(), [String.t()]) :: [Harper.Lint.t()]
Lints text as plain English prose and returns a list of Harper.Lint.
dialect is one of dialects/0 (default :american); an unknown value falls
back to American. custom_words is a list of words to treat as correctly
spelled (proper nouns, handles, brand terms) — this is the server-side
equivalent of "add to dictionary"; they are merged into the dictionary so they
are never flagged as misspellings.
The input is treated as plain text (not Markdown): pass the reader-visible
prose (e.g. quill.getText()), not source markup. Returns [] for clean
text. Runs on a dirty CPU scheduler, so a large document will not block the
BEAM's normal schedulers.