proselint-0.10.2/ 0000775 0003720 0003720 00000000000 13331225202 014444 5 ustar travis travis 0000000 0000000 proselint-0.10.2/README.md 0000664 0003720 0003720 00000027312 13331225053 015734 0 ustar travis travis 0000000 0000000
[](https://travis-ci.org/amperser/proselint)
[](https://ci.appveyor.com/project/suchow/proselint-knwyf/branch/master)
[](https://houndci.com)
[](https://codeclimate.com/repos/5538989ee30ba0793100090f/feed)
[](https://coveralls.io/github/amperser/proselint?branch=master)
[](https://gemnasium.com/amperser/proselint)
[](https://en.wikipedia.org/wiki/BSD_licenses)
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 American Usage*, a 975-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, like a spell checker, scans through a document and analyzes it.)
`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, E.B. 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.
`proselint` is a command-line utility that can be integrated into existing tools.
### Installation
To get this up and running, install it using [pip](https://packaging.python.org/installing/#use-pip-for-installing):
```
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:
- [x] A [demo editor](http://proselint.com/write)
- [x] [Sublime Text](https://github.com/amperser/proselint/tree/master/plugins/sublime/SublimeLinter-contrib-proselint)
- [x] [Atom Editor](https://github.com/smockle/linter-proselint) (thanks to [Clay Miller](https://github.com/smockle)).
- [x] [Emacs via Flycheck](http://www.flycheck.org/).
- [x] Vim via [ALE](https://github.com/w0rp/ale) or [Syntastic](https://github.com/vim-syntastic/syntastic) (thanks to @lcd047, @Carreau, and [Daniel M. Capella](https://github.com/polyzen))
- [x] [Phabricator's `arc` CLI](https://github.com/google/arc-proselint) (thanks to [Jeff Verkoeyen](https://github.com/jverkoey))
- [x] [Danger](https://github.com/dbgrandi/danger-prose) (thanks to [David Grandinetti](https://github.com/dbgrandi) and [Orta Therox](https://github.com/orta))
- [x] [Visual Studio Code](https://github.com/ppeszko/vscode-proselint) (thanks to [Patryk Peszko](https://github.com/ppeszko))
- [x] [coala](https://github.com/coala-analyzer/bear-docs/blob/master/docs/ProseLintBear.rst) (thanks to the [coala Development Group](https://github.com/coala-analyzer))
- [x] [IntelliJ](https://github.com/kropp/intellij-proselint) (by [Victor Kropp](https://github.com/kropp))
- [x] [pre-commit](https://pre-commit.com/) (by [Andy Airey](https://github.com/aairey))
### Usage
Suppose you had a document `text.md` with the following text:
```
John is very unique.
```
You can run `proselint` over the document using the command line:
```bash
❯ proselint text.md
```
This prints a list of suggestions to stdout, one per line. Each suggestion has the form:
```bash
text.md:::
```
For example,
```bash
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:
```javascript
{
// 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,
// 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 program, you can use the `lint` function in `proselint.tools`:
```python
import proselint
suggestions = proselint.tools.lint("This sentence is very unique")
```
This will return a list of suggestions:
```python
[('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`. If `$XDG_CONFIG_HOME` is not set or empty, `~/.config/proselint/config` will be used.
Additionally for compatible reason, the legacy configuration `~/.proselintrc` will be used if `$XDG_CONFIG_HOME/proselint/config` does not exist.
```json
{
"checks": {
"typography.diacritical_marks": false
}
}
```
| ID | Description |
| ----- | --------------- |
| `airlinese.misc` | Avoiding jargon of the airline industry |
| `annotations.misc` | Catching annotations left in the text |
| `archaism.misc` | Avoiding archaic forms |
| `cliches.hell` | Avoiding a common cliché |
| `cliches.misc` | Avoiding clichés |
| `consistency.spacing` | Consistent sentence spacing |
| `consistency.spelling` | Consistent spelling |
| `corporate_speak.misc` | Avoiding corporate buzzwords |
| `cursing.filth` | Words to avoid |
| `cursing.nfl` | Avoiding words banned by the NFL |
| `dates_times.am_pm` | Using the right form for the time of day |
| `dates_times.dates` | Stylish formatting of dates |
| `hedging.misc` | Not hedging |
| `hyperbole.misc` | Not being hyperbolic |
| `jargon.misc` | Avoiding miscellaneous jargon |
| `lgbtq.offensive_terms` | Avoding offensive LGBTQ terms |
| `lgbtq.terms` | Misused LGBTQ terms |
| `lexical_illusions.misc` | Avoiding lexical illusions |
| `links.broken` | Linking only to existing sites |
| `malapropisms.misc` | Avoiding common malapropisms |
| `misc.apologizing` | Being confident |
| `misc.back_formations` | Avoiding needless backformations |
| `misc.bureaucratese` | Avoiding bureaucratese |
| `misc.but` | Avoid starting a paragraph with "But..." |
| `misc.capitalization` | Capitalizing only what ought to be capitalized |
| `misc.chatspeak` | Avoiding lolling and other chatspeak |
| `misc.commercialese` | Avoiding jargon of the commercial world |
| `misc.currency` | Avoiding redundant currency symbols |
| `misc.debased` | Avoiding debased language |
| `misc.false_plurals` | Avoiding false plurals |
| `misc.illogic` | Avoiding illogical forms |
| `misc.inferior_superior` | Superior to, not than |
| `misc.latin` | Avoiding overuse of Latin phrases |
| `misc.many_a` | Many a singular |
| `misc.metaconcepts` | Avoiding overuse of metaconcepts |
| `misc.narcissism` | Talking about the subject, not its study |
| `misc.phrasal_adjectives` | Hyphenating phrasal adjectives |
| `misc.preferred_forms` | Miscellaneous preferred forms |
| `misc.pretension` | Avoiding being pretentious |
| `misc.professions` | Calling jobs by the right name |
| `misc.punctuation` | Using punctuation assiduously |
| `misc.scare_quotes` | Using scare quotes only when needed |
| `misc.suddenly` | Avoiding the word suddenly |
| `misc.tense_present` | Advice from Tense Present |
| `misc.waxed` | Waxing poetic |
| `misc.whence` | Using "whence" |
| `mixed_metaphors.misc` | Not mixing metaphors |
| `mondegreens.misc` | Avoiding mondegreen |
| `needless_variants.misc` | Using the preferred form |
| `nonwords.misc` | Avoid using nonwords |
| `oxymorons.misc` | Avoiding oxymorons |
| `psychology.misc` | Avoiding misused psychological terms |
| `redundancy.misc` | Avoiding redundancy and saying things twice |
| `redundancy.ras_syndrome` | Avoiding RAS syndrome |
| `skunked_terms.misc` | Avoid using skunked terms |
| `spelling.able_atable` | -able vs. -atable |
| `spelling.able_ible` | -able vs. -ible |
| `spelling.athletes` | Spelling of athlete names |
| `spelling.em_im_en_in` | -em vs. -im and -en vs. -in |
| `spelling.er_or` | -er vs. -or |
| `spelling.in_un` | in- vs. un- |
| `spelling.misc` | Spelling words corectly |
| `security.credit_card` | Keeping credit card numbers secret |
| `security.password` | Keeping passwords secret |
| `sexism.misc` | Avoiding sexist language |
| `terms.animal_adjectives` | Animal adjectives |
| `terms.denizen_labels` | Calling denizens by the right name |
| `terms.eponymous_adjectives` | Calling people by the right name |
| `terms.venery` | Call groups of animals by the right name |
| `typography.diacritical_marks` | Using dïacríticâl marks |
| `typography.exclamation` | Avoiding overuse of exclamation |
| `typography.symbols` | Using the right symbols |
| `uncomparables.misc` | Not comparing uncomparables |
| `weasel_words.misc` | Avoiding weasel words |
| `weasel_words.very` | Avoiding the word "very" |
### Contributing
Interested in contributing to `proselint`? Great — there are plenty of ways you can help. Read more on [our website](http://proselint.com/contributing/), where we describe how you can help us build `proselint` into the greatest writing tool in the world.
- [Issue Tracker](http://github.com/amperser/proselint/issues)
- [Source Code](http://github.com/amperser/proselint)
### Support
If you run into a problem, please [open an issue](http://github.com/amperser/proselint/issues) 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, use the test runner [pytest](https://docs.pytest.org/en/latest/) and run the following commands:
```bash
pytest
```
and watch the output. Nose is compatible with Python versions 2.7, 3.4, 3.5 and 3.6.
All automated tests in `tests/` are run as part of each submitted pull request, including newly added tests.
### License
The project is licensed under the BSD license.
proselint-0.10.2/setup.py 0000664 0003720 0003720 00000002761 13331225053 016170 0 ustar travis travis 0000000 0000000 """Installation script for proselint."""
import io
import os
from setuptools import setup, find_packages
from proselint.version import __version__
DESCRIPTION = "A linter for prose."
base_url = 'http://github.com/amperser/proselint'
here = os.path.abspath(os.path.dirname(__file__))
try:
with io.open(os.path.join(here, 'README.md'), encoding='utf-8') as f:
long_description = '\n' + f.read()
except FileNotFoundError:
long_description = DESCRIPTION
setup(
name='proselint',
version=__version__,
description=DESCRIPTION,
long_description=long_description,
long_description_content_type='text/markdown',
url=base_url,
download_url="{}/tarball/{}".format(base_url, __version__),
author='Amperser Labs',
author_email='hello@amperser.com',
license='BSD',
classifiers=[
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: Implementation :: CPython',
],
packages=find_packages(
exclude=["*.tests", "*.tests.*", "tests.*", "tests"]),
package_data={'': ['demo.md', '.proselintrc']},
zip_safe=False,
entry_points={
'console_scripts': [
'proselint = proselint.command_line:proselint',
],
},
install_requires=[
'click',
'future',
'six'
])
proselint-0.10.2/CHANGELOG.md 0000664 0003720 0003720 00000121631 13331225053 016265 0 ustar travis travis 0000000 0000000 # Change Log
## [0.10.2](https://github.com/amperser/proselint/tree/0.10.2) (2018-08-03)
[Full Changelog](https://github.com/amperser/proselint/compare/0.10.1...0.10.2)
- Include tests in source package ([mavit](https://github.com/mavit))
## [0.10.1](https://github.com/amperser/proselint/tree/0.10.1) (2018-08-01)
[Full Changelog](https://github.com/amperser/proselint/compare/0.10.0...0.10.1)
- Support use as [pre-commit](https://pre-commit.com/) hook ([Andy Airey](https://github.com/aairey))
## [0.10.0](https://github.com/amperser/proselint/tree/0.10.0) (2018-07-23)
[Full Changelog](https://github.com/amperser/proselint/compare/0.9.0...0.10.0)
- Update dependencies to latest
- Add support for reading from stdin with the CLI ([io12](https://github.com/io12))
- Use pytest, not Nose, on Travis
## [0.9.0](https://github.com/amperser/proselint/tree/0.9.0) (2018-07-20)
[Full Changelog](https://github.com/amperser/proselint/compare/0.8.0...0.9.0)
- Add new plugins to README
- Update dependencies
- Comply with XDG spec ([xu-cheng](https://github.com/xu-cheng))
## [0.8.0](https://github.com/amperser/proselint/tree/0.8.0) (2017-02-22)
[Full Changelog](https://github.com/amperser/proselint/compare/0.7.0...0.8.0)
- Fix a cache-clearing issue ([m-charlton](https://github.com/m-charlton))
- Tons of improvements to tests ([joshmgrant](https://github.com/joshmgrant))
- New LGBTQ-terms module
- Misc. bug fixes and improvements
- Update various dependencies
## [0.7.0](https://github.com/amperser/proselint/tree/0.7.0) (2016-08-25)
[Full Changelog](https://github.com/amperser/proselint/compare/0.6.1...0.7.0)
**Implemented enhancements:**
- how about `typography.symbols` instead of `me.symbols` [\#373](https://github.com/amperser/proselint/issues/373)
- Improve test coverage [\#145](https://github.com/amperser/proselint/issues/145)
- Add a changelog [\#596](https://github.com/amperser/proselint/pull/596) ([suchow](https://github.com/suchow))
**Fixed bugs:**
- Exclamation point warning on all caps text [\#540](https://github.com/amperser/proselint/issues/540)
- proselint choked on bad character [\#504](https://github.com/amperser/proselint/issues/504)
- Could not open cache file [\#399](https://github.com/amperser/proselint/issues/399)
**Closed issues:**
- Add Instructions for Running Automated Tests on README [\#575](https://github.com/amperser/proselint/issues/575)
- Add the "real estate tycoon" to phrasal adjectives [\#543](https://github.com/amperser/proselint/issues/543)
- proselint CLI should append path to files [\#539](https://github.com/amperser/proselint/issues/539)
- Add "English-language learners" to phrasal adjectives [\#537](https://github.com/amperser/proselint/issues/537)
- Check out this Danger plugin [\#489](https://github.com/amperser/proselint/issues/489)
- No args leads to repeated messages: Exception TypeError: "'NoneType' object is not callable" in ignore [\#323](https://github.com/amperser/proselint/issues/323)
- Add rule on redundancies extracted from After the Deadline [\#279](https://github.com/amperser/proselint/issues/279)
- Add rule on "not guilty beyond a reasonable doubt" [\#242](https://github.com/amperser/proselint/issues/242)
- Eventually, submit to https://github.com/mcandre/linters [\#143](https://github.com/amperser/proselint/issues/143)
- Add check for Mondegreens [\#134](https://github.com/amperser/proselint/issues/134)
**Merged pull requests:**
- Ensure a clean commit history [\#592](https://github.com/amperser/proselint/pull/592) ([suchow](https://github.com/suchow))
- Remove Danger CI token [\#591](https://github.com/amperser/proselint/pull/591) ([suchow](https://github.com/suchow))
- Move Danger to Travis 'script' section [\#590](https://github.com/amperser/proselint/pull/590) ([suchow](https://github.com/suchow))
- more tests, all modules from C to L except links [\#589](https://github.com/amperser/proselint/pull/589) ([joshmgrant](https://github.com/joshmgrant))
- Add phrasal adj for issues \#543 and \#537 [\#588](https://github.com/amperser/proselint/pull/588) ([kylesezhi](https://github.com/kylesezhi))
- Added More Tests For Coverage [\#584](https://github.com/amperser/proselint/pull/584) ([joshmgrant](https://github.com/joshmgrant))
- added some instructions for running automated tests [\#581](https://github.com/amperser/proselint/pull/581) ([suchow](https://github.com/suchow))
- unintentionally unintentionally misspelled. [\#580](https://github.com/amperser/proselint/pull/580) ([suchow](https://github.com/suchow))
- unintentionally unintentionally misspelled. [\#579](https://github.com/amperser/proselint/pull/579) ([suchow](https://github.com/suchow))
- Update GitHub access token [\#578](https://github.com/amperser/proselint/pull/578) ([suchow](https://github.com/suchow))
- Add cats to list of venerys [\#568](https://github.com/amperser/proselint/pull/568) ([Decagon](https://github.com/Decagon))
- Add "kind of" and "mildly" to uncomparables [\#562](https://github.com/amperser/proselint/pull/562) ([Decagon](https://github.com/Decagon))
- Fix \#540 [\#557](https://github.com/amperser/proselint/pull/557) ([Decagon](https://github.com/Decagon))
- Survey improvements [\#554](https://github.com/amperser/proselint/pull/554) ([suchow](https://github.com/suchow))
- Use a more up-to-date link checker [\#553](https://github.com/amperser/proselint/pull/553) ([suchow](https://github.com/suchow))
- Fix a typo [\#552](https://github.com/amperser/proselint/pull/552) ([suchow](https://github.com/suchow))
- Add "color" to inconsistent spelling [\#547](https://github.com/amperser/proselint/pull/547) ([Decagon](https://github.com/Decagon))
- Danger [\#546](https://github.com/amperser/proselint/pull/546) ([suchow](https://github.com/suchow))
- Add Danger plugin to readme [\#545](https://github.com/amperser/proselint/pull/545) ([suchow](https://github.com/suchow))
- Removing relative directory line on extract\_files function in the command line interface [\#541](https://github.com/amperser/proselint/pull/541) ([CatherineH](https://github.com/CatherineH))
- Improve survey [\#538](https://github.com/amperser/proselint/pull/538) ([suchow](https://github.com/suchow))
- Bump version to 0.6.1 [\#531](https://github.com/amperser/proselint/pull/531) ([suchow](https://github.com/suchow))
- Guidelines based on GLAAD Media Reference [\#486](https://github.com/amperser/proselint/pull/486) ([joshmgrant](https://github.com/joshmgrant))
## [0.6.1](https://github.com/amperser/proselint/tree/0.6.1) (2016-07-18)
[Full Changelog](https://github.com/amperser/proselint/compare/0.6.0...0.6.1)
**Closed issues:**
- sort output by line number? [\#505](https://github.com/amperser/proselint/issues/505)
**Merged pull requests:**
- Pr/518 [\#529](https://github.com/amperser/proselint/pull/529) ([suchow](https://github.com/suchow))
- Test Case for `tools.consistency\_check` [\#522](https://github.com/amperser/proselint/pull/522) ([joshmgrant](https://github.com/joshmgrant))
- Testing for illegal utf-8 seq handling [\#520](https://github.com/amperser/proselint/pull/520) ([CraigKelly](https://github.com/CraigKelly))
- Remove skipping tests for preferred\_forms\_check [\#515](https://github.com/amperser/proselint/pull/515) ([joshmgrant](https://github.com/joshmgrant))
- Change file opening to replace characters on UTF-8 decode errors [\#514](https://github.com/amperser/proselint/pull/514) ([suchow](https://github.com/suchow))
- Sort output by line and column number [\#512](https://github.com/amperser/proselint/pull/512) ([vikasgorur](https://github.com/vikasgorur))
- typo? [\#507](https://github.com/amperser/proselint/pull/507) ([ivarvong](https://github.com/ivarvong))
## [0.6.0](https://github.com/amperser/proselint/tree/0.6.0) (2016-07-01)
[Full Changelog](https://github.com/amperser/proselint/compare/0.5.4...0.6.0)
**Closed issues:**
- Proselint doesn't work on readonly files [\#502](https://github.com/amperser/proselint/issues/502)
- Segmentation fault: 11 [\#487](https://github.com/amperser/proselint/issues/487)
**Merged pull requests:**
- Bump version to 0.6.0 [\#503](https://github.com/amperser/proselint/pull/503) ([suchow](https://github.com/suchow))
## [0.5.4](https://github.com/amperser/proselint/tree/0.5.4) (2016-06-28)
[Full Changelog](https://github.com/amperser/proselint/compare/0.5.3...0.5.4)
**Fixed bugs:**
- Remove `shell=True` as they are a security hazard [\#395](https://github.com/amperser/proselint/issues/395)
**Closed issues:**
- Speed up AppVeyor builds by caching [\#470](https://github.com/amperser/proselint/issues/470)
- Instructions for installing on OS X [\#457](https://github.com/amperser/proselint/issues/457)
- Wow [\#435](https://github.com/amperser/proselint/issues/435)
- OS X Installation issue [\#423](https://github.com/amperser/proselint/issues/423)
- Create a list of known automated grammar / usage checkers [\#281](https://github.com/amperser/proselint/issues/281)
- Checklist for open sourcing [\#198](https://github.com/amperser/proselint/issues/198)
**Merged pull requests:**
- Pr/376 [\#500](https://github.com/amperser/proselint/pull/500) ([suchow](https://github.com/suchow))
- Pr/481 [\#499](https://github.com/amperser/proselint/pull/499) ([suchow](https://github.com/suchow))
- Improve formatting of Josh Grant's cliches test [\#498](https://github.com/amperser/proselint/pull/498) ([suchow](https://github.com/suchow))
- Call load\_options\(\) once and save the results instead of calling it t… [\#493](https://github.com/amperser/proselint/pull/493) ([suchow](https://github.com/suchow))
- Fix typos [\#492](https://github.com/amperser/proselint/pull/492) ([jwilk](https://github.com/jwilk))
- Fixed spelling [\#482](https://github.com/amperser/proselint/pull/482) ([TalkingAvocado](https://github.com/TalkingAvocado))
- Tweak website [\#479](https://github.com/amperser/proselint/pull/479) ([suchow](https://github.com/suchow))
- Update Werkzeug version [\#478](https://github.com/amperser/proselint/pull/478) ([suchow](https://github.com/suchow))
- Tracebacks [\#475](https://github.com/amperser/proselint/pull/475) ([suchow](https://github.com/suchow))
- Add replacements to return value of checks [\#473](https://github.com/amperser/proselint/pull/473) ([suchow](https://github.com/suchow))
- Tests for existence\_check in tools.py [\#469](https://github.com/amperser/proselint/pull/469) ([joshmgrant](https://github.com/joshmgrant))
- Remove `shell=True` [\#467](https://github.com/amperser/proselint/pull/467) ([suchow](https://github.com/suchow))
- Fix typo in docstring [\#466](https://github.com/amperser/proselint/pull/466) ([suchow](https://github.com/suchow))
- Improve code coverage [\#465](https://github.com/amperser/proselint/pull/465) ([suchow](https://github.com/suchow))
- Update dependencies to latest versions [\#464](https://github.com/amperser/proselint/pull/464) ([suchow](https://github.com/suchow))
- Create a list of other usage & grammar tools [\#462](https://github.com/amperser/proselint/pull/462) ([suchow](https://github.com/suchow))
- Improve documentation [\#461](https://github.com/amperser/proselint/pull/461) ([suchow](https://github.com/suchow))
- Copyedit the readme [\#459](https://github.com/amperser/proselint/pull/459) ([suchow](https://github.com/suchow))
- Update Coveralls badge in readme [\#456](https://github.com/amperser/proselint/pull/456) ([suchow](https://github.com/suchow))
- Add link to Phabricator integration to readme [\#453](https://github.com/amperser/proselint/pull/453) ([suchow](https://github.com/suchow))
- Remove lintscore badge from README [\#452](https://github.com/amperser/proselint/pull/452) ([suchow](https://github.com/suchow))
- Allow proselintrc to be overriden by user [\#451](https://github.com/amperser/proselint/pull/451) ([suchow](https://github.com/suchow))
- Create test pattern for checks [\#450](https://github.com/amperser/proselint/pull/450) ([suchow](https://github.com/suchow))
- Add CodeClimate config file [\#449](https://github.com/amperser/proselint/pull/449) ([suchow](https://github.com/suchow))
- Do not open file for reading and writing [\#447](https://github.com/amperser/proselint/pull/447) ([Tatsh](https://github.com/Tatsh))
- Refactor tools [\#445](https://github.com/amperser/proselint/pull/445) ([suchow](https://github.com/suchow))
## [0.5.3](https://github.com/amperser/proselint/tree/0.5.3) (2016-04-05)
[Full Changelog](https://github.com/amperser/proselint/compare/0.5.2...0.5.3)
**Merged pull requests:**
- Bump version to 0.5.3 [\#448](https://github.com/amperser/proselint/pull/448) ([suchow](https://github.com/suchow))
## [0.5.2](https://github.com/amperser/proselint/tree/0.5.2) (2016-04-04)
[Full Changelog](https://github.com/amperser/proselint/compare/0.5.1...0.5.2)
**Implemented enhancements:**
- Make `proselint .` run over entire directory, possibly with a recursive option [\#292](https://github.com/amperser/proselint/issues/292)
**Merged pull requests:**
- Fix error message for phrasal-adj. hyphenation [\#444](https://github.com/amperser/proselint/pull/444) ([suchow](https://github.com/suchow))
- Show status of master in AppVeyor badge [\#442](https://github.com/amperser/proselint/pull/442) ([suchow](https://github.com/suchow))
- Fix AppVeyor badge in readme [\#441](https://github.com/amperser/proselint/pull/441) ([suchow](https://github.com/suchow))
- Use AppVeyor for Windows CI [\#440](https://github.com/amperser/proselint/pull/440) ([suchow](https://github.com/suchow))
- Handle missing dbm module on some python 2.7 systems [\#439](https://github.com/amperser/proselint/pull/439) ([CraigKelly](https://github.com/CraigKelly))
## [0.5.1](https://github.com/amperser/proselint/tree/0.5.1) (2016-04-02)
[Full Changelog](https://github.com/amperser/proselint/compare/0.5.0...0.5.1)
**Fixed bugs:**
- JSON flag gives incorrect line/column numbers [\#418](https://github.com/amperser/proselint/issues/418)
- Exception TypeError: "'NoneType' object is not callable" in ignored [\#238](https://github.com/amperser/proselint/issues/238)
**Merged pull requests:**
- Bump version to 0.5.1 [\#436](https://github.com/amperser/proselint/pull/436) ([suchow](https://github.com/suchow))
- Attempt to fix cache-related bugs [\#432](https://github.com/amperser/proselint/pull/432) ([CraigKelly](https://github.com/CraigKelly))
- Add entry to phrasal-adj. hyphenation check [\#431](https://github.com/amperser/proselint/pull/431) ([suchow](https://github.com/suchow))
- Fix off-by-one error in JSON output [\#429](https://github.com/amperser/proselint/pull/429) ([suchow](https://github.com/suchow))
- Don't warn when there's only 1 "!" [\#426](https://github.com/amperser/proselint/pull/426) ([laraross](https://github.com/laraross))
## [0.5.0](https://github.com/amperser/proselint/tree/0.5.0) (2016-03-31)
[Full Changelog](https://github.com/amperser/proselint/compare/0.4.4...0.5.0)
**Implemented enhancements:**
- Return a non-zero exit status when there are warnings [\#427](https://github.com/amperser/proselint/issues/427)
**Merged pull requests:**
- Use exit codes [\#428](https://github.com/amperser/proselint/pull/428) ([suchow](https://github.com/suchow))
## [0.4.4](https://github.com/amperser/proselint/tree/0.4.4) (2016-03-30)
[Full Changelog](https://github.com/amperser/proselint/compare/0.4.3...0.4.4)
**Implemented enhancements:**
- Assorted issues from Debian mailing list [\#389](https://github.com/amperser/proselint/issues/389)
**Fixed bugs:**
- Typo on API page [\#417](https://github.com/amperser/proselint/issues/417)
- Assorted issues from Debian mailing list [\#389](https://github.com/amperser/proselint/issues/389)
**Merged pull requests:**
- Reorganization [\#424](https://github.com/amperser/proselint/pull/424) ([suchow](https://github.com/suchow))
- Update api.md - fixes \#417 [\#420](https://github.com/amperser/proselint/pull/420) ([shubheksha](https://github.com/shubheksha))
- added tests for butterick.symbols [\#413](https://github.com/amperser/proselint/pull/413) ([suchow](https://github.com/suchow))
- Deploy to PyPi only once [\#410](https://github.com/amperser/proselint/pull/410) ([suchow](https://github.com/suchow))
- Deploy to pypi automatically [\#409](https://github.com/amperser/proselint/pull/409) ([suchow](https://github.com/suchow))
## [0.4.3](https://github.com/amperser/proselint/tree/0.4.3) (2016-03-19)
[Full Changelog](https://github.com/amperser/proselint/compare/0.4.2...0.4.3)
## [0.4.2](https://github.com/amperser/proselint/tree/0.4.2) (2016-03-18)
[Full Changelog](https://github.com/amperser/proselint/compare/0.4.1...0.4.2)
**Merged pull requests:**
- Fixed exception in the TypeError handler when cache sync fails [\#408](https://github.com/amperser/proselint/pull/408) ([saul](https://github.com/saul))
- Set option name to json output [\#406](https://github.com/amperser/proselint/pull/406) ([marsam](https://github.com/marsam))
## [0.4.1](https://github.com/amperser/proselint/tree/0.4.1) (2016-03-18)
[Full Changelog](https://github.com/amperser/proselint/compare/0.4.0...0.4.1)
**Implemented enhancements:**
- explain corpora directory [\#357](https://github.com/amperser/proselint/issues/357)
- Add clean option to ensure that proselint clears cache before running [\#330](https://github.com/amperser/proselint/issues/330)
- Hide filename in log when linting individual files [\#317](https://github.com/amperser/proselint/issues/317)
**Fixed bugs:**
- Remove filthy language from demo and test site [\#347](https://github.com/amperser/proselint/issues/347)
**Closed issues:**
- 'bug' when run with op to terminal? [\#405](https://github.com/amperser/proselint/issues/405)
- Validity of Strunk & White as source [\#394](https://github.com/amperser/proselint/issues/394)
- Create plugin for Atom [\#371](https://github.com/amperser/proselint/issues/371)
- Add tex support for vim plugin [\#340](https://github.com/amperser/proselint/issues/340)
- Create plugin for emacs [\#37](https://github.com/amperser/proselint/issues/37)
**Merged pull requests:**
- Add check for 'But' at start of paragraph [\#404](https://github.com/amperser/proselint/pull/404) ([dhan12](https://github.com/dhan12))
- Fix the Vim plugin to work with older versions of syntastic [\#398](https://github.com/amperser/proselint/pull/398) ([lcd047](https://github.com/lcd047))
- Added check for inferior/superior to/than. [\#392](https://github.com/amperser/proselint/pull/392) ([tkmharris](https://github.com/tkmharris))
- Added a directory for checks from Fowler's. Added a check for 'waxed … [\#391](https://github.com/amperser/proselint/pull/391) ([tkmharris](https://github.com/tkmharris))
- Add check for nonwords [\#390](https://github.com/amperser/proselint/pull/390) ([suchow](https://github.com/suchow))
- Make it possible to run `proselint .` over a directory [\#388](https://github.com/amperser/proselint/pull/388) ([suchow](https://github.com/suchow))
- Add rule on 'geometer' [\#387](https://github.com/amperser/proselint/pull/387) ([suchow](https://github.com/suchow))
- Fix the Vim plugin [\#377](https://github.com/amperser/proselint/pull/377) ([lcd047](https://github.com/lcd047))
- Fix bug in version formatting [\#372](https://github.com/amperser/proselint/pull/372) ([suchow](https://github.com/suchow))
- Add a --compact flag [\#370](https://github.com/amperser/proselint/pull/370) ([suchow](https://github.com/suchow))
- Fix bug in garner.dates \#278 [\#369](https://github.com/amperser/proselint/pull/369) ([ksslng](https://github.com/ksslng))
- Fix bug in Travis yml [\#368](https://github.com/amperser/proselint/pull/368) ([suchow](https://github.com/suchow))
- Remove filth from demo [\#366](https://github.com/amperser/proselint/pull/366) ([suchow](https://github.com/suchow))
- Remove rogue print statement [\#365](https://github.com/amperser/proselint/pull/365) ([suchow](https://github.com/suchow))
- Create file in memory in worker function [\#363](https://github.com/amperser/proselint/pull/363) ([suchow](https://github.com/suchow))
- Fix bug in webapp [\#362](https://github.com/amperser/proselint/pull/362) ([suchow](https://github.com/suchow))
- Describe corpus in README [\#360](https://github.com/amperser/proselint/pull/360) ([laraross](https://github.com/laraross))
- Add check for 'not guilty beyond a reasonable doubt' [\#359](https://github.com/amperser/proselint/pull/359) ([suchow](https://github.com/suchow))
- Update commercialese.py [\#354](https://github.com/amperser/proselint/pull/354) ([ciarand](https://github.com/ciarand))
- Fix backwards reference [\#353](https://github.com/amperser/proselint/pull/353) ([drinks](https://github.com/drinks))
- Fix spelling of kaleidoscope [\#352](https://github.com/amperser/proselint/pull/352) ([drinks](https://github.com/drinks))
- Correct duplicate docstrings [\#351](https://github.com/amperser/proselint/pull/351) ([hugovk](https://github.com/hugovk))
- Fix misattributed Twain quote [\#350](https://github.com/amperser/proselint/pull/350) ([hugovk](https://github.com/hugovk))
- Fix typo of garner in three checks' error messages [\#349](https://github.com/amperser/proselint/pull/349) ([stig](https://github.com/stig))
- Github -\> GitHub typos [\#348](https://github.com/amperser/proselint/pull/348) ([hugovk](https://github.com/hugovk))
## [0.4.0](https://github.com/amperser/proselint/tree/0.4.0) (2016-03-08)
[Full Changelog](https://github.com/amperser/proselint/compare/0.3.5...0.4.0)
**Implemented enhancements:**
- Proselint's SublimeText plugin is not on Package Control [\#234](https://github.com/amperser/proselint/issues/234)
**Fixed bugs:**
- Short flags are broken [\#326](https://github.com/amperser/proselint/issues/326)
- trigger happy on exclamation mark warnings [\#322](https://github.com/amperser/proselint/issues/322)
- proselint --initialize throws errors [\#304](https://github.com/amperser/proselint/issues/304)
- Add -h argument option and double dash single character options [\#303](https://github.com/amperser/proselint/issues/303)
- Enforce compatibility with Python 2 and 3 [\#297](https://github.com/amperser/proselint/issues/297)
- Remove newline characters from error messages [\#288](https://github.com/amperser/proselint/issues/288)
**Closed issues:**
- Add LICENSE.md and README.md to source distribution [\#343](https://github.com/amperser/proselint/issues/343)
- Website Lintscore Error [\#319](https://github.com/amperser/proselint/issues/319)
- Vim Plugin [\#309](https://github.com/amperser/proselint/issues/309)
- broken link http://amzn.to/15wF76r [\#298](https://github.com/amperser/proselint/issues/298)
- Extract rules from the Federal Plain Language Guidelines [\#255](https://github.com/amperser/proselint/issues/255)
- Create plugin for Atom editor [\#36](https://github.com/amperser/proselint/issues/36)
**Merged pull requests:**
- v0.4.0 [\#346](https://github.com/amperser/proselint/pull/346) ([suchow](https://github.com/suchow))
- Add README.md and LICENSE.md to source distribution [\#344](https://github.com/amperser/proselint/pull/344) ([viccuad](https://github.com/viccuad))
- Only complain about punctuational exclamation marks. Fixes \#322 [\#339](https://github.com/amperser/proselint/pull/339) ([jsenn](https://github.com/jsenn))
- Update site table [\#338](https://github.com/amperser/proselint/pull/338) ([michaelpacer](https://github.com/michaelpacer))
- Add list of available plugins to README [\#337](https://github.com/amperser/proselint/pull/337) ([suchow](https://github.com/suchow))
- added clean mode to build with no cache [\#332](https://github.com/amperser/proselint/pull/332) ([michaelpacer](https://github.com/michaelpacer))
- add short option to show help [\#329](https://github.com/amperser/proselint/pull/329) ([jstewmon](https://github.com/jstewmon))
- use absolute import to find proselint.tools [\#328](https://github.com/amperser/proselint/pull/328) ([jstewmon](https://github.com/jstewmon))
- fix click option declarations [\#327](https://github.com/amperser/proselint/pull/327) ([jstewmon](https://github.com/jstewmon))
- Fix miscalculation in lintscore example [\#324](https://github.com/amperser/proselint/pull/324) ([suchow](https://github.com/suchow))
- Update site only on master [\#321](https://github.com/amperser/proselint/pull/321) ([suchow](https://github.com/suchow))
- support variadic file args and stdin [\#320](https://github.com/amperser/proselint/pull/320) ([jstewmon](https://github.com/jstewmon))
- Correct spelling of "multiplication" [\#318](https://github.com/amperser/proselint/pull/318) ([fdb](https://github.com/fdb))
- Spelling corrections on page 'checks' [\#311](https://github.com/amperser/proselint/pull/311) ([TKAB](https://github.com/TKAB))
- v0.3.6 [\#307](https://github.com/amperser/proselint/pull/307) ([suchow](https://github.com/suchow))
- Update Flask-Limiter to latest version [\#302](https://github.com/amperser/proselint/pull/302) ([suchow](https://github.com/suchow))
- Update dependencies to latest [\#301](https://github.com/amperser/proselint/pull/301) ([suchow](https://github.com/suchow))
- Clean up source URLs and attributions [\#299](https://github.com/amperser/proselint/pull/299) ([suchow](https://github.com/suchow))
- Curly-quote max [\#296](https://github.com/amperser/proselint/pull/296) ([suchow](https://github.com/suchow))
- Don't flag 'matrices' [\#294](https://github.com/amperser/proselint/pull/294) ([suchow](https://github.com/suchow))
- Add rule on the redundant 'collocated together' [\#291](https://github.com/amperser/proselint/pull/291) ([suchow](https://github.com/suchow))
- Don't print errors object in json output [\#290](https://github.com/amperser/proselint/pull/290) ([marsam](https://github.com/marsam))
- Kill newline characters and whitespace in errors [\#289](https://github.com/amperser/proselint/pull/289) ([suchow](https://github.com/suchow))
- Add Flycheck plugin [\#287](https://github.com/amperser/proselint/pull/287) ([suchow](https://github.com/suchow))
- Add clichés from GNU diction [\#284](https://github.com/amperser/proselint/pull/284) ([suchow](https://github.com/suchow))
- Add check for diacritical marks [\#280](https://github.com/amperser/proselint/pull/280) ([suchow](https://github.com/suchow))
- Use subdirectories for posts [\#274](https://github.com/amperser/proselint/pull/274) ([suchow](https://github.com/suchow))
- Require a number on either side [\#273](https://github.com/amperser/proselint/pull/273) ([suchow](https://github.com/suchow))
- Skunked terms [\#270](https://github.com/amperser/proselint/pull/270) ([suchow](https://github.com/suchow))
- Allow no space around x in multiplication [\#269](https://github.com/amperser/proselint/pull/269) ([suchow](https://github.com/suchow))
- Add rule on false plurals [\#268](https://github.com/amperser/proselint/pull/268) ([suchow](https://github.com/suchow))
- Add stub for phrasal adjectives [\#267](https://github.com/amperser/proselint/pull/267) ([suchow](https://github.com/suchow))
- Improve typography checks [\#266](https://github.com/amperser/proselint/pull/266) ([suchow](https://github.com/suchow))
- Add stub of rule for professions [\#265](https://github.com/amperser/proselint/pull/265) ([suchow](https://github.com/suchow))
- Remove bare except clauses [\#264](https://github.com/amperser/proselint/pull/264) ([Uran198](https://github.com/Uran198))
- Upgrade to latest version of requirements [\#262](https://github.com/amperser/proselint/pull/262) ([suchow](https://github.com/suchow))
- Add instructions for Vim plug-in [\#258](https://github.com/amperser/proselint/pull/258) ([Carreau](https://github.com/Carreau))
- enable testing on Python 3.5 [\#257](https://github.com/amperser/proselint/pull/257) ([Carreau](https://github.com/Carreau))
- add a vim syntastic checker [\#256](https://github.com/amperser/proselint/pull/256) ([Carreau](https://github.com/Carreau))
- Add rule on "nouveau riche" [\#251](https://github.com/amperser/proselint/pull/251) ([suchow](https://github.com/suchow))
- Use Jekyll v2.5.3 [\#250](https://github.com/amperser/proselint/pull/250) ([suchow](https://github.com/suchow))
- Use bumpversion to manage versions [\#241](https://github.com/amperser/proselint/pull/241) ([suchow](https://github.com/suchow))
- Bump version number to 0.3.5 [\#240](https://github.com/amperser/proselint/pull/240) ([suchow](https://github.com/suchow))
## [0.3.5](https://github.com/amperser/proselint/tree/0.3.5) (2015-10-20)
[Full Changelog](https://github.com/amperser/proselint/compare/0.3.4...0.3.5)
**Fixed bugs:**
- Permission issues with current location of cache directory [\#225](https://github.com/amperser/proselint/issues/225)
**Merged pull requests:**
- Further copyedit Sublime Text plugin README [\#239](https://github.com/amperser/proselint/pull/239) ([suchow](https://github.com/suchow))
- Fix up the SublimeText README [\#237](https://github.com/amperser/proselint/pull/237) ([suchow](https://github.com/suchow))
- Fix bug in mondegreen rule [\#236](https://github.com/amperser/proselint/pull/236) ([suchow](https://github.com/suchow))
- Copy edit README for SublimeText plugin [\#235](https://github.com/amperser/proselint/pull/235) ([suchow](https://github.com/suchow))
- Update comment in butterick.symbols [\#233](https://github.com/amperser/proselint/pull/233) ([FakeYou](https://github.com/FakeYou))
- Add rule on mondegreens [\#232](https://github.com/amperser/proselint/pull/232) ([suchow](https://github.com/suchow))
- Fix for cache saving [\#231](https://github.com/amperser/proselint/pull/231) ([PatchRanger](https://github.com/PatchRanger))
- Fix bug in README formatting [\#230](https://github.com/amperser/proselint/pull/230) ([suchow](https://github.com/suchow))
- Add rule on 'neck-and-neck' [\#229](https://github.com/amperser/proselint/pull/229) ([suchow](https://github.com/suchow))
- Copy edit readme [\#228](https://github.com/amperser/proselint/pull/228) ([suchow](https://github.com/suchow))
- Update exclamation.py [\#226](https://github.com/amperser/proselint/pull/226) ([MichalPokorny](https://github.com/MichalPokorny))
- Fix version label [\#222](https://github.com/amperser/proselint/pull/222) ([suchow](https://github.com/suchow))
- Add rule on Wallace's examples of redundancy [\#221](https://github.com/amperser/proselint/pull/221) ([suchow](https://github.com/suchow))
- Revert "Enable all the checks by default" [\#220](https://github.com/amperser/proselint/pull/220) ([suchow](https://github.com/suchow))
- Fix autoresponder [\#219](https://github.com/amperser/proselint/pull/219) ([suchow](https://github.com/suchow))
- Tweak website [\#218](https://github.com/amperser/proselint/pull/218) ([suchow](https://github.com/suchow))
- Reinstate web app [\#216](https://github.com/amperser/proselint/pull/216) ([suchow](https://github.com/suchow))
- Misc. website improvements [\#215](https://github.com/amperser/proselint/pull/215) ([suchow](https://github.com/suchow))
- Update dependencies [\#214](https://github.com/amperser/proselint/pull/214) ([suchow](https://github.com/suchow))
- Remove live demo link, for now [\#213](https://github.com/amperser/proselint/pull/213) ([suchow](https://github.com/suchow))
- Further improve the README [\#212](https://github.com/amperser/proselint/pull/212) ([suchow](https://github.com/suchow))
- Update README [\#211](https://github.com/amperser/proselint/pull/211) ([suchow](https://github.com/suchow))
- Remove Heroku build from Travis [\#210](https://github.com/amperser/proselint/pull/210) ([suchow](https://github.com/suchow))
- Add stub for a rule on venery terms [\#209](https://github.com/amperser/proselint/pull/209) ([suchow](https://github.com/suchow))
## [0.3.4](https://github.com/amperser/proselint/tree/0.3.4) (2015-10-01)
[Full Changelog](https://github.com/amperser/proselint/compare/0.3.3...0.3.4)
**Merged pull requests:**
- Deploy to PyPi manually for now [\#207](https://github.com/amperser/proselint/pull/207) ([suchow](https://github.com/suchow))
- Fix some versioning issues [\#206](https://github.com/amperser/proselint/pull/206) ([suchow](https://github.com/suchow))
## [0.3.3](https://github.com/amperser/proselint/tree/0.3.3) (2015-09-30)
[Full Changelog](https://github.com/amperser/proselint/compare/0.3.2...0.3.3)
**Merged pull requests:**
- fixes version number [\#205](https://github.com/amperser/proselint/pull/205) ([michaelpacer](https://github.com/michaelpacer))
## [0.3.2](https://github.com/amperser/proselint/tree/0.3.2) (2015-09-30)
[Full Changelog](https://github.com/amperser/proselint/compare/0.3.1...0.3.2)
**Merged pull requests:**
- Disable version test [\#204](https://github.com/amperser/proselint/pull/204) ([laraross](https://github.com/laraross))
- fixup for pypi so demo will work [\#203](https://github.com/amperser/proselint/pull/203) ([laraross](https://github.com/laraross))
- Continuous integration [\#200](https://github.com/amperser/proselint/pull/200) ([suchow](https://github.com/suchow))
## [0.3.1](https://github.com/amperser/proselint/tree/0.3.1) (2015-09-30)
[Full Changelog](https://github.com/amperser/proselint/compare/0.3.0...0.3.1)
## [0.3.0](https://github.com/amperser/proselint/tree/0.3.0) (2015-09-30)
[Full Changelog](https://github.com/amperser/proselint/compare/0.2.1...0.3.0)
**Merged pull requests:**
- Get ready for PyPi [\#199](https://github.com/amperser/proselint/pull/199) ([suchow](https://github.com/suchow))
## [0.2.1](https://github.com/amperser/proselint/tree/0.2.1) (2015-09-30)
[Full Changelog](https://github.com/amperser/proselint/compare/0.2.0...0.2.1)
**Implemented enhancements:**
- Create a timing test on the command line [\#191](https://github.com/amperser/proselint/issues/191)
**Merged pull requests:**
- Add timing test to CLI [\#197](https://github.com/amperser/proselint/pull/197) ([suchow](https://github.com/suchow))
- Test proselint version number [\#196](https://github.com/amperser/proselint/pull/196) ([suchow](https://github.com/suchow))
- Print full email headers [\#195](https://github.com/amperser/proselint/pull/195) ([suchow](https://github.com/suchow))
- Fix bug in email bot [\#194](https://github.com/amperser/proselint/pull/194) ([suchow](https://github.com/suchow))
- Improve links [\#193](https://github.com/amperser/proselint/pull/193) ([suchow](https://github.com/suchow))
- Improve website copy [\#192](https://github.com/amperser/proselint/pull/192) ([suchow](https://github.com/suchow))
- Contributing recommendations [\#189](https://github.com/amperser/proselint/pull/189) ([laraross](https://github.com/laraross))
- Tweak license formatting [\#188](https://github.com/amperser/proselint/pull/188) ([laraross](https://github.com/laraross))
- Remove corpus [\#186](https://github.com/amperser/proselint/pull/186) ([laraross](https://github.com/laraross))
- Add CI token to Travis [\#185](https://github.com/amperser/proselint/pull/185) ([suchow](https://github.com/suchow))
- Don't run timing test [\#184](https://github.com/amperser/proselint/pull/184) ([suchow](https://github.com/suchow))
- add bsd license [\#181](https://github.com/amperser/proselint/pull/181) ([michaelpacer](https://github.com/michaelpacer))
- Move to proselint.com [\#180](https://github.com/amperser/proselint/pull/180) ([suchow](https://github.com/suchow))
- Move scoring into its own file [\#179](https://github.com/amperser/proselint/pull/179) ([suchow](https://github.com/suchow))
- Fix one more malapropism typo [\#178](https://github.com/amperser/proselint/pull/178) ([suchow](https://github.com/suchow))
- Fix typos [\#177](https://github.com/amperser/proselint/pull/177) ([suchow](https://github.com/suchow))
- Specify version of future in reqs. [\#174](https://github.com/amperser/proselint/pull/174) ([suchow](https://github.com/suchow))
- Remove 'll' from NFL's naughty words [\#173](https://github.com/amperser/proselint/pull/173) ([suchow](https://github.com/suchow))
- Beef up the README [\#172](https://github.com/amperser/proselint/pull/172) ([suchow](https://github.com/suchow))
- Consolidate hardcoding of version number [\#169](https://github.com/amperser/proselint/pull/169) ([suchow](https://github.com/suchow))
## [0.2.0](https://github.com/amperser/proselint/tree/0.2.0) (2015-09-18)
[Full Changelog](https://github.com/amperser/proselint/compare/v0.1.0...0.2.0)
**Closed issues:**
- should we delete the python3 branch now that it's complete? [\#157](https://github.com/amperser/proselint/issues/157)
- Add Louis C.K.'s rule on "the N-word" [\#154](https://github.com/amperser/proselint/issues/154)
- Upgrade to most recent version of dependencies [\#144](https://github.com/amperser/proselint/issues/144)
- Figure out the right name for a "check" [\#21](https://github.com/amperser/proselint/issues/21)
- Extract rules from DFW's dictionary in The Telegraph [\#4](https://github.com/amperser/proselint/issues/4)
**Merged pull requests:**
- Daily GMAUs [\#160](https://github.com/amperser/proselint/pull/160) ([suchow](https://github.com/suchow))
- Add Louis C.K.'s rule on the n-word [\#159](https://github.com/amperser/proselint/pull/159) ([suchow](https://github.com/suchow))
- Python3 [\#156](https://github.com/amperser/proselint/pull/156) ([michaelpacer](https://github.com/michaelpacer))
- Update requirements [\#147](https://github.com/amperser/proselint/pull/147) ([suchow](https://github.com/suchow))
- Improve test coverage [\#146](https://github.com/amperser/proselint/pull/146) ([suchow](https://github.com/suchow))
## [v0.1.0](https://github.com/amperser/proselint/tree/v0.1.0) (2015-07-13)
**Implemented enhancements:**
- Move cache to a place where Heroku can see it [\#90](https://github.com/amperser/proselint/issues/90)
- Fork NLTK / TextBlob and speed up importing them [\#88](https://github.com/amperser/proselint/issues/88)
**Fixed bugs:**
- "every possible" flagged as comparing an uncomparable [\#129](https://github.com/amperser/proselint/issues/129)
- Make proselint work in normal install mode [\#91](https://github.com/amperser/proselint/issues/91)
- Decade detector false alarms on 50 cent posessive [\#82](https://github.com/amperser/proselint/issues/82)
- Fix web plugin's handling of Unicode [\#62](https://github.com/amperser/proselint/issues/62)
**Closed issues:**
- Extract business euphemisms from Inc article [\#136](https://github.com/amperser/proselint/issues/136)
- Refactor proselint/checks/norris/denizen\_labels.py from a D on Code Climate [\#127](https://github.com/amperser/proselint/issues/127)
- Refactor proselint/checks/garner/sexism.py from a D on Code Climate [\#126](https://github.com/amperser/proselint/issues/126)
- Refactor proselint/checks/butterick/symbols.py from a D on Code Climate [\#125](https://github.com/amperser/proselint/issues/125)
- Test ticket from Code Climate [\#124](https://github.com/amperser/proselint/issues/124)
- Create a linter email service [\#123](https://github.com/amperser/proselint/issues/123)
- Make a splash page to collect email addresses [\#102](https://github.com/amperser/proselint/issues/102)
- Get a logo [\#101](https://github.com/amperser/proselint/issues/101)
- Add rate limiting to API [\#100](https://github.com/amperser/proselint/issues/100)
- Use worker and web processes [\#96](https://github.com/amperser/proselint/issues/96)
- Issue with broken link parsing [\#84](https://github.com/amperser/proselint/issues/84)
- Extract rules from "Anguished English" [\#67](https://github.com/amperser/proselint/issues/67)
- Make pep8 and pep257 run cleanly [\#61](https://github.com/amperser/proselint/issues/61)
- Add rule about spelling names correctly [\#58](https://github.com/amperser/proselint/issues/58)
- Build online writing editor using http://codemirror.net/? [\#50](https://github.com/amperser/proselint/issues/50)
- Check out the cement framework for command line utilities [\#47](https://github.com/amperser/proselint/issues/47)
- False alarms, corpora, QA, and contributing back [\#45](https://github.com/amperser/proselint/issues/45)
- Create a .proselintrc file [\#39](https://github.com/amperser/proselint/issues/39)
- Create plugin for Sublime Text [\#35](https://github.com/amperser/proselint/issues/35)
- Create an API [\#33](https://github.com/amperser/proselint/issues/33)
- Using "a" vs. "an" [\#31](https://github.com/amperser/proselint/issues/31)
- Figure out test inheritance [\#30](https://github.com/amperser/proselint/issues/30)
- Great writing should come back nearly clean [\#25](https://github.com/amperser/proselint/issues/25)
- Don't lint quoted text [\#24](https://github.com/amperser/proselint/issues/24)
- Architecture for sharing processed data across rules [\#20](https://github.com/amperser/proselint/issues/20)
- It's et al., not et. al [\#18](https://github.com/amperser/proselint/issues/18)
- Sort errors by the position in which they occur [\#12](https://github.com/amperser/proselint/issues/12)
- Integrate into Sublime Text as a linter [\#11](https://github.com/amperser/proselint/issues/11)
- Extract rules from write-good [\#5](https://github.com/amperser/proselint/issues/5)
- working out how i can best contribute using github/git [\#3](https://github.com/amperser/proselint/issues/3)
- Create a plugin system [\#2](https://github.com/amperser/proselint/issues/2)
- Choose a sensible naming/numbering scheme for errors [\#1](https://github.com/amperser/proselint/issues/1)
**Merged pull requests:**
- Make compatible with Python 3 [\#95](https://github.com/amperser/proselint/pull/95) ([suchow](https://github.com/suchow))
- Change the sublime plugin file [\#53](https://github.com/amperser/proselint/pull/53) ([suchow](https://github.com/suchow))
- Create a plugin system [\#13](https://github.com/amperser/proselint/pull/13) ([suchow](https://github.com/suchow))
proselint-0.10.2/proselint/ 0000775 0003720 0003720 00000000000 13331225202 016463 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/tools.py 0000664 0003720 0003720 00000032055 13331225053 020206 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""General-purpose tools shared across linting checks."""
from __future__ import print_function
from __future__ import unicode_literals
import sys
import traceback
import os
import shelve
import inspect
import functools
import re
import hashlib
import json
import importlib
try:
import dbm
except ImportError:
import anydbm as dbm
PY3 = sys.version_info[0] == 3
if PY3:
string_types = str
else:
string_types = basestring,
_cache_shelves = dict()
proselint_path = os.path.dirname(os.path.realpath(__file__))
def close_cache_shelves():
"""Close previously opened cache shelves."""
for pth, cache in _cache_shelves.items():
cache.close()
_cache_shelves.clear()
def close_cache_shelves_after(f):
"""Decorator that ensures cache shelves are closed after the call."""
@functools.wraps(f)
def wrapped(*args, **kwargs):
f(*args, **kwargs)
close_cache_shelves()
return wrapped
def _get_xdg_path(variable_name, default_path):
path = os.environ.get(variable_name)
if path is None or path == '':
return default_path
else:
return path
def _get_xdg_config_home():
return _get_xdg_path('XDG_CONFIG_HOME',
os.path.join(os.path.expanduser('~'), '.config'))
def _get_xdg_cache_home():
return _get_xdg_path('XDG_CACHE_HOME',
os.path.join(os.path.expanduser('~'), '.cache'))
def _get_cache(cachepath):
if cachepath in _cache_shelves:
return _cache_shelves[cachepath]
try:
cache = shelve.open(cachepath, protocol=2)
except dbm.error:
# dbm error on open - delete and retry
print('Error (%s) opening %s - will attempt to delete and re-open.' %
(sys.exc_info()[1], cachepath))
try:
os.remove(cachepath)
cache = shelve.open(cachepath, protocol=2)
except Exception:
print('Error on re-open: %s' % sys.exc_info()[1])
cache = None
except Exception:
# unknown error
print('Could not open cache file %s, maybe name collision. '
'Error: %s' % (cachepath, traceback.format_exc()))
cache = None
# Don't fail on bad caches
if cache is None:
print('Using in-memory shelf for cache file %s' % cachepath)
cache = shelve.Shelf(dict())
_cache_shelves[cachepath] = cache
return cache
def memoize(f):
"""Cache results of computations on disk."""
# Determine the location of the cache.
cache_dirname = os.path.join(_get_xdg_cache_home(), 'proselint')
legacy_cache_dirname = os.path.join(os.path.expanduser("~"), ".proselint")
if not os.path.isdir(cache_dirname):
# Migrate the cache from the legacy path to XDG complaint location.
if os.path.isdir(legacy_cache_dirname):
os.rename(legacy_cache_dirname, cache_dirname)
# Create the cache if it does not already exist.
else:
os.makedirs(cache_dirname)
cache_filename = f.__module__ + "." + f.__name__
cachepath = os.path.join(cache_dirname, cache_filename)
@functools.wraps(f)
def wrapped(*args, **kwargs):
# handle instance methods
if hasattr(f, '__self__'):
args = args[1:]
signature = (f.__module__ + '.' + f.__name__).encode("utf-8")
tempargdict = inspect.getcallargs(f, *args, **kwargs)
for item in list(tempargdict.items()):
signature += item[1].encode("utf-8")
key = hashlib.sha256(signature).hexdigest()
try:
cache = _get_cache(cachepath)
return cache[key]
except KeyError:
value = f(*args, **kwargs)
cache[key] = value
cache.sync()
return value
except TypeError:
call_to = f.__module__ + '.' + f.__name__
print('Warning: could not disk cache call to %s;'
'it probably has unhashable args. Error: %s' %
(call_to, traceback.format_exc()))
return f(*args, **kwargs)
return wrapped
def get_checks(options):
"""Extract the checks."""
sys.path.append(proselint_path)
checks = []
check_names = [key for (key, val)
in list(options["checks"].items()) if val]
for check_name in check_names:
module = importlib.import_module("checks." + check_name)
for d in dir(module):
if re.match("check", d):
checks.append(getattr(module, d))
return checks
def load_options():
"""Read various proselintrc files, allowing user overrides."""
possible_defaults = (
'/etc/proselintrc',
os.path.join(proselint_path, '.proselintrc'),
)
options = {}
has_overrides = False
for filename in possible_defaults:
try:
options = json.load(open(filename))
break
except IOError:
pass
try:
user_options = json.load(
open(os.path.join(_get_xdg_config_home(), 'proselint', 'config')))
has_overrides = True
except IOError:
pass
# Read user configuration from the legacy path.
if not has_overrides:
try:
user_options = json.load(
open(os.path.join(os.path.expanduser('~'), '.proselintrc')))
has_overrides = True
except IOError:
pass
if has_overrides:
if 'max_errors' in user_options:
options['max_errors'] = user_options['max_errors']
if 'checks' in user_options:
for (key, value) in user_options['checks'].items():
try:
options['checks'][key] = value
except KeyError:
pass
return options
def errors_to_json(errors):
"""Convert the errors to JSON."""
out = []
for e in errors:
out.append({
"check": e[0],
"message": e[1],
"line": 1 + e[2],
"column": 1 + e[3],
"start": 1 + e[4],
"end": 1 + e[5],
"extent": e[6],
"severity": e[7],
"replacements": e[8],
})
return json.dumps(
dict(status="success", data={"errors": out}), sort_keys=True)
def line_and_column(text, position):
"""Return the line number and column of a position in a string."""
position_counter = 0
for idx_line, line in enumerate(text.splitlines(True)):
if (position_counter + len(line.rstrip())) >= position:
return (idx_line, position - position_counter)
else:
position_counter += len(line)
def lint(input_file, debug=False):
"""Run the linter on the input file."""
options = load_options()
if isinstance(input_file, string_types):
text = input_file
else:
text = input_file.read()
# Get the checks.
checks = get_checks(options)
# Apply all the checks.
errors = []
for check in checks:
result = check(text)
for error in result:
(start, end, check, message, replacements) = error
(line, column) = line_and_column(text, start)
if not is_quoted(start, text):
errors += [(check, message, line, column, start, end,
end - start, "warning", replacements)]
if len(errors) > options["max_errors"]:
break
# Sort the errors by line and column number.
errors = sorted(errors[:options["max_errors"]], key=lambda e: (e[2], e[3]))
return errors
def assert_error(text, check, n=1):
"""Assert that text has n errors of type check."""
assert_error.description = "No {} error for '{}'".format(check, text)
assert(check in [error[0] for error in lint(text)])
def consistency_check(text, word_pairs, err, msg, offset=0):
"""Build a consistency checker for the given word_pairs."""
errors = []
msg = " ".join(msg.split())
for w in word_pairs:
matches = [
[m for m in re.finditer(w[0], text)],
[m for m in re.finditer(w[1], text)]
]
if len(matches[0]) > 0 and len(matches[1]) > 0:
idx_minority = len(matches[0]) > len(matches[1])
for m in matches[idx_minority]:
errors.append((
m.start() + offset,
m.end() + offset,
err,
msg.format(w[~idx_minority], m.group(0)),
w[~idx_minority]))
return errors
def preferred_forms_check(text, list, err, msg, ignore_case=True, offset=0,
max_errors=float("inf")):
"""Build a checker that suggests the preferred form."""
if ignore_case:
flags = re.IGNORECASE
else:
flags = 0
msg = " ".join(msg.split())
errors = []
regex = u"[\W^]{}[\W$]"
for p in list:
for r in p[1]:
for m in re.finditer(regex.format(r), text, flags=flags):
txt = m.group(0).strip()
errors.append((
m.start() + 1 + offset,
m.end() + offset,
err,
msg.format(p[0], txt),
p[0]))
errors = truncate_to_max(errors, max_errors)
return errors
def existence_check(text, list, err, msg, ignore_case=True,
str=False, max_errors=float("inf"), offset=0,
require_padding=True, dotall=False,
excluded_topics=None, join=False):
"""Build a checker that blacklists certain words."""
flags = 0
msg = " ".join(msg.split())
if ignore_case:
flags = flags | re.IGNORECASE
if str:
flags = flags | re.UNICODE
if dotall:
flags = flags | re.DOTALL
if require_padding:
regex = u"(?:^|\W){}[\W$]"
else:
regex = u"{}"
errors = []
# If the topic of the text is in the excluded list, return immediately.
if excluded_topics:
tps = topics(text)
if any([t in excluded_topics for t in tps]):
return errors
rx = "|".join(regex.format(w) for w in list)
for m in re.finditer(rx, text, flags=flags):
txt = m.group(0).strip()
errors.append((
m.start() + 1 + offset,
m.end() + offset,
err,
msg.format(txt),
None))
errors = truncate_to_max(errors, max_errors)
return errors
def truncate_to_max(errors, max_errors):
"""If max_errors was specified, truncate the list of errors.
Give the total number of times that the error was found elsewhere.
"""
if len(errors) > max_errors:
start1, end1, err1, msg1, replacements = errors[0]
if len(errors) == (max_errors + 1):
msg1 += " Found once elsewhere."
else:
msg1 += " Found {} times elsewhere.".format(len(errors))
errors = errors[1:max_errors]
errors = [(start1, end1, err1, msg1, replacements)] + errors
return errors
def is_quoted(position, text):
"""Determine if the position in the text falls within a quote."""
def matching(quotemark1, quotemark2):
straight = '\"\''
curly = '“”'
if quotemark1 in straight and quotemark2 in straight:
return True
if quotemark1 in curly and quotemark2 in curly:
return True
else:
return False
def find_ranges(text):
s = 0
q = pc = ''
start = None
ranges = []
seps = " .,:;-\r\n"
quotes = ['\"', '“', '”', "'"]
for i, c in enumerate(text + "\n"):
if s == 0 and c in quotes and pc in seps:
start = i
s = 1
q = c
elif s == 1 and matching(c, q):
s = 2
elif s == 2:
if c in seps:
ranges.append((start+1, i-1))
start = None
s = 0
else:
s = 1
pc = c
return ranges
def position_in_ranges(ranges, position):
for start, end in ranges:
if start <= position < end:
return True
return False
return position_in_ranges(find_ranges(text), position)
def detector_50_Cent(text):
"""Determine whether 50 Cent is a topic."""
keywords = [
"50 Cent",
"rap",
"hip hop",
"Curtis James Jackson III",
"Curtis Jackson",
"Eminem",
"Dre",
"Get Rich or Die Tryin'",
"G-Unit",
"Street King Immortal",
"In da Club",
"Interscope",
]
num_keywords = sum(word in text for word in keywords)
return ("50 Cent", float(num_keywords > 2))
def topics(text):
"""Return a list of topics."""
detectors = [
detector_50_Cent
]
ts = []
for detector in detectors:
ts.append(detector(text))
return [t[0] for t in ts if t[1] > 0.95]
def context(text, position, level="paragraph"):
"""Get sentence or paragraph that surrounds the given position."""
if level == "sentence":
pass
elif level == "paragraph":
pass
return ""
proselint-0.10.2/proselint/checks/ 0000775 0003720 0003720 00000000000 13331225202 017723 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/weasel_words/ 0000775 0003720 0003720 00000000000 13331225202 022421 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/weasel_words/very.py 0000664 0003720 0003720 00000001335 13331225053 023766 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Very.
---
layout: post
source: William Allen White
source_url: http://bit.ly/1XaMllw
title: very
date: 2014-06-10 12:31:19
categories: writing
---
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.
"""
from proselint.tools import memoize, existence_check
@memoize
def check(text):
"""Avoid 'very'."""
err = "weasel_words.very"
msg = ("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.")
regex = "very"
return existence_check(text, [regex], err, msg, max_errors=1)
proselint-0.10.2/proselint/checks/weasel_words/__init__.py 0000664 0003720 0003720 00000000024 13331225053 024532 0 ustar travis travis 0000000 0000000 """Weasel words."""
proselint-0.10.2/proselint/checks/weasel_words/misc.py 0000664 0003720 0003720 00000000633 13331225053 023734 0 ustar travis travis 0000000 0000000 """Weasel words.
---
layout: post
source: write-good
source_url: https://github.com/btford/write-good
title: Weasel words.
date: 2014-06-10 12:31:19
categories: writing
---
Weasel words clearly weaken various aspects of a number of your sentences.
"""
# def check(text):
# error_code = "weasel_words.misc"
# msg = "Weasel words present."
# return [(1, 1, error_code, msg)]
proselint-0.10.2/proselint/checks/sexism/ 0000775 0003720 0003720 00000000000 13331225202 021233 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/sexism/__init__.py 0000664 0003720 0003720 00000000016 13331225053 023345 0 ustar travis travis 0000000 0000000 """Sexism."""
proselint-0.10.2/proselint/checks/sexism/misc.py 0000664 0003720 0003720 00000005007 13331225053 022546 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Sexism.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: sexism
date: 2014-06-10 12:31:19
categories: writing
---
Points out sexist language.
"""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "sexism.misc"
msg = "Gender bias. Use '{}' instead of '{}'."
sexism = [
["anchor", ["anchorman", "anchorwoman"]],
["chair", ["chairman", "chairwoman"]],
["drafter", ["draftman", "draftwoman"]],
["ombuds", ["ombudsman", "ombudswoman"]],
["tribe member", ["tribesman", "tribeswoman"]],
["police officer", ["policeman", "policewoman"]],
["firefighter", ["fireman", "firewoman"]],
["mail carrier", ["mailman", "mailwoman"]],
["history", ["herstory"]],
["women", ["womyn"]],
["poet", ["poetess"]],
["author", ["authoress"]],
["waiter", ["waitress"]],
["lawyer", ["lady lawyer"]],
["doctor", ["woman doctor"]],
["bookseller", ["female booksalesman"]],
["air pilot", ["female airman"]],
["executor", ["executrix"]],
["prosecutor", ["prosecutrix"]],
["testator", ["testatrix"]],
["husband and wife", ["man and wife"]],
["chairs", ["chairmen and chairs"]],
["men and women", ["men and girls"]],
["comedian", ["comedienne"]],
["confidant", ["confidante"]],
["scientist", ["woman scientist"]],
["scientists", ["women scientists"]]
# ["hero", ["heroine"]]
]
errors = preferred_forms_check(text, sexism, err, msg, ignore_case=False)
msg = "Not a preferred form. Use '{}' instead of '{}'."
pref = [
["anchor", ["anchorperson"]],
["chair", ["chairperson"]],
["drafter", ["draftperson"]],
["ombuds", ["ombudsperson"]],
["tribe member", ["tribesperson"]],
["police officer", ["policeperson"]],
["firefighter", ["fireperson"]],
["mail carrier", ["mailperson"]],
]
for x in preferred_forms_check(text, pref, err, msg, ignore_case=False):
errors.append(x)
return errors
proselint-0.10.2/proselint/checks/links/ 0000775 0003720 0003720 00000000000 13331225202 021043 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/links/broken.py 0000664 0003720 0003720 00000003200 13331225053 022674 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Checks that links are viable.
---
layout: post
source: SublimeLinter-annotations
source_url: http://bit.ly/16Q7H41
title: broken links
date: 2014-06-10 12:31:19
categories: writing
---
Check that links are not broken.
"""
from proselint.tools import memoize
from future import standard_library
import re
try:
import urllib.request as urllib_request # for Python 3
except ImportError:
import urllib2 as urllib_request # for Python 2
from socket import error as SocketError
standard_library.install_aliases()
@memoize
def check(text):
"""Check the text."""
err = "links.valid"
msg = u"Broken link: {}"
regex = re.compile(
r"""(?i)\b((?:https?://|www\d{0,3}[.]
|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+
|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)
|[^\s`!()\[\]{};:\'".,<>?\xab\xbb\u201c\u201d\u2018\u2019\u21a9]))""",
re.U | re.X)
errors = []
for m in re.finditer(regex, text):
url = m.group(0).strip()
if "http://" not in url and "https://" not in url:
url = "http://" + url
if is_broken_link(url):
errors.append((m.start(), m.end(), err, msg.format(url), None))
return errors
@memoize
def is_broken_link(url):
"""Determine whether the link returns a 404 error."""
try:
request = urllib_request.Request(
url, headers={'User-Agent': 'Mozilla/5.0'})
urllib_request.urlopen(request).read()
return False
except urllib_request.URLError:
return True
except SocketError:
return True
proselint-0.10.2/proselint/checks/links/__init__.py 0000664 0003720 0003720 00000000024 13331225053 023154 0 ustar travis travis 0000000 0000000 """Broken links."""
proselint-0.10.2/proselint/checks/jargon/ 0000775 0003720 0003720 00000000000 13331225202 021203 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/jargon/__init__.py 0000664 0003720 0003720 00000000016 13331225053 023315 0 ustar travis travis 0000000 0000000 """Jargon."""
proselint-0.10.2/proselint/checks/jargon/misc.py 0000664 0003720 0003720 00000001263 13331225053 022516 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
u"""Cliches.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: a vs. an
date: 2014-06-10 12:31:19
categories: writing
---
Cliches are cliché.
"""
from proselint.tools import memoize, existence_check
@memoize
def check(text):
"""Check the text."""
err = "jargon.misc"
msg = u"'{}' is jargon. Can you replace it with something more standard?"
jargon = [
"in the affirmative",
"in the negative",
"agendize",
"per your order",
"per your request",
"disincentivize",
]
return existence_check(text, jargon, err, msg, join=True)
proselint-0.10.2/proselint/checks/mixed_metaphors/ 0000775 0003720 0003720 00000000000 13331225202 023113 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/mixed_metaphors/__init__.py 0000664 0003720 0003720 00000000027 13331225053 025227 0 ustar travis travis 0000000 0000000 """Mixed metaphors."""
proselint-0.10.2/proselint/checks/mixed_metaphors/misc.py 0000664 0003720 0003720 00000002551 13331225053 024427 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Mixed metaphors."""
from proselint.tools import memoize, existence_check, preferred_forms_check
@memoize
def check_bottleneck(text):
"""Avoid mixing metaphors about bottles and their necks.
source: Sir Ernest Gowers
source_url: http://bit.ly/1CQPH61
"""
err = "mixed_metaphors.misc.bottleneck"
msg = u"Mixed metaphor — bottles with big necks are easy to pass through."
list = [
"biggest bottleneck",
"big bottleneck",
"large bottleneck",
"largest bottleneck",
"world-wide bottleneck",
"huge bottleneck",
"massive bottleneck",
]
return existence_check(text, list, err, msg, max_errors=1)
@memoize
def check_misc(text):
"""Avoid mixing metaphors.
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
"""
err = "mixed_metaphors.misc.misc"
msg = u"Mixed metaphor. Try '{}'."
preferences = [
["cream rises to the top", ["cream rises to the crop"]],
["fasten your seatbelts", ["button your seatbelts"]],
["a minute to decompress", ["a minute to decompose"]],
["sharpest tool in the shed", ["sharpest marble in the (shed|box)"]],
["not rocket science", ["not rocket surgery"]],
]
return preferred_forms_check(text, preferences, err, msg)
proselint-0.10.2/proselint/checks/mondegreens/ 0000775 0003720 0003720 00000000000 13331225202 022231 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/mondegreens/__init__.py 0000664 0003720 0003720 00000000023 13331225053 024341 0 ustar travis travis 0000000 0000000 """Mondegreens."""
proselint-0.10.2/proselint/checks/mondegreens/misc.py 0000664 0003720 0003720 00000002101 13331225053 023534 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Mondegreens.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: mondegreens
date: 2014-06-10 12:31:19
categories: writing
---
Points out preferred form.
"""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "misc.mondegreens"
msg = "'{}' is the preferred form."
list = [
["a girl with kaleidoscope eyes", ["a girl with colitis goes by"]],
["a partridge in a pear tree", ["a part-red gingerbread tree"]],
["attorney and not a republic", ["attorney and notary public"]],
["beck and call", ["beckon call"]],
["for all intents and purposes", ["for all intensive purposes"]],
["laid him on the green", ["Lady Mondegreen"]],
["all of the other reindeer", ["Olive, the other reindeer"]],
["to the manner born", ["to the manor born"]],
]
return preferred_forms_check(text, list, err, msg)
proselint-0.10.2/proselint/checks/airlinese/ 0000775 0003720 0003720 00000000000 13331225202 021676 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/airlinese/__init__.py 0000664 0003720 0003720 00000000021 13331225053 024004 0 ustar travis travis 0000000 0000000 """Airlinese."""
proselint-0.10.2/proselint/checks/airlinese/misc.py 0000664 0003720 0003720 00000001110 13331225053 023200 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Airlinese.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: Airlinese
date: 2014-06-10 12:31:19
categories: writing
---
Airlinese.
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "airlinese.misc"
msg = u"'{}' is airlinese."
airlinese = [
"enplan(?:e|ed|ing|ement)",
"deplan(?:e|ed|ing|ement)",
"taking off momentarily",
]
return existence_check(text, airlinese, err, msg)
proselint-0.10.2/proselint/checks/dates_times/ 0000775 0003720 0003720 00000000000 13331225202 022224 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/dates_times/dates.py 0000664 0003720 0003720 00000003240 13331225053 023701 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Dates.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: dates
date: 2014-06-10 12:31:19
categories: writing
---
Dates.
"""
from proselint.tools import existence_check, memoize
import calendar
@memoize
def check_decade_apostrophes_short(text):
"""Check the text for dates of the form X0's."""
err = "dates_times.dates"
msg = u"Apostrophes aren't needed for decades."
regex = "\d0\'s"
return existence_check(
text, [regex], err, msg, excluded_topics=["50 Cent"])
@memoize
def check_decade_apostrophes_long(text):
"""Check the text for dates of the form XXX0's."""
err = "dates_times.dates"
msg = u"Apostrophes aren't needed for decades."
regex = "\d\d\d0\'s"
return existence_check(text, [regex], err, msg)
@memoize
def check_dash_and_from(text):
"""Check the text."""
err = "dates_times.dates"
msg = u"When specifying a date range, write 'from X to Y'."
regex = "[fF]rom \d+[^ \t\n\r\f\va-zA-Z0-9_\.]\d+"
return existence_check(text, [regex], err, msg)
def check_month_year_comma(text):
"""Check the text."""
err = "dates_times.dates"
msg = u"When specifying a month and year, no comma is needed."
regex = "(?:" + "|".join(calendar.month_name[1:]) + "), \d{3,}"
return existence_check(text, [regex], err, msg)
@memoize
def check_month_of_year(text):
"""Check the text."""
err = "dates_times.dates"
msg = u"When specifying a month and year, 'of' is unnecessary."
regex = "(?:" + "|".join(calendar.month_name[1:]) + ") of \d{3,}"
return existence_check(text, [regex], err, msg)
proselint-0.10.2/proselint/checks/dates_times/__init__.py 0000664 0003720 0003720 00000000027 13331225053 024340 0 ustar travis travis 0000000 0000000 """Dates and times."""
proselint-0.10.2/proselint/checks/dates_times/am_pm.py 0000664 0003720 0003720 00000002667 13331225053 023706 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
u"""a.m. / p.m.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: a.m. & p.m.
date: 2014-06-10 12:31:19
categories: writing
---
"""
from proselint.tools import memoize, existence_check
@memoize
def check_lowercase_periods(text):
"""Check the text."""
err = "dates_times.am_pm.lowercase_periods"
msg = u"With lowercase letters, the periods are standard."
return existence_check(text, ["\d{1,2} ?[ap]m"], err, msg)
@memoize
def check_spacing(text):
"""Check the text."""
err = "dates_times.am_pm.spacing"
msg = u"It's standard to put a space before 'a.m.' or 'p.m.'."
return existence_check(text, ["\d{1,2}[ap]\.?m\.?"], err, msg)
@memoize
def check_midnight_noon(text):
"""Check the text."""
err = "dates_times.am_pm.midnight_noon"
msg = (u"12 a.m. and 12 p.m. are wrong and confusing."
" Use 'midnight' or 'noon'.")
return existence_check(text, ["12 ?[ap]\.?m\.?"], err, msg)
@memoize
def check_redundancy(text):
"""Check the text."""
err = "dates_times.am_pm.midnight_noon"
msg = (u"'a.m.' is always morning; 'p.m.' is always night.")
list = [
"\d{1,2} ?a\.?m\.? in the morning",
"\d{1,2} ?p\.?m\.? in the evening",
"\d{1,2} ?p\.?m\.? at night",
"\d{1,2} ?p\.?m\.? in the afternoon",
]
return existence_check(text, list, err, msg, join=True)
proselint-0.10.2/proselint/checks/typography/ 0000775 0003720 0003720 00000000000 13331225202 022131 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/typography/exclamation.py 0000664 0003720 0003720 00000002152 13331225053 025013 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Too much yelling.
---
layout: post
source: ???
source_url: ???
title: yelling
date: 2014-06-10 12:31:19
categories: writing
---
Too much yelling.
"""
import re
from proselint.tools import existence_check, memoize
@memoize
def check_repeated_exclamations(text):
"""Check the text."""
err = "leonard.exclamation.multiple"
msg = u"Stop yelling. Keep your exclamation points under control."
regex = r"[\!]\s*?[\!]{1,}"
return existence_check(
text, [regex], err, msg, require_padding=False, ignore_case=False,
max_errors=1, dotall=True)
@memoize
def check_exclamations_ppm(text):
"""Make sure that the exclamation ppm is under 30."""
err = "leonard.exclamation.30ppm"
msg = u"More than 30 ppm of exclamations. Keep them under control."
regex = r"\w!"
count = len(re.findall(regex, text))
num_words = len(text.split(" "))
ppm = (count*1.0 / num_words) * 1e6
if ppm > 30 and count > 1:
loc = re.search(regex, text).start() + 1
return [(loc, loc+1, err, msg, ".")]
else:
return []
proselint-0.10.2/proselint/checks/typography/diacritical_marks.py 0000664 0003720 0003720 00000011162 13331225053 026155 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Diacritical marks.
Use of diacritical marks where common.
"""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "typography.diacritical_marks"
msg = u"Use diacritical marks in '{}'."
list = [
# French loanwords
[u"beau idéal", ["beau ideal"]],
[u"boutonnière", ["boutonniere"]],
[u"bric-à-brac", ["bric-a-brac"]],
[u"café", ["cafe"]],
[u"cause célèbre", ["cause celebre"]],
[u"chèvre", ["chevre"]],
[u"cliché", ["cliche"]],
[u"comme ci comme ça", ["comme ci comme ca", "comsi comsa"]],
[u"consommé", ["consomme"]],
[u"coup d'état", ["coup d'etat"]],
[u"coup de grâce", ["coup de grace"]],
[u"crudités", ["crudites"]],
[u"crème brûlée", ["creme brulee"]],
[u"crème de menthe", ["creme de menthe"]],
[u"crème fraîche", ["creme fraice"]],
[u"crème fraîche", ["creme fresh"]],
[u"crêpe", ["crepe"]],
[u"débutante", ["debutante"]],
[u"décor", ["decor"]],
[u"déjà vu", ["deja vu"]],
[u"dénouement", ["denouement"]],
[u"façade", ["facade"]],
[u"fiancé", ["fiance"]],
[u"fiancée", ["fiancee"]],
[u"flambé", ["flambe"]],
[u"garçon", ["garcon"]],
[u"lycée", ["lycee"]],
[u"maître d", ["maitre d"]],
[u"ménage à trois", ["menage a trois"]],
[u"négligée", ["negligee"]],
[u"papier-mâché", ["papier-mache", "paper mache", "paper-mache"]],
[u"protégé", ["protege"]],
[u"protégée", ["protegee"]],
[u"purée", ["puree"]],
[u"raison d'être", ["raison d'etre"]],
[u"my résumé", ["my resume"]],
[u"your résumé", ["your resume"]],
[u"his résumé", ["his resume"]],
[u"her résumé", ["her resume"]],
[u"a résumé", ["a resume"]],
[u"the résumé", ["the resume"]],
[u"risqué", ["risque"]],
[u"roué", ["roue"]],
[u"soirée", ["soiree"]],
[u"soufflé", ["souffle"]],
[u"soupçon", ["soupcon"]],
[u"touché", ["touche"]],
[u"tête-à-tête", ["tete-a-tete"]],
[u"voilà", ["voila"]],
[u"à la carte", ["a la carte"]],
[u"à la mode", ["a la mode"]],
[u"émigré", ["emigre"]],
# Spanish loanwords
[u"El Niño", ["El Nino"]],
[u"jalapeño", ["jalapeno"]],
[u"La Niña", ["La Nina"]],
[u"piña colada", ["pina colada"]],
[u"señor", ["senor"]],
[u"señora", ["senora"]],
[u"señorita", ["senorita"]],
# Portuguese loanwords
[u"açaí", ["acai"]],
# German loanwords
[u"doppelgänger", ["doppelganger"]],
[u"Führer", ["Fuhrer"]],
[u"Gewürztraminer", ["Gewurztraminer"]],
[u"vis-à-vis", ["vis-a-vis"]],
[u"Übermensch", ["Ubermensch"]],
# Swedish loanwords
[u"filmjölk", ["filmjolk"]],
[u"smörgåsbord", ["smorgasbord"]],
# Names, places, and companies
[u"Beyoncé", ["Beyonce"]],
[u"Brontë", ["Bronte"]],
[u"Brontë", ["Bronte"]],
[u"Champs-Élysées", ["Champs-Elysees"]],
[u"Citroën", ["Citroen"]],
[u"Curaçao", ["Curacao"]],
[u"Häagen-Dazs", ["Haagen-Dazs", "Haagen Dazs"]],
[u"Löwenbräu", ["Lowenbrau"]],
[u"Monégasque", ["Monegasque"]],
[u"Mötley Crüe", ["Motley Crue"]],
[u"Nescafé", ["Nescafe"]],
[u"Queensrÿche", ["Queensryche"]],
[u"Québec", ["Quebec"]],
[u"Québécois", ["Quebecois"]],
[u"Ångström", ["Angstrom"]],
[u"ångström", ["angstrom"]],
[u"Škoda", ["Skoda"]],
]
return preferred_forms_check(text, list, err, msg)
proselint-0.10.2/proselint/checks/typography/symbols.py 0000664 0003720 0003720 00000005440 13331225053 024202 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Use the right symbols.
source: Butterick's Practical Typography
source_url: http://practicaltypography.com/
"""
from proselint.tools import memoize, existence_check, preferred_forms_check
@memoize
def check_ellipsis(text):
"""Use an ellipsis instead of three dots."""
err = "typography.symbols.ellipsis"
msg = u"'...' is an approximation, use the ellipsis symbol '…'."
regex = "\.\.\."
return existence_check(text, [regex], err, msg, max_errors=3,
require_padding=False, offset=0)
@memoize
def check_copyright_symbol(text):
"""Use the copyright symbol instead of (c)."""
err = "typography.symbols.copyright"
msg = u"(c) is a goofy alphabetic approximation, use the symbol ©."
regex = "\([cC]\)"
return existence_check(
text, [regex], err, msg, max_errors=1, require_padding=False)
@memoize
def check_trademark_symbol(text):
"""Use the trademark symbol instead of (TM)."""
err = "typography.symbols.trademark"
msg = u"(TM) is a goofy alphabetic approximation, use the symbol ™."
regex = "\(TM\)"
return existence_check(
text, [regex], err, msg, max_errors=3, require_padding=False)
@memoize
def check_registered_trademark_symbol(text):
"""Use the registered trademark symbol instead of (R)."""
err = "typography.symbols.trademark"
msg = u"(R) is a goofy alphabetic approximation, use the symbol ®."
regex = "\([rR]\)"
return existence_check(
text, [regex], err, msg, max_errors=3, require_padding=False)
@memoize
def check_sentence_spacing(text):
"""Use no more than two spaces after a period."""
err = "typography.symbols.sentence_spacing"
msg = u"More than two spaces after the period; use 1 or 2."
regex = "\. {3}"
return existence_check(
text, [regex], err, msg, max_errors=3, require_padding=False)
@memoize
def check_multiplication_symbol(text):
u"""Use the multiplication symbol ×, not the lowercase letter x."""
err = "typography.symbols.multiplication_symbol"
msg = u"Use the multiplication symbol ×, not the letter x."
regex = "[0-9]+ ?x ?[0-9]+"
return existence_check(
text, [regex], err, msg, max_errors=3, require_padding=False)
@memoize
def check_curly_quotes(text):
u"""Use curly quotes, not straight quotes."""
err = "typography.symbols.curly_quotes"
msg = u'Use curly quotes “”, not straight quotes "".'
list = [
[u"“ or ”", ['"']],
]
return preferred_forms_check(
text, list, err, msg, ignore_case=False, max_errors=2)
# @memoize
# def check_en_dash_separated_names(text):
# """Use an en-dash to separate names."""
# # [u"[A-Z][a-z]{1,10}[-\u2014][A-Z][a-z]{1,10}",
# # u"Use an en dash (–) to separate names."],
proselint-0.10.2/proselint/checks/typography/__init__.py 0000664 0003720 0003720 00000000034 13331225053 024243 0 ustar travis travis 0000000 0000000 """Advice on typography."""
proselint-0.10.2/proselint/checks/misc/ 0000775 0003720 0003720 00000000000 13331225202 020656 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/misc/metadiscourse.py 0000664 0003720 0003720 00000001301 13331225053 024076 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Metadiscourse.
---
layout: post
source: Pinker's book on writing
source_url: ???
title: metadiscourse
date: 2014-06-10 12:31:19
categories: writing
---
Points out metadiscourse.
"""
from proselint.tools import memoize, existence_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "pinker.metadiscourse"
msg = "Excessive metadiscourse."
metadiscourse = [
"The preceeding discussion",
"The rest of this article",
"This chapter discusses",
"The preceding paragraph demonstrated",
"The previous section analyzed",
]
return existence_check(text, metadiscourse, err, msg)
proselint-0.10.2/proselint/checks/misc/inferior_superior.py 0000664 0003720 0003720 00000001324 13331225053 025001 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Inferior / Superior.
---
layout: post
source: Fowler's Modern English Usage
source_url: bit.ly/1YBG8QJ
title: Inferior / Superior
date: 2016-03-10 17:27:37
categories: writing
---
Corrects 'inferior/superior than' to 'inferior/superior to'.
"""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "misc.inferior_superior"
msg = "'Inferior' and 'superior' are not true comparatives. Use '{}'."
preferences = [
["inferior to", ["inferior than"]],
["superior to", ["superior than"]],
]
return preferred_forms_check(text, preferences, err, msg)
proselint-0.10.2/proselint/checks/misc/tense_present.py 0000664 0003720 0003720 00000002101 13331225053 024104 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Tense present.
---
layout: post
source: DFW's Tense Present
source_url: http://bit.ly/1c85lgR
title: Tense present
date: 2014-06-10 12:31:19
categories: writing
---
Archaism.
"""
from proselint.tools import memoize
import re
@memoize
def check(text):
"""Check the text."""
err = "misc.tense_present"
msg = u"'{}'."
illogics = [
u"up to \d{1,3}% ?[-\u2014\u2013]{0,3} ?(?:or|and) more\W?",
"between you and I",
"on accident",
"somewhat of a",
"all it's own",
"reason is because",
"audible to the ear",
"in regards to",
"would of",
# "and so",
"i ?(?:feel|am feeling|am|'m|'m feeling) nauseous",
]
errors = []
for i in illogics:
for m in re.finditer(u"\s{}\s".format(i), text, flags=re.U | re.I):
txt = m.group(0).strip()
errors.append((
m.start() + 1,
m.end(),
err,
msg.format(txt),
None))
return errors
proselint-0.10.2/proselint/checks/misc/apologizing.py 0000664 0003720 0003720 00000001056 13331225053 023560 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Excessive apologizing.
---
layout: post
source: Pinker's book on writing
source_url: ???
title: excessive apologizing
date: 2014-06-10 12:31:19
categories: writing
---
Points out excessive apologizing.
"""
from proselint.tools import memoize, existence_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "pinker.apologizing"
msg = "Excessive apologizing."
narcissism = [
"More research is needed",
]
return existence_check(text, narcissism, err, msg)
proselint-0.10.2/proselint/checks/misc/back_formations.py 0000664 0003720 0003720 00000001114 13331225053 024372 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Back-formations.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: back-formations
date: 2014-06-10 12:31:19
categories: writing
---
Back-formations.
"""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "misc.back_formations"
msg = "Back-formation. '{}' is the preferred form."
list = [
["improper", ["improprietous"]],
]
return preferred_forms_check(text, list, err, msg)
proselint-0.10.2/proselint/checks/misc/greylist.py 0000664 0003720 0003720 00000001674 13331225053 023106 0 ustar travis travis 0000000 0000000 """Use of greylisted words.
---
layout: post
source: Strunk & White
source_url: ???
title: Use of greylisted words
date: 2014-06-10 12:31:19
categories: writing
---
Strunk & White say:
"""
from proselint.tools import memoize
import re
@memoize
def check(text):
"""Check the text."""
err = "strunk_white.greylist"
msg = "Use of '{}'. {}"
bad_words = [
"obviously",
"utilize"
]
explanations = {
"obviously":
"This is obviously an inadvisable word to use.",
"utilize":
r"Do you know anyone who *needs* to utilize the word utilize?"
}
errors = []
for word in bad_words:
occ = [m for m in re.finditer(word, text.lower())]
for o in occ:
errors.append((
o.start(),
o.end(),
err,
msg.format(word, explanations[word]),
None))
return errors
proselint-0.10.2/proselint/checks/misc/many_a.py 0000664 0003720 0003720 00000001316 13331225053 022501 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
u"""Many a singular.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: Many a singular.
date: 2014-06-10 12:31:19
categories: writing
---
The idiom 'many a' requires a singular verb.
"""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "misc.many_a"
msg = "'many a' requires a singular verb."
preferences = [
["is many a", ["are many a"]],
["has been many a", ["have been many a"]],
["was many a", ["were many a"]],
]
return preferred_forms_check(text, preferences, err, msg)
proselint-0.10.2/proselint/checks/misc/false_plurals.py 0000664 0003720 0003720 00000001507 13331225053 024073 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
u"""False plurals.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: False plurals.
date: 2014-06-10 12:31:19
categories: writing
---
Using the incorrect form of the plural.
"""
from proselint.tools import memoize, preferred_forms_check, existence_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "misc.false_plurals.examples"
msg = "The plural is {}"
preferences = [
["talismans", ["talismen"]],
["phenomena", ["phenomenons"]],
]
return preferred_forms_check(text, preferences, err, msg)
@memoize
def check_kudos(text):
"""Check the text."""
err = "misc.false_plurals.kudos"
msg = u"Kudos is singular."
return existence_check(text, ["many kudos"], err, msg)
proselint-0.10.2/proselint/checks/misc/illogic.py 0000664 0003720 0003720 00000002542 13331225053 022661 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Illogic.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: Illogic
date: 2014-06-10 12:31:19
categories: writing
---
Archaism.
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "misc.illogic"
msg = u"'{}' is illogical."
illogics = [
"preplan",
"more than .{1,10} all",
"appraisal valuations?",
"(?:i|you|he|she|it|y'all|all y'all|you all|they) could care less",
"least worst",
"much-needed gaps?",
"much-needed voids?",
"no longer requires oxygen",
"without scarcely",
]
return existence_check(text, illogics, err, msg, offset=1)
@memoize
def check_coin_a_phrase_from(text):
"""Check the text."""
err = "misc.illogic.coin"
msg = "You can't coin an existing phrase. Did you mean 'borrow'?"
regex = "to coin a phrase from"
return existence_check(text, [regex], err, msg, offset=1)
@memoize
def check_without_your_collusion(text):
"""Check the textself."""
err = "misc.illogic.collusion"
msg = "It's impossible to defraud yourself. Try 'aquiescence'."
regex = "without your collusion"
return existence_check(
text, [regex], err, msg, require_padding=False, offset=-1)
proselint-0.10.2/proselint/checks/misc/usage.py 0000664 0003720 0003720 00000003743 13331225053 022347 0 ustar travis travis 0000000 0000000 """Elementary Rules of Usage.
---
layout: post
source: Strunk & White
source_url: ???
title: Elementary Rules of Usage
date: 2014-06-10 12:31:19
categories: writing
---
Strunk & White say:
1. Form the possessive singular of nouns by adding 's.
2. In a series of three or more terms with a conjunction, use a comma after
each term except the last.
3. Enclose parenthetic expressions between commas. ("This rule is difficult to
apply.")
4. Place a comma before a conjunction introducing an independent clause.
5. Do not join independent clauses with a comma; use a semi-colon. Or a period.
6. Do not break sentences in two. Do not use periods for the role of commas.
7. Use a colon after an independent clause if you introduce: a list of
particulars, an appositive, an application, or an illustrative quotation.
8. Use a dash to set off an abrupt break or interruption and to announce a
long appositive or summary.
9. The number of the subject determines the number of the verb. (MDPNB: This
will require nltk & syntactic parsing)
10. Use the proper case(grammatical gender) of pronouns.
* MDPNB: hard case: "Give this work to whoever looks idle." `whoever looks
idle` is the object of `to`.
11. A participial phrase at the beginning of a sentence must refer to the
grammatical subject.
"""
# from proselint.tools import memoize
# import re
# @memoize
# def check(text):
# err = "strunk_white.usage"
# msg = "Use of '{}'. {}"
# bad_words = [
# "obviously",
# "utilize"
# ]
# explanations = {
# "obviously":
# "This is obviously an inadvisable word to use.",
# "utilize":
# r"Do you know anyone who *needs* to utilize the word utilize?"
# }
# errors = []
# for word in bad_words:
# occ = [m for m in re.finditer(word, text.lower())]
# for o in occ:
# errors.append((o.start(), o.end(), err,
# msg.format(word, explanations[word])))
# return errors
proselint-0.10.2/proselint/checks/misc/metaconcepts.py 0000664 0003720 0003720 00000001113 13331225053 023715 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Metaconcepts.
---
layout: post
source: Pinker's book on writing
source_url: ???
title: misuse of scare quotes
date: 2014-06-10 12:31:19
categories: writing
---
Point out misuse of scare quotes.
"""
# from proselint.tools import memoize, existence_check
# @memoize
# def check(text):
# """Suggest the preferred forms."""
# err = "pinker.metaconcepts"
# msg = "Misuse of 'scare quotes'. Delete them."
# narcissism = [
# "the 'take-home message'",
# ]
# return existence_check(text, narcissism, err, msg)
proselint-0.10.2/proselint/checks/misc/institution_name.py 0000664 0003720 0003720 00000001423 13331225053 024625 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Common errors with institution names.
---
layout: post
source: Institution's webpage
source_url: http://bit.ly/2en1zbv,
title: Institution Name
date: 2016-11-16 11:46:19
categories: writing
---
Institution names.
"""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check_vtech(text):
"""Suggest the correct name.
source: Virginia Tech Division of Student Affairs
source_url: http://bit.ly/2en1zbv
"""
err = "institution.vtech"
msg = "Incorrect name. Use '{}' instead of '{}'."
institution = [
["Virginia Polytechnic Institute and State University",
["Virginia Polytechnic and State University"]],
]
return preferred_forms_check(text, institution, err, msg)
proselint-0.10.2/proselint/checks/misc/__init__.py 0000664 0003720 0003720 00000000066 13331225053 022775 0 ustar travis travis 0000000 0000000 """Miscellaneous advice not otherwise categorized."""
proselint-0.10.2/proselint/checks/misc/but.py 0000664 0003720 0003720 00000001014 13331225053 022022 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
u"""Don't start a paragraph with 'But'.
---
layout:
source: Justin Jungé
source_url:
title:
date: 2016-03-10 12:31:19
categories: writing
---
Paragraphs should not start with certain bad words.
"""
from proselint.tools import memoize, existence_check
@memoize
def check(text):
"""Do not start a paragraph with a 'But'."""
err = "misc.but"
msg = u"No paragraph should start with a 'But'."
regex = "(^|([\n\r]+))(\s*)But"
return existence_check(text, [regex], err, msg)
proselint-0.10.2/proselint/checks/misc/currency.py 0000664 0003720 0003720 00000001012 13331225053 023060 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Currency.
---
layout: post
source: SublimeLinter-annotations
source_url: http://bit.ly/16Q7H41
title: symbols
date: 2014-06-10 12:31:19
categories: writing
---
Symbols.
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "misc.currency"
msg = u"Incorrect use of symbols in {}."
symbols = [
"\$[\d]* ?(?:dollars|usd|us dollars)"
]
return existence_check(text, symbols, err, msg)
proselint-0.10.2/proselint/checks/misc/not_guilty.py 0000664 0003720 0003720 00000002076 13331225053 023436 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Not guilty beyond a reasonable doubt.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: Not guilty beyond a reasonable doubt.
date: 2016-03-09 15:50:31
categories: writing
---
This phrasing is ambiguous. The standard by which a jury decides criminal
charges is this: a defendant is guilty only if the evidence shows, beyond a
reasonable doubt, that he or she committed the crime. Otherwise, the defendant
is not guilty. Thus, we say that a defendant was not found "guilty beyond a
reasonable doubt."
If somebody is found not guilty, say "not guilty." Omit the standard
("beyond a reasonable doubt") to prevent a miscue.
Not guilty beyond a reasonable doubt
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "misc.not_guilty"
msg = u"'not guilty beyond a reasonable doubt' is an ambiguous phrasing."
regex = r"not guilty beyond (a |any )?reasonable doubt"
return existence_check(text, [regex], err, msg)
proselint-0.10.2/proselint/checks/misc/capitalization.py 0000664 0003720 0003720 00000004755 13331225053 024262 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Incorrect capitalization.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: incorrect captalization
date: 2014-06-10 12:31:19
categories: writing
---
Incorrect capitalization.
"""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "misc.captalization"
msg = "Incorrect capitalization. '{}' is the preferred form."
list = [
["Stone Age", ["stone age"]],
["space age", ["Space Age"]],
["the American West", ["the American west"]],
["Mother Nature", ["mother nature"]],
]
return preferred_forms_check(text, list, err, msg, ignore_case=False)
# @memoize
# def check_seasons(text):
# """Suggest the preferred forms."""
# err = "MAU102"
# msg = "Seasons shouldn't be capitalized. '{}' is the preferred form."
# list = [
# # ["winter", ["Winter"]],
# # ["fall", ["Fall"]],
# # ["summer", ["Summer"]],
# # ["spring", ["Spring"]],
# ]
# return preferred_forms_check(text, list, err, msg, ignore_case=False)
@memoize
def check_months(text):
"""Suggest the preferred forms."""
err = "MAU102"
msg = "Months should be capitalized. '{}' is the preferred form."
list = [
["January", ["january"]],
["February", ["february"]],
# ["March", ["march"]],
["April", ["april"]],
# ["May", ["may"]],
["June", ["june"]],
["July", ["july"]],
["August", ["august"]],
["September", ["september"]],
["October", ["october"]],
["November", ["november"]],
["December", ["december"]],
]
return preferred_forms_check(text, list, err, msg, ignore_case=False)
@memoize
def check_days(text):
"""Suggest the preferred forms."""
err = "MAU102"
msg = "Days of the week should be capitalized. '{}' is the preferred form."
list = [
["Monday", ["monday"]],
["Tuesday", ["tuesday"]],
["Wednesday", ["wednesday"]],
["Thursday", ["thursday"]],
["Friday", ["friday"]],
["Saturday", ["saturday"]],
["Sunday", ["sunday"]],
]
return preferred_forms_check(text, list, err, msg, ignore_case=False)
proselint-0.10.2/proselint/checks/misc/pretension.py 0000664 0003720 0003720 00000001160 13331225053 023420 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Pretension.
---
layout: post
source: ???
source_url: ???
title: yelling
date: 2014-06-10 12:31:19
categories: writing
---
Never use the phrase 'all hell broke loose'.
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "ogilvy.pretension"
msg = u"Jargon words like this one are the hallmarks of a pretentious ass."
list = [
"reconceptualize",
"demassification",
"attitudinally",
"judgmentally",
]
return existence_check(text, list, err, msg, max_errors=1)
proselint-0.10.2/proselint/checks/misc/chatspeak.py 0000664 0003720 0003720 00000001427 13331225053 023203 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Chatspeak.
---
layout: post
source: ???
source_url: ???
title: textese
date: 2014-06-10 12:31:19
categories: writing
---
Chatspeak.
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "misc.chatspeak"
msg = u"'{}' is chatspeak. Write it out."
words = [
"2day",
"4U",
"AFAIK",
"AFK",
"AFK",
"ASAP",
"B4",
"brb",
"btw",
"cya",
"GR8",
"lol",
"LOL",
"LUV",
"OMG",
"rofl",
"roftl",
"sum1",
"SWAK",
"THNX",
"THX",
"TTYL",
"XOXO"
]
return existence_check(text, words, err, msg)
proselint-0.10.2/proselint/checks/misc/latin.py 0000664 0003720 0003720 00000001417 13331225053 022346 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Back-formations.
---
layout: post
source: The sense of style
source_url: http://amzn.to/1EOUZ5g
title: back-formations
date: 2014-06-10 12:31:19
categories: writing
---
Back-formations.
"""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "pinker.latin"
msg = "Use English. '{}' is the preferred form."
list = [
["other things being equal", ["ceteris paribus"]],
["among other things", ["inter alia"]],
["in and of itself", ["simpliciter"]],
["having made the necessary changes", ["mutatis mutandis"]],
]
return preferred_forms_check(text, list, err, msg)
proselint-0.10.2/proselint/checks/misc/preferred_forms.py 0000664 0003720 0003720 00000016643 13331225053 024432 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Preferred forms.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: preferred forms
date: 2014-06-10 12:31:19
categories: writing
---
Points out preferred forms.
"""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "garner.preferred_forms"
msg = "'{}' is the preferred form."
preferences = [
# Obsolete words
["imprimatur", ["imprimature"]],
# Proper nouns
["Halloween", ["haloween", "hallowe'en"]],
["Khrushchev", ["Khruschev", "Kruschev"]],
["Ku Klux Klan", ["Klu Klux Klan"]],
["Pontius Pilate", ["Pontius Pilot"]],
# Plurals
["hippopotamuses", ["hippopotami"]],
["manifestos", ["manifesti"]],
# ["matrixes", ["matrices"]],
["mongooses", ["mongeese"]],
["narcissi", ["narcissuses"]],
["retinas", ["retinae"]],
["sopranos", ["soprani"]],
["titmice", ["titmouses"]],
# Hyphenated words
["long-standing", ["longstanding"]],
["sans serif", ["sans-serif", "sanserif"]],
["tortfeasor", ["tort feasor", "tort-feasor"]],
["transship", ["tranship", "trans-ship"]],
["transshipped", ["transhipped", "trans-shipped"]],
["transshipping", ["transhipping", "trans-shipping"]],
["non sequitur", ["non-sequitur"]],
# Misc
["attitude", ["mental attitude"]],
["Chief Justice of the United States",
["Chief Justice of the United States Supreme Court",
"Chief Justice of the Supreme Court of the United States."]],
["chitterlings", ["chitlings", "chitlins"]],
["combustion engine", ["combustible engine"]],
["during / throughout", ["for the duration of"]],
["foreclose on", ["foreclose againt"]],
["friend in common", ["mutual friend"]],
["in regard to", ["in regards to"]],
["infectious", ["infectuous"]],
["inferable", ["inferrable", "inferrible"]],
["knowing that", ["in light of the fact that"]],
["lanyard", ["laniard"]],
["largess", ["largesse"]],
["lasagna", ["lasagne"]],
["leery", ["leary"]],
["lend me her", ["loan me her"]],
["lend me his", ["loan me his"]],
["lend me their", ["loan me their"]],
["lend me your", ["loan me your"]],
["lent me her", ["loaned me her"]],
["lent me his", ["loaned me his"]],
["lent me their", ["loaned me their"]],
["lent me your", ["loaned me your"]],
["linguist", ["linguistician"]],
["matzo-ball", ["matzoh-ball",
"matza-ball",
"matzah-ball",
"matsah-ball"]],
["mayoralty", ["mayorality"]],
["mealy-mouthed", ["mealymouthed"]],
["mean-spirited", ["meanspirited"]],
["midwifed", ["midwived"]],
["moniker", ["monicker"]],
["musical revue", ["musical review"]],
["mustache", ["moustache"]],
["nonplussed", ["nonplused"]],
["nonplussing", ["nonplusing"]],
["non sequitur", ["nonsequitur"]],
["not nearly as", ["nowhere near as"]],
["off", ["off of"]],
["podiatrist", ["chiropodist"]],
["podiatry", ["chiropody"]],
["shoo-in", ["shoe-in"]],
["suicide", ["suicide victim"]],
["the highway median", ["the highway medium"]],
["vaipidity", ["vapidness"]],
["weather vane", ["weather vein", "weather vain"]],
["with regard to", ["with regards to"]],
# Idioms
["a couple of people", ["a couple people"]],
["all the time", ["all of the time"]],
["as follows", ["as follow"]],
["bulk large", ["bulk largely"]],
["burying the lede", ["burying the lead"]],
["came to naught", ["came to nought"]],
["come off it", ["come off of it"]],
["corroborating evidence", ["corroborative evidence"]],
["dear departed", ["dearly departed"]],
["default on a loan", ["default to a loan"]],
["draw an inference", ["make an inference"]],
["in the meantime", ["in the meanwhile"]],
["long distances", ["lengthy distances"]],
["madding crowd", ["maddening crowd"]],
["Magna Carta", ["Magna Charta"]],
["marriage of convenience", ["mariage de convenance"]],
["Meanwhile,", ["Meantime,"]],
["Midwest", ["Middle West"]],
["Midwestern", ["Middle Western"]],
["modi operandi", ["modes of operandi"]],
["modus operandi", ["mode of operandi"]],
["motion seconded", ["notion seconded"]],
["mucous membranes", ["mucus membranes"]],
["must pass muster", ["must past muster"]],
["neck-and-neck", ["neck-in-neck"]],
["no-holds-barred", ["no-holes-barred"]],
["oil magnate", ["oil magnet"]],
["punch up the lede", ["punch up the lead"]],
["railroad magnate", ["railroad magnet"]],
["seconded the motion", ["seconded the notion"]],
["statute of limitationas", ["statute of limits"]],
["take precedence over", ["take prescience over"]],
["the last two", ["both of the last two"]],
["the last two", ["both of the last"]],
["unorganic food", ["inorganic food"]],
["vale of tears", ["veil of tears"]],
["Venus flytrap", ["Venus's flytrap", "Venus' flytrap"]],
["was accused of", ["was accused with"]],
# Verbosity
["try to", ["make an attempt to"]],
["try to", ["make attempts to"]],
["try to", ["make efforts to"]],
["tried to", ["made an attempt to"]],
["tried to", ["made attempts to"]],
["tried to", ["made efforts to"]],
["modern", ["modern-day"]],
# Grammar
["be misled", ["be mislead"]],
["was misled", ["was mislead"]],
["were misled", ["were mislead"]],
# Euphemisms
["a search-and-destroy mission", ["armed reconnaissance"]],
["abortion", ["pregnancy termination"]],
["bisexual", ["sexually ambidextrous"]],
["exterminator", ["extermination engineer"]],
["firing", ["permanent layoff"]],
["rat-catcher", ["rodent operative"]],
# Tenses
["mistook", ["mistaked"]],
# Accents
["né", ["ne"]],
["née", ["nee"]],
]
return preferred_forms_check(text, preferences, err, msg)
proselint-0.10.2/proselint/checks/misc/whence.py 0000664 0003720 0003720 00000000714 13331225053 022507 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""From whence it came.
---
layout: post
source: unknown
source_url: unknown
title: whence
date: 2014-06-10 12:31:19
categories: writing
---
From whence it came.
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "misc.whence"
msg = u"The 'from' in 'from whence' is not needed."
return existence_check(text, ["from whence"], err, msg)
proselint-0.10.2/proselint/checks/misc/suddenly.py 0000664 0003720 0003720 00000002727 13331225053 023073 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
u"""Suddenly.
---
layout: post
source: Reference for Writers
source_url: http://bit.ly/1E94vyD
title: suddenly
date: 2014-06-10 12:31:19
categories: writing
---
“Sudden” means quickly and without warning, but using the word “suddenly” both
slows down the action and warns your reader. Do you know what’s more effective
for creating the sense of the sudden? Just saying what happens.
When using “suddenly,” you communicate through the narrator that the action
seemed sudden. By jumping directly into the action, you allow the reader to
experience that suddenness first hand. “Suddenly” also suffers from being
nondescript, failing to communicate the nature of the action itself; providing
no sensory experience or concrete fact to hold on to. Just … suddenly.
Feel free to employ “suddenly” in situations where the suddenness is not
apparent in the action itself. For example, in “Suddenly, I don’t hate you
anymore,” the “suddenly” substantially changes the way we think about the
shift in emotional calibration.
"""
from proselint.tools import memoize, existence_check
@memoize
def check(text):
"""Advice on sudden vs suddenly."""
err = "misc.suddenly"
msg = u"Suddenly is nondescript, slows the action, and warns your reader."
regex = "Suddenly,"
return existence_check(text, [regex], err, msg, max_errors=3,
require_padding=False, offset=-1, ignore_case=False)
proselint-0.10.2/proselint/checks/misc/commercialese.py 0000664 0003720 0003720 00000002402 13331225053 024042 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Commercialese.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: commercialese
date: 2014-06-10 12:31:19
categories: writing
---
Commercialese.
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "misc.commercialese"
msg = u"'{}' is commercialese."
commercialese = [
"acknowledging yours of",
"beg to advise",
"enclosed herewith",
"enclosed please find",
"further to yours of",
"further to your letter",
"in regard to",
"inst\.",
"in the amount of",
"of even date",
"pending receipt of",
"please be advised that",
"please return same",
"pleasure of a reply",
"prox\.",
"pursuant to your request",
"regarding the matter",
"regret to inform",
"thanking you in advance",
"the undersigned",
"this acknowledges your letter",
"ult\."
"we are pleased to note",
"with regard to",
"your favor has come to hand",
"yours of even date"
]
return existence_check(text, commercialese, err, msg, join=True)
proselint-0.10.2/proselint/checks/misc/professions.py 0000664 0003720 0003720 00000001051 13331225053 023603 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Profession.
---
layout: post
source:
source_url:
title: Professions
date: 2014-06-10 12:31:19
categories: writing
---
Professions.
"""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "misc.professions"
msg = "'{}' is the name of that job."
preferences = [
["cobbler", ["shoe repair guy"]],
["geometer", ["geometrist"]],
]
return preferred_forms_check(text, preferences, err, msg)
proselint-0.10.2/proselint/checks/misc/waxed.py 0000664 0003720 0003720 00000003463 13331225053 022352 0 ustar travis travis 0000000 0000000 """Waxed lyrical.
---
layout: post
source: Fowler's Modern English Usage
source_url: bit.ly/1YBG8QJ
title: Waxed lyrical
date: 2016-03-10 14:48:42
categories: writing
---
Fowler's says:
Its primary meaning 'grow larger, increase' (as opposed to 'wane') leads
naturally to the sense 'pass into a specified state or mood, begin to use a
specified tone. In this meaning a following modifier must be an adj. not an
adverb ('He waxed enthusiastic [not enthusiastically] about Australia').
"""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "misc.waxed"
msg = u"The modifier following 'waxed' must be an adj.: '{}' is correct"
waxes = ["wax", "waxes", "waxed", "waxing"]
modifiers = [("ebullient", "ebulliently"),
("ecstatic", "ecstatically"),
("eloquent", "eloquently"),
("enthusiastic", "enthusiastically"),
("euphoric", "euphorically"),
("indignant", "indignantly"),
("lyrical", "lyrically"),
("melancholic", "melancholically"),
("metaphorical", "metaphorically"),
("nostalgic", "nostalgically"),
("patriotic", "patriotically"),
("philosophical", "philosophically"),
("poetic", "poetically"),
("rhapsodic", "rhapsodically"),
("romantic", "romantically"),
("sentimental", "sentimentally")
]
def pairs(word):
return [[word + ' ' + pair[0], [word + ' ' + pair[1]]]
for pair in modifiers]
preferred = []
for word in waxes:
preferred += pairs(word)
return preferred_forms_check(text, preferred, err, msg)
proselint-0.10.2/proselint/checks/misc/narcissism.py 0000664 0003720 0003720 00000001176 13331225053 023414 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Professional narcissism.
---
layout: post
source: Pinker's book on writing
source_url: ???
title: professional narcissism
date: 2014-06-10 12:31:19
categories: writing
---
Points out academic narcissism.
"""
from proselint.tools import memoize, existence_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "pinker.narcissism"
msg = "Professional narcissism. Talk about the subject, not its study."
narcissism = [
"In recent years, an increasing number of [a-zA-Z]{3,}sts have",
]
return existence_check(text, narcissism, err, msg)
proselint-0.10.2/proselint/checks/misc/bureaucratese.py 0000664 0003720 0003720 00000001114 13331225053 024063 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Bureaucratese.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: bureaucratese
date: 2014-06-10 12:31:19
categories: writing
---
Bureaucratese.
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "misc.bureaucratese"
msg = u"'{}' is bureaucratese."
bureaucratese = [
"meet with your approval",
"meets with your approval",
]
return existence_check(text, bureaucratese, err, msg, join=True)
proselint-0.10.2/proselint/checks/misc/punctuation.py 0000664 0003720 0003720 00000001022 13331225053 023600 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Punctuation.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: dates
date: 2014-06-10 12:31:19
categories: writing
---
Dates.
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "garner.punctuation"
msg = u"Misplaced punctuation. It's 'et al.'"
list = [
"et. al",
"et. al."
]
return existence_check(text, list, err, msg, join=True)
proselint-0.10.2/proselint/checks/misc/scare_quotes.py 0000664 0003720 0003720 00000001102 13331225053 023723 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Misuse of scare quotes.
---
layout: post
source: Pinker's book on writing
source_url: ???
title: misuse of scare quotes
date: 2014-06-10 12:31:19
categories: writing
---
Points out misuse of scare quotes.
"""
from proselint.tools import memoize, existence_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "pinker.scare_quotes"
msg = "Misuse of 'scare quotes'. Delete them."
narcissism = [
"the 'take-home message'",
]
return existence_check(text, narcissism, err, msg)
proselint-0.10.2/proselint/checks/misc/composition.py 0000664 0003720 0003720 00000006636 13331225053 023612 0 ustar travis travis 0000000 0000000 """Elementary Rules of Usage.
---
layout: post
source: Strunk & White
source_url: ???
title: Elementary Principles of Composition
date: 2014-06-10 12:31:19
categories: writing
---
Strunk & White say:
1. Choose a suitable design and hold to it.
* MDPNB: Sounds like a principle of `consistency`.
2. Make the paragraph the unit of composition.
* MDPNB: This can be generalized to say something about variability in the
length of paragraphs and sentences. When any device is too often used it
becomes a mannerism.
* MDPNB: Sounds like a principle of `variation`.
3. Use the active voice.
4. Put statements in positive form.
* MDPNB: In some cases this will apply as an invective against the use of
a double negative.
* Ex: He was not very often on time. -> He usually came late.
* Ex:
4.1. Placing negative and positive in opposition makes for a stronger
structure.
* Ex. Not charity, but simple justice.
* Not that I loved Caesar less, but that I loved Rome more.
4.2. Do not use unnecessary auxiliaries or conditionals.
5. Use definite, specific, concrete language.
* A period of unfavorable weather set in. ->It rained every day for a week.
6. Omit needless words.
* `The fact that` is particularly pernicious.
* `who is, which was` and the like are often superfluous
7. Avoid a succession of loose sentences.
* MDPNB Principle of brevity. Take 2.
8. Express coordinate ideas in similar form.
* MDPNB: Principle of parallel structure.
* MDPNB: This one will be hard...
9. Keep related words together.
* MDPNB: Principle of localism in semantics.
10. In summaries, keep to one tense.
* MDPNB: Principle of temporal consistency.
11. Place the emphatic word of a sentence at the end.
* MDPNB: Principle of recency.
"""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "strunk_white.composition"
msg = "Try '{}' instead of '{}'."
bad_forms = [
# Put statements in positive form
["dishonest", ["not honest"]],
["trifling", ["not important"]],
["forgot", ["did not remember"]],
["ignored", ["did not pay (any )?attention to"]],
["distrusted", ["did not have much confidence in"]],
# Omit needless words
["whether", ["the question as to whether"]],
["no doubt", ["there is no doubt but that"]],
["used for fuel", ["used for fuel purposes"]],
["he", ["he is a man who"]],
["hastily", ["in a hasty manner"]],
["this subject", ["this is a subject that"]],
["Her story is strange.", ["Her story is a strange one."]],
["because", ["the reason why is that"]],
["because / since", ["owing to the fact that"]],
["although / though", ["in spite of the fact that"]],
["remind you / notify you",
["call your attention to the fact that"]],
["I did not know that / I was unaware that",
["I was unaware of the fact that"]],
["his failure", ["the fact that he had not succeeded"]],
["my arrival", ["the fact that i had arrived"]]
]
return preferred_forms_check(text, bad_forms, err, msg)
proselint-0.10.2/proselint/checks/misc/debased.py 0000664 0003720 0003720 00000001210 13331225053 022615 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Debased language.
---
layout: post
source: ???
source_url: ???
title: yelling
date: 2014-06-10 12:31:19
categories: writing
---
Too much yelling.
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "misc.debased"
msg = u"Bad usage, debased language, a continuous temptation."
list = [
"a not unjustifiable assumption",
"leaves much to be desired",
"would serve no purpose",
"a consideration which we should do well to bear in mind",
]
return existence_check(text, list, err, msg)
proselint-0.10.2/proselint/checks/misc/phrasal_adjectives.py 0000664 0003720 0003720 00000015477 13331225053 025105 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Phrasal adjectives.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: Phrasal adjectives
date: 2014-06-10 12:31:19
categories: writing
---
Phrasal adjectives.
"""
from proselint.tools import existence_check, preferred_forms_check, memoize
@memoize
def check_ly(text):
"""Check the text."""
err = "garner.phrasal_adjectives.ly"
msg = u"""No hyphen is necessary in phrasal adjectives with an adverb
ending in -ly, unless the -ly adverb is part of a longer
phrase"""
regex = "\s[^\s-]+ly-"
return existence_check(text, [regex], err, msg,
require_padding=False, offset=-1)
@memoize
def check(text):
"""Check the text."""
err = "garner.phrasal_adjectives.examples"
msg = u"""Hyphenate '{1}', a phrasal adjective, as '{0}'."""
list = [
["across-the-board discounts", ["across the board discounts"]],
["acute-care treatment", ["acute care treatment"]],
["agreed-upon answer", ["agreed upon answer"]],
["big-ticket item", ["big ticket item"]],
["class-action lawyer", ["class action lawyer"]],
["criminal-law professor", ["criminal law professor"]],
["cut-and-dried issue", ["cut and dried issue"]],
["downward-sloping line", ["downward sloping line"]],
["English-language learners", ["English language learners"]],
["English-speaking people", ["English speaking people"]],
["even-numbered", ["even numbered"]],
["face-to-face meeting", ["fact to face meeting"]],
["fixed-rate mortgage", ["fixed rate mortgage"]],
["for-profit firm", ["for profit firm"]],
["foreign-sounding name", ["foreign sounding name"]],
["government-owned business", ["government owned business"]],
["hard-and-fast issue", ["hard and fast issue"]],
["head-on collision", ["head on collision"]],
["head-to-head battle", ["head to head battle"]],
["head-to-head competition", ["head to head competition"]],
["health-care coverage", ["heath care coverage"]],
["high-school student", ["high school student"]],
["hit-and-run statute", ["hit and run statute"]],
["HIV-negative person", ["HIV negative person"]],
["HIV-positive person", ["HIV positive person"]],
["information-technology personnel",
["information technology personnel"]],
["intellectual-property rights", ["intellectual property rights"]],
["interest-group pressures", ["interest group pressures"]],
["joint-stock company", ["joint stock company"]],
["kidney-dialysis machine", ["kidney dialysis machine"]],
["long-run costs", ["long run costs"]],
["long-term care", ["long term care"]],
["low-income housing", ["low income housing"]],
["mom-and-pop retail outlet", ["mom and pop retail outlet"]],
["mom-and-pop shop", ["mom and pop shop"]],
["national-security briefing", ["national security briefing"]],
["natural-gas pipeline", ["natural gas pipeline"]],
["no-fault accident", ["no fault accident"]],
["no-fault divorce", ["no fault divorce"]],
["no-fault insurance", ["no fault insurance"]],
["odd-numbered", ["odd numbered"]],
["office-supply store", ["office supply store"]],
["one-way flight", ["one way flight"]],
["one-way window", ["one way window"]],
["open-and-shut case", ["open and shut case"]],
["open-and-shut issue", ["open and shut issue"]],
["open-source community", ["open source community"]],
["optical-scan ballot", ["optical scan ballot"]],
["pension-fund investments", ["pension fund investments"]],
["private-sector employment", ["private sector employment"]],
["profit-seeking efforts", ["profit seeking efforts"]],
["punch-card ballot", ["punch card ballot"]],
["quality-adjusted price", ["quality adjusted price"]],
["razor-sharp intellect", ["razor sharp intellect"]],
["razor-sharp mind", ["razor sharp mind"]],
["razor-sharp mind", ["razor sharp mind"]],
["razor-sharp wit", ["razor sharp wit"]],
["larger-than-life personality", ["larger than life personality"]],
["real-estate prices", ["real estate prices"]],
["real-estate tycoon", ["real estate tycoon"]],
["right-wing militia", ["right wing militia"]],
["round-trip flight", ["round trip flight"]],
["search-and-rescue operation", ["search and rescue operation"]],
["second-largest army", ["second largest army"]],
["shell-shocked mothers", ["shell shocked mothers"]],
["shell-shocked soldiers", ["shell shocked soldiers"]],
["small-business loan", ["small business loan"]],
["small-business owner", ["small business owner"]],
["small-state senator", ["small state senator"]],
["small-animal veterinarian", ["small animal veterinarian"]],
["state-sponsored terrorism", ["state sponsored terrorism"]],
["state-sponsored violence", ["state sponsored violence"]],
["thumbs-up sign", ["thumbs up sign"]],
["time-honored tradition", ["time honored tradition"]],
["U.S.-led campaign", ["U.S. led campaign"]],
["upward-sloping line", ["upward sloping line"]],
["venture-backed company", ["venture backed company"]],
["well-publicized event", ["well publicized event"]],
["wire-transfer service", ["wire transfer service"]],
["yes-or-no question", ["yes or no question"]],
["zero-sum game", ["zero sum game"]],
["stained-glass ceiling", ["stained glass ceiling"]],
["stained-glass window", ["stained glass window"]],
["free-range chicken", ["free range chicken"]],
["free-range poultry", ["free range poultry"]],
["non-profit-making organization",
["non profit making organization",
"non-profit making organization",
"non profit-making organization"]],
# Harmony
["three-part harmony", ["three part harmony"]],
["four-part harmony", ["four part harmony"]],
["six-part harmony", ["six part harmony"]],
["eight-part harmony", ["eight part harmony"]],
# Losses and gains.
["first-quarter loss", ["first quarter loss"]],
["second-quarter loss", ["second quarter loss"]],
["third-quarter loss", ["third quarter loss"]],
["fourth-quarter loss", ["fourth quarter loss"]],
["first-quarter gain", ["first quarter gain"]],
["second-quarter gain", ["second quarter gain"]],
["third-quarter gain", ["third quarter gain"]],
["fourth-quarter gain", ["fourth quarter gain"]],
]
return preferred_forms_check(text, list, err, msg)
proselint-0.10.2/proselint/checks/__init__.py 0000664 0003720 0003720 00000000101 13331225053 022030 0 ustar travis travis 0000000 0000000 """All the checks are organized into modules and places here."""
proselint-0.10.2/proselint/checks/hedging/ 0000775 0003720 0003720 00000000000 13331225202 021330 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/hedging/__init__.py 0000664 0003720 0003720 00000000017 13331225053 023443 0 ustar travis travis 0000000 0000000 """Hedging."""
proselint-0.10.2/proselint/checks/hedging/misc.py 0000664 0003720 0003720 00000001060 13331225053 022636 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Hedging.
---
layout: post
source: Pinker's book on writing
source_url: ???
title: hedging
date: 2014-06-10 12:31:19
categories: writing
---
Points out hedging.
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "hedging.misc"
msg = "Hedging. Just say it."
narcissism = [
"I would argue that",
", so to speak",
"to a certain degree",
]
return existence_check(text, narcissism, err, msg)
proselint-0.10.2/proselint/checks/oxymorons/ 0000775 0003720 0003720 00000000000 13331225202 022000 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/oxymorons/__init__.py 0000664 0003720 0003720 00000000021 13331225053 024106 0 ustar travis travis 0000000 0000000 """Oxymorons."""
proselint-0.10.2/proselint/checks/oxymorons/misc.py 0000664 0003720 0003720 00000002106 13331225053 023310 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Oxymorons.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: Oxymorons
date: 2014-06-10 12:31:19
categories: writing
---
Archaism.
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "oxymorons.misc"
msg = u"'{}' is an oxymoron."
oxymorons = [
"amateur expert",
"increasingly less",
"advancing backwards?",
"alludes explicitly to",
"explicitly alludes to",
"totally obsolescent",
"completely obsolescent",
"generally always",
"usually always",
"increasingly less",
"build down",
"conspicuous absence",
"exact estimate",
"found missing",
"intense apathy",
"mandatory choice",
"nonworking mother",
"organized mess",
# "pretty ugly",
# "sure bet",
# "executive secretary",
]
return existence_check(text, oxymorons, err, msg, offset=1, join=True)
proselint-0.10.2/proselint/checks/needless_variants/ 0000775 0003720 0003720 00000000000 13331225202 023434 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/needless_variants/__init__.py 0000664 0003720 0003720 00000000031 13331225053 025543 0 ustar travis travis 0000000 0000000 """Needless variants."""
proselint-0.10.2/proselint/checks/needless_variants/misc.py 0000664 0003720 0003720 00000042256 13331225053 024756 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Needless variants.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: needless variants
date: 2014-06-10 12:31:19
categories: writing
---
Points out use of needless variants.
"""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "needless_variants.misc"
msg = "Needless variant. '{}' is the preferred form."
preferences = [
# Needless variants
["abolition", ["abolishment"]],
["accessory", ["accessary"]],
["accredit", ["accreditate"]],
["accrual", ["accruement"]],
["accumulate", ["cumulate"]],
["accused", ["accusee"]],
["acquaintance", ["acquaintanceship"]],
["acquittal", ["acquitment"]],
["administer", ["administrate"]],
["administered", ["administrated"]],
["administering", ["administrating"]],
["adulterous", ["adulterate"]],
["advisory", ["advisatory"]],
["advocate", ["advocator"]],
["alleger", ["allegator"]],
["allusive", ["allusory"]],
["ameliorate", ["meliorate"]],
["amorous", ["amative"]],
["amortization", ["amortizement"]],
["amphibology", ["amphiboly"]],
["anachronism", ["parachronism"]],
["anecdotist", ["anecdotalist"]],
["anilingus", ["anilinctus"]],
["anticipatory", ["anticipative"]],
["antithetical", ["antithetic"]],
["applicable", ["applicative"]],
["applicable", ["applicatory"]],
["applicator", ["applier"]],
["approbatory", ["approbative"]],
["arbitrageur", ["arbitrager"]],
["arsenious", ["arsenous"]],
["ascendancy", ["ascendance"]],
["ascendancy", ["ascendence"]],
["ascendancy", ["ascendency"]],
["authorial", ["auctorial"]],
["averment", ["averral"]],
["barbed wire", ["barbwire"]],
["beneficent", ["benefic"]],
["benign", ["benignant"]],
["bestowal", ["bestowment"]],
["betrothal", ["betrothment"]],
["blameworthiness", ["blamableness"]],
["buck naked", ["butt naked"]],
["captor", ["capturer"]],
["carte blanche", ["carta blanca"]],
["casualties", ["casualities"]],
["casualty", ["casuality"]],
["catch fire", ["catch on fire"]],
["catholically", ["catholicly"]],
["ceasefire", ["cease fire"]],
["cellphone", ["cell phone", "cell-phone"]],
["channel", ["channelize"]],
["chaplaincy", ["chaplainship"]],
["chrysalis", ["chrysalid"]],
["chrysalises", ["chrysalids"]],
["cigarette", ["cigaret"]],
["cliquish", ["cliquey", "cliquy"]],
["cognitive", ["cognitional"]],
["cohabit", ["cohabitate"]],
["cohabitant", ["cohabitor"]],
["collodion", ["collodium"]],
["collusive", ["collusory"]],
["commemorative", ["commemoratory"]],
["commonage", ["commonty"]],
["communicative", ["communicatory"]],
["compensatory", ["compensative"]],
["complacency", ["complacence"]],
["complicit", ["complicitous"]],
["compute", ["computate"]],
["comrade", ["camarade"]],
["conciliatory", ["conciliative"]],
["concomitance", ["concomitancy"]],
["condonation", ["condonance"]],
["confirmatory", ["confirmative"]],
["congruence", ["congruency"]],
["connote", ["connotate"]],
["consanguine", ["consanguineal"]],
["conspicuousness", ["conspicuity"]],
["conspirator", ["conspiratorialist"]],
["constitutionalist", ["constitutionist"]],
["contemporaneous", ["cotemporaneous"]],
["contemporary", ["cotemporary"]],
["contigency", ["contingence"]],
["contributory", ["contributary"]],
["contumacy", ["contumacity"]],
["convertible", ["conversible"]],
["conveyance", ["conveyal"]],
["corroborative", ["corroboratory"]],
["coworker", ["coemployee"]],
["curative", ["curatory"]],
["daredevilry", ["daredeviltry"]],
["deceptive", ["deceptious"]],
["defamatory", ["defamative"]],
["degenerative", ["degeneratory"]],
["delimit", ["delimitate"]],
["delusive", ["delusory"]],
["denunciation", ["denouncement"]],
["depositary", ["depositee"]],
["depreciatory", ["depreciative"]],
["deprivation", ["deprival"]],
["derogatory", ["derogative"]],
["destructible", ["destroyable"]],
["dethrone", ["disenthrone"]],
["detoxify", ["detoxicate"]],
["detractive", ["detractory"]],
["deuterogamy", ["digamy"]],
["deviance", ["deviancy"]],
["deviant", ["deviationist"]],
["digitize", ["digitalize"]],
["diminution", ["diminishment"]],
["diplomat", ["diplomatist"]],
["disciplinary", ["disciplinatory"]],
["discriminating", ["discriminant"]],
["disintegrative", ["disintegratory"]],
["dismissal", ["dismission"]],
["disorient", ["disorientate"]],
["disoriented", ["disorientated"]],
["disquiet", ["disquieten"]],
["dissociate", ["disassociate"]],
["distrait", ["distraite"]],
["divergence", ["divergency"]],
["divisible", ["dividable"]],
["doctrinaire", ["doctrinary"]],
["documentary", ["documental"]],
["domesticate", ["domesticize"]],
["doubt", ["misdoubt"]],
["duplicative", ["duplicatory"]],
["dutiful", ["duteous"]],
["educationist", ["educationalist"]],
["educative", ["educatory"]],
["empanel", ["impanel"]],
["encumbrance", ["cumbrance"]],
["endow", ["indow"]],
["endue", ["indue"]],
["enigmas", ["enigmatas"]],
["enlarge", ["enlargen"]],
["epic", ["epical"]],
["eroticism", ["erotism"]],
["ethicist", ["ethician"]],
["ex officio", ["ex officiis"]],
["exculpatory", ["exculpative"]],
["exigency", ["exigence"]],
["exigent", ["exigeant"]],
["exoticism", ["exotism"]],
["expediency", ["expedience"]],
["expedient", ["expediential"]],
["expedient", ["expediential"]],
["extendable", ["extensible"]],
["eyeing", ["eying"]],
["fief", ["fiefdom"]],
["flagrancy", ["flagrance"]],
["flatulence", ["flatulency"]],
["fraudulent", ["defraudulent"]],
["fraudulent", ["fraudful"]],
["funereal", ["funebrial"]],
["geographic", ["geographical"]],
["geometric", ["geometrical"]],
["goatherd", ["goatherder"]],
["grievance", ["aggrievance"]],
["gustatory", ["gustatorial"]],
["habit", ["habitude"]],
["henceforth", ["henceforward"]],
["hesitancy", ["hesitance"]],
["heterogeneous", ["heterogenous"]],
["hierarchical", ["hierarchic"]],
["hindmost", ["hindermost"]],
["honoree", ["honorand"]],
["hypostatize", ["hypostasize"]],
["hysterical", ["hysteric"]],
["idolize", ["idolatrize"]],
["impersonation", ["personation"]],
["impervious", ["imperviable"]],
["importunity", ["importunacy"]],
["impotence", ["impotency"]],
["imprimatur", ["imprimatura"]],
["improper", ["improprietous"]],
["incitement", ["incitation"]],
["inconsistency", ["inconsistence"]],
["incriminate", ["criminate"]],
["inculpatory", ["culpatory"]],
["incurrence", ["incurment"]],
["infrequent", ["unfrequent"]],
["inhibitory", ["inhibitive"]],
["innovative", ["innovational"]],
["inquisitorial", ["inquisitional"]],
["insistence", ["insistment"]],
["instillation", ["instillment"]],
["instinctive", ["instinctual"]],
["insubstantial", ["unsubstantial"]],
["insurer", ["insuror"]],
["insurrectionary", ["insurrectional"]],
["interpret", ["interpretate"]],
["intervention", ["intervenience"]],
["ironic", ["ironical"]],
["irrevocable", ["unrevokable"]],
["judgmental", ["judgmatic"]],
["jury-rigged", ["gerry-rigged"]],
["jury-rigged", ["jerry-rigged"]],
["kaffeeklatsch", ["Coffee klatsch", "coffee klatch"]],
["knickknack", ["nicknack"]],
["labyrinthine", ["labyrinthian"]],
["laudatory", ["laudative"]],
["legitimation", ["legitimatization"]],
["legitimation", ["legitimization"]],
["legitimize", ["legitimatize"]],
["lengthwise", ["lengthways"]],
["licorice", ["liquorice"]],
["life-size", ["life-sized"]],
["lithe", ["lithesome"]],
["loath", ["loth"]],
["lollypop", ["lollipop"]],
["lubricious", ["lubricous"]],
["mayhem", ["maihem"]],
["medical marijuana", ["medicinal marijuana"]],
["minimize", ["minimalize"]],
["monetize", ["monetarize"]],
["movable", ["moveable"]],
["murk", ["mirk"]],
["murky", ["mirky"]],
["narcissism", ["narcism"]],
["neglectful", ["neglective"]],
["negligence", ["negligency"]],
["neologist", ["neologizer"]],
["neurological", ["neurologic"]],
["nictitate", ["nictate"]],
["normality", ["normalcy"]],
["numbness", ["numbedness"]],
["omissible", ["omittable"]],
["onomatopoeic", ["onomatopoetic"]],
["opined", ["opinioned"]],
["optimal advantage", ["optimum advantage"]],
["orient", ["orientate"]],
["outsize", ["outsized"]],
["oversize", ["oversized"]],
["overthrow", ["overthrowal"]],
["pacifist", ["pacificist"]],
["parti-colored", ["parti-color"]],
["parti-colored", ["party-colored"]],
["participatory", ["participative"]],
["partner", ["copartner"]],
["partnership", ["copartnership"]],
# ["password", ["passcode"]], # FIXME
["patina", ["patine"]],
["pederast", ["paederast"]],
["pediatrician", ["pediatrist"]],
["pejorative", ["perjorative"]],
["penumbral", ["penumbrous"]],
["permissive", ["permissory"]],
["permute", ["permutate"]],
["pharmaceutical", ["pharmaceutic"]],
["pleurisy", ["pleuritis"]],
["policyholder", ["policy holder"]],
["policyholder", ["policyowner"]],
["politicize", ["politicalize"]],
["pre-Columbian", ["precolumbian"]],
["precedence", ["precedency"]],
["preceptorial", ["preceptoral"]],
["precipitancy", ["precipitance"]],
["precipitate", ["precipitant"]],
["preclusive", ["preclusory"]],
["prefectorial", ["prefectoral"]],
["preponderantly", ["preponderately"]],
["preservation", ["preserval"]],
["preventive", ["preventative"]],
["proconsulate", ["proconsulship"]],
["procreative", ["procreational"]],
["procurement", ["procurance"]],
["propulsion", ["propelment"]],
["propulsive", ["propulsory"]],
["prosecutory", ["prosecutive"]],
["protective", ["protectory"]],
["provocative", ["provocatory"]],
["prurience", ["pruriency"]],
["psychical", ["psychal"]],
["punitive", ["punitory"]],
["pygmy", ["pygmean", "pygmaen"]],
["quantify", ["quantitate"]],
["questionnaire", ["questionary"]],
["quiescence", ["quiescency"]],
["rabbi", ["rabbin"]],
["reasonableness", ["reasonability"]],
["recidivous", ["recidivistic"]],
["recriminatory", ["recriminative"]],
["recruitment", ["recruital"]],
["recurrence", ["recurrency"]],
["recusal", ["recusation"]],
["recusal", ["recusement"]],
["recusancy", ["recusance"]],
["redemptive", ["redemptory"]],
["referable", ["referrable"]],
["referable", ["referrible"]],
["refutative", ["refutatory"]],
["remission", ["remittal"]],
["remittance", ["remitment"]],
["renounceable", ["renunciable"]],
["renunciation", ["renouncement"]],
["reparative", ["reparatory"]],
["repudiatory", ["repudiative"]],
["requital", ["requitement"]],
["rescission", ["rescindment"]],
["restoration", ["restoral"]],
["reticence", ["reticency"]],
["retributive", ["retributional", "retributionary"]],
["review", ["reviewal"]],
["revision", ["revisal"]],
["revisionary", ["revisional"]],
["revocable", ["revokable", "revokeable"]],
["revolt", ["revolute"]],
["salience", ["saliency"]],
["salutary", ["salutiferous"]],
["sensory", ["sensatory"]],
["sessional", ["sessionary"]],
["shareholder", ["shareowner"]],
["sickly", ["sicklily"]],
["signatory", ["signator"]],
["slander", ["slanderize"]],
["societal", ["societary"]],
["sodomite", ["sodomist"]],
["solicit", ["solicitate"]],
["speculative", ["speculatory"]],
["spirituous", ["spiritous"]],
["statutory", ["statutorial"]],
["submersible", ["submergeable"]],
["submission", ["submittal"]],
["subtle", ["subtile"]],
["succubus", ["succuba"]],
["sufficiency", ["sufficience"]],
["supplicant", ["suppliant"]],
["surmise", ["surmisal"]],
["suspendable", ["suspendible"]],
["swathe", ["enswathe"]],
["synthesize", ["synthetize"]],
["systematize", ["systemize"]],
["T-shirt", ["tee-shirt"]],
["tactile", ["tactual"]],
["tangential", ["tangental"]],
["tautological", ["tautologous"]],
["thenceforth", ["thenceforward"]],
["transience", ["transiency"]],
["transposition", ["transposal"]],
["transposition", ["transposal"]],
["unalterable", ["inalterable"]],
["uncommunicative", ["incommunicative"]],
["uncontrollable", ["incontrollable"]],
["unenforceable", ["nonenforceable"]],
["unnavigable", ["innavigable"]],
["unreasonableness", ["unreasonability"]],
["unsolvable", ["insolvable"]],
["usurpation", ["usurpature"]],
["variational", ["variative"]],
["vegetative", ["vegetive"]],
["vindictive", ["vindicative"]],
["vituperative", ["vituperous"]],
["vociferous", ["vociferant"]],
["volitional", ["volitive"]],
["wolfish", ["wolvish"]],
["wolverine", ["wolverene"]],
["Zoroastrianism", ["Zoroastrism"]],
]
return preferred_forms_check(text, preferences, err, msg)
proselint-0.10.2/proselint/checks/psychology/ 0000775 0003720 0003720 00000000000 13331225202 022123 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/psychology/__init__.py 0000664 0003720 0003720 00000000031 13331225053 024232 0 ustar travis travis 0000000 0000000 """Advice on science."""
proselint-0.10.2/proselint/checks/psychology/misc.py 0000664 0003720 0003720 00000002604 13331225053 023436 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Psychological and psychiatric terms to avoid.
---
layout: post
source: Scott O. Lilienfeld, et al.
source_url: http://dx.doi.org/10.3389/fpsyg.2015.01100
title: psychological and psychiatric terms to avoid
date: 2014-06-10 12:31:19
categories: writing
---
Psychological and psychiatric terms to avoid.
"""
from proselint.tools import preferred_forms_check, existence_check, memoize
@memoize
def check_lie_detector_test(text):
"""Suggest the preferred forms."""
err = "psychology.lie_detector"
msg = "Polygraph machines measure arousal, not lying per se. Try {}."
list = [
["polygraph test", ["lie detector test"]],
["polygraph machine", ["lie detector machine"]],
]
return preferred_forms_check(text, list, err, msg)
@memoize
def check_p_equals_zero(text):
"""Check for p = 0.000."""
err = "psychology.p_equals_zero"
msg = "Unless p really equals zero, you should use more decimal places."
list = [
"p = 0.00",
"p = 0.000",
"p = 0.0000",
]
return existence_check(text, list, err, msg, join=True)
@memoize
def check_mental_telepathy(text):
"""Check for 'mental telepathy'."""
err = "psychology.mental_telepathy"
msg = "This is redundant because all purported telepathy is mental."
return existence_check(text, ["mental telepathy"], err, msg)
proselint-0.10.2/proselint/checks/lexical_illusions/ 0000775 0003720 0003720 00000000000 13331225202 023445 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/lexical_illusions/__init__.py 0000664 0003720 0003720 00000000031 13331225053 025554 0 ustar travis travis 0000000 0000000 """Lexical illusions."""
proselint-0.10.2/proselint/checks/lexical_illusions/misc.py 0000664 0003720 0003720 00000001245 13331225053 024760 0 ustar travis travis 0000000 0000000 """Lexical illusions.
---
layout: post
source: write-good
source_url: https://github.com/btford/write-good
title: Lexical illusion present
date: 2014-06-10 12:31:19
categories: writing
---
A lexical illusion is when a word word is unintentionally repeated twice, and
and this happens most often between line breaks.
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "lexical_illusions.misc"
msg = u"There's a lexical illusion here: a word is repeated."
list = [
"the\sthe",
"am\sam",
"has\shas"
]
return existence_check(text, list, err, msg)
proselint-0.10.2/proselint/checks/annotations/ 0000775 0003720 0003720 00000000000 13331225202 022260 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/annotations/__init__.py 0000664 0003720 0003720 00000000023 13331225053 024370 0 ustar travis travis 0000000 0000000 """Annotations."""
proselint-0.10.2/proselint/checks/annotations/misc.py 0000664 0003720 0003720 00000001224 13331225053 023570 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Annotation left in text.
---
layout: post
source: SublimeLinter-annotations
source_url: http://bit.ly/16Q7H41
title: archaism
date: 2014-06-10 12:31:19
categories: writing
---
Annotation left in text.
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "misc.annotations"
msg = u"Annotation left in text."
annotations = [
"FIXME",
"FIX ME",
"TODO",
"todo",
"ERASE THIS",
"FIX THIS",
]
return existence_check(
text, annotations, err, msg, ignore_case=False, join=True)
proselint-0.10.2/proselint/checks/corporate_speak/ 0000775 0003720 0003720 00000000000 13331225202 023104 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/corporate_speak/__init__.py 0000664 0003720 0003720 00000000030 13331225053 025212 0 ustar travis travis 0000000 0000000 u"""Corporate-speak."""
proselint-0.10.2/proselint/checks/corporate_speak/misc.py 0000664 0003720 0003720 00000002414 13331225053 024416 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Corporate speak.
---
layout: post
source: Travis Bradberry for Inc.com
source_url: http://bit.ly/1IxWnto
title: corporate speak
date: 2014-06-10 12:31:19
categories: writing
---
Avoid these cases of business jargon.
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "corporate_speak.misc"
msg = u"Minimize your use of corporate catchphrases like this one."
list = [
"at the end of the day",
"back to the drawing board",
"hit the ground running",
"get the ball rolling",
"low-hanging fruit",
"thrown under the bus",
"think outside the box",
"let's touch base",
"get my manager's blessing",
"it's on my radar",
"ping me",
"i don't have the bandwidth",
"no brainer",
"par for the course",
"bang for your buck",
"synergy",
"move the goal post",
"apples to apples",
"win-win",
"circle back around",
"all hands on deck",
"take this offline",
"drill-down",
"elephant in the room",
"on my plate",
]
return existence_check(text, list, err, msg, ignore_case=True)
proselint-0.10.2/proselint/checks/malapropisms/ 0000775 0003720 0003720 00000000000 13331225202 022432 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/malapropisms/__init__.py 0000664 0003720 0003720 00000000025 13331225053 024544 0 ustar travis travis 0000000 0000000 """Malaproprisms."""
proselint-0.10.2/proselint/checks/malapropisms/misc.py 0000664 0003720 0003720 00000001127 13331225053 023744 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Malaproprisms.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: Malaproprisms
date: 2014-06-10 12:31:19
categories: writing
---
Archaism.
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "malapropisms.misc"
msg = u"'{}' is a malapropism."
illogics = [
"the infinitesimal universe",
"a serial experience",
"attack my voracity",
]
return existence_check(text, illogics, err, msg, offset=1)
proselint-0.10.2/proselint/checks/hyperbole/ 0000775 0003720 0003720 00000000000 13331225202 021714 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/hyperbole/__init__.py 0000664 0003720 0003720 00000000021 13331225053 024022 0 ustar travis travis 0000000 0000000 """Hyperbole."""
proselint-0.10.2/proselint/checks/hyperbole/misc.py 0000664 0003720 0003720 00000000771 13331225053 023232 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Hyperbolic language.
---
layout: post
source: ???
source_url: ???
title: hyperbolic language
date: 2014-06-10 12:31:19
categories: writing
---
Hyperbolic language.
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "hyperbolic.misc"
msg = u"'{}' is hyperbolic."
words = [
"[a-z]*[!]{2,}",
"[a-z]*\?{2,}"
]
return existence_check(text, words, err, msg)
proselint-0.10.2/proselint/checks/spelling/ 0000775 0003720 0003720 00000000000 13331225202 021540 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/spelling/able_atable.py 0000664 0003720 0003720 00000007160 13331225053 024335 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""-able vs. -atable."""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""-able vs. -atable."""
err = "spelling.able_atable"
msg = "-able vs. -atable. '{}' is the preferred spelling."
preferences = [
["abbreviable", ["abbreviatable"]],
["abdicable", ["abdicatable"]],
["abrogable", ["abrogatable"]],
["accommodable", ["accommodatable"]],
["accumulable", ["accumulatable"]],
["activable", ["activatable"]],
["administrable", ["administratable"]],
["adulterable", ["adulteratable"]],
["affiliable", ["affiliatable"]],
["aggregable", ["aggregatable"]],
["agitable", ["agitatable"]],
["alienable", ["alienatable"]],
["alleviable", ["alleviatable"]],
["allocable", ["allocatable"]],
["ameliorable", ["amelioratable"]],
["annihilable", ["annihilatable"]],
["appreciable", ["appreciatable"]],
["appropriable", ["appropriatable"]],
["arbitrable", ["arbitratable"]],
["articulable", ["articulatable"]],
["calculable", ["calculatable"]],
["communicable", ["communicatable"]],
["compensable", ["compensatable"]],
["confiscable", ["confiscatable"]],
["corroborable", ["corroboratable"]],
["cultivable", ["cultivatable"]],
["delegable", ["delegatable"]],
["delineable", ["delineatable"]],
["demonstrable", ["demonstratable"]],
["detonable", ["detonatable"]],
["differentiable", ["differentiatable"]],
["eradicable", ["eradicatable"]],
["evacuable", ["evacuatable"]],
["evaluable", ["evaluatable"]],
["expropriable", ["expropriatable"]],
["generable", ["generatable"]],
["indicable", ["indicatable"]],
["inebriable", ["inebriatable"]],
["inextirpable", ["inextirpatable"]],
["inextricable", ["inextricatable"]],
["infatuable", ["infatuatable"]],
["infuriable", ["infuriatable"]],
["invalidable", ["invalidatable"]],
["investigable", ["investigatable"]],
["isolable", ["isolatable"]],
["litigable", ["litigatable"]],
["manipulable", ["manipulatable"]],
["medicable", ["medicatable"]],
["navigable", ["navigatable"]],
["obligable", ["obligatable"]],
["obviable", ["obviatable"]],
["operable", ["operatable"]],
["originable", ["originatable"]],
["participable", ["participatable"]],
["penetrable", ["penetratable"]],
["perpetrable", ["perpetratable"]],
["perpetuable", ["perpetuatable"]],
["predicable", ["predicatable"]],
["propagable", ["propagatable"]],
["regulable", ["regulatable"]],
["replicable", ["replicatable"]],
["repudiable", ["repudiatable"]],
["segregable", ["segregatable"]],
["separable", ["separatable"]],
["subjugable", ["subjugatable"]],
["vindicable", ["vindicatable"]],
["violable", ["violatable"]],
["vitiable", ["vitiatable"]]
]
return preferred_forms_check(text, preferences, err, msg)
proselint-0.10.2/proselint/checks/spelling/er_or.py 0000664 0003720 0003720 00000002754 13331225053 023234 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""-er vs. -or."""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""-er vs. -or."""
err = "spelling.er_or"
msg = "-er vs. -or. '{}' is the preferred spelling."
preferences = [
["abductor", ["abducter"]],
["abettor", ["abbeter"]],
["acquirer", ["acquiror"]],
["adapter", ["adaptor"]],
["collector", ["collecter"]],
["conjurer", ["conjuror"]],
["corrupter", ["corruptor"]],
["digester", ["digestor"]],
["dispenser", ["dispensor"]],
["distributor", ["distributer"]],
["endorser", ["endorsor"]],
["eraser", ["erasor"]],
["idolater", ["idolator"]],
["impostor", ["imposter"]],
["infiltrator", ["infiltrater"]],
["investor", ["invester"]],
["manipulator", ["manipulater"]],
["mortgagor", ["mortgager"]],
["persecutor", ["persecuter"]],
["promoter", ["promotor"]],
["promoter", ["promotor"]],
["purveyor", ["purveyer"]],
["requester", ["requestor"]],
["reviser", ["revisor"]],
["surveyor", ["surveyer"]],
]
return preferred_forms_check(text, preferences, err, msg)
proselint-0.10.2/proselint/checks/spelling/able_ible.py 0000664 0003720 0003720 00000016307 13331225053 024023 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""-able vs. -ible."""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""-able vs. -ible."""
err = "spelling.able_ible"
msg = "-able vs. -ible. '{}' is the preferred spelling."
preferences = [
["actionable", ["actionible"]],
["addable", ["addible"]],
["admittable", ["admittible"]],
["advisable", ["advisible"]],
["affectable", ["affectible"]],
["allegeable", ["allegeible"]],
["analyzable", ["analyzible"]],
["annexable", ["annexible"]],
["arrestable", ["arrestible"]],
["ascendable", ["ascendible"]],
["assertable", ["assertible"]],
["assessable", ["assessible"]],
["averageable", ["averageible"]],
["bailable", ["bailible"]],
["blamable", ["blamible"]],
["changeable", ["changeible"]],
["chargeable", ["chargeible"]],
["circumscribable", ["circumscribible"]],
["commensurable", ["commensurible"]],
["committable", ["committible"]],
["condensable", ["condensible"]],
["connectable", ["connectible"]],
["contestable", ["contestible"]],
["contractable", ["contractible"]],
["conversable", ["conversible"]],
["convictable", ["convictible"]],
["correctable", ["correctible"]],
["definable", ["definible"]],
["detectable", ["detectible"]],
["diagnosable", ["diagnosible"]],
["discussable", ["discussible"]],
["endorsable", ["endorsible"]],
["enforceable", ["enforceible"]],
["evadable", ["evadible"]],
["excisable", ["excisible"]],
["excludable", ["excludible"]],
["expandable", ["expandible"]],
["extendable", ["extendible"]],
["extractable", ["extractible"]],
["ignitable", ["ignitible"]],
["immovable", ["immovible"]],
["improvable", ["improvible"]],
["includable", ["includible"]],
["inferable", ["inferible"]],
["inventable", ["inventible"]],
["investable", ["investible"]],
["lapsable", ["lapsible"]],
["lovable", ["lovible"]],
["mixable", ["mixible"]],
["movable", ["movible"]],
["noticeable", ["noticeible"]],
["offendable", ["offendible"]],
["patentable", ["patentible"]],
["persuadable", ["persuadible"]],
["preventable", ["preventible"]],
["processable", ["processible"]],
["protectable", ["protectible"]],
["ratable", ["ratible"]],
["redressable", ["redressible"]],
["referable", ["referible"]],
["retractable", ["retractible"]],
["revisable", ["revisible"]],
["rinsable", ["rinsible"]],
["salable", ["salible"]],
["suspendable", ["suspendible"]],
["tractable", ["tractible"]],
["transferable", ["transferible"]],
["transmittable", ["transmittible"]],
["willable", ["willible"]],
["accessible", ["accessable"]],
["adducible", ["adducable"]],
["admissible", ["admissable"]],
["audible", ["audable"]],
["avertible", ["avertable"]],
["collapsible", ["collapsable"]],
["collectible", ["collectable"]],
["combustible", ["combustable"]],
["compactible", ["compactable"]],
["compatible", ["compatable"]],
["comprehensible", ["comprehensable"]],
["compressible", ["compressable"]],
["concussible", ["concussable"]],
["conductible", ["conductable"]],
["contemptible", ["contemptable"]],
["controvertible", ["controvertable"]],
["convertible", ["convertable"]],
["corrodible", ["corrodable"]],
["corruptible", ["corruptable"]],
["credible", ["credable"]],
["deducible", ["deducable"]],
["deductible", ["deductable"]],
["defeasible", ["defeasable"]],
["defensible", ["defensable"]],
["descendible", ["descendable"]],
["destructible", ["destructable"]],
["diffusible", ["diffusable"]],
["digestible", ["digestable"]],
["discernible", ["discernable"]],
["dismissible", ["dismissable"]],
["divisible", ["divisable"]],
["edible", ["edable"]],
["educible", ["educable"]],
["eligible", ["eligable"]],
["erodible", ["erodable"]],
["exhaustible", ["exhaustable"]],
["expressible", ["expressable"]],
["fallible", ["fallable"]],
["feasible", ["feasable"]],
["flexible", ["flexable"]],
["forcible", ["forcable"]],
["fusible", ["fusable"]],
["gullible", ["gullable"]],
["horrible", ["horrable"]],
["impressible", ["impressable"]],
["inadmissible", ["inadmissable"]],
["incorrigible", ["incorrigable"]],
["indelible", ["indelable"]],
["inexpressible", ["inexpressable"]],
["intelligible", ["intelligable"]],
["interfusible", ["interfusable"]],
["invincible", ["invincable"]],
["irascible", ["irascable"]],
["irresistible", ["irresistable"]],
["legible", ["legable"]],
["negligible", ["negligable"]],
["omissible", ["omissable"]],
["oppressible", ["oppressable"]],
["ostensible", ["ostensable"]],
["perceptible", ["perceptable"]],
["perfectible", ["perfectable"]],
["permissible", ["permissable"]],
["plausible", ["plausable"]],
["possible", ["possable"]],
["producible", ["producable"]],
["reducible", ["reducable"]],
["remissible", ["remissable"]],
["reprehensible", ["reprehensable"]],
["repressible", ["repressable"]],
["resistible", ["resistable"]],
["responsible", ["responsable"]],
["reversible", ["reversable"]],
["revertible", ["revertable"]],
["risible", ["risable"]],
["seducible", ["seducable"]],
["sensible", ["sensable"]],
["submersible", ["submersable"]],
["submergible", ["submergable"]],
["suggestible", ["suggestable"]],
["suppressible", ["suppressable"]],
["susceptible", ["susceptable"]],
["terrible", ["terrable"]],
["transfusible", ["transfusable"]],
["transmissible", ["transmissable"]],
["uncollectible", ["uncollectable"]],
["vendible", ["vendable"]],
["visible", ["visable"]]
]
return preferred_forms_check(text, preferences, err, msg)
proselint-0.10.2/proselint/checks/spelling/__init__.py 0000664 0003720 0003720 00000000020 13331225053 023645 0 ustar travis travis 0000000 0000000 """Spelling."""
proselint-0.10.2/proselint/checks/spelling/misc.py 0000664 0003720 0003720 00000014312 13331225053 023052 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Misspellings.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: misspellings
date: 2014-06-10 12:31:19
categories: writing
---
Points out misspellings.
"""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "spelling.misc"
msg = "Misspelling. '{}' is the preferred spelling."
misspellings = [
["a lot", ["alot"]],
["academically", ["academicly"]],
["accidentally", ["accidently"]],
["accommodable", ["accomodatable"]],
["anilingus", ["analingus"]],
["aren't i", ["amn't i"]],
["aren't i", ["an't i"]],
["barbed wire", ["bob wire"]],
["chargeable", ["chargable"]],
["chiffonier", ["chiffonnier"]],
["chintzy", ["chinchy"]],
["chipotle", ["chipolte"]],
["chlorophyll", ["chlorophyl"]],
["chocolaty", ["chocolatey"]],
["chronicle", ["chronical"]],
["chronicles", ["chronicals"]],
["coleslaw", ["coldslaw"]],
["choosy", ["choosey"]],
["cummerbund", ["kummerbund"]],
["financeable", ["financable"]],
["fluorescent", ["flourescent"]],
["fluoridation", ["flouridation"]],
["fluoride", ["flouride"]],
["foreclose", ["forclose"]],
["forswear", ["foreswear"]],
["free rein", ["free reign"]],
["gist", ["jist"]],
["glamour", ["glamor"]],
["granddad", ["grandad"]],
["grandpa", ["granpa"]],
["highfalutin", ["highfaluting", "highfalutin'", "hifalutin"]],
["Hippocratic", ["hypocratic"]],
["hirable", ["hireable"]],
["holistic", ["wholistic"]],
["ideology", ["idealogy"]],
["idiosyncrasy", ["ideosyncracy"]],
["improvise", ["improvize"]],
["incurrence", ["incurment"]],
["inevitability", ["inevitableness"]],
["innovate", ["inovate"]],
["inoculation", ["innoculation", "inocculation"]],
["integral", ["intergral"]],
["inundate", ["innundate"]],
["inundated", ["innundated"]],
["inundates", ["innundates"]],
["inundating", ["innundating"]],
["iridescent", ["irridescent"]],
["irrelevant", ["irrevelant"]],
["jujitsu", ["jiujutsu"]],
["kaleidoscope", ["kaleidascope"]],
["knickknack", ["knicknack"]],
["lassos", ["lassoes"]],
["lessee", ["leasee"]],
["lessor", ["leasor"]],
["liaison", ["liason"]],
["liaison", ["laison"]],
["lightning rod", ["lightening rod"]],
["struck by lightning", ["struck by lightening"]],
["liquefy", ["liquify"]],
["loathsome", ["loathesome"]],
["lodestar", ["loadstar"]],
["to make do", ["to make due"]],
["mademoiselle", ["madamoiselle"]],
["martial arts", ["marshall arts"]],
["court-martial", ["court marshall", "court-marshall"]],
["maelstrom", ["maelstorm"]],
["mafia", ["maffia"]],
["mafiosi", ["mafiosos"]],
["mangoes", ["mangos"]],
["marijuana", ["marihuana"]],
["marshmallow", ["marshmellow"]],
["martial law", ["marshall law"]],
["massacring", ["massacering", "massacreing"]],
["measles", ["measels"]],
["memento", ["momento"]],
["minuscule", ["miniscule"]],
["mileage", ["milage"]],
["milieu", ["mileau"]],
["millennium", ["millenium"]],
["millennia", ["millenia"]],
["millenniums", ["milleniums"]],
["millipede", ["millepede"]],
["millionaire", ["millionnaire"]],
["milquetoast", ["milktoast"]],
["mimicked", ["mimiced"]],
["mimicking", ["mimicing"]],
["misspelling", ["mispelling"]],
["mischievous", ["mischievious"]],
["moccasin", ["mocasin", "moccassin", "mocassin"]],
["monologue", ["monolog"]],
["monologuist", ["monologist"]],
["naphtha", ["naptha"]],
["navel orange", ["naval orange"]],
["neckwear", ["neckware"]],
["newsstand", ["newstand"]],
["non sequitur", ["non sequiter",
"non sequitar",
"non sequitor"]],
["nouveau riche", ["nouveau rich"]],
["occurred", ["occured"]],
["plantar fasciitis", ["planter fasciitis", "plantar fascitis"]],
["pledgeable", ["pledgable", "pledgeble"]],
["portentous", ["portentuous", "portentious"]],
["praying mantis", ["preying mantis"]],
["preestablished", ["prestablished"]],
["preexisting", ["prexisting"]],
["presumptuous", ["presumptious"]],
["rarefy", ["rarify"]],
["reckless", ["wreckless"]],
["remuneration", ["renumeration"]],
["restaurateur", ["restauranteur"]],
["retractable", ["retractible"]],
["reverie", ["revery"]],
["spicy", ["spicey"]],
["stupefy", ["stupify"]],
["subtly", ["subtley"]],
["till", ["\'till?"]],
["tinderbox", ["tenderbox"]],
["timpani", ["tympani"]],
["a timpani", ["a timpano"]],
["umpteenth", ["umteenth"]],
["verbiage", ["verbage"]],
]
return preferred_forms_check(text, misspellings, err, msg)
proselint-0.10.2/proselint/checks/spelling/em_im_en_in.py 0000664 0003720 0003720 00000004271 13331225053 024360 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Em vs. im, en vs. in."""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""em- vs. en-, im- vs. in-."""
err = "spelling.em_im_en_in"
msg = "em-, im-, en-, and in-. '{}' is the preferred spelling."
preferences = [
["embalm", ["imbalm"]],
["embark", ["imbark"]],
["embed", ["imbed"]],
["embitter", ["imbitter"]],
["emblaze", ["imblaze"]],
["embody", ["imbody"]],
["embolden", ["imbolden"]],
["embosom", ["imbosom"]],
["embower", ["imbower"]],
["embrown", ["imbrown"]],
["empanel", ["impanel"]],
["empower", ["impower"]],
["encage", ["incage"]],
["encapsulate", ["incapsulate"]],
["encase", ["incase"]],
["enclasp", ["inclasp"]],
["encumber", ["incumber"]],
["encumbrance", ["incumbrance"]],
["endow", ["indow"]],
["endowment", ["indowment"]],
["endue", ["indue"]],
["enfold", ["infold"]],
["engraft", ["ingraft"]],
["engulf", ["ingulf"]],
["enlace", ["inlace"]],
["enmesh", ["inmesh"]],
["ensheathe", ["insheathe"]],
["enshrine", ["inshrine"]],
["ensnare", ["insnare"]],
["ensoul", ["insoul"]],
["ensphere", ["insphere"]],
["enthrall", ["inthrall"]],
["enthrone", ["inthrone"]],
["entitle", ["intitle"]],
["entomb", ["intomb"]],
["entreat", ["intreat"]],
["entrench", ["intrench"]],
["entrust", ["intrust"]],
["entwine", ["intwine"]],
["entwist", ["intwist"]],
["enwind", ["inwind"]],
["enwrap", ["inwrap"]],
["enwreathe", ["inwreathe"]],
["imbrue", ["embrue"]],
["impale", ["empale"]],
["impoverish", ["empoverish"]],
["inflame", ["enflame"]],
["ingrain", ["engrain"]],
["inure", ["enure"]],
]
return preferred_forms_check(text, preferences, err, msg)
proselint-0.10.2/proselint/checks/spelling/in_un.py 0000664 0003720 0003720 00000001021 13331225053 023220 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""in- vs. un-."""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""in- vs un-."""
err = "spelling.in_un"
msg = "in- vs. un-. '{}' is the preferred spelling."
preferences = [
["inadvisable", ["unadvisable"]],
["inalienable", ["unalienable"]],
["inexpressive", ["unexpressive"]],
["infeasible", ["unfeasible"]],
]
return preferred_forms_check(text, preferences, err, msg)
proselint-0.10.2/proselint/checks/spelling/athletes.py 0000664 0003720 0003720 00000002654 13331225053 023736 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Misspellings.
---
layout: post
source: The Wall Street Journal
source_url: http://on.wsj.com/1rksm8k
title: misspellings
date: 2014-06-10 12:31:19
categories: writing
---
Points out misspellings.
"""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "spelling.athletes"
msg = "Misspelling of athlete's name. '{}' is the preferred form."
misspellings = [
["Dwyane Wade", ["Dwayne Wade"]],
["Miikka Kiprusoff", ["Mikka Kiprusoff"]],
["Mark Buehrle", ["Mark Buerhle"]],
["Skylar Diggins", ["Skyler Diggins"]],
["Agnieszka Radwanska", ["Agnieska Radwanska"]],
["J.J. Redick", ["J.J. Reddick"]],
["Manny Pacquiao", ["Manny Packquaio"]],
["Antawn Jamison", ["Antwan Jamison"]],
["Cal Ripken", ["Cal Ripkin"]],
["Jhonny Peralta", ["Johnny Peralta"]],
["Monta Ellis", ["Monte Ellis"]],
["Alex Rodriguez", ["Alex Rodriquez"]],
["Mark Teixeira", ["Mark Texeira"]],
["Brett Favre", ["Brett Farve"]],
["Torii Hunter", ["Tori Hunter"]],
["Stephen Curry", ["Stephon Curry"]],
["Mike Krzyzewski", ["Mike Kryzewski"]],
]
return preferred_forms_check(text, misspellings, err, msg)
proselint-0.10.2/proselint/checks/uncomparables/ 0000775 0003720 0003720 00000000000 13331225202 022556 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/uncomparables/__init__.py 0000664 0003720 0003720 00000000041 13331225053 024666 0 ustar travis travis 0000000 0000000 """Comparing an uncomparable."""
proselint-0.10.2/proselint/checks/uncomparables/misc.py 0000664 0003720 0003720 00000010217 13331225053 024070 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
u"""Comparing uncomparables.
---
layout: post
source: David Foster Wallace
source_url: http://www.telegraph.co.uk/a/9715551
title: Comparing an uncomparable
date: 2014-06-10 12:31:19
categories: writing
---
David Foster Wallace says:
> This is one of a class of adjectives, sometimes called “uncomparables”, that
can be a little tricky. Among other uncomparables are precise, exact, correct,
entire, accurate, preferable, inevitable, possible, false; there are probably
two dozen in all. These adjectives all describe absolute, non-negotiable
states: something is either false or it’s not; something is either inevitable
or it’s not. Many writers get careless and try to modify uncomparables with
comparatives like more and less or intensives like very. But if you really
think about them, the core assertions in sentences like “War is becoming
increasingly inevitable as Middle East tensions rise”; “Their cost estimate was
more accurate than the other firms’”; and “As a mortician, he has a very unique
attitude” are nonsense. If something is inevitable, it is bound to happen; it
cannot be bound to happen and then somehow even more bound to happen. Unique
already means one-of-a-kind, so the adj. phrase very unique is at best
redundant and at worst stupid, like “audible to the ear” or “rectangular in
shape”. You can blame the culture of marketing for some of this difficulty.
As the number and rhetorical volume of US ads increase, we become inured to
hyperbolic language, which then forces marketers to load superlatives and
uncomparables with high-octane modifiers (special - very special -
Super-special! - Mega-Special!!), and so on. A deeper issue implicit in the
problem of uncomparables is the dissimilarities between Standard Written
English and the language of advertising. Advertising English, which probably
deserves to be studied as its own dialect, operates under different syntactic
rules than SWE, mainly because AE’s goals and assumptions are different.
Sentences like “We offer a totally unique dining experience”; “Come on down and
receive your free gift”; and “Save up to 50 per cent… and more!” are perfectly
OK in Advertising English — but this is because Advertising English is aimed at
people who are not paying close attention. If your audience is by definition
involuntary, distracted and numbed, then free gift and totally unique stand a
better chance of penetrating — and simple penetration is what AE is all about.
One axiom of Standard Written English is that your reader is paying close
attention and expects you to have done the same.
"""
import re
from proselint.tools import memoize
import itertools
@memoize
def check(text):
"""Check the text."""
err = "uncomparables.misc"
msg = "Comparison of an uncomparable: '{}' is not comparable."
comparators = [
"most",
"more",
"less",
"least",
"very",
"quite",
"largely",
"extremely",
"increasingly",
"kind of",
"mildly"
]
uncomparables = [
"absolute",
"adequate",
"chief",
"complete",
"correct",
"devoid",
"entire",
"false",
"fatal",
"favorite",
"final",
"ideal",
"impossible",
"inevitable",
"infinite",
"irrevocable",
"main",
"manifest",
"only",
"paramount",
"perfect",
"perpetual",
"possible",
"preferable",
"principal",
"singular",
"stationary",
"sufficient",
"true",
"unanimous",
"unavoidable",
"unbroken",
"uniform",
"unique",
"universal",
"void",
"whole",
]
exceptions = [
("more", "perfect"),
("more", "possible") # FIXME
]
all = ["\\b" + i[0] + "\s" + i[1] + "[\W$]" for i in itertools.product(
comparators, uncomparables) if i not in exceptions]
occ = re.finditer("|".join(all), text.lower())
return [(o.start(), o.end(), err, msg.format(o.group(0)), None)
for o in occ]
proselint-0.10.2/proselint/checks/redundancy/ 0000775 0003720 0003720 00000000000 13331225202 022057 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/redundancy/__init__.py 0000664 0003720 0003720 00000000022 13331225053 024166 0 ustar travis travis 0000000 0000000 """Redundancy."""
proselint-0.10.2/proselint/checks/redundancy/misc.py 0000664 0003720 0003720 00000060765 13331225053 023406 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Redundancy."""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "redundancy.wallace"
msg = "Redundancy. Use '{}' instead of '{}'."
redundancies = [
["rectangular", ["rectangular in shape"]],
["audible", ["audible to the ear"]],
]
return preferred_forms_check(text, redundancies, err, msg)
@memoize
def check_garner(text):
"""Suggest the preferred forms.
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
"""
err = "redundancy.garner"
msg = "Redundancy. Use '{}' instead of '{}'."
redundancies = [
["adequate", ["adequate enough"]],
["admitted", ["self-admitted"]],
["affidavit", ["sworn affidavit"]],
["agreement", ["mutual agreement"]],
["alumnus", ["former alumnus"]],
["antithetical", ["directly antithetical"]],
["approximately", ["approximately about"]],
["associate", ["associate together(?: in groups)?"]],
["bivouac", ["temporary bivouac", "bivouac camp"]],
["blend", ["blend together"]],
["but", ["but nevertheless"]],
["charged with...", ["accused of a charge"]],
["circumstances of", ["circumstances surrounding"]],
["circumstances", ["surrounding circumstances"]],
["close", ["close proximity"]],
["collaborate", ["collaborate together"]],
["collaborator", ["fellow collaborator"]],
["collaborators", ["fellow collaborators"]],
["collocated", ["collocated together"]],
["colleagues", ["fellow colleagues"]],
["combine", ["combine together"]],
["complacent", ["self-complacent"]],
["confessed", ["self-confessed"]],
["connect", ["connect together"]],
["consensus", ["(?:general )?consensus of opinion"]],
["consolidate", ["consolidate together"]],
["continues to", ["still continues to"]],
["contradictory", ["mutually contradictory"]],
["cooperation", ["mutual cooperation"]],
["couple", ["couple together"]],
["crisis", ["serious crisis"]],
["eliminate", ["entirely eliminate"]],
["especially", ["most especially"]],
["fact", ["actual fact"]],
["facts", ["true facts"]],
["forecast", ["future forecast"]],
["founding fathers", ["founding forefathers"]],
["free", ["free and gratis"]],
["free", ["free gratis"]],
["full", ["completely full"]],
["fundamentals", ["basic fundamentals"]],
["gift", ["free gift"]],
["innovation", ["new innovation"]],
["interact", ["interact with each other"]],
["large", ["large-size"]],
["meld", ["meld together"]],
["merge", ["merge together"]],
["mingle", ["mingle together"]],
["mix", ["mix together"]],
["mutual feelings", ["mutual feelings for eachother"]],
["mutual respect", ["mutual respect for each other"]],
["native citizen", ["native-born citizen"]],
["necessity", ["absolute necessity"]],
["obvious", ["blatantly obvious"]],
["pause", ["pause for a moment"]],
["planning", ["advance planning"]],
["plans", ["future plans"]],
["pooled", ["pooled together"]],
["potable water", ["potable drinking water"]],
["potable water", ["potable drinking water"]],
["recruit", ["new recruit"]],
["reelected", ["reelected for another term"]],
["refer", ["refer back"]],
["regress", ["regress back"]],
["repay them", ["repay them back"]],
["repay", ["repay back"]],
["repeat", ["repeat again"]],
["repeat", ["repeat back"]],
["repeat", ["repeat the same"]],
["repeated", ["repeated the same"]],
["reprieve", ["temporary reprieve"]],
["respite", ["brief respite"]],
["retirement", ["retiral", "retiracy"]],
["retreat", ["retreat back"]],
["return", ["return back"]],
["scrutinize", ["closely scrutinize"]],
["software", ["software program"]],
["surrounded", ["surrounded on all sides"]],
["the nation", ["the whole entire nation"]],
["throughout the", ["throughout the entire"]],
["timpani", ["timpani drum"]],
["twins", ["pair of twins"]],
["vacancy", ["unfilled vacancy"]],
["various", ["various different"]],
["veteran", ["former veteran"]],
["visible", ["visible to the eye"]],
["vocation", ["professional vocation"]],
["while", ["while at the same time"]],
]
return preferred_forms_check(text, redundancies, err, msg)
@memoize
def check_nordquist(text):
"""Suggest the preferred forms.
source: Richard Nordquist
source_url: http://grammar.about.com/bio/Richard-Nordquist-22176.htm
"""
err = "redundancy.nordquist"
msg = "Redundancy. Use '{}' instead of '{}'."
redundancies = [
["essential", ["absolutely essential"]],
["necessary", ["absolutely necessary"]],
["a.m.", ["a.m. in the morning"]],
["p.m.", ["p.m. at night"]],
]
return preferred_forms_check(text, redundancies, err, msg)
@memoize
def check_atd(text):
"""Check for redundancies from After the Deadline."""
err = "after_the_deadline.redundancy"
msg = "Redundancy. Use '{}' instead of '{}'."
redundancies = [
[u"Bō", ["Bo Staff"]],
["Challah", ["Challah bread"]],
["Hallah", ["Hallah bread"]],
["Challah", ["Challah bread"]],
["I", ["I myself", "I personally"]],
["Mount Fuji", ["Mount Fujiyama"]],
["Milky Way", ["Milky Way galaxy"]],
["Rio Grande", ["Rio Grande river"]],
["adage", ["old adage"]],
["add", ["add a further", "add an additional"]],
["advance", ["advance forward"]],
["alternative", ["alternative choice"]],
["amaretto", ["amaretto almond"]],
["annihilate", ["completely annihilate"]],
["anniversary", ["annual anniversary"]],
["anonymous", ["unnamed anonymous"]],
["as", ["equally as"]],
["ascend", ["ascend up"]],
["ask", ["ask the question"]],
["assemble", ["assemble together"]],
["at present the", ["at the present time the"]],
["at this point", ["at this point in time"]],
["attach", ["attach together"]],
["autumn", ["autumn season"]],
["bald", ["bald-headed"]],
["balsa", ["balsa wood"]],
["belongings", ["personal belongings"]],
["benefits", ["desirable benefits"]],
["bento", ["bento box"]],
["best", ["best ever"]],
["bit", ["tiny bit"]],
["blend", ["blend together"]],
["bond", ["common bond"]],
["bonus", ["added bonus", "extra bonus"]],
["bouquet", ["bouquet of flowers"]],
["breakthrough", ["major breakthrough"]],
["bride", ["new bride"]],
["brief", ["brief in duration"]],
["bruin", ["bruin bear"]],
["hot", ["burning hot"]],
["cacophony", ["cacophony of sound"]],
["cameo", ["brief cameo", "cameo appearance"]],
["cancel", ["cancel out"]],
["cash", ["cash money"]],
["chai", ["chai tea"]],
["chance", ["random chance"]],
["charm", ["personal charm"]],
["circle", ["circle around", "round circle"]],
["circulate", ["circulate around"]],
["classify", ["classify into groups"]],
["classmates", ["fellow classmates"]],
["cliche", ["old cliche", "overused cliche"]],
["climb", ["climb up"]],
["clock", ["time clock"]],
["collaborate", ["collaborate together"]],
["collaboration", ["joint collaboration"]],
["colleague", ["fellow colleague"]],
["combine", ["combine together"]],
["commute", ["commute back and forth"]],
["compete", ["compete with each other"]],
["comprise", ["comprise of"]],
["comprises", ["comprises of"]],
["conceived", ["first conceived"]],
["conclusion", ["final conclusion"]],
["confer", ["confer together"]],
["confrontation", ["direct confrontation"]],
# ["confused", ["confused state"]],
["connect", ["connect together", "connect up"]],
["consensus", ["consensus of opinion", "general consensus"]],
["consult", ["consult with"]],
["conversation", ["oral conversation"]],
["cool", ["cool down"]],
["cooperate", ["cooperate together"]],
["cooperation", ["mutual cooperation"]],
["copy", ["duplicate copy"]],
["core", ["inner core"]],
["cost", ["cost the sum of"]],
["could", ["could possibly"]],
["coupon", ["money-saving coupon"]],
["created", ["originally created"]],
["crisis", ["crisis situation"]],
["crouch", ["crouch down"]],
["currently", ["now currently"]],
["custom", ["old custom", "usual custom"]],
["danger", ["serious danger"]],
["dates", ["dates back"]],
["decision", ["definite decision"]],
["depreciate", ["depreciate in value"]],
["descend", ["descend down"]],
["destroy", ["totally destroy"]],
["destroyed", ["completely destroyed"]],
["destruction", ["total destruction"]],
["details", ["specific details"]],
["dilemma", ["difficult dilemma"]],
["disappear", ["disappear from sight"]],
["discovered", ["originally discovered"]],
["dive", ["dive down"]],
["done", ["over and done with"]],
["drawing", ["illustrated drawing"]],
["drop", ["drop down"]],
["dune", ["sand dune"]],
["during", ["during the course of"]],
["dwindle", ["dwindle down"]],
["dwindled", ["dwindled down"]],
["every", ["each and every"]],
["earlier", ["earlier in time"]],
["eliminate", ["completely eliminate", "eliminate altogether",
"entirely eliminate"]],
["ember", ["glowing ember"]],
["embers", ["burning embers"]],
["emergency", ["emergency situation", "unexpected emergency"]],
["empty", ["empty out"]],
["enclosed", ["enclosed herein"]],
["end", ["final end"]],
["engulfed", ["completely engulfed"]],
["enter", ["enter in", "enter into"]],
["equal", ["equal to one another"]],
["eradicate", ["eradicate completely"]],
["essential", ["absolutely essential"]],
["estimated at", ["estimated at about",
"estimated at approximately",
"estimated at around"]],
["etc.", ["and etc."]],
["evolve", ["evolve over time"]],
["exaggerate", ["over exaggerate"]],
["exited", ["exited from"]],
["experience", ["actual experience", "past experience"]],
["experts", ["knowledgeable experts"]],
["extradite", ["extradite back"]],
["face the consequences", ["face up to the consequences"]],
["face the fact", ["face up to the fact"]],
["face the challenge", ["face up to the challenge"]],
["face the problem", ["face up to the problem"]],
["facilitate", ["facilitate easier"]],
["fact", ["established fact"]],
["facts", ["actual facts", "hard facts", "true facts"]],
["fad", ["passing fad"]],
["fall", ["fall down"]],
["fall", ["fall season"]],
["feat", ["major feat"]],
["feel", ["feel inside"]],
["feelings", ["inner feelings"]],
["few", ["few in number"]],
["filled", ["completely filled", "filled to capacity"]],
["first", ["first of all"]],
["first time", ["first time ever"]],
["fist", ["closed fist"]],
["fly", ["fly through the air"]],
["focus", ["focus in", "main focus"]],
["follow", ["follow after"]],
["for example", ["as for example"]],
# ["foremost", ["first and foremost"]],
["forever", ["forever and ever"]],
["free", ["for free"]],
["friend", ["personal friend"]],
["friendship", ["personal friendship"]],
["full", ["full to capacity"]],
["fundamentals", ["basic fundamentals"]],
["fuse", ["fuse together"]],
["gather", ["gather together", "gather up"]],
["get up", ["get up on his feet", "get up on your feet"]],
["gift", ["free gift"]],
["gifts", ["free gifts"]],
["goal", ["ultimate goal"]],
# ["graduate", ["former graduate"]],
["grow", ["grow in size"]],
["guarantee", ["absolute guarantee"]],
["gunman", ["armed gunman"]],
["gunmen", ["armed gunmen"]],
["habitat", ["native habitat"]],
["had done", ["had done previously"]],
["halves", ["two equal halves"]],
# ["has", ["has got"]],
# ["have", ["have got"]],
["haven", ["safe haven"]],
# ["he", ["he himself"]],
["heat", ["heat up"]],
["history", ["past history"]],
["hoist", ["hoist up"]],
["hole", ["empty hole"]],
["honcho", ["head honcho"]],
["ice", ["frozen ice"]],
["ideal", ["perfect ideal"]],
["identical", ["same identical"]],
["identification", ["positive identification"]],
["imports", ["foreign imports"]],
["impulse", ["sudden impulse"]],
["in fact", ["in actual fact"]],
["in the yard", ["outside in the yard"]],
["inclusive", ["all inclusive"]],
["incredible", ["incredible to believe"]],
["incumbent", ["present incumbent"]],
# ["indicted", ["indicted on a charge"]],
["industry", ["private industry"]],
["injuries", ["harmful injuries"]],
["innovation", ["new innovation"]],
["innovative", ["innovative new", "new innovative"]],
# ["input", ["input into"]],
["instinct", ["natural instinct", "naturally instinct"]],
["integrate", ["integrate together",
"integrate with each other"]],
["interdependent", ["interdependent on each other",
"mutually interdependent"]],
["introduced", ["introduced for the first time"]],
["invention", ["new invention"]],
["kneel", ["kneel down"]],
["knots", ["knots per hour"]],
# ["last", ["last of all"]],
# ["later", ["later time"]],
["lift", ["lift up"]],
["lingers", ["still lingers"]],
["look to the future", ["look ahead to the future"]],
["love triangle", ["three-way love triangle"]],
["maintained", ["constantly maintained"]],
["manually", ["manually by hand"]],
["marina", ["boat marina"]],
["may", ["may possibly"]],
["meet", ["meet together", "meet with each other"]],
["memories", ["past memories"]],
["merge", ["merge together"]],
["merged", ["merged together"]],
["meshed", ["meshed together"]],
["midnight", ["twelve midnight"]],
["migraine", ["migraine headache"]],
["minestrone", ["minestrone soup"]],
["mix", ["mix together"]],
["moment", ["brief moment", "moment in time"]],
["monopoly", ["complete monopoly"]],
["mural", ["wall mural"]],
["mutual respect", ["mutual respect for each other"]],
["mutually dependent", ["mutually dependent on each other"]],
["mystery", ["unsolved mystery"]],
# ["naked", ["bare naked"]],
["nape", ["nape of her neck"]],
["necessary", ["absolutely necessary"]],
["never", ["never at any time"]],
["noon", ["12 noon", "12 o'clock noon", "high noon",
"twelve noon"]],
["nostalgia", ["nostalgia for the past"]],
["number of", ["number of different"]],
["opening", ["exposed opening"]],
["my opinion", ["my personal opinion"]],
["opposites", ["exact opposites", "polar opposites"]],
["opposite", ["exact opposite", "polar opposite"]],
["orbits", ["orbits around"]],
["outcome", ["final outcome"]],
["panacea", ["universal panacea"]],
["pending", ["now pending"]],
["penetrate", ["penetrate through"]],
["persists", ["still persists"]],
["pioneer", ["old pioneer"]],
["plan", ["plan ahead", "plan in advance",
"proposed plan"]],
["planning", ["advance planning", "forward planning"]],
["plans", ["future plans"]],
["plan", ["future plan"]],
["point", ["point in time"]],
["point", ["sharp point"]],
["postpone", ["postpone until later"]],
["pouring rain", ["pouring down rain"]],
["preview", ["advance preview"]],
["previously listed", ["previously listed above"]],
["probed", ["probed into"]],
["proceed", ["proceed ahead"]],
["prosthesis", ["artificial prosthesis"]],
# ["protrude", ["protrude out"]],
["proverb", ["old proverb"]],
# ["proximity", ["close proximity"]],
["put off", ["put off until later"]],
# ["raise", ["raise up"]],
["re-elect", ["re-elect for another term"]],
["reason is", ["reason is because"]],
["recur", ["recur again"]],
["recurrence", ["future recurrence"]],
["refer", ["refer back"]],
["reflect", ["reflect back"]],
# ["relevant", ["highly relevant"]],
["remain", ["continue to remain"]],
["remains", ["still remains"]],
["replica", ["exact replica"]],
["reply", ["reply back"]],
# ["requirements", ["necessary requirements"]],
["reservations", ["advance reservations"]],
["retreat", ["retreat back"]],
["revert", ["revert back"]],
["round", ["round in shape"]],
["rule of thumb", ["rough rule of thumb"]],
["rumor", ["unconfirmed rumor"]],
["rustic", ["rustic country"]],
["same", ["exact same", "precise same", "same exact"]],
["sanctuary", ["safe sanctuary"]],
["satisfaction", ["full satisfaction"]],
["scrutinize", ["scrutinize in detail"]],
["scrutiny", ["careful scrutiny", "close scrutiny"]],
["secret", ["secret that cannot be told"]],
["seek", ["seek to find"]],
["separated", ["separated apart from each other"]],
["share", ["share together"]],
["shiny", ["shiny in appearance"]],
["sincere", ["truly sincere"]],
["sink", ["sink down"]],
["skipped", ["skipped over"]],
# ["slow", ["slow speed"]],
# ["small", ["small size"]],
["soft", ["soft in texture", "soft to the touch"]],
["sole", ["sole of the foot"]],
["some time", ["some time to come"]],
["speck", ["small speck"]],
["speed", ["rate of speed"]],
["spell out", ["spell out in detail"]],
["spiked", ["spiked upward", "spiked upwards"]],
["spring", ["spring season"]],
["stranger", ["anonymous stranger"]],
["studio audience", ["live studio audience"]],
["subway", ["underground subway"]],
["sufficient", ["sufficient enough"]],
["summer", ["summer season"]],
["sure", ["absolutely sure"]],
["surprise", ["unexpected surprise"]],
["surround", ["completely surround"]],
["surrounded", ["surrounded on all sides"]],
["tall", ["tall in height", "tall in stature"]],
["telepathy", ["mental telepathy"]],
["ten", ["ten in number"]],
["these", ["these ones"]],
# ["they", ["they themselves"]],
["those", ["those ones"]],
["trench", ["open trench"]],
["truth", ["honest truth"]],
["tundra", ["frozen tundra"]],
["ultimatum", ["final ultimatum"]],
# ["undeniable", ["undeniable truth"]],
["undergraduate", ["undergraduate student"]],
# ["unintentional", ["unintentional mistake"]],
["vacillate", ["vacillate back and forth"]],
["veteran", ["former veteran"]],
["visible", ["visible to the eye"]],
["warn", ["warn in advance"]],
["warning", ["advance warning"]],
["water heater", ["hot water heater"]],
["in which we live", ["in which we live in"]],
["winter", ["winter season"]],
["witness", ["live witness"]],
["yakitori", ["yakitori chicken"]],
["yerba mate", ["yerba mate tea"]],
["yes", ["affirmative yes"]],
]
return preferred_forms_check(text, redundancies, err, msg)
proselint-0.10.2/proselint/checks/redundancy/ras_syndrome.py 0000664 0003720 0003720 00000002463 13331225053 025147 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Redundant Acronym Syndrome (RAS) syndrome."""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "garner.redundancy.ras"
msg = "RAS syndrome. Use '{}' instead of '{}'."
redundancies = [
["ABM", ["ABM missile"]],
["ACT", ["ACT test"]],
["ABMs", ["ABM missiles"]],
["ABS", ["ABS braking system"]],
["ATM", ["ATM machine"]],
["CD", ["CD disc"]],
["CPI", ["CPI Index"]],
["GPS", ["GPS system"]],
["GUI", ["GUI interface"]],
["HIV", ["HIV virus"]],
["ISBN", ["ISBN number"]],
["LCD", ["LCD display"]],
["PDF", ["PDF format"]],
["PIN", ["PIN number"]],
["RAS", ["RAS syndrome"]],
["RIP", ["RIP in peace"]],
["RSVP", ["please RSVP"]],
["SALT", ["SALT talks"]],
["SAT", ["SAT test"]],
["UPC", ["UPC codes"]],
]
return preferred_forms_check(text, redundancies, err, msg)
proselint-0.10.2/proselint/checks/skunked_terms/ 0000775 0003720 0003720 00000000000 13331225202 022601 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/skunked_terms/__init__.py 0000664 0003720 0003720 00000000033 13331225053 024712 0 ustar travis travis 0000000 0000000 """Avoid skunked terms."""
proselint-0.10.2/proselint/checks/skunked_terms/misc.py 0000664 0003720 0003720 00000001376 13331225053 024121 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Skunked terms.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: Skunked terms.
date: 2014-06-10 12:31:19
categories: writing
---
Archaism.
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "skunked_terms.misc"
msg = u"""'{}' is a bit of a skunked term — impossible to use without issue.
Find some other way to say it."""
skunked_terms = [
"bona fides",
"deceptively",
"decimate",
"effete",
"fulsome",
"hopefully",
"impassionate",
"Thankfully,",
]
return existence_check(text, skunked_terms, err, msg)
proselint-0.10.2/proselint/checks/nonwords/ 0000775 0003720 0003720 00000000000 13331225202 021574 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/nonwords/__init__.py 0000664 0003720 0003720 00000000020 13331225053 023701 0 ustar travis travis 0000000 0000000 """Nonwords."""
proselint-0.10.2/proselint/checks/nonwords/misc.py 0000664 0003720 0003720 00000004610 13331225053 023106 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Nonwords.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: nonwords
date: 2014-06-10 12:31:19
categories: writing
---
Nonwords.
"""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "nonwords.misc"
msg = "Nonword, try '{}'."
preferences = [
["doubtless' or 'undoubtedly", ["doubtlessly"]],
["analysis", ["analyzation"]],
["annoyance", ["annoyment"]],
["confirmand", ["confirmant"]],
["confirmands", ["confirmants"]],
["converse", ["conversate"]],
["cranded", ["crained"]],
["disbursement' or 'dispersal", ["dispersement"]],
["discomfort' or 'discomfiture", ["discomforture"]],
["effrontery", ["affrontery"]],
["forbearance", ["forebearance"]],
["improper", ["improprietous"]],
["inclement", ["inclimate"]],
["relatively low price' or 'affordability", ["relative inexpense"]],
["inimical", ["inimicable"]],
["regardless", ["irregardless"]],
["minimize", ["minimalize"]],
["minimized", ["minimalized"]],
["minimizes", ["minimalizes"]],
["minimizing", ["minimalizing"]],
# muchly
["optimize", ["optimalize"]],
["paralysis", ["paralyzation"]],
["pettifog", ["pettifogger"]],
["proper", ["proprietous"]],
["quell' or 'quash", ["squelch"]],
["seldom", ["seldomly"]],
# slinged
["thus", ["thusly"]],
["categorically", ["uncategorically"]],
["undoubtedly' or 'indubitably", ["undoubtably"]],
["unequivocal", ["unequivocable"]],
["mercilessly", ["unmercilessly"]],
["unrelentingly' or relentlessly", ["unrelentlessly"]],
]
return preferred_forms_check(text, preferences, err, msg)
proselint-0.10.2/proselint/checks/security/ 0000775 0003720 0003720 00000000000 13331225202 021572 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/security/credit_card.py 0000664 0003720 0003720 00000001213 13331225053 024410 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Credit card number printed.
---
layout: post
source: ???
source_url: ???
title: credit card number printed
date: 2014-06-10 12:31:19
categories: writing
---
Credit card number printed.
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "security.credit_card"
msg = u"Don't put credit card numbers in plain text."
credit_card_numbers = [
"4\d{15}",
"5[1-5]\d{14}",
"3[4,7]\d{13}",
"3[0,6,8]\d{12}",
"6011\d{12}",
]
return existence_check(text, credit_card_numbers, err, msg)
proselint-0.10.2/proselint/checks/security/__init__.py 0000664 0003720 0003720 00000000020 13331225053 023677 0 ustar travis travis 0000000 0000000 """Security."""
proselint-0.10.2/proselint/checks/security/password.py 0000664 0003720 0003720 00000001346 13331225053 024016 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Password in plain text.
---
layout: post
source: ???
source_url: ???
title: password in plain text
date: 2014-06-10 12:31:19
categories: writing
---
Don't put pass
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "security.password"
msg = u"Don't put passwords in plain text."
pwd_regex = "[:]? [\S]{6,30}"
password = [
"the password is{}".format(pwd_regex),
"my password is{}".format(pwd_regex),
"the password's{}".format(pwd_regex),
"my password's{}".format(pwd_regex),
"^[pP]assword{}".format(pwd_regex),
]
return existence_check(text, password, err, msg)
proselint-0.10.2/proselint/checks/consistency/ 0000775 0003720 0003720 00000000000 13331225202 022264 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/consistency/spacing.py 0000664 0003720 0003720 00000001230 13331225053 024262 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Mixed one vs. two spaces after a period.
---
layout: post
source: Consistency.
source_url: ???
title: Mixed use of 1 vs. 2 spaces after a period.
date: 2014-06-10 12:31:19
categories: writing
---
Points out instances where there are two conventions, 1 vs. 2 spaces after
a period, in the same document.
"""
from proselint.tools import consistency_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "consistency.spacing"
msg = "Inconsistent spacing after period (1 vs. 2 spaces)."
regex = ["[\.\?!] [A-Z]", "[\.\?!] [A-Z]"]
return consistency_check(text, [regex], err, msg)
proselint-0.10.2/proselint/checks/consistency/__init__.py 0000664 0003720 0003720 00000000042 13331225053 024375 0 ustar travis travis 0000000 0000000 """Various consistency checks."""
proselint-0.10.2/proselint/checks/consistency/spelling.py 0000664 0003720 0003720 00000002702 13331225053 024460 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Inconsistent spelling.
---
layout: post
source: Intelligent Editing Ltd.
source_url: http://bit.ly/1x3hYj7
title: Inconsistent spelling
date: 2014-06-10 12:31:19
categories: writing
---
Intelligent Editing Ltd. says:
> Some words have more than one correct spelling. American, British, Australian
and Canadian English all have their own preferences. Even within those, there
can be multiple spellings. For example, in the UK 'realise' is often preferred.
However, 'realize' has been used in British-English for centuries and is
preferred in the Oxford English Dictionary. However, no matter which spelling
is preferred, one thing is always wrong: you mustn't use two different
spellings in the same document.
"""
from proselint.tools import consistency_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "consistency.spelling"
msg = "Inconsistent spelling of '{}' (vs. '{}')."
word_pairs = [
["advisor", "adviser"],
# ["analyse", "analyze"],
["centre", "center"],
["colour", "color"],
["emphasise", "emphasize"],
["finalise", "finalize"],
["focussed", "focused"],
["labour", "labor"],
["learnt", "learned"],
["organise", "organize"],
["organised", "organized"],
["organising", "organizing"],
["recognise", "recognize"],
]
return consistency_check(text, word_pairs, err, msg)
proselint-0.10.2/proselint/checks/cursing/ 0000775 0003720 0003720 00000000000 13331225202 021375 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/cursing/nfl.py 0000664 0003720 0003720 00000057226 13331225053 022546 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Words the NFL won't print on a jersey.
---
layout: post
source: The National Football League
source_url: http://bit.ly/1ISK0rb
title: words the NFL won't print on a jersey
date: 2014-06-10 12:31:19
categories: writing
---
Words the NFL won't print on a jersey.
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "cursing.nfl"
msg = u"The NFL won't print this word on a jersey."
list = [
"420",
"666",
"2 on 1",
"3rd eye",
"3rd leg",
"3rdeye",
"3rdleg",
"3some",
"4 twenty",
"4twenty",
"60 nine",
"60nine",
"a.s.s.",
"anal",
"anal annie",
"anal sex",
"analannie",
"analsex",
"anus",
"arse",
"ass",
"ass bagger",
"ass blaster",
"ass clown",
"ass cowboy",
"ass fuck",
"ass fucker",
"ass hole",
"ass holes",
"ass hore",
"ass jockey",
"ass kiss",
"ass kisser",
"ass klown",
"ass lick",
"ass licker",
"ass lover",
"ass man",
"ass monkey",
"ass munch",
"ass muncher",
"ass packer",
"ass pirate",
"ass puppies",
"ass ranger",
"ass whore",
"ass wipe",
"assbagger",
"assblaster",
"assclown",
"asscowboy",
"assfuck",
"assfucker",
"asshole",
"assholes",
"asshore",
"assjockey",
"asskiss",
"asskisser",
"assklown",
"asslick",
"asslicker",
"asslover",
"assman",
"assmonkey",
"assmunch",
"assmuncher",
"asspacker",
"asspirate",
"asspuppies",
"assranger",
"asswhore",
"asswipe",
"athletes foot",
"athletesfoot",
"axing the weasel",
"b hard",
"back door",
"back door man",
"backdoor",
"backdoorman",
"backseat",
"bad ass",
"bad fuck",
"badfuck",
"ball licker",
"ball sack",
"balllicker",
"balls",
"ballsack",
"banging",
"barely legal",
"barelylegal",
"barf",
"barf face",
"barface",
"barfface",
"bastard",
"bazongas",
"bazooms",
"beastality",
"beastiality",
"beat off",
"beat your meat",
"beatoff",
"beat-off",
"beatyourmeat",
"bi",
"bi sexual",
"biatch",
"big ass",
"big bitch",
"big bitch",
"big butt",
"bigass",
"bigbastard",
"bigbutt",
"bisexual",
"bi-sexual",
"bitch",
"bitches",
"bitchin",
"bitchy",
"bite me",
"biteme",
"black out",
"blackout",
"blow job",
"blowjob",
"bm",
"boner",
"bong",
"boobies",
"boobs",
"boody",
"breast",
"breast job",
"breast lover",
"breast man",
"breastjob",
"breastlover",
"breastman",
"budweiser",
"bull crap",
"bull dike",
"bull dyke",
"bull shit",
"bullcrap",
"bulldike",
"bulldyke",
"bullshit",
"bumble fuck",
"bumblefuck",
"bumfuck",
"bunghole",
"butch babes",
"butch dike",
"butch dyke",
"butchbabes",
"butchdike",
"butchdyke",
"butt bang",
"butt fuck",
"butt fucker",
"butt fuckers",
"butt head",
"butt man",
"butt plug",
"butt stain",
"buttbang",
"butt-bang",
"buttface",
"buttfuck",
"butt-fuck",
"buttfucker",
"butt-fucker",
"buttfuckers",
"butt-fuckers",
"butthead",
"buttman",
"buttpirate",
"buttplug",
"buttstain",
"camel toe",
"cameltoe",
"carpet muncher",
"carpetmuncher",
"carruth",
"cherry popper",
"cherrypopper",
"chick slick",
"chickslick",
"clam digger",
"clam diver",
"clamdigger",
"clamdiver",
"clit",
"clitoris",
"cock",
"cock block",
"cock blocker",
"cock cowboy",
"cock fight",
"cock knob",
"cock licker",
"cock lover",
"cock nob",
"cock queen",
"cock rider",
"cock smith",
"cock sucker",
"cock tail",
"cock tease",
"cockblock",
"cockblocker",
"cockcowboy",
"cockfight",
"cockhead",
"cockknob",
"cocklicker",
"cocklover",
"cocknob",
"cockqueen",
"cockrider",
"cocks man",
"cocksman",
"cocksmith",
"cocksucer",
"cocksucker",
"cocktail",
"cocktease",
"cocky",
"condom",
"copulate",
"corn hole",
"cornhole",
"crabs",
"crack",
"crack pipe",
"crack whore",
"crackpipe",
"crackwhore",
"crack-whore",
"crap",
"crappy",
"creamy",
"crotch",
"crotch jockey",
"crotch monkey",
"crotch rot",
"crotchjockey",
"crotchmonkey",
"crotchrot",
"cum",
"cum bubble",
"cum fest",
"cum jockey",
"cum quat",
"cum queen",
"cum shot",
"cumbubble",
"cumfest",
"cumjockey",
"cumm",
"cumming",
"cumquat",
"cumqueen",
"cumshot",
"cunnilingus",
"cunt",
"cunt fuck",
"cunt fucker",
"cunt licker",
"cuntfuck",
"cuntfucker",
"cuntlicker",
"cyber sex",
"cyber slimer",
"cybersex",
"cyberslimer",
"dahmer",
"damn",
"damn it",
"damnit",
"datnigga",
"dd",
"deap throat",
"deaper",
"deapthroat",
"deep throat",
"deeper",
"deepthroat",
"defecate",
"deposit",
"devil",
"dick brain",
"dick fart",
"dick for brains",
"dick head",
"dick lick",
"dick licker",
"dick likcer",
"dick wad",
"dick weed",
"dickbrain",
"dickforbrains",
"dickhead",
"dickless",
"dicklick",
"dicklicker",
"dickman",
"dickwad",
"dickweed",
"dike",
"dildo",
"dip stick",
"dipstick",
"dirty ho",
"dix",
"dixie dike",
"dixie dyke",
"dixiedike",
"dixiedyke",
"do me",
"doggie style",
"doggiestyle",
"doggy stlye",
"doggystyle",
"dome",
"dong",
"dope",
"double d",
"doubled",
"drag queen",
"dragqueen",
"dragqween",
"dre",
"drip dick",
"dripdick",
"drunk",
"drunken",
"dumb ass",
"dumb bitch",
"dumb fuck",
"dumbass",
"dumbbitch",
"dumbfuck",
"easy slut",
"easyslut",
"eat me",
"eat pussy",
"eatballs",
"eatme",
"eatpussy",
"ejaculate",
"erection",
"evl",
"excrement",
"f toyota",
"f.i.n.e.",
"f.u.c.k.",
"face fucker",
"facefucker",
"faggot",
"fagot",
"fairy",
"fanny fucker",
"fannyfucker",
"fart",
"fast fuck",
"fastfuck",
"fat ass",
"fat fuck",
"fat fucker",
"fatass",
"fatfuck",
"fatfucker",
"fatso",
"fellatio",
"femme",
"finger food",
"finger fuck",
"finger fucker",
"fingerfood",
"fingerfuck",
"fingerfucker",
"fist fuck",
"fist fucker",
"fistfuck",
"fistfucker",
"fisting",
"flasher",
"flatulence",
"floggin the dolphin",
"fondle",
"foot fuck",
"foot fucker",
"foot licker",
"footaction",
"footfuck",
"footfucker",
"footlicker",
"footstar",
"fore skin",
"foreskin",
"fornicate",
"four 20",
"four twenty",
"four20",
"fourtwenty",
"freak fuck",
"freakfuck",
"freaky fucker",
"freakyfucker",
"free 4 all",
"free for all",
"free fuck",
"free4all",
"freeforall",
"freefuck",
"fuck",
"fuck bag",
"fuck buddy",
"fuck face",
"fuck fest",
"fuck freak",
"fuck friend",
"fuck head",
"fuck her",
"fuck it",
"fuck knob",
"fuck me",
"fuck me hard",
"fuck monkey",
"fuck off",
"fuck pig",
"fuck them",
"fuck whore",
"fuck you",
"fucka",
"fuckable",
"fuckbag",
"fuckbuddy",
"fucked",
"fucked up",
"fuckedup",
"fucker",
"fuckers",
"fuckface",
"fuckfest",
"fuckfreak",
"fuckfriend",
"fuckhead",
"fuckher",
"fuckin",
"fuckin a",
"fuckin nuts",
"fuckin right",
"fuckina",
"fucking",
"fucking a",
"fucking bitch",
"fucking nuts",
"fuckingbitch",
"fuckinnuts",
"fuckinright",
"fuckit",
"fuckknob",
"fuckme",
"fuckmehard",
"fuckmonkey",
"fuckoff",
"fuckpig",
"fuckwhore",
"fuckyou",
"fudge pakcers",
"fun fuck",
"funfuck",
"fuuck",
"g unit",
"gang bang",
"gang banger",
"gangbang",
"gangbanger",
"gay",
"gay ass",
"gay mutha fuckin queer",
"gay pride",
"gaymuthafuckinwhore",
"genital",
"get it on",
"getiton",
"giehn",
"give head",
"givehead",
"glazed donut",
"glazeddonut",
"go me",
"go to hell",
"god",
"god damed mutha fucka",
"god damit",
"god damn",
"god damned",
"god manit",
"goddamit",
"goddamn",
"goddamned",
"goddamnes",
"goddamnit",
"goddamnmuthafucker",
"gonorrehea",
"gonzagas",
"gook",
"got jesus",
"got2haveit",
"gotohell",
"g-unit",
"hand job",
"handjob",
"hard on",
"harder",
"hardon",
"harem",
"he hate me",
"head fuck",
"head lights",
"headfuck",
"headlights",
"hehateme",
"hell",
"hell no",
"hell yes",
"hellno",
"hellyes",
"hen house",
"henhouse",
"herpes",
"hershey hi way",
"hersheyhighway",
"hersheyhiway",
"hershy high way",
"ho",
"ho mo",
"hobo",
"hole",
"hole stuffer",
"holestuffer",
"homo",
"homo bangers",
"homo sexual",
"homobangers",
"homosexual",
"honkers",
"honkey",
"hooker",
"hookers",
"hooters",
"hore",
"horney",
"horny",
"horseshit",
"hose job",
"hosejob",
"hoser",
"hostage",
"hot damn",
"hot pussy",
"hot to trot",
"hot2trot",
"hotdamn",
"hotpussy",
"hottotrot",
"hussy",
"hustler",
"i love beer",
"i luv beer",
"id ten t",
"id10t",
"idiot",
"idoit",
"in the ass",
"in the buff",
"ingin",
"insest",
"inter course",
"inter racial",
"intercourse",
"interracial",
"intheass",
"inthebuff",
"jack the ripper",
"jackass",
"jackoff",
"jacktheripper",
"jap",
"jap crap",
"japcrap",
"jerk off",
"jerkoff",
"jesus chirst",
"jesuschrist",
"jism",
"jiz",
"jiz juice",
"jizim",
"jizjuice",
"jizz",
"jizzim",
"joint",
"juggalo",
"jugs",
"k mart",
"kill",
"killer",
"killing",
"kiss ass",
"kissass",
"kkk",
"kmart",
"knockers",
"koon",
"kotex",
"krap",
"krappy",
"kum",
"kum bubble",
"kum quat",
"kumbubble",
"kumbullbe",
"kumquat",
"kunt",
"ky",
"ky jelly",
"lactate",
"lady boog",
"laid",
"lap dance",
"lapdance",
"lesbain",
"lesbayn",
"lesbian",
"lesbin",
"lesbo",
"lez",
"lez be",
"lez be friends",
"lezbe",
"lezbefriends",
"lezbo",
"lezz",
"lezzo",
"lick me",
"licker",
"lickme",
"limp dick",
"limpdick",
"limy",
"live sex",
"livesex",
"loaded gun",
"loadedgun",
"lolita",
"looser",
"lotion",
"love bone",
"love goo",
"love gun",
"love juice",
"love muscle",
"love pistol",
"love rocket",
"lovebone",
"lovegoo",
"lovegun",
"lovejuice",
"lovemuscle",
"lovepistol",
"loverocket",
"low life",
"lowlife",
"lube job",
"lubejob",
"lucky camel toe",
"luckycammeltoe",
"magic wand",
"magicwand",
"mams",
"man hater",
"man paste",
"manhater",
"manpaste",
"mary jane",
"maryjane",
"mastabate",
"mastabater",
"master blaster",
"masterbate",
"masterblaster",
"mastrabator",
"mattress princess",
"mattressprincess",
"meat beatter",
"meatbeatter",
"molest",
"molester",
"molestor",
"money shot",
"moneyshot",
"mother fucker",
"mother love bone",
"motherfuck",
"motherfucker",
"motherlovebone",
"muff",
"muff dive",
"muff diver",
"muff licker",
"muffdive",
"muffdiver",
"muffin diver",
"muffindiver",
"mufflikcer",
"murder",
"mutha fucker",
"naked",
"nasty bitch",
"nasty ho",
"nasty slut",
"nasty whore",
"nastybitch",
"nastyho",
"nastyslut",
"nastywhore",
"neon deon",
"nig",
"niger",
"nigga",
"nigger",
"nipple",
"nipple ring",
"nipplering",
"nit tit",
"nittit",
"no fucking way",
"no sex",
"nofuckingway",
"nookie",
"nooner",
"nude",
"nut fucker",
"nutfucker",
"oicu812",
"on the rag",
"ontherag",
"orgasm",
"orgy",
"ou812",
"oui",
"p i m p",
"pearl necklace",
"pearlnecklace",
"pecker",
"pee",
"peep show",
"peepshow",
"peepshpw",
"penetration",
"penis",
"penthouse",
"period",
"phque",
"pimp",
"pimp simp",
"pimped",
"pimper",
"pimpjuic",
"pimpjuice",
"pimpsimp",
"piss",
"piss head",
"pissed",
"pisser",
"pisshead",
"play boy",
"play girl",
"playboy",
"playgirl",
"pocket pool",
"pocketpool",
"polack",
"poon tang",
"poontang",
"poop",
"pooper",
"poor white trash",
"poorwhitetrash",
"popimp",
"porch monkey",
"porchmonkey",
"porn",
"porn flick",
"porn king",
"porn princess",
"pornflick",
"pornking",
"porno",
"pornprincess",
"pot",
"premature",
"prick",
"prick head",
"prickhead",
"primetime",
"prostitute",
"pubic",
"pubic lice",
"pubiclice",
"pud",
"pud boy",
"pudboy",
"pudd",
"pudd boy",
"puddboy",
"pun tang",
"puntang",
"purina princess",
"purinapricness",
"pussy",
"pussy cat",
"pussy eater",
"pussy fucker",
"pussy licker",
"pussy lips",
"pussy lover",
"pussy pounder",
"pussycat",
"pussyeater",
"pussyfucker",
"pussylicker",
"pussylips",
"pussylover",
"pussypounder",
"putt pirate",
"pwt",
"queef",
"queer",
"quickie",
"rae carruth",
"rape",
"rapist",
"rear end",
"rear entry",
"rearend",
"rearentry",
"rectum",
"red light",
"redlight",
"reefer",
"rent a fuck",
"rentafuck",
"retard",
"retarded",
"ribbed",
"rim job",
"rimjob",
"roach",
"robber",
"s and m",
"s&m",
"samckdaddy",
"sandm",
"satan",
"schlong",
"screw",
"screw you",
"screwyou",
"scrotum",
"semen",
"sex",
"sex farm",
"sex hound",
"sex house",
"sex kitten",
"sex pot",
"sex slave",
"sex to go",
"sex toy",
"sex toys",
"sex whore",
"sexfarm",
"sexhound",
"sexhouse",
"sexkitten",
"sexpot",
"sexslave",
"sextogo",
"sextoy",
"sextoys",
"sexual",
"sexwhore",
"sexy",
"sexy biatch",
"sexy bitch",
"sexy moma",
"sexy slim",
"sexymoma",
"sexy-slim",
"shag",
"shaggin",
"shagging",
"shawtypimp",
"shit",
"shit dick",
"shit eater",
"shit face",
"shit for brains",
"shit fuck",
"shit fucker",
"shit happens",
"shit head",
"shit out of luck",
"shit stain",
"shit4brains",
"shitdick",
"shiteater",
"shitface",
"shitforbrains",
"shitfuck",
"shitfucker",
"shithapens",
"shithappens",
"shithead",
"shitoutofluck",
"shits",
"shitstain",
"shitter",
"shitting",
"shitty",
"short fuck",
"shortfuck",
"showtime",
"six six six",
"sixsixsix",
"sixty 9",
"sixty nine",
"sixty9",
"sixtynine",
"skank",
"skank bitch",
"skank fuck",
"skank whore",
"skankbitch",
"skankfuck",
"skankwhore",
"skanky bitch",
"skanky whore",
"skankybitch",
"skankywhore",
"skin flute",
"skinflute",
"skum",
"skum bag",
"skumbag",
"slant",
"slant eye",
"slanteye",
"slave",
"slave driver",
"slavedriver",
"sleeze bag",
"sleeze ball",
"sleezebag",
"sleezeball",
"slide it in",
"slideitin",
"slime",
"slime ball",
"slime bucket",
"slimeball",
"slimebucket",
"slut",
"slut wear",
"slut whore",
"sluts",
"slutt",
"slutting",
"slutty",
"slutwear",
"slutwhore",
"smack daddy",
"smack the monkey",
"smackthemonkey",
"smagma",
"smart ass",
"snatch",
"snatch patch",
"snatchpatch",
"sniper",
"snot",
"sob",
"sodomite",
"sodomy",
"son of a bitch",
"sonofabitch",
"sonofbitch",
"spank the monkey",
"spankthemonkey",
"sperm",
"sperm bag",
"sperm hearder",
"sperm herder",
"spermacide",
"spermbag",
"spermhearder",
"spermherder",
"spic",
"spick",
"spit",
"spitter",
"split tail",
"split tial",
"splittail",
"stagg",
"strap on",
"strapon",
"stringer",
"strip club",
"stripclub",
"stroke",
"stroking",
"stupid",
"stupid fuck",
"stupid fucker",
"stupidfuck",
"stupidfucker",
"suck",
"suck dick",
"suck me",
"suck my ass",
"suck my dick",
"suck my tit",
"suck off",
"suckdick",
"sucker",
"suckme",
"suckmyass",
"suckmydick",
"suckmytit",
"suckoff",
"suicide",
"swallow",
"swallower",
"swalow",
"sweetness",
"swign dixx",
"swing dixx",
"swingin dixx",
"swinging dicks",
"syphilis",
"tampon",
"tang",
"testicle",
"testicles",
"third eye",
"third leg",
"thirdeye",
"thirdleg",
"three some",
"threesome",
"tit",
"tit bit nipply",
"tit fuck",
"tit fucker",
"tit fuckin",
"tit job",
"tit licker",
"tit lover",
"titbitnipply",
"titfuck",
"titfucker",
"titfuckin",
"titjob",
"titlicker",
"titlover",
"tits",
"titties",
"titty",
"toilet",
"toilet bowl",
"tongethruster",
"tongue",
"tongue thruster",
"tongue tramp",
"tonguethrust",
"tonguetramp",
"toung thruster",
"tounge baller",
"tounge thrust",
"trailer trash",
"trailertrash",
"tramp",
"tri sexual",
"triple x",
"triplex",
"trisexual",
"trojan",
"trots",
"tunnel of love",
"tunneloflove",
"turd",
"two bit whore",
"two on one",
"twobitwhore",
"unfuckable",
"up the ass",
"up the butt",
"upskirt",
"uptheass",
"upthebutt",
"urinate",
"urine",
"uterus",
"vagina",
"vaginal",
"vd",
"vibrater",
"vibrator",
"virgin",
"virgin breaker",
"virginbreaker",
"vulva",
"waysted",
"weenie",
"wet spot",
"wetspot",
"whacker",
"whiskey dick",
"whiskeydick",
"whisky dick",
"whiskydick",
"white trash",
"whitetrash",
"whore",
"whore fucker",
"whore house",
"whorefucker",
"whorehouse",
"wigger",
"willie wanker",
"williewanker",
"wuutang",
"xxx",
"yellow man",
"yellowman"
]
return existence_check(text, list, err, msg)
proselint-0.10.2/proselint/checks/cursing/filth.py 0000664 0003720 0003720 00000001306 13331225053 023061 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Filthy words.
---
layout: post
source: George Carlin
source_url: https://youtu.be/kyBH5oNQOS0
title: filthy words
date: 2014-06-10 12:31:19
categories: writing
---
Filthy words.
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "cursing.filth"
msg = u"""Nobody ever tells you this as a kid, but you're supposed to avoid
this word."""
list = [
"shit",
"piss",
"fuck",
"cunt",
"cocksucker",
"motherfucker",
"tits",
"fart",
"turd",
"twat",
]
return existence_check(text, list, err, msg)
proselint-0.10.2/proselint/checks/cursing/__init__.py 0000664 0003720 0003720 00000000017 13331225053 023510 0 ustar travis travis 0000000 0000000 """Cursing."""
proselint-0.10.2/proselint/checks/cursing/nword.py 0000664 0003720 0003720 00000001076 13331225053 023110 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""On 'the N word'.
---
layout: post
source: Louis CK
source_url: https://youtu.be/dF1NUposXVQ?t=30s
title: the 'n-word'
date: 2014-06-10 12:31:19
categories: writing
---
Take responsibility with the shitty words you wanna say.
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "cursing.nword"
msg = u"Take responsibility for the shitty words you want to say."
list = [
"the n-word",
]
return existence_check(text, list, err, msg)
proselint-0.10.2/proselint/checks/lgbtq/ 0000775 0003720 0003720 00000000000 13331225202 021034 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/lgbtq/__init__.py 0000664 0003720 0003720 00000000015 13331225053 023145 0 ustar travis travis 0000000 0000000 """GLAAD."""
proselint-0.10.2/proselint/checks/lgbtq/offensive_terms.py 0000664 0003720 0003720 00000002123 13331225053 024606 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""GLAAD.
---
layout: post
source: GLAAD Media Reference Guide - 9th Edition
source_url: http://www.glaad.org/reference
title: GLAAD Guidelines
date: 2016-07-06
categories: writing
---
This check looks for offensive terms related to LGBTQ issues and
raises an error marking them as offensive. The New York Times and
Associated Press have also adopted this style guide.
"""
from proselint.tools import memoize, existence_check
@memoize
def check(text):
"""Flag offensive words based on the GLAAD reference guide."""
err = "glaad.offensive_terms"
msg = "Offensive term. Remove it or consider the context."
list = [
"fag",
"faggot",
"dyke",
"sodomite",
"homosexual agenda",
"gay agenda",
"transvestite",
"homosexual lifestyle",
"gay lifestyle"
# homo - may create false positives without additional context
# FIXME use topic detetor to decide whether "homo" is offensive
]
return existence_check(text, list, err, msg, join=True, ignore_case=False)
proselint-0.10.2/proselint/checks/lgbtq/terms.py 0000664 0003720 0003720 00000002375 13331225053 022553 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""GLAAD.
---
layout: post
source: GLAAD Media Reference Guide - 9th Edition
source_url: http://www.glaad.org/reference
title: GLAAD Guidelines
date: 2016-07-06
categories: writing
---
This check looks for possibly offensive terms related to LGBTQ issues and
makes more acceptable recommendations. TheNew York Times and
Associated Press have also adopted this style guide.
"""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""Suggest preferred forms given the reference document."""
err = "glaad.terms"
msg = "Possibly offensive term. Consider using '{}' instead of '{}'."
list = [
["gay man", ["homosexual man"]],
["gay men", ["homosexual men"]],
["lesbian", ["homosexual woman"]],
["lesbians", ["homosexual women"]],
["gay people", ["homosexual people"]],
["gay couple", ["homosexual couple"]],
["sexual orientation", ["sexual preference"]],
["openly gay", ["admitted homosexual", "avowed homosexual"]],
["equal rights", ["special rights"]]
]
return preferred_forms_check(text, list, err, msg, ignore_case=False)
proselint-0.10.2/proselint/checks/archaism/ 0000775 0003720 0003720 00000000000 13331225202 021512 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/archaism/__init__.py 0000664 0003720 0003720 00000000020 13331225053 023617 0 ustar travis travis 0000000 0000000 """Archaism."""
proselint-0.10.2/proselint/checks/archaism/misc.py 0000664 0003720 0003720 00000003467 13331225053 023035 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Archaism.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: archaism
date: 2014-06-10 12:31:19
categories: writing
---
Archaism.
"""
from proselint.tools import existence_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "archaism.misc"
msg = u"'{}' is archaic."
archaisms = [
"alack",
"anent",
# "anon",
"begat",
"belike",
"betimes",
"boughten",
"brocage",
"brokage",
"camarade",
"chiefer",
"chiefest",
"Christiana",
"completely obsolescent",
"cozen",
"divers",
"deflexion",
"durst",
"fain",
"forsooth",
"foreclose from",
"haply",
"howbeit",
"illumine",
"in sooth",
"maugre",
"meseems",
"methinks",
"nigh",
"peradventure",
"perchance",
"saith",
"shew",
"sistren",
"spake",
"to wit",
"verily",
"whilom",
"withal",
"wot",
"enclosed please find",
"please find enclosed",
"enclosed herewith",
"enclosed herein",
"inforce",
"ex postfacto",
"foreclose from",
"forewent",
"for ever",
# "designer", when used to mean a plotter against Christ
# "demean", when used to mean "to behave" in legal contexts
# "by the bye", # variant, modern is "by the by"
# "comptroller" # in British English
# "abortive" Abortive is archaic in reference to abortions of fetuses,
# except in the sense “causing an abortion.”
]
return existence_check(text, archaisms, err, msg, join=True)
proselint-0.10.2/proselint/checks/cliches/ 0000775 0003720 0003720 00000000000 13331225202 021335 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/cliches/__init__.py 0000664 0003720 0003720 00000000025 13331225053 023447 0 ustar travis travis 0000000 0000000 """Avoid cliches."""
proselint-0.10.2/proselint/checks/cliches/hell.py 0000664 0003720 0003720 00000001046 13331225053 022640 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Too much yelling.
---
layout: post
source: ???
source_url: ???
title: yelling
date: 2014-06-10 12:31:19
categories: writing
---
Never use the phrase 'all hell broke loose'.
"""
from proselint.tools import existence_check, memoize
@memoize
def check_repeated_exclamations(text):
"""Check the text."""
err = "leonard.hell"
msg = u"Never use the words 'all hell broke loose'."
regex = r"all hell broke loose"
return existence_check(
text, [regex], err, msg, max_errors=1)
proselint-0.10.2/proselint/checks/cliches/misc.py 0000664 0003720 0003720 00000061423 13331225053 022654 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
u"""Cliches are cliché."""
from proselint.tools import memoize, existence_check
@memoize
def check_cliches_garner(text):
"""Check the text.
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
"""
err = "cliches.garner"
msg = u"'{}' is cliché."
cliches = [
"a fate worse than death",
"alas and alack",
"at the end of the day",
"bald-faced lie",
"between a rock and a hard place",
"between Scylla and Charybdis",
"between the devil and the deep blue sea",
"betwixt and between",
"blissful ignorance",
"blow a fuse",
"bulk large",
"but that's another story",
"cast aspersions",
"chase a red herring",
"comparing apples and oranges",
"compleat",
"conspicuous by its absence",
"crystal clear",
"cutting edge",
"decision-making process",
"dubious distinction",
"duly authorized",
"eyes peeled",
"far be it from me",
"fast and loose",
"fills the bill",
"first and foremost",
"for free",
"get with the program",
"gilding the lily",
"have a short fuse",
"he's got his hands full",
"his own worst enemy",
"his work cut out for him",
"hither and yon",
"Hobson's choice",
"horns of a dilemma",
"if you catch my drift",
"in light of",
"in the final analysis",
"in the last analysis",
"innocent bystander",
"it's not what you know, it's who you know",
"last but not least",
"make a mockery of",
"male chauvinism",
"moment of truth",
"more in sorrow than in anger",
"more sinned against than sinning",
"my better half",
"nip in the bud",
"olden days",
"on the same page",
"presidential timber",
"pulled no punches",
"quantum jump",
"quantum leap",
"redound to one's credit",
"redound to the benefit of",
"sea change",
"shirked his duties",
"six of one, half a dozen of the other",
"stretched to the breaking point",
"than you can shake a stick at",
"the cream of the crop",
"the cream rises to the top",
"the straw that broke the camel's back",
"thick as thieves",
"thinking outside the box",
"thought leaders?",
"throw the baby out with the bathwater",
"various and sundry",
"viable alternative",
"wax eloquent",
"wax poetic",
"we've got a situation here",
"whet (?:the|your) appetite",
"wool pulled over our eyes",
"writ large",
]
return existence_check(text, cliches, err, msg, join=True)
@memoize
def check_cliches_write_good(text):
"""Check the text.
source: write-good
source_url: https://github.com/btford/write-good
"""
err = "cliches.write_good"
msg = u"'{}' is a cliché."
cliches = [
"a chip off the old block",
"a clean slate",
"a dark and stormy night",
"a far cry",
"a fine kettle of fish",
"a loose cannon",
"a penny saved is a penny earned",
"a tough row to hoe",
"a word to the wise",
"ace in the hole",
"acid test",
"add insult to injury",
"against all odds",
"air your dirty laundry",
"all fun and games",
"all in a day's work",
"all talk, no action",
"all thumbs",
"all your eggs in one basket",
"all's fair in love and war",
"all's well that ends well",
"almighty dollar",
"American as apple pie",
"an axe to grind",
"another day, another dollar",
"armed to the teeth",
"as luck would have it",
"as old as time",
"as the crow flies",
"at loose ends",
"at my wits end",
"avoid like the plague",
"babe in the woods",
"back against the wall",
"back in the saddle",
"back to square one",
"back to the drawing board",
"bad to the bone",
"badge of honor",
"bald faced liar",
"ballpark figure",
"banging your head against a brick wall",
"baptism by fire",
"barking up the wrong tree",
"bat out of hell",
"be all and end all",
"beat a dead horse",
"beat around the bush",
"been there, done that",
"beggars can't be choosers",
"behind the eight ball",
"bend over backwards",
"benefit of the doubt",
"bent out of shape",
"best thing since sliced bread",
"bet your bottom dollar",
"better half",
"better late than never",
"better mousetrap",
"better safe than sorry",
"between a rock and a hard place",
"beyond the pale",
"bide your time",
"big as life",
"big cheese",
"big fish in a small pond",
"big man on campus",
"bigger they are the harder they fall",
"bird in the hand",
"bird's eye view",
"birds and the bees",
"birds of a feather flock together",
"bit the hand that feeds you",
"bite the bullet",
"bite the dust",
"bitten off more than he can chew",
"black as coal",
"black as pitch",
"black as the ace of spades",
"blast from the past",
"bleeding heart",
"blessing in disguise",
"blind ambition",
"blind as a bat",
"blind leading the blind",
"blood is thicker than water",
"blood sweat and tears",
"blow off steam",
"blow your own horn",
"blushing bride",
"boils down to",
"bolt from the blue",
"bone to pick",
"bored stiff",
"bored to tears",
"bottomless pit",
"boys will be boys",
"bright and early",
"brings home the bacon",
"broad across the beam",
"broken record",
"brought back to reality",
"bull by the horns",
"bull in a china shop",
"burn the midnight oil",
"burning question",
"burning the candle at both ends",
"burst your bubble",
"bury the hatchet",
"busy as a bee",
"by hook or by crook",
"call a spade a spade",
"called onto the carpet",
"calm before the storm",
"can of worms",
"can't cut the mustard",
"can't hold a candle to",
"case of mistaken identity",
"cat got your tongue",
"cat's meow",
"caught in the crossfire",
"caught red-handed",
"checkered past",
"chomping at the bit",
"cleanliness is next to godliness",
"clear as a bell",
"clear as mud",
"close to the vest",
"cock and bull story",
"cold shoulder",
"come hell or high water",
"cool as a cucumber",
"cool, calm, and collected",
"cost a king's ransom",
"count your blessings",
"crack of dawn",
"crash course",
"creature comforts",
"cross that bridge when you come to it",
"crushing blow",
"cry like a baby",
"cry me a river",
"cry over spilt milk",
"crystal clear",
"curiosity killed the cat",
"cut and dried",
"cut through the red tape",
"cut to the chase",
"cute as a bugs ear",
"cute as a button",
"cute as a puppy",
"cuts to the quick",
"dark before the dawn",
"day in, day out",
"dead as a doornail",
"devil is in the details",
"dime a dozen",
"divide and conquer",
"dog and pony show",
"dog days",
"dog eat dog",
"dog tired",
"don't burn your bridges",
"don't count your chickens",
"don't look a gift horse in the mouth",
"don't rock the boat",
"don't step on anyone's toes",
"don't take any wooden nickels",
"down and out",
"down at the heels",
"down in the dumps",
"down the hatch",
"down to earth",
"draw the line",
"dressed to kill",
"dressed to the nines",
"drives me up the wall",
"dull as dishwater",
"dyed in the wool",
"eagle eye",
"ear to the ground",
"early bird catches the worm",
"easier said than done",
"easy as pie",
"eat your heart out",
"eat your words",
"eleventh hour",
"even the playing field",
"every dog has its day",
"every fiber of my being",
"everything but the kitchen sink",
"eye for an eye",
"face the music",
"facts of life",
"fair weather friend",
"fall by the wayside",
"fan the flames",
"feast or famine",
"feather your nest",
"feathered friends",
"few and far between",
"fifteen minutes of fame",
"filthy vermin",
"fine kettle of fish",
"fish out of water",
"fishing for a compliment",
"fit as a fiddle",
"fit the bill",
"fit to be tied",
"flash in the pan",
"flat as a pancake",
"flip your lid",
"flog a dead horse",
"fly by night",
"fly the coop",
"follow your heart",
"for all intents and purposes",
"for the birds",
"for what it's worth",
"force of nature",
"force to be reckoned with",
"forgive and forget",
"fox in the henhouse",
"free and easy",
"free as a bird",
"fresh as a daisy",
"full steam ahead",
"fun in the sun",
"garbage in, garbage out",
"gentle as a lamb",
"get a kick out of",
"get a leg up",
"get down and dirty",
"get the lead out",
"get to the bottom of",
"get your feet wet",
"gets my goat",
"gilding the lily",
"give and take",
"go against the grain",
"go at it tooth and nail",
"go for broke",
"go him one better",
"go the extra mile",
"go with the flow",
"goes without saying",
"good as gold",
"good deed for the day",
"good things come to those who wait",
"good time was had by all",
"good times were had by all",
"greased lightning",
"greek to me",
"green thumb",
"green-eyed monster",
"grist for the mill",
"growing like a weed",
"hair of the dog",
"hand to mouth",
"happy as a clam",
"happy as a lark",
"hasn't a clue",
"have a nice day",
"have high hopes",
"have the last laugh",
"haven't got a row to hoe",
"head honcho",
"head over heels",
"hear a pin drop",
"heard it through the grapevine",
"heart's content",
"heavy as lead",
"hem and haw",
"high and dry",
"high and mighty",
"high as a kite",
"hit paydirt",
"hold your head up high",
"hold your horses",
"hold your own",
"hold your tongue",
"honest as the day is long",
"horns of a dilemma",
"horse of a different color",
"hot under the collar",
"hour of need",
"I beg to differ",
"icing on the cake",
"if the shoe fits",
"if the shoe were on the other foot",
"in a jam",
"in a jiffy",
"in a nutshell",
"in a pig's eye",
"in a pinch",
"in a word",
"in hot water",
"in the gutter",
"in the nick of time",
"in the thick of it",
"in your dreams",
"it ain't over till the fat lady sings",
"it goes without saying",
"it takes all kinds",
"it takes one to know one",
"it's a small world",
"it's only a matter of time",
"ivory tower",
"Jack of all trades",
"jockey for position",
"jog your memory",
"joined at the hip",
"judge a book by its cover",
"jump down your throat",
"jump in with both feet",
"jump on the bandwagon",
"jump the gun",
"jump to conclusions",
"just a hop, skip, and a jump",
"just the ticket",
"justice is blind",
"keep a stiff upper lip",
"keep an eye on",
"keep it simple, stupid",
"keep the home fires burning",
"keep up with the Joneses",
"keep your chin up",
"keep your fingers crossed",
"kick the bucket",
"kick up your heels",
"kick your feet up",
"kid in a candy store",
"kill two birds with one stone",
"kiss of death",
"knock it out of the park",
"knock on wood",
"knock your socks off",
"know him from Adam",
"know the ropes",
"know the score",
"knuckle down",
"knuckle sandwich",
"knuckle under",
"labor of love",
"ladder of success",
"land on your feet",
"lap of luxury",
"last but not least",
"last hurrah",
"last-ditch effort",
"law of the jungle",
"law of the land",
"lay down the law",
"leaps and bounds",
"let sleeping dogs lie",
"let the cat out of the bag",
"let the good times roll",
"let your hair down",
"let's talk turkey",
"letter perfect",
"lick your wounds",
"lies like a rug",
"life's a bitch",
"life's a grind",
"light at the end of the tunnel",
"lighter than a feather",
"lighter than air",
"like clockwork",
"like father like son",
"like taking candy from a baby",
"like there's no tomorrow",
"lion's share",
"live and learn",
"live and let live",
"long and short of it",
"long lost love",
"look before you leap",
"look down your nose",
"look what the cat dragged in",
"looking a gift horse in the mouth",
"looks like death warmed over",
"loose cannon",
"lose your head",
"lose your temper",
"loud as a horn",
"lounge lizard",
"loved and lost",
"low man on the totem pole",
"luck of the draw",
"luck of the Irish",
"make hay while the sun shines",
"make money hand over fist",
"make my day",
"make the best of a bad situation",
"make the best of it",
"make your blood boil",
"man of few words",
"man's best friend",
"mark my words",
"meaningful dialogue",
"missed the boat on that one",
"moment in the sun",
"moment of glory",
"moment of truth",
"money to burn",
"more power to you",
"more than one way to skin a cat",
"movers and shakers",
"moving experience",
"naked as a jaybird",
"naked truth",
"neat as a pin",
"needle in a haystack",
"needless to say",
"neither here nor there",
"never look back",
"never say never",
"nip and tuck",
"nip it in the bud",
"no guts, no glory",
"no love lost",
"no pain, no gain",
"no skin off my back",
"no stone unturned",
"no time like the present",
"no use crying over spilled milk",
"nose to the grindstone",
"not a hope in hell",
"not a minute's peace",
"not in my backyard",
"not playing with a full deck",
"not the end of the world",
"not written in stone",
"nothing to sneeze at",
"nothing ventured nothing gained",
"now we're cooking",
"off the top of my head",
"off the wagon",
"off the wall",
"old hat",
"older and wiser",
"older than dirt",
"older than Methuselah",
"on a roll",
"on cloud nine",
"on pins and needles",
"on the bandwagon",
"on the money",
"on the nose",
"on the rocks",
"on the spot",
"on the tip of my tongue",
"on the wagon",
"on thin ice",
"once bitten, twice shy",
"one bad apple doesn't spoil the bushel",
"one born every minute",
"one brick short",
"one foot in the grave",
"one in a million",
"one red cent",
"only game in town",
"open a can of worms",
"open and shut case",
"open the flood gates",
"opportunity doesn't knock twice",
"out of pocket",
"out of sight, out of mind",
"out of the frying pan into the fire",
"out of the woods",
"out on a limb",
"over a barrel",
"over the hump",
"pain and suffering",
"pain in the",
"panic button",
"par for the course",
"part and parcel",
"party pooper",
"pass the buck",
"patience is a virtue",
"pay through the nose",
"penny pincher",
"perfect storm",
"pig in a poke",
"pile it on",
"pillar of the community",
"pin your hopes on",
"pitter patter of little feet",
"plain as day",
"plain as the nose on your face",
"play by the rules",
"play your cards right",
"playing the field",
"playing with fire",
"pleased as punch",
"plenty of fish in the sea",
"point with pride",
"poor as a church mouse",
"pot calling the kettle black",
"pretty as a picture",
"pull a fast one",
"pull your punches",
"pulling your leg",
"pure as the driven snow",
"put it in a nutshell",
"put one over on you",
"put the cart before the horse",
"put the pedal to the metal",
"put your best foot forward",
"put your foot down",
"quick as a bunny",
"quick as a lick",
"quick as a wink",
"quick as lightning",
"quiet as a dormouse",
"rags to riches",
"raining buckets",
"raining cats and dogs",
"rank and file",
"rat race",
"reap what you sow",
"red as a beet",
"red herring",
"reinvent the wheel",
"rich and famous",
"rings a bell",
"ripe old age",
"ripped me off",
"rise and shine",
"road to hell is paved with good intentions",
"rob Peter to pay Paul",
"roll over in the grave",
"rub the wrong way",
"ruled the roost",
"running in circles",
"sad but true",
"sadder but wiser",
"salt of the earth",
"scared stiff",
"scared to death",
"sealed with a kiss",
"second to none",
"see eye to eye",
"seen the light",
"seize the day",
"set the record straight",
"set the world on fire",
"set your teeth on edge",
"sharp as a tack",
"shoot for the moon",
"shoot the breeze",
"shot in the dark",
"shoulder to the wheel",
"sick as a dog",
"sigh of relief",
"signed, sealed, and delivered",
"sink or swim",
"six of one, half a dozen of another",
"skating on thin ice",
"slept like a log",
"slinging mud",
"slippery as an eel",
"slow as molasses",
"smart as a whip",
"smooth as a baby's bottom",
"sneaking suspicion",
"snug as a bug in a rug",
"sow wild oats",
"spare the rod, spoil the child",
"speak of the devil",
"spilled the beans",
"spinning your wheels",
"spitting image of",
"spoke with relish",
"spread like wildfire",
"spring to life",
"squeaky wheel gets the grease",
"stands out like a sore thumb",
"start from scratch",
"stick in the mud",
"still waters run deep",
"stitch in time",
"stop and smell the roses",
"straight as an arrow",
"straw that broke the camel's back",
"strong as an ox",
"stubborn as a mule",
"stuff that dreams are made of",
"stuffed shirt",
"sweating blood",
"sweating bullets",
"take a load off",
"take one for the team",
"take the bait",
"take the bull by the horns",
"take the plunge",
"takes one to know one",
"takes two to tango",
"the more the merrier",
"the real deal",
"the real McCoy",
"the red carpet treatment",
"the same old story",
"there is no accounting for taste",
"thick as a brick",
"thick as thieves",
"thin as a rail",
"think outside of the box",
"third time's the charm",
"this day and age",
"this hurts me worse than it hurts you",
"this point in time",
"three sheets to the wind",
"through thick and thin",
"throw in the towel",
"tie one on",
"tighter than a drum",
"time and time again",
"time is of the essence",
"tip of the iceberg",
"tired but happy",
"to coin a phrase",
"to each his own",
"to make a long story short",
"to the best of my knowledge",
"toe the line",
"tongue in cheek",
"too good to be true",
"too hot to handle",
"too numerous to mention",
"touch with a ten foot pole",
"tough as nails",
"trial and error",
"trials and tribulations",
"tried and true",
"trip down memory lane",
"twist of fate",
"two cents worth",
"two peas in a pod",
"ugly as sin",
"under the counter",
"under the gun",
"under the same roof",
"under the weather",
"until the cows come home",
"unvarnished truth",
"up the creek",
"uphill battle",
"upper crust",
"upset the applecart",
"vain attempt",
"vain effort",
"vanquish the enemy",
"vested interest",
"waiting for the other shoe to drop",
"wakeup call",
"warm welcome",
"watch your p's and q's",
"watch your tongue",
"watching the clock",
"water under the bridge",
"weather the storm",
"weed them out",
"week of Sundays",
"went belly up",
"wet behind the ears",
"what goes around comes around",
"what you see is what you get",
"when it rains, it pours",
"when push comes to shove",
"when the cat's away",
"when the going gets tough, the tough get going",
"white as a sheet",
"whole ball of wax",
"whole hog",
"whole nine yards",
"wild goose chase",
"will wonders never cease?",
"wisdom of the ages",
"wise as an owl",
"wolf at the door",
"words fail me",
"work like a dog",
"world weary",
"worst nightmare",
"worth its weight in gold",
"wrong side of the bed",
"yanking your chain",
"yappy as a dog",
"years young",
"you are what you eat",
"you can run but you can't hide",
"you only live once",
"you're the boss ",
"young and foolish",
"young and vibrant",
]
return existence_check(text, cliches, err, msg, join=True)
@memoize
def check_cliches_gnu_diction(text):
"""Check the text.
source: GNU diction
source_url: https://directory.fsf.org/wiki/Diction
"""
err = "cliches.gnu_diction"
msg = u"'{}' is a cliché."
list = [
"a matter of concern",
"all things being equal",
"as a last resort",
"attached hereto",
"by no means",
"conspicuous by its absence",
"easier said than done",
"enclosed herewith",
"if and when",
"in reference to",
"in short supply",
"in the foreseeable future",
"in the long run",
"in the matter of",
"it stands to reason",
"many and diverse",
"on the right track",
"par for the course",
"please feel free to",
"pursuant to your request",
"regarding the matter of",
"slowly but surely",
"this will acknowledge",
"we are pleased to advice",
"we regret to inform you",
"we wish to state",
"you are hereby advised that",
]
return existence_check(text, list, err, msg, join=True, ignore_case=True)
proselint-0.10.2/proselint/checks/terms/ 0000775 0003720 0003720 00000000000 13331225202 021055 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint/checks/terms/eponymous_adjectives.py 0000664 0003720 0003720 00000001250 13331225053 025670 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Eponymous adjectives.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: Eponymous adjectives
date: 2014-06-10 12:31:19
categories: writing
---
Eponymous adjectives.
"""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "garner.eponymous_adjective"
msg = "'{}' is the preferred eponymous adjective."
preferences = [
["Mephistophelean", ["Mephistophelian"]],
["Shakespearean", ["Shakespearian"]],
]
return preferred_forms_check(text, preferences, err, msg)
proselint-0.10.2/proselint/checks/terms/animal_adjectives.py 0000664 0003720 0003720 00000004610 13331225053 025076 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Animal adjectives.
---
layout: post
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
title: animal words
date: 2014-06-10 12:31:19
categories: writing
---
Animal words.
"""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""Suggest the preferred forms."""
err = "garner.animal_labels"
msg = "There's a word for this: '{}'."
preferences = [
["accipitrine", ["hawk-like"]],
["anserine", ["goose-like"]],
["aquiline", ["eagle-like"]],
["avine", ["bird-like"]],
["cancrine", ["crab-like"]],
["hircine", ["goat-like"]],
["damine", ["deer-like"]],
["corvine", ["crow-like", "raven-like"]],
["crocodiline", ["crocodile-like"]],
["crotaline", ["rattlesnake-like"]],
["falconine", ["falcon-like"]],
["ferine", ["wild animal-like"]],
["hippopotamine", ["hippopotamus-like"]],
["hirundine", ["swallow-like"]],
["hystricine", ["porcupine-like"]],
["lacertine", ["lizard-like"]],
["laridine", ["gull-like"]],
["leporine", ["hare-like"]],
["lumbricine", ["earthworm-like"]],
["lupine", ["wolf-like"]],
["murine", ["mouse-like"]],
["ovine", ["sheep-like"]],
["pardine", ["leopard-like", "panther-like"]],
["passerine", ["sparrow-like"]],
["pavonine", ["peacock-like"]],
["picine", ["woodpecker-like"]],
["piscine", ["fish-like"]],
["ranine", ["frog-like"]],
["scolopendrine", ["centipede-like"]],
["soricine", ["shrew-like"]],
["struthionine", ["ostrich-like"]],
["suilline", ["swine-like"]],
["taurine", ["bull-like", "ox-like"]],
["tigrine", ["tiger-like"]],
["vespine", ["wasp-like"]],
["viperine", ["viper-like"]],
["vituline", ["calf-like", "veal-like"]],
["viverrine", ["mongoose-like"]],
["vulpine", ["fox-like"]],
["vulturine", ["vulture-like"]],
["zebrine", ["zebra-like"]],
["zibeline", ["sable-like"]],
]
return preferred_forms_check(text, preferences, err, msg)
proselint-0.10.2/proselint/checks/terms/__init__.py 0000664 0003720 0003720 00000000015 13331225053 023166 0 ustar travis travis 0000000 0000000 """Terms."""
proselint-0.10.2/proselint/checks/terms/denizen_labels.py 0000664 0003720 0003720 00000006403 13331225053 024414 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Denizen labels."""
from proselint.tools import memoize, preferred_forms_check
@memoize
def check(text):
"""Suggest the preferred forms.
source: Garner's Modern American Usage
source_url: http://bit.ly/1T4alrY
"""
err = "terms.denizen_labels.garner"
msg = "'{}' is the preferred denizen label."
preferences = [
["Afrikaner", ["Afrikaaner"]],
["Afrikaner", ["Afrikander"]],
["Alabamian", ["Alabaman"]],
["Albuquerquean", ["Albuquerquian"]],
["Anchorageite", ["Anchoragite"]],
["Angeleno", ["Los Angelean"]],
["Arizonan", ["Arizonian"]],
["Arkansan", ["Arkansawyer"]],
["Belarusian", ["Belarusan"]],
["Caymanian", ["Cayman Islander"]],
["Coloradan", ["Coloradoan"]],
["Fairbanksan", ["Fairbanksian"]],
["Fort Worthian", ["Fort Worther"]],
["Grenadan", ["Grenadian"]],
["Hong Konger", ["Hong Kongite", "Hong Kongian"]],
["Hoosier", ["Indianan", "Indianian"]],
["Illinoisan", ["Illinoisian"]],
["Iowan", ["Iowegian"]],
["Louisianian", ["Louisianan"]],
["Michigander", ["Michiganite", "Michiganian"]],
["Missourian", ["Missouran"]],
["Monegasque", ["Monacan"]],
["Neapolitan", ["Neopolitan"]],
["New Hampshirite", ["New Hampshireite", "New Hampshireman"]],
["New Jerseyan", ["New Jerseyite"]],
["New Orleanian", ["New Orleansian"]],
["Nutmegger", ["Connecticuter"]],
["Oklahoma Cityan", ["Oklahoma Citian"]],
["Oklahoman", ["Oklahomian"]],
["Seattleite", ["Seattlite"]],
["Surinamese", ["Surinamer"]],
["Tallahasseean", ["Tallahassean"]],
["Tennessean", ["Tennesseean"]],
["Tusconan", ["Tusconian", "Tusconite"]],
["Utahn", ["Utahan"]],
["Saudi", ["Saudi Arabian"]],
]
return preferred_forms_check(text, preferences, err, msg)
@memoize
def check_denizen_labels_norris(text):
"""Suggest the preferred forms.
source: Mary Norris
source_url: http://nyr.kr/1rGienj
"""
err = "terms.denizen_labels.norris"
msg = "Would you like '{}'?"
preferences = [
["Mancunian", ["Manchesterian"]],
["Mancunians", ["Manchesterians"]],
["Vallisoletano", ["Valladolidian"]],
["Wulfrunian", ["Wolverhamptonian", "Wolverhamptonite"]],
["Novocastrian", ["Newcastleite", "Newcastlite"]],
["Trifluvian", [u"Trois-Rivièrester"]],
["Leodenisian", ["Leedsian"]],
["Minneapolitan", ["Minneapolisian"]],
["Hartlepudlian", ["Hartlepoolian"]],
["Liverpudlian", ["Liverpoolian"]],
["Haligonian", ["Halifaxer"]],
["Varsovian", ["Warsawer", "Warsawian"]],
["Providentian", ["Providencian", "Providencer"]],
["Tridentine", ["Trentian", "Trentonian"]],
]
return preferred_forms_check(text, preferences, err, msg)
proselint-0.10.2/proselint/checks/terms/venery.py 0000664 0003720 0003720 00000005113 13331225053 022743 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Names for groups of animals.
---
layout: post
source: Oxford Dictionaries
source_url: http://www.oxforddictionaries.com/words/what-do-you-call-a-group-of
title: Names for groups of animals
date: 2014-06-10 12:31:19
categories: writing
---
Names for groups of animals.
"""
from proselint.tools import preferred_forms_check, memoize
@memoize
def check(text):
"""Check the text."""
err = "oxford.venery_terms"
msg = "The venery term is '{}'."
term_list = [
["alligators", "congregation"],
["antelopes", "herd"],
["baboons", "troop"],
["badgers", "cete"],
["bats", "colony"],
["bears", "sloth"],
["buffalo", "herd"],
["bullfinches", "bellowing"],
["caribou", "herd"],
["cats", "glaring"],
["caterpillars", "army"],
["cockroaches", "intrusion"],
["coyotes", "pack"],
["crows", "murder"],
["dogs", "pack"],
["eagles", "convocation"],
["emus", "mob"],
["flamingos", "stand"],
["frogs", "army"],
["goldfinches", "charm"],
["gorillas", "band"],
["guineafowl", "rasp"],
["hedgehogs", "array"],
["herons", "siege"],
["hogs", "parcel"],
["hyenas", "cackle"],
["ibex", "herd"],
["iguanas", "mess"],
["lions", "pride"],
["locusts", "plague"],
["mackerel", "shoal"],
["mares", "stud"],
["minnows", "shoal"],
["moose", "herd"],
["mosquitoes", "scourge"],
["nightingales", "watch"],
["oysters", "bed"],
["partridges", "covey"],
["pelicans", "pod"],
["raccoons", "gaze"],
["ravens", "unkindness"],
["rhinoceroses", "crash"],
["sea urchins", "sea"],
["starlings", "murmuration"],
["toads", "knot"],
["wombats", "wisdom"],
["woodcocks", "fall"],
["woodpeckers", "descent"],
["wrens", "herd"],
]
generic_terms = [
"group",
"bunch",
]
list = []
for term_pair in term_list:
for generic in generic_terms:
wrong = "a {} of {}".format(generic, term_pair[0])
right = "a {} of {}".format(term_pair[1], term_pair[0])
list += [[right, [wrong]]]
return preferred_forms_check(text, list, err, msg)
proselint-0.10.2/proselint/score.py 0000664 0003720 0003720 00000005143 13331225053 020157 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Compute the lintscore on the corpus."""
from __future__ import print_function
from builtins import input
from builtins import int
import os
import subprocess
import re
proselint_path = os.path.dirname(os.path.realpath(__file__))
def score(check=None):
"""Compute the linter's score on the corpus.
Proselint's score reflects the desire to have a linter that catches many
errors, but which takes false alarms seriously. It is better not to say
something than to say the wrong thing, and the harm from saying the wrong
thing is greater than the benefit of saying the right thing. Thus our score
metric is defined as:
TP * (TP / (FP + TP)) ^ k,
where TP is the number of true positives (hits), FP is the number of
false positives (false alarms), and k > 0 is a temperature parameter that
determines the penalty for imprecision. In general, we should choose a
large value of k, one that strongly discourages the creation of rules that
can't be trusted. Suppose that k = 2. Then if the linter detects 100
errors, of which 10 are false positives, the score is 81.
"""
tp = 0
fp = 0
parent_directory = os.path.dirname(proselint_path)
path_to_corpus = os.path.join(parent_directory, "corpora", "0.1.0")
for root, _, files in os.walk(path_to_corpus):
files = [f for f in files if f.endswith(".md")]
for f in files:
fullpath = os.path.join(root, f)
# Run the linter.
print("Linting {}".format(f))
out = subprocess.check_output(["proselint", fullpath])
# Determine the number of errors.
regex = r".+?:(?P\d+):(?P\d+): (?P.+)"
num_errors = len(tuple(re.finditer(regex, out)))
print("Found {} errors.".format(num_errors))
# Open the document.
subprocess.call(["open", fullpath])
# Ask the scorer how many of the errors were false alarms?
input_val = None
while not isinstance(input_val, int):
try:
input_val = input("# of false alarms? ")
if input_val == "exit":
return
else:
input_val = int(input_val)
fp += input_val
tp += (num_errors - input_val)
except ValueError:
pass
print("Currently {} hits and {} false alarms\n---".format(tp, fp))
if (tp + fp) > 0:
return tp * (1.0 * tp / (tp + fp)) ** 2
else:
return 0
proselint-0.10.2/proselint/__main__.py 0000664 0003720 0003720 00000000216 13331225053 020560 0 ustar travis travis 0000000 0000000 """
__main__.py.
This lets you run python -m proselint.
"""
from .command_line import proselint
if __name__ == '__main__':
proselint()
proselint-0.10.2/proselint/__init__.py 0000664 0003720 0003720 00000000154 13331225053 020600 0 ustar travis travis 0000000 0000000 """Proselint applies advice from great writers to your writing."""
from . import tools
__all__ = ('tools')
proselint-0.10.2/proselint/version.py 0000664 0003720 0003720 00000000070 13331225053 020523 0 ustar travis travis 0000000 0000000 """Proselint version number."""
__version__ = "0.10.2"
proselint-0.10.2/proselint/.proselintrc 0000664 0003720 0003720 00000007464 13331225053 021047 0 ustar travis travis 0000000 0000000 {
"max_errors": 1000,
"checks": {
"airlinese.misc" : true,
"annotations.misc" : true,
"archaism.misc" : true,
"cliches.hell" : true,
"cliches.misc" : true,
"consistency.spacing" : true,
"consistency.spelling" : true,
"corporate_speak.misc" : true,
"cursing.filth" : true,
"cursing.nfl" : false,
"cursing.nword" : true,
"dates_times.am_pm" : true,
"dates_times.dates" : true,
"hedging.misc" : true,
"hyperbole.misc" : true,
"jargon.misc" : true,
"lexical_illusions.misc" : true,
"lgbtq.offensive_terms" : true,
"lgbtq.terms" : true,
"links.broken" : false,
"malapropisms.misc" : true,
"misc.apologizing" : true,
"misc.back_formations" : true,
"misc.bureaucratese" : true,
"misc.but" : true,
"misc.capitalization" : true,
"misc.chatspeak" : true,
"misc.commercialese" : true,
"misc.composition" : true,
"misc.currency" : true,
"misc.debased" : true,
"misc.false_plurals" : true,
"misc.illogic" : true,
"misc.inferior_superior" : true,
"misc.institution_name" : true,
"misc.latin" : true,
"misc.many_a" : true,
"misc.metaconcepts" : true,
"misc.metadiscourse" : true,
"misc.narcissism" : true,
"misc.not_guilty" : true,
"misc.phrasal_adjectives" : true,
"misc.preferred_forms" : true,
"misc.pretension" : true,
"misc.professions" : true,
"misc.punctuation" : true,
"misc.scare_quotes" : true,
"misc.suddenly" : true,
"misc.tense_present" : true,
"misc.waxed" : true,
"misc.whence" : true,
"mixed_metaphors.misc" : true,
"mondegreens.misc" : true,
"needless_variants.misc" : true,
"nonwords.misc" : true,
"oxymorons.misc" : true,
"psychology.misc" : true,
"redundancy.misc" : true,
"redundancy.ras_syndrome" : true,
"skunked_terms.misc" : true,
"spelling.able_atable" : true,
"spelling.able_ible" : true,
"spelling.athletes" : true,
"spelling.em_im_en_in" : true,
"spelling.er_or" : true,
"spelling.in_un" : true,
"spelling.misc" : true,
"security.credit_card" : true,
"security.password" : true,
"sexism.misc" : true,
"terms.animal_adjectives" : true,
"terms.denizen_labels" : true,
"terms.eponymous_adjectives" : true,
"terms.venery" : true,
"typography.diacritical_marks" : true,
"typography.exclamation" : true,
"typography.symbols" : true,
"uncomparables.misc" : true,
"weasel_words.misc" : true,
"weasel_words.very" : true
}
}
proselint-0.10.2/proselint/demo.md 0000664 0003720 0003720 00000013717 13331225053 017746 0 ustar travis travis 0000000 0000000 # Proselint
Writing is notoriously hard, even for the best writers. Yet there is a tremendous amount of knowledge about the discipline 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 American Usage, a 975-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 prose. (A linter is a computer program that, like a spell checker, scans through a document and analyzes it.)
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, E.B. 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.
This is a live demo. Obviously, you can hover over the underlined text to see what the issue is, then fix it.
# Dates & times
The 1950's were a swell time.
The 50's were a swell time.
Things happened from 1980-1999 and from 240-398 A.D.
March, 2013 was notable in that
In February of 2010, the mayor considered
It's 5 pm somewhere.
It's 12 a.m., time to eat lunch.
It's 11 p.m. at night.
# Consistency
This is a sentence! One space after a period.
This is a sentence. Two spaces after a period.
This is a sentence? Two spaces after a period.
This is a sentence. One space after a period.
This is a sentence. One space after a period.
This is a sentence. One space after a period.
This is a sentence. One space after a period.
centre centre center
organize, organized, organizing, organise
recognize, recognise, recognise, recognise
# Symbols
$1000 USD
I hit him over the head with a 2 x 4.
# Venery terms
A bunch of antelopes walked by the road.
A group of emus attacked me.
She swam by a bunch of oysters.
# Mondegreens
They hae slain the Earl o' Moray and Lady Mondegreen.
A girl with colitis goes by.
# Skunked terms
The building is deceptively large.
The project would decimate the fragile wetland wilderness.
Hopefully, one day we will all grow older.
# Links
www.google.com
http://broken.proselint.com
http://news.ycombinator.com
# Hyperbolic language
and so I said PLEASE STOP YELLING
so excited!
so excited!!
so excited!!!
so excited!!!!
really??
and so I said PLEASE STOP YELLING
and so I said PLEASE STOP YELLING okay?
THESE ARE SMALL CAPS at the beginning of a new line.
# Preferred forms
abbreviatable to NASA
academicly superior.
transhipped
an aider and abbeter
it's adducable
let's look for an acquiror
i wonder what tort-feasor means
Get that off of me before I catch on fire!
There are many a person I have met and worked with who simply deride themselves into taking some action
In the meanwhile, he looked loving at the sheep.
Suddenly, I see.
# Mixed metaphors
Get ready: button your seatbelts.
The cream rises to the crop.
The biggest bottleneck is that...
# Illogic and redundancy
he is very smart
approximately about 5 atm machines
atm machine
we associate together
it's blatantly obvious that this obviously works.
a very unique idea
a more perfect union
the surrounding circumstances
he filled a much-needed gap
To coin a phrase from the movie,
# Blowing the punchline
Suddenly, the car came to a stop.
All hell broke loose on the farm.
# Clichés
under the weather
He's a chip off the old block
a quantum leap
Our cutting edge decision-making process will make your life crystal clear.
He's a thought leader.
# Security
John's cc#:
378282246310005
the password is tnoernturpn
my password is long and 'long'
my password is amazing
# Commercialese
inst.
please be advised that
# Archaism
boughten
# Dismissive tone
this obviously works
# Chatspeak
brb
rofl
# Ogilvy's pretension
We'll need to reconceptualize this sentence.
# Airlinese
enplanement
We'll be taking off momentarily.
# Tense present
Save up to 50% or More!
between you and i
I did it on accident
I feel nauseous
# Phrasal adjectives
It was a highly-anticipated event.
The English speaking people speak English.
A big ticket item.
A right wing militia.
# Various misspellings
highfaluting
the statement was inadmissable in court
Nikita Khruschev
I feel innundated with email
Nicknack
He's a shoe-in
Brett Farve and Dwayne Wade are good friends.
The Chronicals of Narnia
# Strunk & White composition & regex checks
I did not pay for the check. Honestly, attention to detail is useful.
I did not pay attention to detail.
I did not pay any attention to detail.
# Typography
(c) 2015
(R) The Corporation
Use ellipsis not three dots...
# Denizen labels
The Manchesterian was a good Brit.
One from Michigan is not a Michiganite but a Michigander.
One from Colorado is not a Coloradoan but a Coloradan.
# Sexism
The lady lawyer handled my case.
John and Mary married. Now they are man and wife.
Chairman Mao was the chairman of the communist party.
# Punctuation
Smith, et. al (2006) said
# Quoted text
John said that I am "very unique."
John knows that I am very unique.
John knows every unique snowflake is cold.
# Metadiscourse
The preceeding discussion
# Narcisism, metadiscourse, latin, and hedging
The 'take-home message' is that
more research is needed
The rest of this article argues that, to a certain degree
in recent years, an increasing number of psychologists have
mutatis mutandis
proselint-0.10.2/proselint/command_line.py 0000664 0003720 0003720 00000012043 13331225053 021466 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Command line utility for proselint."""
from __future__ import print_function
from __future__ import absolute_import
from builtins import str
import click
import os
from .tools import (
close_cache_shelves_after,
close_cache_shelves,
errors_to_json,
lint,
)
import shutil
import subprocess
import sys
from .version import __version__
import traceback
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
base_url = "proselint.com/"
proselint_path = os.path.dirname(os.path.realpath(__file__))
demo_file = os.path.join(proselint_path, "demo.md")
def timing_test(corpus="0.1.0"):
"""Measure timing performance on the named corpus."""
import time
dirname = os.path.dirname
corpus_path = os.path.join(
dirname(dirname(os.path.realpath(__file__))), "corpora", corpus)
start = time.time()
for file in os.listdir(corpus_path):
filepath = os.path.join(corpus_path, file)
if ".md" == filepath[-3:]:
subprocess.call(["proselint", filepath, ">/dev/null"])
return time.time() - start
def clear_cache():
"""Delete the contents of the cache."""
click.echo("Deleting the cache...")
# see issue #624
_delete_compiled_python_files()
_delete_cache()
def _delete_compiled_python_files():
"""Remove files with a 'pyc' extension."""
for path, _, files in os.walk(os.getcwd()):
for fname in [f for f in files if os.path.splitext(f)[1] == ".pyc"]:
try:
os.remove(os.path.join(path, fname))
except OSError:
pass
def _delete_cache():
"""Remove the proselint cache."""
proselint_cache = os.path.join("proselint", "cache")
try:
shutil.rmtree(proselint_cache)
except OSError:
pass
def print_errors(filename, errors, output_json=False, compact=False):
"""Print the errors, resulting from lint, for filename."""
if output_json:
click.echo(errors_to_json(errors))
else:
for error in errors:
(check, message, line, column, start, end,
extent, severity, replacements) = error
if compact:
filename = "-"
click.echo(
filename + ":" +
str(1 + line) + ":" +
str(1 + column) + ": " +
check + " " +
message)
@click.command(context_settings=CONTEXT_SETTINGS)
@click.version_option(__version__, '--version', '-v', message='%(version)s')
@click.option('--debug', '-d', is_flag=True, help="Give verbose output.")
@click.option('--clean', '-c', is_flag=True, help="Clear the cache.")
@click.option('--json', '-j', 'output_json', is_flag=True,
help="Output as JSON.")
@click.option('--time', '-t', is_flag=True, help="Time on a corpus.")
@click.option('--demo', is_flag=True, help="Run over demo file.")
@click.option('--compact', is_flag=True, help="Shorten output.")
@click.argument('paths', nargs=-1, type=click.Path())
@close_cache_shelves_after
def proselint(paths=None, version=None, clean=None, debug=None,
output_json=None, time=None, demo=None, compact=None):
"""A CLI for proselint, a linter for prose."""
if time:
click.echo(timing_test())
return
# In debug or clean mode, delete cache & *.pyc files before running.
if debug or clean:
clear_cache()
# Use the demo file by default.
if demo:
paths = [demo_file]
# Expand the list of directories and files.
filepaths = extract_files(list(paths))
# Lint the files
num_errors = 0
# Use stdin if no paths were specified
if len(paths) == 0:
filepaths.append('-')
for fp in filepaths:
try:
if fp == '-':
fp = ''
f = sys.stdin
else:
f = click.open_file(
fp, 'r', encoding="utf-8", errors="replace")
errors = lint(f, debug=debug)
num_errors += len(errors)
print_errors(fp, errors, output_json, compact=compact)
except Exception:
traceback.print_exc()
# Return an exit code
close_cache_shelves()
if num_errors > 0:
sys.exit(1)
else:
sys.exit(0)
def extract_files(files):
"""Expand list of paths to include all text files matching the pattern."""
expanded_files = []
legal_extensions = [".md", ".txt", ".rtf", ".html", ".tex", ".markdown"]
for f in files:
# If it's a directory, recursively walk through it and find the files.
if os.path.isdir(f):
for dir_, _, filenames in os.walk(f):
for filename in filenames:
fn, file_extension = os.path.splitext(filename)
if file_extension in legal_extensions:
joined_file = os.path.join(dir_, filename)
expanded_files.append(joined_file)
# Otherwise add the file directly.
else:
expanded_files.append(f)
return expanded_files
if __name__ == '__main__':
proselint()
proselint-0.10.2/setup.cfg 0000664 0003720 0003720 00000000372 13331225202 016267 0 ustar travis travis 0000000 0000000 [bumpversion]
current_version = 0.10.2
commit = True
tag = True
tag_name = {new_version}
message = Bump version to {new_version}
[bumpversion:file:proselint/version.py]
[metadata]
description-file = README.md
[egg_info]
tag_build =
tag_date = 0
proselint-0.10.2/tests/ 0000775 0003720 0003720 00000000000 13331225202 015606 5 ustar travis travis 0000000 0000000 proselint-0.10.2/tests/test_misc_currency.py 0000664 0003720 0003720 00000001030 13331225053 022062 0 ustar travis travis 0000000 0000000 """Tests for misc.currency check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import currency as chk
class TestCheck(Check):
"""The test class for misc.currency."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.currency."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""It cost $10 dollars.""")
proselint-0.10.2/tests/test_leonard.py 0000664 0003720 0003720 00000001542 13331225053 020651 0 ustar travis travis 0000000 0000000 """Test garner.dates."""
from __future__ import absolute_import
from __future__ import print_function
from .check import Check
from proselint.checks.typography import exclamation
class TestCheck(Check):
"""Test class for leonard.exclamation."""
__test__ = True
def test_capitalization_and_no_exclamation(self):
"""Don't throw error when phrase has capitalization."""
text = """
The QUICK BROWN fox juMPED over the lazy cat.
"""
errors = exclamation.check_repeated_exclamations(text)
assert len(errors) == 0
def test_exclamation(self):
"""Test leonard.exclamation. with exclamation marks."""
text = """Sally sells seashells and they were too expensive!!!!"""
errors = exclamation.check_repeated_exclamations(text)
print(errors)
assert len(errors) == 1
proselint-0.10.2/tests/test_redundancy_misc.py 0000664 0003720 0003720 00000002645 13331225053 022401 0 ustar travis travis 0000000 0000000 """Tests for redundancy.misc check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.redundancy import misc as chk
class TestCheck(Check):
"""The test class for redundancy.misc."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke_check(self):
"""Basic smoke test for redundancy.misc.check."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""The table was rectangular in shape.""")
def test_smoke_garner(self):
"""Basic smoke test for redundancy.misc.check_garner."""
assert chk.check_garner(
"""Smoke phrase with nothing flagged.""") == []
assert chk.check_garner(
"""It was blatantly obvious what to do next.""") != []
def test_smoke_nordquist(self):
"""Basic smoke test for redundancy.misc.check_norquist."""
assert chk.check_nordquist(
"""Smoke phrase with nothing flagged.""") == []
assert chk.check_nordquist(
"""Taking the package was absolutely essential.""") != []
def test_smoke_atd(self):
"""Basic smoke test for redundancy.misc.check_norquist."""
assert chk.check_atd(
"""Smoke phrase with nothing flagged.""") == []
assert chk.check_atd(
"""He often repeated the old adage.""") != []
proselint-0.10.2/tests/test_typography_exclamation.py 0000664 0003720 0003720 00000002055 13331225053 024017 0 ustar travis travis 0000000 0000000 """Tests for typography.exclamation check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.typography import exclamation as chk
class TestCheck(Check):
"""The test class for typography.exclamation."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke_repeated_exclamations(self):
"""Basic smoke test.
Test for typography.exclamation.check_repeated_exclamations.
"""
assert chk.check_repeated_exclamations(
"""Smoke phrase with nothing flagged.""") == []
assert chk.check_repeated_exclamations(
"""I'm really excited!!""") != []
def test_smoke_exclamations_ppm(self):
"""Basic smoke test.
Test for typography.exclamation.check_exclamations_ppm.
"""
assert chk.check_exclamations_ppm(
"""Smoke phrase with nothing flagged.""") == []
assert chk.check_exclamations_ppm(
"""I'm really excited! Really!""") != []
proselint-0.10.2/tests/test_spelling_able_ible.py 0000664 0003720 0003720 00000001063 13331225053 023016 0 ustar travis travis 0000000 0000000 """Tests for spelling.able_ible check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.spelling import able_ible as chk
class TestCheck(Check):
"""The test class for spelling.able_ible."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for spelling.able_ible."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""It was a sensable decision.""")
proselint-0.10.2/tests/test_consistency_spelling.py 0000664 0003720 0003720 00000001343 13331225053 023462 0 ustar travis travis 0000000 0000000 """Tests for consistency.spelling check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.consistency import spelling as chk
class TestCheck(Check):
"""The test class for consistency.spelling."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for consistency.spelling."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert self.passes("""The centre for the arts is the art centre.""")
assert self.passes("""The center for the arts is the art center.""")
assert not self.passes("""The centre of the arts is the art center.""")
proselint-0.10.2/tests/test_consistency_spacing.py 0000664 0003720 0003720 00000001244 13331225053 023271 0 ustar travis travis 0000000 0000000 """Tests for consistency.spacing check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.consistency import spacing as chk
class TestCheck(Check):
"""The test class for consistency.spacing."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for consistency.spacing."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert self.passes(
"""This is good. Only one space each time. Every time.""")
assert not self.passes("""This is bad. Not consistent. At all.""")
proselint-0.10.2/tests/test_misc_debased.py 0000664 0003720 0003720 00000001037 13331225053 021626 0 ustar travis travis 0000000 0000000 """Tests for misc.debased check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import debased as chk
class TestCheck(Check):
"""The test class for misc.debased."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.debased."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""This leaves much to be desired.""")
proselint-0.10.2/tests/test_cursing_nword.py 0000664 0003720 0003720 00000001017 13331225053 022105 0 ustar travis travis 0000000 0000000 """Tests for cursing.nword check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.cursing import nword as chk
class TestCheck(Check):
"""The test class for cursing.nword."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for cursing.nword."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""The n-word.""")
proselint-0.10.2/tests/test_misc_suddenly.py 0000664 0003720 0003720 00000001040 13331225053 022060 0 ustar travis travis 0000000 0000000 """Tests for misc.suddenly check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import suddenly as chk
class TestCheck(Check):
"""The test class for misc.suddenly."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.suddenly."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""Suddenly, it all made sense.""")
proselint-0.10.2/tests/test_malaproprisms.py 0000664 0003720 0003720 00000001073 13331225053 022115 0 ustar travis travis 0000000 0000000 """Tests for malaproprisms.misc check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.malapropisms import misc as chk
class TestCheck(Check):
"""The test class for malaproprisms.misc."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for malaproprisms.misc."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""Found in the Infinitesimal Universe.""")
proselint-0.10.2/tests/test_misc_commercialese.py 0000664 0003720 0003720 00000001070 13331225053 023044 0 ustar travis travis 0000000 0000000 """Tests for misc.commercialese check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import commercialese as chk
class TestCheck(Check):
"""The test class for misc.commercialese."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.commercialese."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""We regret to inform you of this.""")
proselint-0.10.2/tests/test_spelling_in_un.py 0000664 0003720 0003720 00000001040 13331225053 022223 0 ustar travis travis 0000000 0000000 """Tests for spelling.in_un check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.spelling import in_un as chk
class TestCheck(Check):
"""The test class for spelling.in_un."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for spelling.in_un."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""The plan was unfeasible.""")
proselint-0.10.2/tests/test_misc_latin.py 0000664 0003720 0003720 00000001031 13331225053 021340 0 ustar travis travis 0000000 0000000 """Tests for misc.latin check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import latin as chk
class TestCheck(Check):
"""The test class for misc.latin."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.latin."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""And ceteris paribus, it was good.""")
proselint-0.10.2/tests/test_misc_waxed.py 0000664 0003720 0003720 00000001031 13331225053 021341 0 ustar travis travis 0000000 0000000 """Tests for misc.waxed check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import waxed as chk
class TestCheck(Check):
"""The test class for misc.waxed."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.waxed."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""They really could wax poetically.""")
proselint-0.10.2/tests/test_misc_apologizing.py 0000664 0003720 0003720 00000001050 13331225053 022554 0 ustar travis travis 0000000 0000000 """Tests for misc.apologizing check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import apologizing as chk
class TestCheck(Check):
"""The test class for misc.apologizing."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.apologizing."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""More research is needed.""")
proselint-0.10.2/tests/test_misc_not_guilty.py 0000664 0003720 0003720 00000001105 13331225053 022430 0 ustar travis travis 0000000 0000000 """Tests for misc.not_guilty check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import not_guilty as chk
class TestCheck(Check):
"""The test class for misc.not_guilty."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.not_guilty."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes(
"""She is not guilty beyond a reasonable doubt.""")
proselint-0.10.2/tests/test_strunk_white_eos.py 0000664 0003720 0003720 00000001303 13331225053 022614 0 ustar travis travis 0000000 0000000 """Unit tests for strunk_white_eos."""
# from __future__ import absolute_import
# from .check import Check
# from proselint.checks.strunkwhite import elementary_composition as chk
# class TestCheck(Check):
# """Define the suite of checks."""
# __test__ = True
# @property
# def this_check(self):
# return chk
# def test_with_utilized(self):
# """Don't produce an error when 'use' is used correctly."""
# assert self.check("I use a hammer to drive nails into wood.")
# def test_no_utilized(self):
# """Produce an error when 'utilize' is used in place of 'use'."""
# assert not self.check("I utilize a hammer to drive nails into wood.")
proselint-0.10.2/tests/test_spelling_able_atable.py 0000664 0003720 0003720 00000001106 13331225053 023331 0 ustar travis travis 0000000 0000000 """Tests for spelling.able_atable check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.spelling import able_atable as chk
class TestCheck(Check):
"""The test class for spelling.able_atable."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for spelling.able_atable."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""There was a demonstratable difference.""")
proselint-0.10.2/tests/test_misc_usage.py 0000664 0003720 0003720 00000000631 13331225053 021342 0 ustar travis travis 0000000 0000000 """Tests for misc.usage check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import usage as chk
class TestCheck(Check):
"""The test class for misc.usage."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.usage."""
pass
proselint-0.10.2/tests/test_misc_composition.py 0000664 0003720 0003720 00000001050 13331225053 022575 0 ustar travis travis 0000000 0000000 """Tests for misc.composition check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import composition as chk
class TestCheck(Check):
"""The test class for misc.composition."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.composition."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""His story is not honest.""")
proselint-0.10.2/tests/test_misc_preferred_forms.py 0000664 0003720 0003720 00000001067 13331225053 023426 0 ustar travis travis 0000000 0000000 """Tests for misc.preferred_forms check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import preferred_forms as chk
class TestCheck(Check):
"""The test class for misc.preferred_forms."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.preferred_forms."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""It was almost haloween.""")
proselint-0.10.2/tests/test_psychology.py 0000664 0003720 0003720 00000002454 13331225053 021430 0 ustar travis travis 0000000 0000000 """Tests for psychology.misc check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.psychology import misc as chk
class TestCheck(Check):
"""The test class for psychology.misc."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke_lie_detector_test(self):
"""Basic smoke test for psychology.misc.check_lie_detector_test."""
assert chk.check_lie_detector_test(
"""Smoke phrase with nothing flagged.""") == []
assert chk.check_lie_detector_test(
"""The defendant took a lie detector test.""") != []
def test_smoke_p_equals_zero(self):
"""Basic smoke test for psychology.misc.check_p_equals_zero."""
assert chk.check_p_equals_zero(
"""Smoke phrase with nothing flagged.""") == []
assert chk.check_p_equals_zero(
"""The effect was highly signficant at p = 0.00.""") != []
def test_smoke_mental_telepathy(self):
"""Basic smoke test for psychology.misc.check_mental_telepathy."""
assert chk.check_mental_telepathy(
"""Smoke phrase with nothing flagged.""") == []
assert chk.check_mental_telepathy(
"""I've been practicing mental telepathy.""") != []
proselint-0.10.2/tests/test_spelling_er_or.py 0000664 0003720 0003720 00000001042 13331225053 022223 0 ustar travis travis 0000000 0000000 """Tests for spelling.er_or check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.spelling import er_or as chk
class TestCheck(Check):
"""The test class for spelling.er_or."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for spelling.er_or."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""She met with the invester.""")
proselint-0.10.2/tests/test_clear_cache.py 0000664 0003720 0003720 00000010673 13331225053 021443 0 ustar travis travis 0000000 0000000 # -*- coding: utf-8 -*-
"""Tests for the clear cache operation from proselint.command_line."""
import os
import unittest
from proselint import command_line as cl
try:
from unittest import mock
except ImportError:
# Py2.x
import mock
try:
from builtins import PermissionError
except ImportError:
class PermissionError(OSError):
"""Introduced in Py3.3, emulate for earlier versions."""
def __init__(self, *args, **kwargs):
"""Constructor."""
OSError.__init__(self, *args, **kwargs)
try:
from builtins import FileNotFoundError
except ImportError:
class FileNotFoundError(OSError):
"""Introduced in Py3.3, emulate for earlier versions."""
def __init__(self, *args, **kwargs):
"""Constructor."""
OSError.__init__(self, *args, **kwargs)
try:
from builtins import IsADirectoryError
except ImportError:
class IsADirectoryError(OSError):
"""Introduced in Py3.3, emulate for earlier versions."""
def __init__(self, *args, **kwargs):
"""Constructor."""
OSError.__init__(self, *args, **kwargs)
class Test__delete_compiled_python_files(unittest.TestCase):
"""proselint.command_line._delete_compiled_python_files()."""
def setUp(self):
"""init common data."""
self.base_dir = '.'
self.python_file = 'a.py'
self.pyc_file = 'a.pyc'
self.dot_pyc = '.pyc'
self.files = [
(self.base_dir, ('dummy',), (self.pyc_file,
self.python_file,
self.dot_pyc))
]
self.pyc_file_path = os.path.join(self.base_dir, self.pyc_file)
self.python_file_path = os.path.join(self.base_dir, self.python_file)
self.dot_pyc_path = os.path.join(self.base_dir, self.python_file)
@mock.patch('os.walk')
@mock.patch('os.remove')
def test_delete_pyc_file(self, mock_remove, mock_walk):
"""Ensure 'pyc' files are removed."""
mock_walk.return_value = self.files
cl._delete_compiled_python_files()
mock_remove.assert_called_with(self.pyc_file_path)
@mock.patch('os.walk')
@mock.patch('os.remove')
def test_files_not_deleted(self, mock_remove, mock_walk):
"""Ensure non 'pyc' files are not removed."""
mock_walk.return_value = self.files
cl._delete_compiled_python_files()
with self.assertRaises(AssertionError):
mock_remove.assert_called_with(self.python_file_path)
with self.assertRaises(AssertionError):
mock_remove.assert_called_with(self.dot_pyc_path)
@mock.patch('os.walk')
@mock.patch('os.remove', side_effect=PermissionError)
def test_no_permission(self, mock_remove, mock_walk):
"""Ignore if unable to delete files."""
mock_walk.return_value = self.files
cl._delete_compiled_python_files()
@mock.patch('os.walk')
@mock.patch('os.remove', side_effect=OSError)
def test_on_oserror(self, mock_remove, mock_walk):
"""Ignore if OSError."""
mock_walk.return_value = self.files
cl._delete_compiled_python_files()
@mock.patch('os.walk')
@mock.patch('os.remove', side_effect=FileNotFoundError)
def test_files_not_found(self, mock_remove, mock_walk):
"""Ignore if file not found."""
mock_walk.return_value = self.files
cl._delete_compiled_python_files()
@mock.patch('os.walk')
@mock.patch('os.remove', side_effect=IsADirectoryError)
def test__remove_dir(self, mock_remove, mock_walk):
"""Ignore if attempt to delete a directory."""
mock_walk.return_value = self.files
cl._delete_compiled_python_files()
class Test__delete_cache(unittest.TestCase):
"""proselint.command_line.__delete_cache()."""
def setUp(self):
"""Init common data."""
self.cache_path = os.path.join("proselint", "cache")
@mock.patch('shutil.rmtree')
def test_rm_cache(self, mock_rmtree):
"""Correct directory is removed."""
cl._delete_cache()
mock_rmtree.assert_called_with(self.cache_path)
@mock.patch('shutil.rmtree', side_effect=PermissionError)
def test_no_permission(self, mock_rmtree):
"""Ignore if unable to delete."""
cl._delete_cache()
@mock.patch('shutil.rmtree', side_effect=OSError)
def test_on_oserror(self, mock_rmtree):
"""Ignore if general OSError."""
cl._delete_cache()
proselint-0.10.2/tests/test_misc_tense_present.py 0000664 0003720 0003720 00000001066 13331225053 023117 0 ustar travis travis 0000000 0000000 """Tests for misc.tense_present check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import tense_present as chk
class TestCheck(Check):
"""The test class for misc.tense_present."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.tense_present."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""I did it on accident honestly.""")
proselint-0.10.2/tests/test_misc_punctuation.py 0000664 0003720 0003720 00000001041 13331225053 022603 0 ustar travis travis 0000000 0000000 """Tests for misc.punctuation check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import punctuation as chk
class TestCheck(Check):
"""The test class for misc.punctuation."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.punctuation."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""See Smith et. al.""")
proselint-0.10.2/tests/test_misc_professions.py 0000664 0003720 0003720 00000001060 13331225053 022605 0 ustar travis travis 0000000 0000000 """Tests for misc.professions check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import professions as chk
class TestCheck(Check):
"""The test class for misc.professions."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.professions."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""I really need a shoe repair guy.""")
proselint-0.10.2/tests/test_weasel_words_very.py 0000664 0003720 0003720 00000001062 13331225053 022765 0 ustar travis travis 0000000 0000000 """Tests for weasel_words.very check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.weasel_words import very as chk
class TestCheck(Check):
"""The test class for weasel_words.very."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for weasel_words.very."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""The book was very interesting.""")
proselint-0.10.2/tests/test_weasel_words_misc.py 0000664 0003720 0003720 00000001116 13331225053 022733 0 ustar travis travis 0000000 0000000 """Tests for weasel_words.misc check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.weasel_words import misc as chk
from nose import SkipTest
class TestCheck(Check):
"""The test class for weasel_words.misc."""
raise SkipTest
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for weasel_words.misc."""
assert self.passes("""Smoke phrase with nothing flagged.""")
# FIXME add test when check is implemented
proselint-0.10.2/tests/test_oxymorons.py 0000664 0003720 0003720 00000001044 13331225053 021277 0 ustar travis travis 0000000 0000000 """Tests for oxymorons.misc check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.oxymorons import misc as chk
class TestCheck(Check):
"""The test class for oxymorons.misc."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for oxymorons.misc."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""He needed an exact estimate.""")
proselint-0.10.2/tests/test_mixed_metaphors.py 0000664 0003720 0003720 00000001611 13331225053 022412 0 ustar travis travis 0000000 0000000 """Tests for mixed_metaphors.misc check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.mixed_metaphors import misc as chk
class TestCheck(Check):
"""The test class for mixed_metaphors.misc."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke_bottleneck(self):
"""Basic smoke test for check_bottleneck."""
assert chk.check_bottleneck(
"""Smoke phrase with nothing flagged.""") == []
assert chk.check_bottleneck(
"""The project produced a huge bottleneck.""") != []
def test_smoke_misc(self):
"""Basic smoke test for check_misc."""
assert chk.check_misc(
"""Smoke phrase with nothing flagged.""") == []
assert chk.check_misc(
"""Writing tests is not rocket surgery.""") != []
proselint-0.10.2/tests/test_cursing_nfl.py 0000664 0003720 0003720 00000001030 13331225053 021526 0 ustar travis travis 0000000 0000000 """Tests for cursing.nfl check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.cursing import nfl as chk
class TestCheck(Check):
"""The test class for cursing.nfl."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for cursing.nfl."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""The QB is named ball licker.""")
proselint-0.10.2/tests/test_misc_metadiscourse.py 0000664 0003720 0003720 00000001077 13331225053 023112 0 ustar travis travis 0000000 0000000 """Tests for misc.metadiscourse check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import metadiscourse as chk
class TestCheck(Check):
"""The test class for misc.metadiscourse."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.metadiscourse."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""It's based on the rest of this article.""")
proselint-0.10.2/tests/__init__.py 0000664 0003720 0003720 00000000033 13331225053 017717 0 ustar travis travis 0000000 0000000 """Tests for proselint."""
proselint-0.10.2/tests/test_misc_inferior_superior.py 0000664 0003720 0003720 00000001137 13331225053 024005 0 ustar travis travis 0000000 0000000 """Tests for misc.inferior_superior check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import inferior_superior as chk
class TestCheck(Check):
"""The test class for misc.inferior_superior."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.inferior_superior."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes(
"""It was more inferior than the alternative.""")
proselint-0.10.2/tests/test_misc_bureaucratese.py 0000664 0003720 0003720 00000001120 13331225053 023062 0 ustar travis travis 0000000 0000000 """Tests for misc.bureaucratese check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import bureaucratese as chk
class TestCheck(Check):
"""The test class for misc.bureaucratese."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.bureaucratese."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes(
"""I hope the report meets with your approval.""")
proselint-0.10.2/tests/test_misc_metaconcepts.py 0000664 0003720 0003720 00000000665 13331225053 022732 0 ustar travis travis 0000000 0000000 """Tests for misc.metaconcepts check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import metaconcepts as chk
class TestCheck(Check):
"""The test class for misc.metaconcepts."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.metaconcepts."""
pass
proselint-0.10.2/tests/test_typography_diacritical_marks.py 0000664 0003720 0003720 00000001142 13331225053 025154 0 ustar travis travis 0000000 0000000 """Tests for typography.diacritical_marks check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.typography import diacritical_marks as chk
class TestCheck(Check):
"""The test class for typography.diacritical_marks."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for typography.diacritical_marks."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""He saw the performance by Beyonce.""")
proselint-0.10.2/tests/test_misc_back_formations.py 0000664 0003720 0003720 00000001073 13331225053 023400 0 ustar travis travis 0000000 0000000 """Tests for misc.back_formations check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import back_formations as chk
class TestCheck(Check):
"""The test class for misc.back_formations."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.back_formations."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""It is an improprietous use.""")
proselint-0.10.2/tests/test_misc_false_plurals.py 0000664 0003720 0003720 00000001447 13331225053 023100 0 ustar travis travis 0000000 0000000 """Tests for misc.false_plurals check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import false_plurals as chk
class TestCheck(Check):
"""The test class for misc.false_plurals."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.false_plurals."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""There were several phenomenons.""")
def test_smoke_kudos(self):
"""Basic smoke test for misc.false_plurals.kudos."""
assert chk.check_kudos("""Smoke phrase with nothing flagged.""") == []
assert chk.check_kudos("""I give you many kudos.""") != []
proselint-0.10.2/tests/test_misc_narcissism.py 0000664 0003720 0003720 00000001175 13331225053 022415 0 ustar travis travis 0000000 0000000 """Tests for misc.narcissism check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import narcissism as chk
class TestCheck(Check):
"""The test class for misc.narcissism."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.narcissism."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes(
"""In recent years, an increasing number of scientists have studied
the problem in detail.""")
proselint-0.10.2/tests/test_lgbtq_terms.py 0000664 0003720 0003720 00000001622 13331225053 021547 0 ustar travis travis 0000000 0000000 """Tests for lgbtq.offensive_terms check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.lgbtq import terms as chk
class TestCheck(Check):
"""The test class for lgbtq.terms."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for lgbtq.terms."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert self.passes("""They were a gay couple.""")
assert not self.passes("""He was a homosexual man.""")
def test_homosexual_term(self):
"""Check that the term homosexual does not get caught."""
assert self.passes("""Homosexual.""")
def test_sexual_prefence(self):
"""Check that sexual preference is flagged."""
assert not self.passes("""My sexual preference is for women.""")
proselint-0.10.2/tests/test_preferred_forms_check.py 0000664 0003720 0003720 00000002313 13331225053 023543 0 ustar travis travis 0000000 0000000 """Test the preferred_forms_check function from the tools.py module."""
from __future__ import absolute_import
from .check import Check
from proselint.tools import preferred_forms_check as chk
class TestCheck(Check):
"""The test class for tools.preferred_forms_check."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def setUp(self):
"""Create some test fixtures."""
self.l = [['use', ['utilize']]]
self.l_caps = [["Stone Age", ["stone age"]]]
self.err = 'error message'
self.msg = 'use the preferred form'
def test_smoke(self):
"""Basic smoke test for preferred_forms_check."""
assert chk(
"We utilize this tech", self.l, self.err, self.msg) != []
assert chk(
"We use this tech", self.l, self.err, self.msg) == []
def test_capitalization(self):
"""Test for preferred forms involving capitalization."""
assert not chk(
"In the stone age", self.l_caps, self.err, self.msg,
ignore_case=False)
assert chk(
"In the Stone Age", self.l_caps, self.err, self.msg,
ignore_case=False) == []
proselint-0.10.2/tests/test_cliches.py 0000664 0003720 0003720 00000003406 13331225053 020640 0 ustar travis travis 0000000 0000000 """Test the Cliches.misc module."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.cliches import misc as chk
class TestCheck(Check):
"""The test class for cliches.misc."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def setUp(self):
"""Create test sentences."""
self.l_garner = """Worse than a fate worse than death."""
self.l_write_good = """He's a chip off the old block."""
self.l_gnu_diction = """It's a matter of concern."""
def test_cliches_garner_basic(self):
"""Basic checks on check_cliches_garner."""
assert chk.check_cliches_garner("""No cliches here.""") == []
# use one of the example cliches to verify basic functionality
assert chk.check_cliches_garner(self.l_garner) != []
assert "cliches.garner" in chk.check_cliches_garner(self.l_garner)[0]
def test_cliches_write_good_basic(self):
"""Basic checks on check_cliches_write_good."""
assert chk.check_cliches_write_good("""No cliches here.""") == []
# use one of the example cliches to verify basic functionality
assert chk.check_cliches_write_good(self.l_write_good) != []
assert "cliches.write_good" in chk.check_cliches_write_good(
self.l_write_good)[0]
def test_cliches_gnu_diction_basic(self):
"""Basic check on check_cliches_gnu_diction."""
assert chk.check_cliches_gnu_diction("""No cliches here.""") == []
# use one of the example cliches to verify basic functionality
assert chk.check_cliches_gnu_diction(self.l_gnu_diction) != []
assert "cliches.gnu_diction" in chk.check_cliches_gnu_diction(
self.l_gnu_diction)[0]
proselint-0.10.2/tests/test_terms_venery.py 0000664 0003720 0003720 00000001040 13331225053 021740 0 ustar travis travis 0000000 0000000 """Tests for terms.venery check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.terms import venery as chk
class TestCheck(Check):
"""The test class for terms.venery."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for terms.venery."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""There was a group of alligators.""")
proselint-0.10.2/tests/test_existence_check.py 0000664 0003720 0003720 00000003554 13331225053 022356 0 ustar travis travis 0000000 0000000 """Test the existence_check function from the tools.py module."""
from __future__ import absolute_import
from .check import Check
from proselint.tools import existence_check as chk
class TestCheck(Check):
"""The test class for tools.existence_check."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def setUp(self):
"""setUp method creating some test fixtures."""
self.l = ['abc']
self.err = 'error message'
self.msg = 'it exists'
def test_smoke(self):
"""Basic smoke test to determine that existence_check is working."""
assert chk(
"""abc is as easy as 123""", self.l, self.err, self.msg) != []
assert chk(
"""easy breezy""", self.l, self.err, self.msg) == []
assert self.err in chk(
"""abc is as easy as 123""", self.l, self.err, self.msg)[0]
assert self.msg in chk(
"""abc is as easy as 123""", self.l, self.err, self.msg)[0]
def test_multiple_matches(self):
"""Test that multiple matches are found correctly."""
assert len(
chk("""abc and abc are as easy as 123""",
self.l, self.err, self.msg)) == 2
assert len(
chk("""ABC and abc are as easy as 123""",
self.l, self.err, self.msg, ignore_case=True)) == 2
assert chk(
"""abcabc are easy as 123""", self.l, self.err, self.msg) == []
def test_string_types(self):
"""Test that the function works with different string types."""
assert chk('abc is easy as 123', self.l, self.err, self.msg) != []
assert chk("abc is easy as 123", self.l, self.err, self.msg) != []
assert chk(u'abc is easy as 123', self.l, self.err, self.msg) != []
assert chk(u"abc is easy as 123", self.l, self.err, self.msg) != []
proselint-0.10.2/tests/test_topic_detector.py 0000664 0003720 0003720 00000001305 13331225053 022231 0 ustar travis travis 0000000 0000000 """Test the topic detector tool."""
from proselint.tools import topics
def test_50_Cent_detector_on_topic():
"""Check precision of the 50 Cent topic-detector."""
text = """With the aid of Eminem and Dr. Dre (who produced his first
major-label album, Get Rich or Die Tryin'), Jackson became one
of the world's best selling rappers and rose to prominence with
East Coast hip hop group G-Unit (which he leads de facto). """
assert("50 Cent" in topics(text))
text = """Hip hop was started in the early 50's."""
assert("50 Cent" not in topics(text))
text = """Nowadays it costs 50 cents to buy a lollipop."""
assert("50 Cent" not in topics(text))
proselint-0.10.2/tests/test_jargon.py 0000664 0003720 0003720 00000001034 13331225053 020501 0 ustar travis travis 0000000 0000000 """Tests for jargon.misc check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.jargon import misc as chk
class TestCheck(Check):
"""The test class for jargon.misc."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for jargon.misc."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""I agree it's in the affirmative.""")
proselint-0.10.2/tests/test_misc_greylist.py 0000664 0003720 0003720 00000001045 13331225053 022100 0 ustar travis travis 0000000 0000000 """Tests for misc.greylist check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import greylist as chk
class TestCheck(Check):
"""The test class for misc.greylist."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.greylist."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""She should utilize her knowledge.""")
proselint-0.10.2/tests/test_nonwords.py 0000664 0003720 0003720 00000001043 13331225053 021072 0 ustar travis travis 0000000 0000000 """Tests for nonwords.misc check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.nonwords import misc as chk
class TestCheck(Check):
"""The test class for nonwords.misc."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for nonwords.misc."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""The test was good irregardless.""")
proselint-0.10.2/tests/test_corporate_speak.py 0000664 0003720 0003720 00000001175 13331225053 022410 0 ustar travis travis 0000000 0000000 """Tests for corporate_speak.misc check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.corporate_speak import misc as chk
class TestCheck(Check):
"""The test class for corporate_speak.misc."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for corporate_speak.misc."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert self.passes("""We will discuss it later.""")
assert not self.passes("""We will circle back around to it.""")
proselint-0.10.2/tests/test_garner_dates.py 0000664 0003720 0003720 00000002100 13331225053 021652 0 ustar travis travis 0000000 0000000 """Test garner.dates."""
from __future__ import absolute_import
from __future__ import print_function
from .check import Check
from proselint.checks.dates_times import dates
class TestCheck(Check):
"""Test class for garner.dates."""
__test__ = True
def test_50s_hyphenation(self):
"""Find unneeded hyphen in 50's."""
text = """The 50's were swell."""
errors = dates.check_decade_apostrophes_short(text)
assert len(errors) == 1
def test_50_Cent_hyphenation(self):
"""Don't flag 50's when it refers to 50 Cent's manager."""
text = """
Dr. Dre suggested to 50's manager that he look into signing
Eminem to the G-Unit record label.
"""
errors = dates.check_decade_apostrophes_short(text)
assert len(errors) == 0
def test_dash_and_from(self):
"""Test garner.check_dash_and_from."""
text = """From 1999-2002, Sally served as chair of the committee."""
errors = dates.check_dash_and_from(text)
print(errors)
assert len(errors) == 1
proselint-0.10.2/tests/test_skunked_terms.py 0000664 0003720 0003720 00000001125 13331225053 022100 0 ustar travis travis 0000000 0000000 """Tests for skunked_terms.misc check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.skunked_terms import misc as chk
class TestCheck(Check):
"""The test class for skunked_terms.misc."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for skunked_terms.misc."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes(
"""I gave an impassionate defence of the situation.""")
proselint-0.10.2/tests/test_redundancy_ras_syndrome.py 0000664 0003720 0003720 00000001111 13331225053 024136 0 ustar travis travis 0000000 0000000 """Tests for redundancy.ras_syndrome check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.redundancy import ras_syndrome as chk
class TestCheck(Check):
"""The test class for redundancy.ras_syndrome."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for redundancy.ras_syndrome."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""Please enter your PIN number.""")
proselint-0.10.2/tests/test_dates_times_am_pm.py 0000664 0003720 0003720 00000003777 13331225053 022713 0 ustar travis travis 0000000 0000000 """Tests for dates_times.am_pm check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.dates_times import am_pm as chk
class TestCheck(Check):
"""The test class for dates_times.am_pm."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke_check_lowercase_periods(self):
"""Basic smoke test.
This is for the function
dates_times.am_pm.check_lowercase_periods.
"""
assert chk.check_lowercase_periods(
"Basic smoke phrase without issues.") == []
assert chk.check_lowercase_periods(
"It happened at 7 a.m.") == []
assert chk.check_lowercase_periods(
"It happened at 7 am.") != []
def test_smoke_check_spacing(self):
"""Basic smoke test.
This is for the function
dates_times.am_pm.check_spacing.
"""
assert chk.check_spacing(
"Basic smoke phrase without issues.") == []
assert chk.check_spacing(
"It happened at 7 a.m.") == []
assert chk.check_spacing(
"It happened at 7a.m.") != []
def test_smoke_check_midnight_noon(self):
"""Basic smoke test.
This for the function
dates_times.am_pm.midnight_noon.
"""
assert chk.check_midnight_noon(
"Basic smoke phrase without issues.") == []
assert chk.check_midnight_noon(
"It happened at noon.") == []
assert chk.check_midnight_noon(
"It happened at 12 a.m.") != []
def test_smoke_check_redundancy(self):
"""Basic smoke test.
This for the function
dates_times.am_pm.check_redundancy.
"""
assert chk.check_redundancy(
"Basic smoke phrase without issues.") == []
assert chk.check_redundancy(
"It happened at 7 a.m.") == []
assert chk.check_redundancy(
"It happened at 7a.m. in the morning.") != []
proselint-0.10.2/tests/test_misc_illogic.py 0000664 0003720 0003720 00000002257 13331225053 021666 0 ustar travis travis 0000000 0000000 """Tests for misc.illogic check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import illogic as chk
class TestCheck(Check):
"""The test class for misc.illogic."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.illogic."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""We should preplan the trip.""")
def test_smoke_coin_a_phrase_from(self):
"""Basic smoke test for misc.illogic.check_coin_a_phrase_from."""
assert chk.check_coin_a_phrase_from(
"""Smoke phrase with nothing flagged.""") == []
assert chk.check_coin_a_phrase_from(
"""To coin a phrase from him, No diggity""") != []
def test_smoke_check_without_your_collusion(self):
"""Basic smoke test for misc.illogic."""
assert chk.check_without_your_collusion(
"""Smoke phrase with nothing flagged.""") == []
assert chk.check_without_your_collusion(
"""Not Without your collusion you won't'.""") != []
proselint-0.10.2/tests/test_exit_codes.py 0000664 0003720 0003720 00000001071 13331225053 021350 0 ustar travis travis 0000000 0000000 """Check that the CLI returns the appropriate exit code."""
import subprocess
def test_exit_code_demo():
"""Ensure that linting the demo returns an exit code of 1."""
try:
subprocess.check_output(["proselint", "--demo"])
except subprocess.CalledProcessError as grepexc:
assert(grepexc.returncode == 1)
def test_exit_code_version():
"""Ensure that getting the version returns an exit code of 0."""
try:
subprocess.check_output(["proselint", "--version"])
except subprocess.CalledProcessError:
assert(False)
proselint-0.10.2/tests/_test_version.py 0000664 0003720 0003720 00000000745 13331225053 021055 0 ustar travis travis 0000000 0000000 """Test version number."""
from __future__ import absolute_import
from __future__ import print_function
from .check import Check
from proselint.version import __version__
import subprocess
class TestCheck(Check):
"""Test class for version number."""
__test__ = True
def test_version(self):
"""Make sure the version number is correct."""
out = subprocess.check_output(["proselint", "--version"])
assert out.decode('utf-8') == __version__ + "\n"
proselint-0.10.2/tests/test_hedging.py 0000664 0003720 0003720 00000001047 13331225053 020632 0 ustar travis travis 0000000 0000000 """Tests for hedging.misc check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.hedging import misc as chk
class TestCheck(Check):
"""The test class for hedging.misc."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for hedging.misc."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""I would argue that this is a good test.""")
proselint-0.10.2/tests/test_dates_times_dates.py 0000664 0003720 0003720 00000005146 13331225053 022712 0 ustar travis travis 0000000 0000000 """Tests for dates_times.dates check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.dates_times import dates as chk
class TestCheck(Check):
"""The test class for dates_times.dates."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke_check_decade_apostrophes_short(self):
"""Basic smoke test.
This for the function
dates_times.dates.check_decade_apostrophes_short.
"""
assert chk.check_decade_apostrophes_short(
"Basic smoke phrase without issues.") == []
assert chk.check_decade_apostrophes_short(
"It happened in the 90s.") == []
assert chk.check_decade_apostrophes_short(
"It happened in the 90's.") != []
def test_smoke_check_decade_apostrophes_long(self):
"""Basic smoke test.
This is for the function
dates_times.dates.decade_apostrophes_long.
"""
assert chk.check_decade_apostrophes_long(
"Basic smoke phrase without issues.") == []
assert chk.check_decade_apostrophes_long(
"It happened in the 1980s.") == []
assert chk.check_decade_apostrophes_long(
"It happened in the 1980's.") != []
def test_smoke_check_dash_and_from(self):
"""Basic smoke test.
This for the function
dates_times.dates.dash_and_from.
"""
assert chk.check_dash_and_from(
"Basic smoke phrase without issues.") == []
assert chk.check_dash_and_from(
"It happened from 2000 to 2005.") == []
assert chk.check_dash_and_from(
"It happened from 2000-2005.") != []
def test_smoke_check_month_year_comma(self):
"""Basic smoke test.
This is for the function
dates_times.dates.check_month_year_comma.
"""
assert chk.check_month_year_comma(
"Basic smoke phrase without issues.") == []
assert chk.check_month_year_comma(
"It happened in August 2008.") == []
assert chk.check_month_year_comma(
"It happened in August, 2008.") != []
def test_smoke_check_month_of_year(self):
"""Basic smoke test.
This is for the function
dates_times.dates.check_month_of_year.
"""
assert chk.check_month_of_year(
"Basic smoke phrase without issues.") == []
assert chk.check_month_of_year(
"It happened in August 2008.") == []
assert chk.check_month_of_year(
"It happened in August of 2008.") != []
proselint-0.10.2/tests/test_needless_variants.py 0000664 0003720 0003720 00000001107 13331225053 022733 0 ustar travis travis 0000000 0000000 """Tests for needless_variants.misc check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.needless_variants import misc as chk
class TestCheck(Check):
"""The test class for needless_variants.misc."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for needless_variants.misc."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""It was an extensible telescope.""")
proselint-0.10.2/tests/test_lexical_illusions.py 0000664 0003720 0003720 00000001104 13331225053 022741 0 ustar travis travis 0000000 0000000 """Tests for lexical_illusions.misc check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.lexical_illusions import misc as chk
class TestCheck(Check):
"""The test class for lexical_illusions.misc."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for lexical_illusions.misc."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""Paris in the the springtime.""")
proselint-0.10.2/tests/test_hyperbole.py 0000664 0003720 0003720 00000001031 13331225053 021207 0 ustar travis travis 0000000 0000000 """Tests for hyperbole.misc check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.hyperbole import misc as chk
class TestCheck(Check):
"""The test class for hyperbole.misc."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for hyperbole.misc."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""So exaggerated!!!""")
proselint-0.10.2/tests/test_spelling_em_im_en_in.py 0000664 0003720 0003720 00000001074 13331225053 023360 0 ustar travis travis 0000000 0000000 """Tests for spelling.em_im_en_in check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.spelling import em_im_en_in as chk
class TestCheck(Check):
"""The test class for spelling.em_im_en_in."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for spelling.em_im_en_in."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""We shall imbark on a voyage.""")
proselint-0.10.2/tests/test_misc_but.py 0000664 0003720 0003720 00000001026 13331225053 021027 0 ustar travis travis 0000000 0000000 """Tests for misc.but check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import but as chk
class TestCheck(Check):
"""The test class for misc.but."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.but."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""But I never start with the word "but".""")
proselint-0.10.2/tests/test_misc_scare_quotes.py 0000664 0003720 0003720 00000001065 13331225053 022735 0 ustar travis travis 0000000 0000000 """Tests for misc.scare_quotes check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import scare_quotes as chk
class TestCheck(Check):
"""The test class for misc.scare_quotes."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.scare_quotes."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""What was the 'take-home message'?""")
proselint-0.10.2/tests/test_misc_phrasal_adjectives.py 0000664 0003720 0003720 00000001653 13331225053 024076 0 ustar travis travis 0000000 0000000 """Tests for misc.phrasal_adjectives check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import phrasal_adjectives as chk
class TestCheck(Check):
"""The test class for misc.phrasal_adjectives."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.phrasal_adjectives."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""There were across the board discounts.""")
def test_smoke_ly(self):
"""Basic smoke test for misc.phrasal_adjectives.check_ly."""
assert chk.check_ly("""Smoke phrase with nothing flagged.""") == []
assert chk.check_ly("""He ran swiftly-fast.""")
assert chk.check_ly("""The not-so-hotly-contested
result was fine.""") == []
proselint-0.10.2/tests/illegal-chars.txt 0000664 0003720 0003720 00000000101 13331225053 021052 0 ustar travis travis 0000000 0000000 This file contains an illegal character on the next line...
don
proselint-0.10.2/tests/test_security_credit_card.py 0000664 0003720 0003720 00000001225 13331225053 023415 0 ustar travis travis 0000000 0000000 """Tests for security.credit_card check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.security import credit_card as chk
class TestCheck(Check):
"""The test class for security.credit_card."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for security.credit_card.
This makes use of a test MasterCard number.
"""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes(
"""My credit card number is 5555555555554444.""")
proselint-0.10.2/tests/test_uncomparables.py 0000664 0003720 0003720 00000001061 13331225053 022054 0 ustar travis travis 0000000 0000000 """Tests for uncomparables.misc check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.uncomparables import misc as chk
class TestCheck(Check):
"""The test class for uncomparables.misc."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for uncomparables.misc."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""The item was more unique.""")
proselint-0.10.2/tests/test_spelling_athletes.py 0000664 0003720 0003720 00000001062 13331225053 022730 0 ustar travis travis 0000000 0000000 """Tests for spelling.athletes check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.spelling import athletes as chk
class TestCheck(Check):
"""The test class for spelling.athletes."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for spelling.athletes."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""One of the greats: Cal Ripkin.""")
proselint-0.10.2/tests/test_dfw_uncomparables.py 0000664 0003720 0003720 00000001353 13331225053 022720 0 ustar travis travis 0000000 0000000 """Test dfw.uncomparables."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.uncomparables import misc as chk
class TestCheck(Check):
"""The test class for dfw.uncomparables."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_sample_phrases(self):
"""Find 'very unique'."""
assert not self.passes("""This sentence is very unique.""")
def test_linebreaks(self):
"""Handle linebreaks correctly."""
assert not self.passes("""This sentence is very\nunique.""")
def test_constitutional(self):
"""Don't flag 'more perfect'."""
assert self.passes("""A more perfect union.""")
proselint-0.10.2/tests/test_cursing_filth.py 0000664 0003720 0003720 00000001034 13331225053 022061 0 ustar travis travis 0000000 0000000 """Tests for cursing.filth check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.cursing import filth as chk
class TestCheck(Check):
"""The test class for cursing.filth."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for cursing.filth."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""Bad shit in this phrase.""")
proselint-0.10.2/tests/test_terms_denizen_labels.py 0000664 0003720 0003720 00000001101 13331225053 023404 0 ustar travis travis 0000000 0000000 """Tests for terms.denizen_labels check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.terms import denizen_labels as chk
class TestCheck(Check):
"""The test class for terms.denizen_labels."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for terms.denizen_labels."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""He was definitely a Hong Kongite.""")
proselint-0.10.2/tests/test_illegal_chars.py 0000664 0003720 0003720 00000002236 13331225053 022017 0 ustar travis travis 0000000 0000000 """Check that the CLI can handle invalid characters."""
import os.path as pth
import subprocess
def test_invalid_characters():
"""Ensure that a file with illegal characters does not break us."""
try:
output = ""
curr_dir = pth.dirname(pth.abspath(__file__))
test_file = pth.join(curr_dir, "illegal-chars.txt")
# We only print out exception text and continue after printing a trace,
# so the only way (currently) to test for failure is to look for the
# exception text. Refactoring the command line function would let us
# write better tests (one day).
output = str(subprocess.check_output(
["proselint", test_file],
stderr=subprocess.STDOUT
))
except subprocess.CalledProcessError as e:
# Non-zero return codes are OK, but what did we catch?
print("Non-zero return value: will proceed. %s" % e)
output += str(e.output)
except Exception:
assert(not "Unknown Exception Occurred")
assert("UnicodeDecodeError" not in output) # Failed to process the file
assert("FileNotFoundError" not in output) # Failed to find our test file
proselint-0.10.2/tests/test_consistency_check.py 0000664 0003720 0003720 00000001636 13331225053 022727 0 ustar travis travis 0000000 0000000 """Test the consistency_check function from the tools.py module."""
from __future__ import absolute_import
from .check import Check
from proselint.tools import consistency_check as chk
class TestCheck(Check):
"""The test class for tools.consistency_check."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def setUp(self):
"""Create some test fixtures."""
self.l = [['colour', 'color']]
self.err = 'error message'
self.msg = 'inconsistent form of {} vs {}'
def test_smoke(self):
"""Basic smoke test for consistency_check."""
assert chk(
"Painting colour on color", self.l, self.err, self.msg) != []
assert chk(
"Painting colour on colour", self.l, self.err, self.msg) == []
assert chk(
"Painting color on color", self.l, self.err, self.msg) == []
proselint-0.10.2/tests/check.py 0000664 0003720 0003720 00000003365 13331225053 017250 0 ustar travis travis 0000000 0000000 """Check that a check is working."""
from past.builtins import basestring
from unittest import TestCase
import os
import codecs
class Check(TestCase):
"""All tests inherit from Check."""
__test__ = False
def setUp(self):
"""Placeholder for setup procedure."""
pass
def tearDown(self):
"""Placeholder for teardown procedure."""
from proselint.tools import close_cache_shelves
close_cache_shelves()
@property
def this_check(self):
"""The specific check."""
raise NotImplementedError
def passes(self, lst):
"""Check if the test runs cleanly on the given text."""
if isinstance(lst, basestring):
lst = [lst]
errors = []
for text in lst:
errors.append(self.this_check.check(text))
return len(errors[0]) == 0
def wpe_too_high(self):
"""Check whether the check is too noisy."""
min_wpe = 50
examples_dir = os.path.join(os.getcwd(), "tests", "corpus")
examples = os.listdir(examples_dir)
for example in examples:
example_path = os.path.join(examples_dir, example)
if ".DS_Store" in example_path:
break
# Compute the number of words per (wpe) error.
with codecs.open(example_path, "r", encoding='utf-8') as f:
text = f.read()
num_errors = len(self.this_check.check(text))
num_words = len(text)
try:
wpe = 1.0 * num_words / num_errors
except ZeroDivisionError:
wpe = float('Inf')
# Make sure that
assert wpe > min_wpe, \
"{} has only {} wpe.".format(example, round(wpe, 2))
proselint-0.10.2/tests/test_sexism.py 0000664 0003720 0003720 00000001072 13331225053 020533 0 ustar travis travis 0000000 0000000 """Tests for sexism.misc check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.sexism import misc as chk
class TestCheck(Check):
"""The test class for sexism.misc."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for sexism.misc."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes(
"""The legal team had two lawyers and a lady lawyer.""")
proselint-0.10.2/tests/test_butterick_symbols.py 0000664 0003720 0003720 00000003131 13331225053 022765 0 ustar travis travis 0000000 0000000 """Test Butterick's symbols."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.typography import symbols as chk
class TestCheck(Check):
"""The test class for typography.symbols."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_ellipsis(self):
"""Find ... in a string."""
assert chk.check_ellipsis("""The long and winding road...""")
def test_copyright(self):
"""Find a (c) or (C) in a string."""
assert chk.check_copyright_symbol("""Show me the money! (C)""")
assert chk.check_copyright_symbol("""Show me the money! (c)""")
def test_trademark(self):
"""Find a (TM) or (tm) in a string."""
assert chk.check_trademark_symbol("""The Fresh Maker (TM)""")
assert chk.check_trademark_symbol("""The Fresh Maker (tm)""")
def test_registered_trademark(self):
"""Find a (r) or (R) in a string."""
assert chk.check_registered_trademark_symbol("""Just Do It (R)""")
assert chk.check_registered_trademark_symbol("""Just Do It (r)""")
def test_sentence_spacing(self):
"""Find a sentence followed by three or more spaces."""
assert chk.check_sentence_spacing(
"""This is a sentence. This is another.""")
def test_multiplication(self):
"""Find an x between two digits."""
assert chk.check_multiplication_symbol(
"""It is obvious that 2 x 2 = 4.""")
def test_curly_quotes(self): # FIXME
"""Find "" quotes in a string."""
pass
proselint-0.10.2/tests/test_terms_animal_adjectives.py 0000664 0003720 0003720 00000001113 13331225053 024073 0 ustar travis travis 0000000 0000000 """Tests for terms.animal_adjectives check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.terms import animal_adjectives as chk
class TestCheck(Check):
"""The test class for terms.animal_adjectives."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for terms.animal_adjectives."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""It was some bird-like creature.""")
proselint-0.10.2/tests/test_demo.py 0000664 0003720 0003720 00000000154 13331225053 020147 0 ustar travis travis 0000000 0000000 """Run the demo."""
import subprocess
subprocess.call(["proselint", "--debug", ">/dev/null"], shell=True)
proselint-0.10.2/tests/test_typography_symbols.py 0000664 0003720 0003720 00000003131 13331225053 023177 0 ustar travis travis 0000000 0000000 """Test Butterick's symbols."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.typography import symbols as chk
class TestCheck(Check):
"""The test class for typography.symbols."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_ellipsis(self):
"""Find ... in a string."""
assert chk.check_ellipsis("""The long and winding road...""")
def test_copyright(self):
"""Find a (c) or (C) in a string."""
assert chk.check_copyright_symbol("""Show me the money! (C)""")
assert chk.check_copyright_symbol("""Show me the money! (c)""")
def test_trademark(self):
"""Find a (TM) or (tm) in a string."""
assert chk.check_trademark_symbol("""The Fresh Maker (TM)""")
assert chk.check_trademark_symbol("""The Fresh Maker (tm)""")
def test_registered_trademark(self):
"""Find a (r) or (R) in a string."""
assert chk.check_registered_trademark_symbol("""Just Do It (R)""")
assert chk.check_registered_trademark_symbol("""Just Do It (r)""")
def test_sentence_spacing(self):
"""Find a sentence followed by three or more spaces."""
assert chk.check_sentence_spacing(
"""This is a sentence. This is another.""")
def test_multiplication(self):
"""Find an x between two digits."""
assert chk.check_multiplication_symbol(
"""It is obvious that 2 x 2 = 4.""")
def test_curly_quotes(self): # FIXME
"""Find "" quotes in a string."""
pass
proselint-0.10.2/tests/test_gmeu/ 0000775 0003720 0003720 00000000000 13331225202 017602 5 ustar travis travis 0000000 0000000 proselint-0.10.2/tests/test_gmeu/test_a_C.py 0000664 0003720 0003720 00000000303 13331225053 021675 0 ustar travis travis 0000000 0000000 #!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Test GMEU entry 'a', part C.
This entry is about pronunciation of the word 'a' and is unlikely to be
relevant to usage in written language.
"""
proselint-0.10.2/tests/test_gmeu/test_a_B.py 0000664 0003720 0003720 00000001310 13331225053 021673 0 ustar travis travis 0000000 0000000 #!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Test GMEU entry 'a', part B."""
from proselint.tools import assert_error
from nose import SkipTest
def test_a_distributive():
"""Use a over per in the distributive sense."""
raise SkipTest
sentences = [
"An apple per day keeps the doctor away.",
"I sleep eight hours per night.",
"Their policy allows one golf cart a couple.",
"The company donated five books a student.",
"Our a-unit cost is less than $1000.",
"The $50-a-parent fee seems unreasonably high."
]
error_check_name = "misc.a_distributive"
for sentence in sentences:
yield assert_error, sentence, error_check_name
proselint-0.10.2/tests/test_gmeu/test_a_A.py 0000664 0003720 0003720 00000004125 13331225053 021701 0 ustar travis travis 0000000 0000000 #!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Test GMEU entry 'a', part A."""
from proselint.tools import assert_error
from nose import SkipTest
def test_a_vs_an():
"""Use the correct determiner."""
raise SkipTest
sentences = [
"Are you an Yankee fan?",
"Coffee tastes less sweet in an white mug.",
"One of them wore a opalescent vest.",
"You're a intelligent guy, often misguided.",
"Ezra gave an eulogy.",
"What capital of an European country is the farthest north?",
"His sole reward was an one-year term as Ambassador to Thailand.",
"I will be relying on a roulette wheel and an Ouija board.",
"Anyone in an uniform is fair game.",
"Grimm started working as a F.B.I. agent in 1995.",
"Out of 186 managers participating, 57 had a MBA degree.",
"Smith announced that a SEC filing is pending.",
"This argument is an historical desecration.",
u"The treatment of crime in Britain shows an historic shift away…",
"It is, in some ways, an humble form.",
"The thief turned out to be an habitual offender from Darlington.",
"This stage displays an hallucinatory image that signifies itself.",
"He saw an hallucinatory image before passing out.",
"A triumphant Adolf Hitler addressed an hysterical crowd.",
"Kun pieced together an history of gender-segregated dining in L.A.",
"An historian who fled the Nazis and still wants us to read Hitler.",
"It is nominally an historical novel.",
"It feels good to validate an hypothesis.",
"An hereditary title can be passed to a member of the family.",
"The Clinton Presidency was an historic era of prosperity.",
"There comes to be an habitual pattern between neurons in the brain.",
"They had the authority to start an humanitarian intervention.",
"She laughed aloud, an hysterical sort of giggled, quickly stifled",
]
error_check_name = "misc.a_vs_an"
for sentence in sentences:
yield assert_error, sentence, error_check_name
proselint-0.10.2/tests/test_archaism.py 0000664 0003720 0003720 00000001154 13331225053 021013 0 ustar travis travis 0000000 0000000 """Tests for archaism.misc check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.archaism import misc as chk
class TestCheck(Check):
"""The test class for archaism.misc."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for archaism.misc."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert self.passes("""I want to sleep, and maybe dream.""")
assert not self.passes("""I want to sleep, perchance to dream.""")
proselint-0.10.2/tests/test_lgbtq_offensive_terms.py 0000664 0003720 0003720 00000001143 13331225053 023611 0 ustar travis travis 0000000 0000000 """Tests for lgbtq.terms check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.lgbtq import offensive_terms as chk
class TestCheck(Check):
"""The test class for lgbtq.offensive_terms."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for lgbtq.offensive_terms."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert self.passes("""I once met a gay man.""")
assert not self.passes("""I once met a fag.""")
proselint-0.10.2/tests/test_misc_pretension.py 0000664 0003720 0003720 00000001063 13331225053 022424 0 ustar travis travis 0000000 0000000 """Tests for misc.pretension check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import pretension as chk
class TestCheck(Check):
"""The test class for misc.pretension."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.pretension."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""We need to reconceptualize the project.""")
proselint-0.10.2/tests/test_spelling_misc.py 0000664 0003720 0003720 00000001025 13331225053 022051 0 ustar travis travis 0000000 0000000 """Tests for spelling.misc check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.spelling import misc as chk
class TestCheck(Check):
"""The test class for spelling.misc."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for spelling.misc."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""I like this alot.""")
proselint-0.10.2/tests/test_misc_chatspeak.py 0000664 0003720 0003720 00000001033 13331225053 022176 0 ustar travis travis 0000000 0000000 """Tests for misc.chatspeak check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import chatspeak as chk
class TestCheck(Check):
"""The test class for misc.chatspeak."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.chatspeak."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""BRB getting coffee.""")
proselint-0.10.2/tests/test_misc_whence.py 0000664 0003720 0003720 00000001031 13331225053 021502 0 ustar travis travis 0000000 0000000 """Tests for misc.whence check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import whence as chk
class TestCheck(Check):
"""The test class for misc.whence."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.whence."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""Go back from whence you came!""")
proselint-0.10.2/tests/test_mondegreens.py 0000664 0003720 0003720 00000001147 13331225053 021534 0 ustar travis travis 0000000 0000000 """Tests for mondegreens.misc check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.mondegreens import misc as chk
class TestCheck(Check):
"""The test class for mondegreens.misc."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for mondegreens.misc."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert self.passes("""... and laid him on the green.""")
assert not self.passes("""..and Lady Mondegreen.""")
proselint-0.10.2/tests/test_annotations.py 0000664 0003720 0003720 00000001144 13331225053 021560 0 ustar travis travis 0000000 0000000 """Tests for annotations.misc check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.annotations import misc as chk
class TestCheck(Check):
"""The test class for annotations.misc."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for annotations.misc."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert self.passes("""Add it to the to do list.""")
assert not self.passes("""Add it to the TODO list.""")
proselint-0.10.2/tests/test_misc_many_a.py 0000664 0003720 0003720 00000001062 13331225053 021501 0 ustar travis travis 0000000 0000000 """Tests for misc.many_a check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import many_a as chk
class TestCheck(Check):
"""The test class for misc.many_a."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.many_a."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes(
"""There were many a day I thought about it.""")
proselint-0.10.2/tests/test_tools.py 0000664 0003720 0003720 00000002023 13331225053 020360 0 ustar travis travis 0000000 0000000 """Test the tools module."""
from __future__ import absolute_import
from .check import Check
from proselint.tools import lint as lint
class TestLint(Check):
"""The test class for tools.lint."""
__test__ = True
def setUp(self):
"""setUp method creating text fixtures."""
self.text = """But this is a very bad sentence.
This is also a no-good sentence.
"""
self.text_with_no_newline = """A very bad sentence."""
def extract_line_col(self, error):
"""Extract the line and column number from an error tuple."""
_, _, line, column, _, _, _, _, _ = error
return line, column
def test_errors_sorted(self):
"""Test that errors are sorted by line and column number."""
lines_and_cols = [self.extract_line_col(e) for e in lint(self.text)]
assert sorted(lines_and_cols) == lines_and_cols
def test_on_no_newlines(self):
"""Test that lint works on text without a terminal newline."""
assert len(lint(self.text_with_no_newline)) == 1
proselint-0.10.2/tests/test_terms_eponymous_adjectives.py 0000664 0003720 0003720 00000001131 13331225053 024670 0 ustar travis travis 0000000 0000000 """Tests for terms.eponymous_adjectives check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.terms import eponymous_adjectives as chk
class TestCheck(Check):
"""The test class for terms.eponymous_adjectives."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for terms.eponymous_adjectives."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""The writing wasn't Shakespearian.""")
proselint-0.10.2/tests/test_misc_capitalization.py 0000664 0003720 0003720 00000002065 13331225053 023254 0 ustar travis travis 0000000 0000000 """Tests for misc.capitalization check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.misc import capitalization as chk
class TestCheck(Check):
"""The test class for misc.capitalization."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for misc.capitalization.check."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""It goes back to the stone age.""")
def test_smoke_check_months(self):
"""Basic smoke test for misc.capitalization.check_months."""
assert chk.check_months("""Smoke phrase with nothing flagged""") == []
assert chk.check_months("""A nice day in june.""") != []
def test_smoke_check_days(self):
"""Basic smoke test for misc.capitalization.check_days."""
assert chk.check_days("""Smoke phrase with nothing flagged""") == []
assert chk.check_days("""It happened on friday.""") != []
proselint-0.10.2/tests/test_security_password.py 0000664 0003720 0003720 00000001152 13331225053 023013 0 ustar travis travis 0000000 0000000 """Tests for security.password check."""
from __future__ import absolute_import
from .check import Check
from proselint.checks.security import password as chk
class TestCheck(Check):
"""The test class for security.password."""
__test__ = True
@property
def this_check(self):
"""Boilerplate."""
return chk
def test_smoke(self):
"""Basic smoke test for security.password."""
assert self.passes("""Smoke phrase with nothing flagged.""")
assert not self.passes("""The password is 123456.""")
assert not self.passes("""My password is PASSWORD.""")
proselint-0.10.2/MANIFEST.in 0000664 0003720 0003720 00000000141 13331225053 016202 0 ustar travis travis 0000000 0000000 include README.md LICENSE.md CHANGELOG.md tests/illegal-chars.txt tests/*.py tests/test_gmeu/*.py proselint-0.10.2/PKG-INFO 0000664 0003720 0003720 00000034574 13331225202 015556 0 ustar travis travis 0000000 0000000 Metadata-Version: 2.1
Name: proselint
Version: 0.10.2
Summary: A linter for prose.
Home-page: http://github.com/amperser/proselint
Author: Amperser Labs
Author-email: hello@amperser.com
License: BSD
Download-URL: http://github.com/amperser/proselint/tarball/0.10.2
Description:
[](https://travis-ci.org/amperser/proselint)
[](https://ci.appveyor.com/project/suchow/proselint-knwyf/branch/master)
[](https://houndci.com)
[](https://codeclimate.com/repos/5538989ee30ba0793100090f/feed)
[](https://coveralls.io/github/amperser/proselint?branch=master)
[](https://gemnasium.com/amperser/proselint)
[](https://en.wikipedia.org/wiki/BSD_licenses)
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 American Usage*, a 975-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, like a spell checker, scans through a document and analyzes it.)
`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, E.B. 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.
`proselint` is a command-line utility that can be integrated into existing tools.
### Installation
To get this up and running, install it using [pip](https://packaging.python.org/installing/#use-pip-for-installing):
```
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:
- [x] A [demo editor](http://proselint.com/write)
- [x] [Sublime Text](https://github.com/amperser/proselint/tree/master/plugins/sublime/SublimeLinter-contrib-proselint)
- [x] [Atom Editor](https://github.com/smockle/linter-proselint) (thanks to [Clay Miller](https://github.com/smockle)).
- [x] [Emacs via Flycheck](http://www.flycheck.org/).
- [x] Vim via [ALE](https://github.com/w0rp/ale) or [Syntastic](https://github.com/vim-syntastic/syntastic) (thanks to @lcd047, @Carreau, and [Daniel M. Capella](https://github.com/polyzen))
- [x] [Phabricator's `arc` CLI](https://github.com/google/arc-proselint) (thanks to [Jeff Verkoeyen](https://github.com/jverkoey))
- [x] [Danger](https://github.com/dbgrandi/danger-prose) (thanks to [David Grandinetti](https://github.com/dbgrandi) and [Orta Therox](https://github.com/orta))
- [x] [Visual Studio Code](https://github.com/ppeszko/vscode-proselint) (thanks to [Patryk Peszko](https://github.com/ppeszko))
- [x] [coala](https://github.com/coala-analyzer/bear-docs/blob/master/docs/ProseLintBear.rst) (thanks to the [coala Development Group](https://github.com/coala-analyzer))
- [x] [IntelliJ](https://github.com/kropp/intellij-proselint) (by [Victor Kropp](https://github.com/kropp))
- [x] [pre-commit](https://pre-commit.com/) (by [Andy Airey](https://github.com/aairey))
### Usage
Suppose you had a document `text.md` with the following text:
```
John is very unique.
```
You can run `proselint` over the document using the command line:
```bash
❯ proselint text.md
```
This prints a list of suggestions to stdout, one per line. Each suggestion has the form:
```bash
text.md:::
```
For example,
```bash
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:
```javascript
{
// 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,
// 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 program, you can use the `lint` function in `proselint.tools`:
```python
import proselint
suggestions = proselint.tools.lint("This sentence is very unique")
```
This will return a list of suggestions:
```python
[('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`. If `$XDG_CONFIG_HOME` is not set or empty, `~/.config/proselint/config` will be used.
Additionally for compatible reason, the legacy configuration `~/.proselintrc` will be used if `$XDG_CONFIG_HOME/proselint/config` does not exist.
```json
{
"checks": {
"typography.diacritical_marks": false
}
}
```
| ID | Description |
| ----- | --------------- |
| `airlinese.misc` | Avoiding jargon of the airline industry |
| `annotations.misc` | Catching annotations left in the text |
| `archaism.misc` | Avoiding archaic forms |
| `cliches.hell` | Avoiding a common cliché |
| `cliches.misc` | Avoiding clichés |
| `consistency.spacing` | Consistent sentence spacing |
| `consistency.spelling` | Consistent spelling |
| `corporate_speak.misc` | Avoiding corporate buzzwords |
| `cursing.filth` | Words to avoid |
| `cursing.nfl` | Avoiding words banned by the NFL |
| `dates_times.am_pm` | Using the right form for the time of day |
| `dates_times.dates` | Stylish formatting of dates |
| `hedging.misc` | Not hedging |
| `hyperbole.misc` | Not being hyperbolic |
| `jargon.misc` | Avoiding miscellaneous jargon |
| `lgbtq.offensive_terms` | Avoding offensive LGBTQ terms |
| `lgbtq.terms` | Misused LGBTQ terms |
| `lexical_illusions.misc` | Avoiding lexical illusions |
| `links.broken` | Linking only to existing sites |
| `malapropisms.misc` | Avoiding common malapropisms |
| `misc.apologizing` | Being confident |
| `misc.back_formations` | Avoiding needless backformations |
| `misc.bureaucratese` | Avoiding bureaucratese |
| `misc.but` | Avoid starting a paragraph with "But..." |
| `misc.capitalization` | Capitalizing only what ought to be capitalized |
| `misc.chatspeak` | Avoiding lolling and other chatspeak |
| `misc.commercialese` | Avoiding jargon of the commercial world |
| `misc.currency` | Avoiding redundant currency symbols |
| `misc.debased` | Avoiding debased language |
| `misc.false_plurals` | Avoiding false plurals |
| `misc.illogic` | Avoiding illogical forms |
| `misc.inferior_superior` | Superior to, not than |
| `misc.latin` | Avoiding overuse of Latin phrases |
| `misc.many_a` | Many a singular |
| `misc.metaconcepts` | Avoiding overuse of metaconcepts |
| `misc.narcissism` | Talking about the subject, not its study |
| `misc.phrasal_adjectives` | Hyphenating phrasal adjectives |
| `misc.preferred_forms` | Miscellaneous preferred forms |
| `misc.pretension` | Avoiding being pretentious |
| `misc.professions` | Calling jobs by the right name |
| `misc.punctuation` | Using punctuation assiduously |
| `misc.scare_quotes` | Using scare quotes only when needed |
| `misc.suddenly` | Avoiding the word suddenly |
| `misc.tense_present` | Advice from Tense Present |
| `misc.waxed` | Waxing poetic |
| `misc.whence` | Using "whence" |
| `mixed_metaphors.misc` | Not mixing metaphors |
| `mondegreens.misc` | Avoiding mondegreen |
| `needless_variants.misc` | Using the preferred form |
| `nonwords.misc` | Avoid using nonwords |
| `oxymorons.misc` | Avoiding oxymorons |
| `psychology.misc` | Avoiding misused psychological terms |
| `redundancy.misc` | Avoiding redundancy and saying things twice |
| `redundancy.ras_syndrome` | Avoiding RAS syndrome |
| `skunked_terms.misc` | Avoid using skunked terms |
| `spelling.able_atable` | -able vs. -atable |
| `spelling.able_ible` | -able vs. -ible |
| `spelling.athletes` | Spelling of athlete names |
| `spelling.em_im_en_in` | -em vs. -im and -en vs. -in |
| `spelling.er_or` | -er vs. -or |
| `spelling.in_un` | in- vs. un- |
| `spelling.misc` | Spelling words corectly |
| `security.credit_card` | Keeping credit card numbers secret |
| `security.password` | Keeping passwords secret |
| `sexism.misc` | Avoiding sexist language |
| `terms.animal_adjectives` | Animal adjectives |
| `terms.denizen_labels` | Calling denizens by the right name |
| `terms.eponymous_adjectives` | Calling people by the right name |
| `terms.venery` | Call groups of animals by the right name |
| `typography.diacritical_marks` | Using dïacríticâl marks |
| `typography.exclamation` | Avoiding overuse of exclamation |
| `typography.symbols` | Using the right symbols |
| `uncomparables.misc` | Not comparing uncomparables |
| `weasel_words.misc` | Avoiding weasel words |
| `weasel_words.very` | Avoiding the word "very" |
### Contributing
Interested in contributing to `proselint`? Great — there are plenty of ways you can help. Read more on [our website](http://proselint.com/contributing/), where we describe how you can help us build `proselint` into the greatest writing tool in the world.
- [Issue Tracker](http://github.com/amperser/proselint/issues)
- [Source Code](http://github.com/amperser/proselint)
### Support
If you run into a problem, please [open an issue](http://github.com/amperser/proselint/issues) 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, use the test runner [pytest](https://docs.pytest.org/en/latest/) and run the following commands:
```bash
pytest
```
and watch the output. Nose is compatible with Python versions 2.7, 3.4, 3.5 and 3.6.
All automated tests in `tests/` are run as part of each submitted pull request, including newly added tests.
### License
The project is licensed under the BSD license.
Platform: UNKNOWN
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: Implementation :: CPython
Description-Content-Type: text/markdown
proselint-0.10.2/proselint.egg-info/ 0000775 0003720 0003720 00000000000 13331225202 020155 5 ustar travis travis 0000000 0000000 proselint-0.10.2/proselint.egg-info/top_level.txt 0000664 0003720 0003720 00000000012 13331225202 022700 0 ustar travis travis 0000000 0000000 proselint
proselint-0.10.2/proselint.egg-info/not-zip-safe 0000664 0003720 0003720 00000000001 13331225202 022403 0 ustar travis travis 0000000 0000000
proselint-0.10.2/proselint.egg-info/requires.txt 0000664 0003720 0003720 00000000021 13331225202 022546 0 ustar travis travis 0000000 0000000 click
future
six
proselint-0.10.2/proselint.egg-info/PKG-INFO 0000664 0003720 0003720 00000034574 13331225202 021267 0 ustar travis travis 0000000 0000000 Metadata-Version: 2.1
Name: proselint
Version: 0.10.2
Summary: A linter for prose.
Home-page: http://github.com/amperser/proselint
Author: Amperser Labs
Author-email: hello@amperser.com
License: BSD
Download-URL: http://github.com/amperser/proselint/tarball/0.10.2
Description:
[](https://travis-ci.org/amperser/proselint)
[](https://ci.appveyor.com/project/suchow/proselint-knwyf/branch/master)
[](https://houndci.com)
[](https://codeclimate.com/repos/5538989ee30ba0793100090f/feed)
[](https://coveralls.io/github/amperser/proselint?branch=master)
[](https://gemnasium.com/amperser/proselint)
[](https://en.wikipedia.org/wiki/BSD_licenses)
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 American Usage*, a 975-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, like a spell checker, scans through a document and analyzes it.)
`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, E.B. 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.
`proselint` is a command-line utility that can be integrated into existing tools.
### Installation
To get this up and running, install it using [pip](https://packaging.python.org/installing/#use-pip-for-installing):
```
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:
- [x] A [demo editor](http://proselint.com/write)
- [x] [Sublime Text](https://github.com/amperser/proselint/tree/master/plugins/sublime/SublimeLinter-contrib-proselint)
- [x] [Atom Editor](https://github.com/smockle/linter-proselint) (thanks to [Clay Miller](https://github.com/smockle)).
- [x] [Emacs via Flycheck](http://www.flycheck.org/).
- [x] Vim via [ALE](https://github.com/w0rp/ale) or [Syntastic](https://github.com/vim-syntastic/syntastic) (thanks to @lcd047, @Carreau, and [Daniel M. Capella](https://github.com/polyzen))
- [x] [Phabricator's `arc` CLI](https://github.com/google/arc-proselint) (thanks to [Jeff Verkoeyen](https://github.com/jverkoey))
- [x] [Danger](https://github.com/dbgrandi/danger-prose) (thanks to [David Grandinetti](https://github.com/dbgrandi) and [Orta Therox](https://github.com/orta))
- [x] [Visual Studio Code](https://github.com/ppeszko/vscode-proselint) (thanks to [Patryk Peszko](https://github.com/ppeszko))
- [x] [coala](https://github.com/coala-analyzer/bear-docs/blob/master/docs/ProseLintBear.rst) (thanks to the [coala Development Group](https://github.com/coala-analyzer))
- [x] [IntelliJ](https://github.com/kropp/intellij-proselint) (by [Victor Kropp](https://github.com/kropp))
- [x] [pre-commit](https://pre-commit.com/) (by [Andy Airey](https://github.com/aairey))
### Usage
Suppose you had a document `text.md` with the following text:
```
John is very unique.
```
You can run `proselint` over the document using the command line:
```bash
❯ proselint text.md
```
This prints a list of suggestions to stdout, one per line. Each suggestion has the form:
```bash
text.md:::
```
For example,
```bash
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:
```javascript
{
// 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,
// 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 program, you can use the `lint` function in `proselint.tools`:
```python
import proselint
suggestions = proselint.tools.lint("This sentence is very unique")
```
This will return a list of suggestions:
```python
[('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`. If `$XDG_CONFIG_HOME` is not set or empty, `~/.config/proselint/config` will be used.
Additionally for compatible reason, the legacy configuration `~/.proselintrc` will be used if `$XDG_CONFIG_HOME/proselint/config` does not exist.
```json
{
"checks": {
"typography.diacritical_marks": false
}
}
```
| ID | Description |
| ----- | --------------- |
| `airlinese.misc` | Avoiding jargon of the airline industry |
| `annotations.misc` | Catching annotations left in the text |
| `archaism.misc` | Avoiding archaic forms |
| `cliches.hell` | Avoiding a common cliché |
| `cliches.misc` | Avoiding clichés |
| `consistency.spacing` | Consistent sentence spacing |
| `consistency.spelling` | Consistent spelling |
| `corporate_speak.misc` | Avoiding corporate buzzwords |
| `cursing.filth` | Words to avoid |
| `cursing.nfl` | Avoiding words banned by the NFL |
| `dates_times.am_pm` | Using the right form for the time of day |
| `dates_times.dates` | Stylish formatting of dates |
| `hedging.misc` | Not hedging |
| `hyperbole.misc` | Not being hyperbolic |
| `jargon.misc` | Avoiding miscellaneous jargon |
| `lgbtq.offensive_terms` | Avoding offensive LGBTQ terms |
| `lgbtq.terms` | Misused LGBTQ terms |
| `lexical_illusions.misc` | Avoiding lexical illusions |
| `links.broken` | Linking only to existing sites |
| `malapropisms.misc` | Avoiding common malapropisms |
| `misc.apologizing` | Being confident |
| `misc.back_formations` | Avoiding needless backformations |
| `misc.bureaucratese` | Avoiding bureaucratese |
| `misc.but` | Avoid starting a paragraph with "But..." |
| `misc.capitalization` | Capitalizing only what ought to be capitalized |
| `misc.chatspeak` | Avoiding lolling and other chatspeak |
| `misc.commercialese` | Avoiding jargon of the commercial world |
| `misc.currency` | Avoiding redundant currency symbols |
| `misc.debased` | Avoiding debased language |
| `misc.false_plurals` | Avoiding false plurals |
| `misc.illogic` | Avoiding illogical forms |
| `misc.inferior_superior` | Superior to, not than |
| `misc.latin` | Avoiding overuse of Latin phrases |
| `misc.many_a` | Many a singular |
| `misc.metaconcepts` | Avoiding overuse of metaconcepts |
| `misc.narcissism` | Talking about the subject, not its study |
| `misc.phrasal_adjectives` | Hyphenating phrasal adjectives |
| `misc.preferred_forms` | Miscellaneous preferred forms |
| `misc.pretension` | Avoiding being pretentious |
| `misc.professions` | Calling jobs by the right name |
| `misc.punctuation` | Using punctuation assiduously |
| `misc.scare_quotes` | Using scare quotes only when needed |
| `misc.suddenly` | Avoiding the word suddenly |
| `misc.tense_present` | Advice from Tense Present |
| `misc.waxed` | Waxing poetic |
| `misc.whence` | Using "whence" |
| `mixed_metaphors.misc` | Not mixing metaphors |
| `mondegreens.misc` | Avoiding mondegreen |
| `needless_variants.misc` | Using the preferred form |
| `nonwords.misc` | Avoid using nonwords |
| `oxymorons.misc` | Avoiding oxymorons |
| `psychology.misc` | Avoiding misused psychological terms |
| `redundancy.misc` | Avoiding redundancy and saying things twice |
| `redundancy.ras_syndrome` | Avoiding RAS syndrome |
| `skunked_terms.misc` | Avoid using skunked terms |
| `spelling.able_atable` | -able vs. -atable |
| `spelling.able_ible` | -able vs. -ible |
| `spelling.athletes` | Spelling of athlete names |
| `spelling.em_im_en_in` | -em vs. -im and -en vs. -in |
| `spelling.er_or` | -er vs. -or |
| `spelling.in_un` | in- vs. un- |
| `spelling.misc` | Spelling words corectly |
| `security.credit_card` | Keeping credit card numbers secret |
| `security.password` | Keeping passwords secret |
| `sexism.misc` | Avoiding sexist language |
| `terms.animal_adjectives` | Animal adjectives |
| `terms.denizen_labels` | Calling denizens by the right name |
| `terms.eponymous_adjectives` | Calling people by the right name |
| `terms.venery` | Call groups of animals by the right name |
| `typography.diacritical_marks` | Using dïacríticâl marks |
| `typography.exclamation` | Avoiding overuse of exclamation |
| `typography.symbols` | Using the right symbols |
| `uncomparables.misc` | Not comparing uncomparables |
| `weasel_words.misc` | Avoiding weasel words |
| `weasel_words.very` | Avoiding the word "very" |
### Contributing
Interested in contributing to `proselint`? Great — there are plenty of ways you can help. Read more on [our website](http://proselint.com/contributing/), where we describe how you can help us build `proselint` into the greatest writing tool in the world.
- [Issue Tracker](http://github.com/amperser/proselint/issues)
- [Source Code](http://github.com/amperser/proselint)
### Support
If you run into a problem, please [open an issue](http://github.com/amperser/proselint/issues) 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, use the test runner [pytest](https://docs.pytest.org/en/latest/) and run the following commands:
```bash
pytest
```
and watch the output. Nose is compatible with Python versions 2.7, 3.4, 3.5 and 3.6.
All automated tests in `tests/` are run as part of each submitted pull request, including newly added tests.
### License
The project is licensed under the BSD license.
Platform: UNKNOWN
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: Implementation :: CPython
Description-Content-Type: text/markdown
proselint-0.10.2/proselint.egg-info/dependency_links.txt 0000664 0003720 0003720 00000000001 13331225202 024223 0 ustar travis travis 0000000 0000000
proselint-0.10.2/proselint.egg-info/entry_points.txt 0000664 0003720 0003720 00000000100 13331225202 023442 0 ustar travis travis 0000000 0000000 [console_scripts]
proselint = proselint.command_line:proselint
proselint-0.10.2/proselint.egg-info/SOURCES.txt 0000664 0003720 0003720 00000017007 13331225202 022046 0 ustar travis travis 0000000 0000000 CHANGELOG.md
LICENSE.md
MANIFEST.in
README.md
setup.cfg
setup.py
proselint/.proselintrc
proselint/__init__.py
proselint/__main__.py
proselint/command_line.py
proselint/demo.md
proselint/score.py
proselint/tools.py
proselint/version.py
proselint.egg-info/PKG-INFO
proselint.egg-info/SOURCES.txt
proselint.egg-info/dependency_links.txt
proselint.egg-info/entry_points.txt
proselint.egg-info/not-zip-safe
proselint.egg-info/requires.txt
proselint.egg-info/top_level.txt
proselint/checks/__init__.py
proselint/checks/airlinese/__init__.py
proselint/checks/airlinese/misc.py
proselint/checks/annotations/__init__.py
proselint/checks/annotations/misc.py
proselint/checks/archaism/__init__.py
proselint/checks/archaism/misc.py
proselint/checks/cliches/__init__.py
proselint/checks/cliches/hell.py
proselint/checks/cliches/misc.py
proselint/checks/consistency/__init__.py
proselint/checks/consistency/spacing.py
proselint/checks/consistency/spelling.py
proselint/checks/corporate_speak/__init__.py
proselint/checks/corporate_speak/misc.py
proselint/checks/cursing/__init__.py
proselint/checks/cursing/filth.py
proselint/checks/cursing/nfl.py
proselint/checks/cursing/nword.py
proselint/checks/dates_times/__init__.py
proselint/checks/dates_times/am_pm.py
proselint/checks/dates_times/dates.py
proselint/checks/hedging/__init__.py
proselint/checks/hedging/misc.py
proselint/checks/hyperbole/__init__.py
proselint/checks/hyperbole/misc.py
proselint/checks/jargon/__init__.py
proselint/checks/jargon/misc.py
proselint/checks/lexical_illusions/__init__.py
proselint/checks/lexical_illusions/misc.py
proselint/checks/lgbtq/__init__.py
proselint/checks/lgbtq/offensive_terms.py
proselint/checks/lgbtq/terms.py
proselint/checks/links/__init__.py
proselint/checks/links/broken.py
proselint/checks/malapropisms/__init__.py
proselint/checks/malapropisms/misc.py
proselint/checks/misc/__init__.py
proselint/checks/misc/apologizing.py
proselint/checks/misc/back_formations.py
proselint/checks/misc/bureaucratese.py
proselint/checks/misc/but.py
proselint/checks/misc/capitalization.py
proselint/checks/misc/chatspeak.py
proselint/checks/misc/commercialese.py
proselint/checks/misc/composition.py
proselint/checks/misc/currency.py
proselint/checks/misc/debased.py
proselint/checks/misc/false_plurals.py
proselint/checks/misc/greylist.py
proselint/checks/misc/illogic.py
proselint/checks/misc/inferior_superior.py
proselint/checks/misc/institution_name.py
proselint/checks/misc/latin.py
proselint/checks/misc/many_a.py
proselint/checks/misc/metaconcepts.py
proselint/checks/misc/metadiscourse.py
proselint/checks/misc/narcissism.py
proselint/checks/misc/not_guilty.py
proselint/checks/misc/phrasal_adjectives.py
proselint/checks/misc/preferred_forms.py
proselint/checks/misc/pretension.py
proselint/checks/misc/professions.py
proselint/checks/misc/punctuation.py
proselint/checks/misc/scare_quotes.py
proselint/checks/misc/suddenly.py
proselint/checks/misc/tense_present.py
proselint/checks/misc/usage.py
proselint/checks/misc/waxed.py
proselint/checks/misc/whence.py
proselint/checks/mixed_metaphors/__init__.py
proselint/checks/mixed_metaphors/misc.py
proselint/checks/mondegreens/__init__.py
proselint/checks/mondegreens/misc.py
proselint/checks/needless_variants/__init__.py
proselint/checks/needless_variants/misc.py
proselint/checks/nonwords/__init__.py
proselint/checks/nonwords/misc.py
proselint/checks/oxymorons/__init__.py
proselint/checks/oxymorons/misc.py
proselint/checks/psychology/__init__.py
proselint/checks/psychology/misc.py
proselint/checks/redundancy/__init__.py
proselint/checks/redundancy/misc.py
proselint/checks/redundancy/ras_syndrome.py
proselint/checks/security/__init__.py
proselint/checks/security/credit_card.py
proselint/checks/security/password.py
proselint/checks/sexism/__init__.py
proselint/checks/sexism/misc.py
proselint/checks/skunked_terms/__init__.py
proselint/checks/skunked_terms/misc.py
proselint/checks/spelling/__init__.py
proselint/checks/spelling/able_atable.py
proselint/checks/spelling/able_ible.py
proselint/checks/spelling/athletes.py
proselint/checks/spelling/em_im_en_in.py
proselint/checks/spelling/er_or.py
proselint/checks/spelling/in_un.py
proselint/checks/spelling/misc.py
proselint/checks/terms/__init__.py
proselint/checks/terms/animal_adjectives.py
proselint/checks/terms/denizen_labels.py
proselint/checks/terms/eponymous_adjectives.py
proselint/checks/terms/venery.py
proselint/checks/typography/__init__.py
proselint/checks/typography/diacritical_marks.py
proselint/checks/typography/exclamation.py
proselint/checks/typography/symbols.py
proselint/checks/uncomparables/__init__.py
proselint/checks/uncomparables/misc.py
proselint/checks/weasel_words/__init__.py
proselint/checks/weasel_words/misc.py
proselint/checks/weasel_words/very.py
tests/__init__.py
tests/_test_version.py
tests/check.py
tests/illegal-chars.txt
tests/test_annotations.py
tests/test_archaism.py
tests/test_butterick_symbols.py
tests/test_clear_cache.py
tests/test_cliches.py
tests/test_consistency_check.py
tests/test_consistency_spacing.py
tests/test_consistency_spelling.py
tests/test_corporate_speak.py
tests/test_cursing_filth.py
tests/test_cursing_nfl.py
tests/test_cursing_nword.py
tests/test_dates_times_am_pm.py
tests/test_dates_times_dates.py
tests/test_demo.py
tests/test_dfw_uncomparables.py
tests/test_existence_check.py
tests/test_exit_codes.py
tests/test_garner_dates.py
tests/test_hedging.py
tests/test_hyperbole.py
tests/test_illegal_chars.py
tests/test_jargon.py
tests/test_leonard.py
tests/test_lexical_illusions.py
tests/test_lgbtq_offensive_terms.py
tests/test_lgbtq_terms.py
tests/test_malaproprisms.py
tests/test_misc_apologizing.py
tests/test_misc_back_formations.py
tests/test_misc_bureaucratese.py
tests/test_misc_but.py
tests/test_misc_capitalization.py
tests/test_misc_chatspeak.py
tests/test_misc_commercialese.py
tests/test_misc_composition.py
tests/test_misc_currency.py
tests/test_misc_debased.py
tests/test_misc_false_plurals.py
tests/test_misc_greylist.py
tests/test_misc_illogic.py
tests/test_misc_inferior_superior.py
tests/test_misc_latin.py
tests/test_misc_many_a.py
tests/test_misc_metaconcepts.py
tests/test_misc_metadiscourse.py
tests/test_misc_narcissism.py
tests/test_misc_not_guilty.py
tests/test_misc_phrasal_adjectives.py
tests/test_misc_preferred_forms.py
tests/test_misc_pretension.py
tests/test_misc_professions.py
tests/test_misc_punctuation.py
tests/test_misc_scare_quotes.py
tests/test_misc_suddenly.py
tests/test_misc_tense_present.py
tests/test_misc_usage.py
tests/test_misc_waxed.py
tests/test_misc_whence.py
tests/test_mixed_metaphors.py
tests/test_mondegreens.py
tests/test_needless_variants.py
tests/test_nonwords.py
tests/test_oxymorons.py
tests/test_preferred_forms_check.py
tests/test_psychology.py
tests/test_redundancy_misc.py
tests/test_redundancy_ras_syndrome.py
tests/test_security_credit_card.py
tests/test_security_password.py
tests/test_sexism.py
tests/test_skunked_terms.py
tests/test_spelling_able_atable.py
tests/test_spelling_able_ible.py
tests/test_spelling_athletes.py
tests/test_spelling_em_im_en_in.py
tests/test_spelling_er_or.py
tests/test_spelling_in_un.py
tests/test_spelling_misc.py
tests/test_strunk_white_eos.py
tests/test_terms_animal_adjectives.py
tests/test_terms_denizen_labels.py
tests/test_terms_eponymous_adjectives.py
tests/test_terms_venery.py
tests/test_tools.py
tests/test_topic_detector.py
tests/test_typography_diacritical_marks.py
tests/test_typography_exclamation.py
tests/test_typography_symbols.py
tests/test_uncomparables.py
tests/test_weasel_words_misc.py
tests/test_weasel_words_very.py
tests/test_gmeu/test_a_A.py
tests/test_gmeu/test_a_B.py
tests/test_gmeu/test_a_C.py proselint-0.10.2/LICENSE.md 0000664 0003720 0003720 00000002764 13331225053 016065 0 ustar travis travis 0000000 0000000 Copyright © 2014–2015, Jordan Suchow, Michael Pacer, and Lara A. Ross
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.