Top Related Projects
:pencil: A markup-aware linter for prose built with speed and extensibility in mind.
A linter for prose.
Catch insensitive, inconsiderate writing
natural language processor powered by plugins part of the @unifiedjs collective
The pluggable natural language linter for text and markdown.
State of the Art Natural Language Processing
Quick Overview
Write-good is a linter for English prose, designed to help improve writing style. It's a Node.js module that provides suggestions for simplifying and clarifying your text, focusing on common writing issues such as passive voice, redundant words, and overly complex phrases.
Pros
- Easy to use and integrate into existing workflows
- Customizable rules to fit specific writing styles or preferences
- Can be used as a command-line tool or as a module in Node.js applications
- Supports multiple languages through community-contributed extensions
Cons
- May produce false positives or miss context-dependent issues
- Limited in scope compared to more comprehensive writing tools
- Requires some technical knowledge to set up and use effectively
- Not suitable for analyzing highly technical or specialized writing
Code Examples
- Basic usage as a Node.js module:
const writeGood = require('write-good');
const suggestions = writeGood('So the cat was stolen.');
console.log(suggestions);
This code analyzes a simple sentence and returns suggestions for improvement.
- Using specific checks:
const writeGood = require('write-good');
const text = 'Really, this is just a test.';
const suggestions = writeGood(text, { weasel: false });
console.log(suggestions);
This example disables the "weasel words" check when analyzing the text.
- Analyzing text from a file:
const fs = require('fs');
const writeGood = require('write-good');
const text = fs.readFileSync('myfile.txt', 'utf8');
const suggestions = writeGood(text);
console.log(suggestions);
This code reads text from a file and analyzes it using write-good.
Getting Started
To use write-good in your project, follow these steps:
-
Install the package:
npm install write-good
-
Use it in your Node.js script:
const writeGood = require('write-good'); const text = 'Your text to analyze goes here.'; const suggestions = writeGood(text); console.log(suggestions);
-
Run your script:
node your-script.js
This will output an array of suggestions for improving your text.
Competitor Comparisons
:pencil: A markup-aware linter for prose built with speed and extensibility in mind.
Pros of Vale
- More comprehensive and customizable linting rules
- Supports multiple markup formats (Markdown, AsciiDoc, HTML, etc.)
- Integrates with various text editors and CI/CD pipelines
Cons of Vale
- Steeper learning curve due to more complex configuration
- Requires more setup and maintenance compared to Write-good
- May be overkill for simple writing tasks or small projects
Code Comparison
Vale configuration example:
StylesPath = styles
MinAlertLevel = suggestion
[*.md]
BasedOnStyles = Vale, proselint
Write-good usage example:
var writeGood = require('write-good');
var suggestions = writeGood('So the cat was stolen.');
console.log(suggestions);
Both tools aim to improve writing quality, but Vale offers more advanced features and customization options, while Write-good provides a simpler, more straightforward approach to identifying common writing issues.
A linter for prose.
Pros of proselint
- More comprehensive set of writing checks, covering a wider range of style and grammar issues
- Supports multiple languages and file formats (e.g., Markdown, reStructuredText, HTML)
- Provides detailed explanations and suggestions for each detected issue
Cons of proselint
- Slower performance compared to write-good, especially on larger documents
- More complex setup and configuration process
- May produce more false positives due to its extensive rule set
Code Comparison
proselint:
from proselint.tools import lint
text = "The quick brown fox jumps over the lazy dog."
suggestions = lint(text)
write-good:
var writeGood = require('write-good');
var suggestions = writeGood('The quick brown fox jumps over the lazy dog.');
Both tools provide similar functionality for analyzing text, but proselint offers a more comprehensive analysis at the cost of increased complexity and potentially slower performance. write-good is simpler to use and faster, but may not catch as many writing issues. The choice between the two depends on the specific needs of the project and the desired balance between thoroughness and speed.
Catch insensitive, inconsiderate writing
Pros of alex
- Focuses on inclusive and respectful language, addressing gender, race, and other sensitive topics
- Supports multiple languages and file formats (Markdown, HTML, plain text)
- Integrates well with various text editors and CI/CD pipelines
Cons of alex
- May produce more false positives due to its broad scope of language analysis
- Requires more configuration to customize rules for specific use cases
- Can be overly sensitive in certain contexts, potentially flagging non-problematic language
Code Comparison
alex:
import alex from 'alex';
alex('His network was set up by John.').messages;
// [{ message: '`His` may be insensitive, use `Their`, `Theirs`, `Them` instead' }]
write-good:
var writeGood = require('write-good');
var suggestions = writeGood('So the cat was stolen.');
// [{ reason: '"So" adds no meaning', index: 0, offset: 2 }]
Both tools aim to improve writing quality, but they focus on different aspects. alex emphasizes inclusive language and avoiding potentially offensive terms, while write-good concentrates on general writing style and clarity. The choice between them depends on the specific needs of the project and the type of content being analyzed.
natural language processor powered by plugins part of the @unifiedjs collective
Pros of retext
- More comprehensive and modular ecosystem with various plugins
- Supports multiple natural languages beyond English
- Offers a unified text processing system for various tasks
Cons of retext
- Steeper learning curve due to its more complex architecture
- May be overkill for simple writing style checks
- Requires more setup and configuration for basic use cases
Code comparison
write-good:
var writeGood = require('write-good');
var suggestions = writeGood('So the cat was stolen.');
console.log(suggestions);
retext:
var retext = require('retext');
var english = require('retext-english');
var simplify = require('retext-simplify');
retext()
.use(english)
.use(simplify)
.process('So the cat was stolen.')
.then((file) => console.log(String(file)));
Summary
write-good is a simpler, more straightforward tool for quick writing style checks, primarily focused on English. It's easy to set up and use out of the box, making it ideal for basic writing improvement tasks.
retext, on the other hand, is a more powerful and flexible text processing system. It offers a wider range of capabilities through its plugin ecosystem and supports multiple languages. While it requires more setup and has a steeper learning curve, it provides a more comprehensive solution for various text analysis and manipulation tasks.
Choose write-good for quick, simple writing checks, and retext for more advanced, customizable text processing needs.
The pluggable natural language linter for text and markdown.
Pros of textlint
- Highly extensible with a plugin system, allowing for custom rules and integrations
- Supports multiple languages and file formats beyond just English text
- Provides a more comprehensive set of default rules for various writing styles
Cons of textlint
- Steeper learning curve due to its more complex configuration options
- Requires more setup and configuration to get started compared to write-good
- May be overkill for simple writing tasks or quick checks
Code Comparison
write-good:
var writeGood = require('write-good');
var suggestions = writeGood('So the cat was stolen.');
console.log(suggestions);
textlint:
import { TextLintEngine } from "textlint";
const engine = new TextLintEngine();
const results = await engine.executeOnFiles(["README.md"]);
console.log(results[0].messages);
Both tools aim to improve writing quality, but textlint offers more flexibility and power at the cost of complexity. write-good is simpler and more straightforward, making it easier to use for basic writing checks. textlint shines in scenarios requiring customized rules or working with multiple languages and file formats. The choice between the two depends on the specific needs of the project and the level of control desired over the linting process.
State of the Art Natural Language Processing
Pros of spark-nlp
- Comprehensive NLP library with advanced features like named entity recognition, sentiment analysis, and more
- Scalable for big data processing using Apache Spark
- Supports multiple languages and pre-trained models
Cons of spark-nlp
- Steeper learning curve due to complexity and Spark integration
- Requires more computational resources
- May be overkill for simple text analysis tasks
Code Comparison
write-good:
var writeGood = require('write-good');
var suggestions = writeGood('So the cat was stolen.');
console.log(suggestions);
spark-nlp:
from sparknlp.base import *
from sparknlp.annotator import *
from pyspark.ml import Pipeline
documentAssembler = DocumentAssembler().setInputCol("text").setOutputCol("document")
sentenceDetector = SentenceDetector().setInputCols(["document"]).setOutputCol("sentence")
tokenizer = Tokenizer().setInputCols(["sentence"]).setOutputCol("token")
pipeline = Pipeline().setStages([documentAssembler, sentenceDetector, tokenizer])
Summary
write-good is a lightweight, easy-to-use tool for identifying common writing issues, while spark-nlp is a comprehensive NLP library for advanced text processing tasks. write-good is more suitable for quick writing improvements, whereas spark-nlp is better for complex NLP projects and big data scenarios.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
write good
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
- shell script for avoiding "weasel words" â I based my initial implementation on this
- Academic Writing Check â a perl script similar to above
- writegood mode for emacs
- natural â general purpose NLP toolkit in JavaScript
- WordNet â lexical database of the English language
- LanguageTool â style and grammar checker implemented in Java
Prose
- Elements of Style
- FleschâKincaid readability
- Fear and Loathing of the English passive
- Words to Avoid in Educational Writing
Apps
This is not an endorsement. These apps have similar functionality that you may find useful.
Other projects using write good
- linter-write-good for Atom
- Write Good action for Drafts iOS App
- Write Good Linter for Visual Studio Code
- Vim ALE realtime linter for Vim with included support for write-good.
- Write Better A Chrome extension for Google Docs.
- Statick plugin to combine results with other linters.
License
MIT
Top Related Projects
:pencil: A markup-aware linter for prose built with speed and extensibility in mind.
A linter for prose.
Catch insensitive, inconsiderate writing
natural language processor powered by plugins part of the @unifiedjs collective
The pluggable natural language linter for text and markdown.
State of the Art Natural Language Processing
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot