✨ feat(detect): add Unicode normalization (UAX #15)#560
Merged
Conversation
Merging this PR will not alter performance
Performance Changes
Comparing Footnotes
|
762518f to
0647ba9
Compare
normalize() and is_normalized() on turbohtml.detect run the four Unicode normalization forms (NFC, NFD, NFKC, NFKD) in C, replacing unicodedata.normalize and unicodedata.is_normalized. The engine decomposes each code point over pinned tables, puts combining marks in canonical order, and recomposes for the C forms. A UAX tox-dev#15 quick check returns already-normalized text as the same object. Hangul (de)composes by arithmetic, with no table rows. tools/generate_normalize.py builds the combining-class, decomposition, and composition tables from the interpreter's own unicodedata, gated on Unicode 16.0.0, so the C output matches it. The NFC/NFKC quick-check property comes from the SHA-pinned DerivedNormalizationProps.txt. Closes tox-dev#543
0647ba9 to
4ff37e8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
turbohtml.detect.normalize(form, text)andturbohtml.detect.is_normalized(form, text)add Unicode normalization (UAX #15) in C, for all four forms: NFC, NFD, NFKC, and NFKD. They replaceunicodedata.normalizeandunicodedata.is_normalized.How it works
The engine decomposes each code point over pinned tables (canonical mappings for the C and D forms, compatibility mappings for the K forms), puts the combining marks in canonical order, then recomposes for the composing forms. A UAX #15 quick check returns already-normalized text as the same object, so the common case skips allocation. Hangul (de)composes by arithmetic, with no table rows.
tools/generate_normalize.pybuilds the combining-class, decomposition, and composition tables from the interpreter's ownunicodedata, gated on Unicode 16.0.0, so the C engine reimplements the dataunicodedatacarries and matches it. The NFC/NFKC quick-check property comes from the SHA-pinnedDerivedNormalizationProps.txt. The module is self-contained and shares no table withurl/idna.c, whose private NFC stays bound to UTS #46.Competitor study
I studied lexbor and utf8proc. From utf8proc I took the decompose, canonical-order, recompose pipeline and the recomposition rule: a canonical length-2 decomposition whose first element is a starter and whose result is not a composition exclusion. From lexbor I took the quick-check fast path, where a code point marked No or Maybe, or a combining mark out of canonical order, drops to the full pipeline and everything else short-circuits. Streaming stays out of scope, which leaves the fast whole-string implementation as the floor.
Also
tools/benchnormalizeop measured against stdlibunicodedata.normalize, plus aunicodedatacompetitor module.Closes #543