textlint rule that flags inappropriate transliterations of Ukrainian place and person names and auto-fixes them to the correct forms. Promotes respectful, consistent naming across documentation.
  • TypeScript 88.1%
  • JavaScript 10.4%
  • Just 1.5%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-24 05:03:03 -03:00
.github build(gha): migrate to resolute 2026-06-17 21:28:17 -03:00
data feat: add dictionary JSON Schema validation 2026-07-25 15:15:06 -03:00
LICENSES chore(reuse): now compliant with version 3.3 of the REUSE Specification 2026-05-23 01:04:59 -03:00
scripts fix(style): unicorn warnings 2026-09-17 18:14:47 -03:00
src fix: kill surviving mutants and add mutation testing setup 2026-10-20 08:26:11 -03:00
tests fix: kill surviving mutants and add mutation testing setup 2026-10-20 08:26:11 -03:00
.editorconfig chore(editor): add .editorconfig, .prettierignore, .tool-versions 2026-05-27 00:55:04 -03:00
.gitignore fix: kill surviving mutants and add mutation testing setup 2026-10-20 08:26:11 -03:00
.prettierignore chore(editor): add .editorconfig, .prettierignore, .tool-versions 2026-05-27 00:55:04 -03:00
.prettierrc.yaml build: gate formatting on prettier 2026-10-15 22:37:01 -03:00
.tool-versions chore(editor): add .editorconfig, .prettierignore, .tool-versions 2026-05-27 00:55:04 -03:00
CITATION.cff chore(version): 1.5.14 2026-10-24 05:03:03 -03:00
CODE_OF_CONDUCT.md chore: sync prose with projectfile 2026-06-17 16:57:22 -03:00
cog.toml build: skip merge commits (sign fix) 2026-05-30 11:16:07 -03:00
CONTRIBUTING.md chore: make GitHub the primary repository and issue tracker 2026-10-11 15:25:14 -03:00
eslint.config.js chore: step tseslint up from recommended to strict 2026-10-15 22:37:02 -03:00
justfile feat: add dictionary JSON Schema validation 2026-07-25 15:15:06 -03:00
lefthook.yaml refactor: unify justfile, package.json and lefthook across projects 2026-07-08 16:26:36 -03:00
LICENSE chore(deps): eslint 10.8.0 2026-07-25 09:44:26 -03:00
package-lock.json chore(version): 1.5.14 2026-10-24 05:03:03 -03:00
package-lock.json.license chore(reuse): now compliant with version 3.3 of the REUSE Specification 2026-05-23 01:04:59 -03:00
package.json chore(version): 1.5.14 2026-10-24 05:03:03 -03:00
package.json.license chore(reuse): now compliant with version 3.3 of the REUSE Specification 2026-05-23 01:04:59 -03:00
projectfile.yaml chore(version): 1.5.14 2026-10-24 05:03:03 -03:00
README.md docs: fix README errors 2026-09-30 15:40:19 -03:00
SECURITY.md chore: sync prose with projectfile 2026-06-17 16:57:22 -03:00
stryker.config.mjs chore(license): reuse for stryker config 2026-10-20 09:57:40 -03:00
SUPPORT.md chore: make GitHub the primary repository and issue tracker 2026-10-11 15:25:14 -03:00
tsconfig.json build: enable strict TypeScript checking 2026-07-08 13:59:00 -03:00
tsconfig.json.license chore(reuse): now compliant with version 3.3 of the REUSE Specification 2026-05-23 01:04:59 -03:00
tsconfig.test.json refactor: rename test/ to tests/, unify build output under dist/, walk-up dictionary loader 2026-05-27 00:54:36 -03:00
tsconfig.test.json.license chore(reuse): now compliant with version 3.3 of the REUSE Specification 2026-05-23 01:04:59 -03:00
tsconfig.validate.json feat: add dictionary JSON Schema validation 2026-07-25 15:15:06 -03:00
tsconfig.validate.json.license feat: add dictionary JSON Schema validation 2026-07-25 15:15:06 -03:00

textlint-rule-ukraine

StandWithUkraine NPM Downloads NPM Version NPM Last Update NPM License PRs Welcome Libraries.io dependency status for GitHub repo

Pipeline CodeQL Known Vulnerabilities REUSE status

A textlint rule that detects and fixes russified spellings of Ukrainian geographical and personal names.

The corrections database is sourced from the SpellingUkraine project (MIT) and other sources.

Install

npm install --save-dev textlint textlint-rule-ukraine

Usage

Add the rule to your .textlintrc:

{
  "rules": {
    "ukraine": true
  }
}

Lint your Markdown files:

npx textlint "docs/**/*.md"

Auto-fix in place:

npx textlint --fix "docs/**/*.md"

Replacements are case-preserving:

Input Output
Bahmut Bakhmut
BAHMUT BAKHMUT
bahmut bakhmut
Artyomovsk Artemivsk

Text inside fenced code blocks and inline backtick spans is never touched.

Only three casing patterns are detected: ALL CAPS, all lower, and Title case. Mixed or irregular casing like aRTyOMovsK is left in canonical form (Artemivsk) instead of trying to mirror a garbled input — the fix is always clean Ukrainian orthography.

Options

The dictionary is split into tagged groups. geo is on by default; names and extra are opt-in.

Option Default Covers
geo true Place names (cities, regions, rivers)
names false Personal names (first names, public figures)
extra false Opinionated corrections (e.g. lowercase russia)
dictionaryOverrides [] Additional entries appended at runtime (see below)

To enable personal names checking:

{
  "rules": {
    "ukraine": { "names": true }
  }
}

To enable all groups:

{
  "rules": {
    "ukraine": { "names": true, "extra": true }
  }
}

To disable place names (e.g. when only personal names matter):

{
  "rules": {
    "ukraine": { "geo": false, "names": true }
  }
}

dictionaryOverrides

Append entries to the dictionary at runtime without patching data/dictionary.json inside node_modules. Each entry follows the same shape as the built-in dictionary and supports the same fields, including the exact flag (see Dictionary):

{
  "rules": {
    "ukraine": {
      "dictionaryOverrides": [
        { "wrong": ["Novoiavorivsk"], "correct": "Novoiavorivsk", "id": "novoiavorivsk", "tags": ["geo"] }
      ]
    }
  }
}

If an override declares the same wrong string as a built-in entry, the override wins (last-write-wins).

Dictionary

All entries live in data/dictionary.json. Each entry has the form:

{ "wrong": ["Bahmut", "Bahmoot"], "correct": "Bakhmut", "id": "bakhmut", "tags": ["geo"] }

By default replacements are case-preserving (Bahmut→Bakhmut, BAHMUT→BAKHMUT). Add "exact": true to always output correct verbatim regardless of input casing:

{ "wrong": ["Russia"], "correct": "russia", "id": "example", "exact": true, "tags": ["extra"] }

Override entries follow the same format — use tags to control which option group activates them.

Contributing

Dictionary improvements go directly in data/dictionary.json. Rule improvements (casing logic, AST handling, performance) go in src/.

License

MIT