NodeFactory.ts 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*************************************************************
  2. *
  3. * Copyright (c) 2009-2022 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. * @fileoverview Node factory for creating MmlNodes. This allows extension
  19. * packages to add node constructors or overwrite existing ones.
  20. *
  21. * @author v.sorge@mathjax.org (Volker Sorge)
  22. */
  23. import {TextNode, MmlNode} from '../../core/MmlTree/MmlNode.js';
  24. import {MmlFactory} from '../../core/MmlTree/MmlFactory.js';
  25. import ParseOptions from './ParseOptions.js';
  26. import NodeUtil from './NodeUtil.js';
  27. export type NodeFactoryMethod = (factory: NodeFactory, kind: string, ...rest: any[]) => MmlNode;
  28. export class NodeFactory {
  29. /**
  30. * Parser configuration that can be used to pass information between node methods.
  31. * @type {ParseOption}
  32. */
  33. public configuration: ParseOptions;
  34. /**
  35. * The external node factory.
  36. * @type {MmlFactory}
  37. */
  38. protected mmlFactory: MmlFactory = null;
  39. /**
  40. * The factory table populated with some default methods.
  41. */
  42. private factory: {[kind: string]: NodeFactoryMethod} =
  43. {'node': NodeFactory.createNode,
  44. 'token': NodeFactory.createToken,
  45. 'text': NodeFactory.createText,
  46. 'error': NodeFactory.createError
  47. };
  48. /**
  49. * Default node generation function.
  50. * @param {NodeFactory} factory The current node factory.
  51. * @param {string} kind The type of node to create.
  52. * @param {MmlNode[]} children Its children.
  53. * @param {any=} def Its properties.
  54. * @param {TextNode=} text An optional text node if this is a token.
  55. * @return {MmlNode} The newly created Mml node.
  56. */
  57. public static createNode(factory: NodeFactory, kind: string,
  58. children: MmlNode[] = [], def: any = {},
  59. text?: TextNode): MmlNode {
  60. const node = factory.mmlFactory.create(kind);
  61. node.setChildren(children);
  62. if (text) {
  63. node.appendChild(text);
  64. }
  65. NodeUtil.setProperties(node, def);
  66. return node;
  67. }
  68. /**
  69. * Default token generation function.
  70. * @param {NodeFactory} factory The current node factory.
  71. * @param {string} kind The type of node to create.
  72. * @param {any} def Its properties.
  73. * @param {string} text Text of the token.
  74. * @return {MmlNode} The newly created token node.
  75. */
  76. public static createToken(factory: NodeFactory, kind: string,
  77. def: any = {}, text: string = ''): MmlNode {
  78. const textNode = factory.create('text', text);
  79. return factory.create('node', kind, [], def, textNode);
  80. }
  81. /**
  82. * Default text node generation function.
  83. * @param {NodeFactory} factory The current node factory.
  84. * @param {string} text The text for the new node.
  85. * @return {TextNode} The newly created text node.
  86. */
  87. public static createText(factory: NodeFactory, text: string): TextNode {
  88. if (text == null) {
  89. return null;
  90. }
  91. return (factory.mmlFactory.create('text') as TextNode).setText(text);
  92. }
  93. /**
  94. * Default error node generation function.
  95. * @param {NodeFactory} factory The current node factory.
  96. * @param {string} message The error message.
  97. * @return {MmlNode} The newly created error node.
  98. */
  99. public static createError(factory: NodeFactory, message: string): MmlNode {
  100. let text = factory.create('text', message);
  101. let mtext = factory.create('node', 'mtext', [], {}, text);
  102. let error = factory.create('node', 'merror', [mtext], {'data-mjx-error': message});
  103. return error;
  104. }
  105. /**
  106. * @param {MmlFactory} mmlFactory The MmlFactory for the TeX jax to use
  107. */
  108. public setMmlFactory(mmlFactory: MmlFactory) {
  109. this.mmlFactory = mmlFactory;
  110. }
  111. /**
  112. * Adds a method to the factory.
  113. * @param {string} kind The type of node the method creates.
  114. * @param {NodeFactoryMethod} func The node creator.
  115. */
  116. public set(kind: string, func: NodeFactoryMethod) {
  117. this.factory[kind] = func;
  118. }
  119. /**
  120. * Adds a set of node creators to the factory.
  121. * @param {Object.<NodeFactoryMethod>} maps The set of functions.
  122. */
  123. public setCreators(maps: {[kind: string]: NodeFactoryMethod}) {
  124. for (let kind in maps) {
  125. this.set(kind, maps[kind]);
  126. }
  127. }
  128. /**
  129. * Creates a node for the internal data structure from the factory.
  130. * @param {string} kind The type of node to be created.
  131. * @param {any[]} ...rest The arguments for the node.
  132. * @return {MmlNode} The created node.
  133. */
  134. public create(kind: string, ...rest: any[]): MmlNode {
  135. const func = this.factory[kind] || this.factory['node'];
  136. const node = func(this, rest[0], ...rest.slice(1));
  137. if (kind === 'node') {
  138. this.configuration.addNode(rest[0], node);
  139. }
  140. return node;
  141. }
  142. /**
  143. * @param {string} kind The method for generating a node of given kind.
  144. */
  145. public get(kind: string) {
  146. return this.factory[kind];
  147. }
  148. }