📝 alex — Catch insensitive, inconsiderate writing.
Whether your own or someone else’s writing, alex helps you find gender favouring, polarising, race related, religion inconsiderate, or other unequal phrasing in text.
For example, when We’ve confirmed his identity
is given, alex will warn
you and suggest using their
instead of his
.
Give alex a spin on the Online demo ».
- Helps to get better at considerate writing
- Catches many possible offences
- Suggests helpful alternatives
- Reads plain-text, HTML, and markdown as input
- Stylish
$ npm install alex --global
Using yarn:
$ yarn global add alex
Or you can follow this step-by-step tutorial: Setting up alex in your project
- Checks
- Integrations
- Ignoring files
- Control
- Configuration
- CLI
- API
- Workflow
- FAQ
- Contribute
- Origin story
- Acknowledgments
- License
alex checks things such as:
- Gendered work-titles, such as suggesting
garbage collector
forgarbageman
andproprietor
forlandlord
- Gendered proverbs, such as suggesting
bravely
forlike a man
, orcourteous
forladylike
. - Ablist language, such as suggesting
person with learning disabilities
forlearning disabled
- Condescending language, such as warning for
obviously
,everyone knows
, etc - Intolerant phrasing, such as suggesting
primary
andreplica
instead ofmaster
andslave
- Profanities, such as
butt
🍑
…and much more!
See retext-equality
and retext-profanities
for
all rules.
alex ignores words meant literally, so “he”
, He — ...
, and the
like are not warned about.
- Atom —
get-alex/atom-linter-alex
- Sublime —
sindresorhus/SublimeLinter-contrib-alex
- Visual Studio Code —
shinnn/vscode-alex
- Gulp —
dustinspecker/gulp-alex
- Slack —
keoghpe/alex-slack
- Ember —
yohanmishkin/ember-cli-alex
- Probot —
swinton/linter-alex
- Vim —
w0rp/ale
- Browser extension —
skn0tt/alex-browser-extension
- Contentful -
stefanjudis/alex-js-contentful-ui-extension
The CLI searches for files with a markdown or text extension when given
directories (so $ alex .
will find readme.md
and path/to/file.txt
).
To prevent files from being found, create an .alexignore
file.
The CLI will sometimes search for files.
To prevent files from being found, add a file named .alexignore
in one of the
directories above the current working directory (the place you run alex
from).
The format of these files is similar to .eslintignore
(which
is in turn similar to .gitignore
files).
For example, when working in ~/path/to/place
, the ignore file can be in
place
, but also in ~
.
The ignore file for this project itself looks like this:
# `node_modules` is ignored by default.
example.md
Sometimes alex makes mistakes:
A message for this sentence will pop up.
Yields:
readme.md
1:15-1:18 warning `pop` may be insensitive, use `parent` instead dad-mom retext-equality
⚠ 1 warning
HTML comments in markdown can be used to ignore them:
<!--alex ignore dad-mom-->
A message for this sentence will **not** pop up.
Yields:
readme.md: no issues found
ignore
turns off messages for the thing after the comment (in this case, the
paragraph).
It’s also possible to turn off messages after a comment by using disable
, and,
turn those messages back on using enable
:
<!--alex disable dad-mom-->
A message for this sentence will **not** pop up.
A message for this sentence will also **not** pop up.
Yet another sentence where a message will **not** pop up.
<!--alex enable dad-mom-->
A message for this sentence will pop up.
Yields:
readme.md
9:15-9:18 warning `pop` may be insensitive, use `parent` instead dad-mom retext-equality
⚠ 1 warning
Multiple messages can be controlled in one go:
<!--alex disable he-her his-hers dad-mom-->
…and all messages can be controlled by omitting all rule identifiers:
<!--alex ignore-->
You can control alex through .alexrc
configuration files:
{
"allow": ["boogeyman-boogeywoman"]
}
…you can use YAML if the file is named .alexrc.yml
or .alexrc.yaml
:
allow:
- dad-mom
…you can also use JavaScript if the file is named .alexrc.js
:
exports.profanitySureness = Math.floor(Math.random() * 3)
…and finally it is possible to use an alex
field in package.json
:
{
…
"alex": {
"noBinary": true
},
…
}
The allow
field should be an array of rules (the default is []
).
The noBinary
field should be a boolean (the default is false
).
When turned on (true
), pairs such as he and she
, garbageman or garbagewoman
, are seen as errors.
When turned off (false
, the default), such pairs are seen as OK.
The profanitySureness
field is a number (the default is 0
).
We use cuss, which has a dictionary of words that have a rating between 0
and 2 of how likely it is that a word or phrase is a profanity (not how “bad” it
is):
Rating | Use as a profanity | Use in clean text | Example |
---|---|---|---|
2 | likely | unlikely | asshat |
1 | maybe | maybe | addict |
0 | unlikely | likely | beaver |
The profanitySureness
field is the minimum rating (including) that you want to
check for.
If you set it to 1
(maybe) then it will warn for level 1
and 2
(likely)
profanities, but not for level 0
(unlikely).
Let’s say example.md
looks as follows:
The boogeyman wrote all changes to the **master server**. Thus, the slaves
were read-only copies of master. But not to worry, he was a cripple.
Now, run alex on example.md
:
$ alex example.md
Yields:
example.md
1:5-1:14 warning `boogeyman` may be insensitive, use `boogeymonster` instead boogeyman-boogeywoman retext-equality
1:42-1:48 warning `master` / `slaves` may be insensitive, use `primary` / `replica` instead master-slave retext-equality
1:69-1:75 warning Don’t use `slaves`, it’s profane slaves retext-profanities
2:52-2:54 warning `he` may be insensitive, use `they`, `it` instead he-she retext-equality
2:61-2:68 warning `cripple` may be insensitive, use `person with a limp` instead gimp retext-equality
⚠ 5 warnings
See $ alex --help
for more information.
When no input files are given to alex, it searches for files in the current directory,
doc
, anddocs
. If--html
is given, it searches forhtm
andhtml
extensions. Otherwise, it searches fortxt
,text
,md
,mkd
,mkdn
,mkdown
,ron
, andmarkdown
extensions.
npm:
$ npm install alex --save
alex is also available as an AMD, CommonJS, and globals module, uncompressed and compressed.
Check markdown (ignoring syntax).
value
(VFile
orstring
) — Markdown documentconfig
(Object
, optional) — See the Configuration section
VFile
.
You are probably interested in its messages
property, as
shown in the example above, because it holds the possible violations.
alex('We’ve confirmed his identity.').messages
Yields:
[
[1:17-1:20: `his` may be insensitive, when referring to a person, use `their`, `theirs`, `them` instead] {
message: '`his` may be insensitive, when referring to a ' +
'person, use `their`, `theirs`, `them` instead',
name: '1:17-1:20',
reason: '`his` may be insensitive, when referring to a ' +
'person, use `their`, `theirs`, `them` instead',
line: 1,
column: 17,
location: { start: [Object], end: [Object] },
source: 'retext-equality',
ruleId: 'her-him',
fatal: false,
actual: 'his',
expected: [ 'their', 'theirs', 'them' ]
}
]
Check HTML (ignoring syntax).
Similar to alex()
and alex.text()
).
value
(VFile
orstring
) — HTML documentconfig
(Object
, optional) — See the Configuration section
alex.html('<p class="black">He walked to class.</p>').messages
Yields:
[
[1:18-1:20: `He` may be insensitive, use `They`, `It` instead] {
message: '`He` may be insensitive, use `They`, `It` instead',
name: '1:18-1:20',
reason: '`He` may be insensitive, use `They`, `It` instead',
line: 1,
column: 18,
location: { start: [Object], end: [Object] },
source: 'retext-equality',
ruleId: 'he-she',
fatal: false,
actual: 'He',
expected: [ 'They', 'It' ]
}
]
Check plain text (so syntax is checked).
Similar to alex()
and alex.html()
).
value
(VFile
orstring
) — Text documentconfig
(Object
, optional) — See the Configuration section
alex('The `boogeyman`.').messages // => []
alex.text('The `boogeyman`.').messages
Yields:
[
[1:6-1:15: `boogeyman` may be insensitive, use `boogeymonster` instead] {
message: '`boogeyman` may be insensitive, use `boogeymonster` instead',
name: '1:6-1:15',
reason: '`boogeyman` may be insensitive, use `boogeymonster` instead',
line: 1,
column: 6,
location: Position { start: [Object], end: [Object] },
source: 'retext-equality',
ruleId: 'boogeyman-boogeywoman',
fatal: false,
actual: 'boogeyman',
expected: [ 'boogeymonster' ]
}
]
The recommended workflow is to add alex to package.json
and to run it with
your tests in Travis.
You can opt to ignore warnings through alexrc files and control comments.
A package.json
file with npm scripts, and additionally using
AVA for unit tests, could look like so:
{
"scripts": {
"test-api": "ava",
"test-doc": "alex",
"test": "npm run test-api && npm run test-doc"
},
"devDependencies": {
"alex": "^1.0.0",
"ava": "^0.1.0"
}
}
If you’re using Travis for continuous integration, set up something like the
following in your .travis.yml
:
script:
- npm test
+- alex --diff
Make sure to still install alex though!
If the --diff
flag is used, and Travis is detected, lines that are not changes
in this push are ignored.
Using this workflow, you can merge PRs if it has warnings, and then if someone
edits an entirely different file, they won’t be bothered about existing
warnings, only about the things they added!
Not a question. And yeah, alex isn’t very smart. People are much better at this. But people make mistakes, and alex is there to help.
See contributing.md
on how to get “X” checked by alex.
It’s a nice unisex name, it was free on npm, I like it! 😄
See contributing.md
in get-alex/.github
for ways
to get started.
See support.md
for ways to get help.
This project has a Code of conduct. By interacting with this repository, organisation, or community you agree to abide by its terms.
Thanks to @iheanyi for raising the problem and @sindresorhus for inspiring me (@wooorm) to do something about it.
When alex launched, it got some traction on twitter and producthunt. Then there was a lot of press coverage.
Preliminary work for alex was done in 2015. The project was authored by @wooorm.
Lot’s of people helped since!