MmlVisitor.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /*************************************************************
  2. *
  3. * Copyright (c) 2019-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 A visitor to serialize MathML taking menu settings into account
  19. *
  20. * @author dpvc@mathjax.org (Davide Cervone)
  21. */
  22. import {MathItem} from '../../core/MathItem.js';
  23. import {MmlNode} from '../../core/MmlTree/MmlNode.js';
  24. import {SerializedMmlVisitor} from '../../core/MmlTree/SerializedMmlVisitor.js';
  25. import {OptionList, userOptions} from '../../util/Options.js';
  26. /*==========================================================================*/
  27. /**
  28. * The visitor to serialize MathML
  29. *
  30. * @template N The HTMLElement node class
  31. * @template T The Text node class
  32. * @template D The Document class
  33. */
  34. export class MmlVisitor<N, T, D> extends SerializedMmlVisitor {
  35. /**
  36. * The options controlling the serialization
  37. */
  38. public options: OptionList = {
  39. texHints: true, // True means include classes for TeXAtom elements
  40. semantics: false, // True means include original form as annotation in a semantics element
  41. };
  42. /**
  43. * The MathItem currently being processed
  44. */
  45. public mathItem: MathItem<N, T, D> = null;
  46. /**
  47. * @param {MmlNode} node The internal MathML node to serialize
  48. * @param {MathItem} math The MathItem for this node
  49. * @param {OptionList} options The options controlling the processing
  50. * @override
  51. */
  52. public visitTree(node: MmlNode, math: MathItem<N, T, D> = null, options: OptionList = {}) {
  53. this.mathItem = math;
  54. userOptions(this.options, options);
  55. return this.visitNode(node, '');
  56. }
  57. /**
  58. * @override
  59. */
  60. public visitTeXAtomNode(node: MmlNode, space: string) {
  61. if (this.options.texHints) {
  62. return super.visitTeXAtomNode(node, space);
  63. }
  64. if (node.childNodes[0] && node.childNodes[0].childNodes.length === 1) {
  65. return this.visitNode(node.childNodes[0], space);
  66. }
  67. return space + '<mrow' + this.getAttributes(node) + '>\n'
  68. + this.childNodeMml(node, space + ' ', '\n')
  69. + space + '</mrow>';
  70. }
  71. /**
  72. * @param {MmlNode} node The math node to visit
  73. * @param {string} space The number of spaces to use for indentation
  74. * @returns {string} The serialized math element
  75. */
  76. public visitMathNode(node: MmlNode, space: string): string {
  77. if (!this.options.semantics || this.mathItem.inputJax.name !== 'TeX') {
  78. return super.visitDefault(node, space);
  79. }
  80. const addRow = node.childNodes.length && node.childNodes[0].childNodes.length > 1;
  81. return space + '<math' + this.getAttributes(node) + '>\n'
  82. + space + ' <semantics>\n'
  83. + (addRow ? space + ' <mrow>\n' : '')
  84. + this.childNodeMml(node, space + (addRow ? ' ' : ' '), '\n')
  85. + (addRow ? space + ' </mrow>\n' : '')
  86. + space + ' <annotation encoding="application/x-tex">' + this.mathItem.math + '</annotation>\n'
  87. + space + ' </semantics>\n'
  88. + space + '</math>';
  89. }
  90. }