Support Gif in pages
This commit is contained in:
parent
260de52533
commit
0eee845431
@ -1,5 +1,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
typealias SVGSelection = (x: Int, y: Int, width: Int, height: Int)
|
||||||
|
|
||||||
struct HTMLElementsGenerator {
|
struct HTMLElementsGenerator {
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
@ -37,20 +39,17 @@ struct HTMLElementsGenerator {
|
|||||||
"\(text)<span class=\"icon-next\"></span>"
|
"\(text)<span class=\"icon-next\"></span>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func svgImage(file: String) -> String {
|
func image(file: String, width: Int, height: Int) -> String {
|
||||||
"""
|
"""
|
||||||
<span class="image">
|
<span class="image">
|
||||||
<img src="\(file)"/>
|
<img src="\(file)" loading="lazy" width="\(width) height="\(height)"/>
|
||||||
</span>
|
</span>
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
func svgImage(file: String, x: Int, y: Int, width: Int, height: Int) -> String {
|
func svgImage(file: String, part: SVGSelection, width: Int, height: Int) -> String {
|
||||||
"""
|
let path = "\(file)#svgView(viewBox(\(part.x),\(part.y),\(part.width),\(part.height))"
|
||||||
<span class="image">
|
return image(file: path, width: width, height: height)
|
||||||
<img src="\(file)#svgView(viewBox(\(x), \(y), \(width), \(height)))" style="aspect-ratio:\(Float(width)/Float(height))"/>
|
|
||||||
</span>
|
|
||||||
"""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func downloadButtons(_ buttons: [(file: String, text: String, downloadName: String?)]) -> String {
|
func downloadButtons(_ buttons: [(file: String, text: String, downloadName: String?)]) -> String {
|
||||||
|
@ -103,11 +103,15 @@ struct PageContentGenerator {
|
|||||||
if let _ = VideoType(rawValue: fileExtension) {
|
if let _ = VideoType(rawValue: fileExtension) {
|
||||||
return handleVideo(page: page, file: file, optionString: alt)
|
return handleVideo(page: page, file: file, optionString: alt)
|
||||||
}
|
}
|
||||||
if fileExtension == "svg" {
|
switch fileExtension {
|
||||||
|
case "svg":
|
||||||
return handleSvg(page: page, file: file, area: alt)
|
return handleSvg(page: page, file: file, area: alt)
|
||||||
}
|
case "gif":
|
||||||
|
return handleGif(page: page, file: file)
|
||||||
|
default:
|
||||||
return handleFile(page: page, file: file, fileExtension: fileExtension)
|
return handleFile(page: page, file: file, fileExtension: fileExtension)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func handleShortHandCommand(_ command: ShorthandMarkdownKey, page: Element, language: String, content: String) -> String {
|
private func handleShortHandCommand(_ command: ShorthandMarkdownKey, page: Element, language: String, content: String) -> String {
|
||||||
switch command {
|
switch command {
|
||||||
@ -189,24 +193,42 @@ struct PageContentGenerator {
|
|||||||
return factory.video.generate(sources: sources, options: options)
|
return factory.video.generate(sources: sources, options: options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func handleGif(page: Element, file: String) -> String {
|
||||||
|
let imagePath = page.pathRelativeToRootForContainedInputFile(file)
|
||||||
|
results.require(file: imagePath, source: page.path)
|
||||||
|
|
||||||
|
guard let size = results.getImageSize(atPath: imagePath, source: page.path) else {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
let width = Int(size.width)
|
||||||
|
let height = Int(size.height)
|
||||||
|
return factory.html.image(file: file, width: width, height: height)
|
||||||
|
}
|
||||||
|
|
||||||
private func handleSvg(page: Element, file: String, area: String?) -> String {
|
private func handleSvg(page: Element, file: String, area: String?) -> String {
|
||||||
let imagePath = page.pathRelativeToRootForContainedInputFile(file)
|
let imagePath = page.pathRelativeToRootForContainedInputFile(file)
|
||||||
results.require(file: imagePath, source: page.path)
|
results.require(file: imagePath, source: page.path)
|
||||||
|
|
||||||
|
guard let size = results.getImageSize(atPath: imagePath, source: page.path) else {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
let width = Int(size.width)
|
||||||
|
let height = Int(size.height)
|
||||||
|
|
||||||
guard let area = area else {
|
guard let area = area else {
|
||||||
return factory.html.svgImage(file: file)
|
return factory.html.image(file: file, width: width, height: height)
|
||||||
}
|
}
|
||||||
let parts = area.components(separatedBy: ",").map { $0.trimmed }
|
let parts = area.components(separatedBy: ",").map { $0.trimmed }
|
||||||
guard parts.count == 4,
|
guard parts.count == 4,
|
||||||
let x = Int(parts[0].trimmed),
|
let x = Int(parts[0]),
|
||||||
let y = Int(parts[1].trimmed),
|
let y = Int(parts[1]),
|
||||||
let width = Int(parts[2].trimmed),
|
let partWidth = Int(parts[2]),
|
||||||
let height = Int(parts[3].trimmed) else {
|
let partHeight = Int(parts[3]) else {
|
||||||
results.warning("Invalid area string for svg image", source: page.path)
|
results.warning("Invalid area string for svg image", source: page.path)
|
||||||
return factory.html.svgImage(file: file)
|
return factory.html.image(file: file, width: width, height: height)
|
||||||
}
|
}
|
||||||
|
let part = SVGSelection(x, y, partWidth, partHeight)
|
||||||
return factory.html.svgImage(file: file, x: x, y: y, width: width, height: height)
|
return factory.html.svgImage(file: file, part: part, width: width, height: height)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleFile(page: Element, file: String, fileExtension: String) -> String {
|
private func handleFile(page: Element, file: String, fileExtension: String) -> String {
|
||||||
|
@ -368,7 +368,7 @@ final class GenerationResultsHandler {
|
|||||||
return scaledSize
|
return scaledSize
|
||||||
}
|
}
|
||||||
|
|
||||||
private func getImageSize(atPath path: String, source: String) -> NSSize? {
|
func getImageSize(atPath path: String, source: String) -> NSSize? {
|
||||||
if let size = imageSizeCache[path] {
|
if let size = imageSizeCache[path] {
|
||||||
return size
|
return size
|
||||||
}
|
}
|
||||||
@ -469,9 +469,9 @@ final class GenerationResultsHandler {
|
|||||||
add("Unwritable files", unwritableFiles) { "\($0.key) (required by \($0.value.source)): \($0.value.message)" }
|
add("Unwritable files", unwritableFiles) { "\($0.key) (required by \($0.value.source)): \($0.value.message)" }
|
||||||
add("Missing linked pages", missingLinkedPages) { "\($0.key) (linked by \($0.value))" }
|
add("Missing linked pages", missingLinkedPages) { "\($0.key) (linked by \($0.value))" }
|
||||||
add("Warnings", pageWarnings) { "\($0.source): \($0.message)" }
|
add("Warnings", pageWarnings) { "\($0.source): \($0.message)" }
|
||||||
|
add("Generated files", generatedFiles) { $0 }
|
||||||
add("Drafts", draftPages) { $0 }
|
add("Drafts", draftPages) { $0 }
|
||||||
add("Empty pages", emptyPages) { "\($0.key) (from \($0.value))" }
|
add("Empty pages", emptyPages) { "\($0.key) (from \($0.value))" }
|
||||||
add("Generated files", generatedFiles) { $0 }
|
|
||||||
let data = lines.joined(separator: "\n").data(using: .utf8)!
|
let data = lines.joined(separator: "\n").data(using: .utf8)!
|
||||||
do {
|
do {
|
||||||
try data.createFolderAndWrite(to: file)
|
try data.createFolderAndWrite(to: file)
|
||||||
|
Loading…
Reference in New Issue
Block a user