Skip to content

Commit a2da259

Browse files
authored
Merge pull request #703 from mathjax/empheq-numcases
Empheq and numcases packages
2 parents 53b13c0 + 995b35c commit a2da259

16 files changed

Lines changed: 775 additions & 2 deletions

File tree

components/src/dependencies.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ export const dependencies = {
3232
'[tex]/tagformat': ['input/tex-base'],
3333
'[tex]/textmacros': ['input/tex-base'],
3434
'[tex]/unicode': ['input/tex-base'],
35-
'[tex]/verb': ['input/tex-base']
35+
'[tex]/verb': ['input/tex-base'],
36+
'[tex]/cases': ['[tex]/empheq'],
37+
'[tex]/empheq': ['input/tex-base', '[tex]/ams']
3638
};
3739

3840
export const paths = {
@@ -68,7 +70,9 @@ const allPackages = [
6870
'[tex]/tagformat',
6971
'[tex]/textmacros',
7072
'[tex]/unicode',
71-
'[tex]/verb'
73+
'[tex]/verb',
74+
'[tex]/cases',
75+
'[tex]/empheq'
7276
];
7377

7478
export const provides = {
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"component": "input/tex/extensions/cases",
3+
"targets": ["input/tex/cases"]
4+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import './lib/cases.js';
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
const PACKAGE = require('../../../../../webpack.common.js');
2+
3+
module.exports = PACKAGE(
4+
'cases', // the package to build
5+
'../../../../../js', // location of the compiled js files
6+
[ // packages to link to (relative to Mathjax components)
7+
'components/src/input/tex-base/lib',
8+
'components/src/input/tex/extensions/ams/lib',
9+
'components/src/input/tex/extensions/empheq/lib',
10+
'components/src/core/lib'
11+
],
12+
__dirname // our directory
13+
);
14+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"component": "input/tex/extensions/empheq",
3+
"targets": ["input/tex/empheq"]
4+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import './lib/empheq.js';
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
const PACKAGE = require('../../../../../webpack.common.js');
2+
3+
module.exports = PACKAGE(
4+
'empheq', // the package to build
5+
'../../../../../js', // location of the compiled js files
6+
[ // packages to link to
7+
'components/src/input/tex-base/lib',
8+
'components/src/core/lib'
9+
],
10+
__dirname // our directory
11+
);
12+

components/src/source.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ export const source = {
3535
'[tex]/textmacros': `${src}/input/tex/extensions/textmacros/textmacros.js`,
3636
'[tex]/unicode': `${src}/input/tex/extensions/unicode/unicode.js`,
3737
'[tex]/verb': `${src}/input/tex/extensions/verb/verb.js`,
38+
'[tex]/cases': `${src}/input/tex/extensions/cases/cases.js`,
39+
'[tex]/empheq': `${src}/input/tex/extensions/empheq/empheq.js`,
3840
'input/mml': `${src}/input/mml/mml.js`,
3941
'input/mml/entities': `${src}/input/mml/entities/entities.js`,
4042
'[mml]/mml3': `${src}/input/mml/extensions/mml3/mml3.js`,

ts/core/MmlTree/MmlNode.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ export type MMLNODE = MmlNode | TextNode | XMLNode;
8787
*/
8888

8989
export interface MmlNode extends Node {
90+
9091
/**
9192
* Test various properties of MathML nodes
9293
*/
@@ -95,21 +96,25 @@ export interface MmlNode extends Node {
9596
readonly isSpacelike: boolean;
9697
readonly linebreakContainer: boolean;
9798
readonly hasNewLine: boolean;
99+
98100
/**
99101
* The expected number of children (-1 means use inferred mrow)
100102
*/
101103
readonly arity: number;
102104
readonly isInferred: boolean;
105+
103106
/**
104107
* Get the parent node (skipping inferred mrows and
105108
* other nodes marked as notParent)
106109
*/
107110
readonly Parent: MmlNode;
108111
readonly notParent: boolean;
112+
109113
/**
110114
* The actual parent in the tree
111115
*/
112116
parent: MmlNode;
117+
113118
/**
114119
* values needed for TeX spacing computations
115120
*/
@@ -127,16 +132,19 @@ export interface MmlNode extends Node {
127132
* core <mo> node. For non-embellished nodes, the original node.
128133
*/
129134
core(): MmlNode;
135+
130136
/**
131137
* @return {MmlNode} For embellished operators, the core <mo> element (at whatever
132138
* depth). For non-embellished nodes, the original node itself.
133139
*/
134140
coreMO(): MmlNode;
141+
135142
/**
136143
* @return {number} For embellished operators, the index of the child node containing
137144
* the core <mo>. For non-embellished nodes, 0.
138145
*/
139146
coreIndex(): number;
147+
140148
/**
141149
* @return {number} The index of this node in its parent's childNodes array.
142150
*/
@@ -149,10 +157,12 @@ export interface MmlNode extends Node {
149157
* in the tree (usually, either the last child, or the node itself)
150158
*/
151159
setTeXclass(prev: MmlNode): MmlNode;
160+
152161
/**
153162
* @return {string} The spacing to use before this element (one of TEXSPACELENGTH array above)
154163
*/
155164
texSpacing(): string;
165+
156166
/**
157167
* @return {boolean} The core mo element has an explicit 'form', 'lspace', or 'rspace' attribute
158168
*/
@@ -201,10 +211,12 @@ export interface MmlNode extends Node {
201211
*/
202212

203213
export interface MmlNodeClass extends NodeClass {
214+
204215
/**
205216
* The list of default attribute values for nodes of this class
206217
*/
207218
defaults?: PropertyList;
219+
208220
/**
209221
* An MmlNode takes a NodeFactory (so it can create additional nodes as needed), a list
210222
* of attributes, and an array of children and returns the desired MmlNode with
@@ -216,6 +228,7 @@ export interface MmlNodeClass extends NodeClass {
216228
* @param {MmlNode[]} children The initial child nodes (more can be added later)
217229
*/
218230
new (factory: MmlFactory, attributes?: PropertyList, children?: MmlNode[]): MmlNode;
231+
219232
}
220233

221234

@@ -237,6 +250,7 @@ export abstract class AbstractMmlNode extends AbstractNode implements MmlNode {
237250
// scale all spaces, fractions, etc.
238251
dir: INHERIT
239252
};
253+
240254
/**
241255
* This lists properties that do NOT get inherited between specific kinds
242256
* of nodes. The outer keys are the node kinds that are being inherited FROM,
@@ -285,6 +299,7 @@ export abstract class AbstractMmlNode extends AbstractNode implements MmlNode {
285299
* The TeX class for the preceding node
286300
*/
287301
public prevClass: number = null;
302+
288303
/**
289304
* The scriptlevel of the preceding node
290305
*/
@@ -299,10 +314,12 @@ export abstract class AbstractMmlNode extends AbstractNode implements MmlNode {
299314
* Child nodes are MmlNodes (special case of Nodes).
300315
*/
301316
public childNodes: MmlNode[];
317+
302318
/**
303319
* The parent is an MmlNode
304320
*/
305321
public parent: MmlNode;
322+
306323
/**
307324
* The node factory is an MmlFactory
308325
*/
@@ -335,6 +352,40 @@ export abstract class AbstractMmlNode extends AbstractNode implements MmlNode {
335352
this.attributes.setList(attributes);
336353
}
337354

355+
/**
356+
* @override
357+
*
358+
* @param {boolean} keepIds True to copy id attributes, false to skip them.
359+
* (May cause error in the future, since not part of the interface.)
360+
* @return {AbstractMmlNode} The copied node tree.
361+
*/
362+
public copy(keepIds: boolean = false): AbstractMmlNode {
363+
const node = this.factory.create(this.kind) as AbstractMmlNode;
364+
node.properties = {...this.properties};
365+
if (this.attributes) {
366+
const attributes = this.attributes.getAllAttributes();
367+
for (const name of Object.keys(attributes)) {
368+
if (name !== 'id' || keepIds) {
369+
node.attributes.set(name, attributes[name]);
370+
}
371+
}
372+
}
373+
if (this.childNodes && this.childNodes.length) {
374+
let children = this.childNodes as MmlNode[];
375+
if (children.length === 1 && children[0].isInferred) {
376+
children = children[0].childNodes as MmlNode[];
377+
}
378+
for (const child of children) {
379+
if (child) {
380+
node.appendChild(child.copy() as MmlNode);
381+
} else {
382+
node.childNodes.push(null);
383+
}
384+
}
385+
}
386+
return node;
387+
}
388+
338389
/**
339390
* The TeX class for this node
340391
*/
@@ -1176,6 +1227,13 @@ export class TextNode extends AbstractMmlEmptyNode {
11761227
return this;
11771228
}
11781229

1230+
/**
1231+
* @override
1232+
*/
1233+
public copy() {
1234+
return (this.factory.create(this.kind) as TextNode).setText(this.getText());
1235+
}
1236+
11791237
/**
11801238
* Just use the text
11811239
*/
@@ -1234,6 +1292,13 @@ export class XMLNode extends AbstractMmlEmptyNode {
12341292
return this.adaptor.serializeXML(this.xml);
12351293
}
12361294

1295+
/**
1296+
* @override
1297+
*/
1298+
public copy(): XMLNode {
1299+
return (this.factory.create(this.kind) as XMLNode).setXML(this.adaptor.clone(this.xml));
1300+
}
1301+
12371302
/**
12381303
* Just indicate that this is XML data
12391304
*/

ts/core/Tree/Node.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ export interface Node {
102102
*/
103103
childIndex(child: Node): number;
104104

105+
/**
106+
* Make a deep copy of the node (but with no parent).
107+
*/
108+
copy(): Node;
109+
105110
/**
106111
* @param {string} kind The kind of nodes to be located in the tree
107112
* @return {Node[]} An array of nodes that are children (at any depth) of the given kind
@@ -264,6 +269,20 @@ export abstract class AbstractNode implements Node {
264269
}
265270

266271

272+
/**
273+
* @override
274+
*/
275+
public copy() {
276+
const node = (this as AbstractNode).factory.create(this.kind) as AbstractNode;
277+
node.properties = {...this.properties};
278+
for (const child of this.childNodes || []) {
279+
if (child) {
280+
node.appendChild(child.copy());
281+
}
282+
}
283+
return node;
284+
}
285+
267286
/**
268287
* @override
269288
*/

0 commit comments

Comments
 (0)