jkitchin / org-ref

org-mode modules for citations, cross-references, bibliographies in org-mode and useful bibtex tools to go with it.
GNU General Public License v3.0
1.37k stars 244 forks source link

open pdf from bib field #172

Closed vcurdia closed 8 years ago

vcurdia commented 8 years ago

I've recently started using org-ref to include citations in my org notes. I like the idea of it allowing me to open the pdf straight from the cite link.

However, that only works if all my pdfs are in a single large folder. I usually keep the pdfs in subfolders and I would like to specify the pdf location on a per-bib entry basis. This works in Helm-bibtex using the following command: (setq helm-bibtex-pdf-field "File")

However, when I click on the cite link from my org file using the link created by org-ref it does not find the pdf. I guess that this happens because org-ref does not recognize the bib entry field "File" as a store for the pdf location of that entry.

I tried a couple of alternative ways to force org-ref to use the find-pdf function of helm-bibtex but my very limited knowledge of lisp was not enough to get that to work unfortunately.

Can anyone let me know if the behavior that I describe is feasible or not with some tweaks in my ".emacs"?

Also, if it were possible to specify multiple files (to include support materials), that would be really great. I know that this is possible as well in helm-bibtex.

jagrg commented 8 years ago

Indeed, org-ref-pdf-directory only accepts one directory. I'm not sure if this would work using helm-bibtex-pdf-field, but one solution may be to check if the pdf file exists in helm-bibtex-library-path. This is what worked for me:

2 files changed, 9 insertions(+), 6 deletions(-)
org-ref-helm-bibtex.el |  5 +++--
org-ref-utils.el       | 10 ++++++----

modified   org-ref-helm-bibtex.el
@@ -327,6 +327,7 @@ Checks for pdf and doi, and add appropriate functions."
   (let* ((results (org-ref-get-bibtex-key-and-file))
          (key (car results))
          (pdf-file (funcall org-ref-get-pdf-filename-function key))
+    (pdf-other (car (helm-bibtex-find-pdf-in-library key)))
          (bibfile (cdr results))
          (url (save-excursion
                 (with-temp-buffer
@@ -350,8 +351,8 @@ Checks for pdf and doi, and add appropriate functions."
     (when (string= url "") (setq url nil))

     ;; Conditional pdf functions
-    (if (file-exists-p pdf-file)
-        (cl-pushnew
+    (if (or (file-exists-p pdf-file) (file-exists-p pdf-other))
+   (cl-pushnew
          '("Open pdf" . org-ref-open-pdf-at-point)
          candidates)
       (cl-pushnew
modified   org-ref-utils.el
@@ -353,10 +353,12 @@ Argument KEY is the bibtex key."
   (interactive)
   (let* ((results (org-ref-get-bibtex-key-and-file))
          (key (car results))
-         (pdf-file (funcall org-ref-get-pdf-filename-function key)))
-    (if (file-exists-p pdf-file)
-        (org-open-file pdf-file)
-      (message "no pdf found for %s" key))))
+         (pdf-file (funcall org-ref-get-pdf-filename-function key))
+    (pdf-other (car (helm-bibtex-find-pdf-in-library key))))
+    (cond ((file-exists-p pdf-file)
+      (org-open-file pdf-file))
+     ((file-exists-p pdf-other)
+      (browse-url pdf-other)))))

 ;;;###autoload
jkitchin commented 8 years ago

The best way to do this is to define a function of your own to find and open the pdf, and set org-ref-open-pdf-function to that function.

https://github.com/jkitchin/org-ref/blob/f7729df257db092dc30624a00271a99e6f483a1d/org-ref.el#L262

Basically you get the key at point, find the bibtex entry, and derive a path to the pdf(s) from the entry, perhaps from a File field.

Jonathan Gregory writes:

Indeed, org-ref-pdf-directory only accepts one directory. I'm not sure if this would work using helm-bibtex-pdf-field, but one solution may be to check if the pdf file exists in helm-bibtex-library-path. This is what worked for me:

2 files changed, 9 insertions(+), 6 deletions(-)
org-ref-helm-bibtex.el |  5 +++--
org-ref-utils.el       | 10 ++++++----

modified   org-ref-helm-bibtex.el
@@ -327,6 +327,7 @@ Checks for pdf and doi, and add appropriate functions."
   (let* ((results (org-ref-get-bibtex-key-and-file))
          (key (car results))
          (pdf-file (funcall org-ref-get-pdf-filename-function key))
+      (pdf-other (car (helm-bibtex-find-pdf-in-library key)))
          (bibfile (cdr results))
          (url (save-excursion
                 (with-temp-buffer
@@ -350,8 +351,8 @@ Checks for pdf and doi, and add appropriate functions."
     (when (string= url "") (setq url nil))

     ;; Conditional pdf functions
-    (if (file-exists-p pdf-file)
-        (cl-pushnew
+    (if (or (file-exists-p pdf-file) (file-exists-p pdf-other))
+ (cl-pushnew
          '("Open pdf" . org-ref-open-pdf-at-point)
          candidates)
       (cl-pushnew
modified   org-ref-utils.el
@@ -353,10 +353,12 @@ Argument KEY is the bibtex key."
   (interactive)
   (let* ((results (org-ref-get-bibtex-key-and-file))
          (key (car results))
-         (pdf-file (funcall org-ref-get-pdf-filename-function key)))
-    (if (file-exists-p pdf-file)
-        (org-open-file pdf-file)
-      (message "no pdf found for %s" key))))
+         (pdf-file (funcall org-ref-get-pdf-filename-function key))
+      (pdf-other (car (helm-bibtex-find-pdf-in-library key))))
+    (cond ((file-exists-p pdf-file)
+        (org-open-file pdf-file))
+       ((file-exists-p pdf-other)
+        (browse-url pdf-other)))))

 ;;;###autoload

You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/jkitchin/org-ref/issues/172#issuecomment-206877528

Professor John Kitchin Doherty Hall A207F Department of Chemical Engineering Carnegie Mellon University Pittsburgh, PA 15213 412-268-7803 @johnkitchin http://kitchingroup.cheme.cmu.edu

vcurdia commented 8 years ago

Thanks for the comments. Unfortunately I don't know lisp enough to create my own function from scratch.

However I noticed that if I set the "File" field in helm-bibtex and then from org-ref I press C-] to insert citation and I click on tab I am given the option to open the pdf and it works (regardless of whether the file is in the default bibpdf folder or in a path set in the File field) but when I click on the citation link created by org-ref that no longer works.

This suggests to me that it should be feasible to get the citation link to open the pdf from the file field with existing org-ref functionality, as long as we establish some additional links between org-ref functions and helm-bibtex functions.

I haven't figured this out yet, so I'm open to further suggestions.

jagrg commented 8 years ago

@vcurdia From @jkitchin's suggestion, you will need something like the code below. But we need to change a few things in the source code first before it can actually work.

(setq org-ref-open-pdf-function 'my/org-ref-open-pdf-at-point)

(defun my/org-ref-open-pdf-at-point ()
  "Open the pdf for bibtex key under point if it exists."
  (interactive)
  (let* ((results (org-ref-get-bibtex-key-and-file))
         (key (car results))
         (pdf-file (funcall org-ref-get-pdf-filename-function key))
     (pdf-other (car (helm-bibtex-find-pdf-in-library key))))
    (cond ((file-exists-p pdf-file)
       (org-open-file pdf-file))
      (helm-bibtex-pdf-field
       (funcall helm-bibtex-pdf-open-function
            (helm-bibtex-find-pdf-in-field key)))
      ((file-exists-p pdf-other)
       (funcall helm-bibtex-pdf-open-function pdf-other))
      (message "No PDF found for %s" key))))
vcurdia commented 8 years ago

I tried this after updating org-ref with today's update.

When trying to use the pdf in the File field, it still works in helm-bibtex (when searching the database using C-] ). However, when I create the cite link with org-ref and then click on the link it is broken and I get the following message:

org-ref-cite-candidates: Wrong type argument: stringp, nil

To be sure, this is the entry in my bib file:

@Article{DelNegroFRBNYDSGE2016a, author = {Del Negro, Marco and {FRBNY DSGE}}, title = {aMeasures and Policy Applications of the Equilibrium Neutral Real Interest Rate}, journal = {Unpublished}, year = 2016, File = {BibPDF/DelNegro/DelNegroFRBNYDSGE2016a.pdf}, }

and these are the relevant lines in my .emacs

;; Use org-ref (require 'org-ref)

;; Default bib for reftex (setq reftex-default-bibliography '("~/Work/Bibliography/References.bib"))

;; see org-ref for use of these variables (setq org-ref-bibliography-notes "~/Work/Bibliography/Notes.org" org-ref-default-bibliography '("~/Work/Bibliography/References.bib") org-ref-pdf-directory "~/Work/Bibliography/BibPDF/")

;; Helm-bibtex options (setq helm-bibtex-pdf-field "File") ; open pdf with system pdf viewer (setq helm-bibtex-pdf-open-function 'org-open-file)

;; Allow for file field to be recognized in org-ref (setq org-ref-open-pdf-function 'my/org-ref-open-pdf-at-point) (defun my/org-ref-open-pdf-at-point () "Open the pdf for bibtex key under point if it exists." (interactive) (let* ((results (org-ref-get-bibtex-key-and-file)) (key (car results)) (pdf-file (funcall org-ref-get-pdf-filename-function key)) (pdf-other (car (helm-bibtex-find-pdf-in-library key)))) (cond ((file-exists-p pdf-file) (org-open-file pdf-file)) (helm-bibtex-pdf-field (funcall helm-bibtex-pdf-open-function (helm-bibtex-find-pdf-in-field key))) ((file-exists-p pdf-other) (funcall helm-bibtex-pdf-open-function pdf-other)) (message "No PDF found for %s" key))))

jagrg commented 8 years ago

Try adding this line to your org document and see if that helps: #+LATEX_HEADER: \bibliography{~/Work/Bibliography/References}

vcurdia commented 8 years ago

That didn't fix the problem. I was already using the following at the end of my org file: bibliography:References.bib

Let me be clear: if the pdf is in the main folder with all BibPDF files then the org-ref link works fine. It's only if I specify the path/filename in the bib entry that it doesn't work. Two examples:

bib file:

@Article{DelNegroFRBNYDSGE2016, author = {Del Negro, Marco and {FRBNY DSGE}}, title = {Measures and Policy Applications of the Equilibrium Neutral Real Interest Rate}, journal = {Unpublished}, year = 2016, }

@Article{DelNegroFRBNYDSGE2016a, author = {Del Negro, Marco and {FRBNY DSGE}}, title = {aMeasures and Policy Applications of the Equilibrium Neutral Real Interest Rate}, journal = {Unpublished}, year = 2016, File = {BibPDF/DelNegro/DelNegroFRBNYDSGE2016a.pdf}, }

org file:

cite:DelNegroFRBNYDSGE2016 cite:DelNegroFRBNYDSGE2016a

First link works because the file DelNegroFRBNYDSGE2016.pdf is in the folder BibPDF which is the default BibPDF folder.

The second link does not work. I assume that it is because the functions searching through the path and filename in bib entry File field crash at some point.

jagrg commented 8 years ago

I tested a few times with the new changes and it seems to be working fine. You will also need to update the function below:

(defun my/org-ref-open-pdf-at-point ()
  "Open the pdf for bibtex key under point if it exists."
  (interactive)
  (let* ((results (org-ref-get-bibtex-key-and-file))
         (key (car results))
         (pdf-file (funcall org-ref-get-pdf-filename-function key))
     (pdf-other (bibtex-completion-find-pdf key)))
    (cond ((file-exists-p pdf-file)
       (org-open-file pdf-file))
      (pdf-other
       (org-open-file pdf-other))
      (message "No PDF found for %s" key))))
vcurdia commented 8 years ago

It works now!! Thanks a lot.

randomwangran commented 4 years ago

org-open-file will lauch pdf-file using external program under my configuration.

Here's how I force it open within Emacs:

(defun org-ref-open-pdf-at-point ()
  "Open the pdf for bibtex key under point if it exists.
Tweak from https://github.com/jkitchin/org-ref/issues/172#issuecomment-207626125"
  (interactive)
  (let* ((results (org-ref-get-bibtex-key-and-file))
         (key (car results))
         (pdf-other (bibtex-completion-find-pdf key)))
    (find-file (car pdf-other))))
jdtonkin commented 3 years ago

I can't get this to work. I've started using zotero and want to keep the pdfs in their original subdirectories (it's only one directory deep). I can access the pdfs when I tab on an org-ref link inside an org file, which opens up helm-bibtex. But when I press return on a link opening org-ref, it can't find the pdf. It was working fine with all pdfs in one directory with no subdirectories. Any suggestions. None of the lisp above works. The message I get is "let*: Symbol’s value as variable is void: message".

jkitchin commented 3 years ago

That error message means there is probably a bug in some function where message is incorrectly used in a let* body. What is the function you use to get a pdf file name?

On Fri, Jul 9, 2021 at 2:58 AM Jonathan Tonkin @.***> wrote:

I can't get this to work. I've started using zotero and want to keep the pdfs in their original subdirectories (it's only one directory deep). I can access the pdfs when I tab on an org-ref link inside an org file, which opens up helm-bibtex. But when I press return on a link opening org-ref, it can't find the pdf. It was working fine with all pdfs in one directory with no subdirectories. Any suggestions. None of the lisp above works. The message I get is "let*: Symbol’s value as variable is void: message".

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/jkitchin/org-ref/issues/172#issuecomment-876962060, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAMJCVQU6TAKIHTFFXJUW4TTW2MZNANCNFSM4CAGWBTA .

-- John


Professor John Kitchin (he/him/his) Doherty Hall A207F Department of Chemical Engineering Carnegie Mellon University Pittsburgh, PA 15213 412-268-7803 @johnkitchin http://kitchingroup.cheme.cmu.edu

jdtonkin commented 3 years ago

I tried the above suggestion, so it'd be org-ref-get-pdf-filename-function I assume.

(defun my/org-ref-open-pdf-at-point () "Open the pdf for bibtex key under point if it exists." (interactive) (let* ((results (org-ref-get-bibtex-key-and-file)) (key (car results)) (pdf-file (funcall org-ref-get-pdf-filename-function key)) (pdf-other (bibtex-completion-find-pdf key))) (cond ((file-exists-p pdf-file) (org-open-file pdf-file)) (pdf-other (org-open-file pdf-other)) (message "No PDF found for %s" key))))

https://github.com/jkitchin/org-ref/issues/172#issuecomment-207626125

jkitchin commented 3 years ago

I am traveling, so I can’t see real clearly, but I think the way you use the message incorrectly. It looks like it doesn’t fall through correctly in the cond. it should be wrapped in (t (message …)) instead.

On Fri, Jul 9, 2021 at 1:27 PM Jonathan Tonkin @.***> wrote:

I tried the above suggestion, so it'd be org-ref-get-pdf-filename-function I assume.

(defun my/org-ref-open-pdf-at-point () "Open the pdf for bibtex key under point if it exists." (interactive) (let* ((results (org-ref-get-bibtex-key-and-file)) (key (car results)) (pdf-file (funcall org-ref-get-pdf-filename-function key)) (pdf-other (bibtex-completion-find-pdf key))) (cond ((file-exists-p pdf-file) (org-open-file pdf-file)) (pdf-other (org-open-file pdf-other)) (message "No PDF found for %s" key))))

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/jkitchin/org-ref/issues/172#issuecomment-877342098, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAMJCVXJUCIKGXOMBGV66CLTW4WPNANCNFSM4CAGWBTA .

-- John


Professor John Kitchin (he/him/his) Doherty Hall A207F Department of Chemical Engineering Carnegie Mellon University Pittsburgh, PA 15213 412-268-7803 @johnkitchin http://kitchingroup.cheme.cmu.edu

jdtonkin commented 3 years ago

Thanks. Tried that and it now tells me the pdf can't be found. So at least gives the right error message, but helm-bibtex can find the pdf.

jdtonkin commented 3 years ago

Figured it out. Replaced (pdf-other (bibtex-completion-find-pdf key))) with (pdf-other (org-ref-get-pdf-filename-helm-bibtex key)))

tiagoweber commented 2 years ago

I had a similar problem and the function described by some in this issue had helped me. However, after about a year (probably due to some version update) it stopped working. In my case, the problem was that the function "bibtex-completion-find-pdf" was not being able to find the pdf. The solution was to set the variable bibtex-completion-library-path: (setq org-ref-pdf-directory '("/my/pdf/directory")) (setq bibtex-completion-library-path org-ref-pdf-directory)

vcurdia commented 2 years ago

This happened to me about a couple of weeks ago. I stopped using this custom-made function and it just works fine. I wonder if helm-bibtex incorporated some version of this into their codes.