资讯动态

一个 x² 难倒了三个终端:数学公式的显示、输入和判分

发布时间:2026/10/26 10:24:42 来源:尧图企业网站定制
一道填空题标准答案是k^2。学生在手机上写了k²系统判 0 分。学生没写错系统也没有 bug至少每一行代码单独看都没有。题库里的答案是 LaTeX 写法学生手机键盘上能打出的是 Unicode 上标。比较之前系统会先做一次 Unicode 规范化NFKC它把k²折成了k2。于是k^2对k2不相等。做学习类产品数学公式是绕不开的。它在三个地方都会出问题显示学生看不看得懂题输入学生能不能把答案写出来判分写对了能不能被认出来。拾阶有网页、App、微信小程序三个终端同一个公式在这三处各有各的坑。这篇把我们的解法摊开讲。一、显示同一个 LaTeX三个终端三种画法我们的内容约定很简单公式一律写 LaTeX$...$排版一律 Markdown。约定只有一份三个终端各自想办法把它画出来。网页最省事KaTeX 直接排。App是 React Native没有现成的公式排版。摆在面前的路有两条自己写一个 LaTeX 排版器或者把 KaTeX 放进 WebView。自己写排版器的问题不是做不出来而是做不全。分式、根号、上下标好办矩阵、化学方程式箭头上的条件、多行对齐不好办。做一半的排版器会让一部分题目显示成乱码这比统一用 WebView 慢一点糟得多。所以 App 的讲解、题干、解析这类长文本走 WebView KaTeX列表里的短文本不值得为它开一个 WebView转成近似的纯文本显示。KaTeX 加载失败也不白屏公式原样显示成文本简单的式子照样读得懂。小程序最麻烦。小程序的富文本组件不认 SVG 标签把 KaTeX 的输出放进去根号和伸缩括号会消失在小程序里跑 MathJax又会撑爆 2MB 的主包。最后的做法是让服务端画。网页那边加了一个接口用 MathJax 把单个公式渲染成自包含的 SVG长缓存小程序把公式当图片插进富文本。图片在富文本里必须给出尺寸才显示所以还有第二个接口一页里的所有公式一次性批量询问宽、高和基线位置。MathJax 给的尺寸单位是 ex换算成 em 再插进去公式图片就和周围的文字一样大、基线对齐。这里有个容易忽略的体验细节尺寸回来之前显示什么最初显示的是 LaTeX 源码。网慢的时候学生盯着题干上的「在$-2$$3$$0$中」看好几秒像一串乱码。后来改成先显示纯文本近似-2、x²、1/2尺寸回来再无缝换成公式图片。二、一个专门的坑框起来的一整句中文讲解里有一种写法很常见$$\boxed{两条直线相交所成的四个角中有一个是直角就说这两条直线互相垂直}$$用公式框标出重点排出来是一个带边框的结论。已发布的知识点里九成都用到了它。问题是 KaTeX 把它当成一整块公式不会换行。网页上屏幕够宽没事App 里手机屏宽放不下右半句直接被切掉小程序里它是一张公式图片缩到屏幕宽度以后字小得看不清。这个问题单看代码是发现不了的渲染没报错数据也没问题只有在真机屏幕上看才知道右半句没了。解法是承认它的本质这种框里装的是一句话不是公式。所以当整条公式只有一个\boxed、里面又有中文时改写成一个能换行的文字框中文照常排版夹在中间的公式片段比如180^{\circ}仍按行内公式排。纯公式的框\boxed{140^{\circ}}不动。三、列表里的公式只求认得出错题本、成绩页的折叠卡片只显示两行题干。最早的做法是把公式一律换成「…」结果数学题成了这样若关于 … 的方程 … 的两根均为正数则 … 的取值范围是一屏全是省略号学生认不出是哪道题。每题都开一个公式渲染又太重。所以写了一个转换函数把公式转成能读的纯文本x^2-3x20→x²-3x20\frac{1}{2}→1/2\angle→∠。上下标只在每个字符都有对应的上标字形时才转否则写成^(…)分子分母不止一个字的时候自动加括号。只求认得出不求排版精确点开以后仍是完整的公式渲染。这个函数 App 和小程序是同一份文件头写着「改一处要同步另一处」。四、输入一排符号键显示解决了接下来是学生怎么写答案。手机键盘打不出 x²、√、π、≥。学生只好写「x的平方」「根号3」在手机浏览器上还得切三四次键盘找符号。我们的办法很朴素在正在输入的框下面放一排符号键。// 上下标单独一个字形太小看不清键面画成 x²、x₁插进去的只有上标本身exportconstMATH_KEYS[...[²,³,^,₁,₂].map((c)({label:c^?xⁿ:x${c},insert:c})),...[√,π,/,(,),°,±,×,÷,≥,≤,≠,∠,△,⊥,∥,∞,≈,∈].map((c)({label:c,insert:c})),];做起来有几个细节每一个都是踩过才知道的插进去的是 Unicode 字形不是 LaTeX。学生看到的就是x²1而不是x^{2}1。按下按键时不能让输入框失焦。失焦了符号键就收起来点击落空。所以按键在pointerdown时阻止默认行为。光标要放回符号后面。受控输入框重新渲染后光标会跳到末尾要等这一帧画完再把光标放回去。否则学生在中间插一个 √光标就飞到最后了。只在需要的时候出现。题干里有公式或数字才给符号键语文、英语的填空用不上平白占一行。三个终端用的是同一套键位。同一道题不能 App 上能打 x²、小程序上打不了。五、判分把不同写法折成同一种回到开头那道题。学生写k²题库存k^2。以前全靠出题时把每种写法都列进答案漏列一种学生写对了也判错。题库里有上万道填空题指望每道都列全是不现实的。现在的做法是两边都折成同一种线性写法再比。x² / x^2 / x^{2} → x^2 \sqrt{19} / √19 / √(19) → √19 \dfrac{a^2}{4b^4} / a²/(4b⁴) → a^2/(4b^4) 180^\circ / 180° → 180°有一个顺序问题必须注意上下标字形要在 Unicode 规范化之前处理。NFKC 会把²折成普通的2等它折完再想转成^2已经来不及了。开头那个 0 分就是这么来的。另外两条原则只会更宽不会更严。原来的比较照旧新规则只在原来判错时再补一次。原来判对的现在一定还判对。能按数值比的就按数值比。0.5、1/2、50%本来就按数值比-\dfrac37原本解析不成数字折成-3/7以后也能参与数值比较了。规则上线前我们用本地题库里 1.4 万道填空题、1 万种不同的答案写法跑了一遍。新规则一共把 464 组写法合并成了相同逐组看过全部是同一个式子的不同写法没有把两个不同的答案判成相同。最后这一步最不能省。判分规则放宽是有风险的放得太宽错的答案也会被判对。「只会更宽」保证了不会冤枉学生而那 464 组的人工核对保证了不会放过错误。如果只带走几句公式内容只存一种格式显示交给每个终端各自解决不要为某个终端改内容。画不了就让服务端画。小程序的限制很硬绕不过去就换个地方做。加载中的样子也是体验。先显示纯文本近似比显示源码好得多。框里装的是什么决定它该怎么排。一句话就按一句话排能换行。判分放宽要有数据兜底。改之前拿全量题库跑一遍逐组看合并结果。附这些在产品里长什么样网页版答题页填空题下面那排符号键。图里的-1/8是用「/」键输入的。拾阶网页版填空题的数学符号键小程序里的知识点讲解公式是服务端画好的图片「对顶角相等」那几个带边框的结论就是改写后能换行的文字框。拾阶小程序知识点讲解里的公式与重点框App 的错题本折叠卡片里的题干是公式转出来的纯文本x²x10、x²-√5x10一眼认得出是哪道题。拾阶 App错题本的题干预览下一篇讲我们怎么发现这类「代码没错、页面不对」的问题让 AI 当测试员对着正式环境把 App 和小程序的每个页面点一遍。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑