24

In emacs+org-mode, when viewing an org-mode buffer, you can inline linked images with the org-toggle-inline-images command. This includes various formats out of the box, but apparently PDF images aren't included yet.

Given that emacs is perfectly capable of rendering PDF files, is it possible to make org-mode inline PDF files like it does with images (png,jpeg,etc)?

Some background: PDF images are more convenient for me for several reasons, the biggest being that they scale well and work well with latex, from small papers to large posters.

Malabarba
  • 4,473
  • 2
  • 30
  • 49
  • 1
    Correction: Emacs is not capable of rendering PDF files (I guess you could write such a thing in Elisp, but it would be a lot of work, for a very disappointing result since it would be slow). It can display PDF files by using external tools, tho, so indeed it should be possible to make Org display such linked documents inline. – Stefan Mar 14 '13 at 14:05
  • @Stefan You're right. An external tool does the actual rendering. I meant to say it displays PDF files out of the box (at least on linux). – Malabarba Mar 14 '13 at 17:39

3 Answers3

13

Let me finish this question.

Firstly, Org-mode does not support any pdf inline display function with itself. However, it is possible to modify org-display-inline-images to achieve what you want. First you need to refer to this answer: Configuring emacs for showing fixed width inline images, which inspired me a lot. Then I slightly modified the function, making it support pdf, bmp display in org-mode. My function is on below.

(setq image-file-name-extensions
   (quote
    ("png" "jpeg" "jpg" "gif" "tiff" "tif" "xbm" "xpm" "pbm" "pgm" "ppm" "pnm" "svg" "pdf" "bmp")))

(setq org-image-actual-width 600)

(setq org-imagemagick-display-command "convert -density 600 \"%s\" -thumbnail \"%sx%s>\" \"%s\"")
(defun org-display-inline-images (&optional include-linked refresh beg end)
  "Display inline images.
Normally only links without a description part are inlined, because this
is how it will work for export.  When INCLUDE-LINKED is set, also links
with a 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 REFRESH is set, refresh existing images between BEG and END.
This will create new image displays only if necessary.
BEG and END default to the buffer boundaries."
  (interactive "P")
  (unless refresh
    (org-remove-inline-images)
    (if (fboundp 'clear-image-cache) (clear-image-cache)))
  (save-excursion
    (save-restriction
      (widen)
      (setq beg (or beg (point-min)) end (or end (point-max)))
      (goto-char beg)
      (let ((re (concat "\\[\\[\\(\\(file:\\)\\|\\([./~]\\)\\)\\([^]\n]+?"
                        (substring (org-image-file-name-regexp) 0 -2)
                        "\\)\\]" (if include-linked "" "\\]")))
            old file ov img)
        (while (re-search-forward re end t)
          (setq old (get-char-property-and-overlay (match-beginning 1)
                                                   'org-image-overlay)
        file (expand-file-name
                      (concat (or (match-string 3) "") (match-string 4))))
          (when (file-exists-p file)
            (let ((file-thumb (format "%s%s_thumb.png" (file-name-directory file) (file-name-base file))))
              (if (file-exists-p file-thumb)
                  (let ((thumb-time (nth 5 (file-attributes file-thumb 'string)))
                        (file-time (nth 5 (file-attributes file 'string))))
                    (if (time-less-p thumb-time file-time)
            (shell-command (format org-imagemagick-display-command
                           file org-image-actual-width org-image-actual-width file-thumb) nil nil)))
                (shell-command (format org-imagemagick-display-command
                                         file org-image-actual-width org-image-actual-width file-thumb) nil nil))
              (if (and (car-safe old) refresh)
                  (image-refresh (overlay-get (cdr old) 'display))
                (setq img (save-match-data (create-image file-thumb)))
                (when img
                  (setq ov (make-overlay (match-beginning 0) (match-end 0)))
                  (overlay-put ov 'display img)
                  (overlay-put ov 'face 'default)
                  (overlay-put ov 'org-image-overlay t)
                  (overlay-put ov 'modification-hooks
                               (list 'org-display-inline-remove-overlay))
                  (push ov org-inline-image-overlays))))))))))

The function uses convert file.pdf -thumbnail "400x400>" file_thumb.png to generate a file_thumb named thumbnail in your folder to substitute overlay of pdf, and force org-mode to display pdf with file_thumb without any modification to the org file.

Moreover, because i use babel to generate image with python. It always need me to update the _thumb file, so I add a if condition to say if this thumb file existed or not, and if the pdf file changed i need to change thumb file on the same time... and so on!

Hope it can help you.

Community
  • 1
  • 1
Leu_Grady
  • 498
  • 3
  • 15
  • 1
    great solution! This should be default behavior. – TNT Feb 23 '16 at 11:28
  • I tried this solution on an image file that is not in the same folder of the org file. But it does not make the png file. What is my problem? – bobsacameno Jun 11 '20 at 12:27
  • Can you elaborate more? – Leu_Grady Jun 12 '20 at 13:06
  • I have my org file in some folder. And the pdf (image) file in another folder. I insert the link to the file, and when I toggle the inline image I see a little black square. When I check the messages, I see that it cannot find the png file. BTW, I am looking for a way to view a large image - can this help me? – bobsacameno Jun 12 '20 at 22:11
  • Can you check the result of `(executable-find "convert")`? This checks if "convert" command exist in your exec-path. By the way, can you tell which system you are on? – Leu_Grady Jun 15 '20 at 04:00
  • It gives back `no-match` so I guess I don't have it... I am on MacOS. – bobsacameno Jun 15 '20 at 15:50
  • How can I use this together with https://github.com/hpjansson/chafa to have inline images in the TUI? – HappyFace May 10 '21 at 08:27
3

Short answer: no support for PDF inline images.

The function org-image-file-name-regexp has the image file extensions hardcoded (and does not include PDF). This function is used by org-display-inline-images, which in turn calls create-image.

I've tried adding PDF to org-image-file-name-regexp, and deleting PDF from imagemagik-types-inhibit with no luck.

You may try to dig further, or request the feature to org-mode mailing list.

Juancho
  • 7,207
  • 27
  • 31
  • 1
    Just to update on that: Now (2020) the list of extensions can be customized in the variable `image-file-name-extensions`. – ricma May 04 '20 at 12:48
3

I ran into the same problem and after poking around a bit, got it to work by adding the following to my .emacs file:

(add-to-list 'image-type-file-name-regexps '("\\.pdf\\'" . imagemagick))
(add-to-list 'image-file-name-extensions "pdf")
(setq imagemagick-types-inhibit (remove 'PDF imagemagick-types-inhibit))
(setq org-image-actual-width 600)

Not sure yet, if there are any issues for other modes by these changes. My pdfs in org mode are created by python src code blocks and the above works, but the images don't get updated when I change something in the python mode and I need to run org-display-inline-images by hand.

This assumes that you have an emacs with imagemagick support, something similar should also work for using ghostscript (with perhaps some more edits in org.el).

Arun
  • 481
  • 3
  • 9