package utils import ( "regexp" "strings" ) // Helper function to change patterns func changeAll(text, oldIns, newIns, leftDelim, rightDelim, newLeftDelim, newRightDelim string) string { pattern := regexp.MustCompile(regexp.QuoteMeta(oldIns) + `\s*` + regexp.QuoteMeta(leftDelim) + `(.*?)` + regexp.QuoteMeta(rightDelim)) return pattern.ReplaceAllString(text, newIns+newLeftDelim+"$1"+newRightDelim) } // Helper function to remove dollar surroundings func rmDollarSurr(text string) string { if strings.HasPrefix(text, "$") && strings.HasSuffix(text, "$") { return text[1 : len(text)-1] } return text } // ToKatex converts LaTeX formula to KaTeX compatible format func ToKatex(formula string) string { res := formula // Remove mbox surrounding res = changeAll(res, `\mbox `, " ", "{", "}", "", "") res = changeAll(res, `\mbox`, " ", "{", "}", "", "") // Remove hbox surrounding hboxPattern := regexp.MustCompile(`\\hbox to ?-? ?\d+\.\d+(pt)?\{`) res = hboxPattern.ReplaceAllString(res, `\hbox{`) res = changeAll(res, `\hbox`, " ", "{", "}", "", " ") // Remove raise surrounding raisePattern := regexp.MustCompile(`\\raise ?-? ?\d+\.\d+(pt)?`) res = raisePattern.ReplaceAllString(res, " ") // Remove makebox makeboxPattern := regexp.MustCompile(`\\makebox ?\[\d+\.\d+(pt)?\]\{`) res = makeboxPattern.ReplaceAllString(res, `\makebox{`) res = changeAll(res, `\makebox`, " ", "{", "}", "", " ") // Remove vbox, scalebox, raisebox surrounding raisebox := regexp.MustCompile(`\\raisebox\{-? ?\d+\.\d+(pt)?\}\{`) scalebox := regexp.MustCompile(`\\scalebox\{-? ?\d+\.\d+(pt)?\}\{`) res = raisebox.ReplaceAllString(res, `\raisebox{`) res = scalebox.ReplaceAllString(res, `\scalebox{`) res = changeAll(res, `\scalebox`, " ", "{", "}", "", " ") res = changeAll(res, `\raisebox`, " ", "{", "}", "", " ") res = changeAll(res, `\vbox`, " ", "{", "}", "", " ") // Handle size instructions sizeInstructions := []string{ `\Huge`, `\huge`, `\LARGE`, `\Large`, `\large`, `\normalsize`, `\small`, `\footnotesize`, `\tiny`, } for _, ins := range sizeInstructions { res = changeAll(res, ins, ins, "$", "$", "{", "}") } // Handle boldmath res = changeAll(res, `\boldmath `, `\bm`, "{", "}", "{", "}") res = changeAll(res, `\boldmath`, `\bm`, "{", "}", "{", "}") res = changeAll(res, `\boldmath `, `\bm`, "$", "$", "{", "}") res = changeAll(res, `\boldmath`, `\bm`, "$", "$", "{", "}") // Handle other instructions res = changeAll(res, `\scriptsize`, `\scriptsize`, "$", "$", "{", "}") res = changeAll(res, `\emph`, `\textit`, "{", "}", "{", "}") res = changeAll(res, `\emph `, `\textit`, "{", "}", "{", "}") // Handle math delimiters delimiters := []string{ `\left`, `\middle`, `\right`, `\big`, `\Big`, `\bigg`, `\Bigg`, `\bigl`, `\Bigl`, `\biggl`, `\Biggl`, `\bigm`, `\Bigm`, `\biggm`, `\Biggm`, `\bigr`, `\Bigr`, `\biggr`, `\Biggr`, } for _, delim := range delimiters { res = changeAll(res, delim, delim, "{", "}", "", "") } // Handle display math displayMath := regexp.MustCompile(`\\\[(.*?)\\\]`) res = displayMath.ReplaceAllString(res, "$1\\newline") res = strings.TrimSuffix(res, `\newline`) // Remove multiple spaces spaces := regexp.MustCompile(`(\\,){1,}`) res = spaces.ReplaceAllString(res, " ") res = regexp.MustCompile(`(\\!){1,}`).ReplaceAllString(res, " ") res = regexp.MustCompile(`(\\;){1,}`).ReplaceAllString(res, " ") res = regexp.MustCompile(`(\\:){1,}`).ReplaceAllString(res, " ") res = regexp.MustCompile(`\\vspace\{.*?}`).ReplaceAllString(res, "") // Merge consecutive text textPattern := regexp.MustCompile(`(\\text\{[^}]*\}\s*){2,}`) res = textPattern.ReplaceAllStringFunc(res, func(match string) string { texts := regexp.MustCompile(`\\text\{([^}]*)\}`).FindAllStringSubmatch(match, -1) var merged strings.Builder for _, t := range texts { merged.WriteString(t[1]) } return `\text{` + merged.String() + "}" }) res = strings.ReplaceAll(res, `\bf `, "") res = rmDollarSurr(res) // Remove extra spaces res = regexp.MustCompile(` +`).ReplaceAllString(res, " ") return strings.TrimSpace(res) }