From 63c482d0c3782dcb328581f1d56275a131e78610 Mon Sep 17 00:00:00 2001
From: stardiviner <numbchild@gmail.com>
Date: Mon, 22 May 2023 16:25:33 +0800
Subject: [PATCH] org: Implement conditionally inline images displaying logic

* lisp/org.el (org-toggle-inline-images): Implement conditionally
inline images displaying logic based on universal-argument.
---
 etc/ORG-NEWS     |   5 ++
 lisp/org-keys.el |   2 +-
 lisp/org.el      | 117 +++++++++++++++++++++++++++++++++++++++++------
 3 files changed, 108 insertions(+), 16 deletions(-)

diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 8a2a1ec0e..2798fb131 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -113,6 +113,11 @@ accept the INFO channel and return a string.  This makes it possible
 to dynamically generate the content of the resulting ~<head>~ tag in
 the resulting HTML document.
 
+*** ~org-toggle-inline-images~ implement conditionally inline images displaying logic
+
+You can display or hide inline images at point, region, or current
+section through universal-argument.
+
 ** Miscellaneous
 *** ~org-refile~ now saves current position to Org mark ring when jumping to heading
 
diff --git a/lisp/org-keys.el b/lisp/org-keys.el
index edd4059fc..52608b747 100644
--- a/lisp/org-keys.el
+++ b/lisp/org-keys.el
@@ -218,7 +218,7 @@
 (declare-function org-toggle-radio-button "org" (&optional arg))
 (declare-function org-toggle-comment "org" ())
 (declare-function org-toggle-fixed-width "org" ())
-(declare-function org-toggle-inline-images "org" (&optional include-linked beg end))
+(declare-function org-toggle-inline-images "org" (&optional arg beg end include-linked))
 (declare-function org-latex-preview "org" (&optional arg))
 (declare-function org-toggle-narrow-to-subtree "org" ())
 (declare-function org-toggle-ordered-property "org" ())
diff --git a/lisp/org.el b/lisp/org.el
index 362f0c158..83e440632 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -16665,22 +16665,109 @@ SNIPPETS-P indicates if this is run to create snippet images for HTML."
       (when (memq ov org-inline-image-overlays)
         (push ov result)))))
 
-(defun org-toggle-inline-images (&optional include-linked beg end)
-  "Toggle the display of inline images.
-INCLUDE-LINKED is passed to `org-display-inline-images'."
+(defun org-toggle-inline-images (&optional arg beg end)
+  "Toggle the display of inline images at point.
+
+The parameter ARG from `\\[universal-argument]' is used as condition in bellowing \"argument\".
+
+1. No argument, no region selected :: toggle (display or hide dwim) images in current section or image link at point
+2. No argument, region selected :: toggle images in region
+3. C-u argument :: toggle images in the whole buffer
+4. C-u C-u argument, no region selected :: unconditionally hide images in the buffer
+5. M-1 argument, no region selected :: display images in current section with INCLUDE-LINKED
+6. M-1 argument, region selected :: ... in region ...
+7. M-11 argument :: ... in the whole buffer ...
+8. Any other argument :: treat as INCLUDE-LINKED = t"
   (interactive "P")
-  (if (org--inline-image-overlays beg end)
-      (progn
-        (org-remove-inline-images beg end)
-        (when (called-interactively-p 'interactive)
-	  (message "Inline image display turned off")))
-    (org-display-inline-images include-linked nil beg end)
-    (when (called-interactively-p 'interactive)
-      (let ((new (org--inline-image-overlays beg end)))
-        (message (if new
-		     (format "%d images displayed inline"
-			     (length new))
-		   "No images to display inline"))))))
+  (cond
+   ((not (display-graphic-p)) (message "Your Emacs does not support displaying images!"))
+   ;; 1. No argument, no region selected :: toggle (display or hide dwim) images in current section or image link at point.
+   ((and (null arg) (not (use-region-p)))
+    (let ((context (org-element-context))
+          (beg (if (org-before-first-heading-p) (point-min)
+	         (save-excursion
+	           (org-with-limited-levels (org-back-to-heading t) (point)))))
+          (end (org-with-limited-levels (org-entry-end-position)))
+          (include-linked nil))
+      ;; toggle display of inline image link at point.
+      (if (memq (org-element-type context) '(link))
+          (let ((beg (org-element-property :begin context))
+		(end (org-element-property :end context)))
+	    (if (org--inline-image-overlays beg end)
+                (progn
+                  (org-remove-inline-images beg end)
+	          (message "Remove inline image at point."))
+	      (org-display-inline-images include-linked t beg end)
+	      (message "Display inline image at point ... done.")))
+        (if (org--inline-image-overlays beg end)
+            (org-remove-inline-images beg end)
+          (message "Display inline images in section...")
+          (org-display-inline-images include-linked t beg end)
+          (message "Display inline images in section... done.")))))
+   ;; 2. No argument, region selected :: toggle images in region.
+   ((and (null arg) (use-region-p))
+    (let* ((beg (region-beginning))
+           (end (region-end))
+           (include-linked nil)
+           (inline-images (org--inline-image-overlays beg end)))
+      (if (org--inline-image-overlays beg end)
+          (progn
+            (org-remove-inline-images beg end)
+            (message "%d inline images display removed." (length inline-images)))
+        (message "Display inline images displayed in region...")
+        (org-display-inline-images include-linked t beg end)
+        (message "Display inline images displayed in region... done."))))
+   ;; 3. C-u argument :: toggle images in the whole buffer.
+   ((equal arg '(4))
+    (let ((include-linked nil))
+      (if (org--inline-image-overlays (point-min) (point-max))
+          (org-remove-inline-images (point-min) (point-max))
+        (message "Display all inline images in buffer...")
+        (org-display-inline-images include-linked nil (point-min) (point-max))
+        (message "Display all inline images in buffer... done."))))
+   ;; 4. C-u C-u argument, no region selected :: unconditionally hide images in the buffer.
+   ((and (equal arg '(16)) (not (use-region-p)))
+    (org-remove-inline-images (point-min) (point-max))
+    (message "Remove all inline images in buffer displaying."))
+   ;; 5. M-1 argument, no region selected :: display images in current section with `INCLUDE-LINKED'.
+   ((and (equal arg 1) (not (use-region-p)))
+    (let ((context (org-element-context))
+          (beg (if (org-before-first-heading-p) (point-min)
+	         (save-excursion
+	           (org-with-limited-levels (org-back-to-heading t) (point)))))
+          (end (org-with-limited-levels (org-entry-end-position)))
+          (include-linked t))
+      (message "Display inline images in section...")
+      (org-display-inline-images include-linked t beg end)
+      (message "Display inline images in section... done.")))
+   ;; 6. M-1 argument, region selected :: ... in region ...
+   ;; [M-1] / [C-1] argument for linked images like:
+   ;; [[https://orgmode.org/resources/img/org-mode-unicorn.svg][description]]
+   ((and (equal arg 1) (use-region-p))
+    (let* ((beg (region-beginning))
+	   (end (region-end))
+           (include-linked t)
+           (inline-images (org--inline-image-overlays beg end)))
+      (org-display-inline-images include-linked t beg end)
+      (message "%d inline images displayed in region... done."  (length inline-images))))
+   ;; 7. M-11 argument :: ... in the whole buffer ...
+   ((equal arg '11)
+    (let ((beg (point-min))
+          (end (point-max))
+          (include-linked t))
+      (message "Display inline images in buffer...")
+      (org-display-inline-images include-linked t beg end)
+      (message "Display inline images in buffer... done.")))
+   ;; 8. Any other argument :: treat ARG as INCLUDE-LINKED = t
+   ((not (null arg))
+    (let ((beg (if (org-before-first-heading-p) (point-min)
+	         (save-excursion
+	           (org-with-limited-levels (org-back-to-heading t) (point)))))
+          (end (org-with-limited-levels (org-entry-end-position)))
+          (include-linked arg))
+      (message "Display inline images in section...")
+      (org-display-inline-images include-linked t beg end)
+      (message "Display inline images in section... done.")))))
 
 (defun org-redisplay-inline-images ()
   "Assure display of inline images and refresh them."
-- 
2.39.3 (Apple Git-146)

