swiftgemtext

[ACTIVE] gemtext parsing in swift
git clone git://git.figbert.com/swiftgemtext.git
Log | Files | Refs | README

commit 64056171c6970ee83c06cd09510647c79ea55694
parent 90b09918d02636b404d3e24cf8ee474033331bfa
Author: FIGBERT <figbert@figbert.com>
Date:   Tue, 20 Apr 2021 12:03:49 -0700

Upgrade parsing preformatted sections of Gemtext

PreformattingToggle and PreformattedText have been combined
into PreformattedText, to make rendering easier for clients.
Now, each section of preformatted text is represented by a
single LineType containing the full content and an optional
alt text.

The Gemtext.parse function has been significantly reworked
to handle this change, and a PreformattedState struct has
been introduced to abstract preformatting-related values.

Diffstat:
MSources/SwiftGemtext/SwiftGemtext.swift | 31++++++++++++++++++++++---------
MTests/SwiftGemtextTests/SwiftGemtextTests.swift | 11++++-------
2 files changed, 26 insertions(+), 16 deletions(-)

diff --git a/Sources/SwiftGemtext/SwiftGemtext.swift b/Sources/SwiftGemtext/SwiftGemtext.swift @@ -9,20 +9,23 @@ struct Gemtext { func parse() -> [LineType] { var lines = [LineType]() - var pre = false + var pre = PreformattedState() + for line in source.lines() { - if pre { + if pre.active { if line.starts(with: "```") { - lines.append(LineType.PreformattingToggle(nil)) - pre.toggle() + lines.append(pre.getLineType()) + pre = PreformattedState() } else { - lines.append(LineType.PreformattedText(line)) + pre.lines.append(line) } } else { if line.starts(with: "```") { let alt = line.dropFirst(3).trimmingCharacters(in: .whitespacesAndNewlines) - lines.append(LineType.PreformattingToggle(alt.count > 0 ? alt : nil)) - pre.toggle() + if alt.count > 0 { + pre.alt = alt + } + pre.active = true } else { lines.append(parsePlainLine(line)) } @@ -69,11 +72,21 @@ struct Gemtext { } } +struct PreformattedState { + var lines = [String]() + var active = false + var alt: String? + + func getLineType() -> LineType { + let str = self.lines.joined(separator: "\r\n") + return LineType.PreformattedText(str, alt) + } +} + enum LineType: Equatable { case Text(String) case Link(URL, String?) - case PreformattingToggle(String?) - case PreformattedText(String) + case PreformattedText(String, String?) case Heading(Int, String) case UnorderedList(String) case Quote(String) diff --git a/Tests/SwiftGemtextTests/SwiftGemtextTests.swift b/Tests/SwiftGemtextTests/SwiftGemtextTests.swift @@ -42,7 +42,8 @@ final class SwiftGemtextTests: XCTestCase { ``` ```python - print("example") + while True: + print("example") ``` Lorem ipsum dolor sit amet. @@ -60,13 +61,9 @@ final class SwiftGemtextTests: XCTestCase { LineType.Heading(2, "Two"), LineType.Heading(3, "Three"), LineType.EmptyLine, - LineType.PreformattingToggle(nil), - LineType.PreformattedText("(?<=\\.\\/IssuerIcons\\/).*(?=\\.png)"), - LineType.PreformattingToggle(nil), + LineType.PreformattedText("(?<=\\.\\/IssuerIcons\\/).*(?=\\.png)", nil), LineType.EmptyLine, - LineType.PreformattingToggle("python"), - LineType.PreformattedText("print(\"example\")"), - LineType.PreformattingToggle(nil), + LineType.PreformattedText("while True:\r\n print(\"example\")", "python"), LineType.EmptyLine, LineType.Text("Lorem ipsum dolor sit amet."), LineType.EmptyLine,