MCPcopy Create free account
hub / github.com/KaTeX/KaTeX / buildExpression

Function buildExpression

src/buildMathML.ts:168–238  ·  view source on GitHub ↗
(
    expression: AnyParseNode[],
    options: Options,
    isOrdgroup?: boolean,
)

Source from the content-addressed store, hash-verified

166 * <mtext> tag.
167 */
168export const buildExpression = function(
169 expression: AnyParseNode[],
170 options: Options,
171 isOrdgroup?: boolean,
172): MathNode[] {
173 if (expression.length === 1) {
174 const group = buildGroup(expression[0], options);
175 if (isOrdgroup && group instanceof MathNode && group.type === "mo") {
176 // When TeX writers want to suppress spacing on an operator,
177 // they often put the operator by itself inside braces.
178 group.setAttribute("lspace", "0em");
179 group.setAttribute("rspace", "0em");
180 }
181 return [group];
182 }
183
184 const groups = [];
185 let lastGroup;
186 for (let i = 0; i < expression.length; i++) {
187 const group = buildGroup(expression[i], options);
188 if (group instanceof MathNode && lastGroup instanceof MathNode) {
189 // Concatenate adjacent <mtext>s
190 if (group.type === 'mtext' && lastGroup.type === 'mtext'
191 && group.getAttribute('mathvariant') ===
192 lastGroup.getAttribute('mathvariant')) {
193 lastGroup.children.push(...group.children);
194 continue;
195 // Concatenate adjacent <mn>s
196 } else if (group.type === 'mn' && lastGroup.type === 'mn') {
197 lastGroup.children.push(...group.children);
198 continue;
199 // Concatenate <mn>...</mn> followed by <mi>.</mi>
200 } else if (isNumberPunctuation(group) && lastGroup.type === 'mn') {
201 lastGroup.children.push(...group.children);
202 continue;
203 // Concatenate <mi>.</mi> followed by <mn>...</mn>
204 } else if (group.type === 'mn' && isNumberPunctuation(lastGroup)) {
205 group.children = [...lastGroup.children, ...group.children];
206 groups.pop();
207 // Put preceding <mn>...</mn> or <mi>.</mi> inside base of
208 // <msup><mn>...base...</mn>...exponent...</msup> (or <msub>)
209 } else if ((group.type === 'msup' || group.type === 'msub') &&
210 group.children.length >= 1 &&
211 (lastGroup.type === 'mn' || isNumberPunctuation(lastGroup))
212 ) {
213 const base = group.children[0];
214 if (base instanceof MathNode && base.type === 'mn') {
215 base.children = [...lastGroup.children, ...base.children];
216 groups.pop();
217 }
218 // \not
219 } else if (lastGroup.type === 'mi' && lastGroup.children.length === 1) {
220 const lastChild = lastGroup.children[0];
221 if (lastChild instanceof TextNode && lastChild.text === '\u0338' &&
222 (group.type === 'mo' || group.type === 'mi' ||
223 group.type === 'mn')) {
224 const child = group.children[0];
225 if (child instanceof TextNode && child.text.length > 0) {

Callers 2

buildExpressionRowFunction · 0.70
buildMathMLFunction · 0.70

Calls 4

isNumberPunctuationFunction · 0.85
getAttributeMethod · 0.80
buildGroupFunction · 0.70
setAttributeMethod · 0.45

Tested by

no test coverage detected