Add links to headlines

This commit is contained in:
Christoph Hagen
2025-02-23 10:42:43 +01:00
parent d4c0da0a32
commit cdcbe21c0d
4 changed files with 58 additions and 13 deletions

View File

@ -23,7 +23,6 @@ struct PhoneScreensBlock: OrderedKeyBlockProcessor {
}
func process(_ arguments: [(key: Key, value: String)], markdown: Substring) -> String {
print("Processing Phone Screens Block")
guard let frameId = arguments.first(where: {$0.key == .frame })?.value else {
invalid(markdown)
return ""

View File

@ -19,20 +19,20 @@ struct MarkdownHeadlineProcessor: MarkdownProcessor {
/**
Modify headlines by extracting an id from the headline and adding it into the html element
Format: ##<title>#<id>
The id is created by lowercasing the string, removing all special characters, and replacing spaces with scores
*/
func process(html: String, markdown: Substring) -> String {
let id = markdown
.last(after: "#")
.trimmed
.filter { $0.isNumber || $0.isLetter || $0 == " " }
.lowercased()
.components(separatedBy: " ")
.filter { $0 != "" }
.joined(separator: "-")
let parts = html.components(separatedBy: ">")
return parts[0] + " id=\"\(id)\">" + parts.dropFirst().joined(separator: ">")
let parts2 = markdown.components(separatedBy: "#")
// Determine the type of heading, e.g. 2 for <h2>
let headlineParts = parts2.drop { $0.isEmpty }
let headlineType = parts2.count - headlineParts.count
guard headlineType > 1 && headlineType < 4 else {
return html
}
let title = headlineParts.joined(separator: "#")
let headline = HeadlineLink(level: headlineType, title: title)
return headline.content
}
}

View File

@ -0,0 +1,42 @@
struct HeadlineLink: HtmlProducer {
/// The type of headline, e.g. `2` for `<h2>`
let level: Int
let title: String
var id: String {
title.validHtmlId()
}
func populate(_ result: inout String) {
result += "<h\(level) id='\(id)'>"
result += "<a href='#\(id)'>\(title)</a>"
result += "</h\(level)>"
}
}
private extension String {
static let characterReplacements: [Character: String] = [
"ä": "ae", "ö": "oe", "ü": "ue", "ß": "ss",
"Ä": "Ae", "Ö": "Oe", "Ü": "Ue",
" ": "-", "/": "-", "&": "and"
]
func validHtmlId() -> String {
var result = self.lowercased()
for (char, replacement) in String.characterReplacements {
result = result.replacingOccurrences(of: String(char), with: replacement)
}
result = result.filter { $0.isLetter || $0.isNumber || $0 == "-" }
return result
.components(separatedBy: "-")
.filter { $0 != "" }
.joined(separator: "-")
}
}