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)
This commit is contained in:
2026-02-25 13:07:05 +01:00
parent 4ea1b2be54
commit 12deb16152

View File

@@ -1809,28 +1809,31 @@ Skip for beamer exports — beamer uses adjustbox on plain tabular."
;;; ============================================================ ;;; ============================================================
;;; BIBLIOGRAPHY — citar + biblio + org-cite ;;; BIBLIOGRAPHY — citar + biblio + org-cite
;;; ============================================================ ;;; ============================================================
;; Workflow: ;; Global .bib: ~/org/references.bib (always available)
;; 1. SPC b s → search CrossRef/DBLP/arXiv by author/title/DOI ;; Per-project: add #+BIBLIOGRAPHY: ./refs.bib in org file header
;; 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
;; ;;
;; Files: ;; Workflow:
;; ~/org/references.bib — master bibliography (auto-created if missing) ;; SPC B n → create new .bib (prompted for path)
;; ~/org/notes/ — reading notes per reference ;; SPC B s → search CrossRef → in results press 'i' to save to .bib
;; ~/org/papers/ — PDF library (optional) ;; 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 (after! citar
(setq citar-bibliography '("~/org/references.bib") (setq! citar-bibliography '("~/org/references.bib"))
citar-notes-paths '("~/org/notes/") (setq! citar-notes-paths '("~/org/notes/"))
citar-library-paths '("~/org/papers/")) (setq! citar-library-paths '("~/org/papers/"))
;; Ensure references.bib exists ;; Auto-create global .bib if missing
(let ((bib (expand-file-name "~/org/references.bib"))) (let ((bib (expand-file-name "~/org/references.bib")))
(unless (file-exists-p 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 (after! oc
(require 'citeproc) (require 'citeproc)
(setq org-cite-global-bibliography '("~/org/references.bib") (setq org-cite-global-bibliography '("~/org/references.bib")
@@ -1838,7 +1841,7 @@ Skip for beamer exports — beamer uses adjustbox on plain tabular."
(html csl) (html csl)
(t csl)))) (t csl))))
;; biblio.el: search and import references from online databases ;; biblio.el: polite CrossRef access (required by their API policy)
(after! biblio (after! biblio
(setq biblio-crossref-user-email-address "martin@sukany.cz")) (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-titleword-length 5
bibtex-autokey-titlewords 3) 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 (map! :leader
(:prefix ("B" . "bibliography") (:prefix ("B" . "bibliography")
:desc "Browse references" "b" #'citar-open :desc "Browse references" "b" #'citar-open
:desc "Insert citation" "i" #'citar-insert-citation :desc "Insert citation" "i" #'citar-insert-citation
:desc "Open notes for reference" "n" #'citar-open-notes :desc "Open notes for reference" "n" #'citar-open-notes
:desc "Refresh bibliography" "r" #'citar-refresh :desc "Refresh bibliography" "r" #'citar-refresh
:desc "New .bib file" "N" #'my/bib-new
:desc "Search CrossRef" "s" #'biblio-crossref-lookup :desc "Search CrossRef" "s" #'biblio-crossref-lookup
:desc "Search arXiv" "a" #'biblio-arxiv-lookup :desc "Search arXiv" "a" #'biblio-arxiv-lookup
:desc "Search DBLP" "d" #'biblio-dblp-lookup :desc "Search DBLP" "d" #'biblio-dblp-lookup
:desc "Import DOI → bib" "D" #'biblio-doi-insert-bibtex :desc "Import from DOI" "D" #'my/bib-import-doi
:desc "Open .bib file" "f" (cmd! (find-file (car citar-bibliography))))) :desc "Open global .bib" "f" (cmd! (find-file (expand-file-name "~/org/references.bib")))))
;;; ============================================================ ;;; ============================================================