Add alt text to images
This commit is contained in:
parent
7a0e1300ac
commit
5ecfc0d51d
@ -39,17 +39,17 @@ struct HTMLElementsGenerator {
|
|||||||
"\(text)<span class=\"icon-next\"></span>"
|
"\(text)<span class=\"icon-next\"></span>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func image(file: String, width: Int, height: Int) -> String {
|
func image(file: String, width: Int, height: Int, altText: String) -> String {
|
||||||
"""
|
"""
|
||||||
<span class="image">
|
<span class="image">
|
||||||
<img src="\(file)" loading="lazy" width="\(width)" height="\(height)"/>
|
<img src="\(file)" loading="lazy" width="\(width)" height="\(height)" alt="\(altText)"/>
|
||||||
</span>
|
</span>
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
func svgImage(file: String, part: SVGSelection, width: Int, height: Int) -> String {
|
func svgImage(file: String, part: SVGSelection, width: Int, height: Int, altText: String) -> String {
|
||||||
let path = "\(file)#svgView(viewBox(\(part.x),\(part.y),\(part.width),\(part.height))"
|
let path = "\(file)#svgView(viewBox(\(part.x),\(part.y),\(part.width),\(part.height))"
|
||||||
return image(file: path, width: width, height: height)
|
return image(file: path, width: width, height: height, altText: altText)
|
||||||
}
|
}
|
||||||
|
|
||||||
func downloadButtons(_ buttons: [(file: String, text: String, downloadName: String?)]) -> String {
|
func downloadButtons(_ buttons: [(file: String, text: String, downloadName: String?)]) -> String {
|
||||||
|
@ -56,6 +56,7 @@ struct OverviewSectionGenerator {
|
|||||||
let metadata = item.localized(for: language)
|
let metadata = item.localized(for: language)
|
||||||
var content = [SlideshowImageTemplate.Key : String]()
|
var content = [SlideshowImageTemplate.Key : String]()
|
||||||
content[.number] = "\(number + 1)"
|
content[.number] = "\(number + 1)"
|
||||||
|
content[.altText] = metadata.linkPreviewDescription
|
||||||
|
|
||||||
if item.state.hasThumbnailLink {
|
if item.state.hasThumbnailLink {
|
||||||
let fullPageUrl = item.fullPageUrl(for: language)
|
let fullPageUrl = item.fullPageUrl(for: language)
|
||||||
|
@ -107,7 +107,7 @@ struct PageContentGenerator {
|
|||||||
case "svg":
|
case "svg":
|
||||||
return handleSvg(page: page, file: file, area: alt)
|
return handleSvg(page: page, file: file, area: alt)
|
||||||
case "gif":
|
case "gif":
|
||||||
return handleGif(page: page, file: file)
|
return handleGif(page: page, file: file, altText: alt ?? "gif image")
|
||||||
default:
|
default:
|
||||||
return handleFile(page: page, file: file, fileExtension: fileExtension)
|
return handleFile(page: page, file: file, fileExtension: fileExtension)
|
||||||
}
|
}
|
||||||
@ -144,14 +144,18 @@ struct PageContentGenerator {
|
|||||||
destination: imagePath,
|
destination: imagePath,
|
||||||
requiredBy: page.path)
|
requiredBy: page.path)
|
||||||
|
|
||||||
|
let altText = left.nonEmpty ?? rightTitle ?? "image"
|
||||||
|
|
||||||
|
var content = [PageImageTemplateKey : String]()
|
||||||
|
content[.altText] = altText
|
||||||
|
content[.image] = file.dropAfterLast(".")
|
||||||
|
content[.imageExtension] = file.lastComponentAfter(".")
|
||||||
|
content[.width] = "\(Int(size.width))"
|
||||||
|
content[.height] = "\(Int(size.height))"
|
||||||
|
content[.leftText] = left
|
||||||
|
content[.rightText] = rightTitle ?? ""
|
||||||
|
|
||||||
guard createFullScreenVersion else {
|
guard createFullScreenVersion else {
|
||||||
let content: [PageImageTemplate.Key : String] = [
|
|
||||||
.image: file.dropAfterLast("."),
|
|
||||||
.imageExtension: file.lastComponentAfter("."),
|
|
||||||
.width: "\(Int(size.width))",
|
|
||||||
.height: "\(Int(size.height))",
|
|
||||||
.leftText: left,
|
|
||||||
.rightText: rightTitle ?? ""]
|
|
||||||
return factory.image.generate(content)
|
return factory.image.generate(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,14 +165,7 @@ struct PageContentGenerator {
|
|||||||
requiredBy: page.path)
|
requiredBy: page.path)
|
||||||
|
|
||||||
largeImageCount += 1
|
largeImageCount += 1
|
||||||
let content: [EnlargeableImageTemplate.Key : String] = [
|
content[.number] = "\(largeImageCount)"
|
||||||
.image: file.dropAfterLast("."),
|
|
||||||
.imageExtension: file.lastComponentAfter("."),
|
|
||||||
.width: "\(Int(size.width))",
|
|
||||||
.height: "\(Int(size.height))",
|
|
||||||
.leftText: left,
|
|
||||||
.rightText: rightTitle ?? "",
|
|
||||||
.number: "\(largeImageCount)"]
|
|
||||||
return factory.largeImage.generate(content)
|
return factory.largeImage.generate(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +190,7 @@ 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 {
|
private func handleGif(page: Element, file: String, altText: 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)
|
||||||
|
|
||||||
@ -202,7 +199,7 @@ struct PageContentGenerator {
|
|||||||
}
|
}
|
||||||
let width = Int(size.width)
|
let width = Int(size.width)
|
||||||
let height = Int(size.height)
|
let height = Int(size.height)
|
||||||
return factory.html.image(file: file, width: width, height: height)
|
return factory.html.image(file: file, width: width, height: height, altText: altText)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleSvg(page: Element, file: String, area: String?) -> String {
|
private func handleSvg(page: Element, file: String, area: String?) -> String {
|
||||||
@ -210,25 +207,36 @@ struct PageContentGenerator {
|
|||||||
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 {
|
guard let size = results.getImageSize(atPath: imagePath, source: page.path) else {
|
||||||
return ""
|
return "" // Missing image warning already produced
|
||||||
}
|
}
|
||||||
let width = Int(size.width)
|
let width = Int(size.width)
|
||||||
let height = Int(size.height)
|
let height = Int(size.height)
|
||||||
|
|
||||||
|
var altText = "image " + file.lastComponentAfter("/")
|
||||||
guard let area = area else {
|
guard let area = area else {
|
||||||
return factory.html.image(file: file, width: width, height: height)
|
return factory.html.image(file: file, width: width, height: height, altText: altText)
|
||||||
}
|
}
|
||||||
let parts = area.components(separatedBy: ",").map { $0.trimmed }
|
let parts = area.components(separatedBy: ",").map { $0.trimmed }
|
||||||
guard parts.count == 4,
|
switch parts.count {
|
||||||
let x = Int(parts[0]),
|
case 1:
|
||||||
|
return factory.html.image(file: file, width: width, height: height, altText: parts[0])
|
||||||
|
case 4:
|
||||||
|
break
|
||||||
|
case 5:
|
||||||
|
altText = parts[4]
|
||||||
|
default:
|
||||||
|
results.warning("Invalid area string for svg image", source: page.path)
|
||||||
|
return factory.html.image(file: file, width: width, height: height, altText: altText)
|
||||||
|
}
|
||||||
|
guard let x = Int(parts[0]),
|
||||||
let y = Int(parts[1]),
|
let y = Int(parts[1]),
|
||||||
let partWidth = Int(parts[2]),
|
let partWidth = Int(parts[2]),
|
||||||
let partHeight = Int(parts[3]) 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.image(file: file, width: width, height: height)
|
return factory.html.image(file: file, width: width, height: height, altText: altText)
|
||||||
}
|
}
|
||||||
let part = SVGSelection(x, y, partWidth, partHeight)
|
let part = SVGSelection(x, y, partWidth, partHeight)
|
||||||
return factory.html.svgImage(file: file, part: part, width: width, height: height)
|
return factory.html.svgImage(file: file, part: part, width: width, height: height, altText: altText)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleFile(page: Element, file: String, fileExtension: String) -> String {
|
private func handleFile(page: Element, file: String, fileExtension: String) -> String {
|
||||||
@ -301,6 +309,7 @@ struct PageContentGenerator {
|
|||||||
var content = [PageLinkTemplate.Key: String]()
|
var content = [PageLinkTemplate.Key: String]()
|
||||||
|
|
||||||
content[.title] = linkedPage.title(for: language)
|
content[.title] = linkedPage.title(for: language)
|
||||||
|
content[.altText] = ""
|
||||||
|
|
||||||
let fullThumbnailPath = linkedPage.thumbnailFilePath(for: language).destination
|
let fullThumbnailPath = linkedPage.thumbnailFilePath(for: language).destination
|
||||||
// Note: Here we assume that the thumbnail was already used elsewhere, so already generated
|
// Note: Here we assume that the thumbnail was already used elsewhere, so already generated
|
||||||
|
@ -30,6 +30,7 @@ struct ThumbnailListGenerator {
|
|||||||
let (thumbnailSourcePath, thumbnailDestPath) = item.thumbnailFilePath(for: language)
|
let (thumbnailSourcePath, thumbnailDestPath) = item.thumbnailFilePath(for: language)
|
||||||
let thumbnailDestNoExtension = thumbnailDestPath.dropAfterLast(".")
|
let thumbnailDestNoExtension = thumbnailDestPath.dropAfterLast(".")
|
||||||
content[.image] = parent.relativePathToFileWithPath(thumbnailDestNoExtension)
|
content[.image] = parent.relativePathToFileWithPath(thumbnailDestNoExtension)
|
||||||
|
content[.altText] = metadata.linkPreviewDescription
|
||||||
|
|
||||||
if style == .large, let suffix = metadata.thumbnailSuffix {
|
if style == .large, let suffix = metadata.thumbnailSuffix {
|
||||||
content[.title] = factory.html.make(title: metadata.title, suffix: suffix)
|
content[.title] = factory.html.make(title: metadata.title, suffix: suffix)
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
import Foundation
|
|
||||||
|
|
||||||
struct EnlargeableImageTemplate: Template {
|
|
||||||
|
|
||||||
enum Key: String, CaseIterable {
|
|
||||||
case image = "IMAGE"
|
|
||||||
case imageExtension = "IMAGE_EXT"
|
|
||||||
case width = "WIDTH"
|
|
||||||
case height = "HEIGHT"
|
|
||||||
case leftText = "LEFT_TEXT"
|
|
||||||
case rightText = "RIGHT_TEXT"
|
|
||||||
case number = "NUMBER"
|
|
||||||
}
|
|
||||||
|
|
||||||
static let templateName = "image-enlargeable.html"
|
|
||||||
|
|
||||||
let raw: String
|
|
||||||
|
|
||||||
let results: GenerationResultsHandler
|
|
||||||
|
|
||||||
}
|
|
@ -1,15 +1,31 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
enum PageImageTemplateKey: String, CaseIterable {
|
||||||
|
case altText = "ALT_TEXT"
|
||||||
|
case image = "IMAGE"
|
||||||
|
case imageExtension = "IMAGE_EXT"
|
||||||
|
case width = "WIDTH"
|
||||||
|
case height = "HEIGHT"
|
||||||
|
case leftText = "LEFT_TEXT"
|
||||||
|
case rightText = "RIGHT_TEXT"
|
||||||
|
case number = "NUMBER"
|
||||||
|
}
|
||||||
|
|
||||||
|
struct EnlargeableImageTemplate: Template {
|
||||||
|
|
||||||
|
typealias Key = PageImageTemplateKey
|
||||||
|
|
||||||
|
static let templateName = "image-enlargeable.html"
|
||||||
|
|
||||||
|
let raw: String
|
||||||
|
|
||||||
|
let results: GenerationResultsHandler
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
struct PageImageTemplate: Template {
|
struct PageImageTemplate: Template {
|
||||||
|
|
||||||
enum Key: String, CaseIterable {
|
typealias Key = PageImageTemplateKey
|
||||||
case image = "IMAGE"
|
|
||||||
case imageExtension = "IMAGE_EXT"
|
|
||||||
case width = "WIDTH"
|
|
||||||
case height = "HEIGHT"
|
|
||||||
case leftText = "LEFT_TEXT"
|
|
||||||
case rightText = "RIGHT_TEXT"
|
|
||||||
}
|
|
||||||
|
|
||||||
static let templateName = "image.html"
|
static let templateName = "image.html"
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ import Foundation
|
|||||||
struct PageLinkTemplate: Template {
|
struct PageLinkTemplate: Template {
|
||||||
|
|
||||||
enum Key: String, CaseIterable {
|
enum Key: String, CaseIterable {
|
||||||
|
case altText = "ALT_TEXT"
|
||||||
case url = "URL"
|
case url = "URL"
|
||||||
case image = "IMAGE"
|
case image = "IMAGE"
|
||||||
case title = "TITLE"
|
case title = "TITLE"
|
||||||
|
@ -3,6 +3,7 @@ import Foundation
|
|||||||
struct SlideshowImageTemplate: Template {
|
struct SlideshowImageTemplate: Template {
|
||||||
|
|
||||||
enum Key: String, CaseIterable {
|
enum Key: String, CaseIterable {
|
||||||
|
case altText = "ALT_TEXT"
|
||||||
case url = "URL"
|
case url = "URL"
|
||||||
case image = "IMAGE"
|
case image = "IMAGE"
|
||||||
case title = "TITLE"
|
case title = "TITLE"
|
||||||
|
@ -6,6 +6,7 @@ protocol ThumbnailTemplate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum ThumbnailKey: String, CaseIterable {
|
enum ThumbnailKey: String, CaseIterable {
|
||||||
|
case altText = "ALT_TEXT"
|
||||||
case url = "URL"
|
case url = "URL"
|
||||||
case image = "IMAGE"
|
case image = "IMAGE"
|
||||||
case title = "TITLE"
|
case title = "TITLE"
|
||||||
|
Loading…
Reference in New Issue
Block a user