Skip to content

[FEATURE] DPL-140: Readability score in RTE overlay#57

Merged
sbuerk merged 1 commit into
mainfrom
readability-calculation
Jul 6, 2026
Merged

[FEATURE] DPL-140: Readability score in RTE overlay#57
sbuerk merged 1 commit into
mainfrom
readability-calculation

Conversation

@sbuerk

@sbuerk sbuerk commented Jul 6, 2026

Copy link
Copy Markdown
Member

Summary

Adds a Flesch reading-ease score to the DeepL Write RTE overlay, giving editors
immediate feedback on how readable a text is before and after rephrasing. The
score is shown as a coloured marker bar above the original and the optimized
text and is recalculated for the optimized text once rephrasing returns.

DeepL Write RTE overlay showing the readability score for the original and the optimized text

Details

  • New backend AJAX endpoint (ReadabilityController) computes the score.
  • Language-specific calculators are collected via the deepl.readability
    tagged iterator and resolved per content language (by primary subtag) by a
    registry. Ships documented Flesch adaptations for German, English, French,
    Italian and Portuguese
    ; further languages can be added by tagging a
    calculator that implements the formula.
  • Unsupported languages or empty texts yield no score instead of failing the
    request.
  • Syllables are counted per language via org_heigl/hyphenator. The dependency
    is pinned to 3.1.0 and additionally bundled as a contrib library
    (contrib/Libraries, providesPackages + class_exists autoload in
    ext_localconf.php) so the extension also works in classic mode / TER
    installations. A checkContribComposer integration check keeps the root and
    contrib constraints and the prefer-lowest lock in sync.
  • Documentation: dedicated Developer › Readability calculators pages plus a
    changelog feature entry.

Readability calculator architecture

  • Endpoint deeplwrite_readabilityReadabilityController computes the score
    for the posted text + content language and returns {score: …}, or
    {score: null} for unsupported languages / empty text (non-fatal, no 500).
  • Calculators live in Classes/Readability/Calculator/ and extend
    AbstractReadabilityCalculator (implementing ReadabilityCalculatorInterface).
    The base class owns calculateReadability() — counting sentences, words
    (unicode \p{L}+, accent-safe) and syllables (via org_heigl/hyphenator,
    per-calculator HYPHENATION_LOCALE) — guards empty input and caps the score at
    100. A concrete calculator only sets LANGUAGE + HYPHENATION_LOCALE and
    implements calculateScore(float $asl, float $asw).
  • Registration is attribute-only: each calculator is tagged
    #[AutoconfigureTag('deepl.readability')], collected via
    #[AutowireIterator('deepl.readability')] into ReadabilityCalculatorRegistry
    (exposed through #[AsAlias]), and resolved per content language by its
    primary subtag (ReadabilityCalculatorFactory → registry
    normalizeLanguage), so en-US/en-GB both map to the English calculator.
  • Shipped formulas (sources in the class docblocks / developer docs), with
    ASL = words / sentences and ASW = syllables / word:
    • English — Flesch: 206.835 - 1.015 * ASL - 84.6 * ASW
    • German — Amstad: 180 - ASL - 58.5 * ASW
    • French — Kandel & Moles: 207 - 1.015 * ASL - 73.6 * ASW
    • Italian — Franchina & Vacca: 206 - ASL - 65 * ASW
    • Portuguese — Martins et al.: 248.835 - 1.015 * ASL - 84.6 * ASW
  • Spanish (es) is DeepL-supported but intentionally not shipped: the
    commonly cited Fernández-Huerta formula carries a documented transcription
    error, so it is described as a contribution candidate rather than guessed.

Quality

CGL, PHPStan (level 8), unit and functional tests all pass for TYPO3 v13 and
v14; the documentation renders cleanly.

Refs: DPL-140
Cherry-picked and adapted from #16.

Show a Flesch reading-ease score for the original and the optimized
text in the DeepL Write RTE overlay, so editors get immediate feedback
on how readable a text is before and after rephrasing.

A new backend AJAX endpoint (ReadabilityController) calculates the
score. Language-specific calculators are collected through the tagged
iterator "deepl.readability" and resolved per content language (by
primary subtag) by a registry. German, English, French, Italian and
Portuguese ship with documented Flesch reading-ease adaptations, and
further languages can be added by tagging a calculator that implements
the language formula. Syllables are counted per language via
org_heigl/hyphenator.

The score is rendered as a coloured marker bar in the overlay and
updated for the optimized text once rephrasing returns. Unsupported
languages or empty texts yield no score instead of failing the request.

The org_heigl/hyphenator dependency is pinned and additionally bundled
as a contrib library (contrib/Libraries, declared via
extra.typo3/cms.Package.providesPackages and autoloaded in classic mode
through ext_localconf.php) so the extension also works in classic mode
and TER installations. A dedicated contrib/composer.json plus a
committed, prefer-lowest contrib/composer.lock pin the library; the
publish workflow installs it into the release artifact and the
checkContribComposer integration check keeps the constraint and lock in
sync.

Cherry-picked from the "reading-ease" feature branch and adapted to the
current core-version-aware architecture: dependency injection via
Symfony attributes (AutoconfigureTag, AutowireIterator, AsAlias) instead
of Services.yaml, and the overlay template applied to both the v13 and
v14 variants.

(cherry picked from commit 5c97129)
@private-packagist

Copy link
Copy Markdown

contrib/composer.lock

Package changes

Package Operation From To About
org_heigl/hyphenator add - v3.1.0 view code - License: MIT License

Settings · Docs · Powered by Private Packagist

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown

Documentation rendering

You can find files attached to the below linked Workflow Run URL (Logs).

Please note that files only stay for around 5 days!

Name Link
Commit 85df0af
Logs https://github.com/web-vision/deepl-write/actions/runs/28803510795
Documentation https://github.com/web-vision/deepl-write/actions/runs/28803510795/artifacts/8113889108

@sbuerk sbuerk merged commit ba01d9c into main Jul 6, 2026
8 checks passed
@sbuerk sbuerk deleted the readability-calculation branch July 6, 2026 15:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants