From 348f75ccea5d0b969210eac1a4850556c79672dd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 6 Apr 2026 14:18:08 +0000 Subject: [PATCH] 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> --- .../Internal/Syntax/AtomFactory.swift | 4 +- .../Internal/Syntax/ParserTests.swift | 37 +++++++++++++++++++ Tests/SwiftUIMathTests/MathTests.swift | 27 ++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/Sources/SwiftUIMath/Internal/Syntax/AtomFactory.swift b/Sources/SwiftUIMath/Internal/Syntax/AtomFactory.swift index 423d4ab..4561ffc 100644 --- a/Sources/SwiftUIMath/Internal/Syntax/AtomFactory.swift +++ b/Sources/SwiftUIMath/Internal/Syntax/AtomFactory.swift @@ -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 ")", "]", "!", "?": diff --git a/Tests/SwiftUIMathTests/Internal/Syntax/ParserTests.swift b/Tests/SwiftUIMathTests/Internal/Syntax/ParserTests.swift index edee40e..c9dfb58 100644 --- a/Tests/SwiftUIMathTests/Internal/Syntax/ParserTests.swift +++ b/Tests/SwiftUIMathTests/Internal/Syntax/ParserTests.swift @@ -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)'") + } + } + } diff --git a/Tests/SwiftUIMathTests/MathTests.swift b/Tests/SwiftUIMathTests/MathTests.swift index fa30c7d..3e02f7d 100644 --- a/Tests/SwiftUIMathTests/MathTests.swift +++ b/Tests/SwiftUIMathTests/MathTests.swift @@ -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) {