• Stars
    star
    4,946
  • Rank 8,471 (Top 0.2 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 10 years ago
  • Updated over 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Naive linter for English prose

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

More Repositories

1

angular-socket-io

Socket.IO component for AngularJS
JavaScript
1,520
star
2

angular-express-seed

A great starting point for writing AngularJS apps backed by an Express-powered node.js server.
JavaScript
1,517
star
3

ngmin

**deprecated** AngularJS Pre-minifier –> use ng-annotate –>
JavaScript
860
star
4

angular-socket-io-seed

A great starting point for writing AngularJS apps backed by a Socket.io-powered node.js server.
JavaScript
771
star
5

angular-express-blog

Example AngularJS app using an Express + Node.js backend.
JavaScript
600
star
6

angular-markdown-directive

AngularJS markdown directive using Showdown.js
JavaScript
568
star
7

angular-socket-io-im

Simple Instant Messaging app using AngularJS + Socket.IO
JavaScript
395
star
8

grunt-conventional-changelog

Grunt task for generating a changelog from git metadata
JavaScript
243
star
9

angular-modal

Simple AngularJS service for creating modals
JavaScript
233
star
10

angular-dragon-drop

Drag and Drop for AngularJS
JavaScript
225
star
11

grunt-ngmin

Grunt task for ngmin
JavaScript
170
star
12

angular-d3-demo

JavaScript
148
star
13

participating-in-open-source

141
star
14

mary-poppins

Keeps your GitHub PRs and issues tidy
JavaScript
123
star
15

briantford.com

sup
CSS
99
star
16

angular-phonegap-ready

JavaScript
95
star
17

brian-talks-about-angular-with-lots-of-data

Lightning talk about making Angular apps that deal with lots of data fast
89
star
18

adj-noun

Gives you a random adj-noun pair that you can use as a unique identifier
JavaScript
66
star
19

react-palm

Work in progress, docs forthcoming i promise
JavaScript
60
star
20

grunt-google-cdn

JavaScript
59
star
21

where-does-this-run

dynamic analysis tool to determine what environments arbitrary JavaScript will run in
JavaScript
51
star
22

angular-phonegap-notification

JavaScript
51
star
23

astral

AST tooling framework for JavaScript
JavaScript
47
star
24

angular-phonegap-geolocation

JavaScript
40
star
25

angular-unicorn-directive

Add a <unicorn></unicorn> to your app!
JavaScript
37
star
26

angular-phonegap-accelerometer

JavaScript
33
star
27

socialize

Use twitter as a key-value database
JavaScript
31
star
28

allthethings

ASCII Art
Shell
23
star
29

phone-kitten

WIP: angular "phonecat" tutorial redone with "The New Angular Routerâ„¢"
JavaScript
23
star
30

007

Returns a deep copy of an object with all functions converted to spies.
JavaScript
21
star
31

metahub

github metadata cache/mirror
JavaScript
20
star
32

kawaii

node module for determining if the contents of a string are cute
JavaScript
17
star
33

eshighlight

highlight javascript code based on an esprima AST
JavaScript
16
star
34

brian-talks-about-decorators

Lightning talk about AngularJS decorators
16
star
35

weasel-words

for detecting weasel words
JavaScript
15
star
36

alfred-cool-ascii-faces

15
star
37

passive-voice

for detecting passive voice
JavaScript
15
star
38

grunt-ddescribe-iit

Grunt task for checking that iit and ddescribe don't make it into committed code
JavaScript
14
star
39

grunt-merge-conflict

Grunt plugin for preventing you from accidentally comitting a merge conflict into your project
JavaScript
14
star
40

philosobot

Philosophical IRC bot powered by Node.js
JavaScript
12
star
41

qequire

Promisify modules as you require them.
JavaScript
12
star
42

quinoa

static site generator with versioning
JavaScript
12
star
43

socketron

An event-driven state machine for routing sockets.
JavaScript
12
star
44

poppins-pr-checklist

JavaScript
11
star
45

url-resolver.js

JavaScript
9
star
46

hitch-a-ride

Mobile app for EECS 441
9
star
47

pierogi

tasty alternative CLI for npm focused on discoverability
JavaScript
8
star
48

angular-yeoman-shopping

JavaScript
8
star
49

brian-talks-about-animations

For Devoxx 2013
CSS
8
star
50

angular-shopping-demo

JavaScript
7
star
51

sublime-text-javascript

My personal Sublime Text 3 JavaScript Package
Shell
7
star
52

meatmail

JavaScript
7
star
53

hitch-a-ride-client

Web-based client, shared by hitch-a-ride webapp and Phonegap-powered Android app
JavaScript
7
star
54

astral-angular-annotate

AngularJS DI annotation pass for astral
JavaScript
6
star
55

angular-enabled

complement to angular-disabled
JavaScript
6
star
56

socialjam

A collaborative music composition application created with the HTML5 canvas during Facebook Camp Hackathon. Demo available on Facebook. Server not included.
PHP
6
star
57

readme-good

naive judge of the quality of a markdown readme for an open source project
JavaScript
5
star
58

dmc13-slides

My slides for DMC13 - http://www.mobileconference.nl/
JavaScript
5
star
59

angular-futuristic-router

WIP
JavaScript
5
star
60

btford-env

my environment (settings, dotfiles, etc)
Emacs Lisp
5
star
61

poppins-check-cla

plugin for poppins-pr-checklist
JavaScript
4
star
62

poppins-prioritize

Mary Poppins plugin for prioritizing issues based on labels
JavaScript
4
star
63

angular-animate-shim

adds a `$animate` service for versions of Angular `1.1.x` and below
JavaScript
4
star
64

router-examples

WIP code/docs on routing in AngularJS 2.0
4
star
65

meatgame

JavaScript
4
star
66

astral-pass

JavaScript
4
star
67

angular-contact-manager

JavaScript
3
star
68

insertify

dumb string insertion util for node.js
JavaScript
3
star
69

fn-params

return the names of a function's parameters
JavaScript
3
star
70

poppins-check-commit

JavaScript
3
star
71

wrapgeni.us

CSS
3
star
72

clicli

makes literally any node module into a CLI tool
3
star
73

style-guide

my personal code style guide for all programming and natural languages
3
star
74

ideas

Collection of ideas for open source projects.
3
star
75

poppins-exec

mary-poppins plugin for running local commands in response to GitHub comments
JavaScript
2
star
76

j4y35

/\/\43k |_|R j4y35 /\/\04R 1337 d00d
JavaScript
2
star
77

github-prune-issues

CLI for closing old Github issues
JavaScript
2
star
78

npm-nginx-cache

nginx configs
Shell
2
star
79

fn-body

given a function, get its body as a string
JavaScript
2
star
80

poppins-mock

mocks for mary-poppins
JavaScript
2
star
81

webrebels2013

JavaScript
2
star
82

angular-simplify-module

minification tool to combine `angular.module`s
JavaScript
2
star
83

property-lolscriptors

patches property descriptors so you can configure "non-configurable" properties of objects
JavaScript
2
star
84

poppins-label

JavaScript
2
star
85

brian-talks-about-karma

JavaScript
2
star
86

google-music-shortcuts

Applescripts that can be bound to keys via Automator services to give Google Music global hotkeys in OS X
2
star
87

jsGameLib

JavaScript game library
JavaScript
2
star
88

sweet-observe

Poor man's object.observe to get object diffs with Sweet.js
JavaScript
2
star
89

multiple.singles

totally serious distributed dating site
CSS
2
star
90

ngmin-dynamic

JavaScript
1
star
91

intermediately-sized-hadron-collider

a tool for testing metaprogramming witchcraft
JavaScript
1
star
92

hitch-a-ride-android

Hitch-a-ride android app
JavaScript
1
star
93

end-runner

HTML5 Game for 2013 Wolverinesoft 48-Hour Hackathon
JavaScript
1
star
94

brian-talks-about-angulars-compiler

TODO
1
star
95

stylish-es6

This is me thinking out loud on writing good lookin' ES6.
1
star
96

what-was-i-doing

find uncommitted changes in a directory of git repos
JavaScript
1
star
97

package-good

naive linter for npm's package.json
JavaScript
1
star
98

sublime-text-user

My personal Sublime Text 2 Settings
1
star
99

file-manager.js

file manager, written in JS.
1
star
100

angular-poppins

AngularJS config files for Mary Poppins
JavaScript
1
star