diff --git a/.pa11yci.json b/.pa11yci.json new file mode 100644 index 0000000..8fb6192 --- /dev/null +++ b/.pa11yci.json @@ -0,0 +1,10 @@ +{ + "defaults": { + "standard": "WCAG2AA", + "runners": ["axe", "htmlcs"], + "timeout": 60000, + "chromeLaunchConfig": { + "args": ["--no-sandbox", "--disable-dev-shm-usage"] + } + } +} diff --git a/layouts/_markup/render-image.html b/layouts/_markup/render-image.html new file mode 100644 index 0000000..9c7d95f --- /dev/null +++ b/layouts/_markup/render-image.html @@ -0,0 +1,30 @@ +{{- /* +Content images. The Markdown title ("![alt](src "© Credit")") is the photo credit; it is shown +as a caption instead of a tooltip, so that it is available on touch devices and to screen readers. +An image on its own line becomes a figure; images sharing a paragraph get an inline credit. +*/ -}} +{{- $src := .Destination -}} +{{- $width := 0 -}} +{{- $height := 0 -}} +{{- with or (.PageInner.Resources.Get (strings.TrimPrefix "./" .Destination)) (resources.Get .Destination) -}} + {{- $src = .RelPermalink -}} + {{- if and (eq .ResourceType "image") (ne .MediaType.SubType "svg") -}} + {{- $width = .Width -}} + {{- $height = .Height -}} + {{- end -}} +{{- end -}} +{{- /* A title that only repeats the alt text is not a credit. */ -}} +{{- $credit := cond (eq .Title .PlainText) "" .Title -}} +{{- $img := printf `%s` (htmlEscape $src) (htmlEscape .PlainText) (cond (gt $width 0) (printf ` width="%d" height="%d"` $width $height) "") -}} +{{- if .IsBlock -}} +
+{{ $img | safeHTML }} +{{- with $credit }} +
{{ . }}
+{{- end }} +
+{{- else if $credit -}} +{{ $img | safeHTML }}{{ $credit }} +{{- else -}} +{{ $img | safeHTML }} +{{- end -}} diff --git a/scripts/pa11y.sh b/scripts/pa11y.sh new file mode 100755 index 0000000..e8bfece --- /dev/null +++ b/scripts/pa11y.sh @@ -0,0 +1,34 @@ +#!/bin/sh +# Accessibility check with pa11y-ci, used by CI and for local runs (see README.md). +# Builds the site into a temporary directory, serves it on localhost and checks every page +# in the sitemaps except the past events, which are kept as they were. +set -eu + +PA11Y_CI_VERSION=5.0.0 +PORT=${PORT:-8080} +# Pages that are not checked: past events and the individual news posts. +EXCLUDE='^http://localhost:[0-9]+/[a-z]+/(37c3|38c3|39c3|eh22|posts/[^/]+)/' + +# Use an installed Chrome/Chromium instead of letting Puppeteer download one. +if [ -z "${PUPPETEER_EXECUTABLE_PATH:-}" ]; then + for candidate in /usr/bin/chromium-browser /usr/bin/chromium "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"; do + if [ -x "$candidate" ]; then PUPPETEER_EXECUTABLE_PATH=$candidate; break; fi + done +fi +export PUPPETEER_EXECUTABLE_PATH +export PUPPETEER_SKIP_DOWNLOAD=1 + +cd "$(dirname "$0")/.." +site=$(mktemp -d) +hugo --quiet --buildFuture --buildDrafts --baseURL "http://localhost:$PORT/" -d "$site" +python3 -m http.server "$PORT" --bind 127.0.0.1 -d "$site" >/dev/null 2>&1 & +server=$! +trap 'kill $server; rm -rf "$site"' EXIT +sleep 1 + +status=0 +for lang in de en; do + npx --yes "pa11y-ci@$PA11Y_CI_VERSION" --config .pa11yci.json \ + --sitemap "http://localhost:$PORT/$lang/sitemap.xml" --sitemap-exclude "$EXCLUDE" || status=1 +done +exit $status