aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArash Esbati2022-08-08 15:58:35 +0200
committerArash Esbati2022-08-08 16:02:18 +0200
commit7331ee112c107caaece87db9f65751f9cbcc01c3 (patch)
tree80483161ebf0f2dfd246f307cf43468e6ad9bd0e
parent7f8a3d4e919e495fadb4eb6fae3f73556b987700 (diff)
downloademacs-7331ee112c107caaece87db9f65751f9cbcc01c3.tar.gz
emacs-7331ee112c107caaece87db9f65751f9cbcc01c3.zip
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.
-rw-r--r--lisp/textmodes/reftex-cite.el52
-rw-r--r--test/lisp/textmodes/reftex-tests.el135
2 files changed, 174 insertions, 13 deletions
diff --git a/lisp/textmodes/reftex-cite.el b/lisp/textmodes/reftex-cite.el
index 26b14ebc79e..f3f95627af1 100644
--- a/lisp/textmodes/reftex-cite.el
+++ b/lisp/textmodes/reftex-cite.el
@@ -1116,10 +1116,10 @@ recommended for follow mode. It works OK for individual lookups."
1116 (setq bibtype (reftex-bib-or-thebib)) 1116 (setq bibtype (reftex-bib-or-thebib))
1117 (cond 1117 (cond
1118 ((eq bibtype 'bib) 1118 ((eq bibtype 'bib)
1119; ((assq 'bib (symbol-value reftex-docstruct-symbol)) 1119 ;; ((assq 'bib (symbol-value reftex-docstruct-symbol))
1120 (setq bibfile-list (reftex-get-bibfile-list))) 1120 (setq bibfile-list (reftex-get-bibfile-list)))
1121 ((eq bibtype 'thebib) 1121 ((eq bibtype 'thebib)
1122; ((assq 'thebib (symbol-value reftex-docstruct-symbol)) 1122 ;; ((assq 'thebib (symbol-value reftex-docstruct-symbol))
1123 (setq bibfile-list 1123 (setq bibfile-list
1124 (reftex-uniquify 1124 (reftex-uniquify
1125 (mapcar #'cdr 1125 (mapcar #'cdr
@@ -1142,8 +1142,35 @@ recommended for follow mode. It works OK for individual lookups."
1142 1142
1143;;; Global BibTeX file 1143;;; Global BibTeX file
1144(defun reftex-all-used-citation-keys () 1144(defun reftex-all-used-citation-keys ()
1145 "Return a list of all citation keys used in document."
1145 (reftex-access-scan-info) 1146 (reftex-access-scan-info)
1146 (let ((files (reftex-all-document-files)) file keys kk k) 1147 ;; FIXME: multicites macros provided by biblatex
1148 ;; are not covered in this function.
1149 (let ((files (reftex-all-document-files))
1150 (re (concat "\\\\"
1151 "\\(?:"
1152 ;; biblatex volcite macros take these args:
1153 ;; \volcite[prenote]{volume}[pages]{key}
1154 ;; so cater for the first 3 args:
1155 (regexp-opt '("volcite" "Volcite"
1156 "pvolcite" "Pvolcite"
1157 "fvolcite" "ftvolcite"
1158 "svolcite" "Svolcite"
1159 "tvolcite" "Tvolcite"
1160 "avolcite" "Avolcite"))
1161 "\\(?:\\[[^]]*\\]\\)?"
1162 "{[^}]*}"
1163 "\\(?:\\[[^]]*\\]\\)?"
1164 "\\|"
1165 ;; Other cite macros usually go like:
1166 ;; \cite[prenote][postnote]{key}
1167 ;; so cater for the optional args:
1168 "\\(?:bibentry\\|[a-zA-Z]*[Cc]ite[a-zA-Z*]*\\)"
1169 "\\(?:\\[[^]]*\\]\\)\\{0,2\\}"
1170 "\\)"
1171 ;; Now match the key:
1172 "{\\([^}]+\\)}"))
1173 file keys kk k)
1147 (save-current-buffer 1174 (save-current-buffer
1148 (while (setq file (pop files)) 1175 (while (setq file (pop files))
1149 (set-buffer (reftex-get-file-buffer-force file 'mark)) 1176 (set-buffer (reftex-get-file-buffer-force file 'mark))
@@ -1151,14 +1178,17 @@ recommended for follow mode. It works OK for individual lookups."
1151 (save-restriction 1178 (save-restriction
1152 (widen) 1179 (widen)
1153 (goto-char (point-min)) 1180 (goto-char (point-min))
1154 (while (re-search-forward "\\(?:^\\|\\=\\)[^%\n\r]*?\\\\\\(bibentry\\|[a-zA-Z]*cite[a-zA-Z]*\\)\\(\\[[^]]*\\]\\)?{\\([^}]+\\)}" nil t) 1181 (while (re-search-forward re nil t)
1155 (setq kk (match-string-no-properties 3)) 1182 ;; Make sure we're not inside a comment:
1156 (while (string-match "%.*\n?" kk) 1183 (unless (save-match-data
1157 (setq kk (replace-match "" t t kk))) 1184 (nth 4 (syntax-ppss)))
1158 (setq kk (split-string kk "[, \t\r\n]+")) 1185 (setq kk (match-string-no-properties 1))
1159 (while (setq k (pop kk)) 1186 (while (string-match "%.*\n?" kk)
1160 (or (member k keys) 1187 (setq kk (replace-match "" t t kk)))
1161 (setq keys (cons k keys))))))))) 1188 (setq kk (split-string kk "[, \t\r\n]+"))
1189 (while (setq k (pop kk))
1190 (or (member k keys)
1191 (setq keys (cons k keys))))))))))
1162 (reftex-kill-temporary-buffers) 1192 (reftex-kill-temporary-buffers)
1163 keys)) 1193 keys))
1164 1194
diff --git a/test/lisp/textmodes/reftex-tests.el b/test/lisp/textmodes/reftex-tests.el
index 9ef41088d1e..97ff3908177 100644
--- a/test/lisp/textmodes/reftex-tests.el
+++ b/test/lisp/textmodes/reftex-tests.el
@@ -190,8 +190,8 @@
190 190
191(ert-deftest reftex-format-citation-test () 191(ert-deftest reftex-format-citation-test ()
192 "Test `reftex-format-citation'." 192 "Test `reftex-format-citation'."
193 (let ((entry (reftex-parse-bibtex-entry 193 (let ((entry (reftex-parse-bibtex-entry "\
194"@article{Foo13, 194@article{Foo13,
195 author = {Jane Roe and John Doe and Jane Q. Taxpayer}, 195 author = {Jane Roe and John Doe and Jane Q. Taxpayer},
196 title = {Some Article}, 196 title = {Some Article},
197 journal = {Some Journal}, 197 journal = {Some Journal},
@@ -202,6 +202,137 @@
202 (should (string= (reftex-format-citation entry "%l:%A:%y:%t %j %P %a") 202 (should (string= (reftex-format-citation entry "%l:%A:%y:%t %j %P %a")
203 "Foo13:Jane Roe:2013:Some Article Some Journal 1 Jane Roe, John Doe \\& Jane Taxpayer")))) 203 "Foo13:Jane Roe:2013:Some Article Some Journal 1 Jane Roe, John Doe \\& Jane Taxpayer"))))
204 204
205(ert-deftest reftex-all-used-citation-keys ()
206 "Test `reftex-all-used-citation-keys'.
207Take the cite macros provided by biblatex package as reference."
208 (ert-with-temp-directory temp-dir
209 (let ((tex-file (expand-file-name "keys.tex" temp-dir))
210 keys)
211 (with-temp-buffer
212 (insert "\
213\\documentclass{article}
214\\usepackage{biblatex}
215\\begin{document}
216
217Standard commands:
218\\cite[pre][pos]{cite:2022}
219\\Cite[pos]{Cite:2022}
220\\parencite{parencite:2022}
221\\Parencite[pre][]{Parencite:2022}
222\\footcite[][]{footcite:2022}
223\\footcitetext[pre][pos]{footcitetext:2022}
224
225Style specific commands:
226\\textcite{textcite:2022}
227\\Textcite[pos]{Textcite:2022}
228\\smartcite[pre][pos]{smartcite:2022}
229\\Smartcite[pre][]{Smartcite:2022}
230\\cite*[pre][pos]{cite*:2022}
231\\parencite*[][]{parencite*:2022}
232
233Style independent commands:
234\\autocite[pre][pos]{autocite:2022}
235\\autocite*[pos]{autocite*:2022}
236\\Autocite[pre][]{Autocite:2022}
237\\Autocite*{Autocite*:2022}
238
239Text commands:
240\\citeauthor[pre][pos]{citeauthor:2022}
241\\citeauthor*[pre][]{citeauthor*:2022}
242\\Citeauthor[pos]{Citeauthor:2022}
243\\Citeauthor*{Citeauthor*:2022}
244\\citetitle[][]{citetitle:2022}
245\\citetitle*[pre][pos]{citetitle*:2022}
246\\citeyear[pre][pos]{citeyear:2022}
247\\citeyear*[pre][pos]{citeyear*:2022}
248\\citedate[pre][pos]{citedate:2022}
249\\citedate*[pre][pos]{citedate*:2022}
250\\citeurl[pre][pos]{citeurl:2022}
251
252Special commands:
253\\nocite{nocite:2022}
254\\fullcite[pos]{fullcite:2022}
255\\footfullcite[][]{fullfootcite:2022}
256``volcite'' macros have different number of args.
257\\volcite{2}{volcite:2022}
258\\Volcite[pre]{1}{Volcite:2022}
259\\pvolcite{1}[pg]{pvolcite:2022}
260\\Pvolcite[pre]{2}[pg]{Pvolcite:2022}
261\\fvolcite[pre]{3}[pg]{fvolcite:2022}
262\\ftvolcite[pre]{3}[pg]{ftvolcite:2022}
263\\svolcite[pre]{2}[pg]{svolcite:2022}
264\\Svolcite[pre]{4}[pg]{Svolcite:2022}
265\\tvolcite[pre]{5}[pg]{tvolcite:2022}
266\\Tvolcite[pre]{2}[pg]{Tvolcite:2022}
267\\avolcite[pre]{3}[pg]{avolcite:2022}
268\\Avolcite[pre]{1}[pg]{Avolcite:2022}
269\\Notecite[pre]{Notecite:2022}
270\\pnotecite[pre]{pnotecite:2022}
271\\Pnotecite[pre]{Pnotecite:2022}
272\\fnotecite[pre]{fnotecite:2022}
273
274Natbib compatibility commands:
275\\citet{citet:2022}
276\\citet*[pre][pos]{citet*:2022}
277\\citep[pre][pos]{citep:2022}
278\\citep*[pos]{citep*:2022}
279\\citealt[pre][]{citealt:2022}
280\\citealt*[][]{citealt*:2022}
281\\citealp[pre][pos]{citealp:2022}
282\\citealp*{citealp*:2022}
283\\Citet[pre][pos]{Citet:2022}
284\\Citet*[pre][pos]{Citet*:2022}
285\\Citep[pre][pos]{Citep:2022}
286\\Citep*[pre][pos]{Citep*:2022}
287
288Test for bug#56655:
289There was a few \\% of increase in budget \\Citep*{bug:56655}.
290
291And this should be % \\cite{ignored}.
292\\end{document}")
293 (write-region (point-min) (point-max) tex-file))
294 (find-file tex-file)
295 (setq keys (reftex-all-used-citation-keys))
296 (should (equal (sort keys #'string<)
297 (sort '(;; Standard commands:
298 "cite:2022" "Cite:2022"
299 "parencite:2022" "Parencite:2022"
300 "footcite:2022" "footcitetext:2022"
301 ;; Style specific commands:
302 "textcite:2022" "Textcite:2022"
303 "smartcite:2022" "Smartcite:2022"
304 "cite*:2022" "parencite*:2022"
305 ;; Style independent commands:
306 "autocite:2022" "autocite*:2022"
307 "Autocite:2022" "Autocite*:2022"
308 ;; Text commands
309 "citeauthor:2022" "citeauthor*:2022"
310 "Citeauthor:2022" "Citeauthor*:2022"
311 "citetitle:2022" "citetitle*:2022"
312 "citeyear:2022" "citeyear*:2022"
313 "citedate:2022" "citedate*:2022"
314 "citeurl:2022"
315 ;; Special commands:
316 "nocite:2022" "fullcite:2022"
317 "fullfootcite:2022"
318 "volcite:2022" "Volcite:2022"
319 "pvolcite:2022" "Pvolcite:2022"
320 "fvolcite:2022" "ftvolcite:2022"
321 "svolcite:2022" "Svolcite:2022"
322 "tvolcite:2022" "Tvolcite:2022"
323 "avolcite:2022" "Avolcite:2022"
324 "Notecite:2022" "pnotecite:2022"
325 "Pnotecite:2022" "fnotecite:2022"
326 ;; Natbib compatibility commands:
327 "citet:2022" "citet*:2022"
328 "citep:2022" "citep*:2022"
329 "citealt:2022" "citealt*:2022"
330 "citealp:2022" "citealp*:2022"
331 "Citet:2022" "Citet*:2022"
332 "Citep:2022" "Citep*:2022"
333 "bug:56655")
334 #'string<)))
335 (kill-buffer (file-name-nondirectory tex-file)))))
205 336
206;;; Autoload tests 337;;; Autoload tests
207 338