+++ /dev/null
-;;; biblio-arxiv.el --- Lookup and import bibliographic entries from arXiv -*- lexical-binding: t -*-
-
-;; Copyright (C) 2016 Clément Pit-Claudel
-
-;; Author: Clément Pit-Claudel <clement.pitclaudelNOSPAMlive.com>
-;; URL: https://github.com/cpitclaudel/biblio.el
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;;
-;; Lookup and download bibliographic records from arXiv using `arxiv-lookup'.
-;; When a DOI is available, the metadata is fetched from the DOI's issuer;
-;; otherwise, this package uses arXiv's metadata to generate an entry.
-;;
-;; This file implements a backend for the for the `biblio' package (which see for more
-;; documentation).
-
-;;; Code:
-
-(require 'biblio-core)
-(require 'biblio-doi)
-(require 'timezone)
-
-(defgroup biblio-arxiv nil
- "arXiv support in biblio.el"
- :group 'biblio)
-
-(defcustom biblio-arxiv-bibtex-header "online"
- "Which header to use for BibTeX entries generated from arXiv metadata."
- :group 'biblio
- :type 'string)
-
-(defun biblio-arxiv--build-bibtex-1 (metadata)
- "Create an unformated BibTeX record for METADATA."
- (let-alist metadata
- (format "@%s{NO_KEY,
-author = {%s},
-title = {{%s}},
-year = {%s},
-archivePrefix = {arXiv},
-eprint = {%s},
-primaryClass = {%s}}"
- biblio-arxiv-bibtex-header
- (biblio-join-1 " AND " .authors)
- .title .year .identifier .category)))
-
-(defun biblio-arxiv--build-bibtex (metadata)
- "Create a BibTeX record for METADATA."
- (let-alist metadata
- (message "Auto-generating a BibTeX entry for %S." .id)
- (biblio-format-bibtex (biblio-arxiv--build-bibtex-1 metadata) t)))
-
-(defun biblio-arxiv--forward-bibtex (metadata forward-to)
- "Forward BibTeX for arXiv entry METADATA to FORWARD-TO."
- (let-alist metadata
- (if (seq-empty-p .doi)
- (funcall forward-to (biblio-arxiv--build-bibtex metadata))
- (biblio-doi-forward-bibtex .doi forward-to))))
-
-(defun biblio-arxiv--format-author (author)
- "Format AUTHOR for arXiv search results."
- (when (eq (car-safe author) 'author)
- (let-alist (cdr author)
- (biblio-join " "
- (cadr .name)
- (biblio-parenthesize (cadr .arxiv:affiliation))))))
-
-(defun biblio-arxiv--extract-id (id)
- "Extract identifier from ID, the URL of an arXiv abstract."
- (replace-regexp-in-string "https?://arxiv.org/abs/" "" id))
-
-(defun biblio-arxiv--pdf-url (id)
- "Extract PDF url from ID of an arXiv entry."
- (when id
- (concat "https://arxiv.org/pdf/" id)))
-
-(defun biblio-arxiv--extract-interesting-fields (entry)
- "Prepare an arXiv search result ENTRY for display."
- (let-alist entry
- (let ((id (biblio-arxiv--extract-id (cadr .id))))
- (list (cons 'doi (cadr .arxiv:doi))
- (cons 'identifier id)
- (cons 'year (aref (timezone-parse-date (cadr .published)) 0))
- (cons 'title (cadr .title))
- (cons 'authors (seq-map #'biblio-arxiv--format-author entry))
- (cons 'container (cadr .arxiv:journal_ref))
- (cons 'category
- (biblio-alist-get 'term (car .arxiv:primary_category)))
- (cons 'references (list (cadr .arxiv:doi) id))
- (cons 'type "eprint")
- (cons 'url (biblio-alist-get 'href (car .link)))
- (cons 'direct-url (biblio-arxiv--pdf-url id))))))
-
-(defun biblio-arxiv--entryp (entry)
- "Check if ENTRY is an arXiv entry."
- (eq (car-safe entry) 'entry))
-
-(defun biblio-arxiv--parse-search-results ()
- "Extract search results from arXiv response."
- (biblio-decode-url-buffer 'utf-8)
- (let-alist (xml-parse-region (point-min) (point-max))
- (seq-map #'biblio-arxiv--extract-interesting-fields
- (seq-filter #'biblio-arxiv--entryp .feed))))
-
-(defun biblio-arxiv--url (query)
- "Create an arXiv url to look up QUERY."
- (format "https://export.arxiv.org/api/query?search_query=%s"
- (url-encode-url query)))
-
-;;;###autoload
-(defun biblio-arxiv-backend (command &optional arg &rest more)
- "A arXiv backend for biblio.el.
-COMMAND, ARG, MORE: See `biblio-backends'."
- (pcase command
- (`name "arXiv")
- (`prompt "arXiv query: ")
- (`url (biblio-arxiv--url arg))
- (`parse-buffer (biblio-arxiv--parse-search-results))
- (`forward-bibtex (biblio-arxiv--forward-bibtex arg (car more)))
- (`register (add-to-list 'biblio-backends #'biblio-arxiv-backend))))
-
-;;;###autoload
-(add-hook 'biblio-init-hook #'biblio-arxiv-backend)
-
-;;;###autoload
-(defun biblio-arxiv-lookup (&optional query)
- "Start an arXiv search for QUERY, prompting if needed."
- (interactive)
- (biblio-lookup #'biblio-arxiv-backend query))
-
-;;;###autoload
-(defalias 'arxiv-lookup 'biblio-arxiv-lookup)
-
-(provide 'biblio-arxiv)
-;;; biblio-arxiv.el ends here
+++ /dev/null
-;;; biblio-autoloads.el --- automatically extracted autoloads (do not edit) -*- lexical-binding: t -*-
-;; Generated by the `loaddefs-generate' function.
-
-;; This file is part of GNU Emacs.
-
-;;; Code:
-
-(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
-
-
-\f
-;;; Generated autoloads from biblio-arxiv.el
-
-(autoload 'biblio-arxiv-backend "biblio-arxiv" "\
-A arXiv backend for biblio.el.
-COMMAND, ARG, MORE: See `biblio-backends'.
-
-(fn COMMAND &optional ARG &rest MORE)")
-(add-hook 'biblio-init-hook #'biblio-arxiv-backend)
-(autoload 'biblio-arxiv-lookup "biblio-arxiv" "\
-Start an arXiv search for QUERY, prompting if needed.
-
-(fn &optional QUERY)" t)
-(defalias 'arxiv-lookup 'biblio-arxiv-lookup)
-(register-definition-prefixes "biblio-arxiv" '("biblio-arxiv-"))
-
-\f
-;;; Generated autoloads from biblio-crossref.el
-
-(autoload 'biblio-crossref-backend "biblio-crossref" "\
-A CrossRef backend for biblio.el.
-COMMAND, ARG, MORE: See `biblio-backends'.
-
-(fn COMMAND &optional ARG &rest MORE)")
-(add-hook 'biblio-init-hook #'biblio-crossref-backend)
-(autoload 'biblio-crossref-lookup "biblio-crossref" "\
-Start a CrossRef search for QUERY, prompting if needed.
-
-(fn &optional QUERY)" t)
-(defalias 'crossref-lookup 'biblio-crossref-lookup)
-(register-definition-prefixes "biblio-crossref" '("biblio-crossref-"))
-
-\f
-;;; Generated autoloads from biblio-dblp.el
-
-(autoload 'biblio-dblp-backend "biblio-dblp" "\
-A DBLP backend for biblio.el.
-COMMAND, ARG, MORE: See `biblio-backends'.
-
-(fn COMMAND &optional ARG &rest MORE)")
-(add-hook 'biblio-init-hook #'biblio-dblp-backend)
-(autoload 'biblio-dblp-lookup "biblio-dblp" "\
-Start a DBLP search for QUERY, prompting if needed.
-
-(fn &optional QUERY)" t)
-(defalias 'dblp-lookup 'biblio-dblp-lookup)
-(register-definition-prefixes "biblio-dblp" '("biblio-dblp--"))
-
-\f
-;;; Generated autoloads from biblio-dissemin.el
-
-(autoload 'biblio-dissemin-lookup "biblio-dissemin" "\
-Retrieve a record by DOI from Dissemin, and display it.
-Interactively, or if CLEANUP is non-nil, pass DOI through
-`biblio-cleanup-doi'.
-
-(fn DOI &optional CLEANUP)" t)
-(defalias 'dissemin-lookup 'biblio-dissemin-lookup)
-(autoload 'biblio-dissemin--register-action "biblio-dissemin" "\
-Add Dissemin to list of `biblio-selection-mode' actions.")
-(add-hook 'biblio-selection-mode-hook #'biblio-dissemin--register-action)
-(register-definition-prefixes "biblio-dissemin" '("biblio-dissemin--"))
-
-\f
-;;; Generated autoloads from biblio-doi.el
-
-(autoload 'biblio-doi-insert-bibtex "biblio-doi" "\
-Insert BibTeX entry matching DOI.
-
-(fn DOI)" t)
-(register-definition-prefixes "biblio-doi" '("biblio-doi-" "doi-insert-bibtex"))
-
-\f
-;;; Generated autoloads from biblio-download.el
-
-(autoload 'biblio-download--register-action "biblio-download" "\
-Add download to list of `biblio-selection-mode' actions.")
-(add-hook 'biblio-selection-mode-hook #'biblio-download--register-action)
-(register-definition-prefixes "biblio-download" '("biblio-download-"))
-
-\f
-;;; Generated autoloads from biblio-hal.el
-
-(autoload 'biblio-hal-backend "biblio-hal" "\
-A HAL backend for biblio.el.
-COMMAND, ARG, MORE: See `biblio-backends'.
-
-(fn COMMAND &optional ARG &rest MORE)")
-(add-hook 'biblio-init-hook #'biblio-hal-backend)
-(autoload 'biblio-hal-lookup "biblio-hal" "\
-Start a HAL search for QUERY, prompting if needed.
-
-(fn &optional QUERY)" t)
-(defalias 'hal-lookup 'biblio-hal-lookup)
-(register-definition-prefixes "biblio-hal" '("biblio-hal--"))
-
-\f
-;;; Generated autoloads from biblio-ieee.el
-
-(autoload 'biblio-ieee-backend "biblio-ieee" "\
-A IEEE Xplore backend for biblio.el.
-COMMAND, ARG, MORE: See `biblio-backends'.
-
-(fn COMMAND &optional ARG &rest MORE)")
-(add-hook 'biblio-init-hook #'biblio-ieee-backend)
-(autoload 'biblio-ieee-lookup "biblio-ieee" "\
-Start a IEEE search for QUERY, prompting if needed.
-
-(fn &optional QUERY)" t)
-(defalias 'ieee-lookup 'biblio-ieee-lookup)
-(register-definition-prefixes "biblio-ieee" '("biblio-ieee--"))
-\f
-;;; End of scraped data
-
-(provide 'biblio-autoloads)
-
-;; Local Variables:
-;; version-control: never
-;; no-byte-compile: t
-;; no-update-autoloads: t
-;; no-native-compile: t
-;; coding: utf-8-emacs-unix
-;; End:
-
-;;; biblio-autoloads.el ends here
+++ /dev/null
-;;; biblio-crossref.el --- Lookup and import bibliographic entries from CrossRef -*- lexical-binding: t -*-
-
-;; Copyright (C) 2016 Clément Pit-Claudel
-
-;; Author: Clément Pit-Claudel <clement.pitclaudelNOSPAMlive.com>
-;; URL: https://github.com/cpitclaudel/biblio.el
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;;
-;; Lookup and download bibliographic records from CrossRef (a very nicely
-;; curated metadata engine) using `crossref-lookup'.
-;;
-;; This file implements a backend for the `biblio' package (which see for more
-;; documentation).
-
-;;; Code:
-
-(require 'biblio-core)
-(require 'biblio-doi)
-
-(defcustom biblio-crossref-user-email-address nil
- "Email address to include in CrossRef queries, or nil.
-CrossRef gives priority to queries that include an email address.
-See URL `https://github.com/CrossRef/rest-api-doc#etiquette' for
-more details."
- :group 'biblio
- :type '(choice (const :tag "Do not include an email address." nil)
- (string :tag "Include an email address.")))
-
-(defun biblio-crossref--forward-bibtex (metadata forward-to)
- "Forward BibTeX for CrossRef entry METADATA to FORWARD-TO."
- (biblio-doi-forward-bibtex (biblio-alist-get 'doi metadata) forward-to))
-
-(defun biblio-crossref--format-affiliation (affiliation)
- "Format AFFILIATION for CrossRef search results."
- (mapconcat (apply-partially #'biblio-alist-get 'name) affiliation ", "))
-
-(defun biblio-crossref--format-author (author)
- "Format AUTHOR for CrossRef search results."
- (let-alist author
- (biblio-join " "
- .given .family (biblio-parenthesize (biblio-crossref--format-affiliation .affiliation)))))
-
-(defun biblio-crossref--extract-interesting-fields (item)
- "Prepare a CrossRef search result ITEM for display."
- (let-alist item
- (list (cons 'doi .DOI)
- (cons 'year (let ((year (aref (aref .issued.date-parts 0) 0)))
- (and (numberp year) (number-to-string year))))
- (cons 'title (biblio-join " "
- (biblio-join-1 ", " .title)
- (biblio-parenthesize (biblio-join-1 ", " .subtitle))))
- (cons 'authors (seq-map #'biblio-crossref--format-author .author))
- (cons 'publisher .publisher)
- (cons 'container .container-title)
- (cons 'references (seq-concatenate 'list (list .DOI) .isbn))
- (cons 'type .type)
- (cons 'url .URL))))
-
-(defun biblio-crossref--parse-search-results ()
- "Extract search results from CrossRef response."
- (biblio-decode-url-buffer 'utf-8)
- (let-alist (json-read)
- (unless (string= .status "ok")
- (display-warning 'biblio-crossref "CrossRef query failed"))
- (seq-map #'biblio-crossref--extract-interesting-fields .message.items)))
-
-(defun biblio-crossref--url (query)
- "Create a CrossRef url to look up QUERY."
- (format "https://api.crossref.org/works?query=%s%s"
- (url-encode-url query)
- (if biblio-crossref-user-email-address
- (format "&mailto=%s" (url-encode-url biblio-crossref-user-email-address)) "")))
-
-;;;###autoload
-(defun biblio-crossref-backend (command &optional arg &rest more)
- "A CrossRef backend for biblio.el.
-COMMAND, ARG, MORE: See `biblio-backends'."
- (pcase command
- (`name "CrossRef")
- (`prompt "CrossRef query: ")
- (`url (biblio-crossref--url arg))
- (`parse-buffer (biblio-crossref--parse-search-results))
- (`forward-bibtex (biblio-crossref--forward-bibtex arg (car more)))
- (`register (add-to-list 'biblio-backends #'biblio-crossref-backend))))
-
-;;;###autoload
-(add-hook 'biblio-init-hook #'biblio-crossref-backend)
-
-;;;###autoload
-(defun biblio-crossref-lookup (&optional query)
- "Start a CrossRef search for QUERY, prompting if needed."
- (interactive)
- (biblio-lookup #'biblio-crossref-backend query))
-
-;;;###autoload
-(defalias 'crossref-lookup 'biblio-crossref-lookup)
-
-(provide 'biblio-crossref)
-;;; biblio-crossref.el ends here
+++ /dev/null
-;;; biblio-dblp.el --- Lookup and import bibliographic entries from DBLP -*- lexical-binding: t -*-
-
-;; Copyright (C) 2016 Clément Pit-Claudel
-
-;; Author: Clément Pit-Claudel <clement.pitclaudelNOSPAMlive.com>
-;; URL: https://github.com/cpitclaudel/biblio.el
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;;
-;; Lookup and download bibliographic records from DBLP (a great source of
-;; references for Computer Science papers) using `dblp-lookup'.
-;;
-;; This file implements a backend for the for the `biblio' package (which see for more
-;; documentation).
-
-;;; Code:
-
-(require 'biblio-core)
-
-(defun biblio-dblp--forward-bibtex (metadata forward-to)
- "Forward BibTeX for DBLP entry METADATA to FORWARD-TO."
- (let* ((source-url (biblio-alist-get 'url metadata))
- (url (replace-regexp-in-string "/rec/" "/rec/bib2/" source-url t t)))
- (biblio-url-retrieve url (biblio-generic-url-callback
- (lambda () ;; No allowed errors, so no arguments
- "Parse DBLP BibTeX results."
- (funcall forward-to
- (biblio-response-as-utf-8)))))))
-
-(defun biblio-dblp--extract-interesting-fields (item)
- "Prepare a DBLP search result ITEM for display."
- (let-alist (biblio-alist-get 'info item)
- (list (cons 'year (cadr .year))
- (cons 'title (cadr .title))
- (cons 'authors (seq-map #'cl-caddr (cdr .authors)))
- (cons 'container (cadr .venue))
- (cons 'references nil)
- (cons 'type (cadr .type))
- (cons 'url (cadr .url)))))
-
-(defun biblio-dblp--hitp (item)
- "Check if ITEM is a DBLP hit."
- (eq (car-safe item) 'hit))
-
-(defun biblio-dblp--parse-search-results ()
- "Extract search results from DBLP response."
- (biblio-decode-url-buffer 'utf-8)
- (let-alist (car (xml-parse-region (point-min) (point-max)))
- (unless (string= (cadr .status) "OK")
- (display-warning 'biblio-dblp "DBLP query failed"))
- (seq-map #'biblio-dblp--extract-interesting-fields (seq-filter #'biblio-dblp--hitp .hits))))
-
-(defun biblio-dblp--url (query)
- "Create a DBLP url to look up QUERY."
- (format "https://dblp.org/search/publ/api?q=%s&format=xml" (url-encode-url query)))
-
-;;;###autoload
-(defun biblio-dblp-backend (command &optional arg &rest more)
- "A DBLP backend for biblio.el.
-COMMAND, ARG, MORE: See `biblio-backends'."
- (pcase command
- (`name "DBLP")
- (`prompt "DBLP query: ")
- (`url (biblio-dblp--url arg))
- (`parse-buffer (biblio-dblp--parse-search-results))
- (`forward-bibtex (biblio-dblp--forward-bibtex arg (car more)))
- (`register (add-to-list 'biblio-backends #'biblio-dblp-backend))))
-
-;;;###autoload
-(add-hook 'biblio-init-hook #'biblio-dblp-backend)
-
-;;;###autoload
-(defun biblio-dblp-lookup (&optional query)
- "Start a DBLP search for QUERY, prompting if needed."
- (interactive)
- (biblio-lookup #'biblio-dblp-backend query))
-
-;;;###autoload
-(defalias 'dblp-lookup 'biblio-dblp-lookup)
-
-(provide 'biblio-dblp)
-;;; biblio-dblp.el ends here
+++ /dev/null
-;;; biblio-dissemin.el --- Lookup bibliographic information and open access records from Dissemin -*- lexical-binding: t -*-
-
-;; Copyright (C) 2016 Clément Pit-Claudel
-
-;; Author: Clément Pit-Claudel <clement.pitclaudelNOSPAMlive.com>
-;; URL: https://github.com/cpitclaudel/biblio.el
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;;
-;; Lookup publication records on Dissemin by DOI using `dissemin-lookup'.
-;;
-;; This package also plugs into `biblio-selection-mode' by adding an entry to
-;; the extended actions menu (`x') to quickly locate the Dissemin record of
-;; e.g. a CrossRef entry.
-
-;;; Code:
-
-(require 'biblio-core)
-
-(defun biblio-dissemin--format-author (author)
- "Format a Dissemin AUTHOR entry."
- (let-alist author
- (format "%s %s" .name.first .name.last)))
-
-(defun biblio-dissemin--insert-button (url prefix)
- "Insert a button pointing to URL, prefixed by PREFIX."
- (unless (seq-empty-p url)
- (insert "\n" prefix)
- (insert (biblio-make-url-button url))))
-
-(defun biblio-dissemin--insert-record (record)
- "Insert a Dissemin RECORD entry into the current buffer."
- (let-alist record
- (insert "\n\n")
- (biblio-with-fontification 'font-lock-preprocessor-face
- (biblio-insert-with-prefix ">> " .identifier))
- (biblio-dissemin--insert-button .pdf_url " ")
- (unless (string= .pdf_url .splash_url)
- (biblio-dissemin--insert-button .splash_url " "))
- (unless (seq-empty-p .abstract)
- (insert "\n")
- ;; (biblio-with-fontification 'font-lock-doc-face
- (biblio-insert-with-prefix " " .abstract))))
-
-(defun biblio-dissemin--translate-classification (classification)
- "Translate Dissemin's CLASSIFICATION for display."
- (pcase classification
- (`"OA" "Available from the publisher")
- (`"OK" "Some versions may be shared by the author")
- (`"UNK" "Sharing policy is unclear")
- (`"CLOSED" "Subject to a restrictive sharing policy")
- (_ classification)))
-
-(defun biblio-dissemin--suggest-upload (doi)
- "Insert a link to Dissemin's upload page for DOI."
- (insert "\n\nDid you write this paper? ")
- (biblio-with-fontification '(:weight bold)
- (insert
- (biblio-make-url-button (format "https://dissem.in/%s" doi) "upload it")))
- (insert "!\n"))
-
-(defun biblio-dissemin--pretty-print (paper doi)
- "Pretty-print a Dissemin PAPER entry (with DOI) to current buffer."
- (let-alist paper
- (biblio-insert-result
- (list (cons 'title .title)
- (cons 'authors (seq-map #'biblio-dissemin--format-author .authors))
- (cons 'open-access-status
- (biblio-dissemin--translate-classification .classification)))
- t)
- (biblio-dissemin--insert-button .pdf_url " ")
- (if (seq-empty-p .records)
- (progn (insert "\n\n(no records)")
- (when (member .classification '("OA" "OK"))
- (biblio-dissemin--suggest-upload doi)))
- (seq-do #'biblio-dissemin--insert-record .records))
- (goto-char (point-min))))
-
-(defun biblio-dissemin--print-results (paper doi)
- "Create a buffer for Dissemin, and print PAPER (with DOI) into it."
- (with-current-buffer (biblio-dissemin--make-buffer)
- (let ((inhibit-read-only t))
- (erase-buffer)
- (help-mode)
- (visual-line-mode)
- (biblio-dissemin--pretty-print paper doi))
- (setq buffer-read-only t)
- (pop-to-buffer (current-buffer))))
-
-(defun biblio-dissemin--make-buffer ()
- "Create a buffer to display Dissemin results in."
- (get-buffer-create "*Dissemin search results*"))
-
-(defun biblio-dissemin--parse-buffer ()
- "Extract search results from DBLP response."
- (biblio-decode-url-buffer 'utf-8)
- (let-alist (json-read)
- (unless (string= .status "ok")
- (display-warning 'biblio-dissemin "Dissemin query failed"))
- .paper))
-
-(defun biblio-dissemin--url (doi)
- "Create a DBLP url to look up DOI."
- (format "https://dissem.in/api/%s" (url-encode-url doi)))
-
-(defun biblio-dissemin--callback (doi)
- "Generate a callback to parse Dissemin results for DOI."
- (lambda () ;; no allowed errors, so no arguments
- (biblio-dissemin--print-results (biblio-dissemin--parse-buffer) doi)))
-
-;;;###autoload
-(defun biblio-dissemin-lookup (doi &optional cleanup)
- "Retrieve a record by DOI from Dissemin, and display it.
-Interactively, or if CLEANUP is non-nil, pass DOI through
-`biblio-cleanup-doi'."
- (interactive "MDOI: \nd")
- (when cleanup
- (setq doi (biblio-cleanup-doi doi)))
- (let ((buf (biblio-dissemin--make-buffer)))
- (biblio-url-retrieve (biblio-dissemin--url doi)
- (biblio-generic-url-callback (biblio-dissemin--callback doi)))
- buf))
-
-;;;###autoload
-(defalias 'dissemin-lookup 'biblio-dissemin-lookup)
-
-(defun biblio-dissemin--lookup-record (record)
- "Retrieve a RECORD from Dissemin, and display it.
-RECORD is a formatted record as expected by `biblio-insert-result'."
- (let-alist record
- (if .doi (dissemin-lookup .doi)
- (user-error "Dissemin needs a DOI, but this record does not contain one"))))
-
-;;;###autoload
-(defun biblio-dissemin--register-action ()
- "Add Dissemin to list of `biblio-selection-mode' actions."
- (add-to-list 'biblio-selection-mode-actions-alist
- '("Dissemin (find open access copies of this article)" . biblio-dissemin--lookup-record)))
-
-;;;###autoload
-(add-hook 'biblio-selection-mode-hook #'biblio-dissemin--register-action)
-
-(provide 'biblio-dissemin)
-;;; biblio-dissemin.el ends here
+++ /dev/null
-;;; biblio-doi.el --- Retrieve BibTeX entries by DOI -*- lexical-binding: t -*-
-
-;; Copyright (C) 2016 Clément Pit-Claudel
-
-;; Author: Clément Pit-Claudel <clement.pitclaudelNOSPAMlive.com>
-;; URL: https://github.com/cpitclaudel/biblio.el
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-
-;;; Commentary:
-;;
-;; Retrieve and insert BibTeX records by DOI using `doi-insert-bibtex'.
-;; Information is retrieved from DOI issuing sites of each DOI using the
-;; “application/x-bibtex” and “text/bibliography” request types, falling back to
-;; CrossCite if unavailable.
-;;
-;; This package integrates with `biblio-selection-mode', and is part of the more
-;; general `biblio' package (which see for more documentation).
-
-(require 'biblio-core)
-
-;;; Code:
-
-(defun biblio-doi--dx-url (doi)
- "Create a doi.org url for DOI."
- (format "https://doi.org/%s" doi))
-
-(defun biblio-doi--crosscite-url (doi)
- "Create a crosscite URL to use as a fallback for DOI.
-Not all content providers provide BibTeX formatted entries, so
-instead of failing reroute the request through crosscite, which
-requests a generic format and crates the BibTeX on its own."
- (format "https://crosscite.org/citeproc/format?doi=%s&style=bibtex&lang=en-US" doi))
-
-(defconst biblio-doi--dx-mime-accept
- ;; “Accept:” header; Zenodo recognizes x-bibtex but not text/bibliography
- "text/bibliography;style=bibtex, application/x-bibtex")
-
-(defun biblio-doi--set-mime-accept ()
- "Set `url-mime-accept-string' before contacting the DOI server."
- ;; Ugly: let-binding or buffer-locally setting `url-mime-accept-string' does
- ;; not work, because `url-http-create-request' can be called from a
- ;; sentinel, or from an entirely new buffer (after a redirection).
- (setq url-mime-accept-string biblio-doi--dx-mime-accept))
-
-(defun biblio-doi--restore-mime-accept ()
- "Restore `url-mime-accept-string'."
- (kill-local-variable 'url-mime-accept-string)
- (setq-default url-mime-accept-string nil))
-
-(defun biblio-doi--insert (bibtex buffer)
- "Insert formatted BIBTEX into BUFFER."
- (with-current-buffer buffer
- (insert bibtex "\n\n")))
-
-(defun biblio-doi--generic-url-callback-1 (errors forward-to)
- "Helper function for `biblio-doi--generic-url-callback'.
-ERRORS, FORWARD-TO: see there."
- (funcall forward-to (unless errors (biblio-response-as-utf-8))))
-
-(defun biblio-doi--generic-url-callback (cleanup-fn forward-to)
- "Make an URL-ready callback.
-Call CLEANUP-FN in any case, and FORWARD-TO with BibTeX source
-or nil depending on whether an error occured. If error 406
-occurs, forward nil; otherwise, signal the error. This is
-essentially a thin wrapper around `biblio-generic-url-callback'."
- (biblio-generic-url-callback
- (lambda (&optional errors)
- "Handle response from BibTeX server."
- (biblio-doi--generic-url-callback-1 errors forward-to))
- cleanup-fn '(http . 406)))
-
-(defun biblio-doi--crosscite-callback (forward-to)
- "Generate a handler for response of CrossCite server.
-FORWARD-TO is the callback to call with the results of the search."
- (biblio-doi--generic-url-callback #'ignore forward-to))
-
-(defun biblio-doi--forward-bibtex-crosscite (doi forward-to)
- "Forward BibTeX entry for DOI from CrossCite to FORWARD-TO."
- (biblio-url-retrieve (biblio-doi--crosscite-url doi) (biblio-doi--crosscite-callback forward-to)))
-
-(defun biblio-doi--dx-callback (forward-to)
- "Generate a handler for response of DX server.
-FORWARD-TO is the callback to call with the results of the search."
- (biblio-doi--generic-url-callback #'biblio-doi--restore-mime-accept forward-to))
-
-(defun biblio-doi--forward-bibtex-dx (doi forward-to)
- "Forward BibTeX entry for DOI from doi.org to FORWARD-TO."
- (biblio-doi--set-mime-accept)
- (biblio-url-retrieve (biblio-doi--dx-url doi) (biblio-doi--dx-callback forward-to)))
-
-(defun biblio-doi-forward-bibtex (doi forward-to)
- "Pass BibTeX entry for DOI to FORWARD-TO."
- (biblio-doi--forward-bibtex-dx
- doi (lambda (result)
- (if result (funcall forward-to result)
- (biblio-doi--forward-bibtex-crosscite doi forward-to)))))
-
-;;;###autoload
-(defun biblio-doi-insert-bibtex (doi)
- "Insert BibTeX entry matching DOI."
- (interactive "MDOI: ")
- (let ((target-buffer (current-buffer)))
- (biblio-doi-forward-bibtex
- (biblio-cleanup-doi doi)
- (lambda (result)
- (biblio-doi--insert
- (biblio-format-bibtex result biblio-bibtex-use-autokey)
- target-buffer)))))
-
-(defalias 'doi-insert-bibtex 'biblio-doi-insert-bibtex)
-
-(provide 'biblio-doi)
-;;; biblio-doi.el ends here
+++ /dev/null
-;;; biblio-download.el --- Lookup bibliographic information and open access records from Dissemin -*- lexical-binding: t -*-
-
-;; Copyright (C) 2016 Clément Pit-Claudel
-
-;; Author: Clément Pit-Claudel <clement.pitclaudelNOSPAMlive.com>
-;; URL: https://github.com/cpitclaudel/biblio.el
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;;
-;; Download scientific papers directly from Emacs.
-;;
-;; This package plugs into `biblio-selection-mode' by adding an entry to the
-;; extended actions menu (`x').
-
-;;; Code:
-
-(require 'biblio-core)
-
-(defcustom biblio-download-directory nil
- "Where to put downloaded papers."
- :group 'biblio
- :type 'directory)
-
-(defun biblio-download--action (record)
- "Retrieve a RECORD from Dissemin, and display it.
-RECORD is a formatted record as expected by `biblio-insert-result'."
- (let-alist record
- (if .direct-url
- (let* ((fname (concat .identifier ".pdf"))
- (target (read-file-name "Save as (see also biblio-download-directory): "
- biblio-download-directory fname nil fname)))
- (url-copy-file .direct-url (expand-file-name target biblio-download-directory)))
- (user-error "This record does not contain a direct URL (try arXiv or HAL)"))))
-
-;;;###autoload
-(defun biblio-download--register-action ()
- "Add download to list of `biblio-selection-mode' actions."
- (add-to-list 'biblio-selection-mode-actions-alist
- '("Download this article" . biblio-download--action)))
-
-;;;###autoload
-(add-hook 'biblio-selection-mode-hook #'biblio-download--register-action)
-
-(provide 'biblio-download)
-;;; biblio-download.el ends here
+++ /dev/null
-;;; biblio-hal.el --- Lookup and import bibliographic entries from HAL (archives ouvertes) -*- lexical-binding: t -*-
-
-;; Copyright (C) 2016 Clément Pit-Claudel
-
-;; Author: Clément Pit-Claudel <clement.pitclaudelNOSPAMlive.com>
-;; URL: https://github.com/cpitclaudel/biblio.el
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;;
-;; Lookup and download bibliographic records from HAL using `hal-lookup'.
-;;
-;; This file implements a backend for the for the `biblio' package (which see for more
-;; documentation).
-
-;;; Code:
-
-(require 'biblio-core)
-
-(defun biblio-hal--forward-bibtex (metadata forward-to)
- "Forward BibTeX for HAL entry METADATA to FORWARD-TO."
- (funcall forward-to (biblio-alist-get 'bibtex metadata)))
-
-;; (defun biblio-hal--format-author (author)
-;; "Format AUTHOR for HAL search results."
-;; (pcase author
-;; (`(,author . ,affiliation)
-;; (biblio-join " " author (biblio-parenthesize affiliation)))))
-
-(defun biblio-hal--extract-interesting-fields (item)
- "Prepare a HAL search result ITEM for display."
- (let-alist item
- (list (cons 'doi .doiId_s)
- (cons 'year (aref (timezone-parse-date .producedDate_tdate) 0))
- (cons 'bibtex .label_bibtex)
- (cons 'title (biblio-join " "
- (biblio-join-1 ", " .title_s)
- (biblio-parenthesize
- (biblio-join-1 ", " .subtitle_s))))
- (cons 'authors .authFullName_s)
- ;; Too many institutions? (biblio-parenthesize (biblio-join-1 ", " .structName_s))
- (cons 'publisher .journalPublisher_s)
- (cons 'container .journalTitle_s)
- (cons 'references (biblio-remove-empty
- (list .doiId_s .halId_s .arxivId_s)))
- (cons 'type .submitType_s)
- (cons 'url .uri_s)
- (cons 'direct-url (car (append .files_s nil))))))
-
-(defun biblio-hal--parse-search-results ()
- "Extract search results from HAL response."
- (biblio-decode-url-buffer 'utf-8)
- (let-alist (json-read)
- (unless .response
- (display-warning 'biblio-hal "HAL query failed"))
- (seq-map #'biblio-hal--extract-interesting-fields .response.docs)))
-
-(defun biblio-hal--url (query)
- "Create a HAL url to look up QUERY."
- (format "https://api.archives-ouvertes.fr/search/?q=%s&wt=%s&fl=%s"
- (url-encode-url query) "json"
- (biblio-join "," ;; Use ‘*’ to show all fields
- "arxivId_s" "halId_s" "doiId_s" ;; "journalIssn_s"
- "title_s" "subtitle_s" "authFullName_s" "structName_s"
- "journalPublisher_s" "submitType_s" ;; "abstract_s"
- ;; "journalTitle_s" "volume_s" "issue_s" "page_s" "writingDate_s"
- "label_bibtex" "files_s" "uri_s" "producedDate_tdate")))
-
-;;;###autoload
-(defun biblio-hal-backend (command &optional arg &rest more)
- "A HAL backend for biblio.el.
-COMMAND, ARG, MORE: See `biblio-backends'."
- (pcase command
- (`name "HAL")
- (`prompt "HAL (archives ouvertes) query: ")
- (`url (biblio-hal--url arg))
- (`parse-buffer (biblio-hal--parse-search-results))
- (`forward-bibtex (biblio-hal--forward-bibtex arg (car more)))
- (`register (add-to-list 'biblio-backends #'biblio-hal-backend))))
-
-;;;###autoload
-(add-hook 'biblio-init-hook #'biblio-hal-backend)
-
-;;;###autoload
-(defun biblio-hal-lookup (&optional query)
- "Start a HAL search for QUERY, prompting if needed."
- (interactive)
- (biblio-lookup #'biblio-hal-backend query))
-
-;;;###autoload
-(defalias 'hal-lookup 'biblio-hal-lookup)
-
-(provide 'biblio-hal)
-;;; biblio-hal.el ends here
+++ /dev/null
-;;; biblio-ieee.el --- Lookup and import bibliographic entries from IEEE -*- lexical-binding: t -*-
-
-;; Copyright (C) 2019 Clément Pit-Claudel
-
-;; Author: Clément Pit-Claudel <clement.pitclaudelNOSPAMlive.com>
-;; URL: https://github.com/cpitclaudel/biblio.el
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;;
-;; Lookup and download bibliographic records from IEEE Xplore using
-;; `ieee-lookup'.
-;;
-;; This package uses `biblio-selection-mode', and plugs into the more general
-;; `biblio' package (which see for more documentation).
-
-;;; Code:
-
-(require 'biblio-core)
-(require 'biblio-doi)
-
-(defconst biblio-ieee--api-key "rfwzcsz3f9fkhklhii84xdfz"
- "API key used to query IEEE; for use only with biblio.el!")
-
-(defconst biblio-ieee--api-root-url
- "https://ieeexploreapi.ieee.org/api/v1/search/articles")
-
-(defun biblio-ieee--forward-bibtex (metadata forward-to)
- "Forward BibTeX for IEEE Xplore entry METADATA to FORWARD-TO."
- (biblio-doi-forward-bibtex (biblio-alist-get 'doi metadata) forward-to))
-
-(defun biblio-ieee--format-author (author)
- "Format AUTHOR for IEEE Xplore search results."
- (let-alist author
- (biblio-join " " .full_name (biblio-parenthesize .affiliation))))
-
-(defun biblio-ieee--extract-interesting-fields (item)
- "Prepare a IEEE Xplore search result ITEM for display."
- (let-alist item
- (list (cons 'doi .doi)
- (cons 'year .publication_year)
- (cons 'title .title)
- (cons 'authors (seq-map #'biblio-ieee--format-author .authors.authors))
- (cons 'publisher .publisher)
- (cons 'container .publication_title)
- (cons 'references (list .doi .isbn))
- (cons 'type (or .index_terms.author_terms.terms
- .index_terms.ieee_terms.terms))
- (cons 'url .abstract_url)
- (cons 'direct-url .pdf_url)
- (cons 'open-access-status .access_type))))
-
-(defun biblio-ieee--parse-search-results ()
- "Extract search results from IEEE Xplore response."
- (biblio-decode-url-buffer 'utf-8)
- (let-alist (json-read)
- (seq-map #'biblio-ieee--extract-interesting-fields .articles)))
-
-(defun biblio-ieee--url (query)
- "Create an IEEE Xplore url to look up QUERY."
- (format "%s?querytext=%s&apikey=%s"
- biblio-ieee--api-root-url
- (url-encode-url query)
- (rot13 biblio-ieee--api-key)))
-
-;;;###autoload
-(defun biblio-ieee-backend (command &optional arg &rest more)
- "A IEEE Xplore backend for biblio.el.
-COMMAND, ARG, MORE: See `biblio-backends'."
- (pcase command
- (`name "IEEE Xplore")
- (`prompt "IEEE Xplore query: ")
- (`url (biblio-ieee--url arg))
- (`parse-buffer (biblio-ieee--parse-search-results))
- (`forward-bibtex (biblio-ieee--forward-bibtex arg (car more)))
- (`register (add-to-list 'biblio-backends #'biblio-ieee-backend))))
-
-;;;###autoload
-(add-hook 'biblio-init-hook #'biblio-ieee-backend)
-
-;;;###autoload
-(defun biblio-ieee-lookup (&optional query)
- "Start a IEEE search for QUERY, prompting if needed."
- (interactive)
- (biblio-lookup #'biblio-ieee-backend query))
-
-;;;###autoload
-(defalias 'ieee-lookup 'biblio-ieee-lookup)
-
-(provide 'biblio-ieee)
-;;; biblio-ieee.el ends here
+++ /dev/null
-;; -*- no-byte-compile: t; lexical-binding: nil -*-
-(define-package "biblio" "20250409.2132"
- "Browse and import bibliographic references and BibTeX records from CrossRef, arXiv, DBLP, HAL, IEEE Xplore, Dissemin, and doi.org."
- '((emacs "24.3")
- (biblio-core "0.3"))
- :url "https://github.com/cpitclaudel/biblio.el"
- :commit "0314982c0ca03d0f8e0ddbe9fc20588c35021098"
- :revdesc "0314982c0ca0"
- :keywords '("bib" "tex" "convenience" "hypermedia")
- :authors '(("Clément Pit-Claudel" . "clement.pitclaudelNOSPAMlive.com"))
- :maintainers '(("Clément Pit-Claudel" . "clement.pitclaudelNOSPAMlive.com")))
+++ /dev/null
-;;; biblio.el --- Browse and import bibliographic references and BibTeX records from CrossRef, arXiv, DBLP, HAL, IEEE Xplore, Dissemin, and doi.org -*- lexical-binding: t -*-
-
-;; Copyright (C) 2016 Clément Pit-Claudel
-
-;; Author: Clément Pit-Claudel <clement.pitclaudelNOSPAMlive.com>
-;; Package-Version: 20250409.2132
-;; Package-Revision: 0314982c0ca0
-;; Package-Requires: ((emacs "24.3") (biblio-core "0.3"))
-;; Keywords: bib, tex, convenience, hypermedia
-;; URL: https://github.com/cpitclaudel/biblio.el
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;; # biblio.el: An extensible Emacs package for browsing and fetching references
-;;
-;; biblio.el makes it easy to browse and gather bibliographic references and
-;; publications from various sources, by keywords or by DOI. References are
-;; automatically fetched from well-curated sources, and formatted as BibTeX.
-;;
-;; ## Supported sources:
-;;
-;; * ‘CrossRef’, an exhaustive academic search engine (recommended)
-;; * ‘arXiv’, an archive of pre-prints in various scientific fields
-;; * ‘DBLP’, a database of Computer Science publications
-;; * ‘HAL’, a French repository of Open Access publications
-;; * ‘doi.org’, a DOI resolver (to retrieve BibTeX records from DOIs)
-;; * ‘CrossCite’, an alternative DOI resolver and BibTeX formatting service
-;; * ‘Dissemin’, a database tracking the open access status of scholarly articles
-;;
-;; ## Usage
-;;
-;; Quick start: ‘M-x biblio-lookup’. Each source can also be accessed independently:
-;;
-;; * ‘M-x crossref-lookup’ to query CrossRef
-;; * ‘M-x arxiv-lookup` to query arXiv
-;; * `M-x dblp-lookup’ to query DBLP
-;; * ‘M-x doi-insert’ to insert a BibTeX record by DOI
-;; * ‘M-x dissemin-lookup’ to show information about the open access status of a
-;; particular DOI
-;;
-;; Most of these commands work together: for example, ‘crossref-lookup’ displays a
-;; list of results in ‘biblio-selection-mode’. In that mode, use:
-;;
-;; * ‘RET’ to visit the corresponding web page
-;; * ‘c’ or ‘M-w’ to copy the BibTeX record of the current entry
-;; * ‘i’ or ‘C-y’ to insert the BibTeX record of the current entry
-;; * ‘x’ to run an extended action, such as fetching a Dissemin record
-;;
-;; ‘C’ and ‘I’ do the same as ‘c’ and ‘i’, but additionally close the search window.
-;;
-;; ## Examples
-;;
-;; * To insert a clean BibTeX entry for https://doi.org/10.1145/2676726.2677006
-;; in the current buffer, use
-;;
-;; M-x crossref-lookup RET fiat deductive delaware RET i
-;;
-;; (the last ‘i’ inserts the BibTeX record of the currently selected entry in
-;; your buffer).
-;;
-;; * To find publications by computer scientist Leslie Lamport, use ‘M-x
-;; dblp-lookup RET author:Lamport RET’ (see more info about DBLP's syntax at
-;; <https://dblp.uni-trier.de/search/>)
-;;
-;; * To check whether an article is freely available online, use ‘x’ in the list
-;; of results. For example ‘M-x crossref-lookup RET Emacs stallman RET’
-;; followed by ‘x Dissemin RET’ will help you find open access copies of
-;; Stallman's paper on EMACS (spoiler: https://hdl.handle.net/1721.1/5736).
-;;
-;; See https://github.com/cpitclaudel/biblio.el for more information, including
-;; documentation on extending this framework.
-
-;;; Code:
-
-(require 'biblio-core)
-(require 'biblio-doi)
-(require 'biblio-arxiv)
-(require 'biblio-crossref)
-(require 'biblio-dblp)
-(require 'biblio-hal)
-(require 'biblio-ieee)
-(require 'biblio-dissemin)
-(require 'biblio-download)
-
-(provide 'biblio)
-;;; biblio.el ends here
--- /dev/null
+;;; biblio-arxiv.el --- Lookup and import bibliographic entries from arXiv -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016 Clément Pit-Claudel
+
+;; Author: Clément Pit-Claudel <clement.pitclaudelNOSPAMlive.com>
+;; URL: https://github.com/cpitclaudel/biblio.el
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; Lookup and download bibliographic records from arXiv using `arxiv-lookup'.
+;; When a DOI is available, the metadata is fetched from the DOI's issuer;
+;; otherwise, this package uses arXiv's metadata to generate an entry.
+;;
+;; This file implements a backend for the for the `biblio' package (which see for more
+;; documentation).
+
+;;; Code:
+
+(require 'biblio-core)
+(require 'biblio-doi)
+(require 'timezone)
+
+(defgroup biblio-arxiv nil
+ "arXiv support in biblio.el"
+ :group 'biblio)
+
+(defcustom biblio-arxiv-bibtex-header "online"
+ "Which header to use for BibTeX entries generated from arXiv metadata."
+ :group 'biblio
+ :type 'string)
+
+(defun biblio-arxiv--build-bibtex-1 (metadata)
+ "Create an unformated BibTeX record for METADATA."
+ (let-alist metadata
+ (format "@%s{NO_KEY,
+author = {%s},
+title = {{%s}},
+year = {%s},
+archivePrefix = {arXiv},
+eprint = {%s},
+primaryClass = {%s}}"
+ biblio-arxiv-bibtex-header
+ (biblio-join-1 " AND " .authors)
+ .title .year .identifier .category)))
+
+(defun biblio-arxiv--build-bibtex (metadata)
+ "Create a BibTeX record for METADATA."
+ (let-alist metadata
+ (message "Auto-generating a BibTeX entry for %S." .id)
+ (biblio-format-bibtex (biblio-arxiv--build-bibtex-1 metadata) t)))
+
+(defun biblio-arxiv--forward-bibtex (metadata forward-to)
+ "Forward BibTeX for arXiv entry METADATA to FORWARD-TO."
+ (let-alist metadata
+ (if (seq-empty-p .doi)
+ (funcall forward-to (biblio-arxiv--build-bibtex metadata))
+ (biblio-doi-forward-bibtex .doi forward-to))))
+
+(defun biblio-arxiv--format-author (author)
+ "Format AUTHOR for arXiv search results."
+ (when (eq (car-safe author) 'author)
+ (let-alist (cdr author)
+ (biblio-join " "
+ (cadr .name)
+ (biblio-parenthesize (cadr .arxiv:affiliation))))))
+
+(defun biblio-arxiv--extract-id (id)
+ "Extract identifier from ID, the URL of an arXiv abstract."
+ (replace-regexp-in-string "https?://arxiv.org/abs/" "" id))
+
+(defun biblio-arxiv--pdf-url (id)
+ "Extract PDF url from ID of an arXiv entry."
+ (when id
+ (concat "https://arxiv.org/pdf/" id)))
+
+(defun biblio-arxiv--extract-interesting-fields (entry)
+ "Prepare an arXiv search result ENTRY for display."
+ (let-alist entry
+ (let ((id (biblio-arxiv--extract-id (cadr .id))))
+ (list (cons 'doi (cadr .arxiv:doi))
+ (cons 'identifier id)
+ (cons 'year (aref (timezone-parse-date (cadr .published)) 0))
+ (cons 'title (cadr .title))
+ (cons 'authors (seq-map #'biblio-arxiv--format-author entry))
+ (cons 'container (cadr .arxiv:journal_ref))
+ (cons 'category
+ (biblio-alist-get 'term (car .arxiv:primary_category)))
+ (cons 'references (list (cadr .arxiv:doi) id))
+ (cons 'type "eprint")
+ (cons 'url (biblio-alist-get 'href (car .link)))
+ (cons 'direct-url (biblio-arxiv--pdf-url id))))))
+
+(defun biblio-arxiv--entryp (entry)
+ "Check if ENTRY is an arXiv entry."
+ (eq (car-safe entry) 'entry))
+
+(defun biblio-arxiv--parse-search-results ()
+ "Extract search results from arXiv response."
+ (biblio-decode-url-buffer 'utf-8)
+ (let-alist (xml-parse-region (point-min) (point-max))
+ (seq-map #'biblio-arxiv--extract-interesting-fields
+ (seq-filter #'biblio-arxiv--entryp .feed))))
+
+(defun biblio-arxiv--url (query)
+ "Create an arXiv url to look up QUERY."
+ (format "https://export.arxiv.org/api/query?search_query=%s"
+ (url-encode-url query)))
+
+;;;###autoload
+(defun biblio-arxiv-backend (command &optional arg &rest more)
+ "A arXiv backend for biblio.el.
+COMMAND, ARG, MORE: See `biblio-backends'."
+ (pcase command
+ (`name "arXiv")
+ (`prompt "arXiv query: ")
+ (`url (biblio-arxiv--url arg))
+ (`parse-buffer (biblio-arxiv--parse-search-results))
+ (`forward-bibtex (biblio-arxiv--forward-bibtex arg (car more)))
+ (`register (add-to-list 'biblio-backends #'biblio-arxiv-backend))))
+
+;;;###autoload
+(add-hook 'biblio-init-hook #'biblio-arxiv-backend)
+
+;;;###autoload
+(defun biblio-arxiv-lookup (&optional query)
+ "Start an arXiv search for QUERY, prompting if needed."
+ (interactive)
+ (biblio-lookup #'biblio-arxiv-backend query))
+
+;;;###autoload
+(defalias 'arxiv-lookup 'biblio-arxiv-lookup)
+
+(provide 'biblio-arxiv)
+;;; biblio-arxiv.el ends here
--- /dev/null
+;;; biblio-autoloads.el --- automatically extracted autoloads (do not edit) -*- lexical-binding: t -*-
+;; Generated by the `loaddefs-generate' function.
+
+;; This file is part of GNU Emacs.
+
+;;; Code:
+
+(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
+
+
+\f
+;;; Generated autoloads from biblio-arxiv.el
+
+(autoload 'biblio-arxiv-backend "biblio-arxiv" "\
+A arXiv backend for biblio.el.
+COMMAND, ARG, MORE: See `biblio-backends'.
+
+(fn COMMAND &optional ARG &rest MORE)")
+(add-hook 'biblio-init-hook #'biblio-arxiv-backend)
+(autoload 'biblio-arxiv-lookup "biblio-arxiv" "\
+Start an arXiv search for QUERY, prompting if needed.
+
+(fn &optional QUERY)" t)
+(defalias 'arxiv-lookup 'biblio-arxiv-lookup)
+(register-definition-prefixes "biblio-arxiv" '("biblio-arxiv-"))
+
+\f
+;;; Generated autoloads from biblio-crossref.el
+
+(autoload 'biblio-crossref-backend "biblio-crossref" "\
+A CrossRef backend for biblio.el.
+COMMAND, ARG, MORE: See `biblio-backends'.
+
+(fn COMMAND &optional ARG &rest MORE)")
+(add-hook 'biblio-init-hook #'biblio-crossref-backend)
+(autoload 'biblio-crossref-lookup "biblio-crossref" "\
+Start a CrossRef search for QUERY, prompting if needed.
+
+(fn &optional QUERY)" t)
+(defalias 'crossref-lookup 'biblio-crossref-lookup)
+(register-definition-prefixes "biblio-crossref" '("biblio-crossref-"))
+
+\f
+;;; Generated autoloads from biblio-dblp.el
+
+(autoload 'biblio-dblp-backend "biblio-dblp" "\
+A DBLP backend for biblio.el.
+COMMAND, ARG, MORE: See `biblio-backends'.
+
+(fn COMMAND &optional ARG &rest MORE)")
+(add-hook 'biblio-init-hook #'biblio-dblp-backend)
+(autoload 'biblio-dblp-lookup "biblio-dblp" "\
+Start a DBLP search for QUERY, prompting if needed.
+
+(fn &optional QUERY)" t)
+(defalias 'dblp-lookup 'biblio-dblp-lookup)
+(register-definition-prefixes "biblio-dblp" '("biblio-dblp--"))
+
+\f
+;;; Generated autoloads from biblio-dissemin.el
+
+(autoload 'biblio-dissemin-lookup "biblio-dissemin" "\
+Retrieve a record by DOI from Dissemin, and display it.
+Interactively, or if CLEANUP is non-nil, pass DOI through
+`biblio-cleanup-doi'.
+
+(fn DOI &optional CLEANUP)" t)
+(defalias 'dissemin-lookup 'biblio-dissemin-lookup)
+(autoload 'biblio-dissemin--register-action "biblio-dissemin" "\
+Add Dissemin to list of `biblio-selection-mode' actions.")
+(add-hook 'biblio-selection-mode-hook #'biblio-dissemin--register-action)
+(register-definition-prefixes "biblio-dissemin" '("biblio-dissemin--"))
+
+\f
+;;; Generated autoloads from biblio-doi.el
+
+(autoload 'biblio-doi-insert-bibtex "biblio-doi" "\
+Insert BibTeX entry matching DOI.
+
+(fn DOI)" t)
+(register-definition-prefixes "biblio-doi" '("biblio-doi-" "doi-insert-bibtex"))
+
+\f
+;;; Generated autoloads from biblio-download.el
+
+(autoload 'biblio-download--register-action "biblio-download" "\
+Add download to list of `biblio-selection-mode' actions.")
+(add-hook 'biblio-selection-mode-hook #'biblio-download--register-action)
+(register-definition-prefixes "biblio-download" '("biblio-download-"))
+
+\f
+;;; Generated autoloads from biblio-hal.el
+
+(autoload 'biblio-hal-backend "biblio-hal" "\
+A HAL backend for biblio.el.
+COMMAND, ARG, MORE: See `biblio-backends'.
+
+(fn COMMAND &optional ARG &rest MORE)")
+(add-hook 'biblio-init-hook #'biblio-hal-backend)
+(autoload 'biblio-hal-lookup "biblio-hal" "\
+Start a HAL search for QUERY, prompting if needed.
+
+(fn &optional QUERY)" t)
+(defalias 'hal-lookup 'biblio-hal-lookup)
+(register-definition-prefixes "biblio-hal" '("biblio-hal--"))
+
+\f
+;;; Generated autoloads from biblio-ieee.el
+
+(autoload 'biblio-ieee-backend "biblio-ieee" "\
+A IEEE Xplore backend for biblio.el.
+COMMAND, ARG, MORE: See `biblio-backends'.
+
+(fn COMMAND &optional ARG &rest MORE)")
+(add-hook 'biblio-init-hook #'biblio-ieee-backend)
+(autoload 'biblio-ieee-lookup "biblio-ieee" "\
+Start a IEEE search for QUERY, prompting if needed.
+
+(fn &optional QUERY)" t)
+(defalias 'ieee-lookup 'biblio-ieee-lookup)
+(register-definition-prefixes "biblio-ieee" '("biblio-ieee--"))
+\f
+;;; End of scraped data
+
+(provide 'biblio-autoloads)
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; no-native-compile: t
+;; coding: utf-8-emacs-unix
+;; End:
+
+;;; biblio-autoloads.el ends here
--- /dev/null
+;;; biblio-crossref.el --- Lookup and import bibliographic entries from CrossRef -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016 Clément Pit-Claudel
+
+;; Author: Clément Pit-Claudel <clement.pitclaudelNOSPAMlive.com>
+;; URL: https://github.com/cpitclaudel/biblio.el
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; Lookup and download bibliographic records from CrossRef (a very nicely
+;; curated metadata engine) using `crossref-lookup'.
+;;
+;; This file implements a backend for the `biblio' package (which see for more
+;; documentation).
+
+;;; Code:
+
+(require 'biblio-core)
+(require 'biblio-doi)
+
+(defcustom biblio-crossref-user-email-address nil
+ "Email address to include in CrossRef queries, or nil.
+CrossRef gives priority to queries that include an email address.
+See URL `https://github.com/CrossRef/rest-api-doc#etiquette' for
+more details."
+ :group 'biblio
+ :type '(choice (const :tag "Do not include an email address." nil)
+ (string :tag "Include an email address.")))
+
+(defun biblio-crossref--forward-bibtex (metadata forward-to)
+ "Forward BibTeX for CrossRef entry METADATA to FORWARD-TO."
+ (biblio-doi-forward-bibtex (biblio-alist-get 'doi metadata) forward-to))
+
+(defun biblio-crossref--format-affiliation (affiliation)
+ "Format AFFILIATION for CrossRef search results."
+ (mapconcat (apply-partially #'biblio-alist-get 'name) affiliation ", "))
+
+(defun biblio-crossref--format-author (author)
+ "Format AUTHOR for CrossRef search results."
+ (let-alist author
+ (biblio-join " "
+ .given .family (biblio-parenthesize (biblio-crossref--format-affiliation .affiliation)))))
+
+(defun biblio-crossref--extract-interesting-fields (item)
+ "Prepare a CrossRef search result ITEM for display."
+ (let-alist item
+ (list (cons 'doi .DOI)
+ (cons 'year (let ((year (aref (aref .issued.date-parts 0) 0)))
+ (and (numberp year) (number-to-string year))))
+ (cons 'title (biblio-join " "
+ (biblio-join-1 ", " .title)
+ (biblio-parenthesize (biblio-join-1 ", " .subtitle))))
+ (cons 'authors (seq-map #'biblio-crossref--format-author .author))
+ (cons 'publisher .publisher)
+ (cons 'container .container-title)
+ (cons 'references (seq-concatenate 'list (list .DOI) .isbn))
+ (cons 'type .type)
+ (cons 'url .URL))))
+
+(defun biblio-crossref--parse-search-results ()
+ "Extract search results from CrossRef response."
+ (biblio-decode-url-buffer 'utf-8)
+ (let-alist (json-read)
+ (unless (string= .status "ok")
+ (display-warning 'biblio-crossref "CrossRef query failed"))
+ (seq-map #'biblio-crossref--extract-interesting-fields .message.items)))
+
+(defun biblio-crossref--url (query)
+ "Create a CrossRef url to look up QUERY."
+ (format "https://api.crossref.org/works?query=%s%s"
+ (url-encode-url query)
+ (if biblio-crossref-user-email-address
+ (format "&mailto=%s" (url-encode-url biblio-crossref-user-email-address)) "")))
+
+;;;###autoload
+(defun biblio-crossref-backend (command &optional arg &rest more)
+ "A CrossRef backend for biblio.el.
+COMMAND, ARG, MORE: See `biblio-backends'."
+ (pcase command
+ (`name "CrossRef")
+ (`prompt "CrossRef query: ")
+ (`url (biblio-crossref--url arg))
+ (`parse-buffer (biblio-crossref--parse-search-results))
+ (`forward-bibtex (biblio-crossref--forward-bibtex arg (car more)))
+ (`register (add-to-list 'biblio-backends #'biblio-crossref-backend))))
+
+;;;###autoload
+(add-hook 'biblio-init-hook #'biblio-crossref-backend)
+
+;;;###autoload
+(defun biblio-crossref-lookup (&optional query)
+ "Start a CrossRef search for QUERY, prompting if needed."
+ (interactive)
+ (biblio-lookup #'biblio-crossref-backend query))
+
+;;;###autoload
+(defalias 'crossref-lookup 'biblio-crossref-lookup)
+
+(provide 'biblio-crossref)
+;;; biblio-crossref.el ends here
--- /dev/null
+;;; biblio-dblp.el --- Lookup and import bibliographic entries from DBLP -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016 Clément Pit-Claudel
+
+;; Author: Clément Pit-Claudel <clement.pitclaudelNOSPAMlive.com>
+;; URL: https://github.com/cpitclaudel/biblio.el
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; Lookup and download bibliographic records from DBLP (a great source of
+;; references for Computer Science papers) using `dblp-lookup'.
+;;
+;; This file implements a backend for the for the `biblio' package (which see for more
+;; documentation).
+
+;;; Code:
+
+(require 'biblio-core)
+
+(defun biblio-dblp--forward-bibtex (metadata forward-to)
+ "Forward BibTeX for DBLP entry METADATA to FORWARD-TO."
+ (let* ((source-url (biblio-alist-get 'url metadata))
+ (url (replace-regexp-in-string "/rec/" "/rec/bib2/" source-url t t)))
+ (biblio-url-retrieve url (biblio-generic-url-callback
+ (lambda () ;; No allowed errors, so no arguments
+ "Parse DBLP BibTeX results."
+ (funcall forward-to
+ (biblio-response-as-utf-8)))))))
+
+(defun biblio-dblp--extract-interesting-fields (item)
+ "Prepare a DBLP search result ITEM for display."
+ (let-alist (biblio-alist-get 'info item)
+ (list (cons 'year (cadr .year))
+ (cons 'title (cadr .title))
+ (cons 'authors (seq-map #'cl-caddr (cdr .authors)))
+ (cons 'container (cadr .venue))
+ (cons 'references nil)
+ (cons 'type (cadr .type))
+ (cons 'url (cadr .url)))))
+
+(defun biblio-dblp--hitp (item)
+ "Check if ITEM is a DBLP hit."
+ (eq (car-safe item) 'hit))
+
+(defun biblio-dblp--parse-search-results ()
+ "Extract search results from DBLP response."
+ (biblio-decode-url-buffer 'utf-8)
+ (let-alist (car (xml-parse-region (point-min) (point-max)))
+ (unless (string= (cadr .status) "OK")
+ (display-warning 'biblio-dblp "DBLP query failed"))
+ (seq-map #'biblio-dblp--extract-interesting-fields (seq-filter #'biblio-dblp--hitp .hits))))
+
+(defun biblio-dblp--url (query)
+ "Create a DBLP url to look up QUERY."
+ (format "https://dblp.org/search/publ/api?q=%s&format=xml" (url-encode-url query)))
+
+;;;###autoload
+(defun biblio-dblp-backend (command &optional arg &rest more)
+ "A DBLP backend for biblio.el.
+COMMAND, ARG, MORE: See `biblio-backends'."
+ (pcase command
+ (`name "DBLP")
+ (`prompt "DBLP query: ")
+ (`url (biblio-dblp--url arg))
+ (`parse-buffer (biblio-dblp--parse-search-results))
+ (`forward-bibtex (biblio-dblp--forward-bibtex arg (car more)))
+ (`register (add-to-list 'biblio-backends #'biblio-dblp-backend))))
+
+;;;###autoload
+(add-hook 'biblio-init-hook #'biblio-dblp-backend)
+
+;;;###autoload
+(defun biblio-dblp-lookup (&optional query)
+ "Start a DBLP search for QUERY, prompting if needed."
+ (interactive)
+ (biblio-lookup #'biblio-dblp-backend query))
+
+;;;###autoload
+(defalias 'dblp-lookup 'biblio-dblp-lookup)
+
+(provide 'biblio-dblp)
+;;; biblio-dblp.el ends here
--- /dev/null
+;;; biblio-dissemin.el --- Lookup bibliographic information and open access records from Dissemin -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016 Clément Pit-Claudel
+
+;; Author: Clément Pit-Claudel <clement.pitclaudelNOSPAMlive.com>
+;; URL: https://github.com/cpitclaudel/biblio.el
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; Lookup publication records on Dissemin by DOI using `dissemin-lookup'.
+;;
+;; This package also plugs into `biblio-selection-mode' by adding an entry to
+;; the extended actions menu (`x') to quickly locate the Dissemin record of
+;; e.g. a CrossRef entry.
+
+;;; Code:
+
+(require 'biblio-core)
+
+(defun biblio-dissemin--format-author (author)
+ "Format a Dissemin AUTHOR entry."
+ (let-alist author
+ (format "%s %s" .name.first .name.last)))
+
+(defun biblio-dissemin--insert-button (url prefix)
+ "Insert a button pointing to URL, prefixed by PREFIX."
+ (unless (seq-empty-p url)
+ (insert "\n" prefix)
+ (insert (biblio-make-url-button url))))
+
+(defun biblio-dissemin--insert-record (record)
+ "Insert a Dissemin RECORD entry into the current buffer."
+ (let-alist record
+ (insert "\n\n")
+ (biblio-with-fontification 'font-lock-preprocessor-face
+ (biblio-insert-with-prefix ">> " .identifier))
+ (biblio-dissemin--insert-button .pdf_url " ")
+ (unless (string= .pdf_url .splash_url)
+ (biblio-dissemin--insert-button .splash_url " "))
+ (unless (seq-empty-p .abstract)
+ (insert "\n")
+ ;; (biblio-with-fontification 'font-lock-doc-face
+ (biblio-insert-with-prefix " " .abstract))))
+
+(defun biblio-dissemin--translate-classification (classification)
+ "Translate Dissemin's CLASSIFICATION for display."
+ (pcase classification
+ (`"OA" "Available from the publisher")
+ (`"OK" "Some versions may be shared by the author")
+ (`"UNK" "Sharing policy is unclear")
+ (`"CLOSED" "Subject to a restrictive sharing policy")
+ (_ classification)))
+
+(defun biblio-dissemin--suggest-upload (doi)
+ "Insert a link to Dissemin's upload page for DOI."
+ (insert "\n\nDid you write this paper? ")
+ (biblio-with-fontification '(:weight bold)
+ (insert
+ (biblio-make-url-button (format "https://dissem.in/%s" doi) "upload it")))
+ (insert "!\n"))
+
+(defun biblio-dissemin--pretty-print (paper doi)
+ "Pretty-print a Dissemin PAPER entry (with DOI) to current buffer."
+ (let-alist paper
+ (biblio-insert-result
+ (list (cons 'title .title)
+ (cons 'authors (seq-map #'biblio-dissemin--format-author .authors))
+ (cons 'open-access-status
+ (biblio-dissemin--translate-classification .classification)))
+ t)
+ (biblio-dissemin--insert-button .pdf_url " ")
+ (if (seq-empty-p .records)
+ (progn (insert "\n\n(no records)")
+ (when (member .classification '("OA" "OK"))
+ (biblio-dissemin--suggest-upload doi)))
+ (seq-do #'biblio-dissemin--insert-record .records))
+ (goto-char (point-min))))
+
+(defun biblio-dissemin--print-results (paper doi)
+ "Create a buffer for Dissemin, and print PAPER (with DOI) into it."
+ (with-current-buffer (biblio-dissemin--make-buffer)
+ (let ((inhibit-read-only t))
+ (erase-buffer)
+ (help-mode)
+ (visual-line-mode)
+ (biblio-dissemin--pretty-print paper doi))
+ (setq buffer-read-only t)
+ (pop-to-buffer (current-buffer))))
+
+(defun biblio-dissemin--make-buffer ()
+ "Create a buffer to display Dissemin results in."
+ (get-buffer-create "*Dissemin search results*"))
+
+(defun biblio-dissemin--parse-buffer ()
+ "Extract search results from DBLP response."
+ (biblio-decode-url-buffer 'utf-8)
+ (let-alist (json-read)
+ (unless (string= .status "ok")
+ (display-warning 'biblio-dissemin "Dissemin query failed"))
+ .paper))
+
+(defun biblio-dissemin--url (doi)
+ "Create a DBLP url to look up DOI."
+ (format "https://dissem.in/api/%s" (url-encode-url doi)))
+
+(defun biblio-dissemin--callback (doi)
+ "Generate a callback to parse Dissemin results for DOI."
+ (lambda () ;; no allowed errors, so no arguments
+ (biblio-dissemin--print-results (biblio-dissemin--parse-buffer) doi)))
+
+;;;###autoload
+(defun biblio-dissemin-lookup (doi &optional cleanup)
+ "Retrieve a record by DOI from Dissemin, and display it.
+Interactively, or if CLEANUP is non-nil, pass DOI through
+`biblio-cleanup-doi'."
+ (interactive "MDOI: \nd")
+ (when cleanup
+ (setq doi (biblio-cleanup-doi doi)))
+ (let ((buf (biblio-dissemin--make-buffer)))
+ (biblio-url-retrieve (biblio-dissemin--url doi)
+ (biblio-generic-url-callback (biblio-dissemin--callback doi)))
+ buf))
+
+;;;###autoload
+(defalias 'dissemin-lookup 'biblio-dissemin-lookup)
+
+(defun biblio-dissemin--lookup-record (record)
+ "Retrieve a RECORD from Dissemin, and display it.
+RECORD is a formatted record as expected by `biblio-insert-result'."
+ (let-alist record
+ (if .doi (dissemin-lookup .doi)
+ (user-error "Dissemin needs a DOI, but this record does not contain one"))))
+
+;;;###autoload
+(defun biblio-dissemin--register-action ()
+ "Add Dissemin to list of `biblio-selection-mode' actions."
+ (add-to-list 'biblio-selection-mode-actions-alist
+ '("Dissemin (find open access copies of this article)" . biblio-dissemin--lookup-record)))
+
+;;;###autoload
+(add-hook 'biblio-selection-mode-hook #'biblio-dissemin--register-action)
+
+(provide 'biblio-dissemin)
+;;; biblio-dissemin.el ends here
--- /dev/null
+;;; biblio-doi.el --- Retrieve BibTeX entries by DOI -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016 Clément Pit-Claudel
+
+;; Author: Clément Pit-Claudel <clement.pitclaudelNOSPAMlive.com>
+;; URL: https://github.com/cpitclaudel/biblio.el
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+
+;;; Commentary:
+;;
+;; Retrieve and insert BibTeX records by DOI using `doi-insert-bibtex'.
+;; Information is retrieved from DOI issuing sites of each DOI using the
+;; “application/x-bibtex” and “text/bibliography” request types, falling back to
+;; CrossCite if unavailable.
+;;
+;; This package integrates with `biblio-selection-mode', and is part of the more
+;; general `biblio' package (which see for more documentation).
+
+(require 'biblio-core)
+
+;;; Code:
+
+(defun biblio-doi--dx-url (doi)
+ "Create a doi.org url for DOI."
+ (format "https://doi.org/%s" doi))
+
+(defun biblio-doi--crosscite-url (doi)
+ "Create a crosscite URL to use as a fallback for DOI.
+Not all content providers provide BibTeX formatted entries, so
+instead of failing reroute the request through crosscite, which
+requests a generic format and crates the BibTeX on its own."
+ (format "https://crosscite.org/citeproc/format?doi=%s&style=bibtex&lang=en-US" doi))
+
+(defconst biblio-doi--dx-mime-accept
+ ;; “Accept:” header; Zenodo recognizes x-bibtex but not text/bibliography
+ "text/bibliography;style=bibtex, application/x-bibtex")
+
+(defun biblio-doi--set-mime-accept ()
+ "Set `url-mime-accept-string' before contacting the DOI server."
+ ;; Ugly: let-binding or buffer-locally setting `url-mime-accept-string' does
+ ;; not work, because `url-http-create-request' can be called from a
+ ;; sentinel, or from an entirely new buffer (after a redirection).
+ (setq url-mime-accept-string biblio-doi--dx-mime-accept))
+
+(defun biblio-doi--restore-mime-accept ()
+ "Restore `url-mime-accept-string'."
+ (kill-local-variable 'url-mime-accept-string)
+ (setq-default url-mime-accept-string nil))
+
+(defun biblio-doi--insert (bibtex buffer)
+ "Insert formatted BIBTEX into BUFFER."
+ (with-current-buffer buffer
+ (insert bibtex "\n\n")))
+
+(defun biblio-doi--generic-url-callback-1 (errors forward-to)
+ "Helper function for `biblio-doi--generic-url-callback'.
+ERRORS, FORWARD-TO: see there."
+ (funcall forward-to (unless errors (biblio-response-as-utf-8))))
+
+(defun biblio-doi--generic-url-callback (cleanup-fn forward-to)
+ "Make an URL-ready callback.
+Call CLEANUP-FN in any case, and FORWARD-TO with BibTeX source
+or nil depending on whether an error occured. If error 406
+occurs, forward nil; otherwise, signal the error. This is
+essentially a thin wrapper around `biblio-generic-url-callback'."
+ (biblio-generic-url-callback
+ (lambda (&optional errors)
+ "Handle response from BibTeX server."
+ (biblio-doi--generic-url-callback-1 errors forward-to))
+ cleanup-fn '(http . 406)))
+
+(defun biblio-doi--crosscite-callback (forward-to)
+ "Generate a handler for response of CrossCite server.
+FORWARD-TO is the callback to call with the results of the search."
+ (biblio-doi--generic-url-callback #'ignore forward-to))
+
+(defun biblio-doi--forward-bibtex-crosscite (doi forward-to)
+ "Forward BibTeX entry for DOI from CrossCite to FORWARD-TO."
+ (biblio-url-retrieve (biblio-doi--crosscite-url doi) (biblio-doi--crosscite-callback forward-to)))
+
+(defun biblio-doi--dx-callback (forward-to)
+ "Generate a handler for response of DX server.
+FORWARD-TO is the callback to call with the results of the search."
+ (biblio-doi--generic-url-callback #'biblio-doi--restore-mime-accept forward-to))
+
+(defun biblio-doi--forward-bibtex-dx (doi forward-to)
+ "Forward BibTeX entry for DOI from doi.org to FORWARD-TO."
+ (biblio-doi--set-mime-accept)
+ (biblio-url-retrieve (biblio-doi--dx-url doi) (biblio-doi--dx-callback forward-to)))
+
+(defun biblio-doi-forward-bibtex (doi forward-to)
+ "Pass BibTeX entry for DOI to FORWARD-TO."
+ (biblio-doi--forward-bibtex-dx
+ doi (lambda (result)
+ (if result (funcall forward-to result)
+ (biblio-doi--forward-bibtex-crosscite doi forward-to)))))
+
+;;;###autoload
+(defun biblio-doi-insert-bibtex (doi)
+ "Insert BibTeX entry matching DOI."
+ (interactive "MDOI: ")
+ (let ((target-buffer (current-buffer)))
+ (biblio-doi-forward-bibtex
+ (biblio-cleanup-doi doi)
+ (lambda (result)
+ (biblio-doi--insert
+ (biblio-format-bibtex result biblio-bibtex-use-autokey)
+ target-buffer)))))
+
+(defalias 'doi-insert-bibtex 'biblio-doi-insert-bibtex)
+
+(provide 'biblio-doi)
+;;; biblio-doi.el ends here
--- /dev/null
+;;; biblio-download.el --- Lookup bibliographic information and open access records from Dissemin -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016 Clément Pit-Claudel
+
+;; Author: Clément Pit-Claudel <clement.pitclaudelNOSPAMlive.com>
+;; URL: https://github.com/cpitclaudel/biblio.el
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; Download scientific papers directly from Emacs.
+;;
+;; This package plugs into `biblio-selection-mode' by adding an entry to the
+;; extended actions menu (`x').
+
+;;; Code:
+
+(require 'biblio-core)
+
+(defcustom biblio-download-directory nil
+ "Where to put downloaded papers."
+ :group 'biblio
+ :type 'directory)
+
+(defun biblio-download--action (record)
+ "Retrieve a RECORD from Dissemin, and display it.
+RECORD is a formatted record as expected by `biblio-insert-result'."
+ (let-alist record
+ (if .direct-url
+ (let* ((fname (concat .identifier ".pdf"))
+ (target (read-file-name "Save as (see also biblio-download-directory): "
+ biblio-download-directory fname nil fname)))
+ (url-copy-file .direct-url (expand-file-name target biblio-download-directory)))
+ (user-error "This record does not contain a direct URL (try arXiv or HAL)"))))
+
+;;;###autoload
+(defun biblio-download--register-action ()
+ "Add download to list of `biblio-selection-mode' actions."
+ (add-to-list 'biblio-selection-mode-actions-alist
+ '("Download this article" . biblio-download--action)))
+
+;;;###autoload
+(add-hook 'biblio-selection-mode-hook #'biblio-download--register-action)
+
+(provide 'biblio-download)
+;;; biblio-download.el ends here
--- /dev/null
+;;; biblio-hal.el --- Lookup and import bibliographic entries from HAL (archives ouvertes) -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016 Clément Pit-Claudel
+
+;; Author: Clément Pit-Claudel <clement.pitclaudelNOSPAMlive.com>
+;; URL: https://github.com/cpitclaudel/biblio.el
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; Lookup and download bibliographic records from HAL using `hal-lookup'.
+;;
+;; This file implements a backend for the for the `biblio' package (which see for more
+;; documentation).
+
+;;; Code:
+
+(require 'biblio-core)
+(require 'timezone)
+
+(defun biblio-hal--forward-bibtex (metadata forward-to)
+ "Forward BibTeX for HAL entry METADATA to FORWARD-TO."
+ (funcall forward-to (biblio-alist-get 'bibtex metadata)))
+
+;; (defun biblio-hal--format-author (author)
+;; "Format AUTHOR for HAL search results."
+;; (pcase author
+;; (`(,author . ,affiliation)
+;; (biblio-join " " author (biblio-parenthesize affiliation)))))
+
+(defun biblio-hal--extract-interesting-fields (item)
+ "Prepare a HAL search result ITEM for display."
+ (let-alist item
+ (list (cons 'doi .doiId_s)
+ (cons 'year (aref (timezone-parse-date .producedDate_tdate) 0))
+ (cons 'bibtex .label_bibtex)
+ (cons 'title (biblio-join " "
+ (biblio-join-1 ", " .title_s)
+ (biblio-parenthesize
+ (biblio-join-1 ", " .subtitle_s))))
+ (cons 'authors .authFullName_s)
+ ;; Too many institutions? (biblio-parenthesize (biblio-join-1 ", " .structName_s))
+ (cons 'publisher .journalPublisher_s)
+ (cons 'container .journalTitle_s)
+ (cons 'references (biblio-remove-empty
+ (list .doiId_s .halId_s .arxivId_s)))
+ (cons 'type .submitType_s)
+ (cons 'url .uri_s)
+ (cons 'direct-url (car (append .files_s nil))))))
+
+(defun biblio-hal--parse-search-results ()
+ "Extract search results from HAL response."
+ (biblio-decode-url-buffer 'utf-8)
+ (let-alist (json-read)
+ (unless .response
+ (display-warning 'biblio-hal "HAL query failed"))
+ (seq-map #'biblio-hal--extract-interesting-fields .response.docs)))
+
+(defun biblio-hal--url (query)
+ "Create a HAL url to look up QUERY."
+ (format "https://api.archives-ouvertes.fr/search/?q=%s&wt=%s&fl=%s"
+ (url-encode-url query) "json"
+ (biblio-join "," ;; Use ‘*’ to show all fields
+ "arxivId_s" "halId_s" "doiId_s" ;; "journalIssn_s"
+ "title_s" "subtitle_s" "authFullName_s" "structName_s"
+ "journalPublisher_s" "submitType_s" ;; "abstract_s"
+ ;; "journalTitle_s" "volume_s" "issue_s" "page_s" "writingDate_s"
+ "label_bibtex" "files_s" "uri_s" "producedDate_tdate")))
+
+;;;###autoload
+(defun biblio-hal-backend (command &optional arg &rest more)
+ "A HAL backend for biblio.el.
+COMMAND, ARG, MORE: See `biblio-backends'."
+ (pcase command
+ (`name "HAL")
+ (`prompt "HAL (archives ouvertes) query: ")
+ (`url (biblio-hal--url arg))
+ (`parse-buffer (biblio-hal--parse-search-results))
+ (`forward-bibtex (biblio-hal--forward-bibtex arg (car more)))
+ (`register (add-to-list 'biblio-backends #'biblio-hal-backend))))
+
+;;;###autoload
+(add-hook 'biblio-init-hook #'biblio-hal-backend)
+
+;;;###autoload
+(defun biblio-hal-lookup (&optional query)
+ "Start a HAL search for QUERY, prompting if needed."
+ (interactive)
+ (biblio-lookup #'biblio-hal-backend query))
+
+;;;###autoload
+(defalias 'hal-lookup 'biblio-hal-lookup)
+
+(provide 'biblio-hal)
+;;; biblio-hal.el ends here
--- /dev/null
+;;; biblio-ieee.el --- Lookup and import bibliographic entries from IEEE -*- lexical-binding: t -*-
+
+;; Copyright (C) 2019 Clément Pit-Claudel
+
+;; Author: Clément Pit-Claudel <clement.pitclaudelNOSPAMlive.com>
+;; URL: https://github.com/cpitclaudel/biblio.el
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; Lookup and download bibliographic records from IEEE Xplore using
+;; `ieee-lookup'.
+;;
+;; This package uses `biblio-selection-mode', and plugs into the more general
+;; `biblio' package (which see for more documentation).
+
+;;; Code:
+
+(require 'biblio-core)
+(require 'biblio-doi)
+
+(defconst biblio-ieee--api-key "rfwzcsz3f9fkhklhii84xdfz"
+ "API key used to query IEEE; for use only with biblio.el!")
+
+(defconst biblio-ieee--api-root-url
+ "https://ieeexploreapi.ieee.org/api/v1/search/articles")
+
+(defun biblio-ieee--forward-bibtex (metadata forward-to)
+ "Forward BibTeX for IEEE Xplore entry METADATA to FORWARD-TO."
+ (biblio-doi-forward-bibtex (biblio-alist-get 'doi metadata) forward-to))
+
+(defun biblio-ieee--format-author (author)
+ "Format AUTHOR for IEEE Xplore search results."
+ (let-alist author
+ (biblio-join " " .full_name (biblio-parenthesize .affiliation))))
+
+(defun biblio-ieee--extract-interesting-fields (item)
+ "Prepare a IEEE Xplore search result ITEM for display."
+ (let-alist item
+ (list (cons 'doi .doi)
+ (cons 'year .publication_year)
+ (cons 'title .title)
+ (cons 'authors (seq-map #'biblio-ieee--format-author .authors.authors))
+ (cons 'publisher .publisher)
+ (cons 'container .publication_title)
+ (cons 'references (list .doi .isbn))
+ (cons 'type (or .index_terms.author_terms.terms
+ .index_terms.ieee_terms.terms))
+ (cons 'url .abstract_url)
+ (cons 'direct-url .pdf_url)
+ (cons 'open-access-status .access_type))))
+
+(defun biblio-ieee--parse-search-results ()
+ "Extract search results from IEEE Xplore response."
+ (biblio-decode-url-buffer 'utf-8)
+ (let-alist (json-read)
+ (seq-map #'biblio-ieee--extract-interesting-fields .articles)))
+
+(defun biblio-ieee--url (query)
+ "Create an IEEE Xplore url to look up QUERY."
+ (format "%s?querytext=%s&apikey=%s"
+ biblio-ieee--api-root-url
+ (url-encode-url query)
+ (rot13 biblio-ieee--api-key)))
+
+;;;###autoload
+(defun biblio-ieee-backend (command &optional arg &rest more)
+ "A IEEE Xplore backend for biblio.el.
+COMMAND, ARG, MORE: See `biblio-backends'."
+ (pcase command
+ (`name "IEEE Xplore")
+ (`prompt "IEEE Xplore query: ")
+ (`url (biblio-ieee--url arg))
+ (`parse-buffer (biblio-ieee--parse-search-results))
+ (`forward-bibtex (biblio-ieee--forward-bibtex arg (car more)))
+ (`register (add-to-list 'biblio-backends #'biblio-ieee-backend))))
+
+;;;###autoload
+(add-hook 'biblio-init-hook #'biblio-ieee-backend)
+
+;;;###autoload
+(defun biblio-ieee-lookup (&optional query)
+ "Start a IEEE search for QUERY, prompting if needed."
+ (interactive)
+ (biblio-lookup #'biblio-ieee-backend query))
+
+;;;###autoload
+(defalias 'ieee-lookup 'biblio-ieee-lookup)
+
+(provide 'biblio-ieee)
+;;; biblio-ieee.el ends here
--- /dev/null
+;; -*- no-byte-compile: t; lexical-binding: nil -*-
+(define-package "biblio" "20250812.1408"
+ "Browse and import bibliographic references and BibTeX records from CrossRef, arXiv, DBLP, HAL, IEEE Xplore, Dissemin, and doi.org."
+ '((emacs "24.3")
+ (biblio-core "0.3"))
+ :url "https://github.com/cpitclaudel/biblio.el"
+ :commit "bb9d6b4b962fb2a4e965d27888268b66d868766b"
+ :revdesc "bb9d6b4b962f"
+ :keywords '("bib" "tex" "convenience" "hypermedia")
+ :authors '(("Clément Pit-Claudel" . "clement.pitclaudelNOSPAMlive.com"))
+ :maintainers '(("Clément Pit-Claudel" . "clement.pitclaudelNOSPAMlive.com")))
--- /dev/null
+;;; biblio.el --- Browse and import bibliographic references and BibTeX records from CrossRef, arXiv, DBLP, HAL, IEEE Xplore, Dissemin, and doi.org -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016 Clément Pit-Claudel
+
+;; Author: Clément Pit-Claudel <clement.pitclaudelNOSPAMlive.com>
+;; Package-Version: 20250812.1408
+;; Package-Revision: bb9d6b4b962f
+;; Package-Requires: ((emacs "24.3") (biblio-core "0.3"))
+;; Keywords: bib, tex, convenience, hypermedia
+;; URL: https://github.com/cpitclaudel/biblio.el
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; # biblio.el: An extensible Emacs package for browsing and fetching references
+;;
+;; biblio.el makes it easy to browse and gather bibliographic references and
+;; publications from various sources, by keywords or by DOI. References are
+;; automatically fetched from well-curated sources, and formatted as BibTeX.
+;;
+;; ## Supported sources:
+;;
+;; * ‘CrossRef’, an exhaustive academic search engine (recommended)
+;; * ‘arXiv’, an archive of pre-prints in various scientific fields
+;; * ‘DBLP’, a database of Computer Science publications
+;; * ‘HAL’, a French repository of Open Access publications
+;; * ‘doi.org’, a DOI resolver (to retrieve BibTeX records from DOIs)
+;; * ‘CrossCite’, an alternative DOI resolver and BibTeX formatting service
+;; * ‘Dissemin’, a database tracking the open access status of scholarly articles
+;;
+;; ## Usage
+;;
+;; Quick start: ‘M-x biblio-lookup’. Each source can also be accessed independently:
+;;
+;; * ‘M-x crossref-lookup’ to query CrossRef
+;; * ‘M-x arxiv-lookup` to query arXiv
+;; * `M-x dblp-lookup’ to query DBLP
+;; * ‘M-x doi-insert’ to insert a BibTeX record by DOI
+;; * ‘M-x dissemin-lookup’ to show information about the open access status of a
+;; particular DOI
+;;
+;; Most of these commands work together: for example, ‘crossref-lookup’ displays a
+;; list of results in ‘biblio-selection-mode’. In that mode, use:
+;;
+;; * ‘RET’ to visit the corresponding web page
+;; * ‘c’ or ‘M-w’ to copy the BibTeX record of the current entry
+;; * ‘i’ or ‘C-y’ to insert the BibTeX record of the current entry
+;; * ‘x’ to run an extended action, such as fetching a Dissemin record
+;;
+;; ‘C’ and ‘I’ do the same as ‘c’ and ‘i’, but additionally close the search window.
+;;
+;; ## Examples
+;;
+;; * To insert a clean BibTeX entry for https://doi.org/10.1145/2676726.2677006
+;; in the current buffer, use
+;;
+;; M-x crossref-lookup RET fiat deductive delaware RET i
+;;
+;; (the last ‘i’ inserts the BibTeX record of the currently selected entry in
+;; your buffer).
+;;
+;; * To find publications by computer scientist Leslie Lamport, use ‘M-x
+;; dblp-lookup RET author:Lamport RET’ (see more info about DBLP's syntax at
+;; <https://dblp.uni-trier.de/search/>)
+;;
+;; * To check whether an article is freely available online, use ‘x’ in the list
+;; of results. For example ‘M-x crossref-lookup RET Emacs stallman RET’
+;; followed by ‘x Dissemin RET’ will help you find open access copies of
+;; Stallman's paper on EMACS (spoiler: https://hdl.handle.net/1721.1/5736).
+;;
+;; See https://github.com/cpitclaudel/biblio.el for more information, including
+;; documentation on extending this framework.
+
+;;; Code:
+
+(require 'biblio-core)
+(require 'biblio-doi)
+(require 'biblio-arxiv)
+(require 'biblio-crossref)
+(require 'biblio-dblp)
+(require 'biblio-hal)
+(require 'biblio-ieee)
+(require 'biblio-dissemin)
+(require 'biblio-download)
+
+(provide 'biblio)
+;;; biblio.el ends here