1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-15 10:30:25 -08:00

Improve collecting of citation keys

* lisp/textmodes/reftex-cite.el (reftex-all-used-citation-keys):
Improve regexp for matching various cite commands incl. optional
arguments.
Recognize comments more robustly and don't interpret the control
symbol \% as a comment starter.  (bug#56655)

* test/lisp/textmodes/reftex-tests.el
(reftex-all-used-citation-keys): New test.
This commit is contained in:
Arash Esbati 2022-08-08 15:58:35 +02:00
parent 7f8a3d4e91
commit 7331ee112c
2 changed files with 174 additions and 13 deletions

View file

@ -1116,10 +1116,10 @@ recommended for follow mode. It works OK for individual lookups."
(setq bibtype (reftex-bib-or-thebib))
(cond
((eq bibtype 'bib)
; ((assq 'bib (symbol-value reftex-docstruct-symbol))
;; ((assq 'bib (symbol-value reftex-docstruct-symbol))
(setq bibfile-list (reftex-get-bibfile-list)))
((eq bibtype 'thebib)
; ((assq 'thebib (symbol-value reftex-docstruct-symbol))
;; ((assq 'thebib (symbol-value reftex-docstruct-symbol))
(setq bibfile-list
(reftex-uniquify
(mapcar #'cdr
@ -1142,8 +1142,35 @@ recommended for follow mode. It works OK for individual lookups."
;;; Global BibTeX file
(defun reftex-all-used-citation-keys ()
"Return a list of all citation keys used in document."
(reftex-access-scan-info)
(let ((files (reftex-all-document-files)) file keys kk k)
;; FIXME: multicites macros provided by biblatex
;; are not covered in this function.
(let ((files (reftex-all-document-files))
(re (concat "\\\\"
"\\(?:"
;; biblatex volcite macros take these args:
;; \volcite[prenote]{volume}[pages]{key}
;; so cater for the first 3 args:
(regexp-opt '("volcite" "Volcite"
"pvolcite" "Pvolcite"
"fvolcite" "ftvolcite"
"svolcite" "Svolcite"
"tvolcite" "Tvolcite"
"avolcite" "Avolcite"))
"\\(?:\\[[^]]*\\]\\)?"
"{[^}]*}"
"\\(?:\\[[^]]*\\]\\)?"
"\\|"
;; Other cite macros usually go like:
;; \cite[prenote][postnote]{key}
;; so cater for the optional args:
"\\(?:bibentry\\|[a-zA-Z]*[Cc]ite[a-zA-Z*]*\\)"
"\\(?:\\[[^]]*\\]\\)\\{0,2\\}"
"\\)"
;; Now match the key:
"{\\([^}]+\\)}"))
file keys kk k)
(save-current-buffer
(while (setq file (pop files))
(set-buffer (reftex-get-file-buffer-force file 'mark))
@ -1151,14 +1178,17 @@ recommended for follow mode. It works OK for individual lookups."
(save-restriction
(widen)
(goto-char (point-min))
(while (re-search-forward "\\(?:^\\|\\=\\)[^%\n\r]*?\\\\\\(bibentry\\|[a-zA-Z]*cite[a-zA-Z]*\\)\\(\\[[^]]*\\]\\)?{\\([^}]+\\)}" nil t)
(setq kk (match-string-no-properties 3))
(while (string-match "%.*\n?" kk)
(setq kk (replace-match "" t t kk)))
(setq kk (split-string kk "[, \t\r\n]+"))
(while (setq k (pop kk))
(or (member k keys)
(setq keys (cons k keys)))))))))
(while (re-search-forward re nil t)
;; Make sure we're not inside a comment:
(unless (save-match-data
(nth 4 (syntax-ppss)))
(setq kk (match-string-no-properties 1))
(while (string-match "%.*\n?" kk)
(setq kk (replace-match "" t t kk)))
(setq kk (split-string kk "[, \t\r\n]+"))
(while (setq k (pop kk))
(or (member k keys)
(setq keys (cons k keys))))))))))
(reftex-kill-temporary-buffers)
keys))