Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for file links #259

Closed
bdarcus opened this issue Aug 26, 2021 · 7 comments
Closed

Add support for file links #259

bdarcus opened this issue Aug 26, 2021 · 7 comments

Comments

@bdarcus
Copy link
Contributor

bdarcus commented Aug 26, 2021

First of all, thanks for the great package. I have jumped into the vertico ecosystem mainly thanks to having a viable ivy-bibtex replacement and am generally having a great time. I can do nearly everything I want much more conveniently.

However I have been having trouble opening pdf files based on the file field in my bibtex entries and would like to know if this is currently supported or planned to be in the future.

To illustrate what I can't do, I have this entry in my bibliography file:

@book{albertyThermodynamicsBiochemicalReactions2003,
  title = {Thermodynamics of Biochemical Reactions},
  author = {Alberty, Robert A.},
  year = {2003},
  publisher = {{Wiley-Interscience}},
  address = {{Hoboken, N.J}},
  isbn = {978-0-471-22851-6},
  language = {en},
  lccn = {QP517.T48 A42 2003},
  keywords = {Bioenergetics,Physical biochemistry,Thermodynamics},
  file = {/Users/tedgro/Reading/Zotero/storage/LNAYX7S2/Alberty - 2003 - Thermodynamics of biochemical reactions.pdf}
}

When I run

(bibtex-actions-file-open-external
 (bibtex-actions-get-value
  "file"
  (bibtex-actions-get-entry "albertyThermodynamicsBiochemicalReactions2003")))

in the scratch buffer the pdf opens. However running either of these

(bibtex-actions-open '("albertyThermodynamicsBiochemicalReactions2003"))
(bibtex-actions-open-library-files '("albertyThermodynamicsBiochemicalReactions2003"))

produces the following message

"No file(s) found for (albertyThermodynamicsBiochemicalReactions2003)"

From a quick look at the code it seems like these both of these functions are designed around a workflow where the file names match the bibtex keys, which as you can see from the example above isn't how my files are organised (I think I just used the default settings for Zotero/better bibtex on macos for this).

I'd like to know if I have missed the right way to open pdfs based on the file field, or if this isn't currently supported whether it is planned in future.

For reference here is the relevant part of my init.el file:

(use-package bibtex-actions
  :ensure t
  :demand t
  :straight (:type git :host github :repo "bdarcus/bibtex-actions")
  :bind (("C-c b" . bibtex-actions-insert-citation)
         :map minibuffer-local-map
         ("M-b" . bibtex-actions-insert-preset))
  :after (embark parsebib bibtex-completion)
  :config
  (add-to-list 'embark-target-finders 'bibtex-actions-citation-key-at-point)
  (add-to-list 'embark-keymap-alist '(bib-reference . bibtex-actions-map))
  (add-to-list 'embark-keymap-alist '(citation-key . bibtex-actions-buffer-map))
  (advice-add #'completing-read-multiple
              :override #'consult-completing-read-multiple)
  (setq bibtex-actions-file-variable "file"
        bibtex-actions-bibliography '("/Users/tedgro/Reading/bibliography.bib")))

Originally posted by @teddygroves in #258

@bdarcus
Copy link
Contributor Author

bdarcus commented Aug 26, 2021

I added this here, @teddygroves, as it's a legitimate feature request.

We don't currently support that, but happy to add it.

Basically, with #222 and some subsequent changes, we no longer use bibtex-completion for that functionality. So first step was what you see.

If you understand the current code, do you have thoughts on how best to extend it for this?

My understanding is the only wrinkle is non-standard field names?

@teddygroves
Copy link

If you understand the current code, do you have thoughts on how best to extend it for this?

I'm an elisp beginner (I basically just mess with my emacs config) so I can't say too much but I think bibtex-completion uses a variable called bibtex-completion-pdf-field and I noticed bibtex-actions already has a bibtex-actions-file-variable which I might be analogous?

@bdarcus
Copy link
Contributor Author

bdarcus commented Aug 26, 2021

@aikrahguzar - do you have any thoughts on where best to put the logic to pull the file filed value?

bibtex-actions-file--possible-names ?

I could do it in the relevant "open" commands, but that feels wrong.

@aikrahguzar
Copy link
Contributor

bibtex-actions-file--possible-names ? Actually, that won't work.

It does seems like the obvious place for me. Though not entirely clear how to achieve that. One way would be for bibtex-actions-file--possible-names to take another (maybe optional) argument which is the value of the file field. It can than parse this string into file paths and add them to the list. I think another reason for this to happen in bibtex-actions-file--possible-names is that we should treat the resulting paths as just possible ones, they mightn't exist so they should go through the existence check as other paths.

Also we have to give users a way to supply the parsing function. Otherwise we will end up having to handle the quirks of every software generating bib files which is what BC does.

@bdarcus
Copy link
Contributor Author

bdarcus commented Aug 26, 2021

It does seems like the obvious place for me. Though not entirely clear how to achieve that.

In #260, I just look up the file value (using the file-variable field), and if present, push it to the result list of possible-names.

Also we have to give users a way to supply the parsing function.

We should itemize this somewhere at some point; maybe on the wiki? We really just need to know how parsebib parses the different options.

@thisirs
Copy link
Contributor

thisirs commented Aug 31, 2021

Hi,

In bibtex-completion I have replaced the big cl-loop by a "hook until success" to work with my config like this :

(defvar bibtex-completion-find-pdf-hook
  '(bibtex-completion-find-pdf-simple
    bibtex-completion-find-pdf-zotero))

(defun bibtex-completion-find-pdf-simple (value)
  "Handle semicolon-separated relative or absolute filenames."
  (let* ((value (replace-regexp-in-string "\\([^\\]\\);" "\\1\^^" value))
         (items (s-split "\^^" value))
         (paths (-separate 'f-absolute-p items)))
    (append
     (--filter (and (f-file? it) (s-ends-with? ".pdf" it :ignore-case)) (car paths))
     (--filter (and (f-file? it) (s-ends-with? ".pdf" it :ignore-case))
               (-table-flat 'f-join (-flatten bibtex-completion-library-path)
                            (cadr paths))))))

(defun bibtex-completion-find-pdf-zotero (value)
  (let* ((value (replace-regexp-in-string "\\([^\\]\\);" "\\1\^^" value))
         (items (s-split "\^^" value)))
    (when (zerop (% (length items) 3))
      (--filter (and (f-file? it) (s-ends-with? ".pdf" it :ignore-case))
                (-map #'cadr (-partition 3 items))))))

(defun bibtex-completion-find-pdf-in-field (key-or-entry)
  "Return the path of the PDF specified in the field `bibtex-completion-pdf-field' if that file exists.
Returns nil if no file is specified, or if the specified file
does not exist, or if `bibtex-completion-pdf-field' is nil."
  (when bibtex-completion-pdf-field
    (let* ((entry (if (stringp key-or-entry)
                      (bibtex-completion-get-entry1 key-or-entry t)
                    key-or-entry))
           (value (bibtex-completion-get-value bibtex-completion-pdf-field entry)))
      (when value
        (run-hook-with-args-until-success 'bibtex-completion-find-pdf-hook value)))))

It allows the user to write his own parsing function or use predefined ones (Zotero, Jabref etc). Maybe we could do the same here?

PS: I end up here because I have a relative path to a pdf in the file fields of my bib file and this is not currently supported. 😞

@bdarcus
Copy link
Contributor Author

bdarcus commented Aug 31, 2021

It allows the user to write his own parsing function or use predefined ones (Zotero, Jabref etc). Maybe we could do the same here?

I think this is something like what @aikrahguzar was thinking about, but am not sure.

What do your file fields look like, beyond being relative paths? Do the values differ significantly? If yes, what are examples? I see the "semicolon-separated" bit, but not sure what that means in context.

PS: I end up here because I have a relative path to a pdf in the file fields of my bib file and this is not currently supported.

This is I think just a minor oversight that should be easy to fix. Could you create an issue for it please?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants