83 lines
2.2 KiB
Swift
83 lines
2.2 KiB
Swift
//
|
|
// GeminiMarkdownRenderer.swift
|
|
// GeminiRenderer
|
|
//
|
|
// Created by Shadowfacts on 10/1/21.
|
|
//
|
|
|
|
import Foundation
|
|
import GeminiFormat
|
|
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
|
|
}
|
|
|
|
}
|