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 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)

View File

@ -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))

View File

@ -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")
}