commit 69f8b8646b8a68e2fbac904685f09887e2608e78
parent 07d70951be90774505295492b981fef2d551b20c
Author: David Eisinger <[email protected]>
Date: Tue, 8 Sep 2026 23:33:33 -0400
Use alt text for Gemini image links
Diffstat:
2 files changed, 38 insertions(+), 12 deletions(-)
diff --git a/bin/check-gemtext b/bin/check-gemtext
@@ -11,11 +11,15 @@ repo = Path(__file__).resolve().parent.parent
with tempfile.TemporaryDirectory(prefix="gemtext-check-") as directory:
root = Path(directory)
(root / "layouts/partials").mkdir(parents=True)
+ (root / "layouts/shortcodes").mkdir()
(root / "content").mkdir()
for name in ("gemtext.gmi", "gemtext-links.gmi"):
shutil.copy(repo / "themes/v2/layouts/partials" / name, root / "layouts/partials" / name)
(root / "hugo.toml").write_text('baseURL = "https://example.org/"\ndisableKinds = ["home", "taxonomy", "term", "RSS", "sitemap"]\n')
(root / "layouts/single.html").write_text('{{ partial "gemtext.gmi" (dict "content" .RawContent "page" .) }}')
+ # Match the image shortcodes' HTML without fetching or resizing images.
+ (root / "layouts/shortcodes/dither.html").write_text('<img src="/{{ .Get 0 }}" {{ with .Inner }}alt="{{ . }}"{{ end }}>')
+ (root / "layouts/shortcodes/thumbnail.html").write_text('<img src="/{{ .Get 0 }}">{{ with .Inner }}<figcaption>{{ . }}</figcaption>{{ end }}')
(root / "content/check.md").write_text('''---
title: Check
references:
@@ -53,6 +57,15 @@ An [unresolved][98] reference.
[3]: https://source.org/post
[4]: https://example.org/guide
+{{<dither bare.png "782x600" />}}
+{{<dither "photos/beach.png" "782x600">}}A "sunny" day & waves.{{</dither>}}
+
+{{<dither garden.png "782x600">}}A garden
+with flowers.{{</dither>}}
+
+{{<thumbnail thumb.png "782x600">}}A caption & a view.{{</thumbnail>}}
+{{<thumbnail "photos/uncaptioned.png" "782x600" />}}
+
Last paragraph with [_a book_][2].''')
subprocess.run(["hugo", "build", "--source", str(root)], check=True)
result = (root / "public/check/index.html").read_text()
@@ -68,6 +81,9 @@ Last paragraph with [_a book_][2].''')
"Read inline too.\n\n=> https://example.org/inline inline",
"```markdown\nLiteral [first][1].\n\n[99]: https://example.org/code-only\n```",
"An [unresolved][98] reference.",
+ '=> /bare.png\n=> /photos/beach.png Image: A "sunny" day & waves.',
+ "=> /garden.png Image: A garden with flowers.",
+ "=> /thumb.png Image: A caption & a view.\n=> /photos/uncaptioned.png",
"Last paragraph with _a book_.\n\n=> https://example.org/second a book",
]
for fragment in expected:
diff --git a/themes/v2/layouts/partials/gemtext.gmi b/themes/v2/layouts/partials/gemtext.gmi
@@ -31,9 +31,6 @@
{{- $content = delimit $lines "\n" -}}
-{{- /* Place descriptive links after the paragraph that uses them. */ -}}
-{{- $content = partial "gemtext-links.gmi" (dict "content" $content "references" $references "page" $page) -}}
-
{{- /* Replace audio tags */ -}}
{{- $audioRE := `<audio controls src="(.*/([^"]+))"></audio>` -}}
{{- range findRE $audioRE $content -}}
@@ -42,18 +39,31 @@
{{- $content = replace $content . (printf "=> %s %s" $url (substr $title 0 -4)) -}}
{{- end -}}
-{{- /* Photo processing */ -}}
-{{- range findRE `(?s){{<dither[^>]*>}}.*?{{</dither>}}` $content -}}
- {{- $rendered := $page.RenderString . -}}
- {{- $url := $rendered | replaceRE `(?s).*src="([^"]+)".*` "=> $1" -}}
- {{- $content = replace $content . $url -}}
-{{- end -}}
-{{- range findRE `{{<(dither|thumbnail) [^/]+/>}}` $content -}}
+{{- /* Render image descriptions before processing prose links. */ -}}
+{{- $imagePattern := `(?s){{<(?:dither|thumbnail)\s[^>]*[^/]>}}.*?{{</(?:dither|thumbnail)>}}|{{<(?:dither|thumbnail)\s[^>]*?/>}}` -}}
+{{- range findRE $imagePattern $content -}}
{{- $rendered := $page.RenderString . -}}
- {{- $url := $rendered | replaceRE `(?s).*src="([^"]+)".*` "=> $1" -}}
- {{- $content = replace $content . $url -}}
+ {{- $url := $rendered | replaceRE `(?s).*src="([^"]+)".*` "$1" -}}
+ {{- $label := "" -}}
+ {{- with findRE `\balt="[^"]*"` $rendered 1 -}}
+ {{- $label = index . 0 | replaceRE `^alt="([^"]*)"$` "$1" -}}
+ {{- end -}}
+ {{- if not $label -}}
+ {{- with findRE `(?s)<figcaption>.*?</figcaption>` $rendered 1 -}}
+ {{- $label = index . 0 -}}
+ {{- end -}}
+ {{- end -}}
+ {{- $label = $label | plainify | htmlUnescape | replaceRE `\s+` " " | strings.TrimSpace -}}
+ {{- $link := printf "=> %s" $url -}}
+ {{- with $label -}}
+ {{- $link = printf "%s Image: %s" $link . -}}
+ {{- end -}}
+ {{- $content = replace $content . $link -}}
{{- end -}}
+{{- /* Place descriptive links after the paragraph that uses them. */ -}}
+{{- $content = partial "gemtext-links.gmi" (dict "content" $content "references" $references "page" $page) -}}
+
{{- /* Misc. markup fixes */ -}}
{{- $content = $content | replaceRE `<!--more-->\n+` "" -}}
{{- $content = $content | replaceRE `(?m)^[ ]+>` ">" -}}