Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
some helper functions for org-ref
(defun if/pdf-isbn-or-doi-to-bibtex ()
(let ((user-input (read-string "isbn/doi/pdf-path: " (car kill-ring))))
(cond
((string-match-p "^10.[0-9]\\{4,9\\}/[-._;()/:A-Z0-9]+$" user-input) (doi-utils-doi-to-bibtex-string user-input)) ;doi
((string-match-p "pdf" user-input) (if/org-ref-pdf-to-bibtex user-input)) ;pdf
(t (if/isbn-to-bibtex user-input)))))
(defun if/start-org-roam-capture (uri)
(kill-new (replace-regexp-in-string "file:\/\/" "" uri))
(setq org-roam-capture--in-process nil)
(call-interactively 'org-roam-find-file))
;; Fix drag and drop pdf handling
(defun org-download-dnd (uri action)
"When in `org-mode' and URI points to image, download it.
Otherwise, pass URI and ACTION back to dnd dispatch."
(cond ((eq major-mode 'org-mode)
(if (string-match-p "pdf$" uri)
(if/start-org-roam-capture uri)
(progn
(condition-case nil
(org-download-image uri)
(error
(org-download-dnd-fallback uri action))))))
((eq major-mode 'dired-mode)
(org-download-dired uri))
;; redirect to someone else
(t
(org-download-dnd-fallback uri action))))
(defun if/org-ref-pdf-to-bibtex (pdf-file)
"Add pdf of current buffer to bib file and save pdf to
`org-ref-default-bibliography'. The pdf should be open in Emacs
using the `pdf-tools' package."
(interactive)
;; Get doi from pdf of current buffer
(let* ((dois (org-ref-extract-doi-from-pdf pdf-file))
(org-ref-pdf-to-bibtex-function 'rename-file)
(doi-utils-download-pdf nil)
(doi (cond
((> (length dois) 1) (completing-read "Select DOI: " dois))
((= 1 (length dois)) (car dois))
(t nil)))
(entry (if doi
(doi-utils-doi-to-bibtex-string doi)
(if/isbn-to-bibtex (if/find-isbn-in-pdf pdf-file))))
(entry (if/clean-bibtex-string entry))
(key (if/get-cite-key entry)))
(funcall org-ref-pdf-to-bibtex-function
pdf-file
(expand-file-name (format "%s.pdf" key)
org-ref-pdf-directory))
entry))
(defun if/clean-bibtex-string (bibtex-string)
(with-temp-buffer
(insert (concat bibtex-string ""))
(goto-char (point-min))
(org-ref-clean-bibtex-entry)
(buffer-string)))
(defun if/get-cite-key (bibtex-string)
(with-temp-buffer
(insert (concat bibtex-string ""))
(goto-char (point-min))
(cdr (assoc "=key=" (bibtex-parse-entry)))))
(defun if/find-isbn-in-pdf (pdf-file)
(let*
((org-ref-pdf-doi-regex "\\(?:isbn\\|ISBN\\)[ ]*\\([0-9-]*\\)" ) ; abuse pdf regex to find isbn instead "(?=(?:\D*\d){10}(?:(?:\D*\d){3})?$)[\d-]+"
(isbns (mapcar (lambda (x) (replace-regexp-in-string "\\(?:isbn\\|ISBN\\)[ ]*" "" x)) (org-ref-extract-doi-from-pdf pdf-file) ) )
(isbn (if (= 1 (length isbns))
(car isbns)
(completing-read "Select ISBN: " isbns))))
isbn))
(defun if/isbn-to-bibtex (isbn)
"Get bibtex entry for ISBN and insert it into BIBFILE.
Nothing happens if an entry with the generated key already exists
in the file. Data comes from worldcat."
(interactive
(list
(read-string
"ISBN: "
;; now set initial input
(cond
;; If region is active and it starts with a number, we use it
((and (region-active-p)
(s-match "^[0-9]" (buffer-substring (region-beginning) (region-end))))
(buffer-substring (region-beginning) (region-end)))
;; if first entry in kill ring starts with a number assume it is an isbn
;; and use it as the guess
((stringp (car kill-ring))
(when (s-match "^[0-9]" (car kill-ring))
(car kill-ring)))
;; type or paste it in
(t
nil)))))
(let* ((url (format "https://www.ottobib.com/isbn/%s/bibtex" isbn))
(entry))
(with-current-buffer (url-retrieve-synchronously url t t)
(goto-char (point-min))
(when (re-search-forward "@[a-zA-Z]+{.+\\(\n\s+[^\n]+\\)+}$" nil t)
(setq entry (match-string 0))))
(if (not entry)
(message "Nothing found.")
(with-temp-buffer
(insert (concat entry ",\n}"))
(goto-char (point-min))
(org-ref-isbn-clean-bibtex-entry)
(org-ref-clean-bibtex-entry)
(bibtex-fill-entry)
(s-trim (buffer-string))
(buffer-string)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment