Need help with write-good?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

btford
4.2K Stars 194 Forks MIT License 142 Commits 25 Opened issues

Description

Naive linter for English prose

Services available

!
?

Need anything else?

Contributors list

No Data

write good Build Status

Naive linter for English prose for developers who can't write good and wanna learn to do other stuff good too.

Use

npm install write-good

Important: Do not use this tool to be a jerk to other people about their writing.

API

writeGood
is a function that takes a string and returns an array of suggestions.
var writeGood = require('write-good');

var suggestions = writeGood('So the cat was stolen.');

// suggestions: // // [{ // reason: "omit 'So' from the beginning of sentences", // index: 0, offset: 2 // }, { // reason: "'was stolen' is passive voice", // index: 11, offset: 10 // }]

writeGood
takes an optional second argument that allows you to disable certain checks.

You can disable checking for passive voice like this:

var writeGood = require('write-good');

var suggestions = writeGood('So the cat was stolen', { passive: false}); // suggestions: []

You can use the second argument's

checks
property to pass in custom checks instead of
write-good
's default linting configuration. Like this, you can check non-English documents, for example with the linter extension for German, schreib-gut:
var schreibGut = require('schreib-gut');

writeGood('Aller Wahrscheinlichkeit nach können Entwickler nicht gut schreiben', { weasel-words: false, checks: schreibGut});

// suggestions // [{index : 0, offset : 29, reason : '"Aller Wahrscheinlichkeit nach" is wordy or unneeded' }]

You can use the second argument's

whitelist
property to pass in a list of strings to whitelist from suggestions. For example, normally
only
would be picked up as a bad word to use, but you might want to exempt
read-only
from that:
var writeGood = require('write-good');

var suggestions = writeGood('Never write read-only sentences.'); // suggestions: [{ index: 17, offset: 4, reason: '"only" can weaken meaning' }]

var filtered = writeGood('Never write read-only sentences.', { whitelist: ['read-only'] }); // filtered: []

CLI

You can use

write-good
as a command-line tool by installing it globally:
npm install -g write-good

If you have npm version 5.2.0 or later installed, you can use npx to run write-good without installing it:

npx write-good *.md

write-good
takes a glob and prints suggestions to stdout:
$ write-good *.md

In README.md

= writeGood('So the cat was stolen.'); ^^^^^^^^^^ "was stolen" is passive voice on line 20 at column 40


// suggestion: "'was stolen' is passive voice", ^^^^^^^^^^ "was stolen" is passive voice on line 28 at column 19

You can run just specific checks like this:

write-good *.md --weasel --so

Or exclude checks like this:

write-good *.md --no-passive

Or include checks like this:

# E-Prime is disabled by default.
write-good *.md --yes-eprime

Note: The

--yes
prefix only works for E-Prime, because the other checks are included by default, anyway.

You can run just with text without supplying files:

write-good --text="It should have been defined there."

You can even supply multi-line text:

write-good --text="I can't see a problem there that's not been defined yet.
Should be defined again."

You can also pass other arguments:

write-good --text="It should have been defined there." --no-passive

You can even fetch output from a remote file:

write-good --text="$(curl https://raw.githubusercontent.com/btford/write-good/master/README.md)"

Use the

--parse
option to activate parse-happy output and a more conventional Unix exit code:
write-good *.md --parse

To specify a custom checks extension, for example schreib-gut, run:

npm install -g schreib-gut
write-good *.md --checks=schreib-gut

To view all available options use the

--help
option:
write-good --help

Checks

You can disable any combination of the following by providing a key with value

false
as the second argument to
writeGood
.

passive

Checks for passive voice.

illusion

Checks for lexical illusions – cases where a word is repeated.

so

Checks for

so
at the beginning of the sentence.

thereIs

Checks for

there is
or
there are
at the beginning of the sentence.

weasel

Checks for "weasel words."

adverb

Checks for adverbs that can weaken meaning: really, very, extremely, etc.

tooWordy

Checks for wordy phrases and unnecessary words.

cliches

Checks for common cliches.

eprime

Checks for "to-be" verbs. Disabled by default

Extensions

Users can create their own

write-good
language checks. As described above, you can specify such extensions when running
write-good
on the command line or calling it in your JavaScript code.

The following 3rd-party

write-good
extensions are available:
  • schreib-gut: A basic extension for the German language

If you know of any

write-good
extensions that are not in this list, please open a pull request!

Interface

An extension is a Node.js module that exposes an object containing a check function (

fn
) and an
explanation
string for each new check:
module.exports = {
  check1: {
    fn: function(text) {
      …
    },
    explanation: '…'
  },
  check2: {
    fn: function(text) {
      …
    },
    explanation: '…'
  }
}

Each check function takes a string input and determines a list of style violation objects, each with an

index
and an
offset
:
/**
* @param {text} text  Input text
* @return {{index:number, offset:number}[]}  List of all violations
*/

The

index
defines the position of the match in the input text, whereas the
offset
specifies the length of the match.

The following example extension provides a check that determines if the input text contains a set of forbidden terms (Tom Riddle and Voldemort):

module.exports = {
  voldemort: {
    fn: function (text) {
      var positives = ['Tom Riddle', 'Voldemort']
      var re = new RegExp('\\b(' + positives.join('|') + ')\\b', 'gi');
      var suggestions = [];
      while (match = re.exec(text)) {
        suggestions.push({
          index: match.index,
          offset: match[0].length,
        });
      }
      return suggestions;
    },
    explanation: 'You must not name Him-Who-Must-Not-Be-Named'
  }
}

Docker

From Dockerhub

You can also run this application in Docker. Using a pre-built image from Dockerhub, the write-good can be run with this command:

docker run --rm --volume $PWD:/app hochzehn/write-good *.md

Building locally

Or you can first build the image locally:

docker build -t btford/write-good .

And then run using:

docker run -it --rm -v "$(pwd)":/srv/app -w /srv/app btford/write-good:latest *.md

See also

I came across these resources while doing research to make this module. They might be helpful.

Code

Prose

Apps

This is not an endorsement. These apps have similar functionality that you may find useful.

Other projects using write good

License

MIT

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.