From 547e48cc5f8d98380dd8a7226ce630d3aa3b2245 Mon Sep 17 00:00:00 2001 From: Michael S <54802506+roya1v@users.noreply.github.com> Date: Mon, 13 May 2024 15:31:12 +0200 Subject: [PATCH] Allow escaped quotes in tag parameters (#124) * add escaping with "$" * Add new constant * Change escaping to double back slash --------- Co-authored-by: Sam Bishop --- Sources/LeafKit/LeafLexer/LeafLexer.swift | 12 +++++++++++- Tests/LeafKitTests/LeafTests.swift | 10 ++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/Sources/LeafKit/LeafLexer/LeafLexer.swift b/Sources/LeafKit/LeafLexer/LeafLexer.swift index 09228fd0..206209a0 100644 --- a/Sources/LeafKit/LeafLexer/LeafLexer.swift +++ b/Sources/LeafKit/LeafLexer/LeafLexer.swift @@ -160,7 +160,7 @@ internal struct LeafLexer { case .comma: return .parameterDelimiter case .quote: - let read = src.readWhile { $0 != .quote && $0 != .newLine } + let read = readWithEscapingQuotes(src: &src) guard src.peek() == .quote else { throw LexerError(.unterminatedStringLiteral, src: src, lexed: lexed) } @@ -269,4 +269,14 @@ internal struct LeafLexer { return .parameter(.variable(name: name)) } } + + private func readWithEscapingQuotes(src: inout LeafRawTemplate) -> String { + let read = src.readWhile { $0 != .quote && $0 != .newLine } + if read.last == .backSlash && src.peek() == .quote { + src.pop() + return read.dropLast() + "\"" + readWithEscapingQuotes(src: &src) + } else { + return read + } + } } diff --git a/Tests/LeafKitTests/LeafTests.swift b/Tests/LeafKitTests/LeafTests.swift index de4c302a..9dbb7e09 100644 --- a/Tests/LeafKitTests/LeafTests.swift +++ b/Tests/LeafKitTests/LeafTests.swift @@ -191,6 +191,16 @@ final class LeafTests: XCTestCase { try XCTAssertEqual(render(template, [:]), expected) } + func testEscapingQuote() throws { + let template = """ + #("foo \\"bar\\"") + """ + let expected = """ + foo "bar" + """ + try XCTAssertEqual(render(template), expected) + } + func testCount() throws { let template = """ count: #count(array)