Convert Figma logo to code with AI

amperser logoproselint

A linter for prose.

4,324
178
4,324
355

Top Related Projects

4,461

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

Naive linter for English prose

4,811

Catch insensitive, inconsiderate writing

The pluggable natural language linter for text and markdown.

Quick Overview

Proselint is a linter for prose, designed to help writers improve their writing style and catch common errors. It's a command-line tool and Python library that analyzes text and provides suggestions for improvement based on various rules and best practices in writing.

Pros

  • Comprehensive set of rules covering various aspects of writing, including style, grammar, and consistency
  • Customizable and extensible, allowing users to add their own rules or disable existing ones
  • Can be integrated into various text editors and writing workflows
  • Supports multiple languages and writing styles

Cons

  • May produce false positives or unnecessary suggestions in certain contexts
  • Some users might find the default ruleset too strict or opinionated
  • Limited support for non-English languages compared to English
  • Requires Python installation, which might be a barrier for non-technical users

Code Examples

  1. Basic usage as a Python library:
import proselint

text = "The quick brown fox jumps over the lazy dog."
suggestions = proselint.tools.lint(text)

for suggestion in suggestions:
    print(f"Line {suggestion['line']}: {suggestion['message']}")
  1. Checking a specific rule:
from proselint.tools import lint_text

text = "I'm very unique."
errors = lint_text(text, checks=['redundancy.very_unique'])

for error in errors:
    print(f"{error['check']}: {error['message']}")
  1. Customizing the linter:
from proselint.config import default_config

custom_config = default_config.copy()
custom_config['checks']['typography.diacritical_marks'] = False

text = "The cafe is closed."
errors = proselint.tools.lint(text, config=custom_config)

Getting Started

To use Proselint, first install it using pip:

pip install proselint

Then, you can use it as a command-line tool:

proselint your_text_file.txt

Or import it in your Python script:

import proselint

text = "Your text here."
suggestions = proselint.tools.lint(text)

for suggestion in suggestions:
    print(f"{suggestion['check']}: {suggestion['message']}")

Competitor Comparisons

4,461

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

Pros of Vale

  • More customizable with user-defined rules and styles
  • Supports multiple markup formats (Markdown, AsciiDoc, reStructuredText)
  • Actively maintained with frequent updates

Cons of Vale

  • Steeper learning curve due to more complex configuration
  • Requires more setup and configuration compared to Proselint
  • May be overkill for simple writing tasks

Code Comparison

Vale configuration example:

StylesPath = styles
MinAlertLevel = suggestion

[*.md]
BasedOnStyles = Vale, proselint

Proselint usage example:

from proselint import tools
suggestions = tools.lint("Your text goes here")

Key Differences

  • Vale is more flexible and extensible, while Proselint is simpler to use out-of-the-box
  • Vale supports multiple markup formats, whereas Proselint focuses primarily on plain text
  • Vale allows for custom rule creation, while Proselint has a fixed set of rules
  • Vale requires more configuration, but offers greater customization options
  • Proselint is Python-based, while Vale is written in Go

Both tools aim to improve writing quality, but Vale offers more advanced features at the cost of increased complexity, while Proselint provides a simpler, more straightforward approach to prose linting.

Naive linter for English prose

Pros of write-good

  • Lightweight and easy to integrate into various workflows
  • Supports multiple languages (English, German, Spanish, etc.)
  • Customizable rules and easy to extend with plugins

Cons of write-good

  • Less comprehensive in its analysis compared to proselint
  • May produce more false positives due to its simplistic approach
  • Limited documentation and community support

Code Comparison

write-good:

var writeGood = require('write-good');
var suggestions = writeGood('So the cat was stolen.');
console.log(suggestions);

proselint:

import proselint

text = "So the cat was stolen."
suggestions = proselint.tools.lint(text)
print(suggestions)

Summary

write-good is a lightweight, multi-language linter that's easy to integrate and customize. However, it may lack the depth of analysis provided by proselint. proselint offers more comprehensive checks but is primarily focused on English and may be more complex to set up. The choice between the two depends on the specific needs of the project, with write-good being more suitable for quick, basic checks across multiple languages, while proselint is better for in-depth analysis of English text.

4,811

Catch insensitive, inconsiderate writing

Pros of alex

  • More actively maintained with frequent updates
  • Broader focus on inclusive language beyond just writing style
  • Integrates well with various text editors and CI/CD pipelines

Cons of alex

  • Less comprehensive in terms of general writing advice
  • May produce more false positives due to its focus on inclusive language
  • Requires more configuration to customize rules

Code comparison

alex:

const alex = require('alex');

console.log(alex('He is a businessman.').messages);

proselint:

from proselint import tools

text = "He is a businessman."
errors = tools.lint(text)
print(errors)

Key differences

  • alex is written in JavaScript, while proselint is in Python
  • alex focuses more on inclusive language, while proselint covers a wider range of writing issues
  • alex has a larger community and more frequent updates
  • proselint offers more detailed explanations for its suggestions
  • alex is easier to integrate into modern web development workflows

Both tools aim to improve writing quality, but they approach the task from different angles. alex is better suited for projects prioritizing inclusive language, while proselint may be preferable for general writing improvement.

The pluggable natural language linter for text and markdown.

Pros of textlint

  • Highly customizable with a plugin system for creating and using custom rules
  • Supports multiple languages and file formats (Markdown, plain text, HTML, etc.)
  • Active development and large community with numerous plugins available

Cons of textlint

  • Steeper learning curve due to its flexibility and configuration options
  • Requires more setup and configuration compared to proselint's out-of-the-box experience
  • May have higher resource usage for complex rulesets

Code Comparison

textlint configuration example:

{
  "rules": {
    "no-todo": true,
    "max-comma": { "max": 3 },
    "spellcheck-tech-word": true
  }
}

proselint usage example:

from proselint import tools
errors = tools.lint("Your text goes here")
for error in errors:
    print(error)

Both tools aim to improve writing quality, but textlint offers more flexibility and customization at the cost of complexity, while proselint provides a simpler, more focused approach to prose linting. textlint's plugin system allows for extensive customization, making it suitable for various writing styles and languages. proselint, on the other hand, focuses primarily on English prose and offers a more opinionated set of rules out of the box.

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

proselint logo

Workflow status Reviewed by Hound Code Climate codecov License

Writing is notoriously hard, even for the best writers, and it's not for lack of good advice — a tremendous amount of knowledge about the craft is strewn across usage guides, dictionaries, technical manuals, essays, pamphlets, websites, and the hearts and minds of great authors and editors. But poring over Strunk & White hardly makes one a better writer — it turns you into neither Strunk nor White. And nobody has the capacity to apply all the advice from Garner’s Modern English Usage, an 1100-page usage guide, to everything they write. In fact, the whole notion that one becomes a better writer by reading advice on writing rests on untenable assumptions about learning and memory. The traditional formats of knowledge about writing are thus essentially inert, waiting to be transformed.

We devised a simple solution: proselint, a linter for English prose. A linter is a computer program that, akin to a spell checker, scans through a file and detects issues — like how a real lint roller helps you get unwanted lint off of your shirt.

proselint places the world's greatest writers and editors by your side, where they whisper suggestions on how to improve your prose. You’ll be guided by advice inspired by Bryan Garner, David Foster Wallace, Chuck Palahniuk, Steve Pinker, Mary Norris, Mark Twain, Elmore Leonard, George Orwell, Matthew Butterick, William Strunk, Elwyn White, Philip Corbett, Ernest Gowers, and the editorial staff of the world’s finest literary magazines and newspapers, among others. Our goal is to aggregate knowledge about best practices in writing and to make that knowledge immediately accessible to all authors in the form of a linter for prose; all in a neat command-line utility that you can integrate into other tools, scripts, and workflows.

Installation

To get this up and running, install it using pip:

pip install proselint

Fedora

sudo dnf install proselint

Debian

sudo apt install python3-proselint

Ubuntu

sudo add-apt-repository universe
sudo apt install python3-proselint

Plugins for other software

proselint is available on:

Usage

Suppose you have a document text.md with the following text:

John is very unique.

You can run proselint over the document using the command line:

proselint text.md

This prints a list of suggestions to stdout, one per line. Each suggestion has the form:

text.md:<line>:<column>: <check_name> <message>

For example,

text.md:0:10: wallace.uncomparables Comparison of an uncomparable: 'unique' cannot be compared.

The command-line utility can also print suggestions in JSON using the --json flag. In this case, the output is considerably richer:

{
  // Type of check that output this suggestion.
  check: "wallace.uncomparables",

  // Message to describe the suggestion.
  message: "Comparison of an uncomparable: 'unique' cannot be compared.",

  // The person or organization giving the suggestion.
  source: "David Foster Wallace"

  // URL pointing to the source material.
  source_url: "http://www.telegraph.co.uk/a/9715551"

  // Line where the error starts.
  line: 0,

  // Column where the error starts.
  column: 10,

  // Index in the text where the error starts.
  start: 10,

  // Index in the text where the error ends.
  end: 21,

  // length from start -> end
  extent: 11,

  // How important is this? Can be "suggestion", "warning", or "error".
  severity: "warning",

  // Possible replacements.
  replacements: [
    {
      value: "unique"
    }
  ]
}

To run the linter as part of another Python program, you can use the lint function in proselint.tools:

import proselint

suggestions = proselint.tools.lint("This sentence is very unique")

This will return a list of suggestions:

[('weasel_words.very', "Substitute 'damn' every time you're inclined to write 'very;' your editor will delete it and the writing will be just as it should be.", 0, 17, 17, 22, 5, 'warning', None), ('uncomparables.misc', "Comparison of an uncomparable: 'very unique.' is not comparable.", 0, 17, 17, 29, 12, 'warning', None)]

Checks

You can disable any of the checks by modifying $XDG_CONFIG_HOME/proselint/config.json. If $XDG_CONFIG_HOME is not set or empty, ~/.config/proselint/config.json will be used. Additionally, for compatibility reasons, the legacy configurations ~/.proselintrc and $XDG_CONFIG_HOME/proselint/config will be checked if $XDG_CONFIG_HOME/proselint/config.json does not exist.

{
  "checks": {
    "typography.diacritical_marks": false
  }
}
IDDescription
airlinese.miscAvoiding jargon of the airline industry
annotations.miscCatching annotations left in the text
archaism.miscAvoiding archaic forms
cliches.hellAvoiding a common cliché
cliches.miscAvoiding clichés
consistency.spacingConsistent sentence spacing
consistency.spellingConsistent spelling
corporate_speak.miscAvoiding corporate buzzwords
cursing.filthWords to avoid
cursing.nflAvoiding words banned by the NFL
dates_times.am_pmUsing the right form for the time of day
dates_times.datesStylish formatting of dates
hedging.miscNot hedging
hyperbole.miscNot being hyperbolic
jargon.miscAvoiding miscellaneous jargon
lgbtq.offensive_termsAvoding offensive LGBTQ terms
lgbtq.termsMisused LGBTQ terms
lexical_illusions.miscAvoiding lexical illusions
links.brokenLinking only to existing sites
malapropisms.miscAvoiding common malapropisms
misc.apologizingBeing confident
misc.back_formationsAvoiding needless backformations
misc.bureaucrateseAvoiding bureaucratese
misc.butAvoid starting a paragraph with "But..."
misc.capitalizationCapitalizing only what ought to be capitalized
misc.chatspeakAvoiding lolling and other chatspeak
misc.commercialeseAvoiding jargon of the commercial world
misc.currencyAvoiding redundant currency symbols
misc.debasedAvoiding debased language
misc.false_pluralsAvoiding false plurals
misc.illogicAvoiding illogical forms
misc.inferior_superiorSuperior to, not than
misc.latinAvoiding overuse of Latin phrases
misc.many_aMany a singular
misc.metaconceptsAvoiding overuse of metaconcepts
misc.narcissismTalking about the subject, not its study
misc.phrasal_adjectivesHyphenating phrasal adjectives
misc.preferred_formsMiscellaneous preferred forms
misc.pretensionAvoiding being pretentious
misc.professionsCalling jobs by the right name
misc.punctuationUsing punctuation assiduously
misc.scare_quotesUsing scare quotes only when needed
misc.suddenlyAvoiding the word suddenly
misc.tense_presentAdvice from Tense Present
misc.waxedWaxing poetic
misc.whenceUsing "whence"
mixed_metaphors.miscNot mixing metaphors
mondegreens.miscAvoiding mondegreen
needless_variants.miscUsing the preferred form
nonwords.miscAvoid using nonwords
oxymorons.miscAvoiding oxymorons
psychology.miscAvoiding misused psychological terms
redundancy.miscAvoiding redundancy and saying things twice
redundancy.ras_syndromeAvoiding RAS syndrome
skunked_terms.miscAvoid using skunked terms
spelling.able_atable-able vs. -atable
spelling.able_ible-able vs. -ible
spelling.athletesSpelling of athlete names
spelling.em_im_en_in-em vs. -im and -en vs. -in
spelling.er_or-er vs. -or
spelling.in_unin- vs. un-
spelling.miscSpelling words correctly
security.credit_cardKeeping credit card numbers secret
security.passwordKeeping passwords secret
sexism.miscAvoiding sexist language
terms.animal_adjectivesAnimal adjectives
terms.denizen_labelsCalling denizens by the right name
terms.eponymous_adjectivesCalling people by the right name
terms.veneryCall groups of animals by the right name
typography.diacritical_marksUsing dïacríticâl marks
typography.exclamationAvoiding overuse of exclamation
typography.symbolsUsing the right symbols
uncomparables.miscNot comparing uncomparables
weasel_words.miscAvoiding weasel words
weasel_words.veryAvoiding the word "very"

Contributing

Interested in contributing to proselint? Great — there are plenty of ways you can help. Read more on our website, where we describe how you can help us build proselint into the greatest writing tool in the world.

Support

If you run into a problem, please open an issue in or send an email to hello@amperser.com.

Running Automated Tests

Automated tests are included in the proselint/tests directory. To run these tests locally, you can use ./utils.

License

The project is licensed under the BSD license.