tmalsburg/helm-bibtex

Feature request: opening files specified in "File" field.

rdiaz02 opened this issue · 10 comments

(Disclaimer: I am new to helm-bibtex, so maybe I am missing something obvious).
I see we can redefine helm-bibtex-find-pdf. A use case that might not be that rare is when the name of the PDF has no clear relationship with the key, but is actually specified in the file field
File = {:home/ramon/a_directory/some_file_123.pdf:PDF},

But this might now always be the case, so some entries might follow the usual pattern (key.pdf). Is the reommended procedure to redefine helm-bibtex-find-pdf so we search both in the "File" field and the standard way? Or is there some easier procedure? (If the way to do it is by modifying the function, what is the best way to "get the file field" or similar ---elisp ignorant here, with just enough knowledge to modify elisp code by trial and error).

Yes, you have to modify helm-bibtex-find-pdf. This should work:

(defun helm-bibtex-find-pdf (key)
  "Searches in all directories in `helm-bibtex-library-path' for
a PDF whose name is the name specified in the ’file’ property of the
BibTeX entry or whose name is KEY + \".pdf\".  Returns the first
matching PDF."
  (let* ((entry (helm-bibtex-get-entry key))
         (fname (helm-bibtex-get-value "File" entry))
         (files1 (--map (f-join it fname) (-flatten (list helm-bibtex-library-path))))
         (files2 (--map (f-join it (s-concat key ".pdf")) (-flatten (list helm-bibtex-library-path)))))
    (-first 'f-exists? (append files1 files2))))

My code works when the content of the "file" field is just the bare name of the pdf file without directory. This pdf file is then searched in the directories specified in helm-bibtex-library-path. In order to make it work with the format that you have, you have to make some changes.

Thanks a lot. I'll work from that; I might also have to reorganize where directories with PDFs hang from, to make the search or the parsing of the directory easier. I just tried it, and I am getting Variable binding depth exceeds max-specpdl-size even if the pdf is present in the usual way (KEY + pdf); this is a directory with over 4000 subdirectories.
Since the question is basically answered (tweak helm-bibtex-find-pdf to suit the specific needs) I am closing the issue. If/when I am able to get it to work, I'll report back.

Not sure about the error message (which I don’t get on the current development version of Emacs) but you can try the following variant:

(defun helm-bibtex-find-pdf (key)
  "Searches in all directories in `helm-bibtex-library-path' for
a PDF whose name is KEY + \".pdf\".  Returns the first matching PDF."
  (let* ((entry (helm-bibtex-get-entry key))
           (fname (helm-bibtex-get-value "File" entry))
                 (files1 (-map (lambda (it) (f-join it fname)) (-flatten (list helm-bibtex-library-path))))
                 (files2 (-map (lambda (it) (f-join it (s-concat key ".pdf"))) (-flatten (list helm-bibtex-library-path)))))
        (-first 'f-exists? (append files1 files2))))

This replaces --map with -map because --map used to make problems in older versions of Emacs. (Which version are you using?)

Thanks. That does not lead to any problems or errors. I am using version 24.4.1 (from Debian). I still will need to tweek it, because of the format of the file name (with paths, : and other such things ---they way JabRef or Mendely export them, but that ebib will not handle gracefully, for example).

You can use s-split to extract the part between the colons:

(car (s-split ":" ":home/ramon/a_directory/some_file_123.pdf:PDF" t))

But the path is not complete (it starts at home) so you have to prepend the path to home before using it.

Thanks, I didn't know about s-split. Prepending a / to home/ramon should be fairly simple with sed on the bib file.

In Emacs you can do:

(s-concat "/" path)

Ooops. Thanks. (Did I say I know no elisp?)

No problem ;-)