import Foundation import Ink struct PostContentGenerator { private let content: Content private let results: PageGenerationResults private let language: ContentLanguage private let post: Post init(content: Content, results: PageGenerationResults, language: ContentLanguage, post: Post) { self.content = content self.results = results self.language = language self.post = post } func generate() -> String { let parser = MarkdownParser(modifiers: [ Modifier(target: .images, closure: handleImage), Modifier(target: .codeBlocks, closure: handleCode), Modifier(target: .links, closure: handleLink) ]) return parser.html(from: post.localized(in: language).text) } private func handleImage( html: String, markdown: Substring ) -> String { results.warning("Image in \(postDescription)") return "" } private func handleCode( html: String, markdown: Substring ) -> String { results.warning("Code in \(postDescription)") return "" } private var postDescription: String { "content of post \(post.id) (\(language.shortText))" } private func handleLink( html: String, markdown: Substring ) -> String { let converter = MarkdownLinkProcessor(content: content, results: self, language: language) let markdownUrl = markdown.between("(", and: ")") let text = markdown.between("[", and: "]") guard let url = converter.convert(markdownUrl: markdownUrl)?.url else { return text } return "\(text)" } } extension PostContentGenerator: ItemLinkResults { func externalLink(to url: String) { results.externalLink(to: url) } func missing(page: String, source: String) { results.missing(page: page, source: postDescription) } func linked(to page: Page) { results.linked(to: page) } func missing(tag: String, source: String) { results.missing(tag: tag, source: postDescription) } func linked(to tag: Tag) { results.linked(to: tag) } func missing(file: String, source: String) { results.missing(file: file, source: postDescription) } func require(file: FileResource) { results.require(file: file) } }