Search
Search documentation
Natural language plugins
Updated Nov 1, 2026
Natural-language plugins parse prose into nlcst and check or rewrite it. The checks report messages on the file and leave the text as it is. Reach them from Markdown through md.toNaturalLanguage or from HTML through html.toNaturalLanguage.
The tables list each option as Pipeline takes it, by its JSON key and type; each plugin
struct's own fields and Rust types are on docs.rs.
nl.parse
Parses natural language into an nlcst tree of paragraphs, sentences, words and punctuation.
use textlane::{Processor, nl};
let output = Processor::new()
.with(nl::Parse::default())
.with(nl::Smartypants::default())
.with(nl::Stringify)
.freeze()?
.process("\"Hi\" -- she said...")?;
output.value
// “Hi” — she said…Follows retext-english.
| Option | Type | Default | Description |
|---|---|---|---|
language | Language | The rules sentences and words are found by. |
Language
The language nl.parse reads: parse-latin's rules, or parse-english's on top of them.
Takes "latin" | "english".
nl.equality
Warns about insensitive, inconsiderate wording.
use textlane::{Processor, nl};
let output = Processor::new()
.with(nl::Parse::default())
.with(nl::Equality::default())
.with(nl::Stringify)
.freeze()?
.process("Hey guys, the chairman is here.")?;
output.file.messages[0].reason
// Unexpected potentially insensitive use of `guys`, in somes cases `people`, ` …Follows retext-equality.
| Option | Type | Default | Description |
|---|---|---|---|
ignore | string[] | null | null | Phrases not to warn about. |
binary | boolean | null | null | Whether a phrase used next to its counterpart (he or she) is fine. |
nl.passive
Warns about the passive voice.
use textlane::{Processor, nl};
let output = Processor::new()
.with(nl::Parse::default())
.with(nl::Passive::default())
.with(nl::Stringify)
.freeze()?
.process("The cake was eaten.")?;
output.file.messages[0].reason
// Unexpected use of the passive voiceFollows retext-passive.
| Option | Type | Default | Description |
|---|---|---|---|
ignore | string[] | null | null | Participles not to warn about. |
nl.readability
Warns about sentences too hard to read for a target age.
use textlane::{Processor, nl};
let output = Processor::new()
.with(nl::Parse::default())
.with(nl::Readability { age: Some(12.0), ..Default::default() })
.with(nl::Stringify)
.freeze()?
.process("The constitutionally mandated intergovernmental reconciliation procedures necessitate comprehensive multilateral deliberation.")?;
output.file.messages[0].reason
// Unexpected hard to read sentence, according to 6 out of 7 algorithmsFollows retext-readability.
| Option | Type | Default | Description |
|---|---|---|---|
age | number | null | null | The age of the target audience: 16 by default. |
threshold | number | null | null | The share of algorithms that must find a sentence too hard: 4/7 by default. |
minWords | number | null | null | The fewest words a sentence needs to be checked: 5 by default. |
nl.repeatedWords
Warns about a word written twice in a row.
use textlane::{Processor, nl};
let output = Processor::new()
.with(nl::Parse::default())
.with(nl::RepeatedWords)
.with(nl::Stringify)
.freeze()?
.process("It is the the best.")?;
output.file.messages[0].reason
// Unexpected repeated `the`, remove one occurrenceFollows retext-repeated-words.
No options.
nl.sentenceSpacing
Warns about the spaces between sentences: one by default.
use textlane::{Processor, nl};
let output = Processor::new()
.with(nl::Parse::default())
.with(nl::SentenceSpacing::default())
.with(nl::Stringify)
.freeze()?
.process("One. Two.")?;
output.file.messages[0].reason
// Unexpected 2 spaces between sentence, expected 1 spaceFollows retext-sentence-spacing.
| Option | Type | Default | Description |
|---|---|---|---|
preferred | Spacing | null | The spacing expected between sentences: 1 or "space" (the default), 2 or "double-space", 0 or "newline". |
Spacing
A spacing between sentences, as a count of spaces or by name.
Takes number | string.
nl.stringify
Serializes nlcst back into text.
use textlane::{Processor, nl};
let output = Processor::new()
.with(nl::Parse::default())
.with(nl::Stringify)
.freeze()?
.process("Same text out.")?;
output.value
// Same text out.Follows retext-stringify.
No options.
nl.smartypants
Turns straight quotes, dashes, dots and backticks into their typographic forms.
use textlane::{Processor, nl};
let output = Processor::new()
.with(nl::Parse::default())
.with(nl::Smartypants::default())
.with(nl::Stringify)
.freeze()?
.process("\"It's\" -- fine...")?;
output.value
// “It’s” — fine…Follows retext-smartypants.
| Option | Type | Default | Description |
|---|---|---|---|
backticks | Backticks | Turn double backticks and double straight single quotes into double quotes; all turns single ones into single quotes too, and needs quotes: false. | |
closingQuotes | QuoteCharacters | null | The closing quotes to use: ” and ’ by default. | |
dashes | Dashes | Turn two dashes into an em dash; oldschool and inverted treat three too. | |
ellipses | Ellipses | Turn three dots into an ellipsis, with spaces between them or without. | |
openingQuotes | QuoteCharacters | null | The opening quotes to use: “ and ‘ by default. | |
quotes | boolean | null | true | Turn straight quotes into smart ones. |
Backticks
Takes boolean | "all".
QuoteCharacters
The quote characters to use for double and single quotes.
| Option | Type | Default | Description |
|---|---|---|---|
double | string | ||
single | string |
Dashes
Takes boolean | "oldschool" | "inverted".
Ellipses
Takes boolean | "spaced" | "unspaced".
nl.quotes
Warns about quotes and apostrophes that are not the preferred kind, smart by default.
use textlane::{Processor, nl};
let output = Processor::new()
.with(nl::Parse::default())
.with(nl::Quotes::default())
.with(nl::Stringify)
.freeze()?
.process("He said \"hi\".")?;
output.file.messages[0].reason
// Unexpected straight quote `"`, expected `“`Follows retext-quotes.
| Option | Type | Default | Description |
|---|---|---|---|
preferred | QuoteStyle | null | The style of quotes and apostrophes to prefer: smart by default. | |
smart | string[] | null | null | Smart quotes by nesting level, each one character or an opening and closing pair: ["“”", "‘’"] by default. |
straight | string[] | null | null | Straight quotes by nesting level: ["\"", "'"] by default. |
QuoteStyle
A style of quotes: straight (") or smart (“”).
Takes "smart" | "straight".
nl.contractions
Warns about missing or misplaced apostrophes in contractions.
use textlane::{Processor, nl};
let output = Processor::new()
.with(nl::Parse::default())
.with(nl::Contractions::default())
.with(nl::Stringify)
.freeze()?
.process("Dont do that.")?;
output.file.messages[0].reason
// Unexpected missing apostrophe in `Dont`, expected `Don’t`Follows retext-contractions.
| Option | Type | Default | Description |
|---|---|---|---|
allowLiterals | boolean | null | false | Also check contractions written as literals, such as “hasnt”. |
straight | boolean | null | false | Expect straight apostrophes (') instead of smart ones (’). |
nl.indefiniteArticle
Warns about a and an used before the wrong sound.
use textlane::{Processor, nl};
let output = Processor::new()
.with(nl::Parse::default())
.with(nl::IndefiniteArticle)
.with(nl::Stringify)
.freeze()?
.process("It is a apple.")?;
output.file.messages[0].reason
// Unexpected article `a` before `apple`, expected `an`Follows retext-indefinite-article.
No options.
Created with ❤ and Livemark