// Copyright 2017-2022 The MathJax Consortium
// SPDX-License-Identifier: Apache-2.0
// Go translation of MathJax 3.2.2 ParseUtil.internalMath/internalText and HBox.

package tex

import (
	
	

	
)

func ( *parser) (,  string,  bool) ([]*mml.Node, error) {
	, ,  := .readArgument(, false)
	if  != nil {
		return nil, 
	}
	return .internalMath(, , )
}

// internalMath scans only the delimiters and escapes recognized by the source
// helper. Commands in literal text are not parsed as TeX, except ref/eqref.
func ( *parser) (,  string,  bool) ([]*mml.Node, error) {
	if  == "" {
		 = .activeFont
	}
	var  []*mml.Node
	, ,  := 0, 0, 0
	var  byte
	 := func( int) {
		if  <  {
			 = append(, internalText([:], ))
		}
	}
	 := func( int,  bool) error {
		,  := .parseInternalMath([:])
		if  != nil {
			return 
		}
		 := texAtom(, mml.TeXClassOrd)
		if  &&  != "" {
			.Attributes.Set("mathvariant", )
		}
		 = append(, )
		return nil
	}
	for  < len() {
		 := []
		++
		switch  {
		case '$':
			if  == '$' &&  == 0 {
				if  := (-1, false);  != nil {
					return nil, 
				}
				,  = 0, 
			} else if  == 0 {
				( - 1)
				,  = '$', 
			}
		case '{':
			if  != 0 {
				++
			}
		case '}':
			if  == '}' &&  == 0 {
				if  := (, true);  != nil {
					return nil, 
				}
				,  = 0, 
			} else if  != 0 &&  > 0 {
				--
			}
		case '\\':
			if  := internalReferencePrefix([:]);  == 0 &&  > 0 {
				( - 1)
				,  = '}', -1
				 += 
				continue
			}
			if  == len() {
				continue
			}
			 = []
			++
			if  == '(' &&  == 0 {
				( - 2)
				,  = ')', 
			} else if  == ')' &&  == ')' &&  == 0 {
				if  := (-2, false);  != nil {
					return nil, 
				}
				,  = 0, 
			} else if  == 0 && strings.ContainsRune("${}\\", rune()) {
				--
				 = [:-1] + [:]
			}
		}
	}
	if  != 0 {
		return nil, texError("MathNotTerminated", "Math not terminated in text box")
	}
	(len())
	if  {
		 := node("mstyle", ...)
		.Attributes.Set("displaystyle", false)
		.Attributes.Set("scriptlevel", 0)
		return []*mml.Node{}, nil
	}
	if len() > 1 {
		return []*mml.Node{node("mrow", ...)}, nil
	}
	return , nil
}

func internalText(,  string) *mml.Node {
	if  := strings.TrimLeftFunc(, internalTextSpace);  !=  {
		 = "\u00a0" + 
	}
	if  := strings.TrimRightFunc(, internalTextSpace);  !=  {
		 =  + "\u00a0"
	}
	 := node("mtext", mml.NewText())
	if  != "" {
		.Attributes.Set("mathvariant", )
	}
	return 
}

func internalReferencePrefix( string) int {
	 := 0
	if strings.HasPrefix(, "eqref") {
		 = 5
	} else if strings.HasPrefix(, "ref") {
		 = 3
	} else {
		return 0
	}
	for  < len() {
		,  := utf8.DecodeRuneInString([:])
		if !internalTextSpace() {
			break
		}
		 += 
	}
	if  < len() && [] == '{' {
		return  + 1
	}
	return 0
}

// JavaScript whitespace includes BOM and excludes NEL.
func internalTextSpace( rune) bool {
	return  >= '\t' &&  <= '\r' ||  == ' ' ||  == 0xa0 ||  == 0x1680 ||
		 >= 0x2000 &&  <= 0x200a ||  == 0x2028 ||  == 0x2029 ||
		 == 0x202f ||  == 0x205f ||  == 0x3000 ||  == 0xfeff
}

func ( *parser) ( string) (*mml.Node, error) {
	// The configuration (macros, tags, colors and token factory) is shared,
	// while the source's fresh TexParser has an empty lexical environment and
	// its own expansion count. Nested parsing is synchronous; restore the
	// caller's counter even when the inner parser reports an error.
	 := .state.macroCount
	.state.macroCount = 0
	defer func() { .state.macroCount =  }()
	 := &parser{source: , state: .state, vectorFactory: .vectorFactory,
		genfracPalette: .genfracPalette, derivativeChildren: .derivativeChildren}
	, ,  := .parseRow(0, false)
	if  != nil {
		return nil, 
	}
	 := row(, true)
	// A deferred enclosing font walk must respect the choices already made
	// in this empty environment, including a token's default variant.
	.Walk(func( *mml.Node) bool {
		if .Flags.Token {
			.SetProperty(resolvedFontScope, true)
		}
		return true
	})
	return , nil
}