struct InlineLinkProcessor { private let pageLinkMarker = "page:" private let tagLinkMarker = "tag:" private let fileLinkMarker = "file:" let content: Content let results: PageGenerationResults let language: ContentLanguage func process(html: String, markdown: Substring) -> String { let url = markdown.between("(", and: ")") if url.hasPrefix(pageLinkMarker) { return handleInlinePageLink(url: url, html: html, markdown: markdown) } if url.hasPrefix(tagLinkMarker) { return handleInlineTagLink(url: url, html: html, markdown: markdown) } if url.hasPrefix(fileLinkMarker) { return handleInlineFileLink(url: url, html: html, markdown: markdown) } results.externalLink(to: url) return html } private func handleInlinePageLink(url: String, html: String, markdown: Substring) -> String { // Retain links pointing to elements within a page let textToChange = url.dropAfterFirst("#") let pageId = textToChange.replacingOccurrences(of: pageLinkMarker, with: "") guard let page = content.page(pageId) else { results.missing(page: pageId, source: "Inline page link") // Remove link since the page can't be found return markdown.between("[", and: "]") } guard !page.isDraft else { return markdown.between("[", and: "]") } results.linked(to: page) let pagePath = page.absoluteUrl(in: language) return html.replacingOccurrences(of: textToChange, with: pagePath) } private func handleInlineTagLink(url: String, html: String, markdown: Substring) -> String { // Retain links pointing to elements within a page let textToChange = url.dropAfterFirst("#") let tagId = textToChange.replacingOccurrences(of: tagLinkMarker, with: "") guard let tag = content.tag(tagId) else { results.missing(tag: tagId, source: "Inline tag link") // Remove link since the tag can't be found return markdown.between("[", and: "]") } results.linked(to: tag) let tagPath = tag.absoluteUrl(in: language) return html.replacingOccurrences(of: textToChange, with: tagPath) } private func handleInlineFileLink(url: String, html: String, markdown: Substring) -> String { // Retain links pointing to elements within a page let fileId = url.replacingOccurrences(of: fileLinkMarker, with: "") guard let file = content.file(fileId) else { results.missing(file: fileId, source: "Inline file link") // Remove link since the file can't be found return markdown.between("[", and: "]") } results.require(file: file) let filePath = file.absoluteUrl return html.replacingOccurrences(of: url, with: filePath) } }