InputJax.ts 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. /*************************************************************
  2. *
  3. * Copyright (c) 2017-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 Implements the interface and abstract class for the InputJax
  19. *
  20. * @author dpvc@mathjax.org (Davide Cervone)
  21. */
  22. import {MathDocument} from './MathDocument.js';
  23. import {MathItem, ProtoItem} from './MathItem.js';
  24. import {MmlNode} from './MmlTree/MmlNode.js';
  25. import {MmlFactory} from './MmlTree/MmlFactory.js';
  26. import {userOptions, defaultOptions, OptionList} from '../util/Options.js';
  27. import {FunctionList} from '../util/FunctionList.js';
  28. import {DOMAdaptor} from '../core/DOMAdaptor.js';
  29. /*****************************************************************/
  30. /**
  31. * The InputJax interface
  32. *
  33. * @template N The HTMLElement node class
  34. * @template T The Text node class
  35. * @template D The Document class
  36. */
  37. export interface InputJax<N, T, D> {
  38. /**
  39. * The name of the input jax subclass (e.g,. 'TeX')
  40. */
  41. name: string;
  42. /**
  43. * Whether this input jax processes string arrays or DOM nodes
  44. * (TeX and AsciiMath process strings, MathML processes DOM nodes)
  45. */
  46. processStrings: boolean;
  47. /**
  48. * The options for this input jax instance
  49. */
  50. options: OptionList;
  51. /**
  52. * Lists of pre- and post-filters to call before and after processing the input
  53. */
  54. preFilters: FunctionList;
  55. postFilters: FunctionList;
  56. /**
  57. * The DOM adaptor for managing HTML elements
  58. */
  59. adaptor: DOMAdaptor<N, T, D>;
  60. /**
  61. * The MmlFactory for this input jax
  62. */
  63. mmlFactory: MmlFactory;
  64. /**
  65. * @param {DOMAdaptor} adaptor The adaptor to use in this jax
  66. */
  67. setAdaptor(adaptor: DOMAdaptor<N, T, D>): void;
  68. /**
  69. * @param {MmlFactory} mmlFactory The MmlFactory to use in this jax
  70. */
  71. setMmlFactory(mmlFactory: MmlFactory): void;
  72. /**
  73. * Do any initialization that depends on the document being set up
  74. */
  75. initialize(): void;
  76. /**
  77. * Reset any needed features of the input jax
  78. *
  79. * @param {any[]} args The arguments needed by the reset operation
  80. */
  81. reset(...args: any[]): void;
  82. /**
  83. * Finds the math within the DOM or the list of strings
  84. *
  85. * @param {N | string[]} which The element or array of strings to be searched for math
  86. * @param {OptionList} options The options for the search, if any
  87. * @return {ProtoItem[]} Array of proto math items found (further processed by the
  88. * handler to produce actual MathItem objects)
  89. */
  90. findMath(which: N | string[], options?: OptionList): ProtoItem<N, T>[];
  91. /**
  92. * Convert the math in a math item into the internal format
  93. *
  94. * @param {MathItem} math The MathItem whose math content is to processed
  95. * @param {MathDocument} document The MathDocument for this input jax.
  96. * @return {MmlNode} The resulting internal node tree for the math
  97. */
  98. compile(math: MathItem<N, T, D>, document: MathDocument<N, T, D>): MmlNode;
  99. }
  100. /*****************************************************************/
  101. /**
  102. * The abstract InputJax class
  103. *
  104. * @template N The HTMLElement node class
  105. * @template T The Text node class
  106. * @template D The Document class
  107. */
  108. export abstract class AbstractInputJax<N, T, D> implements InputJax<N, T, D> {
  109. /**
  110. * The name of the input jax
  111. */
  112. public static NAME: string = 'generic';
  113. /**
  114. * The default options for the input jax
  115. */
  116. public static OPTIONS: OptionList = {};
  117. /**
  118. * The actual options supplied to the input jax
  119. */
  120. public options: OptionList;
  121. /**
  122. * Filters to run on the TeX string before it is processed
  123. */
  124. public preFilters: FunctionList;
  125. /**
  126. * Filters to run on the generated MathML after the TeX string is processed
  127. */
  128. public postFilters: FunctionList;
  129. /**
  130. * The DOMAdaptor for the MathDocument for this input jax
  131. */
  132. public adaptor: DOMAdaptor<N, T, D> = null; // set by the handler
  133. /**
  134. * The MathML node factory
  135. */
  136. public mmlFactory: MmlFactory = null; // set by the handler
  137. /**
  138. * @param {OptionList} options The options to apply to this input jax
  139. *
  140. * @constructor
  141. */
  142. constructor(options: OptionList = {}) {
  143. let CLASS = this.constructor as typeof AbstractInputJax;
  144. this.options = userOptions(defaultOptions({}, CLASS.OPTIONS), options);
  145. this.preFilters = new FunctionList();
  146. this.postFilters = new FunctionList();
  147. }
  148. /**
  149. * @return {string} The name of this input jax class
  150. */
  151. public get name(): string {
  152. return (this.constructor as typeof AbstractInputJax).NAME;
  153. }
  154. /**
  155. * @override
  156. */
  157. public setAdaptor(adaptor: DOMAdaptor<N, T, D>) {
  158. this.adaptor = adaptor;
  159. }
  160. /**
  161. * @override
  162. */
  163. public setMmlFactory(mmlFactory: MmlFactory) {
  164. this.mmlFactory = mmlFactory;
  165. }
  166. /**
  167. * @override
  168. */
  169. public initialize() {
  170. }
  171. /**
  172. * @override
  173. */
  174. public reset(..._args: any[]) {
  175. }
  176. /**
  177. * @return {boolean} True means find math in string array, false means in DOM element
  178. */
  179. public get processStrings(): boolean {
  180. return true;
  181. }
  182. /**
  183. * @override
  184. */
  185. public findMath(_node: N | string[], _options?: OptionList) {
  186. return [] as ProtoItem<N, T>[];
  187. }
  188. /**
  189. * @override
  190. */
  191. public abstract compile(math: MathItem<N, T, D>, document: MathDocument<N, T, D>): MmlNode;
  192. /**
  193. * Execute a set of filters, passing them the MathItem and any needed data,
  194. * and return the (possibly modified) data
  195. *
  196. * @param {FunctionList} filters The list of functions to be performed
  197. * @param {MathItem} math The math item that is being processed
  198. * @param {MathDocument} document The math document containg the math item
  199. * @param {any} data Whatever other data is needed
  200. * @return {any} The (possibly modified) data
  201. */
  202. protected executeFilters(
  203. filters: FunctionList, math: MathItem<N, T, D>,
  204. document: MathDocument<N, T, D>, data: any
  205. ): any {
  206. let args = {math: math, document: document, data: data};
  207. filters.execute(args);
  208. return args.data;
  209. }
  210. }