From f870daa634829b67d88fd5828aa25962d00ebca1 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sun, 12 Jul 2020 23:52:38 -0400 Subject: [PATCH] Add preformatted toggle line type --- GeminiFormat/Document.swift | 5 ++-- GeminiFormat/GeminiParser.swift | 9 ++++--- GeminiFormatTests/GeminiParserTests.swift | 30 ++++++++++++++++------- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/GeminiFormat/Document.swift b/GeminiFormat/Document.swift index 55480d5..5efba8c 100644 --- a/GeminiFormat/Document.swift +++ b/GeminiFormat/Document.swift @@ -11,7 +11,7 @@ public struct Document { public let url: URL public var lines: [Line] - init(url: URL, lines: [Line] = []) { + public init(url: URL, lines: [Line] = []) { self.url = url self.lines = lines } @@ -21,7 +21,8 @@ public extension Document { enum Line: Equatable { case text(String) case link(URL, text: String?) - case preformattedText(String, alt: String?) + case preformattedToggle(alt: String?) + case preformattedText(String) case heading(String, level: HeadingLevel) case unorderedListItem(String) case quote(String) diff --git a/GeminiFormat/GeminiParser.swift b/GeminiFormat/GeminiParser.swift index 19c6948..2df74fc 100644 --- a/GeminiFormat/GeminiParser.swift +++ b/GeminiFormat/GeminiParser.swift @@ -26,14 +26,17 @@ public struct GeminiParser { alt = nil } preformattingState = .on(alt) - case .on(_): + doc.lines.append(.preformattedToggle(alt: alt)) + case let .on(alt): preformattingState = .off + // todo: should the toggle off line be a separate line type? + doc.lines.append(.preformattedToggle(alt: nil)) } if case .off = preformattingState { } - } else if case let .on(alt) = preformattingState { - doc.lines.append(.preformattedText(line, alt: alt)) + } else if case .on(_) = preformattingState { + doc.lines.append(.preformattedText(line)) } else if line.starts(with: "=>") { // Link line let urlStart = line.firstNonWhitespaceIndex(after: line.index(line.startIndex, offsetBy: 2)) diff --git a/GeminiFormatTests/GeminiParserTests.swift b/GeminiFormatTests/GeminiParserTests.swift index fd6c9c8..71e4a2e 100644 --- a/GeminiFormatTests/GeminiParserTests.swift +++ b/GeminiFormatTests/GeminiParserTests.swift @@ -97,23 +97,35 @@ class GeminiParserTests: XCTestCase { func testParsePreformattedLines() { assertParseLines(text: "```\nsomething\n```", lines: [ - .preformattedText("something", alt: nil) + .preformattedToggle(alt: nil), + .preformattedText("something"), + .preformattedToggle(alt: nil) ], message: "parse simple preformatted line") assertParseLines(text: "```alt\nsomething\n```", lines: [ - .preformattedText("something", alt: "alt") + .preformattedToggle(alt: "alt"), + .preformattedText("something"), + .preformattedToggle(alt: nil) ], message: "parse simple preformatted line with alt") assertParseLines(text: "```alt\nsomething\n```other", lines: [ - .preformattedText("something", alt: "alt") + .preformattedToggle(alt: "alt"), + .preformattedText("something"), + .preformattedToggle(alt: nil) ], message: "ignore extra text after closing ```") assertParseLines(text: "```\n# not a heading\n* not a list item\n>not a quote\n=> /link not a link\n```", lines: [ - .preformattedText("# not a heading", alt: nil), - .preformattedText("* not a list item", alt: nil), - .preformattedText(">not a quote", alt: nil), - .preformattedText("=> /link not a link", alt: nil), + .preformattedToggle(alt: nil), + .preformattedText("# not a heading"), + .preformattedText("* not a list item"), + .preformattedText(">not a quote"), + .preformattedText("=> /link not a link"), + .preformattedToggle(alt: nil) ], message: "don't parse special lines inside preformatted") assertParseLines(text: "```a\na line\n```\n```b\nb line\n```", lines: [ - .preformattedText("a line", alt: "a"), - .preformattedText("b line", alt: "b"), + .preformattedToggle(alt: "a"), + .preformattedText("a line"), + .preformattedToggle(alt: nil), + .preformattedToggle(alt: "b"), + .preformattedText("b line"), + .preformattedToggle(alt: nil), ], message: "parse consecutive preformatted blocks") }