ParseMethods.ts 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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 Base methods for TeX Parsing.
  19. *
  20. * @author v.sorge@mathjax.org (Volker Sorge)
  21. */
  22. import {Symbol} from './Symbol.js';
  23. import TexParser from './TexParser.js';
  24. import NodeUtil from './NodeUtil.js';
  25. import {TexConstant} from './TexConstants.js';
  26. import {MmlNode} from '../../core/MmlTree/MmlNode.js';
  27. import ParseUtil from './ParseUtil.js';
  28. namespace ParseMethods {
  29. /**
  30. * Handle a variable (a single letter or multi-letter if allowed).
  31. * @param {TexParser} parser The current tex parser.
  32. * @param {string} c The letter to transform into an mi.
  33. */
  34. export function variable(parser: TexParser, c: string) {
  35. // @test Identifier Font
  36. const def = ParseUtil.getFontDef(parser);
  37. const env = parser.stack.env;
  38. if (env.multiLetterIdentifiers && env.font !== '') {
  39. c = parser.string.substr(parser.i - 1).match(env.multiLetterIdentifiers as any as RegExp)[0];
  40. parser.i += c.length - 1;
  41. if (def.mathvariant === TexConstant.Variant.NORMAL && env.noAutoOP && c.length > 1) {
  42. def.autoOP = false;
  43. }
  44. }
  45. // @test Identifier
  46. const node = parser.create('token', 'mi', def, c);
  47. parser.Push(node);
  48. }
  49. /**
  50. * Handle a number (a sequence of digits, with decimal separator, etc.).
  51. * @param {TexParser} parser The current tex parser.
  52. * @param {string} c The first character of a number than can be parsed with
  53. * the digits pattern.
  54. */
  55. export function digit(parser: TexParser, c: string) {
  56. let mml: MmlNode;
  57. const pattern = parser.configuration.options['digits'];
  58. const n = parser.string.slice(parser.i - 1).match(pattern);
  59. // @test Integer Font
  60. const def = ParseUtil.getFontDef(parser);
  61. if (n) {
  62. // @test Integer, Number, Decimal (European)
  63. mml = parser.create('token', 'mn', def, n[0].replace(/[{}]/g, ''));
  64. parser.i += n[0].length - 1;
  65. } else {
  66. // @test Decimal Point, Decimal Point European
  67. mml = parser.create('token', 'mo', def, c);
  68. }
  69. parser.Push(mml);
  70. }
  71. /**
  72. * Lookup a control-sequence and process it.
  73. * @param {TexParser} parser The current tex parser.
  74. * @param {string} c The string '\'.
  75. */
  76. export function controlSequence(parser: TexParser, _c: string) {
  77. const name = parser.GetCS();
  78. parser.parse('macro', [parser, name]);
  79. }
  80. /**
  81. * Handle normal mathchar (as an mi).
  82. * @param {TexParser} parser The current tex parser.
  83. * @param {Symbol} mchar The parsed symbol.
  84. */
  85. export function mathchar0mi(parser: TexParser, mchar: Symbol) {
  86. const def = mchar.attributes || {mathvariant: TexConstant.Variant.ITALIC};
  87. // @test Greek
  88. const node = parser.create('token', 'mi', def, mchar.char);
  89. parser.Push(node);
  90. }
  91. /**
  92. * Handle normal mathchar (as an mo).
  93. * @param {TexParser} parser The current tex parser.
  94. * @param {Symbol} mchar The parsed symbol.
  95. */
  96. export function mathchar0mo(parser: TexParser, mchar: Symbol) {
  97. const def = mchar.attributes || {};
  98. def['stretchy'] = false;
  99. // @test Large Set
  100. const node = parser.create('token', 'mo', def, mchar.char);
  101. NodeUtil.setProperty(node, 'fixStretchy', true);
  102. parser.configuration.addNode('fixStretchy', node);
  103. // PROBLEM: Attributes stop working when Char7 are explicitly set.
  104. parser.Push(node);
  105. }
  106. /**
  107. * Handle mathchar in current family.
  108. * @param {TexParser} parser The current tex parser.
  109. * @param {Symbol} mchar The parsed symbol.
  110. */
  111. export function mathchar7(parser: TexParser, mchar: Symbol) {
  112. const def = mchar.attributes || {mathvariant: TexConstant.Variant.NORMAL};
  113. if (parser.stack.env['font']) {
  114. // @test MathChar7 Single Font
  115. def['mathvariant'] = parser.stack.env['font'];
  116. }
  117. // @test MathChar7 Single, MathChar7 Operator, MathChar7 Multi
  118. const node = parser.create('token', 'mi', def, mchar.char);
  119. parser.Push(node);
  120. }
  121. /**
  122. * Handle delimiter.
  123. * @param {TexParser} parser The current tex parser.
  124. * @param {Symbol} delim The parsed delimiter symbol.
  125. */
  126. export function delimiter(parser: TexParser, delim: Symbol) {
  127. let def = delim.attributes || {};
  128. // @test Fenced2, Delimiter (AMS)
  129. def = Object.assign({fence: false, stretchy: false}, def);
  130. const node = parser.create('token', 'mo', def, delim.char);
  131. parser.Push(node);
  132. }
  133. /**
  134. * Parse an environment.
  135. * @param {TexParser} parser The current tex parser.
  136. * @param {string} env The name of the environment.
  137. * @param {Function} func The parse method for the environment.
  138. * @param {any[]} args A list of additional arguments.
  139. */
  140. export function environment(parser: TexParser, env: string, func: Function, args: any[]) {
  141. const end = args[0];
  142. let mml = parser.itemFactory.create('begin').setProperties({name: env, end: end});
  143. mml = func(parser, mml, ...args.slice(1));
  144. parser.Push(mml);
  145. }
  146. }
  147. export default ParseMethods;