Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/btford/write-good
Naive linter for English prose
https://github.com/btford/write-good
Last synced: 5 days ago
JSON representation
Naive linter for English prose
- Host: GitHub
- URL: https://github.com/btford/write-good
- Owner: btford
- License: mit
- Created: 2014-04-25T00:15:20.000Z (over 10 years ago)
- Default Branch: master
- Last Pushed: 2022-04-13T07:26:47.000Z (over 2 years ago)
- Last Synced: 2024-10-14T15:25:43.789Z (20 days ago)
- Language: JavaScript
- Homepage:
- Size: 402 KB
- Stars: 4,952
- Watchers: 82
- Forks: 188
- Open Issues: 24
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-ccamel - btford/write-good - Naive linter for English prose (JavaScript)
- awesome-starred-test - btford/write-good - Naive linter for English prose (JavaScript)
- starred-awesome - write-good - Naive linter for English prose (JavaScript)
README
# write good [![Build Status](https://travis-ci.org/btford/write-good.svg?branch=master)](https://travis-ci.org/btford/write-good)
Naive linter for English prose for developers who can't write good and wanna learn to do other stuff good too.
## Use
```shell
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.
```javascript
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:
```javascript
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](https://github.com/TimKam/schreib-gut):```javascript
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:```javascript
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:
```shell
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:
```shell
npx write-good *.md
````write-good` takes a [glob](https://github.com/isaacs/node-glob) and prints suggestions to stdout:
```shell
$ write-good *.mdIn 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:
```shell
write-good *.md --weasel --so
```Or exclude checks like this:
```shell
write-good *.md --no-passive
```Or include checks like this:
```shell
# 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:
```shell
write-good --text="It should have been defined there."
```You can even supply multi-line text:
```shell
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:
```shell
write-good --text="It should have been defined there." --no-passive
```You can even fetch output from a remote file:
```shell
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:
```shell
write-good *.md --parse
```To specify a custom checks extension, for example [schreib-gut](https://github.com/TimKam/schreib-gut), run:
```shell
npm install -g schreib-gut
write-good *.md --checks=schreib-gut
```To view all available options use the ``--help`` option:
```shell
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"](https://en.wikipedia.org/wiki/E-Prime) 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](https://github.com/timkam/schreib-gut): A basic extension for
the German languageIf 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:```javascript
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``:```javascript
/**
* @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*):```javascript
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](https://www.docker.com). Using a pre-built [image from Dockerhub](https://hub.docker.com/r/hochzehn/write-good/), 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
* [shell script for avoiding "weasel words"](http://matt.might.net/articles/shell-scripts-for-passive-voice-weasel-words-duplicates/) – I based my initial implementation on this
* [Academic Writing Check](https://github.com/devd/Academic-Writing-Check) – a perl script similar to above
* [writegood mode](https://github.com/bnbeckwith/writegood-mode) for emacs
* [natural](https://github.com/NaturalNode/natural) – general purpose NLP toolkit in JavaScript
* [WordNet](http://wordnet.princeton.edu/) – lexical database of the English language
* [LanguageTool](https://languagetool.org/) – style and grammar checker implemented in Java### Prose
* [Elements of Style](http://www.bartleby.com/141/)
* [Flesch–Kincaid readability](http://en.wikipedia.org/wiki/Flesch%E2%80%93Kincaid_readability_test)
* [Fear and Loathing of the English passive](http://www.lel.ed.ac.uk/~gpullum/passive_loathing.pdf)
* [Words to Avoid in Educational Writing](http://css-tricks.com/words-avoid-educational-writing/)### Apps
This is not an endorsement.
These apps have similar functionality that you may find useful.* [Hemingway App](http://www.hemingwayapp.com/)
* [Grammarly](https://app.grammarly.com)## Other projects using write good
* [linter-write-good](https://github.com/gepoch/linter-write-good) for [Atom](https://atom.io/)
* [Write Good action](https://actions.getdrafts.com/a/1RA) for [Drafts](https://getdrafts.com) iOS App
* [Write Good Linter](https://marketplace.visualstudio.com/items?itemName=travisthetechie.write-good-linter) for [Visual Studio Code](https://code.visualstudio.com)
* [Vim ALE](https://github.com/w0rp/ale) realtime linter for [Vim](http://www.vim.org/) with included support for write-good.
* [Write Better](https://github.com/justiceo/write-better) A [Chrome extension](https://chrome.google.com/webstore/detail/write-better/nnnnnpmcdcloafmfkiihafnjidjkfmek) for Google Docs.
* [Statick](https://github.com/sscpac/statick-md) plugin to combine results with other linters.## License
MIT