Releases: PythonShe/Smooth_Reading
Release list
v0.2.0
First stable release. Adds a fifth first-party port for Dart and Flutter and
closes every cross-port divergence found in a full parity audit of the four
existing ports, so all five now produce byte-identical output on an extended
shared fixture suite.
New port: smooth_reading (Dart, pub.dev)
- Pure Dart, zero dependencies, Dart 3.0+ (Flutter 3.10+); runs in Flutter on
every platform, on the server and on the web. tokenizereturns a sealedToken(WordToken/SeparatorToken) that
maps directly onto FlutterTextSpans;toHtml,toMarkdown,
fixationLength, aconstSmoothOptions, andescapeHtml.- A
Segmenterinterface: the defaultSpecSegmenteris the spec's regex
scanner (identical output to the Python port); apps can plug in a platform
ICU break iterator for dictionary-based Chinese, Japanese and Thai breaks
without touching the algorithm. - A Flutter recipe (
docs/recipes/flutter.md):SmoothTextwidget,
selectable variant, and an ICU segmenter over a platform channel.
Parity fixes (algorithm and markup)
- Kotlin: out-of-range
fixation,saccadeandminWordLengthare clamped
instead of throwing, as the spec and every other port already did. - Kotlin: CDATA sections and unterminated comments pass through exactly as in
the TypeScript core; previously the markup could be corrupted. - Swift: the default (no
locale) path now uses the same dictionary-based
word breaker as the explicit-locale path, so Chinese and Japanese are
broken into words by default as in every other port. - Swift: an empty
classNameemitsclass=""like the other ports. - Tag names follow one grammar in every port (the TypeScript rule: a name
runs to whitespace,/or>;</ code>closes;<code / >self-closes). - Regex-fallback tokenizers (TypeScript without
Intl.Segmenter, Python,
Kotlin'sSpecWordSegmenter, Dart) share one run rule: a continuous run of
Han, Kana, Hangul, Thai, Lao, Khmer or Myanmar characters is one word,
split from adjacent text of other scripts (iPhone手机→iPhone+
手机), with combining marks attached. The table of code-point ranges is
now in the spec. - Python: non-integer numeric options are truncated then clamped instead of
raising, matching the TypeScript core.
Fixtures and spec
- New
fixtures/commoncases for option clamping, CDATA, unterminated
comments, the tag-name grammar and script-boundary splitting; every port
passes them. docs/SPEC.mddocuments the known, accepted differences between ICU word
breaking and the regex fallback (3.14,1,000,snake_case,½, Khmer
coeng clusters) and the optional break-iterator hook.
Release engineering
release.ymlpublishessmooth_readingto pub.dev (automated publishing)
and verifies the Dart version;ci.ymltests Dart 3.0.0 and stable.- npm now publishes under the
latestdist-tag; PyPI as a normal release.
v0.1.0-rc.2
Android artifacts move to the Maven group io.github.pythonshe (the Kotlin
package stays io.smoothreading). No algorithm or API changes; npm and PyPI
are republished under the new version for consistency.
v0.1.0-rc.1
Release candidate: the first published build of every port, for integration
testing ahead of 0.1.0. npm publishes under the next dist-tag, PyPI as
0.1.0rc1, Maven Central as 0.1.0-rc.1, SwiftPM from the v0.1.0-rc.1 tag.
Initial release of the guided fixation reading algorithm specified in
docs/SPEC.md, with one first-party port per platform runtime and identical
output across all of them.
Ports
@smooth-reading/core(TypeScript, npm):tokenize,toHtml,
applyToElementwith restore,createTransformStream,fixationLength,
defaults,defaultSkipTagsandstyles.css. Word breaking uses
Intl.Segmenterwhen available and the spec regex otherwise.SmoothReading(Swift Package, iOS 15+/macOS 12+/watchOS 8+/tvOS 15+/
visionOS 1+):NSAttributedStringwith real bold fonts plusUILabel,
UITextView,NSTextFieldandNSTextViewhelpers,AttributedStringfor
SwiftUI,html()andtokenize(). ICU word breaking via
enumerateSubstrings(.byWords)andCFStringTokenizerfor a locale.
Resolvable from the repository root via SwiftPM.io.smoothreading:smooth-reading(Kotlin, minSdk 24): pure-JVM
smooth-reading-coreplusspanned()forTextViewand
annotatedString()for Compose, ICUBreakIteratorword breaking.smooth-reading(Python 3.10+, PyPI):tokenize,to_html,to_markdown
and thesmooth-readingCLI; regex-equivalent tokenizer with no
dependencies.
Algorithm and options
- Fixation strength 1–5 with the ratio table 0.20 / 0.35 / 0.50 / 0.65 / 0.80,
round-half-up, clamped to1…ngrapheme clusters;saccade,
minWordLength,emphasizeNumbers,localeand afixationLength
override. - Out-of-range
fixationandsaccadeare clamped into range in every port. - HTML rendering passes existing tags and character references through,
never emphasises text insidecode,pre,script,style,kbd,
samportextarea, never nests emphasis, and emits neutral markup styled
by CSS custom properties.
Fixtures
- Shared JSON fixtures under
fixtures/common/(basic, edge cases, markup,
options, saccade, scripts) that every port must pass, and
fixtures/segmenter/(CJK, extended CJK, bidi) for ports with an ICU word
breaker. Every port also checks that token texts concatenate back to the
input and that the markup with emphasis tags stripped equals the escaped
input.
Languages
- Chinese, Japanese, Korean, Thai, Vietnamese, Hindi and other Indic
scripts, Arabic, Hebrew, Persian and Urdu are first-class: dictionary-based
word breaks where ICU provides them, grapheme-cluster counting so combining
marks, Indic conjuncts, Thai vowel signs, Hangul jamo and emoji sequences
are never split, and bidi ordering is never altered. Details and known
engine differences are indocs/LANGUAGES.md.
Documentation
docs/SPEC.md(the contract),docs/LANGUAGES.md, copy-paste framework
recipes indocs/recipes/(React, Vue, Svelte, Angular, React Native,
web component, Markdown pipelines) and a Vite playground in
examples/playground/.