Add ~ space support and complex formula tests

Agent-Logs-Url: https://github.com/wesleyel/swiftui-math/sessions/6740d67f-473b-43b8-87ba-25d9469f5757

Co-authored-by: wesleyel <48174882+wesleyel@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-04-06 14:18:08 +00:00
committed by GitHub
parent 569db11ed5
commit 348f75ccea
3 changed files with 67 additions and 1 deletions

View File

@@ -537,8 +537,10 @@ extension Math {
return atom(fromAccentedCharacter: ch)
case _ where ch.utf32 < 0x0021 || ch.utf32 > 0x007E:
return nil
case "$", "%", "#", "&", "~", "\'", "^", "_", "{", "}", "\\":
case "$", "%", "#", "&", "\'", "^", "_", "{", "}", "\\":
return nil
case "~":
return Space(amount: 3)
case "(", "[":
return Atom(type: .open, nucleus: stringValue)
case ")", "]", "!", "?":

View File

@@ -2568,4 +2568,41 @@ struct ParserTests {
}
}
@Test
func complexFormulas() throws {
// Formula 1: limit with integral in denominator, using \mathrm{~d} for the differential
let formula1 =
"\\lim _{x \\rightarrow 0} \\frac{a x-\\sin x}{\\int_{b}^{x} \\frac{\\ln \\left(1+t^{3}\\right)}{t} \\mathrm{~d} t}=c, c \\neq 0"
// Formula 2: double sum with nested fractions and grouped terms
let formula2 =
"\\lim _{n \\rightarrow \\infty} \\sum_{i=1}^{n} \\sum_{j=1}^{n} \\frac{n}{(n+i)\\left(n^{2}+j^{2}\\right)}="
// Formula 3: nested integrals with arctan and \mathrm{d} differentials
let formula3 =
"\\lim _{x \\rightarrow 0} \\frac{\\int_{0}^{x}\\left[\\int_{0}^{u^{2}} \\arctan (1+t) \\mathrm{d} t\\right] \\mathrm{d} u}{x(1-\\cos x)}"
for formula in [formula1, formula2, formula3] {
var error: Math.ParserError? = nil
let list = Math.Parser.build(fromString: formula, error: &error)
#expect(error == nil, "Unexpected parse error for formula: \(formula)")
let unwrappedList = try #require(list)
#expect(!unwrappedList.atoms.isEmpty)
}
}
@Test
func tildeAsSpace() throws {
// ~ in math mode should produce a thin space, not an error
let testCases: [(String, String)] = [
("a~b", "a\\, b"),
("\\mathrm{~d}", "\\mathrm{\\, d}"),
]
for (input, expected) in testCases {
var error: Math.ParserError? = nil
let list = Math.Parser.build(fromString: input, error: &error)
#expect(error == nil)
let latex = Math.Parser.atomListToString(list)
#expect(latex == expected, "Round-trip mismatch for input '\(input)'")
}
}
}

View File

@@ -74,6 +74,33 @@
assertSnapshot(of: view, as: .image(layout: layout))
}
@Test
func complexIntegralFormulas() {
let view = VStack(alignment: .leading, spacing: 16) {
Math(
"\\lim _{x \\rightarrow 0} \\frac{a x-\\sin x}{\\int_{b}^{x} \\frac{\\ln \\left(1+t^{3}\\right)}{t} \\mathrm{~d} t}=c, c \\neq 0"
)
.mathTypesettingStyle(.display)
.mathFont(Math.Font(name: .latinModern, size: 20))
Math(
"\\lim _{n \\rightarrow \\infty} \\sum_{i=1}^{n} \\sum_{j=1}^{n} \\frac{n}{(n+i)\\left(n^{2}+j^{2}\\right)}="
)
.mathTypesettingStyle(.display)
.mathFont(Math.Font(name: .latinModern, size: 20))
Math(
"\\lim _{x \\rightarrow 0} \\frac{\\int_{0}^{x}\\left[\\int_{0}^{u^{2}} \\arctan (1+t) \\mathrm{d} t\\right] \\mathrm{d} u}{x(1-\\cos x)}"
)
.mathTypesettingStyle(.display)
.mathFont(Math.Font(name: .latinModern, size: 20))
}
.background(Color.guide)
.padding(.horizontal)
assertSnapshot(of: view, as: .image(layout: layout))
}
@Test
func inlineTextWrapping() {
let view = VStack(alignment: .leading, spacing: 16) {