From 1ec7f2c6deb64f5b13b32fae2bf74ae2d8aaaabb Mon Sep 17 00:00:00 2001 From: Ruben Beltran del Rio Date: Wed, 9 Jul 2025 08:34:19 +0200 Subject: Account for CRLF/CR/LF. Lex note text. Use Wmap Parser for renderer. --- Map/Business/WmapParser/Lexer.swift | 93 +++++++++++++++++++++++++++++-------- 1 file changed, 74 insertions(+), 19 deletions(-) (limited to 'Map/Business/WmapParser/Lexer.swift') diff --git a/Map/Business/WmapParser/Lexer.swift b/Map/Business/WmapParser/Lexer.swift index dc789bb..c79879f 100644 --- a/Map/Business/WmapParser/Lexer.swift +++ b/Map/Business/WmapParser/Lexer.swift @@ -18,6 +18,7 @@ extension Wmap { private var current: String.Index private var line = 1 private var column = 1 + private var expectingText = false init(_ input: String) { self.input = input @@ -41,17 +42,9 @@ extension Wmap { let tokenStart = current switch char { - case "\n": - advance() - let token = Token( - type: .newline, - value: "\n", - position: pos, - stringRange: tokenStart.. Token { let pos = currentPosition() + + // Skip any leading whitespace + skipWhitespace() + let tokenStart = current - while current < input.endIndex && input[current] != "\n" { + while current < input.endIndex && !isLineEnding(input[current]) { advance() } - let originalValue = String(input[tokenStart.. Token { + let pos = currentPosition() + let tokenStart = current + + if input[current] == "\r" { + advance() + // Check for CRLF + if current < input.endIndex && input[current] == "\n" { + advance() + let token = Token( + type: .newline, + value: "\r\n", + position: pos, + stringRange: tokenStart.. Bool { + return char == "\n" || char == "\r" + } + private func scanBracketedToken() -> Token { let pos = currentPosition() let tokenStart = current advance() // consume '[' let contentStart = current - while current < input.endIndex && input[current] != "]" && input[current] != "\n" { + while current < input.endIndex && input[current] != "]" && !isLineEnding(input[current]) { advance() } - // If we hit a newline or EOF before finding the closing bracket, it's an error + // If we hit a line ending or EOF before finding the closing bracket, it's an error guard current < input.endIndex && input[current] == "]" else { - // Return error token for unclosed bracket (don't consume past newline) + // Return error token for unclosed bracket (don't consume past line ending) return Token( type: .error, value: String(input[tokenStart.. Bool { return char == "-" || char == "+" || char == "," || char == "[" || char == "]" || char == "(" - || char == ")" || char == "\n" + || char == ")" || isLineEnding(char) } private func isDelimiter(_ char: Character) -> Bool { - return char.isWhitespace || char == "\n" || char == "(" || char == ")" || char == "[" + return char.isWhitespace || isLineEnding(char) || char == "(" || char == ")" || char == "[" || char == "]" || char == "," } private func skipWhitespace() { - while current < input.endIndex && input[current].isWhitespace && input[current] != "\n" { + while current < input.endIndex && input[current].isWhitespace && !isLineEnding(input[current]) + { advance() } } -- cgit