pkg update and first config fix
org-brain not working, add org-roam
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
;;; oc-basic.el --- basic back-end for citations -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2021-2022 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Nicolas Goaziou <mail@nicolasgoaziou.fr>
|
||||
|
||||
@@ -66,6 +66,9 @@
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'org-macs)
|
||||
(org-assert-version)
|
||||
|
||||
(require 'bibtex)
|
||||
(require 'json)
|
||||
(require 'map)
|
||||
@@ -73,6 +76,7 @@
|
||||
(require 'seq)
|
||||
|
||||
(declare-function org-open-at-point "org" (&optional arg))
|
||||
(declare-function org-open-file "org" (path &optional in-emacs line search))
|
||||
|
||||
(declare-function org-element-interpret-data "org-element" (data))
|
||||
(declare-function org-element-property "org-element" (property element))
|
||||
@@ -178,21 +182,36 @@ Return a hash table with citation references as keys and fields alist as values.
|
||||
" and ")))
|
||||
('issued
|
||||
;; Date are expressed as an array
|
||||
;; (`date-parts') or a "string (`raw').
|
||||
;; In both cases, extract the year and
|
||||
;; associate it to `year' field, for
|
||||
;; compatibility with BibTeX format.
|
||||
;; (`date-parts') or a "string (`raw'
|
||||
;; or `literal'). In both cases,
|
||||
;; extract the year and associate it
|
||||
;; to `year' field, for compatibility
|
||||
;; with BibTeX format.
|
||||
(let ((date (or (alist-get 'date-parts value)
|
||||
(alist-get 'literal value)
|
||||
(alist-get 'raw value))))
|
||||
(cons 'year
|
||||
(cond
|
||||
((consp date)
|
||||
(caar date))
|
||||
(let ((year (caar date)))
|
||||
(cond
|
||||
((numberp year) (number-to-string year))
|
||||
((stringp year) year)
|
||||
(t
|
||||
(error
|
||||
"First element of CSL-JSON date-parts should be a number or string, got %s: %S"
|
||||
(type-of year) year)))))
|
||||
((stringp date)
|
||||
(car (split-string date "-")))
|
||||
(replace-regexp-in-string
|
||||
(rx
|
||||
(minimal-match (zero-or-more anything))
|
||||
(group-n 1 (repeat 4 digit))
|
||||
(zero-or-more anything))
|
||||
(rx (backref 1))
|
||||
date))
|
||||
(t
|
||||
(error "Unknown CSL-JSON date format: %S"
|
||||
date))))))
|
||||
value))))))
|
||||
(_
|
||||
(cons field value))))
|
||||
item)
|
||||
@@ -206,6 +225,10 @@ Return a hash table with citation references as keys and fields alist as values.
|
||||
(let ((entries (make-hash-table :test #'equal))
|
||||
(bibtex-sort-ignore-string-entries t))
|
||||
(bibtex-set-dialect dialect t)
|
||||
;; Throw an error if bibliography is malformed.
|
||||
(unless (bibtex-validate)
|
||||
(user-error "Malformed bibliography at %S"
|
||||
(or (buffer-file-name) (current-buffer))))
|
||||
(bibtex-map-entries
|
||||
(lambda (key &rest _)
|
||||
;; Normalize entries: field names are turned into symbols
|
||||
@@ -221,10 +244,16 @@ Return a hash table with citation references as keys and fields alist as values.
|
||||
(cons
|
||||
(intern (downcase field))
|
||||
(replace-regexp-in-string "[ \t\n]+" " " value)))))
|
||||
(bibtex-parse-entry t))
|
||||
;; Parse, substituting the @string replacements.
|
||||
;; See Emacs bug#56475 discussion.
|
||||
(let ((bibtex-string-files `(,(buffer-file-name)))
|
||||
(bibtex-expand-strings t))
|
||||
(bibtex-parse-entry t)))
|
||||
entries)))
|
||||
entries))
|
||||
|
||||
(defvar org-cite-basic--file-id-cache nil
|
||||
"Hash table linking files to their hash.")
|
||||
(defun org-cite-basic--parse-bibliography (&optional info)
|
||||
"List all entries available in the buffer.
|
||||
|
||||
@@ -237,27 +266,37 @@ table where keys are references and values are association lists between fields,
|
||||
as symbols, and values as strings or nil.
|
||||
|
||||
Optional argument INFO is the export state, as a property list."
|
||||
(unless (hash-table-p org-cite-basic--file-id-cache)
|
||||
(setq org-cite-basic--file-id-cache (make-hash-table :test #'equal)))
|
||||
(if (plist-member info :cite-basic/bibliography)
|
||||
(plist-get info :cite-basic/bibliography)
|
||||
(let ((results nil))
|
||||
(dolist (file (org-cite-list-bibliography-files))
|
||||
(when (file-readable-p file)
|
||||
(with-temp-buffer
|
||||
(insert-file-contents file)
|
||||
(let* ((file-id (cons file (org-buffer-hash)))
|
||||
(entries
|
||||
(or (cdr (assoc file-id org-cite-basic--bibliography-cache))
|
||||
(let ((table
|
||||
(pcase (file-name-extension file)
|
||||
("json" (org-cite-basic--parse-json))
|
||||
("bib" (org-cite-basic--parse-bibtex 'biblatex))
|
||||
("bibtex" (org-cite-basic--parse-bibtex 'BibTeX))
|
||||
(ext
|
||||
(user-error "Unknown bibliography extension: %S"
|
||||
ext)))))
|
||||
(push (cons file-id table) org-cite-basic--bibliography-cache)
|
||||
table))))
|
||||
(push (cons file entries) results)))))
|
||||
(when (or (org-file-has-changed-p file)
|
||||
(not (gethash file org-cite-basic--file-id-cache)))
|
||||
(insert-file-contents file)
|
||||
(set-visited-file-name file t)
|
||||
(puthash file (org-buffer-hash) org-cite-basic--file-id-cache))
|
||||
(condition-case nil
|
||||
(unwind-protect
|
||||
(let* ((file-id (cons file (gethash file org-cite-basic--file-id-cache)))
|
||||
(entries
|
||||
(or (cdr (assoc file-id org-cite-basic--bibliography-cache))
|
||||
(let ((table
|
||||
(pcase (file-name-extension file)
|
||||
("json" (org-cite-basic--parse-json))
|
||||
("bib" (org-cite-basic--parse-bibtex 'biblatex))
|
||||
("bibtex" (org-cite-basic--parse-bibtex 'BibTeX))
|
||||
(ext
|
||||
(user-error "Unknown bibliography extension: %S"
|
||||
ext)))))
|
||||
(push (cons file-id table) org-cite-basic--bibliography-cache)
|
||||
table))))
|
||||
(push (cons file entries) results))
|
||||
(set-visited-file-name nil t))
|
||||
(error (setq org-cite-basic--file-id-cache nil))))))
|
||||
(when info (plist-put info :cite-basic/bibliography results))
|
||||
results)))
|
||||
|
||||
@@ -310,6 +349,20 @@ non-nil."
|
||||
(org-export-raw-string value)
|
||||
value)))
|
||||
|
||||
(defun org-cite-basic--shorten-names (names)
|
||||
"Return a list of family names from a list of full NAMES.
|
||||
|
||||
To better accomomodate corporate names, this will only shorten
|
||||
personal names of the form \"family, given\"."
|
||||
(when (stringp names)
|
||||
(mapconcat
|
||||
(lambda (name)
|
||||
(if (eq 1 (length name))
|
||||
(cdr (split-string name))
|
||||
(car (split-string name ", "))))
|
||||
(split-string names " and ")
|
||||
", ")))
|
||||
|
||||
(defun org-cite-basic--number-to-suffix (n)
|
||||
"Compute suffix associated to number N.
|
||||
This is used for disambiguation."
|
||||
@@ -326,6 +379,17 @@ This is used for disambiguation."
|
||||
((= n 27) (throw :complete (cons 0 (cons 0 result))))
|
||||
(t nil))))))))
|
||||
|
||||
(defun org-cite-basic--get-author (entry-or-key &optional info raw)
|
||||
"Return author associated to ENTRY-OR-KEY.
|
||||
|
||||
ENTRY-OR-KEY, INFO and RAW arguments are the same arguments as
|
||||
used in `org-cite-basic--get-field', which see.
|
||||
|
||||
Author is obtained from the \"author\" field, if available, or
|
||||
from the \"editor\" field otherwise."
|
||||
(or (org-cite-basic--get-field 'author entry-or-key info raw)
|
||||
(org-cite-basic--get-field 'editor entry-or-key info raw)))
|
||||
|
||||
(defun org-cite-basic--get-year (entry-or-key info &optional no-suffix)
|
||||
"Return year associated to ENTRY-OR-KEY.
|
||||
|
||||
@@ -349,7 +413,7 @@ necessary, unless optional argument NO-SUFFIX is non-nil."
|
||||
;; KEY-SUFFIX-ALIST is an association (KEY . SUFFIX), where KEY is
|
||||
;; the cite key, as a string, and SUFFIX is the generated suffix
|
||||
;; string, or the empty string.
|
||||
(let* ((author (org-cite-basic--get-field 'author entry-or-key info 'raw))
|
||||
(let* ((author (org-cite-basic--get-author entry-or-key info 'raw))
|
||||
(year
|
||||
(or (org-cite-basic--get-field 'year entry-or-key info 'raw)
|
||||
(let ((date
|
||||
@@ -385,7 +449,7 @@ necessary, unless optional argument NO-SUFFIX is non-nil."
|
||||
"Format ENTRY according to STYLE string.
|
||||
ENTRY is an alist, as returned by `org-cite-basic--get-entry'.
|
||||
Optional argument INFO is the export state, as a property list."
|
||||
(let ((author (org-cite-basic--get-field 'author entry info))
|
||||
(let ((author (org-cite-basic--get-author entry info))
|
||||
(title (org-cite-basic--get-field 'title entry info))
|
||||
(from
|
||||
(or (org-cite-basic--get-field 'publisher entry info)
|
||||
@@ -396,7 +460,8 @@ Optional argument INFO is the export state, as a property list."
|
||||
("plain"
|
||||
(let ((year (org-cite-basic--get-year entry info 'no-suffix)))
|
||||
(org-cite-concat
|
||||
author ". " title (and from (list ", " from)) ", " year ".")))
|
||||
(org-cite-basic--shorten-names author) ". "
|
||||
title (and from (list ", " from)) ", " year ".")))
|
||||
("numeric"
|
||||
(let ((n (org-cite-basic--key-number (cdr (assq 'id entry)) info))
|
||||
(year (org-cite-basic--get-year entry info 'no-suffix)))
|
||||
@@ -437,12 +502,15 @@ substitutes for the unknown key. Finally, it may be the symbol
|
||||
(_
|
||||
(lambda ()
|
||||
(interactive)
|
||||
(setf (buffer-substring beg end)
|
||||
(concat "@"
|
||||
(if (= 1 (length suggestions))
|
||||
(car suggestions)
|
||||
(completing-read "Did you mean: "
|
||||
suggestions nil t))))))))
|
||||
(save-excursion
|
||||
(goto-char beg)
|
||||
(delete-region beg end)
|
||||
(insert
|
||||
"@"
|
||||
(if (= 1 (length suggestions))
|
||||
(car suggestions)
|
||||
(completing-read "Did you mean: "
|
||||
suggestions nil t))))))))
|
||||
(put-text-property beg end 'keymap km)))
|
||||
|
||||
(defun org-cite-basic-activate (citation)
|
||||
@@ -512,7 +580,7 @@ INFO is the export state, as a property list."
|
||||
(suffix (org-element-property :suffix ref)))
|
||||
(funcall format-ref
|
||||
prefix
|
||||
(org-cite-basic--get-field 'author k info)
|
||||
(org-cite-basic--get-author k info)
|
||||
(org-cite-basic--get-year k info)
|
||||
suffix)))
|
||||
(org-cite-get-references citation)
|
||||
@@ -551,7 +619,7 @@ INFO is the export state as a property list."
|
||||
INFO is the export state, as a property list."
|
||||
(and field
|
||||
(lambda (a b)
|
||||
(org-string-collate-lessp
|
||||
(string-collate-lessp
|
||||
(org-cite-basic--get-field field a info 'raw)
|
||||
(org-cite-basic--get-field field b info 'raw)
|
||||
nil t))))
|
||||
@@ -584,7 +652,7 @@ export communication channel, as a property list."
|
||||
(org-export-data
|
||||
(mapconcat
|
||||
(lambda (key)
|
||||
(let ((author (org-cite-basic--get-field 'author key info)))
|
||||
(let ((author (org-cite-basic--get-author key info)))
|
||||
(if caps (capitalize author) author)))
|
||||
(org-cite-get-references citation t)
|
||||
org-cite-basic-author-year-separator)
|
||||
@@ -645,15 +713,17 @@ KEYS is the list of cited keys, as strings. STYLE is the expected bibliography
|
||||
style, as a string. BACKEND is the export back-end, as a symbol. INFO is the
|
||||
export state, as a property list."
|
||||
(mapconcat
|
||||
(lambda (k)
|
||||
(let ((entry (org-cite-basic--get-entry k info)))
|
||||
(org-export-data
|
||||
(org-cite-make-paragraph
|
||||
(and (org-export-derived-backend-p backend 'latex)
|
||||
(org-export-raw-string "\\noindent\n"))
|
||||
(org-cite-basic--print-entry entry style info))
|
||||
info)))
|
||||
(org-cite-basic--sort-keys keys info)
|
||||
(lambda (entry)
|
||||
(org-export-data
|
||||
(org-cite-make-paragraph
|
||||
(and (org-export-derived-backend-p backend 'latex)
|
||||
(org-export-raw-string "\\noindent\n"))
|
||||
(org-cite-basic--print-entry entry style info))
|
||||
info))
|
||||
(delq nil
|
||||
(mapcar
|
||||
(lambda (k) (org-cite-basic--get-entry k info))
|
||||
(org-cite-basic--sort-keys keys info)))
|
||||
"\n"))
|
||||
|
||||
|
||||
@@ -719,19 +789,24 @@ Return nil if there are no bibliography files or no entries."
|
||||
(t
|
||||
(clrhash org-cite-basic--completion-cache)
|
||||
(dolist (key (org-cite-basic--all-keys))
|
||||
(let ((completion
|
||||
(concat
|
||||
(let ((author (org-cite-basic--get-field 'author key nil t)))
|
||||
(if author
|
||||
(truncate-string-to-width
|
||||
(replace-regexp-in-string " and " "; " author)
|
||||
org-cite-basic-author-column-end nil ?\s)
|
||||
(make-string org-cite-basic-author-column-end ?\s)))
|
||||
org-cite-basic-column-separator
|
||||
(let ((date (org-cite-basic--get-year key nil 'no-suffix)))
|
||||
(format "%4s" (or date "")))
|
||||
org-cite-basic-column-separator
|
||||
(org-cite-basic--get-field 'title key nil t))))
|
||||
(let* ((entry (org-cite-basic--get-entry
|
||||
key
|
||||
;; Supply pre-calculated bibliography to avoid
|
||||
;; performance degradation.
|
||||
(list :cite-basic/bibliography entries)))
|
||||
(completion
|
||||
(concat
|
||||
(let ((author (org-cite-basic--get-author entry nil 'raw)))
|
||||
(if author
|
||||
(truncate-string-to-width
|
||||
(replace-regexp-in-string " and " "; " author)
|
||||
org-cite-basic-author-column-end nil ?\s)
|
||||
(make-string org-cite-basic-author-column-end ?\s)))
|
||||
org-cite-basic-column-separator
|
||||
(let ((date (org-cite-basic--get-year entry nil 'no-suffix)))
|
||||
(format "%4s" (or date "")))
|
||||
org-cite-basic-column-separator
|
||||
(org-cite-basic--get-field 'title entry nil t))))
|
||||
(puthash completion key org-cite-basic--completion-cache)))
|
||||
(unless (map-empty-p org-cite-basic--completion-cache) ;no key
|
||||
(puthash entries t org-cite-basic--completion-cache)
|
||||
|
||||
Reference in New Issue
Block a user