Skip to content

Commit 387df67

Browse files
authored
Merge pull request #33 from mathjax/more-mml
Support more mml nodes
2 parents 24fa1c7 + d7e2c1c commit 387df67

File tree

13 files changed

+760
-14
lines changed

13 files changed

+760
-14
lines changed

mathjax3-ts/output/chtml/Wrapper.ts

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

2424
import {AbstractWrapper} from '../../core/Tree/Wrapper.js';
25-
import {Node} from '../../core/Tree/Node.js';
26-
import {MmlNode, TextNode} from '../../core/MmlTree/MmlNode.js';
25+
import {Node, PropertyList} from '../../core/Tree/Node.js';
26+
import {MmlNode, TextNode, AbstractMmlNode} from '../../core/MmlTree/MmlNode.js';
2727
import {Property} from '../../core/Tree/Node.js';
2828
import {OptionList} from '../../util/Options.js';
2929
import {unicodeChars} from '../../util/string.js';
@@ -612,6 +612,15 @@ export class CHTMLWrapper extends AbstractWrapper<MmlNode, CHTMLWrapper> {
612612
return LENGTHS.em(m);
613613
}
614614

615+
/*
616+
* @param{number} m A number of em's to be shown as pixels
617+
* @param{number} M The minimum number of pixels to allow
618+
* @return{string} The number with units of px
619+
*/
620+
protected px(m: number, M: number = -LENGTHS.BIGDIMEN) {
621+
return LENGTHS.px(m, M, this.metrics.em);
622+
}
623+
615624
/*
616625
* @param{Property} length A dimension (giving number and units) or number to be converted to ems
617626
* @param{number} size The default size of the dimension (for percentage values)
@@ -662,6 +671,24 @@ export class CHTMLWrapper extends AbstractWrapper<MmlNode, CHTMLWrapper> {
662671
return this.factory.chtml.text(text);
663672
}
664673

674+
/*
675+
* @param{string} text The text from which to create a TextNode object
676+
* @return{CHTMLTextNode} The TextNode with the given text
677+
*/
678+
public mmlText(text: string) {
679+
return ((this.node as AbstractMmlNode).factory.create('text') as TextNode).setText(text);
680+
}
681+
682+
/*
683+
* @param{string} kind The kind of MmlNode to create
684+
* @paramProperyList} properties The properties to set initially
685+
* @param{MmlNode[]} children The child nodes to add to the created node
686+
* @return{MmlNode} The newly created MmlNode
687+
*/
688+
public mmlNode(kind: string, properties: PropertyList = {}, children: MmlNode[] = []) {
689+
return (this.node as AbstractMmlNode).factory.create(kind, properties, children);
690+
}
691+
665692
}
666693

667694
/*

mathjax3-ts/output/chtml/Wrappers.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,32 @@
2323

2424
import {CHTMLWrapper} from './Wrapper.js';
2525
import {CHTMLmo} from './Wrappers/mo.js';
26+
import {CHTMLms} from './Wrappers/ms.js';
2627
import {CHTMLmspace} from './Wrappers/mspace.js';
28+
import {CHTMLmpadded} from './Wrappers/mpadded.js';
2729
import {CHTMLmrow, CHTMLinferredMrow} from './Wrappers/mrow.js';
2830
import {CHTMLmfrac} from './Wrappers/mfrac.js';
31+
import {CHTMLmsqrt} from './Wrappers/msqrt.js';
32+
import {CHTMLmroot} from './Wrappers/mroot.js';
33+
import {CHTMLsemantics, CHTMLannotation, CHTMLannotationXML, CHTMLxml} from './Wrappers/semantics.js';
34+
import {CHTMLTeXAtom} from './Wrappers/TeXAtom.js';
2935
import {CHTMLTextNode} from './Wrappers/TextNode.js';
3036

3137
export const CHTMLWrappers: {[kind: string]: typeof CHTMLWrapper} = {
3238
[CHTMLmrow.kind]: CHTMLmrow,
3339
[CHTMLinferredMrow.kind]: CHTMLinferredMrow,
3440
[CHTMLmo.kind]: CHTMLmo,
41+
[CHTMLms.kind]: CHTMLms,
3542
[CHTMLmspace.kind]: CHTMLmspace,
43+
[CHTMLmpadded.kind]: CHTMLmpadded,
3644
[CHTMLmfrac.kind]: CHTMLmfrac,
45+
[CHTMLmsqrt.kind]: CHTMLmsqrt,
46+
[CHTMLmroot.kind]: CHTMLmroot,
47+
[CHTMLsemantics.kind]: CHTMLsemantics,
48+
[CHTMLannotation.kind]: CHTMLannotation,
49+
[CHTMLannotationXML.kind]: CHTMLannotationXML,
50+
[CHTMLxml.kind]: CHTMLxml,
51+
[CHTMLTeXAtom.kind]: CHTMLTeXAtom,
3752
[CHTMLTextNode.kind]: CHTMLTextNode,
3853
[CHTMLWrapper.kind]: CHTMLWrapper
3954
};
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
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 CHTMLTeXAtom wrapper for the MmlTeXAtom object
20+
*
21+
* @author [email protected] (Davide Cervone)
22+
*/
23+
24+
import {CHTMLWrapper} from '../Wrapper.js';
25+
import {BBox} from '../BBox.js';
26+
import {TeXAtom} from '../../../core/MmlTree/MmlNodes/TeXAtom.js';
27+
import {MmlNode, TEXCLASS} from '../../../core/MmlTree/MmlNode.js';
28+
29+
/*****************************************************************/
30+
/*
31+
* The CHTMLTeXAtom wrapper for the TeXAtom object
32+
*/
33+
34+
export class CHTMLTeXAtom extends CHTMLWrapper {
35+
public static kind = TeXAtom.prototype.kind;
36+
37+
/*
38+
* @override
39+
*/
40+
public toCHTML(parent: HTMLElement) {
41+
super.toCHTML(parent);
42+
//
43+
// Center VCENTER atoms vertically
44+
//
45+
if (this.node.texClass === TEXCLASS.VCENTER) {
46+
const bbox = super.computeBBox(); // get unmodified bbox of children
47+
const {h, d} = bbox;
48+
const a = this.font.params.axis_height;
49+
const dh = ((h + d) / 2 + a) - h; // new height minus old height
50+
this.chtml.style.verticalAlign = this.em(dh);
51+
}
52+
}
53+
54+
/*
55+
* @override
56+
*/
57+
public computeBBox() {
58+
const bbox = super.computeBBox();
59+
//
60+
// Center VCENTER atoms vertically
61+
//
62+
if (this.node.texClass === TEXCLASS.VCENTER) {
63+
const {h, d} = bbox;
64+
const a = this.font.params.axis_height;
65+
const dh = ((h + d) / 2 + a) - h; // new height minus old height
66+
bbox.h += dh;
67+
bbox.d += dh;
68+
}
69+
return bbox;
70+
}
71+
72+
}

mathjax3-ts/output/chtml/Wrappers/TextNode.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ export class CHTMLTextNode extends CHTMLWrapper {
5757
// FIXME: measure this using DOM, if possible
5858
} else {
5959
const chars = this.unicodeChars((this.node as TextNode).getText());
60-
let [h, d, w] = this.font.getChar(variant, chars[0]);
60+
let [h, d, w] = this.font.getChar(variant, chars[0]) || [0, 0, 0];
6161
bbox.h = h;
6262
bbox.d = d;
6363
bbox.w = w;
6464
for (let i = 1, m = chars.length; i < m; i++) {
65-
[h, d, w] = this.font.getChar(variant, chars[i]);
65+
[h, d, w] = this.font.getChar(variant, chars[i]) || [0, 0, 0];
6666
bbox.w += w;
6767
if (h > bbox.h) bbox.h = h;
6868
if (d > bbox.d) bbox.d = d;

mathjax3-ts/output/chtml/Wrappers/mo.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export class CHTMLmo extends CHTMLWrapper {
3838
* The font size that a stretched operator uses.
3939
* If -1, then stretch arbitrarily, and bbox gives the actual height, depth, width
4040
*/
41-
protected size: number = null;
41+
public size: number = null;
4242

4343
/*
4444
* @override
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
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 CHTMLmpadded wrapper for the MmlMpadded object
20+
*
21+
* @author [email protected] (Davide Cervone)
22+
*/
23+
24+
import {CHTMLWrapper, StringMap} from '../Wrapper.js';
25+
import {BBox} from '../BBox.js';
26+
import {MmlMpadded} from '../../../core/MmlTree/MmlNodes/mpadded.js';
27+
import {MmlNode} from '../../../core/MmlTree/MmlNode.js';
28+
import {Property} from '../../../core/Tree/Node.js';
29+
30+
/*****************************************************************/
31+
/*
32+
* The CHTMLmpadded wrapper for the MmlMpadded object
33+
*/
34+
35+
export class CHTMLmpadded extends CHTMLWrapper {
36+
public static kind = MmlMpadded.prototype.kind;
37+
38+
/*
39+
* @override
40+
*/
41+
public toCHTML(parent: HTMLElement) {
42+
let chtml = this.standardCHTMLnode(parent);
43+
const content: HTMLElement[] = [];
44+
const style: StringMap = {};
45+
const [H, D, W, dh, dd, dw, x, y] = this.getDimens();
46+
//
47+
// If the width changed, set the width explicitly
48+
//
49+
if (dw) {
50+
style.width = this.em(W + dw);
51+
}
52+
//
53+
// If the height or depth changed, use margin to make the change
54+
//
55+
if (dh || dd) {
56+
style.margin = this.em(dh) + ' 0 ' + this.em(dd);
57+
}
58+
//
59+
// If there is a horizontal or vertical shift,
60+
// use relative positioning to move the contents
61+
//
62+
if (x || y) {
63+
style.position = 'relative';
64+
content.push(this.html('mjx-rbox', {style: {left: this.em(x), top: this.em(-y)}}));
65+
}
66+
//
67+
// Create the HTML with the proper styles and content
68+
//
69+
chtml = chtml.appendChild(this.html('mjx-block', {style: style}, content));
70+
for (const child of this.childNodes) {
71+
child.toCHTML(chtml.firstChild as HTMLElement || chtml);
72+
}
73+
}
74+
75+
/*
76+
* Get the content bounding box, and the change in size and offsets
77+
* as specified by the parameters
78+
*
79+
* @return{number[]} The original height, depth, width, the changes in height, depth,
80+
* and width, and the horizontal and vertical offsets of the content
81+
*/
82+
protected getDimens() {
83+
const values = this.node.attributes.getList('width', 'height', 'depth', 'lspace', 'voffset');
84+
const bbox = super.computeBBox(); // get unmodified bbox of children
85+
let {w, h, d} = bbox;
86+
let W = w, H = h, D = d, x = 0, y = 0;
87+
if (values.width !== '') w = this.dimen(values.width, bbox, 'w', 0);
88+
if (values.height !== '') h = this.dimen(values.height, bbox, 'h', 0);
89+
if (values.depth !== '') d = this.dimen(values.depth, bbox, 'd', 0);
90+
if (values.voffset !== '') y = this.dimen(values.voffset, bbox);
91+
if (values.lspace !== '') x = this.dimen(values.lspace, bbox);
92+
return [H, D, W, h - H, d - D, w - W, x, y];
93+
}
94+
95+
/*
96+
* Get a particular dimension, which can be relative to any of the BBox dimensions,
97+
* and can be an offset from the default size of the given dimension.
98+
*
99+
* @param{Property} length The value to be converted to a length in ems
100+
* @param{BBox} bbox The bbox of the mpadded content
101+
* @param{string} d The default dimension to use for relative sizes ('w', 'h', or 'd')
102+
* @param{number} m The minimum value allowed for the dimension
103+
* @return{number} The final dimension in ems
104+
*/
105+
protected dimen(length: Property, bbox: BBox, d: string = '', m: number = null) {
106+
length = String(length);
107+
const match = length.match(/width|height|depth/);
108+
const size = (match ? bbox[match[0].charAt(0) as (keyof BBox)] : (d ? bbox[d as (keyof BBox)] : 0)) as number;
109+
let dimen = (this.length2em(length, size) || 0);
110+
if (length.match(/^[-+]/) && d) {
111+
dimen += size;
112+
}
113+
if (m != null) {
114+
dimen = Math.max(m, dimen);
115+
}
116+
return dimen;
117+
}
118+
119+
/*
120+
* @override
121+
*/
122+
public computeBBox() {
123+
const [H, D, W, dh, dd, dw, x, y] = this.getDimens();
124+
const bbox = this.bbox;
125+
bbox.w = W + dw;
126+
bbox.h = H + dh;
127+
bbox.d = D + dd;
128+
return bbox;
129+
}
130+
131+
}

0 commit comments

Comments
 (0)