Add alt text to images

This commit is contained in:
Christoph Hagen 2022-12-21 12:59:42 +01:00
parent 7a0e1300ac
commit 5ecfc0d51d
9 changed files with 66 additions and 57 deletions

View File

@ -39,17 +39,17 @@ struct HTMLElementsGenerator {
"\(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">
<img src="\(file)" loading="lazy" width="\(width)" height="\(height)"/>
<img src="\(file)" loading="lazy" width="\(width)" height="\(height)" alt="\(altText)"/>
</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))"
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 {

View File

@ -56,6 +56,7 @@ struct OverviewSectionGenerator {
let metadata = item.localized(for: language)
var content = [SlideshowImageTemplate.Key : String]()
content[.number] = "\(number + 1)"
content[.altText] = metadata.linkPreviewDescription
if item.state.hasThumbnailLink {
let fullPageUrl = item.fullPageUrl(for: language)

View File

@ -107,7 +107,7 @@ struct PageContentGenerator {
case "svg":
return handleSvg(page: page, file: file, area: alt)
case "gif":
return handleGif(page: page, file: file)
return handleGif(page: page, file: file, altText: alt ?? "gif image")
default:
return handleFile(page: page, file: file, fileExtension: fileExtension)
}
@ -144,14 +144,18 @@ struct PageContentGenerator {
destination: imagePath,
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 {
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)
}
@ -161,14 +165,7 @@ struct PageContentGenerator {
requiredBy: page.path)
largeImageCount += 1
let content: [EnlargeableImageTemplate.Key : String] = [
.image: file.dropAfterLast("."),
.imageExtension: file.lastComponentAfter("."),
.width: "\(Int(size.width))",
.height: "\(Int(size.height))",
.leftText: left,
.rightText: rightTitle ?? "",
.number: "\(largeImageCount)"]
content[.number] = "\(largeImageCount)"
return factory.largeImage.generate(content)
}
@ -193,7 +190,7 @@ struct PageContentGenerator {
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)
results.require(file: imagePath, source: page.path)
@ -202,7 +199,7 @@ struct PageContentGenerator {
}
let width = Int(size.width)
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 {
@ -210,25 +207,36 @@ struct PageContentGenerator {
results.require(file: imagePath, source: page.path)
guard let size = results.getImageSize(atPath: imagePath, source: page.path) else {
return ""
return "" // Missing image warning already produced
}
let width = Int(size.width)
let height = Int(size.height)
var altText = "image " + file.lastComponentAfter("/")
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 }
guard parts.count == 4,
let x = Int(parts[0]),
switch parts.count {
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 partWidth = Int(parts[2]),
let partHeight = Int(parts[3]) else {
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)
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 {
@ -301,6 +309,7 @@ struct PageContentGenerator {
var content = [PageLinkTemplate.Key: String]()
content[.title] = linkedPage.title(for: language)
content[.altText] = ""
let fullThumbnailPath = linkedPage.thumbnailFilePath(for: language).destination
// Note: Here we assume that the thumbnail was already used elsewhere, so already generated

View File

@ -30,6 +30,7 @@ struct ThumbnailListGenerator {
let (thumbnailSourcePath, thumbnailDestPath) = item.thumbnailFilePath(for: language)
let thumbnailDestNoExtension = thumbnailDestPath.dropAfterLast(".")
content[.image] = parent.relativePathToFileWithPath(thumbnailDestNoExtension)
content[.altText] = metadata.linkPreviewDescription
if style == .large, let suffix = metadata.thumbnailSuffix {
content[.title] = factory.html.make(title: metadata.title, suffix: suffix)

View File

@ -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
}

View File

@ -1,15 +1,31 @@
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 {
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"
}
typealias Key = PageImageTemplateKey
static let templateName = "image.html"

View File

@ -3,6 +3,7 @@ import Foundation
struct PageLinkTemplate: Template {
enum Key: String, CaseIterable {
case altText = "ALT_TEXT"
case url = "URL"
case image = "IMAGE"
case title = "TITLE"

View File

@ -3,6 +3,7 @@ import Foundation
struct SlideshowImageTemplate: Template {
enum Key: String, CaseIterable {
case altText = "ALT_TEXT"
case url = "URL"
case image = "IMAGE"
case title = "TITLE"

View File

@ -6,6 +6,7 @@ protocol ThumbnailTemplate {
}
enum ThumbnailKey: String, CaseIterable {
case altText = "ALT_TEXT"
case url = "URL"
case image = "IMAGE"
case title = "TITLE"