diff --git a/Sources/Generator/Extensions/String+Extensions.swift b/Sources/Generator/Extensions/String+Extensions.swift index f85d707..11236e1 100644 --- a/Sources/Generator/Extensions/String+Extensions.swift +++ b/Sources/Generator/Extensions/String+Extensions.swift @@ -82,6 +82,10 @@ extension Substring { func between(first: String, andLast last: String) -> String { dropBeforeFirst(first).dropAfterLast(last) } + + func last(after: String) -> String { + components(separatedBy: after).last! + } } extension String { diff --git a/Sources/Generator/Generators/PageContentGenerator.swift b/Sources/Generator/Generators/PageContentGenerator.swift index 14a90ad..e26b837 100644 --- a/Sources/Generator/Generators/PageContentGenerator.swift +++ b/Sources/Generator/Generators/PageContentGenerator.swift @@ -41,8 +41,11 @@ struct PageContentGenerator { let htmlModifier = Modifier(target: .html) { html, markdown in handleHTML(page: page, language: language, html: html, markdown: markdown) } + let headlinesModifier = Modifier(target: .headings) { html, markdown in + handleHeadlines(page: page, language: language, html: html, markdown: markdown) + } - let parser = MarkdownParser(modifiers: [imageModifier, codeModifier, linkModifier, htmlModifier]) + let parser = MarkdownParser(modifiers: [imageModifier, codeModifier, linkModifier, htmlModifier, headlinesModifier]) return (parser.html(from: content), hasCodeContent) } @@ -77,6 +80,19 @@ struct PageContentGenerator { return html } + private func handleHeadlines(page: Element, language: String, 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: ">") + } + private func processMarkdownImage(markdown: Substring, html: String, page: Element, language: String, largeImageCount: inout Int) -> String { // Split the markdown ![alt](file title) // There are several known shorthand commands