tmalsburg / helm-bibtex

Search and manage bibliographies in Emacs
GNU General Public License v2.0
463 stars 73 forks source link

automatically open pdf or abstract page from arXiv #283

Open jlapeyre opened 5 years ago

jlapeyre commented 5 years ago

I wrote some code to integrate helm bibtex with the arXiv. But, helm bibtex was rewritten and my code is now broken. I looked at the new code for while to find a way to fix it, but was unable. Does anyone have a suggestion ? The broken functions are the following (abbreviated). They work with the bibtex keys and values that the arXiv uses.

(defun helm-find-arxivid (arxiv-item)
  "Open the page arxiv-item (either 'pdf' or 'abs') in associated arXiv entry in a browser."
...
(defun helm-open-arxiv-pdf-in-emacs (_)
  "Open the arXiv pdf in emacs"
...
(defun helm-bibtex-open-arxiv-abs-url (_)
  "Open the associated arXiv abstract in a browser."
  (helm-find-arxivid "abs"))

(defun helm-bibtex-open-arxiv-pdf-url (_)
  "Open the associated arXiv pdf in a browser."
  (helm-find-arxivid "pdf"))
(helm-add-action-to-source "Open arXiv abstract url"
                           'helm-bibtex-open-arxiv-abs-url helm-source-bibtex 10)

(helm-add-action-to-source "Open arXiv pdf url"
                           'helm-bibtex-open-arxiv-pdf-url helm-source-bibtex 11)

(helm-add-action-to-source "Open arXiv pdf in emacs"
                           'helm-open-arxiv-pdf-in-emacs helm-source-bibtex 12)
tmalsburg commented 5 years ago

Could you explain what exactly is going wrong? Do you get an error? If yes, what is the error message?

jlapeyre commented 5 years ago

Yes. I hit TAB on an entry and my added actions are displayed. I select one of them and the following error is displayed in the minibuffer.

Symbol's function definition is void: helm-bibtex-get-entry.

Here is the code is for just one of the actions:

(defun clean-arxivid (arxivid)
  (if (and (stringp arxivid) (string-match "arXiv:" arxivid))
      (replace-match "" nil nil arxivid)
    arxivid))

(defun helm-open-arxiv-pdf-in-emacs (_)
  "Open the arXiv pdf in emacs"
  (let ((keys (helm-marked-candidates :with-wildcard t)))
    (dolist (key keys)
      (let* ((entry (helm-bibtex-get-entry key))
             (arxivid (clean-arxivid (helm-bibtex-get-value "arXivid" entry)))
             (eprint (clean-arxivid (helm-bibtex-get-value "eprint" entry)))
             (eprint-choice (if eprint eprint arxivid)))
        (if eprint-choice
            (let* ((arxiv-url (s-concat "http://arxiv.org/" "pdf" "/" eprint-choice))
                   (tmp-pdf (s-concat (make-temp-file "arXiv") ".pdf")))
              (url-copy-file arxiv-url tmp-pdf)
              (find-file tmp-pdf))
          (message "No arXivid for entry"))))))

(helm-add-action-to-source "Open arXiv pdf in emacs"
                           'helm-open-arxiv-pdf-in-emacs helm-source-bibtex 12)
tmalsburg commented 5 years ago

Wow, you must have been using an ancient version of helm-bibtex. ;) The function helm-bibtex-get-entry has been replaced by bibtex-completion-get-entry. Similarly for helm-bibtex-get-value.

jlapeyre commented 5 years ago

Thanks that fixed it. I really thought I had tried all the simple things.

It is really useful to open the pdf from the arXiv in emacs rather than copying it to my library and renaming it, etc.

tmalsburg commented 5 years ago

Do your actions assume a BibTeX format that is somehow standard for arXiv articles? Perhaps you could give me an example. If these action could be useful for other users as well, we could include them in the package.

jlapeyre commented 5 years ago

I think that would be a great idea. arXiv has changed the format of their bibtex entries (at least once). So, my code checks for the current format and an older one. If you are on the abstract page, and click on the "NASA ADS" link in the bar on the right, you get an information page that has an "export citation" button. This format includes a key with the arXiv id, which can be used to form the url for getting the abstract page, or the pdf, etc. In fact, this adsab page recently added much more information, so an action to open it might be useful.

Currently, I fetch that bibtex entry by hand and copy it to my master bibtex file by hand.

An example of a recent entry is:

@ARTICLE{2016PhRvL.116q0601R,
       author = {{Reuveni}, Shlomi},
        title = "{Optimal Stochastic Restart Renders Fluctuations in First Passage Times Universal}",
      journal = {\prl},
     keywords = {Condensed Matter - Statistical Mechanics},
         year = "2016",
        month = "Apr",
       volume = {116},
          eid = {170601},
        pages = {170601},
          doi = {10.1103/PhysRevLett.116.170601},
archivePrefix = {arXiv},
       eprint = {1512.01600},
 primaryClass = {cond-mat.stat-mech},
       adsurl = {https://ui.adsabs.harvard.edu/\#abs/2016PhRvL.116q0601R},
      adsnote = {Provided by the SAO/NASA Astrophysics Data System}
}

All you need in this case is the eprint field. Following is elisp code for some actions.

(defun clean-arxivid (arxivid)
  (if (and (stringp arxivid) (string-match "arXiv:" arxivid))
      (replace-match "" nil nil arxivid)
    arxivid))

(defun helm-find-arxivid (arxiv-item)
  "Open the page arxiv-item (either 'pdf' or 'abs') in associated arXiv entry in a browser."
  (let ((keys (helm-marked-candidates :with-wildcard t)))
    (dolist (key keys)
      (let* ((entry (bibtex-completion-get-entry key))
             (arxivid (clean-arxivid (bibtex-completion-get-value "arXivid" entry)))
             (eprint (clean-arxivid (bibtex-completion-get-value "eprint" entry)))
             (eprint-choice (if eprint eprint arxivid))
             (browse-url-browser-function
              (or helm-bibtex-browser-function
                  browse-url-browser-function)))
        (if eprint-choice
            (let* ((arxiv-url (s-concat "http://arxiv.org/" arxiv-item "/" eprint-choice)))
              (helm-browse-url arxiv-url))
          (message "No arXivid for entry"))))))

(defun helm-open-arxiv-pdf-in-emacs (_)
  "Open the arXiv pdf in emacs"
  (let ((keys (helm-marked-candidates :with-wildcard t)))
    (dolist (key keys)
      (let* ((entry (bibtex-completion-get-entry key))
             (arxivid (clean-arxivid (bibtex-completion-get-value "arXivid" entry)))
             (eprint (clean-arxivid (bibtex-completion-get-value  "eprint" entry)))
             (eprint-choice (if eprint eprint arxivid)))
        (if eprint-choice
             (let* ((arxiv-url (s-concat "http://arxiv.org/" "pdf" "/" eprint-choice))
                   (tmp-pdf (s-concat (make-temp-file "arXiv") ".pdf")))
              (url-copy-file arxiv-url tmp-pdf)
              (find-file tmp-pdf))
          (message "No arXivid for entry"))))))

(defun helm-bibtex-open-arxiv-abs-url (_)
  "Open the associated arXiv abstract in a browser."
  (helm-find-arxivid "abs"))

(defun helm-bibtex-open-arxiv-pdf-url (_)
  "Open the associated arXiv pdf in a browser."
  (helm-find-arxivid "pdf"))

(helm-add-action-to-source "Open arXiv abstract url"
                           'helm-bibtex-open-arxiv-abs-url helm-source-bibtex 11)

(helm-add-action-to-source "Open arXiv pdf in emacs"
                            'helm-open-arxiv-pdf-in-emacs helm-source-bibtex 12)

(helm-add-action-to-source "Open arXiv pdf url"
                           'helm-bibtex-open-arxiv-pdf-url helm-source-bibtex 13)
tmalsburg commented 5 years ago

Thinking about this a bit more: Instead of additional actions for articles from specific sources, I think what we really want is to make the existing actions smarter. E.g. when I choose the action for opening PDFs and there is none locally, the PDF is retrieved from arXiv if the article is from arXiv.

Sidenote: You say you fetch BibTeX for arXiv papers by hand. Helm-bibtex has a fall-back option for searching arXiv and retrieving BibTeX (uses biblio.el).

jlapeyre commented 5 years ago

when I choose the action for opening PDFs and there is none locally, the PDF is retrieved from arXiv if the article is from arXiv.

Yes, this would be good in general. For various reasons, I sometimes like to get the local pdf or the arXiv version (some have broken links, updates, whatever)