23
votes

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.

3
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
@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

3 Answers

12
votes

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.

3
votes

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.

3
votes

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).