Skip to main content

prosemeter

CI License: MIT Python 3.10–3.13

A ruler for prose texture in Russian, English, Spanish and Italian. Pure stdlib, zero dependencies.

prosemeter measures the surface texture of a text — sentence rhythm, punctuation habits, lexical texture, voice — and hands you a flat dict of numbers. That's the whole product.

It is explicitly not an AI detector and not a quality metric: it describes, it does not pass judgment. Some of the features it reports (filler density, contrast frames, opener repetition) happen to be popular tells of generated or padded prose, but prosemeter attaches no verdict to any value. What counts as "too much" depends on your corpus, your genre and your taste — that's your call, on your data.

Install

pip install prosemeter

Usage

from prosemeter import profile

text = (
    "The kettle clicked off and the kitchen went quiet. I had been rewriting "
    "the same paragraph for an hour, and it still read like a brochure. So I "
    "did what editors do: cut the openers, moved the numbers up front, and "
    "read it aloud. Better. Not perfect, but better."
)

print(profile(text))          # lang="auto" detects English here
print(profile(text, lang="en"))  # or say it explicitly

Real output (English adds five extra keys on top of the common core):

{
  "words": 49, "sentences": 5,
  "mean_sentence_len": 9.8, "cv_sentence_len": 0.69,
  "pct_short": 0.4, "pct_long": 0.0, "staccato_share": 0.4,
  "anaphora_top_share": 0.2,
  "dash_per_100w": 0.0, "guillemet_per_100w": 0.0, "questions_per_sent": 0.0,
  "contrast_frames_per_100w": 0.0,
  "address_per_1k": 0.0, "first_person_per_1k": 40.8,
  "digit_density_per_1k": 0.0,
  "filler_per_100w": 0.0, "nominal_per_100w": 0.0,
  "mean_word_len": 4.14, "ttr": 0.8,
  "syllables_per_word": 1.33, "flesch_reading_ease": 84.7,
  "polysyllable_per_100w": 0.0, "passive_per_100sent": 0.0,
  "ly_adverbs_per_100w": 0.0
}

The public API is three names: profile(text, lang="auto"), SUPPORTED_LANGS (("ru", "en", "es", "it")) and __version__. lang="auto" uses a cheap script/function-word heuristic that is reliable on a paragraph of ordinary prose; pass the language explicitly for short fragments or mixed-language text.

Features

Counts are ints; every other value is a rate, so profiles of texts of different lengths are comparable. Rates are per word (per_100w / per_1k), per sentence (per_sent / per_100sent) or a share in 0..1.

Key What it measures Languages
words Word count. all
sentences Sentence count (regex splitter — see Honest limits). all
mean_sentence_len Mean sentence length in words. all
cv_sentence_len Coefficient of variation (std/mean) of sentence length — the classic dispersion measure used as a rhythm signal. Metronomic prose sits low; prose alternating long and short sentences sits higher. all
pct_short Share of sentences with ≤ 6 words. all
pct_long Share of sentences with ≥ 25 words. all
staccato_share Share of stub sentences (≤ 4 words) — the "Short. Punchy. Fragments." register. all
anaphora_top_share Opener repetition: share of sentences beginning with the single most frequent opening word ("This… This… This…"). English baselines are naturally noisy (articles, pronouns). all
dash_per_100w Em/en dashes (plus the spaced hyphen used as a dash) per 100 words. Dash-for-everything punctuation vs. dash-as-rare-accent. all
guillemet_per_100w Guillemets («») per 100 words — quote/dialogue-heavy vs. plain expository prose. all
questions_per_sent Question marks per sentence — rhetorical-question density. all
contrast_frames_per_100w Density of the "it's not X, it's Y" contrast frame (per-language patterns). One is rhetoric; a high rate is a texture of its own. all
address_per_1k Second-person reader-address words per 1000 words. all
first_person_per_1k First-person words per 1000 words — personal voice. all
digit_density_per_1k Numeric tokens per 1000 words — concreteness of the text's factual grounding. all
filler_per_100w Hits from a per-language filler/officialese phrase list per 100 words ("it is important to note", «важно отметить», "cabe destacar", "va sottolineato"). The Russian list follows the officialese-hunting tradition of Nora Gal. all
nominal_per_100w Abstract nominalizations per 100 words, matched by derivational suffix ("-tion", "-ность", "-ción", "-zione") — Helen Sword's "zombie nouns", Nora Gal's hidden verbs. all
mean_word_len Mean word length in characters. all
ttr Type-token ratio — lexical diversity. Length-sensitive: only compare texts of similar length. all
syllables_per_word Mean syllables per word (heuristic counter). en
flesch_reading_ease Flesch Reading Ease (Rudolf Flesch, 1948): higher = plainer. en
polysyllable_per_100w Words with ≥ 4 syllables per 100 words. en
passive_per_100sent Passive constructions ("to be" + past participle, regex approximation) per 100 sentences — the Orwell / Strunk & White signal. en
ly_adverbs_per_100w -ly adverbs per 100 words — the modifier crutch Stephen King warns about. en

Honest limits

Tokenization is regex-only: sentences split on runs of .!?, words on per-language character classes. Abbreviations, decimals and ellipses can over- or under-split. Over a paragraph or an article these errors average out; do not trust the numbers on a single sentence, and do not compare ttr across texts of very different lengths.

Scope is frozen

This package does one thing: it measures. Bug reports (wrong counts, crash on valid input, broken language detection) are very welcome. Feature requests — new languages, new metrics, verdicts of any kind — are out of scope for now.

Built to power Laspi

Laspi

prosemeter is the measuring half of the writing engine behind Laspi — a marketing employee in a small-business owner's phone. Laspi keeps a living memory of the business (services, prices, cases — every fact confirmed by the owner), writes platform-native posts, images and short vertical videos from it, publishes researched articles, and works on the business's visibility in AI answers: a machine-readable public page that assistants can read and cite, plus regular checks of what ChatGPT, Perplexity and Gemini actually recommend. Content ships in whatever language the business sells in. These metrics are part of how Laspi keeps all that writing sounding human.

The measuring is open source. The writing is the product: start a free trial at laspi.pro — no card needed.

License

MIT © 2026 GradeBuilder S.L.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

prosemeter-0.1.1.tar.gz (81.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

prosemeter-0.1.1-py3-none-any.whl (18.3 kB view details)

Uploaded Python 3

File details

Details for the file prosemeter-0.1.1.tar.gz.

File metadata

  • Download URL: prosemeter-0.1.1.tar.gz
  • Upload date:
  • Size: 81.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for prosemeter-0.1.1.tar.gz
Algorithm Hash digest
SHA256 a1dc50753bd7950b2bb760d5c162b38da52cbd662e5f7a58141201681473099f
MD5 8aff100975c286ba6f6b3a68587141a0
BLAKE2b-256 ca052d66d503ebbfe9859ae5a91f52014315b26017012d8eebfa91028e015c83

See more details on using hashes here.

File details

Details for the file prosemeter-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: prosemeter-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 18.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for prosemeter-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 5400d4a80f8cd61b028203f55f2e64babf3f88909ea12d70fdddb1e941bddf53
MD5 bbff3b31cc45f2db73ebe8da74004fa2
BLAKE2b-256 bae18f978a8bb906779f75c54c252ae0b70c8d0b84d725e1d218843e22630990

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.2

2 files

This release

0.1.1 This release

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page