// Copyright (c) 2018-2022 MathJax Consortium
// SPDX-License-Identifier: Apache-2.0
// This file is a Go translation and modification of MathJax 3.2.2.
//
// Source: ts/input/tex/amscd/AmsCdMethods.ts and AmsCdConfiguration.ts.

package tex

import (
	
)

const (
	amscdMinWidthState  = "\x00amscd-min-width"
	amscdMinHeightState = "\x00amscd-min-height"
)

// amscdCommand handles the two source commands that set per-parser CD arrow
// dimensions.  Values live in parseState so they persist until compilation
// ends, matching MathJax's stack environment without adding shared fields.
func ( *parser) ( string) ( []*mml.Node,  bool,  error) {
	 := ""
	switch  {
	case "minCDarrowwidth":
		 = amscdMinWidthState
	case "minCDarrowheight":
		 = amscdMinHeightState
	default:
		return nil, false, nil
	}
	,  := .readDimension()
	if  != nil {
		return nil, true, 
	}
	.state.macros[] = macroDefinition{body: }
	return nil, true, nil
}

// amscdEnvironment wraps the already source-shaped CD parser to install the
// exact package table options and arrow minsize attributes.
func ( *parser) ( string) ( []*mml.Node,  bool,  error) {
	if  != "CD" {
		return nil, false, nil
	}
	,  := .captureEnvironment()
	if  != nil {
		return nil, true, 
	}
	,  = .parseCD()
	if  != nil {
		return nil, true, 
	}
	if len() == 0 {
		return , true, nil
	}
	 := [0]
	for ,  := range .Children {
		if len(.Children) != 0 && amscdCellHasVerticalArrow(.Children[len(.Children)-1]) {
			.AppendChild(node("mtd"))
		}
	}
	resetTableAttributes(,
		"columnalign", "center",
		"columnspacing", "5pt",
		"rowspacing", tableRowSpacing(),
		"displaystyle", true,
	)
	 := .amscdState(amscdMinWidthState, "2.75em")
	 := .amscdState(amscdMinHeightState, "1.75em")
	.Walk(func( *mml.Node) bool {
		if .Kind != "mo" {
			return true
		}
		 := textContent()
		switch  {
		case "→", "←", "=":
			amscdResetAttributes(,
				"minsize", ,
				"stretchy", true,
			)
		case "↓", "↑", "‖":
			amscdResetAttributes(,
				"minsize", ,
				"stretchy", true,
				"symmetric", true,
				"lspace", 0,
				"rspace", 0,
			)
		}
		return true
	})
	[0] = finishArrayRules()
	return , true, nil
}

func amscdCellHasVerticalArrow( *mml.Node) bool {
	 := false
	.Walk(func( *mml.Node) bool {
		if .Kind == "mo" {
			switch textContent() {
			case "↓", "↑", "‖":
				 = true
			}
		}
		return !
	})
	return 
}

func ( *parser) (,  string) string {
	if ,  := .state.macros[];  {
		return .body
	}
	return 
}

func amscdResetAttributes( *mml.Node,  ...any) {
	for ,  := range .Attributes.ExplicitNames() {
		.Attributes.Explicit().Delete()
	}
	for  := 0;  < len();  += 2 {
		.Attributes.Set([].(string), [+1])
	}
}