Skip to content

Commit ffeb86b

Browse files
committed
Add support for munder/mover/munderover
1 parent 11b0571 commit ffeb86b

File tree

6 files changed

+360
-11
lines changed

6 files changed

+360
-11
lines changed

mathjax3-ts/output/chtml/FontData.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ export class FontData {
197197
big_op_spacing1: .111,
198198
big_op_spacing2: .167,
199199
big_op_spacing3: .2,
200-
big_op_spacing4: .45, // .6, // better spacing for under arrows and braces
200+
big_op_spacing4: .6,
201201
big_op_spacing5: .1,
202202

203203
surd_height: .075,

mathjax3-ts/output/chtml/Wrapper.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ export class CHTMLWrapper extends AbstractWrapper<MmlNode, CHTMLWrapper> {
108108
'mjx-box': {display: 'inline-block'},
109109
'mjx-block': {display: 'block'},
110110
'mjx-itable': {display: 'inline-table'},
111+
'mjx-row': {display: 'table-row'},
112+
'mjx-row > *': {display: 'table-cell'},
111113

112114
//
113115
// These don't have Wrapper subclasses, so add their styles here

mathjax3-ts/output/chtml/Wrappers.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {CHTMLmfrac} from './Wrappers/mfrac.js';
3131
import {CHTMLmsqrt} from './Wrappers/msqrt.js';
3232
import {CHTMLmroot} from './Wrappers/mroot.js';
3333
import {CHTMLmsub, CHTMLmsup, CHTMLmsubsup} from './Wrappers/msubsup.js';
34+
import {CHTMLmover, CHTMLmunder, CHTMLmunderover} from './Wrappers/munderover.js';
3435
import {CHTMLmtable} from './Wrappers/mtable.js';
3536
import {CHTMLmtr, CHTMLmlabeledtr} from './Wrappers/mtr.js';
3637
import {CHTMLmtd} from './Wrappers/mtd.js';
@@ -51,6 +52,9 @@ export const CHTMLWrappers: {[kind: string]: typeof CHTMLWrapper} = {
5152
[CHTMLmsub.kind]: CHTMLmsub,
5253
[CHTMLmsup.kind]: CHTMLmsup,
5354
[CHTMLmsubsup.kind]: CHTMLmsubsup,
55+
[CHTMLmunder.kind]: CHTMLmunder,
56+
[CHTMLmover.kind]: CHTMLmover,
57+
[CHTMLmunderover.kind]: CHTMLmunderover,
5458
[CHTMLmtable.kind]: CHTMLmtable,
5559
[CHTMLmtr.kind]: CHTMLmtr,
5660
[CHTMLmlabeledtr.kind]: CHTMLmlabeledtr,
Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
/*************************************************************
2+
*
3+
* Copyright (c) 2017 The MathJax Consortium
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
/**
19+
* @fileoverview Implements the CHTMLmunderover wrapper for the MmlMunderover object
20+
* and the special cases CHTMLmunder and CHTMLmsup
21+
*
22+
* @author dpvc@mathjax.org (Davide Cervone)
23+
*/
24+
25+
import {CHTMLWrapper} from '../Wrapper.js';
26+
import {CHTMLmsubsup, CHTMLmsub, CHTMLmsup} from './msubsup.js';
27+
import {MmlMunderover, MmlMunder, MmlMover} from '../../../core/MmlTree/MmlNodes/munderover.js';
28+
import {MmlNode} from '../../../core/MmlTree/MmlNode.js';
29+
import {BBox} from '../BBox.js';
30+
import {StyleList} from '../CssStyles.js';
31+
32+
/*****************************************************************/
33+
/*
34+
* The CHTMLmunder wrapper for the MmlMunder object
35+
*/
36+
37+
export class CHTMLmunder extends CHTMLmsub {
38+
public static kind = MmlMunder.prototype.kind;
39+
40+
public static styles: StyleList = {
41+
'mjx-munder:not([limits="false"])': {
42+
display: 'inline-table',
43+
},
44+
'mjx-munder > mjx-row': {
45+
'text-align': 'left'
46+
},
47+
'mjx-under': {
48+
'padding-bottom': '.1em' // big_op_spacing5
49+
}
50+
};
51+
52+
/*
53+
* @override
54+
*/
55+
public get script() {
56+
return this.childNodes[(this.node as MmlMunder).under];
57+
}
58+
59+
/*
60+
* @override
61+
*/
62+
public toCHTML(parent: HTMLElement) {
63+
if (this.hasMovableLimits()) {
64+
super.toCHTML(parent);
65+
this.chtml.setAttribute('limits', 'false');
66+
return;
67+
}
68+
this.chtml = this.standardCHTMLnode(parent);
69+
const base = this.chtml.appendChild(this.html('mjx-row')).appendChild(this.html('mjx-base'));
70+
const under = this.chtml.appendChild(this.html('mjx-row')).appendChild(this.html('mjx-under'));
71+
this.base.toCHTML(base);
72+
this.script.toCHTML(under);
73+
const basebox = this.base.getBBox();
74+
const underbox = this.script.getBBox();
75+
const [k, v] = this.getUnderKV(basebox, underbox);
76+
under.style.paddingTop = this.em(k);
77+
this.setDeltaW([base, under], this.getDeltaW([basebox, underbox]));
78+
}
79+
80+
/*
81+
* @override
82+
*/
83+
public computeBBox(bbox: BBox) {
84+
if (this.hasMovableLimits()) {
85+
super.computeBBox(bbox);
86+
return;
87+
}
88+
bbox.empty();
89+
const basebox = this.base.getBBox();
90+
const underbox = this.script.getBBox();
91+
const [k, v] = this.getUnderKV(basebox, underbox);
92+
const [bw, uw] = this.getDeltaW([basebox, underbox]);
93+
bbox.combine(basebox, bw, 0);
94+
bbox.combine(underbox, uw, v);
95+
bbox.d += this.font.params.big_op_spacing5;
96+
bbox.clean();
97+
}
98+
99+
}
100+
101+
/*****************************************************************/
102+
/*
103+
* The CHTMLmover wrapper for the MmlMover object
104+
*/
105+
106+
export class CHTMLmover extends CHTMLmsup {
107+
public static kind = MmlMover.prototype.kind;
108+
109+
public static styles: StyleList = {
110+
'mjx-mover:not([limits="false"])': {
111+
'padding-top': '.1em' // big_op_spacing5
112+
},
113+
'mjx-mover:not([limits="false"]) > *': {
114+
display: 'block',
115+
'text-align': 'left'
116+
}
117+
};
118+
119+
/*
120+
* @override
121+
*/
122+
public get script() {
123+
return this.childNodes[(this.node as MmlMover).over];
124+
}
125+
126+
/*
127+
* @override
128+
*/
129+
public toCHTML(parent: HTMLElement) {
130+
if (this.hasMovableLimits()) {
131+
super.toCHTML(parent);
132+
this.chtml.setAttribute('limits', 'false');
133+
return;
134+
}
135+
this.chtml = this.standardCHTMLnode(parent);
136+
const over = this.chtml.appendChild(this.html('mjx-over'));
137+
const base = this.chtml.appendChild(this.html('mjx-base'));
138+
this.script.toCHTML(over);
139+
this.base.toCHTML(base);
140+
const overbox = this.script.getBBox();
141+
const basebox = this.base.getBBox();
142+
const [k, u] = this.getOverKU(basebox, overbox);
143+
over.style.paddingBottom = this.em(k);
144+
this.setDeltaW([base, over], this.getDeltaW([basebox, overbox]));
145+
if (overbox.d < 0) {
146+
over.style.marginBottom = this.em(overbox.d * overbox.rscale);
147+
}
148+
}
149+
150+
/*
151+
* @override
152+
*/
153+
public computeBBox(bbox: BBox) {
154+
if (this.hasMovableLimits()) {
155+
super.computeBBox(bbox);
156+
return;
157+
}
158+
bbox.empty();
159+
const basebox = this.base.getBBox();
160+
const overbox = this.script.getBBox();
161+
const [k, u] = this.getOverKU(basebox, overbox);
162+
const [bw, ow] = this.getDeltaW([basebox, overbox]);
163+
bbox.combine(basebox, bw, 0);
164+
bbox.combine(overbox, ow, u);
165+
bbox.h += this.font.params.big_op_spacing5;
166+
bbox.clean();
167+
}
168+
169+
}
170+
171+
/*****************************************************************/
172+
/*
173+
* The CHTMLmunderover wrapper for the MmlMunderover object
174+
*/
175+
176+
export class CHTMLmunderover extends CHTMLmsubsup {
177+
public static kind = MmlMunderover.prototype.kind;
178+
179+
public static styles: StyleList = {
180+
'mjx-munderover:not([limits="false"])': {
181+
'padding-top': '.1em' // big_op_spacing5
182+
},
183+
'mjx-munderover:not([limits="false"]) > *': {
184+
display: 'block'
185+
},
186+
};
187+
188+
/*
189+
* @return{CHTMLWrapper) The wrapped under node
190+
*/
191+
public get under() {
192+
return this.childNodes[(this.node as MmlMunderover).under];
193+
}
194+
195+
/*
196+
* @return{CHTMLWrapper) The wrapped overder node
197+
*/
198+
public get over() {
199+
return this.childNodes[(this.node as MmlMunderover).over];
200+
}
201+
202+
/*
203+
* Needed for movablelimits
204+
*
205+
* @override
206+
*/
207+
public get sub() {
208+
return this.under;
209+
}
210+
211+
/*
212+
* Needed for movablelimits
213+
*
214+
* @override
215+
*/
216+
public get sup() {
217+
return this.over;
218+
}
219+
220+
/*
221+
* @override
222+
*/
223+
public toCHTML(parent: HTMLElement) {
224+
if (this.hasMovableLimits()) {
225+
super.toCHTML(parent);
226+
this.chtml.setAttribute('limits', 'false');
227+
return;
228+
}
229+
this.chtml = this.standardCHTMLnode(parent);
230+
const over = this.chtml.appendChild(this.html('mjx-over'));
231+
const table = this.chtml.appendChild(this.html('mjx-box')).appendChild(this.html('mjx-munder'));
232+
const base = table.appendChild(this.html('mjx-row')).appendChild(this.html('mjx-base'));
233+
const under = table.appendChild(this.html('mjx-row')).appendChild(this.html('mjx-under'));
234+
this.over.toCHTML(over);
235+
this.base.toCHTML(base);
236+
this.under.toCHTML(under);
237+
const overbox = this.over.getBBox();
238+
const basebox = this.base.getBBox();
239+
const underbox = this.under.getBBox();
240+
const [ok, u] = this.getOverKU(basebox, overbox);
241+
const [uk, v] = this.getUnderKV(basebox, underbox);
242+
over.style.paddingBottom = this.em(ok);
243+
under.style.paddingTop = this.em(uk);
244+
this.setDeltaW([base, under, over], this.getDeltaW([basebox, underbox, overbox]));
245+
if (overbox.d < 0) {
246+
over.style.marginBottom = this.em(overbox.d * overbox.rscale);
247+
}
248+
}
249+
250+
/*
251+
* @override
252+
*/
253+
public computeBBox(bbox: BBox) {
254+
if (this.hasMovableLimits()) {
255+
super.computeBBox(bbox);
256+
return;
257+
}
258+
bbox.empty();
259+
const overbox = this.over.getBBox();
260+
const basebox = this.base.getBBox();
261+
const underbox = this.under.getBBox();
262+
const [ok, u] = this.getOverKU(basebox, overbox);
263+
const [uk, v] = this.getUnderKV(basebox, underbox);
264+
const [bw, uw, ow] = this.getDeltaW([basebox, underbox, overbox]);
265+
bbox.combine(basebox, bw, 0);
266+
bbox.combine(overbox, ow, u);
267+
bbox.combine(underbox, uw, v);
268+
const z = this.font.params.big_op_spacing5;
269+
bbox.h += z;
270+
bbox.d += z;
271+
bbox.clean();
272+
}
273+
274+
}

0 commit comments

Comments
 (0)