// Copyright (c) 2009-2022 The MathJax Consortium // SPDX-License-Identifier: Apache-2.0 // Sources: FilterUtil.cleanSubSup, ParseOptions.getList/inTree, // ParseUtil.copyNode and NodeUtil.copyAttributes (MathJax 3.2.2).
package tex import ( ) // Only actual SubsupItem Pop delivery publishes an unfinished generic node. // Keep the diagnostic pendingBase views read-only. The private origin marker // follows ParseUtil.copyNode's cloned registrations, including later pruning. const poppedScriptOrigin = "poppedScriptOrigin" func ( *parser) ( *scriptAttachment) *mml.Node { := .pendingBase() .Properties = .Properties.Clone() .SetProperty(poppedScriptOrigin, true) .Children = append([]*mml.Node(nil), .Children...) .SetChildren(.Children) .notePoppedScript() return } func ( *parser) ( *mml.Node) { if , := .Property(poppedScriptOrigin); == true { .state.poppedScripts = append(.state.poppedScripts, ) } } // This is the source parent-chain predicate, not a traversal-membership test. // Discarded AutoOpen contents must not be validated just because they were // once registered; their unfinished nodes are no longer live in this root. func scriptInTree(, *mml.Node) bool { for != nil && != { = .Parent } return != nil } func cleanPoppedScripts( *mml.Node, []*mml.Node) (*mml.Node, error) { for , := range []struct{ , , string }{ {"msubsup", "msub", "msup"}, {"munderover", "munder", "mover"}, } { for , := range { if .Kind != . || !scriptInTree(, ) { continue } var , *mml.Node if len(.Children) > 1 { = .Children[1] } if len(.Children) > 2 { = .Children[2] } if != nil && != nil { continue } if == nil && == nil { // The original fixed-arity constructor throws here. Preserve // its post-successful-parse timing as a bounded API error. return nil, fmt.Errorf("incomplete %s has no script child", .Kind) } , := ., if == nil { , = ., } := .Parent := node(, .Children[0], ) .Attributes = .Attributes .Properties = .Properties.Clone() if , := .Property("texClass"); { if , := sourceInt(); { .TeXClass = mml.TeXClass() } } if == nil { = } else if := .ReplaceChild(, ); != nil { return nil, } } } return , nil }