Wire the product CTA to store-loan-methods calculate so shoppers can pick a term and see the plan, and render English model runs under Montserrat so fanum fonts stop painting 0-9 as Persian digits. Co-authored-by: Cursor <cursoragent@cursor.com>
45 lines
1.7 KiB
TypeScript
45 lines
1.7 KiB
TypeScript
// IRANYekan *fanum* maps Latin digit codepoints (0-9) to Persian glyphs.
|
|
// Montserrat (`.en`) keeps real Latin digits — so any Latin-letter run that
|
|
// also carries model numbers (HP R5, 8GB, EF2126WM…) must render under `.en`.
|
|
// Pure digit runs (e.g. "13" inside «آیفون 13 پرو») stay on the FA font and
|
|
// correctly show as Persian digits.
|
|
const EN_RUN = /[A-Za-z0-9][A-Za-z0-9\s\-_|./+#%]*/g;
|
|
|
|
export type TextSegment = { type: "fa" | "en"; text: string };
|
|
|
|
export function splitMixedText(text: string): TextSegment[] {
|
|
const segments: TextSegment[] = [];
|
|
let cursor = 0;
|
|
let match: RegExpExecArray | null;
|
|
const re = new RegExp(EN_RUN.source, "g");
|
|
|
|
while ((match = re.exec(text)) !== null) {
|
|
let start = match.index;
|
|
let end = start + match[0].length;
|
|
while (end > start && /\s/.test(text[end - 1]!)) end--;
|
|
const chunk = text.slice(start, end);
|
|
if (!/[A-Za-z]/.test(chunk)) continue;
|
|
|
|
if (start > cursor) segments.push({ type: "fa", text: text.slice(cursor, start) });
|
|
segments.push({ type: "en", text: chunk });
|
|
cursor = end;
|
|
}
|
|
|
|
if (cursor < text.length) segments.push({ type: "fa", text: text.slice(cursor) });
|
|
return segments;
|
|
}
|
|
|
|
/** Wrap Latin runs in a plain string as `.en` spans (text is assumed already HTML-safe). */
|
|
export function wrapLatinRuns(text: string): string {
|
|
return splitMixedText(text)
|
|
.map((seg) =>
|
|
seg.type === "en" ? `<span class="en" dir="ltr" lang="en">${seg.text}</span>` : seg.text,
|
|
)
|
|
.join("");
|
|
}
|
|
|
|
/** Walk HTML text nodes (content between tags) and wrap Latin runs. */
|
|
export function wrapLatinInHtml(html: string): string {
|
|
return html.replace(/(^|>)([^<]+)/g, (_, prefix: string, text: string) => prefix + wrapLatinRuns(text));
|
|
}
|