Repository navigation
fix(markdown): 修复移动端行内 LaTeX 结构、下标与转义定界符 - #7560
dreamfarer-space wants to merge 2 commits into
Conversation
Signed-off-by: 择梦舟 <158067205+dreamfarer-space@users.noreply.github.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
@codex review |
[Medium impact] The PR affects math text in mobile outputs and shared Markdown parsing. 暂不建议合并;应先修复异常公式导致的渲染阻塞和根号公式显示错误。 FindingsFix with agent prompt### Issue 1
packages/maker-shared/src/mathMarkdown.ts:438-441
缺少分母的嵌套分式会让解析器反复处理同一段文本。例如,将 `"\\frac{".repeat(30) + "x" + "}".repeat(30)` 放进 `$...$`:`readArg` 先递归转换整个分子,随后发现没有分母,`readCommand` 却只返回命令名的结束位置。外层循环于是再次进入已经解析过的分子,工作量随层数指数增长。
32 层限制只限制调用深度,无法阻止重复计算。移动端在渲染正文时同步调用此函数,会因此卡住。请先确认两个参数的范围,再递归转换,并补充缺少分母的嵌套回归测试。
**How this was verified:** 消息中的 `$...$` 内容会直接进入同步转换函数,而缺少分母时的返回位置会让循环重新解析刚刚递归处理过的分子。
### Issue 2
packages/maker-shared/src/mathMarkdown.ts:448
`operand` 用转换后的字符数决定是否加括号,却返回原始命令文本。例如,`\sqrt{\alpha}x` 会先变成 `√\alpha`,再拼接 `x`;最后 `flattenLatex` 将 `\alphax` 当作未知命令,输出 `√alphax`,而不是保留 `α` 和后面的乘数 `x`。旧实现会保留括号边界,不会发生这种合并。
请在拼接结构转换结果时保留命令边界,并补充根号内为符号命令、根号后接字母的测试。
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
|
| const first = readArg(end, nesting); | ||
| if (!first) return raw; | ||
| const second = fraction ? readArg(first.end, nesting) : null; | ||
| if (fraction && !second) return raw; |
There was a problem hiding this comment.
缺少分母的嵌套分式会让解析器反复处理同一段文本。例如,将 "\\frac{".repeat(30) + "x" + "}".repeat(30) 放进 $...$:readArg 先递归转换整个分子,随后发现没有分母,readCommand 却只返回命令名的结束位置。外层循环于是再次进入已经解析过的分子,工作量随层数指数增长。
32 层限制只限制调用深度,无法阻止重复计算。移动端在渲染正文时同步调用此函数,会因此卡住。请先确认两个参数的范围,再递归转换,并补充缺少分母的嵌套回归测试。
How this was verified: 消息中的 $...$ 内容会直接进入同步转换函数,而缺少分母时的返回位置会让循环重新解析刚刚递归处理过的分子。
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/maker-shared/src/mathMarkdown.ts
Line: 438-441
Comment:
**异常分式卡住聊天**
缺少分母的嵌套分式会让解析器反复处理同一段文本。例如,将 `"\\frac{".repeat(30) + "x" + "}".repeat(30)` 放进 `$...$`:`readArg` 先递归转换整个分子,随后发现没有分母,`readCommand` 却只返回命令名的结束位置。外层循环于是再次进入已经解析过的分子,工作量随层数指数增长。
32 层限制只限制调用深度,无法阻止重复计算。移动端在渲染正文时同步调用此函数,会因此卡住。请先确认两个参数的范围,再递归转换,并补充缺少分母的嵌套回归测试。
**How this was verified:** 消息中的 `$...$` 内容会直接进入同步转换函数,而缺少分母时的返回位置会让循环重新解析刚刚递归处理过的分子。
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.| text = `${operand(body)}/${operand(second.text)}`; | ||
| } else if (name === 'sqrt') { | ||
| const root = rootIndex === undefined ? '√' : rootIndex === '3' ? '∛' : rootIndex === '4' ? '∜' : `√[${rootIndex}]`; | ||
| text = `${root}${operand(body)}`; |
There was a problem hiding this comment.
operand 用转换后的字符数决定是否加括号,却返回原始命令文本。例如,\sqrt{\alpha}x 会先变成 √\alpha,再拼接 x;最后 flattenLatex 将 \alphax 当作未知命令,输出 √alphax,而不是保留 α 和后面的乘数 x。旧实现会保留括号边界,不会发生这种合并。
请在拼接结构转换结果时保留命令边界,并补充根号内为符号命令、根号后接字母的测试。
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/maker-shared/src/mathMarkdown.ts
Line: 448
Comment:
**根号后的字母吞掉符号**
`operand` 用转换后的字符数决定是否加括号,却返回原始命令文本。例如,`\sqrt{\alpha}x` 会先变成 `√\alpha`,再拼接 `x`;最后 `flattenLatex` 将 `\alphax` 当作未知命令,输出 `√alphax`,而不是保留 `α` 和后面的乘数 `x`。旧实现会保留括号边界,不会发生这种合并。
请在拼接结构转换结果时保留命令边界,并补充根号内为符号命令、根号后接字母的测试。
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Signed-off-by: 择梦舟 <158067205+dreamfarer-space@users.noreply.github.com>
|
@codex review |
|
Codex Review: Something went wrong. Try again later by commenting “@codex review”. ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
这次改了什么
摘要
修复移动端聊天行内 LaTeX 在原生 Text 的 Unicode 近似转换中丢失数学结构的问题。用户提供的截图里,块级公式正常,但
\dot{c}显示为dotc,\frac{2\sqrt{3}}{3}\pi显示为frac2√33π,t_s未转换为下标。根因不是 KaTeX 资源失效:块级公式走 WebView KaTeX,行内公式由
MessageRenderer.renderInline调用共享的latexToUnicodeApproximation。原转换器用不支持嵌套花括号的正则解析分数,随后删除未知命令的反斜杠和分组花括号;重音命令和部分已有 Unicode 下标字符也未覆盖。改为有深度上限的结构读取,先处理分数、根号和重音,再做符号与上下标近似。另修复共享定界符归一化把双反斜杠字面量误当成公式定界符的问题。
变更类型
fix缺陷修复范围
\dot{c}→ċ,支持点、双点、帽、横线、向量和波浪重音;多字符重音保留可读的命令式近似。((2√3)/3)π。3/(ξωₙ)、1/(a/b)、(a/b)²、(a/b)c。ₛ等已有 Unicode 下标字符,t_s→tₛ。\\(literal\\)等字面量不再被归一化为公式;查找闭合定界符时跳过转义反斜杠。UI 变化
以下三张均为用户提供的修复前 iOS 截图,不是修复后或本轮实机验收证据。经用户明确授权随 PR 公开。
docs/design-rules/DESIGN.md§1 内容可读性、§15.13 移动端跨主题要求。仅修复正文中的数学文本,不新增颜色、字体、控件或布局;沿用现有 Light/Dark 样式。两种模式及 iOS/Android 的真实字形/组合重音效果本轮均未实机目检。怎么验证的
自动验证
基线:
0694ed7e001e027a031ffed21a088bd1975132de;当前 head:7f4553c54db8f11843b2ae31a2f31ef5e93a0a61。完整 tree SHA 为995f918d66b70cf5b90ca31fd8efad5f0dfd76ed,与本地已验证提交f3a44c6b完全一致;远端仅作者元数据/DCO 对齐为提交账号。初版回归验证:在独立临时目录将当时的 57 项测试指向基线原版实现,其中 20 项失败;初版补丁 57 项全部通过。本轮新增审核回归后,当前完整文件 60/60 通过。未修改生产源码来运行基线,也未弱化原有断言。
测试价值 —
packages/maker-shared/src/__tests__/mathMarkdown.test.ts:latexToUnicodeApproximation与normalizeMathDelimiters,检查移动端展示文本和传给 Markdown parser 的实际字符串。t_s,以及此次同链路审计确认的分母/后缀作用范围、根次数与转义问题。\dot c、\frac{2\sqrt{3}}{3}、t_s、\frac{a}{b}^2、\sqrt[3]{x}、\{x\}和\\(x\\),按不同可观察分支使用表驱动表达。环境说明:
pnpm install被本环境的 npm 网络访问策略中断,offline 重试也缺少 tarball。为运行共享包测试,仅在未跟踪的本地依赖目录补回了锁定版本 estree-walker 3.0.3 的官方 tag 源码;未改 package.json、锁文件或提交依赖目录。以上共享包测试和类型检查实际通过。手工验证
未执行真实 Cindy App 或 iOS/Android 设备验收。已对照用户原始截图和生产调用链核实输入与输出;这不等于实机验证。
未执行的验证
messageMarkdown.test.ts/mathWebViewHtml.test.ts已尝试,但收集阶段因依赖安装不完整(最终缺react-i18next)失败,没有测试用例执行;不计入通过项。__DEV__身份链,因此不声称任何截图来自当前分支 App。风险
风险分类
影响与回滚
提交前检查
审核后续修复(
7f4553c)已核实 Greptile 的两条 P1,均为有效问题并在同一 PR 修复:
"\\frac{".repeat(30) + "x" + "}".repeat(30)在独立 Node 复现中超过 3 秒未返回而被终止;修复后约 1.86ms 返回可读文本。该时间是本机单次复现实测,不是通用性能承诺。单测保留相同输入并断言结果,不新增真实等待或严格计时测试。\\sqrt{\\alpha}x→√αx,带根次数的同类输入也保留希腊符号。两条新增显示用例指向修复前实现时均失败(√alphax),修复后通过。测试价值补充:仍直接调用同一生产转换入口,覆盖先前未包含的“嵌套不完整 frac”与“控制词操作数后接字母”两个分支;新增 3 条 unit 用例,沿用既有文件,无新依赖/子进程/文件 I/O。隔离超时复现仅用于本轮人工验证,不进入默认 unit。
最新验证:60/60 数学回归、104 文件 / 1961 项共享包单测、共享包 TypeScript、test-hygiene 与差异检查均通过。保留三张用户原图;iOS/Android 实机、Mobile 完整套件及远端 CI 的待验证边界不变。