Skip to content

Commit ce1e3fd

Browse files
authored
Merge pull request #1095 from mathjax/fix-mathaccents
Update handling of math accents to round-trip through SRE
2 parents 51392bc + b833531 commit ce1e3fd

File tree

4 files changed

+51
-6
lines changed

4 files changed

+51
-6
lines changed

ts/core/MmlTree/MmlNodes/mo.ts

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ export class MmlMo extends AbstractMmlTokenNode {
124124

125125
/**
126126
* Regular expression matching characters that are marked as math accents
127+
* (property mathaccent = true)
127128
*/
128129
protected static mathaccents = new RegExp([
129130
'^[',
@@ -135,14 +136,27 @@ export class MmlMo extends AbstractMmlTokenNode {
135136
'\u02D8\u0306', // breve
136137
'\u02C7\u030C', // check
137138
'\u005E\u0302\u02C6', // hat
138-
'\u2192\u20D7', // vec
139+
'\u20D0\u20D1', // harpoons
140+
'\u20D6\u20D7\u20E1', // vec (backward, forward, double)
139141
'\u02D9\u0307', // dot
140142
'\u02DA\u030A', // mathring
141143
'\u20DB', // dddot
142144
'\u20DC', // ddddot
143145
']$'
144146
].join(''));
145147

148+
/**
149+
* Regular expression matching characters that are marked as math accents
150+
* whose widths are to be respected (property mathaccent = false)
151+
*/
152+
protected static mathaccentsWithWidth = new RegExp([
153+
'^[',
154+
'\u2015', // overline and underline
155+
'\u2190\u2192\u2194', // arrows
156+
'\u23DC\u23DD', // over and under parens
157+
']$'
158+
].join(''));
159+
146160
/**
147161
* The internal TeX class of the node (for use with getter/setter below)
148162
*/
@@ -470,10 +484,33 @@ export class MmlMo extends AbstractMmlTokenNode {
470484
const isUnder = !!(under && under.isEmbellished && under.coreMO() === this);
471485
const isOver = !!(over && over.isEmbellished && under.coreMO() === this);
472486
if (!isUnder && !isOver) return;
473-
const MATHACCENT = (this.constructor as typeof MmlMo).mathaccents;
474-
if (mo.match(MATHACCENT)) {
475-
this.setProperty('mathaccent', true);
487+
if (this.isMathAccent(mo)) {
488+
this.setProperty('mathaccent', true); // math accent whose width is replaced by 0
489+
} else if (this.isMathAccentWithWidth(mo)) {
490+
this.setProperty('mathaccent', false); // math accent whose width is normal
476491
}
477492
}
478493

494+
/**
495+
* Check a string for being a mathaccent
496+
*
497+
* @param {string} mo The string to check
498+
* @return {boolean} True if the string should be a mathaccent
499+
*/
500+
public isMathAccent(mo: string = this.getText()): boolean {
501+
const MATHACCENT = (this.constructor as typeof MmlMo).mathaccents;
502+
return !!mo.match(MATHACCENT);
503+
}
504+
505+
/**
506+
* Check a string for being a mathaccent with non-zero width
507+
*
508+
* @param {string} mo The string to check
509+
* @return {boolean} True if the string should be a mathaccent
510+
*/
511+
public isMathAccentWithWidth(mo: string = this.getText()): boolean {
512+
const MATHACCENT = (this.constructor as typeof MmlMo).mathaccentsWithWidth;
513+
return !!mo.match(MATHACCENT);
514+
}
515+
479516
}

ts/core/MmlTree/MmlVisitor.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
*/
2323

2424
import {MmlNode, TextNode, XMLNode, TEXCLASS, TEXCLASSNAMES} from './MmlNode.js';
25+
import {MmlMo} from './MmlNodes/mo.js';
2526
import {MmlMi} from './MmlNodes/mi.js';
2627
import {HtmlNode} from './MmlNodes/HtmlNode.js';
2728
import {MmlFactory} from './MmlFactory.js';
@@ -167,6 +168,13 @@ export class MmlVisitor extends AbstractVisitor<MmlNode> {
167168
vbox && this.setDataAttribute(data, 'vbox', vbox);
168169
const scriptalign = node.getProperty('scriptalign') as string;
169170
scriptalign && this.setDataAttribute(data, 'script-align', scriptalign);
171+
const accent = node.getProperty('mathaccent') as boolean;
172+
if (accent !== undefined) {
173+
if ((accent && !(node as MmlMo).isMathAccent()) ||
174+
(!accent && !(node as MmlMo).isMathAccentWithWidth())) {
175+
this.setDataAttribute(data, 'mathaccent', accent.toString());
176+
}
177+
}
170178
const texclass = node.getProperty('texClass') as number;
171179
if (texclass !== undefined) {
172180
let setclass = true;

ts/input/mathml/MathMLCompile.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ export class MathMLCompile<N, T, D> {
201201
mml.setProperty('scriptlevel', 1);
202202
mml.setProperty('useHeight', false);
203203
break;
204-
case 'accent':
204+
case 'mathaccent':
205205
mml.setProperty('mathaccent', value === 'true');
206206
break;
207207
case 'auto-op':

ts/output/common/Wrappers/scriptbase.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,7 @@ export function CommonScriptbaseMixin<
793793
// Determine if we are setting a mathaccent
794794
//
795795
this.isMathAccent = this.baseIsChar &&
796-
(this.scriptChild && !!this.scriptChild.coreMO().node.getProperty('mathaccent')) as boolean;
796+
(this.scriptChild && this.scriptChild.coreMO().node.getProperty('mathaccent') !== undefined);
797797
//
798798
// Check for overline/underline accents
799799
//

0 commit comments

Comments
 (0)