mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
fix(tui): fall back to raw LaTeX when display math is wider than the content width (#11487)
Display math (`$$…$$`, `\[…\]`) renders as several 2D rows: numerator,
fraction bar and denominator are separate lines. When the layout was
wider than the Markdown content width, `render()` wrapped each row with
`wrapTextWithAnsi` on its own. Only the overflowing row broke, so the
rows below moved down and the equation no longer lined up. For example,
`dx` landed between the fraction bar and the denominators.
The `latexBlock` case in `Markdown.renderToken()` now checks the
rendered layout against the available width. If any row is too wide, it
uses the raw LaTeX source, the same fallback already used when parsing
fails. The raw source then wraps like normal text. Layouts that fit
render exactly as before.
**Testing**
- Added a regression test in `packages/tui/test/markdown.test.ts` using
the equation from the issue. At width 40 it renders the 2D layout
unchanged. At width 30 it falls back to the raw `\[ … \]` source, with
no fraction bars and no line wider than 30. The test fails without the
fix and passes with it.
- `node --test test/markdown.test.ts`: 93 pass. `node --test
test/latex.test.ts`: 111 pass.
- `npm run check` reports no errors in the touched files. The only
errors are 6 type errors in `packages/ai/test`, caused by stale
generated model data, and they are the same on `main` without this
change.
- Reproduction at width 30, before the fix:
```
∂² u ∂² u n 1 1
──── + ──── = ∑ ── +∫ f(x)
dx
∂ x² ∂ y² i=1 i² 0
```
After the fix, the raw source, wrapped:
```
\[
\frac{\partial^2 u}{\partial
x^2} + \frac{\partial^2
...
\]
```
Fixes #11483
Requested by @badlogic
Co-authored-by: triagent <triagent@localhost>
This commit is contained in:
parent
807a5c051f
commit
cd1ea342ae
3 changed files with 31 additions and 3 deletions
|
|
@ -11,6 +11,7 @@
|
|||
- Fixed fullscreen double-click selection splitting paths and tokens at `~`, `.`, `\`, and `+`. Word characters now match iTerm2's defaults ([#10980](https://github.com/earendil-works/pi/issues/10980))
|
||||
- Fixed `fuzzyMatch()` ranking a query scattered over an earlier part of the text above a contiguous match later in it. It now also scores each contiguous occurrence of the query and keeps the best alignment ([#11220](https://github.com/earendil-works/pi/issues/11220), [#11296](https://github.com/earendil-works/pi/pull/11296))
|
||||
- Fixed `ProcessTerminal.setTitle()` writing control characters from the title, which could end the title sequence and send the rest to the terminal as escape sequences
|
||||
- Fixed display math wider than the content width being wrapped row by row, which split fractions and sums apart. It now falls back to the raw LaTeX source ([#11483](https://github.com/earendil-works/pi/issues/11483))
|
||||
|
||||
## [1.4.0] - 2026-10-21
|
||||
|
||||
|
|
|
|||
|
|
@ -536,10 +536,14 @@ export class Markdown implements Component {
|
|||
|
||||
case "latexBlock": {
|
||||
const latexToken = token as LatexToken;
|
||||
const rendered =
|
||||
let rendered =
|
||||
!latexToken.pending && this.options.renderLatex !== false
|
||||
? (renderLatex(latexToken.text, { display: true }) ?? latexToken.raw.trim())
|
||||
: latexToken.raw.trim();
|
||||
? renderLatex(latexToken.text, { display: true })
|
||||
: undefined;
|
||||
// A 2D layout cannot be wrapped row by row; fall back to the raw source when it does not fit.
|
||||
if (rendered === undefined || rendered.split("\n").some((line) => visibleWidth(line) > width)) {
|
||||
rendered = latexToken.raw.trim();
|
||||
}
|
||||
for (const line of rendered.split("\n")) {
|
||||
lines.push(this.applyDefaultStyle(line));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -966,6 +966,29 @@ Inline \(A_{sf}\)`,
|
|||
);
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/earendil-works/pi/issues/11483
|
||||
it("falls back to raw source when display math is wider than the content width", () => {
|
||||
const source = [
|
||||
"\\[",
|
||||
String.raw`\frac{\partial^2 u}{\partial x^2} + \frac{\partial^2 u}{\partial y^2} = \sum_{i=1}^{n} \frac{1}{i^2} + \int_0^1 f(x)\,dx`,
|
||||
"\\]",
|
||||
].join("\n");
|
||||
const render = (width: number) =>
|
||||
new Markdown(source, 0, 0, defaultMarkdownTheme).render(width).map((line) => stripAnsi(line).trimEnd());
|
||||
|
||||
assert.deepStrictEqual(render(40), [
|
||||
"∂² u ∂² u n 1 1",
|
||||
"──── + ──── = ∑ ── +∫ f(x) dx",
|
||||
"∂ x² ∂ y² i=1 i² 0",
|
||||
]);
|
||||
|
||||
const narrow = render(30);
|
||||
assert.strictEqual(narrow[0], "\\[");
|
||||
assert.strictEqual(narrow[narrow.length - 1], "\\]");
|
||||
assert.ok(!narrow.some((line) => line.includes("─")));
|
||||
assert.ok(narrow.every((line) => line.length <= 30));
|
||||
});
|
||||
|
||||
// Regression tests for https://github.com/earendil-works/pi/issues/11159
|
||||
describe("unclosed display math before tables (#11159)", () => {
|
||||
const table = ["| A | B |", "|---|---|", "| 1 | 2 |"];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue