math in Persian text: lists read right-to-left, every content text goes through MathText, chat input picks its direction per line

Measured by rendering every question, option and several tutor answers in
Chrome and comparing the on-screen x of each number (2026-09-29):
- A list inside a sentence ('از −۳ به −۲، −۱، ۰ می‌رسیم', 'الگویِ ۲، ۵، ۸')
  was locked as one left-to-right run, so all 482 read backwards. '،' and
  '؛' outside brackets now split the run; sets and coordinates in brackets
  stay one run. Locked runs are isolates (isolate-override), otherwise the
  comma between two of them was still pulled left-to-right.
- Without MathText 704 of 931 minus signs and 602 of 983 expressions were
  misplaced; lesson and island titles, the lesson intro, unit blurb,
  notification bodies and ticket messages now go through it.
- The chat box takes its direction from each line's first letter, so a
  line of pure math stays left-to-right while typing. A line that starts
  in Persian can still show its math reordered inside the box; a textarea
  cannot isolate part of its text. The sent message renders correctly.

Four expressions with Persian words inside them ('f(x) = (ریشه دوم x) + ۵۰')
remain ambiguous.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-29 23:46:18 +03:30
parent db6d694ab0
commit 0e56d9c8aa
9 changed files with 84 additions and 34 deletions

View File

@@ -8,6 +8,7 @@ import { IslandPath } from '@/components/IslandPath';
import { IslandSheet } from '@/components/IslandSheet';
import { EmptyState, ErrorState, LoadingState, ProgressBar, Screen, ScreenHeader } from '@/components/ui';
import { toFa } from '@/lib/format';
import { MathText } from '@/lib/MathText';
/** نقشه‌ی جزیره‌های یک فصل، مثلِ مسیرِ دولینگو. */
export function UnitScreen({ unitId }: { unitId: string }) {
@@ -34,7 +35,7 @@ export function UnitScreen({ unitId }: { unitId: string }) {
<Screen className="bg-page">
<ScreenHeader
title={unit.title}
subtitle={unit.blurb || `${toFa(progress.done)} از ${toFa(progress.total)} جزیره`}
subtitle={unit.blurb ? <MathText text={unit.blurb} /> : `${toFa(progress.done)} از ${toFa(progress.total)} جزیره`}
color={color}
back
mascot={{ char: companion, mood: progress.percent >= 50 ? 'happy' : 'idle', size: 72 }}