(
tree: AnyParseNode[],
texExpression: string,
options: Options,
isDisplayMode: boolean,
forMathmlOnly: boolean,
)
| 281 | * we can do appropriate styling. |
| 282 | */ |
| 283 | export default function buildMathML( |
| 284 | tree: AnyParseNode[], |
| 285 | texExpression: string, |
| 286 | options: Options, |
| 287 | isDisplayMode: boolean, |
| 288 | forMathmlOnly: boolean, |
| 289 | ): DomSpan { |
| 290 | const expression = buildExpression(tree, options); |
| 291 | |
| 292 | // TODO: Make a pass thru the MathML similar to buildHTML.traverseNonSpaceNodes |
| 293 | // and add spacing nodes. This is necessary only adjacent to math operators |
| 294 | // like \sin or \lim or to subsup elements that contain math operators. |
| 295 | // MathML takes care of the other spacing issues. |
| 296 | |
| 297 | // Wrap up the expression in an mrow so it is presented in the semantics |
| 298 | // tag correctly, unless it's a single <mrow> or <mtable>. |
| 299 | let wrapper; |
| 300 | if (expression.length === 1 && expression[0] instanceof MathNode && |
| 301 | rowLikeTypes.has(expression[0].type)) { |
| 302 | wrapper = expression[0]; |
| 303 | } else { |
| 304 | wrapper = new MathNode("mrow", expression); |
| 305 | } |
| 306 | |
| 307 | // Build a TeX annotation of the source |
| 308 | const annotation = new MathNode( |
| 309 | "annotation", [new TextNode(texExpression)]); |
| 310 | |
| 311 | annotation.setAttribute("encoding", "application/x-tex"); |
| 312 | |
| 313 | const semantics = new MathNode( |
| 314 | "semantics", [wrapper, annotation]); |
| 315 | |
| 316 | const math = new MathNode("math", [semantics]); |
| 317 | math.setAttribute("xmlns", "http://www.w3.org/1998/Math/MathML"); |
| 318 | if (isDisplayMode) { |
| 319 | math.setAttribute("display", "block"); |
| 320 | } |
| 321 | |
| 322 | // You can't style <math> nodes, so we wrap the node in a span. |
| 323 | // NOTE: The span class is not typed to have <math> nodes as children, and |
| 324 | // we don't want to make the children type more generic since the children |
| 325 | // of span are expected to have more fields in `buildHtml` contexts. |
| 326 | // The MathNode implements VirtualNode (toNode/toMarkup) which is all that |
| 327 | // Span needs from its children for rendering. |
| 328 | // TODO(ts): Span's child type is HtmlDomNode, but MathNode only implements |
| 329 | // VirtualNode. The double-cast acknowledges this architectural limitation. |
| 330 | const wrapperClass = forMathmlOnly ? "katex" : "katex-mathml"; |
| 331 | return makeSpan([wrapperClass], [math as unknown as HtmlDomNode]); |
| 332 | } |
no test coverage detected
searching dependent graphs…