parsi-text
v0.2.0
Published
Tiny zero-dependency toolkit for Persian/Farsi text: digit conversion, Arabic→Persian normalization, Persian number formatting, ZWNJ half-space cleanup, and RTL detection.
Maintainers
Readme
parsi-text
Tiny, zero-dependency toolkit for cleaning up Persian/Farsi text. It fixes the small-but-painful bugs that break search, sorting, and equality checks when text mixes Arabic and Persian characters or digit systems.
Works anywhere — Node, browser, Vue/Nuxt, React. Ships ESM + TypeScript types.
Why
ك (Arabic kaf) and ک (Persian keheh) look identical but are different
code points. So do ي and ی. When users paste text from different keyboards,
"کیان" === "كيان" is false, search misses results, and sort order breaks.
parsi-text normalizes these away.
Install
npm install parsi-textUsage
import {
toPersianDigits,
toEnglishDigits,
normalizePersian,
formatPersianNumber,
normalizeZwnj,
isRTL,
} from "parsi-text";
toPersianDigits("2026"); // "۲۰۲۶"
toEnglishDigits("۱۳۹۹"); // "1399"
toEnglishDigits("٤٥٦"); // "456" (Arabic-Indic digits too)
normalizePersian("كيان"); // "کیان" (Arabic kaf/yeh -> Persian)
normalizePersian("مُحَمَّد"); // "محمد" (tashkeel stripped)
formatPersianNumber(1250000); // "۱٬۲۵۰٬۰۰۰" (price display)
formatPersianNumber(12.5); // "۱۲٫۵"
normalizeZwnj("میشود"); // "میشود" (stray half-spaces cleaned)
isRTL("سلام"); // true
isRTL("hello"); // falseMaking text comparable
const a = normalizePersian("كيان"); // typed with an Arabic keyboard
const b = normalizePersian("کیان"); // typed with a Persian keyboard
a === b; // trueAPI
| Function | Description |
| --- | --- |
| toPersianDigits(input) | ASCII digits 0-9 → Persian ۰-۹. Accepts string or number. |
| toEnglishDigits(input) | Persian ۰-۹ and Arabic-Indic ٠-٩ → ASCII 0-9. |
| normalizePersian(input) | Arabic ك/ي/ى → Persian ک/ی; strips tashkeel and tatweel. Leaves digits untouched. |
| formatPersianNumber(input) | Persian digits with Persian thousands (٬) and decimal (٫) separators. Accepts string or number. |
| normalizeZwnj(input) | Collapses repeated ZWNJ (half-space) and drops ZWNJs next to whitespace or at string edges; keeps meaningful ones (میشود). |
| isRTL(input) | true if the string contains any RTL (Arabic/Persian/Hebrew) character. |
All functions are pure, side-effect free, and leave non-target characters unchanged.
License
MIT © Sobhan Azimzadeh
