Convert Figma logo to code with AI

btford logowrite-good

Naive linter for English prose

4,933
188
4,933
24

Top Related Projects

4,461

:pencil: A markup-aware linter for prose built with speed and extensibility in mind.

A linter for prose.

4,811

Catch insensitive, inconsiderate writing

2,355

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

  1. 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.

  1. 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.

  1. 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:

  1. Install the package:

    npm install write-good
    
  2. 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);
    
  3. Run your script:

    node your-script.js
    

This will output an array of suggestions for improving your text.

Competitor Comparisons

4,461

: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.

4,811

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.

2,355

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 Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

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

NPM DownloadsLast 30 Days