30

Note: This question was asked here before, with no success.

Org-mode’s ability to display inline images is fantastic for writing my weekly scientific reports. I can include graphs, link them with their data, link with the conclusions, and really harness the power of org-mode.

The only problem I have is that org needs the images to use conventional image formats (jpeg, png, etc), while I prefer for my graphs to be in PDF.

How can I display inline pdf images in org-mode?

My final objective is to just write a link like this in org-mode:

[[file:~/Work/grap.pdf]]

And have it displayed inline just like it would happen if it were a png.

I know I could just have a copy of each graph in jpeg or something (which is what I do right now), but it’s slightly cumbersome and it always carries the risk of the pdf graph being updated and me forgetting to update the jpeg.

3
  • This might work as a solution: Going along the lines of endless/update-includes, if during before-save-hook, if you find a line with #+NAME or #+CAPTION with a tag like :convertfrompdf followed by a line with [[SOMEFILE.EXT]], then you execute the Imagemagick convert function to convert SOMEFILE.pdf to SOMEFILE.EXT. Sep 28, 2014 at 13:47
  • @kaushalmodi yeah. another option would be something that hooks into org-display-images.
    – Malabarba
    Sep 28, 2014 at 14:48
  • 2
    A solution based on pdf-tools/poppler would be nice.
    – phils
    Apr 5, 2017 at 4:03

2 Answers 2

17

NOTE: You need to have ImageMagick installed on your system (convert executable) for this solution to work.

How this solution is implemented

  • The function org-include-img-from-pdf is the workhorse that does the PDF to Image format conversion using convert.
  • If the org file contains # ()convertfrompdf:t, it will be assumed that the user has a pdf file that they want to convert to an image file. The user should put the above special comment above the image file link as shown in the below example.
  • The image file type is determined by the file extension in the bracket link [[./myimage.EXT]].

  • By adding the org-include-img-from-pdf function to the before-save-hook, that function is executed every time the user saves the file (See the elisp snippet following the function definition below).

Example setup

In this example setup I have the following files:

  • An org file like below that includes an image file.
  • The pdf file myimage.pdf.
# ()convertfrompdf:t
[[./myimage.png]]

Function to auto convert pdf to image files

(defun org-include-img-from-pdf (&rest _)
  "Convert pdf files to image files in org-mode bracket links.

    # ()convertfrompdf:t # This is a special comment; tells that the upcoming
                         # link points to the to-be-converted-to file.
    # If you have a foo.pdf that you need to convert to foo.png, use the
    # foo.png file name in the link.
    [[./foo.png]]
"
  (interactive)
  (if (executable-find "convert")
      (save-excursion
        (goto-char (point-min))
        (while (re-search-forward "^[ \t]*#\\s-+()convertfrompdf\\s-*:\\s-*t"
                                  nil :noerror)
          ;; Keep on going to the next line till it finds a line with bracketed
          ;; file link.
          (while (progn
                   (forward-line 1)
                   (not (looking-at org-bracket-link-regexp))))
          ;; Get the sub-group 1 match, the link, from `org-bracket-link-regexp'
          (let ((link (match-string-no-properties 1)))
            (when (stringp link)
              (let* ((imgfile (expand-file-name link))
                     (pdffile (expand-file-name
                               (concat (file-name-sans-extension imgfile)
                                       "." "pdf")))
                     (cmd (concat "convert -density 96 -quality 85 "
                                  pdffile " " imgfile)))
                (when (and (file-readable-p pdffile)
                           (file-newer-than-file-p pdffile imgfile))
                  ;; This block is executed only if pdffile is newer than
                  ;; imgfile or if imgfile does not exist.
                  (shell-command cmd)
                  (message "%s" cmd)))))))
    (user-error "`convert' executable (part of Imagemagick) is not found")))

Hook setup to specify when to run this function

(defun my/org-include-img-from-pdf-before-save ()
  "Execute `org-include-img-from-pdf' just before saving the file."
    (add-hook 'before-save-hook #'org-include-img-from-pdf nil :local))
(add-hook 'org-mode-hook #'my/org-include-img-from-pdf-before-save)

;; If you want to attempt to auto-convert PDF to PNG  only during exports, and not during each save.
;; (with-eval-after-load 'ox
;;   (add-hook 'org-export-before-processing-hook #'org-include-img-from-pdf))

Code + MWE

1
  • 1
    Does this mean that an exported file uses the png instead of the pdf?
    – gdkrmr
    Jan 28, 2019 at 12:50
3

There is now a package on melpa just for this purpose: org-inline-pdf.

It is developed at github, where you also find usage information. https://github.com/shg/org-inline-pdf.el

Note that this package needs the pdf2svg tool. Also orgmode 9.4 is a minimum requirement.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.