43 lines
1.0 KiB
Swift
43 lines
1.0 KiB
Swift
|
|
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: "-")
|
|
}
|
|
}
|