Add navigation settings, fix page generation
This commit is contained in:
@ -0,0 +1,24 @@
|
||||
|
||||
struct BoxCommandProcessor: CommandProcessor {
|
||||
|
||||
let commandType: ShorthandMarkdownKey = .box
|
||||
|
||||
let results: PageGenerationResults
|
||||
|
||||
init(content: Content, results: PageGenerationResults) {
|
||||
self.results = results
|
||||
}
|
||||
|
||||
/**
|
||||
Format: ``
|
||||
*/
|
||||
func process(_ arguments: [String], markdown: Substring) -> String {
|
||||
guard arguments.count > 1 else {
|
||||
results.invalid(command: .box, markdown)
|
||||
return ""
|
||||
}
|
||||
let title = arguments[0]
|
||||
let text = arguments.dropFirst().joined(separator: ";")
|
||||
return ContentBox(title: title, text: text).content
|
||||
}
|
||||
}
|
@ -3,7 +3,6 @@ struct IconCommandProcessor: CommandProcessor {
|
||||
|
||||
let commandType: ShorthandMarkdownKey = .icons
|
||||
|
||||
|
||||
let results: PageGenerationResults
|
||||
|
||||
init(content: Content, results: PageGenerationResults) {
|
||||
|
@ -13,7 +13,7 @@ struct InlineLinkProcessor {
|
||||
|
||||
let language: ContentLanguage
|
||||
|
||||
func handleLink(html: String, markdown: Substring) -> String {
|
||||
func process(html: String, markdown: Substring) -> String {
|
||||
let url = markdown.between("(", and: ")")
|
||||
if url.hasPrefix(pageLinkMarker) {
|
||||
return handleInlinePageLink(url: url, html: html, markdown: markdown)
|
||||
@ -56,7 +56,7 @@ struct InlineLinkProcessor {
|
||||
return markdown.between("[", and: "]")
|
||||
}
|
||||
results.linked(to: tag)
|
||||
let tagPath = content.absoluteUrlToTag(tag, language: language)
|
||||
let tagPath = tag.absoluteUrl(in: language)
|
||||
return html.replacingOccurrences(of: textToChange, with: tagPath)
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,25 @@
|
||||
import Splash
|
||||
|
||||
struct PageCodeProcessor {
|
||||
|
||||
private let codeHighlightFooter = "<script>hljs.highlightAll();</script>"
|
||||
|
||||
private let swift = SyntaxHighlighter(format: HTMLOutputFormat())
|
||||
|
||||
let results: PageGenerationResults
|
||||
|
||||
init(results: PageGenerationResults) {
|
||||
self.results = results
|
||||
}
|
||||
|
||||
func process(_ html: String, markdown: Substring) -> String {
|
||||
guard markdown.starts(with: "```swift") else {
|
||||
results.require(header: .codeHightlighting)
|
||||
results.require(footer: codeHighlightFooter)
|
||||
return html // Just use normal code highlighting
|
||||
}
|
||||
// Highlight swift code using Splash
|
||||
let code = markdown.between("```swift", and: "```").trimmed
|
||||
return "<pre><code>" + swift.highlight(code) + "</pre></code>"
|
||||
}
|
||||
}
|
153
CHDataManagement/Generator/Page Content/PageHtmlProcessor.swift
Normal file
153
CHDataManagement/Generator/Page Content/PageHtmlProcessor.swift
Normal file
@ -0,0 +1,153 @@
|
||||
import SwiftSoup
|
||||
|
||||
/**
|
||||
Handles both inline HTML and the external HTML command
|
||||
*/
|
||||
struct PageHtmlProcessor: CommandProcessor {
|
||||
|
||||
let commandType: ShorthandMarkdownKey = .includedHtml
|
||||
|
||||
let results: PageGenerationResults
|
||||
|
||||
let content: Content
|
||||
|
||||
init(content: Content, results: PageGenerationResults) {
|
||||
self.content = content
|
||||
self.results = results
|
||||
}
|
||||
|
||||
/**
|
||||
Handle the HTML command
|
||||
|
||||
Format: ``
|
||||
*/
|
||||
func process(_ arguments: [String], markdown: Substring) -> String {
|
||||
guard arguments.count == 1 else {
|
||||
results.invalid(command: .includedHtml, markdown)
|
||||
return ""
|
||||
}
|
||||
let fileId = arguments[0]
|
||||
guard let file = content.file(fileId) else {
|
||||
results.missing(file: fileId, source: "External HTML command")
|
||||
return ""
|
||||
}
|
||||
let content = file.textContent()
|
||||
checkResources(in: content)
|
||||
return content
|
||||
}
|
||||
|
||||
/**
|
||||
Handle inline HTML
|
||||
*/
|
||||
func process(_ html: String, markdown: Substring) -> String {
|
||||
checkResources(in: html)
|
||||
return html
|
||||
}
|
||||
|
||||
private func checkResources(in html: String) {
|
||||
let document: Document
|
||||
do {
|
||||
document = try SwiftSoup.parse(html)
|
||||
} catch {
|
||||
results.warning("Failed to parse inline HTML: \(error)")
|
||||
return
|
||||
}
|
||||
|
||||
checkImages(in: document)
|
||||
checkLinks(in: document)
|
||||
checkSourceSets(in: document)
|
||||
}
|
||||
|
||||
private func checkImages(in document: Document) {
|
||||
let srcAttributes: [String]
|
||||
do {
|
||||
let imgElements = try document.select("img")
|
||||
|
||||
srcAttributes = try imgElements.array()
|
||||
.compactMap { try $0.attr("src") }
|
||||
.filter { !$0.trimmed.isEmpty }
|
||||
} catch {
|
||||
results.warning("Failed to check 'src' attributes of <img> elements in inline HTML: \(error)")
|
||||
return
|
||||
}
|
||||
|
||||
for src in srcAttributes {
|
||||
results.warning("Found image in html: \(src)")
|
||||
}
|
||||
}
|
||||
|
||||
private func checkLinks(in document: Document) {
|
||||
let hrefs: [String]
|
||||
do {
|
||||
let linkElements = try document.select("a")
|
||||
|
||||
hrefs = try linkElements.array()
|
||||
.compactMap { try $0.attr("href").trimmed }
|
||||
.filter { !$0.isEmpty }
|
||||
} catch {
|
||||
results.warning("Failed to check 'href' attributes of <a> elements in inline HTML: \(error)")
|
||||
return
|
||||
}
|
||||
|
||||
for url in hrefs {
|
||||
if url.hasPrefix("http://") || url.hasPrefix("https://") {
|
||||
results.externalLink(to: url)
|
||||
} else {
|
||||
results.warning("Relative link in HTML: \(url)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func checkSourceSets(in document: Document) {
|
||||
let sources: [Element]
|
||||
do {
|
||||
sources = try document.select("source").array()
|
||||
} catch {
|
||||
results.warning("Failed to find <source> elements in inline HTML: \(error)")
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private func checkSourceSetAttributes(sources: [Element]) {
|
||||
let srcSets: [String]
|
||||
do {
|
||||
srcSets = try sources
|
||||
.compactMap { try $0.attr("srcset") }
|
||||
.filter { !$0.trimmed.isEmpty }
|
||||
} catch {
|
||||
results.warning("Failed to check 'srcset' attributes of <source> elements in inline HTML: \(error)")
|
||||
return
|
||||
}
|
||||
|
||||
for src in srcSets {
|
||||
results.warning("Found source set in html: \(src)")
|
||||
}
|
||||
}
|
||||
|
||||
private func checkSourceAttributes(sources: [Element]) {
|
||||
let srcAttributes: [String]
|
||||
do {
|
||||
srcAttributes = try sources
|
||||
.compactMap { try $0.attr("src") }
|
||||
.filter { !$0.trimmed.isEmpty }
|
||||
} catch {
|
||||
results.warning("Failed to check 'src' attributes of <source> elements in inline HTML: \(error)")
|
||||
return
|
||||
}
|
||||
|
||||
for src in srcAttributes {
|
||||
guard content.isValidIdForFile(src) else {
|
||||
results.warning("Found source in html: \(src)")
|
||||
continue
|
||||
}
|
||||
guard let file = content.file(src) else {
|
||||
results.warning("Found source in html: \(src)")
|
||||
continue
|
||||
}
|
||||
#warning("Either find files by their full path, or replace file id with full path")
|
||||
results.require(file: file)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user