From 12deb16152ad01dbca2abf38e905ed4ce0108f97 Mon Sep 17 00:00:00 2001 From: Daneel Date: Wed, 25 Feb 2026 13:07:05 +0100 Subject: [PATCH] bibliography: setq! for citar, new/import helpers, per-project support - setq! for citar-bibliography (Doom custom setter, fixes void variable) - my/bib-new: create new .bib for a project - my/bib-import-doi: import reference by DOI - Per-project: .dir-locals.el or #+BIBLIOGRAPHY: in org header - SPC B prefix (not SPC b which is buffer) --- config.el | 65 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 18 deletions(-) diff --git a/config.el b/config.el index a1c855f..1e999a6 100644 --- a/config.el +++ b/config.el @@ -1809,28 +1809,31 @@ Skip for beamer exports — beamer uses adjustbox on plain tabular." ;;; ============================================================ ;;; BIBLIOGRAPHY — citar + biblio + org-cite ;;; ============================================================ -;; Workflow: -;; 1. SPC b s → search CrossRef/DBLP/arXiv by author/title/DOI -;; 2. In results: select entry → i = insert into references.bib -;; 3. In org file: SPC b i → search your .bib → insert [cite:@key] -;; 4. Export to PDF: citations auto-formatted, bibliography generated +;; Global .bib: ~/org/references.bib (always available) +;; Per-project: add #+BIBLIOGRAPHY: ./refs.bib in org file header ;; -;; Files: -;; ~/org/references.bib — master bibliography (auto-created if missing) -;; ~/org/notes/ — reading notes per reference -;; ~/org/papers/ — PDF library (optional) +;; Workflow: +;; SPC B n → create new .bib (prompted for path) +;; SPC B s → search CrossRef → in results press 'i' to save to .bib +;; SPC B i → insert citation in org file +;; Export: org-cite + CSL auto-formats references +;; +;; Per-project setup: put .dir-locals.el in project root: +;; ((org-mode . ((citar-bibliography . ("./refs.bib"))))) +;; Global bibliography paths (setq! required for Doom's custom setter) (after! citar - (setq citar-bibliography '("~/org/references.bib") - citar-notes-paths '("~/org/notes/") - citar-library-paths '("~/org/papers/")) + (setq! citar-bibliography '("~/org/references.bib")) + (setq! citar-notes-paths '("~/org/notes/")) + (setq! citar-library-paths '("~/org/papers/")) - ;; Ensure references.bib exists + ;; Auto-create global .bib if missing (let ((bib (expand-file-name "~/org/references.bib"))) (unless (file-exists-p bib) - (with-temp-file bib (insert "% Bibliography — managed via citar + biblio\n\n"))))) + (make-directory (file-name-directory bib) t) + (with-temp-file bib (insert "% Global bibliography\n\n"))))) -;; org-cite: use CSL processor (no BibLaTeX/BibTeX toolchain needed) +;; org-cite: CSL processor (no BibLaTeX toolchain needed) (after! oc (require 'citeproc) (setq org-cite-global-bibliography '("~/org/references.bib") @@ -1838,7 +1841,7 @@ Skip for beamer exports — beamer uses adjustbox on plain tabular." (html csl) (t csl)))) -;; biblio.el: search and import references from online databases +;; biblio.el: polite CrossRef access (required by their API policy) (after! biblio (setq biblio-crossref-user-email-address "martin@sukany.cz")) @@ -1850,17 +1853,43 @@ Skip for beamer exports — beamer uses adjustbox on plain tabular." bibtex-autokey-titleword-length 5 bibtex-autokey-titlewords 3) +;; Helper: create new .bib file for a project +(defun my/bib-new () + "Create a new .bib file at prompted path." + (interactive) + (let ((path (read-file-name "New .bib file: " default-directory nil nil "refs.bib"))) + (unless (file-exists-p path) + (make-directory (file-name-directory path) t) + (with-temp-file path + (insert (format "%% Bibliography: %s\n\n" (file-name-nondirectory path))))) + (find-file path) + (message "Created %s — add #+BIBLIOGRAPHY: %s to your org file" path path))) + +;; Helper: import from DOI (prompts for DOI, appends to current/global .bib) +(defun my/bib-import-doi () + "Fetch BibTeX for a DOI and append to the current .bib or global references.bib." + (interactive) + (require 'biblio-doi) + (let* ((doi (read-string "DOI (e.g. 10.1145/2898442.2898444): ")) + (target (if (and buffer-file-name + (string-suffix-p ".bib" buffer-file-name)) + buffer-file-name + (car (ensure-list citar-bibliography))))) + (biblio-doi-insert-bibtex doi) + (message "Imported DOI %s" doi))) + (map! :leader (:prefix ("B" . "bibliography") :desc "Browse references" "b" #'citar-open :desc "Insert citation" "i" #'citar-insert-citation :desc "Open notes for reference" "n" #'citar-open-notes :desc "Refresh bibliography" "r" #'citar-refresh + :desc "New .bib file" "N" #'my/bib-new :desc "Search CrossRef" "s" #'biblio-crossref-lookup :desc "Search arXiv" "a" #'biblio-arxiv-lookup :desc "Search DBLP" "d" #'biblio-dblp-lookup - :desc "Import DOI → bib" "D" #'biblio-doi-insert-bibtex - :desc "Open .bib file" "f" (cmd! (find-file (car citar-bibliography))))) + :desc "Import from DOI" "D" #'my/bib-import-doi + :desc "Open global .bib" "f" (cmd! (find-file (expand-file-name "~/org/references.bib"))))) ;;; ============================================================