2025-05-02 14:54:41 +02:00

97 lines
3.0 KiB
Swift

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<RouteStatisticType> = []
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
}
}