OutputJax.ts 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  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 OutputJax
  19. *
  20. * @author dpvc@mathjax.org (Davide Cervone)
  21. */
  22. import {userOptions, defaultOptions, OptionList} from '../util/Options.js';
  23. import {MathDocument} from './MathDocument.js';
  24. import {MathItem} from './MathItem.js';
  25. import {DOMAdaptor} from '../core/DOMAdaptor.js';
  26. import {FunctionList} from '../util/FunctionList.js';
  27. /*****************************************************************/
  28. /**
  29. * The OutputJax interface
  30. *
  31. * @template N The HTMLElement node class
  32. * @template T The Text node class
  33. * @template D The Document class
  34. */
  35. export interface OutputJax<N, T, D> {
  36. /**
  37. * The name of this output jax class
  38. */
  39. name: string;
  40. /**
  41. * The options for the instance
  42. */
  43. options: OptionList;
  44. /**
  45. * Lists of post-filters to call after typesetting the math
  46. */
  47. postFilters: FunctionList;
  48. /**
  49. * The DOM adaptor for managing HTML elements
  50. */
  51. adaptor: DOMAdaptor<N, T, D>;
  52. /**
  53. * @param {DOMAdaptor} adaptor The adaptor to use in this jax
  54. */
  55. setAdaptor(adaptor: DOMAdaptor<N, T, D>): void;
  56. /**
  57. * Do any initialization that depends on the document being set up
  58. */
  59. initialize(): void;
  60. /**
  61. * Reset any needed features of the output jax
  62. *
  63. * @param {any[]} args The arguments needed by the reset operation
  64. */
  65. reset(...args: any[]): void;
  66. /**
  67. * Typset a given MathItem
  68. *
  69. * @param {MathItem} math The MathItem to be typeset
  70. * @param {MathDocument} document The MathDocument in which the typesetting should occur
  71. * @return {N} The DOM tree for the typeset math
  72. */
  73. typeset(math: MathItem<N, T, D>, document?: MathDocument<N, T, D>): N;
  74. /**
  75. * Handle an escaped character (e.g., \$ from the TeX input jax preventing it from being a delimiter)
  76. *
  77. * @param {MathItem} math The MathItem to be escaped
  78. * @param {MathDocument} document The MathDocument in which the math occurs
  79. * @return {N} The DOM tree for the escaped item
  80. */
  81. escaped(math: MathItem<N, T, D>, document?: MathDocument<N, T, D>): N;
  82. /**
  83. * Get the metric information for all math in the given document
  84. *
  85. * @param {MathDocument} document The MathDocument being processed
  86. */
  87. getMetrics(document: MathDocument<N, T, D>): void;
  88. /**
  89. * Produce the stylesheet needed for this output jax
  90. *
  91. * @param {MathDocument} document The MathDocument being processed
  92. */
  93. styleSheet(document: MathDocument<N, T, D>): N;
  94. /**
  95. * Produce any page-specific elements needed for this output jax
  96. *
  97. * @param {MathDocument} document The MathDocument being processed
  98. */
  99. pageElements(document: MathDocument<N, T, D>): N;
  100. }
  101. /*****************************************************************/
  102. /**
  103. * The OutputJax abstract class
  104. *
  105. * @template N The HTMLElement node class
  106. * @template T The Text node class
  107. * @template D The Document class
  108. */
  109. export abstract class AbstractOutputJax<N, T, D> implements OutputJax<N, T, D> {
  110. /**
  111. * The name for the output jax
  112. */
  113. public static NAME: string = 'generic';
  114. /**
  115. * The default options for the output jax
  116. */
  117. public static OPTIONS: OptionList = {};
  118. /**
  119. * The actual options supplied to the output jax
  120. */
  121. public options: OptionList;
  122. /**
  123. * Filters to run after the output is processed
  124. */
  125. public postFilters: FunctionList;
  126. /**
  127. * The MathDocument's DOMAdaptor
  128. */
  129. public adaptor: DOMAdaptor<N, T, D> = null; // set by the handler
  130. /**
  131. * @param {OptionList} options The options for this instance
  132. */
  133. constructor(options: OptionList = {}) {
  134. let CLASS = this.constructor as typeof AbstractOutputJax;
  135. this.options = userOptions(defaultOptions({}, CLASS.OPTIONS), options);
  136. this.postFilters = new FunctionList();
  137. }
  138. /**
  139. * @return {string} The name for this output jax class
  140. */
  141. public get name(): string {
  142. return (this.constructor as typeof AbstractOutputJax).NAME;
  143. }
  144. /**
  145. * @override
  146. */
  147. public setAdaptor(adaptor: DOMAdaptor<N, T, D>) {
  148. this.adaptor = adaptor;
  149. }
  150. /**
  151. * @override
  152. */
  153. public initialize() {
  154. }
  155. /**
  156. * @override
  157. */
  158. public reset(..._args: any[]) {
  159. }
  160. /**
  161. * @override
  162. */
  163. public abstract typeset(math: MathItem<N, T, D>, document?: MathDocument<N, T, D>): N;
  164. /**
  165. * @override
  166. */
  167. public abstract escaped(math: MathItem<N, T, D>, document?: MathDocument<N, T, D>): N;
  168. /**
  169. * @override
  170. */
  171. public getMetrics(_document: MathDocument<N, T, D>) {
  172. }
  173. /**
  174. * @override
  175. */
  176. public styleSheet(_document: MathDocument<N, T, D>) {
  177. return null as N;
  178. }
  179. /**
  180. * @override
  181. */
  182. public pageElements(_document: MathDocument<N, T, D>) {
  183. return null as N;
  184. }
  185. /**
  186. * Execute a set of filters, passing them the MathItem and any needed data,
  187. * and return the (possibly modified) data
  188. *
  189. * @param {FunctionList} filters The list of functions to be performed
  190. * @param {MathItem} math The math item that is being processed
  191. * @param {MathDocument} document The math document contaiing the math item
  192. * @param {any} data Whatever other data is needed
  193. * @return {any} The (possibly modified) data
  194. */
  195. protected executeFilters(
  196. filters: FunctionList, math: MathItem<N, T, D>,
  197. document: MathDocument<N, T, D>, data: any
  198. ): any {
  199. let args = {math, document, data};
  200. filters.execute(args);
  201. return args.data;
  202. }
  203. }