emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Pan Xie <xiepan@skyguard.com.cn>
To: emacs-orgmode@gnu.org
Subject: [FR] Please add environment variable substitution in `org-display-inline-images'
Date: Sun, 28 May 2023 21:53:16 +0800	[thread overview]
Message-ID: <7a012430-6084-e693-1a86-f14d0512bebc@skyguard.com.cn> (raw)

Hello,

I recently found that the environment variable substitution does not
apply to inline image paths. Supposing I use a path
“/home/pxie/$Gallery/” to store all my image files, “$Gallery”
should be substituted with its corresponding value. The file link DOES
substitute the environment variables, but inline image paths not. So I
think it is a reasonable demand for the consistency.

It is also very important for my and other users' (I strongly believe)
configurations. Environment variable is the key abstraction to make
the same org document works on different machines with different path
hierarchies.

I hunt down the codes and find just one line change can fix that. In
`org-display-inline-images' function, add `substitute-in-file-name' to
the `expand-file-name' call. I can override the function with the
solution but I hope it can be added to the official codes.

So my proposal of the code change would be (find "pxie" in the codes):

#+begin_src elisp
(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\" 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:\\)"
             (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-property :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-property :contents-end link)
                 (match-end 0))
                  (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)))
;;; {{{ pxie changes begin
                               (expand-file-name 
(substitute-in-file-name path)))))
;;; }}} pxie changes end
           (when (and file (file-exists-p file))
             (let ((width (org-display-inline-image--width link))
               (old (get-char-property-and-overlay
                 (org-element-property :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-property :begin link)
                        (progn
                      (goto-char
                       (org-element-property :end link))
                      (skip-chars-backward " \t")
                      (point)))))
                               ;; FIXME: 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))
                   (push ov org-inline-image-overlays))))))))))))))))
#+end_src

Thanks
Pan



             reply	other threads:[~2023-05-28 13:54 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-28 13:53 Pan Xie [this message]
2023-05-28 14:21 ` [FR] Please add environment variable substitution in `org-display-inline-images' Ruijie Yu via General discussions about Org-mode.
2023-05-31  8:24 ` Ihor Radchenko
2023-05-31 14:05   ` Pan Xie
2023-06-01  0:12     ` Samuel Wales
2023-06-01  0:24       ` Pan Xie
2023-06-01  8:20     ` [FR] Should we resolve environment variables in the file link path when exporting? (was: [FR] Please add environment variable substitution in `org-display-inline-images') Ihor Radchenko
2023-06-01  8:24       ` Pan Xie
2023-06-01  8:35         ` Ihor Radchenko
2023-06-01  8:38           ` Pan Xie
2023-06-01  8:52             ` Ihor Radchenko
2023-07-31  8:30       ` 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=7a012430-6084-e693-1a86-f14d0512bebc@skyguard.com.cn \
    --to=xiepan@skyguard.com.cn \
    --cc=emacs-orgmode@gnu.org \
    /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).