Gemini/GeminiFormat/GeminiMarkdownRenderer.swift

82 lines
2.2 KiB
Swift

//
// GeminiMarkdownRenderer.swift
// GeminiRenderer
//
// Created by Shadowfacts on 10/1/21.
//
import Foundation
import HTMLEntities
public class GeminiMarkdownRenderer {
public init() {
}
public func renderDocumentToMarkdown(_ doc: Document) -> String {
var str = ""
var inPreformatting = false
var inList = false
for line in doc.lines {
if inList && !line.isListItem {
str += "\n"
inList = false
}
switch line {
case let .text(text):
if !text.trimmingCharacters(in: .whitespaces).isEmpty {
str += text.htmlEscape()
str += "\n\n"
}
case let .link(url, text: maybeText):
let text = maybeText ?? url.absoluteString
// todo: do ] in the text need to be escaped?
str += "[\(text.htmlEscape())](\(url))"
str += "\n\n"
case let .preformattedToggle(alt: alt):
inPreformatting = !inPreformatting
if inPreformatting {
str += "```"
if let alt = alt {
str += alt
}
str += "\n"
} else {
str += "```"
str += "\n\n"
}
case let .preformattedText(text):
str += text
str += "\n"
case let .heading(text, level: level):
str += String(repeating: "#", count: level.rawValue)
str += " "
str += text.htmlEscape()
str += "\n\n"
case let .unorderedListItem(text):
if !inList {
inList = true
}
str += "* \(text.htmlEscape())"
str += "\n"
case let .quote(text):
str += "> "
str += text.htmlEscape()
str += "\n\n"
}
}
return str
}
}