103 lines
3.5 KiB
Swift
103 lines
3.5 KiB
Swift
|
|
struct ButtonCommand: CommandProcessor {
|
|
|
|
static let commandType: CommandType = .buttons
|
|
|
|
let content: Content
|
|
|
|
let results: PageGenerationResults
|
|
|
|
init(content: Content, results: PageGenerationResults, language: ContentLanguage) {
|
|
self.content = content
|
|
self.results = results
|
|
}
|
|
|
|
/**
|
|
Format: ``
|
|
Types:
|
|
- Download: `download=<fileId>,<text>,<download-filename?>`
|
|
- External link: `external=<url>,<text>`
|
|
- Git: `git=<url>,<text>`
|
|
- Play: `play-circle=<text>,<click-action>`
|
|
*/
|
|
func process(_ arguments: [String], markdown: Substring) -> String {
|
|
let buttons = arguments.compactMap { convert(button: $0, markdown: markdown) }
|
|
return ContentButtons(items: buttons).content
|
|
}
|
|
|
|
private func convert(button: String, markdown: Substring) -> ContentButtons.Item? {
|
|
guard let type = PageIcon(rawValue: button.dropAfterFirst("=").trimmed) else {
|
|
invalid(markdown)
|
|
return nil
|
|
}
|
|
let parts = button.dropBeforeFirst("=").components(separatedBy: ",").map { $0.trimmed }
|
|
switch type {
|
|
case .buttonDownload:
|
|
return download(arguments: parts, markdown: markdown)
|
|
case .buttonGitLink:
|
|
return link(icon: .buttonGitLink, arguments: parts, markdown: markdown)
|
|
case .buttonExternalLink:
|
|
return link(icon: .buttonExternalLink, arguments: parts, markdown: markdown)
|
|
case .buttonPlay:
|
|
return play(arguments: parts, markdown: markdown)
|
|
default:
|
|
invalid(markdown)
|
|
return nil
|
|
}
|
|
}
|
|
|
|
private func download(arguments: [String], markdown: Substring) -> ContentButtons.Item? {
|
|
guard (2...3).contains(arguments.count) else {
|
|
invalid(markdown)
|
|
return nil
|
|
}
|
|
let fileId = arguments[0].trimmed
|
|
let title = arguments[1].trimmed
|
|
let downloadName = arguments.count > 2 ? arguments[2].trimmed : nil
|
|
|
|
guard let file = content.file(fileId) else {
|
|
results.missing(file: fileId, source: "Download button")
|
|
return nil
|
|
}
|
|
results.require(file: file)
|
|
results.require(icon: .buttonDownload)
|
|
return ContentButtons.Item(
|
|
icon: .buttonDownload,
|
|
filePath: file.absoluteUrl,
|
|
text: title,
|
|
downloadFileName: downloadName)
|
|
}
|
|
|
|
private func link(icon: PageIcon, arguments: [String], markdown: Substring) -> ContentButtons.Item? {
|
|
guard arguments.count == 2 else {
|
|
results.invalid(command: .buttons, markdown)
|
|
return nil
|
|
}
|
|
let rawUrl = arguments[0].trimmed
|
|
guard let url = rawUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {
|
|
results.invalid(command: .buttons, markdown)
|
|
return nil
|
|
}
|
|
|
|
results.externalLink(to: rawUrl)
|
|
results.require(icon: icon)
|
|
|
|
let title = arguments[1].trimmed
|
|
|
|
return .init(icon: icon, filePath: url, text: title)
|
|
}
|
|
|
|
private func play(arguments: [String], markdown: Substring) -> ContentButtons.Item? {
|
|
guard arguments.count == 2 else {
|
|
results.invalid(command: .buttons, markdown)
|
|
return nil
|
|
}
|
|
let text = arguments[0].trimmed
|
|
let event = arguments[1].trimmed
|
|
|
|
results.require(icon: .buttonPlay)
|
|
|
|
return .init(icon: .buttonPlay, filePath: nil, text: text, onClickText: event)
|
|
}
|
|
}
|