From d1098e7a1858044ff983357c13540f90c49da024 Mon Sep 17 00:00:00 2001
From: Derek Chen-Becker <oss@chen-becker.org>
Date: Sun, 10 May 2026 07:21:34 -0600
Subject: [PATCH] Generate images in TOC for HTML export

* lisp/ox.el (org-export-toc-entry-backend): Extract the lambda for link
formatting into a new `org-export-toc-default-link-transcoder' defun for
use in other exporters.
* lisp/ox-html.el (org-html--format-toc-headline): Format image links for
the TOC using `org-html-link', but all other link types maintain formatting
using the new `org-export-toc-default-link-transcoder'.
* testing/lisp/test-ox-html.el (org-html/test-toc-images,
org-html/test-toc-links): Create new unit tests to exercise the conditional
formatting of TOC links for image and non-image links.

Prior to this, image links would be rendered in headers, but would be
converted into a plain text filename in the TOC.
---
 lisp/ox-html.el              |  6 +++++-
 lisp/ox.el                   | 13 ++++++++-----
 testing/lisp/test-ox-html.el | 19 +++++++++++++++++++
 3 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/lisp/ox-html.el b/lisp/ox-html.el
index 5f3666ba1..3d4f79de5 100644
--- a/lisp/ox-html.el
+++ b/lisp/ox-html.el
@@ -2589,7 +2589,11 @@ INFO is a plist used as a communication channel."
 			(org-element-property :priority headline)))
 	 (text (org-export-data-with-backend
 		(org-export-get-alt-title headline info)
-		(org-export-toc-entry-backend 'html)
+		(org-export-toc-entry-backend 'html
+                  `(link . ,(lambda (l c i)
+                              (if (org-html-inline-image-p l i)
+                                  (org-html-link l c i)
+                                (org-export-toc-default-link-transcoder l c i)))))
 		info))
 	 (tags (and (eq (plist-get info :with-tags) t)
 		    (org-export-get-tags headline info))))
diff --git a/lisp/ox.el b/lisp/ox.el
index c6f4dcbd7..e0782c1e6 100644
--- a/lisp/ox.el
+++ b/lisp/ox.el
@@ -5687,6 +5687,13 @@ required on headlines excluded from table of contents."
              (> (org-export-get-relative-level headline info)
                 toc-depth)))))
 
+(defun org-export-toc-default-link-transcoder (link contents info)
+  "Format a link by converting to regular text based on LINK, CONTENTS, and INFO."
+  (or contents
+      (org-export-data
+       (org-element-property :raw-link link)
+       info)))
+
 (defun org-export-toc-entry-backend (parent &rest transcoders)
   "Return an export backend appropriate for table of contents entries.
 
@@ -5705,11 +5712,7 @@ transcoding it."
    :transcoders
    (append transcoders
 	   `((footnote-reference . ,#'ignore)
-	     (link . ,(lambda (l c i)
-			(or c
-			    (org-export-data
-			     (org-element-property :raw-link l)
-			     i))))
+	     (link . ,#'org-export-toc-default-link-transcoder)
 	     (radio-target . ,(lambda (_r c _) c))
 	     (target . ,#'ignore)))))
 
diff --git a/testing/lisp/test-ox-html.el b/testing/lisp/test-ox-html.el
index 82e11f472..89ae31caa 100644
--- a/testing/lisp/test-ox-html.el
+++ b/testing/lisp/test-ox-html.el
@@ -1110,6 +1110,25 @@ entirely."
         (expected "\n<ul>\n<li>\n<ul>\n<li>1\n<ul>\n<li>1.1</li>\n</ul>\n</li>\n</ul>\n</li>\n<li>2</li>\n</ul>\n"))
     (should (string= (org-html--toc-text toc-entries nil) expected))))
 
+(ert-deftest org-html/test-toc-images ()
+  "Test the generation of image links in the TOC."
+  (org-test-with-temp-text "* [[file:test.svg]] Test\n\nA test"
+    (let ((export-buffer "*Test HTML Export*")
+          (org-export-show-temporary-export-buffer nil))
+      (org-export-to-buffer 'html export-buffer)
+      (with-current-buffer export-buffer
+        (should (= 1 (how-many "<li>.*<img src=\"test.svg\" .*</li>")))))))
+
+(ert-deftest org-html/test-toc-links ()
+  "Non-image links in the TOC should not result in TOC links."
+  (org-test-with-temp-text "* [[https://orgmode.org][org]] Test\n\nA test"
+    (let ((export-buffer "*Test HTML Export*")
+          (org-export-show-temporary-export-buffer nil))
+      (org-export-to-buffer 'html export-buffer)
+      (with-current-buffer export-buffer
+        (should (= 0 (how-many "<li>.*orgmode.org.*</li>")))))))
+
+
 ;;; Rendering priorities
 
 (ert-deftest ox-html/test-priority ()
-- 
2.43.0

