Skip to content

feat(text-normalizer): opt-in Arabic search equivalences, named profiles and analyze() - #5

Merged
mohaelmrabet merged 2 commits into
mainfrom
feat/v0.2.0-profiles-semantics
Aug 14, 2026
Merged

feat(text-normalizer): opt-in Arabic search equivalences, named profiles and analyze()#5
mohaelmrabet merged 2 commits into
mainfrom
feat/v0.2.0-profiles-semantics

Conversation

@mohaelmrabet

Copy link
Copy Markdown
Contributor

Summary

Two additions for v0.2.0: the Arabic profile stops imposing one folding convention on every caller, and normalization can now return a result object instead of a bare string.

Arabic: search vs strict

ة → ه is a search-index convention, not a Unicode equivalence — it makes مدرسة and مدرسه collide, which is what a search index wants and what a strict comparison does not. It was hardcoded, so callers who needed the distinction had no way back.

NormalizerProfile::arabic() now takes searchEquivalences (default true, preserving current behaviour). Passing false keeps Ta Marbuta intact; every other mapping — alif variants, yeh, kaf, heh, Arabic-Indic digits — is unconditional, being genuine orthographic variance rather than a search convention. all() forwards the flag.

Named profiles and analyze()

Profiles carry a name (latin, arabic_search, arabic_strict, composed on merge() as arabic_search_latin). TextNormalizer::analyze() returns a NormalizedText value object — original, normalized, profile name, plus isEmpty(), length(), originalLength(), wasModified() and __toString(). normalize() is untouched, so nothing existing has to change.

Test plan

  • composer test — 49 tests, 77 assertions
  • composer analyse — no errors

Note

One commit here restores an assertion in testUnicodeEdgeCases that the working tree had reverted to the version that shipped broken before #4. Unrelated to the v0.2.0 work, but the suite is red without it.

The working tree had reverted testUnicodeEdgeCases to the expectation
that shipped broken on the v0.1.x branch: 'à' kept its accent and the
emoji left no trace. Neither holds. This profile folds 'à' to 'a' like
any other Latin diacritic, and the variation selector trailing the emoji
(U+FE0F) is a combining mark the profile does not claim, so it survives
by the same rule that keeps Arabic harakat.
@mohaelmrabet
mohaelmrabet merged commit c0bcb57 into main Aug 14, 2026
8 checks passed
@mohaelmrabet
mohaelmrabet deleted the feat/v0.2.0-profiles-semantics branch August 14, 2026 18:23
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.

1 participant