On 2025-02-23, Ihor Radchenko wrote:

> Jens Lechtenboerger <lech...@wi.uni-muenster.de> writes:
>
>> I publish with the default value for org-publish-use-timestamps-flag
>> (set to t) and I use ":makeindex t" to create a keyword index.
>>
>> Then, files that are skipped during export (as determined by
>> org-publish-needed-p) are not included in the index, which is
>> surprising to me.
>>
>> I guess that the problem/challenge is that org-publish-collect-index
>> only places index terms into a transient cache, not into files.
>
>> Is there an option that I am missing, or is this a bug?  What do you
>> think?
>
> Maybe a bug. Not sure.
> What might be happening is that you published some files without :index
> t in the past and the results (no index) got cached.
> What if you clear the publishing cache?

I am not sure what you aim for, but please see the attached patch,
including the new tests.  This works for me.

Is there any reason for the transient cache with index terms?
Should an option exist to enable the transient cache for index
terms?  (I do not see a reason but wanted to ask.)

Best wishes,
Jens

>From 2b72663634002c6776e967c1b256a75a5db6232d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jens=20Lechtenb=C3=B6rger?= <lech...@wi.uni-muenster.de>
Date: Wed, 26 Feb 2025 15:56:20 +0100
Subject: [PATCH] ox-publish.el: Enable makeindex with
 org-publish-use-timestamps-flag

* lisp/ox-publish.el (org-publish-collect-index): Do not use transient
cache for index terms, but cache on disk.  Otherwise, index terms of
skipped files do not show up in the index.

* testing/lisp/test-ox-publish.el (test-org-publish/index): New test
case, demonstrating previous issue and fix.
(org-test-publish): Delete generated index files.

* testing/examples/pub/index/: New test files
---
 lisp/ox-publish.el                   |  3 +-
 testing/examples/pub/index/file1.org |  7 +++
 testing/examples/pub/index/file2.org |  7 +++
 testing/lisp/test-ox-publish.el      | 83 +++++++++++++++++++++++++++-
 4 files changed, 97 insertions(+), 3 deletions(-)
 create mode 100644 testing/examples/pub/index/file1.org
 create mode 100644 testing/examples/pub/index/file2.org

diff --git a/lisp/ox-publish.el b/lisp/ox-publish.el
index a57a53cab..64d6335f0 100644
--- a/lisp/ox-publish.el
+++ b/lisp/ox-publish.el
@@ -1049,8 +1049,7 @@ its CDR is a string."
 			      (replace-regexp-in-string
 			       "\\[[0-9]+%\\]\\|\\[[0-9]+/[0-9]+\\]" ""
 			       (org-element-property :raw-value parent)))))))))
-	info))
-     nil 'transient))
+	info))))
   ;; Return output unchanged.
   output)
 
diff --git a/testing/examples/pub/index/file1.org b/testing/examples/pub/index/file1.org
new file mode 100644
index 000000000..512704a42
--- /dev/null
+++ b/testing/examples/pub/index/file1.org
@@ -0,0 +1,7 @@
+#+title: File 1
+
+* Section on foo
+#+index: foo
+
+* Section on bar
+#+index: bar
diff --git a/testing/examples/pub/index/file2.org b/testing/examples/pub/index/file2.org
new file mode 100644
index 000000000..be0861cdb
--- /dev/null
+++ b/testing/examples/pub/index/file2.org
@@ -0,0 +1,7 @@
+#+title: File 2
+
+* Section on baz
+#+index: baz
+
+* Section on foo
+#+index: foo
diff --git a/testing/lisp/test-ox-publish.el b/testing/lisp/test-ox-publish.el
index a8127ccf2..619ba61c9 100644
--- a/testing/lisp/test-ox-publish.el
+++ b/testing/lisp/test-ox-publish.el
@@ -71,7 +71,13 @@ including timestamp directory; otherwise, delete it."
 				"sitemap.org")
 			    base-dir))))
 	(when (and site-map (file-exists-p site-map))
-	  (delete-file site-map))))))
+	  (delete-file site-map)))
+      ;; Delete auto-generated index files, if applicable.
+      (when (plist-get properties :makeindex)
+        (let ((index.inc (expand-file-name "theindex.inc" base-dir))
+              (index.org (expand-file-name "theindex.org" base-dir)))
+	  (when (file-exists-p index.inc) (delete-file index.inc))
+          (when (file-exists-p index.org) (delete-file index.org)))))))
 
 
 ;;; Mandatory properties
@@ -429,6 +435,81 @@ Test updates of source and config file."
 	      (with-temp-buffer
 		(insert-file-contents (expand-file-name "sitemap.org" dir))
 		(buffer-string)))))))
+
+;;; Index creation
+
+(ert-deftest test-org-publish/index ()
+  "Test index creation."
+  ;; Index creation is controlled with `:makeindex' (nil by default).
+  ;; If t, generate theindex.inc (and theindex.org if it does not exist).
+  ;; Index terms are only collected via `org-publish-org-to' (thus,
+  ;; `org-publish-attachment' is not good enough).
+  (should
+   (org-test-publish
+       '(:makeindex t)
+     (lambda (dir) (file-exists-p (expand-file-name "theindex.org" dir)))))
+  (should-not
+   (org-test-publish
+       '(:makeindex nil)
+     (lambda (dir) (file-exists-p (expand-file-name "theindex.org" dir)))))
+  (let ((base (expand-file-name "examples/pub/" org-test-dir))
+        (correct "* B
+  - [[file:index/file1.org::*Section on bar][bar]]
+  - [[file:index/file2.org::*Section on baz][baz]]
+* F
+  - [[file:index/file1.org::*Section on foo][foo]]
+  - [[file:index/file2.org::*Section on foo][foo]]
+"))
+    (should
+     (equal correct
+	    (org-test-publish
+	        '(:makeindex t
+                             :publishing-function org-html-publish-to-html
+			     :exclude "."
+			     :include ("index/file1.org" "index/file2.org"))
+	      (lambda (_)
+	        (with-temp-buffer
+		  (insert-file-contents
+                   (expand-file-name "theindex.inc" base))
+		  (buffer-string))))))
+
+    ;; Check that the index not only contains terms for file2.org but
+    ;; also for index/file1.org, even when the latter file is skipped
+    ;; as unchanged.
+    (let ((pub-dir (make-temp-file "org-test" t))
+          (incorrect "* B
+  - [[file:index/file2.org::*Section on baz][baz]]
+* F
+  - [[file:index/file2.org::*Section on foo][foo]]
+"))
+      ;; First publication, ignore results.
+      (org-test-publish
+	  '(:makeindex t
+                       :publishing-function org-html-publish-to-html
+		       :exclude "."
+		       :include ("index/file1.org" "index/file2.org"))
+        (lambda (_)) nil t pub-dir t)
+      ;; Pretend that a new Emacs session started as follows:
+      ;; Use empty transient cache.
+      ;; Touch file2.org as changed, while file1.org is skipped.
+      (setq org-publish-transient-cache nil)
+      (org-test-publish-touch (expand-file-name "index/file2.org" base))
+      (let ((result
+             (org-test-publish
+	         '(:makeindex t
+                              :publishing-function org-html-publish-to-html
+			      :exclude "."
+			      :include ("index/file1.org" "index/file2.org"))
+	       (lambda (_)
+	         (with-temp-buffer
+		   (insert-file-contents (expand-file-name "theindex.inc" base))
+		   (buffer-string)))
+               nil t pub-dir)))
+        ;; Fails up to Org 9.7.23.
+        (should-not
+         (equal incorrect result))
+        (should
+         (equal correct result))))))
 
 
 ;;; Cross references
-- 
2.25.1

Reply via email to