From: Karthik Chikmagalur <karthikchikmagalur@gmail.com>
To: Ihor Radchenko <yantar92@posteo.net>
Cc: stardiviner <numbchild@gmail.com>, Org mode <emacs-orgmode@gnu.org>
Subject: [PATCH v1] Inline image display as part of a new org-link-preview system
Date: Fri, 23 Aug 2024 16:36:04 -0700 [thread overview]
Message-ID: <875xrqg6cb.fsf@gmail.com> (raw)
In-Reply-To: <87msl4wv8d.fsf@localhost>
[-- Attachment #1: Type: text/plain, Size: 3217 bytes --]
>> Would you like this to be part of org.el or should I spin out an
>> org-image-preview.el feature+library?
>
> Spin out will be easier when for my rebase :)
Please find attached the draft of a patch implementing a general
link-preview system.
----
The idea is the following:
1. Introduce the :preview link parameter. This is a function that is
passed an overlay placed over a link (along with some other link
details) and should adorn the overlay however the link should be
previewed. Typically this is by adding an image to the overlay, but
it can be more general.
This has a few advantages over the current system:
- The code is much more modular.
- Previewing image links is no longer "special": all links can have
custom preview behavior. Users or package authors can specify how
they want each link type to be previewed.
- About 300 lines of code have been moved out of org.el, with more
removals to come (details below).
2. A :preview function for links of type "file" or "attachment" is
provided -- it is the old org-display-inline-images function, but broken
up into a couple of more modular functions.
- Note: the new preview behavior for image files should be identical,
no changes or breaking changes are expected.
3. Introduce a new org-link-preview command. This command has the same
prefix arg behaviors as org-latex-preview, and previews each link
using its :preview function. This is a drop-in replacement for
org-toggle-inline-images-command and org-toggle-inline-images.
org-toggle-inline-images-command has been removed, and
org-toggle-inline-images has been moved to org-compat. There are a
couple of other commands for use from elisp: org-link-preview-region
and org-link-preview-clear.
Advantages:
- Uniform preview behavior across Org preview types (links, latex)
- Can preview individual links, links in the section or across the buffer.
- Can preview, refresh existing previews or disable them independently
using different prefix arg behaviors (no need to toggle/run twice).
4. Bind C-c C-x C-v to org-link-preview.
----
Organization:
I didn't create a new feature/library: All the link-preview code is part
of ol.el. I think it fits well there.
I can move the code for creating and examining images from org.el to a
new org-image.el or org-image-utils.el library if required.
----
Not yet handled or final:
- Link abbreviations: I'm using org-link-any-re to find links, and this
appears to be handling link abbreviations fine. So there is no
special code to handle link abbreviations. But I'm not sure.
- Updating NEWS and the manual. I can do this at the end, before
merging.
- The calling convention for the :preview function is not final. Right
now it is given the overlay, the link type and the link path. But
other link details can be required -- for example, image links need to
read the org keywords for the image width and alignment, so I end up
calling (org-element-context) again inside the :preview function.
----
I'll send a short example of using org-link-preview to asynchronously
preview youtube links as thumbnails soon.
Karthik
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-org-link-Move-inline-image-display-to-org-link.patch --]
[-- Type: text/x-patch, Size: 45086 bytes --]
From 93b7e50a50d7c6f72439169e5647a840c6e04bcc Mon Sep 17 00:00:00 2001
From: Karthik Chikmagalur <karthikchikmagalur@gmail.com>
Date: Fri, 23 Aug 2024 15:46:53 -0700
Subject: [PATCH 2/2] org-link: Move inline image display to org-link
Make inline image previews a part of a more universal org-link
preview feature. Each link type can now be previewed differently
based on a new link parameter.
* lisp/ol.el (org-link-parameters, org-link-preview-overlays,
org-link-preview--get-overlays, org-link-preview--remove-overlay,
org-link-previeworg-link-preview-region, org-link-preview-clear,
org-link-preview-file): Add new commands `org-link-preview',
`org-link-preview-region' and `org-link-preview-clear' for
creating link previews for any kind of link. Add new org-link
parameter `:preview' for specifying how a link type should be
previewed. File links and attachments are previewed using inline
image previews as before.
* testing/lisp/test-org-fold.el: Use `org-link-preview'.
* lisp/org.el (org-toggle-inline-images,
org-toggle-inline-images-command, org-display-inline-images,
org--inline-image-overlays, org-inline-image-overlays,
org-redisplay-inline-images, org-image-align,
org-display-inline-remove-overlay, org-remove-inline-images):
Obsolete and move `org-toggle-inline-images',
`org-display-inline-images' and `org-redisplay-inline-images' to
org-compat. These are obsoleted by `org-link-preview' and
`org-link-preview-region'. Remove
`org-toggle-inline-images-command'. Move the other internal
functions to org-link.
* lisp/org-plot.el (org-plot/redisplay-img-in-buffer): Modify to
use `org-link-preview'.
* lisp/org-keys.el: Bind `C-c C-x C-v' to new command
`org-link-preview', which has the same prefix arg behaviors as
`org-latex-preview'.
* lisp/org-cycle.el (org-cycle-display-inline-images): Use
`org-link-preview'.
* lisp/org-compat.el (org-display-inline-remove-overlay,
org--inline-image-overlays, org-remove-inline-images,
org-inline-image-overlays, org-display-inline-images,
org-toggle-inline-images):
* lisp/org-attach.el: Add new `:preview' link parameter for links
of type "attachment".
---
lisp/ol.el | 290 +++++++++++++++++++++++++++++++++-
lisp/org-attach.el | 4 +-
lisp/org-compat.el | 189 ++++++++++++++++++++++
lisp/org-cycle.el | 10 +-
lisp/org-keys.el | 4 +-
lisp/org-plot.el | 2 +-
lisp/org.el | 283 +--------------------------------
testing/lisp/test-org-fold.el | 4 +-
8 files changed, 493 insertions(+), 293 deletions(-)
diff --git a/lisp/ol.el b/lisp/ol.el
index 52ea62d69..78543f8c7 100644
--- a/lisp/ol.el
+++ b/lisp/ol.el
@@ -82,6 +82,13 @@ (declare-function org-src-source-buffer "org-src" ())
(declare-function org-src-source-type "org-src" ())
(declare-function org-time-stamp-format "org" (&optional long inactive))
(declare-function outline-next-heading "outline" ())
+(declare-function image-flush "image" (spec &optional frame))
+(declare-function org-entry-end-position "org" ())
+(declare-function org-element-contents-begin "org-element" (node))
+(declare-function org-attach-expand "org-attach" (file))
+(declare-function org-display-inline-image--width "org" (link))
+(declare-function org-image--align "org" (link))
+(declare-function org--create-inline-image "org" (file width))
\f
;;; Customization
@@ -171,6 +178,14 @@ (defcustom org-link-parameters nil
The default face is `org-link'.
+`:preview'
+
+ Function to run when generating an in-buffer preview for the
+ link. It must accept three arguments:
+ - an overlay placed from the start to the end of the link.
+ - the link type, as a string.
+ - the path, as a string.
+
`:help-echo'
String or function used as a value for the `help-echo' text
@@ -649,6 +664,13 @@ (defvar org-link--insert-history nil
(defvar org-link--search-failed nil
"Non-nil when last link search failed.")
+(defvar-local org-link-preview-overlays nil)
+;; Preserve when switching modes or when restarting Org.
+;; If we clear the overlay list and later enable Or mode, the existing
+;; image overlays will never be cleared by `org-link-preview'
+;; and `org-link-preview-clear'.
+(put 'org-link-preview-overlays 'permanent-local t)
+
\f
;;; Internal Functions
@@ -881,6 +903,28 @@ (defun org-link--file-link-to-here ()
(setq desc search-desc))))
(cons link desc)))
+(defun org-link-preview--get-overlays (&optional beg end)
+ "Return link preview overlays between BEG and END."
+ (let* ((beg (or beg (point-min)))
+ (end (or end (point-max)))
+ (overlays (overlays-in beg end))
+ result)
+ (dolist (ov overlays result)
+ (when (memq ov org-link-preview-overlays)
+ (push ov result)))))
+
+(defun org-link-preview--remove-overlay (ov after _beg _end &optional _len)
+ "Remove link-preview overlay OV if a corresponding region is modified.
+
+AFTER is true when this function is called post-change."
+ (when (and ov after)
+ (setq org-link-preview-overlays (delete ov org-link-preview-overlays))
+ ;; Clear image from cache to avoid image not updating upon
+ ;; changing on disk. See Emacs bug#59902.
+ (when (overlay-get ov 'org-image-overlay)
+ (image-flush (overlay-get ov 'display)))
+ (delete-overlay ov)))
+
\f
;;; Public API
@@ -1573,6 +1617,195 @@ (defun org-link-add-angle-brackets (s)
(unless (equal (substring s -1) ">") (setq s (concat s ">")))
s)
+;;;###autoload
+(defun org-link-preview (&optional arg beg end)
+ "Toggle display of link previews in the buffer.
+
+When region BEG..END is active, preview links in the
+region.
+
+When point is at a link, display a preview for that link only.
+Otherwise, display previews for links in current entry.
+
+With numeric prefix ARG 1, preview links with description as
+well.
+
+With prefix ARG `\\[universal-argument]', clear link previews at
+point or in the current entry.
+
+With prefix ARG `\\[universal-argument] \\[universal-argument]',
+ display link previews in the accessible portion of the
+ buffer. With numeric prefix ARG 11, do the same, but include
+ links with descriptions.
+
+With prefix ARG `\\[universal-argument] \\[universal-argument] \\[universal-argument]',
+hide all link previews in the accessible portion of the buffer.
+
+This command is designed for interactive use. From Elisp, you can
+also use `org-link-preview-region'."
+ (interactive (cons current-prefix-arg
+ (when (use-region-p)
+ (list (region-beginning) (region-end)))))
+ (let* ((include-linked
+ (cond
+ ((member arg '(nil (4) (16)) ) nil)
+ ((member arg '(1 11)) 'include-linked)
+ (t 'include-linked)))
+ (interactive? (called-interactively-p 'any))
+ (toggle-images
+ (lambda (&optional beg end scope remove)
+ (let* ((beg (or beg (point-min)))
+ (end (or end (point-max)))
+ (old (org-link-preview--get-overlays beg end))
+ (scope (or scope (format "%d:%d" beg end))))
+ (if remove
+ (progn
+ (org-link-preview-clear beg end)
+ (when interactive?
+ (message
+ "[%s] Inline link previews turned off (removed %d images)"
+ scope (length old))))
+ (org-link-preview-region include-linked t beg end)
+ (when interactive?
+ (let ((new (org-link-preview--get-overlays beg end)))
+ (message
+ (if new
+ (format "[%s] %d images displayed inline %s"
+ scope (length new)
+ (if include-linked "(including images with description)"
+ ""))
+ (format "[%s] No images to display inline" scope))))))))))
+ (cond
+ ((not (display-graphic-p))
+ (message "Your Emacs does not support displaying images!"))
+ ;; Region selected :: display previews in region.
+ ((and beg end)
+ (funcall toggle-images beg end "region"
+ (and (equal arg '(4)) 'remove)))
+ ;; C-u argument: clear image at point or in entry
+ ((equal arg '(4))
+ (if (get-char-property (point) 'org-image-overlay)
+ ;; clear link preview at point
+ (when-let ((context (org-element-context))
+ ((org-element-type-p context 'link)))
+ (funcall toggle-images
+ (org-element-begin context)
+ (org-element-end context)
+ "preview at point" 'remove))
+ ;; Clear link previews in entry
+ (funcall toggle-images
+ (if (org-before-first-heading-p) (point-min)
+ (save-excursion
+ (org-with-limited-levels (org-back-to-heading t) (point))))
+ (org-with-limited-levels (org-entry-end-position))
+ "current section" 'remove)))
+ ;; C-u C-u or C-11 argument :: display images in the whole buffer.
+ ((member arg '(11 (16))) (funcall toggle-images nil nil "buffer"))
+ ;; C-u C-u C-u argument :: unconditionally hide images in the buffer.
+ ((equal arg '(64)) (funcall toggle-images nil nil "buffer" 'remove))
+ ;; Argument nil or 1, no region selected :: display images in
+ ;; current section or image link at point.
+ ((and (member arg '(nil 1)) (null beg) (null end))
+ (let ((context (org-element-context)))
+ ;; toggle display of inline image link at point.
+ (if (org-element-type-p context 'link)
+ (let* ((ov (cdr-safe (get-char-property-and-overlay
+ (point) 'org-image-overlay)))
+ (remove? (and ov (memq ov org-link-preview-overlays)
+ 'remove)))
+ (funcall toggle-images
+ (org-element-begin context)
+ (org-element-end context)
+ "image at point" remove?))
+ (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))))
+ (funcall toggle-images beg end "current section")))))
+ ;; Any other non-nil argument.
+ ((not (null arg)) (funcall toggle-images beg end "region")))))
+
+(defun org-link-preview-region (&optional include-linked refresh beg end)
+ "Display link previews.
+
+A previewable link type is one that has a `:preview' link
+parameter, see `org-link-parameters'.
+
+By default, a file link or attachment is previewable if it
+follows either of these conventions:
+
+ 1. Its path is a file with an extension matching return value
+ from `image-file-name-regexp' and it has no contents.
+
+ 2. Its description consists in a single link of the previous
+ type. In this case, that link must be a well-formed plain
+ or angle link, i.e., it must have an explicit \"file\" or
+ \"attachment\" type.
+
+File links are equipped with the keymap `image-map'.
+
+When optional argument INCLUDE-LINKED is non-nil, links with a
+text description part will also be inlined. This can be nice for
+a quick look at those images, but it does not reflect what
+exported files will look like.
+
+When optional argument REFRESH is non-nil, refresh existing
+images between BEG and END. This will create new image displays
+only if necessary.
+
+BEG and END define the considered part. They default to the
+buffer boundaries with possible narrowing."
+ (interactive "P")
+ (when (display-graphic-p)
+ (when refresh (org-link-preview-clear beg end))
+ (when (fboundp 'clear-image-cache) (clear-image-cache)))
+ (org-with-point-at (or beg (point-min))
+ (let ((case-fold-search t))
+ (while (re-search-forward org-link-any-re end t)
+ (when-let* ((link (org-element-lineage
+ (save-match-data (org-element-context))
+ 'link t))
+ (linktype (org-element-property :type link))
+ (preview-func (org-link-get-parameter linktype :preview))
+ (path (and (or include-linked
+ (not (org-element-contents-begin link)))
+ (org-element-property :path link))))
+ ;; Create an overlay to hold the preview
+ (let ((ov (make-overlay
+ (org-element-begin link)
+ (progn
+ (goto-char
+ (org-element-end link))
+ (unless (eolp) (skip-chars-backward " \t"))
+ (point)))))
+ ;; TODO: Change this overlay property to `org-link-preview' everywhere.
+ (overlay-put ov 'org-image-overlay t)
+ (overlay-put ov 'modification-hooks
+ (list 'org-link-preview--remove-overlay))
+ ;; call preview function for link type
+ (funcall preview-func ov linktype path)
+ ;; If overlay still exists, add it to the list
+ (when (overlay-buffer ov)
+ (push ov org-link-preview-overlays))))))))
+
+(defun org-link-preview-clear (&optional beg end)
+ "Clear link previews in region BEG to END."
+ (interactive (and (use-region-p) (list (region-beginning) (region-end))))
+ (let* ((beg (or beg (point-min)))
+ (end (or end (point-max)))
+ (overlays (overlays-in beg end)))
+ (dolist (ov overlays)
+ (when (memq ov org-link-preview-overlays)
+ (when-let ((image (overlay-get ov 'display))
+ ((imagep image)))
+ (image-flush image))
+ (setq org-link-preview-overlays (delq ov org-link-preview-overlays))
+ (delete-overlay ov)))
+ ;; Clear removed overlays.
+ (dolist (ov org-link-preview-overlays)
+ (unless (overlay-buffer ov)
+ (setq org-link-preview-overlays (delq ov org-link-preview-overlays))))))
+
\f
;;; Built-in link types
@@ -1595,7 +1828,62 @@ (defun org-link--open-elisp (path _)
(org-link-set-parameters "elisp" :follow #'org-link--open-elisp)
;;;; "file" link type
-(org-link-set-parameters "file" :complete #'org-link-complete-file)
+(org-link-set-parameters "file"
+ :complete #'org-link-complete-file
+ :preview #'org-link-preview-file)
+
+(defun org-link-preview-file (ov linktype path)
+ "Display image file PATH in overlay OV.
+
+LINKTYPE is the Org link type used to preview PATH, either
+\"file\" or \"attachment\".
+
+Equip each image with the keymap `image-map'.
+
+This is intended to be used as the `:preview' link property of
+file links, see `org-link-parameters'."
+ (if-let ((file-full
+ (if (equal "attachment" linktype)
+ (progn
+ (require 'org-attach)
+ (ignore-errors (org-attach-expand path)))
+ (expand-file-name path)))
+ (file (substitute-in-file-name file-full))
+ ((string-match-p (image-file-name-regexp) file))
+ ((file-exists-p file)))
+ (let* ((link (org-element-lineage
+ (save-excursion
+ (goto-char (overlay-start ov))
+ (save-match-data (org-element-context)))
+ 'link t))
+ (width (org-display-inline-image--width link))
+ (align (org-image--align link))
+ (image (org--create-inline-image file width)))
+ (if (not image)
+ ;; Image not available, clean up overlay
+ (delete-overlay ov)
+ ;; Add image to overlay:
+
+ ;; See bug#59902. We cannot rely
+ ;; on Emacs to update image if the file
+ ;; has changed.
+ (image-flush image)
+ (overlay-put ov 'display image)
+ (overlay-put ov 'face 'default)
+ (overlay-put ov 'org-image-overlay t)
+ (when (boundp 'image-map)
+ (overlay-put ov 'keymap image-map))
+ (when align
+ (overlay-put
+ ov 'before-string
+ (propertize
+ " " 'face 'default
+ 'display
+ (pcase align
+ ("center" `(space :align-to (- center (0.5 . ,image))))
+ ("right" `(space :align-to (- right ,image)))))))))
+ ;; file or image not available, clean up overlay
+ (delete-overlay ov)))
;;;; "help" link type
(defun org-link--open-help (path _)
diff --git a/lisp/org-attach.el b/lisp/org-attach.el
index 7a03d170e..7d90dae0b 100644
--- a/lisp/org-attach.el
+++ b/lisp/org-attach.el
@@ -797,9 +797,11 @@ (defun org-attach-follow (file arg)
See `org-open-file' for details about ARG."
(org-link-open-as-file (org-attach-expand file) arg))
+(declare-function org-link-preview-file "org-link-preview")
(org-link-set-parameters "attachment"
:follow #'org-attach-follow
- :complete #'org-attach-complete-link)
+ :complete #'org-attach-complete-link
+ :preview #'org-link-preview-file)
(defun org-attach-complete-link ()
"Advise the user with the available files in the attachment directory."
diff --git a/lisp/org-compat.el b/lisp/org-compat.el
index d843216f3..242b46a86 100644
--- a/lisp/org-compat.el
+++ b/lisp/org-compat.el
@@ -783,6 +783,195 @@ (defun org-add-link-type (type &optional follow export)
(make-obsolete 'org-add-link-type "use `org-link-set-parameters' instead." "9.0")
+(declare-function org-link-preview--remove-overlay "ol")
+(declare-function org-link-preview--get-overlays "ol")
+(declare-function org-link-preview-clear "ol")
+(declare-function org-link-preview--remove-overlay "ol")
+
+(define-obsolete-function-alias 'org-display-inline-remove-overlay
+ 'org-link-preview--remove-overlay "9.8")
+(define-obsolete-function-alias 'org--inline-image-overlays
+ 'org-link-preview--get-overlays "9.8")
+(define-obsolete-function-alias 'org-remove-inline-images
+ 'org-link-preview-clear "9.8")
+(define-obsolete-variable-alias 'org-inline-image-overlays
+ 'org-link-preview-overlays "9.8")
+(defvar org-link-preview-overlays)
+(defvar org-link-abbrev-alist-local)
+(defvar org-link-abbrev-alist)
+(defvar org-link-angle-re)
+(defvar org-link-plain-re)
+(declare-function org-attach-expand "org-attach")
+(declare-function org-display-inline-image--width "org")
+(declare-function org-image--align "org")
+(declare-function org--create-inline-image "org")
+
+(make-obsolete 'org-display-inline-images
+ 'org-link-preview-region "9.8")
+;; FIXME: Unused; obsoleted; to be removed
+(defun org-display-inline-images (&optional include-linked refresh beg end)
+ "Display inline images.
+
+An inline image is a link which follows either of these
+conventions:
+
+ 1. Its path is a file with an extension matching return value
+ from `image-file-name-regexp' and it has no contents.
+
+ 2. Its description consists in a single link of the previous
+ type. In this case, that link must be a well-formed plain
+ or angle link, i.e., it must have an explicit \"file\" or
+ \"attachment\" type.
+
+Equip each image with the key-map `image-map'.
+
+When optional argument INCLUDE-LINKED is non-nil, also links with
+a text description part will be inlined. This can be nice for
+a quick look at those images, but it does not reflect what
+exported files will look like.
+
+When optional argument REFRESH is non-nil, refresh existing
+images between BEG and END. This will create new image displays
+only if necessary.
+
+BEG and END define the considered part. They default to the
+buffer boundaries with possible narrowing."
+ (interactive "P")
+ (when (display-graphic-p)
+ (when refresh
+ (org-link-preview-clear beg end)
+ (when (fboundp 'clear-image-cache) (clear-image-cache)))
+ (let ((end (or end (point-max))))
+ (org-with-point-at (or beg (point-min))
+ (let* ((case-fold-search t)
+ (file-extension-re (image-file-name-regexp))
+ (link-abbrevs (mapcar #'car
+ (append org-link-abbrev-alist-local
+ org-link-abbrev-alist)))
+ ;; Check absolute, relative file names and explicit
+ ;; "file:" links. Also check link abbreviations since
+ ;; some might expand to "file" links.
+ (file-types-re
+ (format "\\[\\[\\(?:file%s:\\|attachment:\\|[./~]\\)\\|\\]\\[\\(<?\\(?:file\\|attachment\\):\\)"
+ (if (not link-abbrevs) ""
+ (concat "\\|" (regexp-opt link-abbrevs))))))
+ (while (re-search-forward file-types-re end t)
+ (let* ((link (org-element-lineage
+ (save-match-data (org-element-context))
+ 'link t))
+ (linktype (org-element-property :type link))
+ (inner-start (match-beginning 1))
+ (path
+ (cond
+ ;; No link at point; no inline image.
+ ((not link) nil)
+ ;; File link without a description. Also handle
+ ;; INCLUDE-LINKED here since it should have
+ ;; precedence over the next case. I.e., if link
+ ;; contains filenames in both the path and the
+ ;; description, prioritize the path only when
+ ;; INCLUDE-LINKED is non-nil.
+ ((or (not (org-element-contents-begin link))
+ include-linked)
+ (and (or (equal "file" linktype)
+ (equal "attachment" linktype))
+ (org-element-property :path link)))
+ ;; Link with a description. Check if description
+ ;; is a filename. Even if Org doesn't have syntax
+ ;; for those -- clickable image -- constructs, fake
+ ;; them, as in `org-export-insert-image-links'.
+ ((not inner-start) nil)
+ (t
+ (org-with-point-at inner-start
+ (and (looking-at
+ (if (char-equal ?< (char-after inner-start))
+ org-link-angle-re
+ org-link-plain-re))
+ ;; File name must fill the whole
+ ;; description.
+ (= (org-element-contents-end link)
+ (match-end 0))
+ (progn
+ (setq linktype (match-string 1))
+ (match-string 2))))))))
+ (when (and path (string-match-p file-extension-re path))
+ (let ((file (if (equal "attachment" linktype)
+ (progn
+ (require 'org-attach)
+ (ignore-errors (org-attach-expand path)))
+ (expand-file-name path))))
+ ;; Expand environment variables.
+ (when file (setq file (substitute-in-file-name file)))
+ (when (and file (file-exists-p file))
+ (let ((width (org-display-inline-image--width link))
+ (align (org-image--align link))
+ (old (get-char-property-and-overlay
+ (org-element-begin link)
+ 'org-image-overlay)))
+ (if (and (car-safe old) refresh)
+ (image-flush (overlay-get (cdr old) 'display))
+ (let ((image (org--create-inline-image file width)))
+ (when image
+ (let ((ov (make-overlay
+ (org-element-begin link)
+ (progn
+ (goto-char
+ (org-element-end link))
+ (unless (eolp) (skip-chars-backward " \t"))
+ (point)))))
+ ;; See bug#59902. We cannot rely
+ ;; on Emacs to update image if the file
+ ;; has changed.
+ (image-flush image)
+ (overlay-put ov 'display image)
+ (overlay-put ov 'face 'default)
+ (overlay-put ov 'org-image-overlay t)
+ (overlay-put
+ ov 'modification-hooks
+ (list 'org-link-preview--remove-overlay))
+ (when (boundp 'image-map)
+ (overlay-put ov 'keymap image-map))
+ (when align
+ (overlay-put
+ ov 'before-string
+ (propertize
+ " " 'face 'default
+ 'display
+ (pcase align
+ ("center" `(space :align-to (- center (0.5 . ,image))))
+ ("right" `(space :align-to (- right ,image)))))))
+ (push ov org-inline-image-overlays))))))))))))))))
+
+(make-obsolete 'org-toggle-inline-images
+ 'org-link-preview "9.8")
+;; FIXME: Unused; obsoleted; to be removed
+(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'."
+ (interactive "P")
+ (if (org-link-preview--get-overlays beg end)
+ (progn
+ (org-link-preview-clear 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-link-preview--get-overlays beg end)))
+ (message (if new
+ (format "%d images displayed inline"
+ (length new))
+ "No images to display inline"))))))
+
+(make-obsolete 'org-redisplay-inline-images
+ 'org-link-preview "9.8")
+;; FIXME: Unused; obsoleted; to be removed
+(defun org-redisplay-inline-images ()
+ "Assure display of inline images and refresh them."
+ (interactive)
+ (org-toggle-inline-images)
+ (unless org-link-preview-overlays
+ (org-toggle-inline-images)))
+
;;;; Functions unused in Org core.
(defun org-table-recognize-table.el ()
"If there is a table.el table nearby, recognize it and move into it."
diff --git a/lisp/org-cycle.el b/lisp/org-cycle.el
index 8a39bdb8c..1a1c916bd 100644
--- a/lisp/org-cycle.el
+++ b/lisp/org-cycle.el
@@ -40,14 +40,14 @@ (declare-function org-element-property "org-element-ast" (property node))
(declare-function org-element-post-affiliated "org-element" (node))
(declare-function org-element-lineage "org-element-ast" (datum &optional types with-self))
(declare-function org-element-at-point "org-element" (&optional pom cached-only))
-(declare-function org-display-inline-images "org" (&optional include-linked refresh beg end))
+(declare-function org-link-preview-region "ol" (&optional include-linked refresh beg end))
(declare-function org-get-tags "org" (&optional pos local fontify))
(declare-function org-subtree-end-visible-p "org" ())
(declare-function org-narrow-to-subtree "org" (&optional element))
(declare-function org-next-visible-heading "org" (arg))
(declare-function org-at-property-p "org" ())
(declare-function org-re-property "org" (property &optional literal allow-null value))
-(declare-function org-remove-inline-images "org" (&optional beg end))
+(declare-function org-link-preview-clear "ol" (&optional beg end))
(declare-function org-item-beginning-re "org" ())
(declare-function org-at-heading-p "org" (&optional invisible-not-ok))
(declare-function org-at-item-p "org" ())
@@ -817,19 +817,19 @@ (defun org-cycle-display-inline-images (state)
;; If has nested headlines, beg,end only from parent headline
;; to first child headline which reference to upper
;; let-binding `org-next-visible-heading'.
- (org-display-inline-images
+ (org-link-preview-region
nil nil
(point-min) (progn (org-next-visible-heading 1) (point)))))
('subtree
(org-with-wide-buffer
(org-narrow-to-subtree)
;; If has nested headlines, also inline display images under all sub-headlines.
- (org-display-inline-images nil nil (point-min) (point-max))))
+ (org-link-preview-region nil nil (point-min) (point-max))))
('folded
(org-with-wide-buffer
(org-narrow-to-subtree)
(if (numberp (point-max))
- (org-remove-inline-images (point-min) (point-max))
+ (org-link-preview-clear (point-min) (point-max))
(ignore)))))))
(provide 'org-cycle)
diff --git a/lisp/org-keys.el b/lisp/org-keys.el
index 1daedaae8..77cbe5c0f 100644
--- a/lisp/org-keys.el
+++ b/lisp/org-keys.el
@@ -218,7 +218,7 @@ (declare-function org-toggle-checkbox "org" (&optional toggle-presence))
(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-command "org" (&optional arg beg end))
+(declare-function org-link-preview "ol" (&optional arg beg end))
(declare-function org-latex-preview "org" (&optional arg))
(declare-function org-toggle-narrow-to-subtree "org" ())
(declare-function org-toggle-ordered-property "org" ())
@@ -618,7 +618,7 @@ (org-defkey org-mode-map (kbd "C-c C-x C-d") #'org-clock-display)
(org-defkey org-mode-map (kbd "C-c C-x x") #'org-dynamic-block-insert-dblock)
(org-defkey org-mode-map (kbd "C-c C-x C-u") #'org-dblock-update)
(org-defkey org-mode-map (kbd "C-c C-x C-l") #'org-latex-preview)
-(org-defkey org-mode-map (kbd "C-c C-x C-v") #'org-toggle-inline-images-command)
+(org-defkey org-mode-map (kbd "C-c C-x C-v") #'org-link-preview)
(org-defkey org-mode-map (kbd "C-c C-x C-M-v") #'org-redisplay-inline-images)
(org-defkey org-mode-map (kbd "C-c C-x \\") #'org-toggle-pretty-entities)
(org-defkey org-mode-map (kbd "C-c C-x C-b") #'org-toggle-checkbox)
diff --git a/lisp/org-plot.el b/lisp/org-plot.el
index b045344f0..836cfaffc 100644
--- a/lisp/org-plot.el
+++ b/lisp/org-plot.el
@@ -633,7 +633,7 @@ (defun org-plot/gnuplot-script (table data-file num-cols params &optional prefac
(defun org-plot/redisplay-img-in-buffer (img-file)
"Find any overlays for IMG-FILE in the current Org buffer, and refresh them."
- (dolist (img-overlay org-inline-image-overlays)
+ (dolist (img-overlay org-link-preview-overlays)
(when (string= img-file (plist-get (cdr (overlay-get img-overlay 'display)) :file))
(when (and (file-exists-p img-file)
(fboundp 'image-flush))
diff --git a/lisp/org.el b/lisp/org.el
index d5c1dcb35..091a09344 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -5079,7 +5079,7 @@ (define-derived-mode org-mode outline-mode "Org"
;; modifications to make cache updates work reliably.
(org-unmodified
(when org-startup-with-beamer-mode (org-beamer-mode))
- (when org-startup-with-inline-images (org-display-inline-images))
+ (when org-startup-with-inline-images (org-link-preview '(16)))
(when org-startup-with-latex-preview (org-latex-preview '(16)))
(unless org-inhibit-startup-visibility-stuff (org-cycle-set-startup-visibility))
(when org-startup-truncated (setq truncate-lines t))
@@ -16651,126 +16651,6 @@ (defun org-normalize-color (value)
\f
;; Image display
-(defvar-local org-inline-image-overlays nil)
-;; Preserve when switching modes or when restarting Org.
-;; If we clear the overlay list and later enable Or mode, the existing
-;; image overlays will never be cleared by `org-toggle-inline-images'
-;; and `org-toggle-inline-images-command'.
-(put 'org-inline-image-overlays 'permanent-local t)
-
-(defun org--inline-image-overlays (&optional beg end)
- "Return image overlays between BEG and END."
- (let* ((beg (or beg (point-min)))
- (end (or end (point-max)))
- (overlays (overlays-in beg end))
- result)
- (dolist (ov overlays result)
- (when (memq ov org-inline-image-overlays)
- (push ov result)))))
-
-(defun org-toggle-inline-images-command (&optional arg beg end)
- "Toggle display of inline images without description at point.
-
-When point is at an image link, toggle displaying that image.
-Otherwise, toggle displaying images in current entry.
-
-When region BEG..END is active, toggle displaying images in the
-region.
-
-With numeric prefix ARG 1, display images with description as well.
-
-With prefix ARG `\\[universal-argument]', toggle displaying images in
-the accessible portion of the buffer. With numeric prefix ARG 11, do
-the same, but include images with description.
-
-With prefix ARG `\\[universal-argument] \\[universal-argument]', hide
-all the images in accessible portion of the buffer.
-
-This command is designed for interactive use. From Elisp, you can
-also use `org-toggle-inline-images'."
- (interactive (cons current-prefix-arg
- (when (use-region-p)
- (list (region-beginning) (region-end)))))
- (let* ((include-linked
- (cond
- ((member arg '(nil (4) (16)) ) nil)
- ((member arg '(1 11)) 'include-linked)
- (t 'include-linked)))
- (interactive? (called-interactively-p 'any))
- (toggle-images
- (lambda (&optional beg end scope force-remove)
- (let* ((beg (or beg (point-min)))
- (end (or end (point-max)))
- (old (org--inline-image-overlays beg end))
- (scope (or scope (format "%d:%d" beg end))))
- (if (or old force-remove)
- (progn
- (org-remove-inline-images beg end)
- (when interactive?
- (message
- "[%s] Inline image display turned off (removed %d images)"
- scope (length old))))
- (org-display-inline-images include-linked t beg end)
- (when interactive?
- (let ((new (org--inline-image-overlays beg end)))
- (message
- (if new
- (format "[%s] %d images displayed inline %s"
- scope (length new)
- (if include-linked "(including images with description)"
- ""))
- (format "[%s] No images to display inline" scope))))))))))
- (cond
- ((not (display-graphic-p))
- (message "Your Emacs does not support displaying images!"))
- ;; Region selected :: toggle images in region.
- ((and beg end) (funcall toggle-images beg end "region"))
- ;; C-u or C-11 argument :: toggle images in the whole buffer.
- ((member arg '(11 (4))) (funcall toggle-images nil nil "buffer"))
- ;; C-u C-u argument :: unconditionally hide images in the buffer.
- ((equal arg '(16)) (funcall toggle-images nil nil "buffer" 'remove))
- ;; Argument nil or 1, no region selected :: toggle (display or hide
- ;; dwim) images in current section or image link at point.
- ((and (member arg '(nil 1)) (null beg) (null end))
- (let ((context (org-element-context)))
- ;; toggle display of inline image link at point.
- (if (org-element-type-p context 'link)
- (funcall toggle-images
- (org-element-begin context)
- (org-element-end context)
- "image at point")
- (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))))
- (funcall toggle-images beg end "current section")))))
- ;; Any other non-nil argument.
- ((not (null arg)) (funcall toggle-images beg end "region")))))
-
-(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'."
- (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"))))))
-
-(defun org-redisplay-inline-images ()
- "Assure display of inline images and refresh them."
- (interactive)
- (org-toggle-inline-images)
- (unless org-inline-image-overlays
- (org-toggle-inline-images)))
-
;; For without-x builds.
(declare-function image-flush "image" (spec &optional frame))
@@ -16793,7 +16673,7 @@ (defcustom org-display-remote-inline-images 'skip
:safe #'symbolp)
(defcustom org-image-align 'left
- "How to align images previewed using `org-display-inline-images'.
+ "How to align images previewed using `org-link-preview-region'.
Only stand-alone image links are affected by this setting. These
are links without surrounding text.
@@ -16850,139 +16730,6 @@ (defun org--create-inline-image (file width)
org-image-max-width)))
:scale 1))))
-(defun org-display-inline-images (&optional include-linked refresh beg end)
- "Display inline images.
-
-An inline image is a link which follows either of these
-conventions:
-
- 1. Its path is a file with an extension matching return value
- from `image-file-name-regexp' and it has no contents.
-
- 2. Its description consists in a single link of the previous
- type. In this case, that link must be a well-formed plain
- or angle link, i.e., it must have an explicit \"file\" or
- \"attachment\" type.
-
-Equip each image with the key-map `image-map'.
-
-When optional argument INCLUDE-LINKED is non-nil, also links with
-a text description part will be inlined. This can be nice for
-a quick look at those images, but it does not reflect what
-exported files will look like.
-
-When optional argument REFRESH is non-nil, refresh existing
-images between BEG and END. This will create new image displays
-only if necessary.
-
-BEG and END define the considered part. They default to the
-buffer boundaries with possible narrowing."
- (interactive "P")
- (when (display-graphic-p)
- (when refresh
- (org-remove-inline-images beg end)
- (when (fboundp 'clear-image-cache) (clear-image-cache)))
- (let ((end (or end (point-max))))
- (org-with-point-at (or beg (point-min))
- (let* ((case-fold-search t)
- (file-extension-re (image-file-name-regexp))
- (link-abbrevs (mapcar #'car
- (append org-link-abbrev-alist-local
- org-link-abbrev-alist)))
- ;; Check absolute, relative file names and explicit
- ;; "file:" links. Also check link abbreviations since
- ;; some might expand to "file" links.
- (file-types-re
- (format "\\[\\[\\(?:file%s:\\|attachment:\\|[./~]\\)\\|\\]\\[\\(<?\\(?:file\\|attachment\\):\\)"
- (if (not link-abbrevs) ""
- (concat "\\|" (regexp-opt link-abbrevs))))))
- (while (re-search-forward file-types-re end t)
- (let* ((link (org-element-lineage
- (save-match-data (org-element-context))
- 'link t))
- (linktype (org-element-property :type link))
- (inner-start (match-beginning 1))
- (path
- (cond
- ;; No link at point; no inline image.
- ((not link) nil)
- ;; File link without a description. Also handle
- ;; INCLUDE-LINKED here since it should have
- ;; precedence over the next case. I.e., if link
- ;; contains filenames in both the path and the
- ;; description, prioritize the path only when
- ;; INCLUDE-LINKED is non-nil.
- ((or (not (org-element-contents-begin link))
- include-linked)
- (and (or (equal "file" linktype)
- (equal "attachment" linktype))
- (org-element-property :path link)))
- ;; Link with a description. Check if description
- ;; is a filename. Even if Org doesn't have syntax
- ;; for those -- clickable image -- constructs, fake
- ;; them, as in `org-export-insert-image-links'.
- ((not inner-start) nil)
- (t
- (org-with-point-at inner-start
- (and (looking-at
- (if (char-equal ?< (char-after inner-start))
- org-link-angle-re
- org-link-plain-re))
- ;; File name must fill the whole
- ;; description.
- (= (org-element-contents-end link)
- (match-end 0))
- (progn
- (setq linktype (match-string 1))
- (match-string 2))))))))
- (when (and path (string-match-p file-extension-re path))
- (let ((file (if (equal "attachment" linktype)
- (progn
- (require 'org-attach)
- (ignore-errors (org-attach-expand path)))
- (expand-file-name path))))
- ;; Expand environment variables.
- (when file (setq file (substitute-in-file-name file)))
- (when (and file (file-exists-p file))
- (let ((width (org-display-inline-image--width link))
- (align (org-image--align link))
- (old (get-char-property-and-overlay
- (org-element-begin link)
- 'org-image-overlay)))
- (if (and (car-safe old) refresh)
- (image-flush (overlay-get (cdr old) 'display))
- (let ((image (org--create-inline-image file width)))
- (when image
- (let ((ov (make-overlay
- (org-element-begin link)
- (progn
- (goto-char
- (org-element-end link))
- (unless (eolp) (skip-chars-backward " \t"))
- (point)))))
- ;; See bug#59902. We cannot rely
- ;; on Emacs to update image if the file
- ;; has changed.
- (image-flush image)
- (overlay-put ov 'display image)
- (overlay-put ov 'face 'default)
- (overlay-put ov 'org-image-overlay t)
- (overlay-put
- ov 'modification-hooks
- (list 'org-display-inline-remove-overlay))
- (when (boundp 'image-map)
- (overlay-put ov 'keymap image-map))
- (when align
- (overlay-put
- ov 'before-string
- (propertize
- " " 'face 'default
- 'display
- (pcase align
- ("center" `(space :align-to (- center (0.5 . ,image))))
- ("right" `(space :align-to (- right ,image)))))))
- (push ov org-inline-image-overlays))))))))))))))))
-
(declare-function org-export-read-attribute "ox"
(attribute element &optional property))
(defvar visual-fill-column-width) ; Silence compiler warning
@@ -17135,32 +16882,6 @@ (defun org-image--align (link)
(when (memq org-image-align '(center right))
(symbol-name org-image-align))))))))
-
-(defun org-display-inline-remove-overlay (ov after _beg _end &optional _len)
- "Remove inline-display overlay if a corresponding region is modified."
- (when (and ov after)
- (setq org-inline-image-overlays (delete ov org-inline-image-overlays))
- ;; Clear image from cache to avoid image not updating upon
- ;; changing on disk. See Emacs bug#59902.
- (when (overlay-get ov 'org-image-overlay)
- (image-flush (overlay-get ov 'display)))
- (delete-overlay ov)))
-
-(defun org-remove-inline-images (&optional beg end)
- "Remove inline display of images."
- (interactive)
- (let* ((beg (or beg (point-min)))
- (end (or end (point-max)))
- (overlays (overlays-in beg end)))
- (dolist (ov overlays)
- (when (memq ov org-inline-image-overlays)
- (setq org-inline-image-overlays (delq ov org-inline-image-overlays))
- (delete-overlay ov)))
- ;; Clear removed overlays.
- (dolist (ov org-inline-image-overlays)
- (unless (overlay-buffer ov)
- (setq org-inline-image-overlays (delq ov org-inline-image-overlays))))))
-
(defvar org-self-insert-command-undo-counter 0)
(defvar org-speed-command nil)
diff --git a/testing/lisp/test-org-fold.el b/testing/lisp/test-org-fold.el
index f58642be6..809738f6c 100644
--- a/testing/lisp/test-org-fold.el
+++ b/testing/lisp/test-org-fold.el
@@ -716,14 +716,14 @@ (ert-deftest test-org-fold/org-fold-display-inline-images ()
(org-show-subtree)
(org-fold-subtree t)
(run-hook-with-args 'org-cycle-hook 'folded)
- (should-not org-inline-image-overlays)
+ (should-not org-link-preview-overlays)
(should-not
(cl-every
(lambda (ov) (overlay-get ov 'org-image-overlay))
(overlays-in (point-min) (point-max))))
(org-show-subtree)
(run-hook-with-args 'org-cycle-hook 'subtree)
- (should org-inline-image-overlays)
+ (should org-link-preview-overlays)
(should
(cl-every
(lambda (ov) (overlay-get ov 'org-image-overlay))
--
2.44.1
next prev parent reply other threads:[~2024-08-23 23:37 UTC|newest]
Thread overview: 75+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-15 3:28 [PATCH] add a function to only refresh inline images under current headline instead of global buffer Christopher M. Miles
2023-05-15 11:08 ` Ihor Radchenko
2023-05-15 13:01 ` Christopher M. Miles
2023-05-15 14:00 ` [PATCH v2] " Christopher M. Miles
2023-05-16 9:17 ` Ihor Radchenko
2023-05-16 12:18 ` Christopher M. Miles
2023-07-24 11:25 ` Ihor Radchenko
2023-08-01 4:40 ` [PATCH v3] " Christopher M. Miles
2023-08-01 8:04 ` Ihor Radchenko
2023-08-01 12:17 ` [PATCH v3.1] " Christopher M. Miles
2023-08-01 14:09 ` Ihor Radchenko
2023-08-01 15:22 ` Christopher M. Miles
2023-08-01 15:46 ` Christopher M. Miles
2023-08-02 16:08 ` Ihor Radchenko
2023-08-04 6:30 ` Christopher M. Miles
2023-08-02 7:26 ` Ihor Radchenko
2023-08-02 15:44 ` Christopher M. Miles
2023-08-04 8:20 ` Ihor Radchenko
2023-08-05 5:28 ` [PATCH v3.2] " Christopher M. Miles
2024-07-22 10:46 ` Ihor Radchenko
2024-08-01 22:58 ` [PATCH v4.0] " stardiviner
[not found] ` <66a8b73b.170a0220.383476.996e@mx.google.com>
2024-08-12 10:18 ` Ihor Radchenko
2024-08-14 2:04 ` stardiviner
2024-08-18 10:27 ` Ihor Radchenko
2024-08-20 2:02 ` Karthik Chikmagalur
2024-08-20 15:43 ` Karthik Chikmagalur
2024-08-20 18:19 ` Ihor Radchenko
2024-08-20 19:46 ` Karthik Chikmagalur
2024-08-22 13:19 ` Ihor Radchenko
2024-08-23 6:04 ` Karthik Chikmagalur
2024-08-23 23:36 ` Karthik Chikmagalur [this message]
2024-08-24 1:00 ` [PATCH v1] Inline image display as part of a new org-link-preview system Karthik Chikmagalur
2024-08-31 14:22 ` Ihor Radchenko
2024-08-31 16:41 ` Karthik Chikmagalur
2024-08-31 16:53 ` Ihor Radchenko
2024-08-31 22:37 ` [PATCH v2] " Karthik Chikmagalur
2024-09-01 13:06 ` Ihor Radchenko
2024-09-02 20:13 ` [PATCH v3] " Karthik Chikmagalur
2024-09-08 7:43 ` Ihor Radchenko
2024-09-09 3:21 ` Karthik Chikmagalur
2024-09-09 6:06 ` Ihor Radchenko
2024-09-09 6:30 ` Karthik Chikmagalur
2024-09-09 16:47 ` Ihor Radchenko
2024-09-09 19:14 ` Karthik Chikmagalur
2024-09-10 16:57 ` Ihor Radchenko
2024-09-10 19:53 ` Karthik Chikmagalur
2024-09-15 7:51 ` Ihor Radchenko
2024-09-09 21:45 ` Karthik Chikmagalur
2024-09-10 16:58 ` Ihor Radchenko
2024-09-10 17:38 ` Karthik Chikmagalur
2024-09-10 18:34 ` Ihor Radchenko
2024-09-10 19:43 ` Karthik Chikmagalur
2024-09-15 8:12 ` Ihor Radchenko
2024-09-15 20:50 ` Karthik Chikmagalur
2024-09-15 21:57 ` [PATCH v4] " Karthik Chikmagalur
2024-09-17 18:16 ` Ihor Radchenko
2024-09-18 1:44 ` [PATCH v5] " Karthik Chikmagalur
2024-09-21 10:11 ` Ihor Radchenko
2024-09-22 22:00 ` [PATCH v6] " Karthik Chikmagalur
2024-10-03 17:03 ` Ihor Radchenko
2024-10-08 0:07 ` [PATCH v7] " Karthik Chikmagalur
2024-10-10 17:15 ` Ihor Radchenko
2024-10-10 21:23 ` Karthik Chikmagalur
2024-10-12 8:15 ` Ihor Radchenko
2024-10-28 6:13 ` [PATCH v8] " Karthik Chikmagalur
2024-10-28 18:16 ` Ihor Radchenko
2024-10-28 21:53 ` [PATCH v9] " Karthik Chikmagalur
2024-10-29 18:46 ` Ihor Radchenko
2024-10-29 20:45 ` [PATCH v10] " Karthik Chikmagalur
2024-10-30 17:32 ` Ihor Radchenko
2024-10-30 19:50 ` Karthik Chikmagalur
2024-10-31 18:16 ` Ihor Radchenko
2024-08-18 10:34 ` [FR] Automatically display images in resutls of evaluation (was: [PATCH v4.0] Re: [PATCH] add a function to only refresh inline images under current headline instead of global buffer) Ihor Radchenko
[not found] ` <66c54dfc.a70a0220.3c823a.2899@mx.google.com>
2024-08-22 13:06 ` [FR] Automatically display images in resutls of evaluation Ihor Radchenko
[not found] ` <66c89411.170a0220.3255c1.0cd5@mx.google.com>
[not found] ` <87zfor7b04.fsf@localhost>
[not found] ` <CAL1eYuLOsaS43ahueN4uWiCn+Ykp=p_-t9dzAypKdy1en_53BQ@mail.gmail.com>
2024-09-15 13:33 ` [PATCH v3] " Ihor Radchenko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.orgmode.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=875xrqg6cb.fsf@gmail.com \
--to=karthikchikmagalur@gmail.com \
--cc=emacs-orgmode@gnu.org \
--cc=numbchild@gmail.com \
--cc=yantar92@posteo.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).