// Copyright 2017-2022 The MathJax Consortium
// SPDX-License-Identifier: Apache-2.0
// This file is a Go translation and modification of MathJax 3.2.2.

package layout

import (
	
	
	
	
	

	
)

var absoluteUnits = map[string]float64{
	"px": 1,
	"in": 96,
	"cm": 96 / 2.54,
	"mm": 96 / 25.4,
}

var relativeUnits = map[string]float64{
	"em": 1,
	"ex": .431,
	"pt": .1,
	"pc": 1.2,
	"mu": 1.0 / 18,
}

// MathSpace contains MathJax's named math-space and size values.
var MathSpace = map[string]float64{
	"veryverythinmathspace":          1.0 / 18,
	"verythinmathspace":              2.0 / 18,
	"thinmathspace":                  3.0 / 18,
	"mediummathspace":                4.0 / 18,
	"thickmathspace":                 5.0 / 18,
	"verythickmathspace":             6.0 / 18,
	"veryverythickmathspace":         7.0 / 18,
	"negativeveryverythinmathspace":  -1.0 / 18,
	"negativeverythinmathspace":      -2.0 / 18,
	"negativethinmathspace":          -3.0 / 18,
	"negativemediummathspace":        -4.0 / 18,
	"negativethickmathspace":         -5.0 / 18,
	"negativeverythickmathspace":     -6.0 / 18,
	"negativeveryverythickmathspace": -7.0 / 18,
	"thin":                           .04,
	"medium":                         .06,
	"thick":                          .1,
	"normal":                         1,
	"big":                            2,
	"small":                          1 / math.Sqrt2,
	"infinity":                       BigDimen,
}

// JavaScript's \s includes Unicode space separators and BOM, but not NEL.
var lengthPattern = regexp.MustCompile(`^[\t-\r \x{00a0}\x{1680}\x{2000}-\x{200a}\x{2028}\x{2029}\x{202f}\x{205f}\x{3000}\x{feff}]*([-+]?(?:\.\d+|\d+(?:\.\d*)?))?(pt|em|ex|mu|px|pc|in|mm|cm|%)?`)

// Length2Em converts a MathML dimension into ems with MathJax 3.2.2's
// permissive prefix parsing.
func ( any, , ,  float64) float64 {
	var  string
	switch x := .(type) {
	case nil:
		return 
	case string:
		 = 
	case float64:
		 = jscompat.NumberString()
	case float32:
		 = jscompat.NumberString(float64())
	case int:
		 = strconv.Itoa()
	case int64:
		 = strconv.FormatInt(, 10)
	default:
		 = fmt.Sprint()
	}
	if  == "" {
		return 
	}
	if ,  := MathSpace[];  {
		return 
	}
	 := lengthPattern.FindStringSubmatch()
	if  == nil {
		return 
	}
	 := 1.0
	if [1] != "" {
		,  := strconv.ParseFloat([1], 64)
		if  != nil {
			return 
		}
		 = 
	}
	 := [2]
	if ,  := absoluteUnits[];  {
		return  *  /  / 
	}
	if ,  := relativeUnits[];  {
		return  * 
	}
	if  == "%" {
		return  / 100 * 
	}
	return  * 
}

// Percent formats a multiplier as a CSS percentage.
func ( float64) string { return trimFixed(100*, 1) + "%" }

// Em formats a dimension as ems.
func ( float64) string {
	if math.Abs() < .001 {
		return "0"
	}
	return trimFixed(, 3) + "em"
}

// EmRounded rounds a dimension to CSS pixel boundaries before formatting.
func (,  float64) string {
	 = (jscompat.Round(*) + .05) / 
	if math.Abs() < .001 {
		return "0em"
	}
	return trimFixed(, 3) + "em"
}

// PX formats an em dimension as pixels with an optional minimum.
func (, ,  float64) string {
	 *= 
	if  != 0 &&  <  {
		 = 
	}
	if math.Abs() < .1 {
		return "0"
	}
	return trimFixed(, 1) + "px"
}

func trimFixed( float64,  int) string {
	return strings.TrimRight(strings.TrimRight(jscompat.ToFixed(, ), "0"), ".")
}