diff --git a/Sources/LaTeXSwiftUI/Extensions/CGRect+Extensions.swift b/Sources/LaTeXSwiftUI/Extensions/CGRect+Extensions.swift index 27a4b08..78d7860 100644 --- a/Sources/LaTeXSwiftUI/Extensions/CGRect+Extensions.swift +++ b/Sources/LaTeXSwiftUI/Extensions/CGRect+Extensions.swift @@ -24,6 +24,7 @@ // import Foundation +import CoreGraphics extension CGRect: Hashable { diff --git a/Sources/LaTeXSwiftUI/Models/Parser.swift b/Sources/LaTeXSwiftUI/Models/Parser.swift index 78c400a..9661e87 100644 --- a/Sources/LaTeXSwiftUI/Models/Parser.swift +++ b/Sources/LaTeXSwiftUI/Models/Parser.swift @@ -49,28 +49,28 @@ internal struct Parser { /// An TeX-style block equation component. static let tex = EquationComponent( - regex: #/\$\$(.*?)\$\$/#, + regex: #/\$\$\s*(.*?)\s*\$\$/#, terminatingRegex: #/\$\$/#, equation: .texEquation, supportsRecursion: false) /// A block equation. static let block = EquationComponent( - regex: #/\\\[(.*?)\\\]/#, + regex: #/\\\[\s*(.*?)\s*\\\]/#, terminatingRegex: #/\\\]/#, equation: .blockEquation, supportsRecursion: false) /// A named equation component. static let named = EquationComponent( - regex: #/\\begin{equation}(.*?)\\end{equation}/#, + regex: #/\\begin{equation}\s*(.*?)\s*\\end{equation}/#, terminatingRegex: #/\\end{equation}/#, equation: .namedEquation, supportsRecursion: true) /// A named no number equation component. static let namedNoNumber = EquationComponent( - regex: #/\\begin{equation\*}(.*?)\\end{equation\*}/#, + regex: #/\\begin{equation\*}\s*(.*?)\s*\\end{equation\*}/#, terminatingRegex: #/\\end{equation\*}/#, equation: .namedNoNumberEquation, supportsRecursion: true) diff --git a/Tests/LaTeXSwiftUITests/GeometryTests.swift b/Tests/LaTeXSwiftUITests/GeometryTests.swift new file mode 100644 index 0000000..8de22a0 --- /dev/null +++ b/Tests/LaTeXSwiftUITests/GeometryTests.swift @@ -0,0 +1,43 @@ +import MathJaxSwift +import XCTest +@testable import LaTeXSwiftUI + +final class GeometryTests: XCTestCase { + + func testSVGGeometry_parseAlignment() { + let input = "\"vertical-align: -1.602ex;\"" + let value = SVGGeometry.parseAlignment(from: input) + XCTAssertEqual(value, -1.602) + } + + func testSVGGeometry_parseAlignmentZero() { + let input = "\"vertical-align: 0;\"" + let value = SVGGeometry.parseAlignment(from: input) + XCTAssertEqual(value, 0) + } + + func testSVGGeometry_parseXHeight() { + let input = "\"-1.602ex\"" + let value = SVGGeometry.parseXHeight(from: input) + XCTAssertEqual(value, -1.602) + } + + func testSVGGeometry_parseViewBox() { + let input = "\"0 -1342 940 2050\"" + let value = SVGGeometry.parseViewBox(from: input) + XCTAssertEqual(value, CGRect(x: 0, y: -1342, width: 940, height: 2050)) + } + + func testSVGGeometry() throws { + let input = """ + +""" + let geometry = try SVGGeometry(svg: input) + XCTAssertNoThrow(geometry) + XCTAssertEqual(geometry.verticalAlignment, -1.602) + XCTAssertEqual(geometry.width, 2.127) + XCTAssertEqual(geometry.height, 4.638) + XCTAssertEqual(geometry.frame, CGRect(x: 0, y: -1342, width: 940, height: 2050)) + } + +} diff --git a/Tests/LaTeXSwiftUITests/LaTeXSwiftUITests.swift b/Tests/LaTeXSwiftUITests/ParserTests.swift similarity index 65% rename from Tests/LaTeXSwiftUITests/LaTeXSwiftUITests.swift rename to Tests/LaTeXSwiftUITests/ParserTests.swift index 8341b24..cc227e9 100644 --- a/Tests/LaTeXSwiftUITests/LaTeXSwiftUITests.swift +++ b/Tests/LaTeXSwiftUITests/ParserTests.swift @@ -1,9 +1,16 @@ +// +// ParserTests.swift +// +// +// Created by Colin Campbell on 5/29/23. +// + import MathJaxSwift import XCTest @testable import LaTeXSwiftUI -final class LaTeXSwiftUITests: XCTestCase { - +final class ParserTests: XCTestCase { + func assertComponent(_ components: [Component], _ index: Int, _ text: String, _ type: Component.ComponentType, file: StaticString = #file, line: UInt = #line) { guard index < components.count else { XCTFail() @@ -85,6 +92,30 @@ final class LaTeXSwiftUITests: XCTestCase { assertComponent(components, 0, input, .text) } + func testParseDoubleDollarOnly_LeadingLineBreak() { + let equation = "\nf(x)=5x+2" + let input = "$$\(equation)$$" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + assertComponent(components, 0, equation, .texEquation) + } + + func testParseDoubleDollarOnly_TrailingLineBreak() { + let equation = "f(x)=5x+2\n" + let input = "$$\(equation)$$" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + assertComponent(components, 0, equation, .texEquation) + } + + func testParseDoubleDollarOnly_Whitespace() { + let equation = " \nf(x)=5x+2\n " + let input = "$$\(equation)$$" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 1) + assertComponent(components, 0, equation, .texEquation) + } + func testParseBracketsOnly() { let input = "\\[\\TeX\\]" let components = Parser.parse(input) @@ -115,11 +146,28 @@ final class LaTeXSwiftUITests: XCTestCase { assertComponent(components, 0, input, .text) } - func testParseBracketsOnly_LineBreak() { - let input = "Hello, \\[\\TeX\n\\\\]!" + func testParseBracketsOnly_LeadingLineBreak() { + let equation = "\n\\TeX" + let input = "Hello, \\[\(equation)\\]!" let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - assertComponent(components, 0, input, .text) + XCTAssertEqual(components.count, 3) + assertComponent(components, 1, equation, .blockEquation) + } + + func testParseBracketsOnly_TrailingLineBreak() { + let equation = "\\TeX\n" + let input = "Hello, \\[\(equation)\\]!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 3) + assertComponent(components, 1, equation, .blockEquation) + } + + func testParseBracketsOnly_Whitespace() { + let equation = " \n\\TeX\n " + let input = "Hello, \\[\(equation)\\]!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 3) + assertComponent(components, 1, equation, .blockEquation) } func testParseBeginEndOnly() { @@ -152,11 +200,28 @@ final class LaTeXSwiftUITests: XCTestCase { assertComponent(components, 0, input, .text) } - func testParseBeginEndOnly_LineBreak() { - let input = "Hello, \\begin{equation}\\TeX\n\\\\end{equation}!" + func testParseBeginEndOnly_LeadingLineBreak() { + let equation = "\n\\TeX" + let input = "Hello, \\begin{equation}\(equation)\\end{equation}!" let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - assertComponent(components, 0, input, .text) + XCTAssertEqual(components.count, 3) + assertComponent(components, 1, equation, .namedEquation) + } + + func testParseBeginEndOnly_TrailingLineBreak() { + let equation = "\\TeX\n" + let input = "Hello, \\begin{equation}\(equation)\\end{equation}!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 3) + assertComponent(components, 1, equation, .namedEquation) + } + + func testParseBeginEndOnly_Whitespace() { + let equation = " \n\\TeX\n " + let input = "Hello, \\begin{equation}\(equation)\\end{equation}!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 3) + assertComponent(components, 1, equation, .namedEquation) } func testParseBeginEndStarOnly() { @@ -189,47 +254,28 @@ final class LaTeXSwiftUITests: XCTestCase { assertComponent(components, 0, input, .text) } - func testParseBeginEndStarOnly_LineBreak() { - let input = "Hello, \\begin{equation*}\\TeX\n\\\\end{equation*}!" + func testParseBeginEndStarOnly_LeadingLineBreak() { + let equation = "\n\\TeX" + let input = "Hello, \\begin{equation*}\(equation)\\end{equation*}!" let components = Parser.parse(input) - XCTAssertEqual(components.count, 1) - assertComponent(components, 0, input, .text) - } - - func testSVGGeometry_parseAlignment() { - let input = "\"vertical-align: -1.602ex;\"" - let value = SVGGeometry.parseAlignment(from: input) - XCTAssertEqual(value, -1.602) - } - - func testSVGGeometry_parseAlignmentZero() { - let input = "\"vertical-align: 0;\"" - let value = SVGGeometry.parseAlignment(from: input) - XCTAssertEqual(value, 0) - } - - func testSVGGeometry_parseXHeight() { - let input = "\"-1.602ex\"" - let value = SVGGeometry.parseXHeight(from: input) - XCTAssertEqual(value, -1.602) + XCTAssertEqual(components.count, 3) + assertComponent(components, 1, equation, .namedNoNumberEquation) } - func testSVGGeometry_parseViewBox() { - let input = "\"0 -1342 940 2050\"" - let value = SVGGeometry.parseViewBox(from: input) - XCTAssertEqual(value, CGRect(x: 0, y: -1342, width: 940, height: 2050)) + func testParseBeginEndStarOnly_TrailingLineBreak() { + let equation = "\\TeX\n" + let input = "Hello, \\begin{equation*}\(equation)\\end{equation*}!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 3) + assertComponent(components, 1, equation, .namedNoNumberEquation) } - func testSVGGeometry() throws { - let input = """ - -""" - let geometry = try SVGGeometry(svg: input) - XCTAssertNoThrow(geometry) - XCTAssertEqual(geometry.verticalAlignment, -1.602) - XCTAssertEqual(geometry.width, 2.127) - XCTAssertEqual(geometry.height, 4.638) - XCTAssertEqual(geometry.frame, CGRect(x: 0, y: -1342, width: 940, height: 2050)) + func testParseBeginEndStarOnly_Whitespace() { + let equation = " \n\\TeX\n " + let input = "Hello, \\begin{equation*}\(equation)\\end{equation*}!" + let components = Parser.parse(input) + XCTAssertEqual(components.count, 3) + assertComponent(components, 1, equation, .namedNoNumberEquation) } - + }