Skip to content

Commit 30f26ce

Browse files
authored
fix(math): use stretchable U+203E for both over and underbar accents (SD-2408) (#2639)
U+2015 (horizontal bar) doesn't stretch in MathML, so underbars on compound expressions like x+y only appeared under a single letter. Use U+203E (overline) for both — it's stretchable and munder/mover controls the position.
1 parent faaedb6 commit 30f26ce

2 files changed

Lines changed: 6 additions & 6 deletions

File tree

packages/layout-engine/painters/dom/src/features/math/converters/bar.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const MATHML_NS = 'http://www.w3.org/1998/Math/MathML';
1010
*
1111
* MathML output:
1212
* top: <mover> <mrow>base</mrow> <mo>&#x203E;</mo> </mover>
13-
* bot (default): <munder> <mrow>base</mrow> <mo>&#x2015;</mo> </munder>
13+
* bot (default): <munder> <mrow>base</mrow> <mo>&#x203E;</mo> </munder>
1414
*
1515
* Word renders an underbar when no position is specified, so the default is "bot".
1616
*
@@ -35,8 +35,8 @@ export const convertBar: MathObjectConverter = (node, doc, convertChildren) => {
3535

3636
const accent = doc.createElementNS(MATHML_NS, 'mo');
3737
accent.setAttribute('stretchy', 'true');
38-
// U+203E = overline, U+2015 = horizontal bar (underbar)
39-
accent.textContent = isUnder ? '\u2015' : '\u203E';
38+
// U+203E = overline (stretchable in MathML, used for both over and under)
39+
accent.textContent = '\u203E';
4040
wrapper.appendChild(accent);
4141

4242
return wrapper;

packages/layout-engine/painters/dom/src/features/math/omml-to-mathml.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ describe('m:bar converter', () => {
235235
expect(mo?.textContent).toBe('\u203E');
236236
});
237237

238-
it('renders underbar (bot) as <munder> with U+2015', () => {
238+
it('renders underbar (bot) as <munder> with U+203E', () => {
239239
const omml = {
240240
name: 'm:oMath',
241241
elements: [
@@ -257,7 +257,7 @@ describe('m:bar converter', () => {
257257
expect(munder).not.toBeNull();
258258
expect(munder!.firstElementChild!.textContent).toBe('y');
259259
const mo = munder!.querySelector('mo');
260-
expect(mo?.textContent).toBe('\u2015');
260+
expect(mo?.textContent).toBe('\u203E');
261261
});
262262

263263
it('defaults to underbar when m:barPr is missing (matches Word behavior)', () => {
@@ -281,6 +281,6 @@ describe('m:bar converter', () => {
281281
expect(munder).not.toBeNull();
282282
expect(munder!.firstElementChild!.textContent).toBe('z');
283283
const mo = munder!.querySelector('mo');
284-
expect(mo?.textContent).toBe('\u2015');
284+
expect(mo?.textContent).toBe('\u203E');
285285
});
286286
});

0 commit comments

Comments
 (0)