Q: How can I create a link in org-mode
to a specific page of a PDF file, which can be opened (in either Skim or Adobe) with a mouse-click?
* My example heading. :tag:
[[pdf:/path/to/file.pdf#105][My description.]]
Emacs Stack Exchange is a question and answer site for those using, extending or developing Emacs. It only takes a minute to sign up.
Sign up to join this communityOn OSX (now macOS), you can simply use org-mac-link.el
, it supports Skim and Adobe Acrobat Pro. To use, open pdf file in Skim and go to the page you want to link, then type M-x org-mac-grab-link
from Emacs, it should insert an org link (like the following) at point.
[[skim:///Users/xcy/Downloads/calccard.pdf::2][calccard.pdf, p. 2]]
then when you click the link, the pdf file will be opened in Skim and goto page 2, no matter if Skim is running.
You can get org-mac-link.el
from
org-mac-link
on Melpaorg-plus-contrib
on Org Elpaunless you install org-mac-link
on Melpa via package.el
, you have to autoload org-mac-grab-link
etc or require org-mac-link.el
somewhere by yourself.
org-mac-link
library, which I was unaware of. It contains some interesting ideas and may become my preferred method in the future, but I would like some time to try it out and see how I like it. At this time, I am leaning in favor of continuing to use #
to separate the page number from the path instead of ::
and I like not having to put an extra //
before the absolute path. With all that being said, I look forward to playing with the org-mac-link
library in the future.
The following answer is for Skim
on OSX, and it utilizes applescript
. Skim does not have any command-line options to open a PDF file to a specific page, unless it is a forward-search situation dealing with a TeX file and the built-in Skim displayline
utility.
Example heading in org-mode
:
* My example heading. :tag:
[[pdf:/path/to/file.pdf#105][My description.]]
The code:
(require 'org)
(org-add-link-type "pdf" 'org-pdf-open nil)
(defun org-pdf-open (link)
"Where page number is 105, the link should look like:
[[pdf:/path/to/file.pdf#105][My description.]]"
(let* ((path+line (split-string link "#"))
(pdf-file (car path+line))
(base-filename (file-name-nondirectory pdf-file))
(page (car (cdr path+line)))
(script
(format
"tell document \"%s\" of application \"Skim\" to go to page %s"
base-filename page))
(skim-program "/Applications/Skim.app/Contents/MacOS/Skim"))
(set-process-sentinel
(start-process "skim-process" nil "open" "-a" skim-program pdf-file)
`(lambda (p e) (when (= 0 (process-exit-status p))
(when ,page ;; just in case user wants to omit the page number from the link
(start-process "goto-page" nil "osascript" "-e" ,script)))))))
This is what I use for evince on Linux (a modified version of lawlist's answer):
(org-add-link-type "pdf" 'org-pdf-open nil)
(defun org-pdf-open (link)
"Where page number is 105, the link should look like:
[[pdf:/path/to/file.pdf#page=105][My description.]]"
(let* ((path+page (split-string link "#page="))
(pdf-file (car path+page))
(page (car (cdr path+page))))
(start-process "view-pdf" nil "evince" "--page-index" page pdf-file)))