Pedro Andres Aranda Gutierrez <paag...@gmail.com> writes:

> after giving ox-html a second (and a third read), there are too many
> dependencies to make a clean move a simple task.
> It will take me more time than I have right now. So why not fixing the bug
> now and doing the factoring out later?

See the attached patch. Let me know if the factored out part is not
sufficient for your needs.

>From 7e1e4e4ab89ae57f87c599e95e47272278711847 Mon Sep 17 00:00:00 2001
Message-ID: <7e1e4e4ab89ae57f87c599e95e47272278711847.1743259382.git.yanta...@posteo.net>
From: Ihor Radchenko <yanta...@posteo.net>
Date: Sat, 29 Mar 2025 15:38:48 +0100
Subject: [PATCH] ox: Factor out `org-html-standalone-image-p' into
 `org-export-standalone-link-p'

* lisp/ox.el (org-export-standalone-link-p): New API function to check
for standalone links (sole link in a paragraph, ignoring whitespace).
* lisp/ox-html.el (org-html-standalone-image-p): Use the new API function.
---
 etc/ORG-NEWS    |  6 ++++++
 lisp/ox-html.el | 29 +++++++++--------------------
 lisp/ox.el      | 41 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+), 20 deletions(-)

diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 1b9dc70300..e3fcb5a45b 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -332,6 +332,12 @@ properties.
 
 # This also includes changes in function behavior from Elisp perspective.
 
+*** New function ~org-export-standalone-link-p~
+
+The new function is aimed to be used in export backends that need to
+handle paragraphs containing a single link (for example, image link) specially.
+For example, many export backends export such image links captioned.
+
 *** New function ~org-gnus-no-new-news-other-frame~ (to be used in ~org-link-frame-setup~)
 
 The new function is like ~org-gnus-no-new-news~, but always opens the
diff --git a/lisp/ox-html.el b/lisp/ox-html.el
index 2f4ec12e28..bebd79ca7f 100644
--- a/lisp/ox-html.el
+++ b/lisp/ox-html.el
@@ -3232,26 +3232,15 @@ (defun org-html-standalone-image-p (element info)
 images, set it to:
 
   (lambda (paragraph) (org-element-property :caption paragraph))"
-  (let ((paragraph (pcase (org-element-type element)
-		     (`paragraph element)
-		     (`link (org-element-parent element)))))
-    (and (org-element-type-p paragraph 'paragraph)
-	 (or (not (and (boundp 'org-html-standalone-image-predicate)
-                     (fboundp org-html-standalone-image-predicate)))
-	     (funcall org-html-standalone-image-predicate paragraph))
-	 (catch 'exit
-	   (let ((link-count 0))
-	     (org-element-map (org-element-contents paragraph)
-		 (cons 'plain-text org-element-all-objects)
-	       (lambda (obj)
-		 (when (pcase (org-element-type obj)
-			 (`plain-text (org-string-nw-p obj))
-			 (`link (or (> (cl-incf link-count) 1)
-				    (not (org-html-inline-image-p obj info))))
-			 (_ t))
-		   (throw 'exit nil)))
-	       info nil 'link)
-	     (= link-count 1))))))
+  (org-export-standalone-link-p
+   element info
+   (lambda (link info)
+     (and (or (not (and (boundp 'org-html-standalone-image-predicate)
+                      (fboundp org-html-standalone-image-predicate)))
+              (let ((paragraph (org-element-parent link)))
+                (and (org-element-type-p paragraph 'paragraph)
+	             (funcall org-html-standalone-image-predicate paragraph))))
+          (org-html-inline-image-p link info)))))
 
 (defun org-html-link (link desc info)
   "Transcode a LINK object from Org to HTML.
diff --git a/lisp/ox.el b/lisp/ox.el
index 7e8ffc715d..5e8ec4befb 100644
--- a/lisp/ox.el
+++ b/lisp/ox.el
@@ -4364,6 +4364,47 @@ (defun org-export-inline-image-p (link &optional rules)
 					 (org-element-property :path link))))
 		  (or rules org-export-default-inline-image-rule)))))
 
+(defun org-export-standalone-link-p (element info &optional predicate)
+  "Non-nil if ELEMENT is a standalone link.
+
+INFO is a plist holding contextual information.
+
+An element or object is a standalone link when
+
+  - its type is `paragraph' and its sole content, save for white
+    spaces, is a link;
+
+  - its type is `link' and its containing paragraph has no other
+    content save white spaces.
+
+PREDICATE, when non-nil should be a function accepting two arguments:
+link object and INFO.  For example, to check for only standalone
+images, one can use:
+
+  (lambda (link _info) (org-export-inline-image-p link))"
+  (let ((paragraph (pcase (org-element-type element)
+		     (`paragraph element)
+		     (`link (org-element-parent element))))
+        (link (pcase (org-element-type element)
+                (`paragraph
+                 (org-element-map element 'link #'identity info 'first))
+                (`link element))))
+    (and (org-element-type-p paragraph 'paragraph)
+         link
+	 (or (not predicate) (funcall predicate link info))
+	 (catch 'exit
+	   (let ((link-count 0))
+	     (org-element-map (org-element-contents paragraph)
+		 (cons 'plain-text org-element-all-objects)
+	       (lambda (obj)
+		 (when (pcase (org-element-type obj)
+			 (`plain-text (org-string-nw-p obj))
+			 (`link (> (cl-incf link-count) 1))
+			 (_ t))
+		   (throw 'exit nil)))
+	       info nil 'link)
+	     (= link-count 1))))))
+
 (defun org-export-insert-image-links (data info &optional rules)
   "Insert image links in DATA.
 
-- 
2.47.1

-- 
Ihor Radchenko // yantar92,
Org mode maintainer,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>

Reply via email to