commit c98a3bf0c627123a55e70370d034620cb6e65a7a
Author: FIGBERT <figbert@figbert.com>
Date: Mon, 19 Apr 2021 16:36:36 -0700
Initial commit
Diffstat:
8 files changed, 146 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,5 @@
+.DS_Store
+/.build
+/Packages
+/*.xcodeproj
+xcuserdata/
diff --git a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:">
+ </FileRef>
+</Workspace>
diff --git a/Package.swift b/Package.swift
@@ -0,0 +1,21 @@
+// swift-tools-version:5.3
+
+import PackageDescription
+
+let package = Package(
+ name: "SwiftGemtext",
+ products: [
+ .library(
+ name: "SwiftGemtext",
+ targets: ["SwiftGemtext"]),
+ ],
+ dependencies: [],
+ targets: [
+ .target(
+ name: "SwiftGemtext",
+ dependencies: []),
+ .testTarget(
+ name: "SwiftGemtextTests",
+ dependencies: ["SwiftGemtext"]),
+ ]
+)
diff --git a/README.md b/README.md
@@ -0,0 +1,3 @@
+# SwiftGemtext
+
+A description of this package.
diff --git a/Sources/SwiftGemtext/SwiftGemtext.swift b/Sources/SwiftGemtext/SwiftGemtext.swift
@@ -0,0 +1,79 @@
+import SwiftUI
+
+struct SwiftGemtext {
+ let source: String
+
+ init(_ src: String) {
+ self.source = src
+ }
+
+ func parse() -> [LineType] {
+ var lines = [LineType]()
+ var pre = false
+ for line in source.lines {
+ let ln = String(line)
+ if pre {
+ if ln.starts(with: "```") {
+ lines.append(LineType.PreformattingToggle(nil))
+ pre.toggle()
+ } else {
+ lines.append(LineType.PreformattedText(ln))
+ }
+ } else {
+ if ln.starts(with: "```") {
+ let alt = ln.dropFirst(3).trimmingCharacters(in: .whitespacesAndNewlines)
+ lines.append(LineType.PreformattingToggle(alt.count > 0 ? alt : nil))
+ pre.toggle()
+ } else {
+ lines.append(parsePlainLine(ln))
+ }
+ }
+ }
+ return lines
+ }
+
+ func parsePlainLine(_ line: String) -> LineType {
+ if line.starts(with: "#") { // Heading
+ var level: Int = 1
+ if line.starts(with: "###") {
+ level = 3
+ } else if line.starts(with: "##") {
+ level = 2
+ }
+ return LineType.Heading(level, line.dropFirst(level).trimmingCharacters(in: .whitespacesAndNewlines))
+ } else if line.starts(with: "=>") { // Link
+ let urlAndCaption = line.dropFirst(2).trimmingCharacters(in: .whitespacesAndNewlines)
+ let delim = urlAndCaption.firstIndex(of: " ")!
+ let url = URL(string: String(urlAndCaption[..<delim]))!
+ let caption = urlAndCaption[delim...]
+ if caption.count > 0 {
+ return LineType.Link(url, String(caption))
+ } else {
+ return LineType.Link(url, nil)
+ }
+ } else if line.starts(with: "* ") { // Unordered List
+ return LineType.UnorderedList(line.dropFirst(2).trimmingCharacters(in: .whitespacesAndNewlines))
+ } else if line.starts(with: ">") { // Quote
+ return LineType.Quote(String(line))
+ } else if line.trimmingCharacters(in: .whitespacesAndNewlines) == "" { // Empty Line
+ return LineType.EmptyLine
+ } else {
+ return LineType.Text(line)
+ }
+ }
+}
+
+enum LineType {
+ case Text(String)
+ case Link(URL, String?)
+ case PreformattingToggle(String?)
+ case PreformattedText(String)
+ case Heading(Int, String)
+ case UnorderedList(String)
+ case Quote(String)
+ case EmptyLine
+}
+
+extension StringProtocol {
+ var lines: [SubSequence] { split(whereSeparator: \.isNewline) }
+}
diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift
@@ -0,0 +1,7 @@
+import XCTest
+
+import SwiftGemtextTests
+
+var tests = [XCTestCaseEntry]()
+tests += SwiftGemtextTests.allTests()
+XCTMain(tests)
diff --git a/Tests/SwiftGemtextTests/SwiftGemtextTests.swift b/Tests/SwiftGemtextTests/SwiftGemtextTests.swift
@@ -0,0 +1,15 @@
+import XCTest
+@testable import SwiftGemtext
+
+final class SwiftGemtextTests: XCTestCase {
+ func testExample() {
+ // This is an example of a functional test case.
+ // Use XCTAssert and related functions to verify your tests produce the correct
+ // results.
+ XCTAssertEqual(SwiftGemtext().text, "Hello, World!")
+ }
+
+ static var allTests = [
+ ("testExample", testExample),
+ ]
+}
diff --git a/Tests/SwiftGemtextTests/XCTestManifests.swift b/Tests/SwiftGemtextTests/XCTestManifests.swift
@@ -0,0 +1,9 @@
+import XCTest
+
+#if !canImport(ObjectiveC)
+public func allTests() -> [XCTestCaseEntry] {
+ return [
+ testCase(SwiftGemtextTests.allTests),
+ ]
+}
+#endif