Add preformatted toggle line type

This commit is contained in:
Shadowfacts 2020-07-12 23:52:38 -04:00
parent f72025ddb7
commit f870daa634
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
3 changed files with 30 additions and 14 deletions

View File

@ -11,7 +11,7 @@ public struct Document {
public let url: URL public let url: URL
public var lines: [Line] public var lines: [Line]
init(url: URL, lines: [Line] = []) { public init(url: URL, lines: [Line] = []) {
self.url = url self.url = url
self.lines = lines self.lines = lines
} }
@ -21,7 +21,8 @@ public extension Document {
enum Line: Equatable { enum Line: Equatable {
case text(String) case text(String)
case link(URL, 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 heading(String, level: HeadingLevel)
case unorderedListItem(String) case unorderedListItem(String)
case quote(String) case quote(String)

View File

@ -26,14 +26,17 @@ public struct GeminiParser {
alt = nil alt = nil
} }
preformattingState = .on(alt) preformattingState = .on(alt)
case .on(_): doc.lines.append(.preformattedToggle(alt: alt))
case let .on(alt):
preformattingState = .off preformattingState = .off
// todo: should the toggle off line be a separate line type?
doc.lines.append(.preformattedToggle(alt: nil))
} }
if case .off = preformattingState { if case .off = preformattingState {
} }
} else if case let .on(alt) = preformattingState { } else if case .on(_) = preformattingState {
doc.lines.append(.preformattedText(line, alt: alt)) doc.lines.append(.preformattedText(line))
} else if line.starts(with: "=>") { } else if line.starts(with: "=>") {
// Link line // Link line
let urlStart = line.firstNonWhitespaceIndex(after: line.index(line.startIndex, offsetBy: 2)) let urlStart = line.firstNonWhitespaceIndex(after: line.index(line.startIndex, offsetBy: 2))

View File

@ -97,23 +97,35 @@ class GeminiParserTests: XCTestCase {
func testParsePreformattedLines() { func testParsePreformattedLines() {
assertParseLines(text: "```\nsomething\n```", lines: [ assertParseLines(text: "```\nsomething\n```", lines: [
.preformattedText("something", alt: nil) .preformattedToggle(alt: nil),
.preformattedText("something"),
.preformattedToggle(alt: nil)
], message: "parse simple preformatted line") ], message: "parse simple preformatted line")
assertParseLines(text: "```alt\nsomething\n```", lines: [ 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") ], message: "parse simple preformatted line with alt")
assertParseLines(text: "```alt\nsomething\n```other", lines: [ 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 ```") ], 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: [ 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), .preformattedToggle(alt: nil),
.preformattedText("* not a list item", alt: nil), .preformattedText("# not a heading"),
.preformattedText(">not a quote", alt: nil), .preformattedText("* not a list item"),
.preformattedText("=> /link not a link", alt: nil), .preformattedText(">not a quote"),
.preformattedText("=> /link not a link"),
.preformattedToggle(alt: nil)
], message: "don't parse special lines inside preformatted") ], message: "don't parse special lines inside preformatted")
assertParseLines(text: "```a\na line\n```\n```b\nb line\n```", lines: [ assertParseLines(text: "```a\na line\n```\n```b\nb line\n```", lines: [
.preformattedText("a line", alt: "a"), .preformattedToggle(alt: "a"),
.preformattedText("b line", alt: "b"), .preformattedText("a line"),
.preformattedToggle(alt: nil),
.preformattedToggle(alt: "b"),
.preformattedText("b line"),
.preformattedToggle(alt: nil),
], message: "parse consecutive preformatted blocks") ], message: "parse consecutive preformatted blocks")
} }