Files
MathApp_frontend/src/lib/StepText.tsx

48 lines
2.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { MathText } from './MathText';
import { toFa } from './format';
/**
* متنِ درس که قدم‌هایش در یک پاراگراف پشتِ هم آمده‌اند («۱. مجموعه را بنویسید. ۲. بررسی کنید… ۳. …»):
* ۱۰۴۱ مقدمه‌ی درس در دیتابیس همین شکل‌اند (۱۴۰۵-۰۷) و روی صفحه یک تکه‌ی درهم دیده می‌شدند. این‌جا به
* فهرستِ شماره‌دار تبدیل می‌شوند؛ متنِ بی‌فهرست همان پاراگرافِ قبلی می‌ماند.
*
* فقط دنباله‌ی ۱، ۲، ۳، … با «.» یا «)» و فاصله‌ی بعدش شمرده می‌شود، پس «۳.۵» (اعشار) و «شکلِ ۲. سپس» که
* پیش از آن ۱ ندارد فهرست نمی‌شوند.
*/
const MARKER = /(^|\s)([0-9۰-۹]{1,2})[.)](?=\s)/g;
const num = (d: string) => Number(d.replace(/[۰-۹]/g, (c) => String(c.charCodeAt(0) - 0x06f0)));
export function parseNumbered(text: string): { lead: string; items: string[] } | null {
const marks: { start: number; end: number }[] = [];
for (const m of text.matchAll(MARKER)) {
if (num(m[2]) !== marks.length + 1) continue;
const start = (m.index ?? 0) + m[1].length;
marks.push({ start, end: start + m[2].length + 1 });
}
if (marks.length < 2) return null;
return {
lead: text.slice(0, marks[0].start).trim(),
items: marks.map((mk, i) => text.slice(mk.end, marks[i + 1]?.start ?? text.length).trim()),
};
}
export function StepText({ text, color, className = '' }: { text: string; color: string; className?: string }) {
const list = parseNumbered(text);
if (!list) return <p className={`whitespace-pre-line ${className}`}><MathText text={text} display /></p>;
return (
<div className={className}>
{list.lead && <p className="mb-2 whitespace-pre-line"><MathText text={list.lead} display /></p>}
<ol className="flex flex-col gap-2.5">
{list.items.map((item, i) => (
<li key={i} className="flex gap-2.5">
<span className="mt-0.5 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full text-xs font-black text-white" style={{ backgroundColor: color }}>
{toFa(i + 1)}
</span>
<span className="flex-1 whitespace-pre-line"><MathText text={item} display /></span>
</li>
))}
</ol>
</div>
);
}