MathText 补齐高中学段记号:向量箭头、黑板粗体数集、集合/逻辑符号、LaTeX 转义字符
上一轮符号表是按 22k 字符的初中题面频次建的,方法没问题,样本口径偏窄。消费方拿 1324 道题(题干 + 解析,含小学到高中)重做了一遍统计,向量与集合/逻辑记号是高中的主力,初中样本里几乎不出现 —— 于是它们全落在表外,在页面上直接显示成反斜杠原文。
向量箭头 `\vec` / `\overrightarrow` — #83
这两个合计出现 282 次,在整张频次表里排第 3,比已经支持的 \overline(5 次)高 56 倍。此前 DECORATE_COMMANDS 只有 overline 与 hat 两档,取不到值就按字面输出(这一步本身是对的,符合「不认识的记号不吞掉」),只是这两个应该被认识。
新增 arrow 一档。箭头宽度跟随内容:杆是可拉伸的 border,箭头尖是不变形的 SVG,所以 \vec{a} 是短箭头、\overrightarrow{AB} 自动盖住两个字母。TeX 里 \vec 是定宽短箭头、\overrightarrow 才满宽,这个差异被有意抹平 —— 题面场景下两个记号都指向量,宽度不携带信息,而自适应能让 \vec{AB} 这种写法也盖得住。箭头是绝对定位的覆盖层,不撑高行盒,与分数一样不会打乱中文正文的行距。
`\mathbb{}` 映射黑板粗体,不是剥壳 — #84
\mathbb{R} → ℝ,26 个大写字母全覆盖(C/H/N/P/Q/R/Z 用 BMP 的字母式符号,其余落 SMP 数学字母区)。刻意不做成「剥掉外壳留下裸字母」:题面里实数集 ℝ 与变量 R 是两个东西,剥成同一个字母后「定义域为 ℝ」读起来就像「定义域为 R」,而且没人看得出信息已经丢了。参数里认不出的字符逐个原样保留,\mathbb{R+} → ℝ+,不会因为一个 + 就整体放弃。
LaTeX 转义字符 `\{` `\}` `\%` `\$` `\&` `\#` `\_`
集合构建式 \{x \mid x>0\} 里的花括号此前会连着反斜杠一起显示出来 —— \mid 补了表也没用,因为两侧还露着 \{ \}。与符号表不同,转义字符是一个有限闭集合而非长尾,所以整套补齐、不按频次裁。
其余按实测频次补入的命令
\Leftrightarrow ⇔(充要条件,10 次)·\to →(极限,4 次)·\mid ∣(集合构建式,4 次)·\backsim ∽·\varphi φ·\Gamma Γ·\langle ⟨ \rangle ⟩(内积)·\forall ∀·\frown ⌢。
另新增两个取参数的命令:\underline{} 给已有内容加下划线(与填空槽是两回事,后者是空位);\overset{}{} 把上方记号叠在内容上,\overset{\frown}{AB} 即弧 AB —— 这是弧的规范写法,\frown{AB} 在 LaTeX 里是「弧符号紧跟一个分组」,本组件仍按字面渲染成 ⌢{AB},看着不对正是设计意图,好过猜一个上游没表达的意思。
\overset 的上方记号在 mathToPlain 里会被保留(⌢AB),这一点与 \overline / \vec 不同:后者是纯样式线,没有对应字符;前者的上方是有语义的内容,检索时丢掉就少了东西。
报告里有三条不成立,这里说明一下
\Rightarrow(52 次)、\mathbf{}(8 次)、\quad(8 次)在 0.20.0 里就已经支持,逐个实测过。另外报告提到「剥 \mathbf{} 外壳要小心命令边界,\cdot\mathbf{b} 直接剥会变成不存在的 \cdotb」—— 这个坑在本组件里不存在:解析器是从左到右逐命令消费的,不是字符串替换,\cdot 在遇到 \mathbf 之前就已经被消费成 · 了。那是消费方在自己的入库归一化里做字符串替换才会踩的坑。
顺带修掉的一处性能问题:`MathText` 现在是 `memo` 的
MathText 每次渲染都要把整条题面重新 parseMath 一遍,而它此前不是 memo 的 —— 父级任何一次无关更新(题库页面上通常是筛选、分页、选中态这类),一屏几十个实例就会全部重新解析一遍。性能扫描在「父组件更新但 props 不变」这一步实测到 3 次可避免的重渲染,加 memo 后归零。props 全是原始值(children 是字符串),浅比较就够;locale 走 context,语言切换仍会正常更新。同库的 Markdown 早就是这么做的,这次只是把 MathText 补齐。
顺带修掉的一处文档缺陷
MathText 与 QuestionCard 的中文文档把「禁忌 / 坑」章节的标题写成了「坑」,而 conventions 生成器认的是前者。结果是这两个组件的中文注意事项从来没进过 `conventions.json` —— 英文侧一直是全的,中文侧是 0 条,通过 MCP 查约定的中文用户看不到它们。标题已统一(其余 369 个组件本来就是对的)。