fix: a bracket typed without \left keeps its glyph height
The MathML operator dictionary makes ( [ { | stretchy, so a plain bracket grew
to the tallest thing in its row — next to a sum with a fraction, C(b) came out
in full row height. Only a fence node emits stretchy brackets now.
This commit is contained in:
1 parent
855cc24371
commit
d8be23cf68
10 files changed
+7
-1
No files matched your search
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -13,6 +13,8 @@ const esc = (s: string) =>
|
||||
|
||||
const TAG_BY_KIND: Record<TxtKind, string> = { i: 'mi', n: 'mn', o: 'mo', f: 'mi' };
|
||||
|
||||
const BRACKETS = /^[([{|‖⟨⌊⌈)\]}⟩⌋⌉]$/;
|
||||
|
||||
// A row that MathML needs as a single element (mfrac, msup, … each take exactly one
|
||||
// child per slot), so a multi-node row is wrapped in <mrow>.
|
||||
function slot(n: MathNode): string {
|
||||
@@ -27,7 +29,9 @@ export function astToMathml(n: MathNode): string {
|
||||
if (n.kind === 'f') return `<mi mathvariant="normal">${esc(n.s)}</mi>`;
|
||||
// Multi-letter identifiers stay upright in MathML unless split, and a number
|
||||
// like 3.14 is one token — so emit the run whole and let the class pick the tag.
|
||||
return `<${TAG_BY_KIND[n.kind]}>${esc(n.s)}</${TAG_BY_KIND[n.kind]}>`;
|
||||
// A bracket typed without \left stays glyph-height; only a fence stretches.
|
||||
const attr = n.kind === 'o' && BRACKETS.test(n.s) ? ' stretchy="false"' : '';
|
||||
return `<${TAG_BY_KIND[n.kind]}${attr}>${esc(n.s)}</${TAG_BY_KIND[n.kind]}>`;
|
||||
}
|
||||
case 'frac': return `<mfrac>${slot(n.num)}${slot(n.den)}</mfrac>`;
|
||||
case 'script': {
|
||||
|
||||
@@ -54,6 +54,8 @@ describe('MathML', () => {
|
||||
expect(astToMathml(parseLatex('\\int_{0}^{1} x'))).toContain('<msubsup>');
|
||||
// Brackets must be stretchy or they stay glyph-height next to a fraction.
|
||||
expect(astToMathml(parseLatex('\\left(x\\right)'))).toContain('<mo stretchy="true">(</mo>');
|
||||
// A plain bracket must not: the dictionary would stretch it to the row's tallest.
|
||||
expect(astToMathml(parseLatex('C(b) = \\frac{1}{2}'))).toContain('<mo stretchy="false">(</mo>');
|
||||
});
|
||||
|
||||
it('round-trips through the document element', () => {
|
||||
|
||||
Reference in new issue
Block a user