struct RouteBlock: KeyedBlockProcessor { enum Key: String { case chartTitle case components case mapTitle case image case caption case file } static let blockId: ContentBlock = .route let content: Content let results: PageGenerationResults let language: ContentLanguage init(content: Content, results: PageGenerationResults, language: ContentLanguage) { self.content = content self.results = results self.language = language } private var thumbnailWidth: Int { content.settings.pages.contentWidth } private var largeImageWidth: Int { content.settings.pages.largeImageWidth } func process(_ arguments: [Key : String], markdown: Substring) -> String { guard let imageId = arguments[.image], let fileId = arguments[.file] else { invalid(markdown) return "" } let rawComponents = arguments[.components] var displayedTypes: Set = [] if let rawComponents { rawComponents.components(separatedBy: ",").compactMap { $0.trimmed.nonEmpty }.forEach { rawType in if let type = RouteStatisticType(rawValue: rawType) { displayedTypes.insert(type) } else { results.warning("Unknown component type '\(rawType)' in route block") } } } if displayedTypes.isEmpty { displayedTypes = Set(RouteStatisticType.allCases) } guard let image = content.image(imageId) else { results.missing(file: imageId, source: "Route block") return "" } guard let file = content.file(fileId) else { results.missing(file: imageId, source: "Route block") return "" } results.used(file: image) results.require(file: file) let thumbnail = image.imageSet(width: thumbnailWidth, height: thumbnailWidth, language: language) results.require(imageSet: thumbnail) let largeImage = image.imageSet(width: largeImageWidth, height: largeImageWidth, language: language) results.require(imageSet: largeImage) results.require(header: .routeJs) let id = imageId.replacingOccurrences(of: ".", with: "-") let views = RouteViews( localization: language == .english ? .english : .german, chartTitle: arguments[.chartTitle], chartId: "chart-" + id, displayedTypes: displayedTypes, mapTitle: arguments[.mapTitle], mapId: "map-" + id, filePath: file.absoluteUrl, imageId: "image-" + id, thumbnail: thumbnail, largeImage: largeImage, caption: arguments[.caption]) results.require(footer: views.script) results.require(icons: displayedTypes.map { $0.icon }) return views.content } }