@@ -87,6 +87,7 @@ export type MMLNODE = MmlNode | TextNode | XMLNode;
8787 */
8888
8989export 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
203213export 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 */
@@ -330,6 +347,36 @@ export abstract class AbstractMmlNode extends AbstractNode implements MmlNode {
330347 this . attributes . setList ( attributes ) ;
331348 }
332349
350+ /**
351+ * @override
352+ *
353+ * @param {boolean } keepIds True to copy id attributes, false to skip them.
354+ */
355+ public copy ( keepIds : boolean = false ) : AbstractMmlNode {
356+ const node = this . factory . create ( this . kind ) as AbstractMmlNode ;
357+ node . properties = { ...this . properties } ;
358+ if ( this . attributes ) {
359+ const attributes = this . attributes . getAllAttributes ( ) ;
360+ for ( const name of Object . keys ( attributes ) ) {
361+ if ( name !== 'id' || keepIds ) {
362+ node . attributes . set ( name , attributes [ name ] ) ;
363+ }
364+ }
365+ }
366+ if ( this . childNodes && this . childNodes . length ) {
367+ let children = this . childNodes as MmlNode [ ] ;
368+ if ( children . length === 1 && children [ 0 ] . isInferred ) {
369+ children = children [ 0 ] . childNodes as MmlNode [ ] ;
370+ }
371+ for ( const child of children ) {
372+ if ( child ) {
373+ node . appendChild ( child . copy ( ) as MmlNode ) ;
374+ }
375+ }
376+ }
377+ return node ;
378+ }
379+
333380 /**
334381 * The TeX class for this node
335382 */
@@ -1150,6 +1197,13 @@ export class TextNode extends AbstractMmlEmptyNode {
11501197 return this ;
11511198 }
11521199
1200+ /**
1201+ * @override
1202+ */
1203+ public copy ( ) {
1204+ return ( this . factory . create ( this . kind ) as TextNode ) . setText ( this . getText ( ) ) ;
1205+ }
1206+
11531207 /**
11541208 * Just use the text
11551209 */
@@ -1208,6 +1262,13 @@ export class XMLNode extends AbstractMmlEmptyNode {
12081262 return this . adaptor . outerHTML ( this . xml ) ;
12091263 }
12101264
1265+ /**
1266+ * @override
1267+ */
1268+ public copy ( ) : XMLNode {
1269+ return ( this . factory . create ( this . kind ) as XMLNode ) . setXML ( this . adaptor . clone ( this . xml ) ) ;
1270+ }
1271+
12111272 /**
12121273 * Just indicate that this is XML data
12131274 */
0 commit comments