Skip to main content

Multilingual readability library for Python — 86 languages, 17 formulas, TeX-based syllable counting via Frank M. Liang algorithm.

Project description

ReadSightPy — Multilingual Readability Engine for Python

CI Python License Tests Mypy Ruff Languages Formulas

ReadSightPy measures text readability across 86 languages using 17 readability formulas with language-specific coefficients. Syllable counting is powered by the Frank M. Liang (TeX) hyphenation algorithm — the same algorithm used by TeX for decades. All with zero heavy dependencies.

This is a Python port of ReadSight (PHP).

Table of Contents

Installation

pip install readsight

Requirements:

  • Python >= 3.10
  • regex (for Unicode regex \p{L} support)
  • platformdirs (for cache directory)

No other runtime dependencies.

Quick Start

from readsight import ReadSight

rs = ReadSight("en-us")

# Syllable counting
rs.syllable_count("banana")         # 3
rs.split_syllables("hyphenation")   # ['hy', 'phen', 'a', 'tion']

# Text analysis
stats = rs.analyze("The quick brown fox jumps over the lazy dog.")
print(f"Words: {stats.word_count}, Syllables: {stats.syllable_count}")

# Readability formulas
fre = rs.flesch_reading_ease(text)
print(f"Flesch Reading Ease: {fre.score} - {fre.interpretation}")

fog = rs.gunning_fog(text)
print(f"Gunning Fog: {fre.score} (grade {fre.grade_level})")

lix = rs.lix(text)
print(f"LIX: {fre.score} - {fre.interpretation}")

Demo

Run the interactive demo to see ReadSightPy in action:

python examples/demo.py

This analyzes built-in sample text and outputs:

  • Syllable breakdown with hyphenation points for common words
  • Text statistics — letters, words, sentences, syllables, histogram
  • All applicable readability formulas with scores and interpretations

Compare the same text across 6 languages:

# Built into demo.py — runs multilingual comparison automatically
python examples/demo.py

Supported Languages

86 languages across 19 writing systems: Latin, Cyrillic, Arabic, Hebrew, Devanagari, Bengali, Tamil, Thai, Greek, Armenian, Georgian, Gujarati, Gurmukhi, Kannada, Malayalam, Odia, Telugu, Ethiopic, Coptic.

rs = ReadSight("ru")        # Russian
rs = ReadSight("de-1996")   # German (1996 reform)
rs = ReadSight("es")        # Spanish
rs = ReadSight("th")        # Thai

# List all supported languages
langs = ReadSight.get_supported_languages()
# ['af', 'ar', 'as', 'be', 'bg', 'bn', 'ca', 'cop', 'cs', 'cu', 'cy', 'da',
#  'de-1901', 'de-1996', 'de-ch-1901', 'el-monoton', 'el-polyton', 'en-gb',
#  'en-us', 'eo', 'es', 'et', 'eu', 'fa', 'fi', 'fi-x-school', 'fr', 'fur',
#  'ga', 'gl', 'grc', 'gu', 'he', 'hi', 'hr', 'hsb', 'hu', 'hy', 'ia', 'id',
#  'is', 'it', 'ka', 'kk', 'kmr', 'kn', 'la', 'la-x-classic', 'la-x-liturgic',
#  'lt', 'lv', 'mk', 'ml', 'mn-cyrl', 'mn-cyrl-x-lmc', 'mr', 'mul-ethi', 'nb',
#  'nl', 'nn', 'oc', 'or', 'pa', 'pi', 'pl', 'pms', 'pt', 'rm', 'ro', 'ru',
#  'sa', 'sh-cyrl', 'sh-latn', 'sk', 'sl', 'sq', 'sr-cyrl', 'sv', 'ta', 'te',
#  'th', 'tk', 'tr', 'uk', 'vi', 'zh-latn-pinyin']

Readability Formulas

Universal (all 86 languages)

Formula Method Type Score Range
Gunning Fog gunning_fog() Syllable-based 0–20+
SMOG Index smog_index() Syllable-based 3–18+
Coleman-Liau coleman_liau() Letter-based 0–18+
ARI automated_readability_index() Letter-based 0–18+
LIX lix() Letter-based 20–60+

Language-Specific

Language Formulas
English (en-us, en-gb) Flesch Reading Ease, FK Grade Level, Dale-Chall*, Spache*
German (de-*) Flesch Reading Ease (Amstad), FKGL, Wiener Sachtextformel (4 variants)
Russian (ru) Flesch Reading Ease (Oborneva), FKGL
Spanish (es) Flesch Reading Ease, Fernandez-Huerta, Szigriszt-Pazos, Gutierrez-Polini, Crawford
Italian (it) Flesch Reading Ease, Gulpease
French (fr) Flesch Reading Ease (Kandel-Moles)
Dutch (nl) Flesch Reading Ease (Douma)
Portuguese (pt) Flesch Reading Ease (Martins)
Turkish (tr) Flesch Reading Ease (Ateşman)
Polish (pl) FOG-PL
Arabic (ar) OSMAN

*Note: Dale-Chall and Spache formulas use a syllable-based heuristic to estimate difficult words (1-syllable ≈ easy). This is a simplified estimation, not based on the original Dale/Spache word lists.

Generic dispatching:

result = rs.score("gunning_fog", text)
result = rs.score("wiener_sachtextformel", text)

FormulaResult

result.score           # float — raw formula score
result.grade_level     # float | None — normalized grade level (FKGL, GF, SMOG, CL, ARI)
result.interpretation  # str — qualitative interpretation ("Easy", "Hard")
result.formula_name    # str — formula key
result.language_code   # str — language code used
result.inputs          # dict[str, float | int] — intermediate values for debugging

API Reference

Text Analysis Methods

rs.syllable_count(word: str) -> int
rs.split_syllables(word: str) -> list[str]
rs.split_word(word: str) -> list[str]
rs.word_count(text: str) -> int
rs.sentence_count(text: str) -> int
rs.letter_count(text: str) -> int
rs.total_syllables(text: str) -> int
rs.average_syllables_per_word(text: str) -> float
rs.average_words_per_sentence(text: str) -> float
rs.polysyllable_count(text: str, count_proper_nouns: bool = True) -> int
rs.words_with_more_than_n_syllables(text: str, n: int, count_proper_nouns: bool = True) -> int
rs.histogram_syllables(text: str) -> dict[int, int]
rs.analyze(text: str) -> TextStatistics

Formula Methods

rs.flesch_reading_ease(text: str) -> FormulaResult
rs.flesch_kincaid_grade_level(text: str) -> FormulaResult
rs.gunning_fog(text: str) -> FormulaResult
rs.smog_index(text: str) -> FormulaResult
rs.coleman_liau(text: str) -> FormulaResult
rs.automated_readability_index(text: str) -> FormulaResult
rs.lix(text: str) -> FormulaResult
rs.wiener_sachtextformel(text: str, variant: int = 1) -> FormulaResult
rs.gulpease(text: str) -> FormulaResult
rs.fernandez_huerta(text: str) -> FormulaResult
rs.szigriszt_pazos(text: str) -> FormulaResult
rs.gutierrez_polini(text: str) -> FormulaResult
rs.crawford(text: str) -> FormulaResult
rs.fog_pl(text: str) -> FormulaResult
rs.dale_chall(text: str) -> FormulaResult
rs.spache(text: str) -> FormulaResult
rs.osman(text: str) -> FormulaResult

Performance

Measured on CPython 3.12, Intel Core i7 (limited data — full benchmarks TBD):

Operation Time
Syllable counting (single word) ~0.05 ms
Text analysis (45 words) ~1 ms
Formula calculation (incl. analysis) ~1 ms
Engine init (en-us, cached) ~10 ms
Engine init (de-1996, first load) ~60 ms

Caching: compiled patterns are stored as JSON in the system cache directory (platformdirs.user_cache_dir). First load parses .tex files (native hyph-utf8 format); subsequent loads use the pre-compiled cache.

Custom Configuration

from readsight import ReadSight, Config

# Set default paths (before creating engines)
ReadSight.set_default_config(Config(
    patterns_dir="/custom/patterns",
    languages_dir="/custom/languages",
    cache_dir="/var/cache/readsight",
))

# Or per-instance
rs = ReadSight(
    language="en-us",
    patterns_dir="/custom/patterns",
    cache_dir="/custom/cache",
)

# Add custom hyphenation rules
rs.add_hyphenations({
    "customword": "cus-tom-word",
})

Architecture

ReadSight (facade)
  ├── TextAnalyzer (syllable counting, text metrics)
  │   ├── SyllableCounter (strategy: tex | heuristic | composite)
  │   │   ├── CompositeSyllableCounter (problemWords → heuristic, rest → TeX)
  │   │   ├── HeuristicSyllableCounter (vowel patterns + word list)
  │   │   └── TexSyllableCounter → LiangHyphenator (TeX hyphenation)
  │   ├── LiangHyphenator
  │   │   ├── TexSource (parses .tex from hyph-utf8)
  │   │   ├── PatternsCollection (pattern data)
  │   │   ├── HyphenationExceptionsCollection (word overrides)
  │   │   └── JsonPatternCache (compiled patterns)
  │   └── TextSplitter (word/sentence/letter counting)
  ├── Language (JSON config per language, syllableMode + formulaConfigs)
  └── FormulaRegistry (17 formulas)
      ├── FleschReadingEase (with lang-specific coefficients)
      ├── GunningFog, SMOG, ColemanLiau, ARI, LIX (universal)
      └── WSTF, Gulpease, Fernandez-Huerta, etc. (lang-specific)

Data Sources

  • TeX hyphenation patterns: hyph-utf8 version 2026-02-21 — the canonical TeX hyphenation repository maintained by the TeX Users Group (TUG). 86 .tex pattern files from hyph-utf8 covering 86 language variants. Packaged under each pattern file's original license.
  • FRE coefficients: Amstad (DE), Oborneva (RU), Fernandez-Huerta (ES), Vacca-Franchina (IT), Kandel-Moles (FR), Douma (NL), Martins (PT), Ateşman (TR)
  • WSTF: Bamberger & Vanecek (DE)
  • Gulpease: GULP, La Sapienza University (IT)

Development

pip install -e ".[dev]"    # Install with dev dependencies

pytest                     # Run all tests (133 tests)
pytest --cov=readsight     # With coverage report
mypy src/                  # Static type checking (strict mode)
ruff check src/ tests/     # Lint
ruff format src/ tests/    # Format

Quality Metrics

Metric Value
Tests 133
Mypy Strict mode, 0 errors
Ruff 0 errors
Source files 56
Test files 18
Supported languages 86
Writing systems 19
Readability formulas 17
Runtime dependencies 2 (regex, platformdirs)

License

MIT. Author: Yevhen Leonidov.

TeX pattern files from hyph-utf8 are packaged under their original licenses (see individual file headers).

Project details


Download files

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

Source Distribution

readsight-1.0.0.tar.gz (1.4 MB view details)

Uploaded Source

Built Distribution

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

readsight-1.0.0-py3-none-any.whl (1.4 MB view details)

Uploaded Python 3

File details

Details for the file readsight-1.0.0.tar.gz.

File metadata

  • Download URL: readsight-1.0.0.tar.gz
  • Upload date:
  • Size: 1.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.6

File hashes

Hashes for readsight-1.0.0.tar.gz
Algorithm Hash digest
SHA256 b3ee036b803787df0f64e3d11d6a4aca1b9f05383826e00bbc4cdf5b0fb24ee8
MD5 85264311b901794650b85d35c4f19697
BLAKE2b-256 b8127003b7bc4325698e06fe660a288e3f53ab6ab9dac8c8699a7eb9a7a4b8f4

See more details on using hashes here.

File details

Details for the file readsight-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: readsight-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.6

File hashes

Hashes for readsight-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6e39bd7bc56a7a6a00a9ee35a26bacf68350ff0a733b49c72df862fbf23947c7
MD5 1692b6b28186c9dc2bfb40e3b017a10d
BLAKE2b-256 30fff842fa8166db0eed64977d582dfefb8d161bc6bd2e7a25e069ec7acfaed8

See more details on using hashes here.

Supported by

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