Repository files

Version 0.1.3 Updated Sep 27, 2026

The builder operates on four files in the consumer repository:

  • .typos-oxendict-base.toml is the untracked local cache of the shared dictionary.
  • .typos-oxendict-base.json is untracked refresh metadata.
  • typos.local.toml is the tracked repository-specific overlay.
  • typos.toml is the tracked, deterministic generated output.

The shared dictionary remains authoritative for estate-wide Oxford spellings. The local overlay is only for repository-specific accepted terms, corrections, patterns, and file exclusions. It must not weaken or contradict the shared policy.

Withdraw a shared ignore pattern

A repository that needs stricter checking than the shared policy provides may list exact shared ignore expressions under [patterns] remove in typos.local.toml:

schema = 1

[patterns]
remove = ['`[^`\n]+`']

Generation unions the shared and local ignore lists and then subtracts every entry in remove, so a withdrawn pattern never reaches typos.toml. Matching is by exact expression text. Removing a pattern the shared base does not contain is a harmless no-op, so an overlay does not break when shared policy retires a pattern. Listing the same expression under both ignore and remove is contradictory and is rejected. Withdrawals are policy metadata: they are never rendered into the generated configuration.

Confine an ignore pattern to Markdown

Available from 0.1.2. Some repositories want a mask to apply to prose but not to code. List those expressions under [patterns] markdown_only in typos.local.toml:

schema = 1

[patterns]
markdown_only = ['`[^`\n]+`', '(?s)```.*?```']

Each listed expression is withheld from the merged [default] ignore set, whether the shared dictionary or the local ignore list supplied it, and is rendered under a Markdown-scoped table instead:

[type.markdown]
extend-glob = [
    "*.md",
]
extend-ignore-re = [
    "(?s)```.*?```",
    "`[^`\n]+`",
]

The example above is cuprum's case. Its architecture decision record 009 requires Oxford spelling in source identifiers, so masking inline code spans and fenced blocks everywhere would let a misspelled identifier through. Under markdown_only the two masks relax the documentation checks alone, and Rust source is still checked in full.

An expression does not have to exist in the shared dictionary to be confined: listing one that is absent simply scopes it to Markdown. Entries are validated for regex safety exactly like ignore entries. remove withdraws a confined expression as well as an ignored one, so a repository can drop a Markdown mask the shared dictionary ships. Listing the same expression under both remove and markdown_only in one overlay is contradictory and is rejected.

See the migration guide for 0.1.2 for the steps a consumer whose legacy output carried a [type.markdown] table should take.

The [type.markdown] table is omitted entirely when the list is empty, so a repository that does not use the key generates byte-identical output.