You have many questions here so I try to stay brief. I presume that you have these lines in your init file:
(add-hook 'LaTeX-mode-hook #'turn-on-reftex)
(setq reftex-plug-into-AUCTeX t)
1 - What would be the normal way (that is, considering default configuration) to add one such command?
RefTeX provides the variable reftex-cite-format
. You can use it for custom query when you hit C-c [. With AUCTeX, you have to set LaTeX-reftex-cite-format-auto-activate
to nil
when setting reftex-cite-format
. In your case, try:
(setq LaTeX-reftex-cite-format-auto-activate nil)
(setq reftex-cite-format
'((?\C-m . "\\cite[][]{%l}")
(?s . "\\cites[][]{%l}")
(?p . "\\parencites[][]{%l}")
(?P . "\\Parencites[][]{%l}")))
in your init file. But I find the input interface in the document cumbersome: You have to do C-c [, s, go through the regex query, mark each entry and hit A. But that's a matter of taste.
2 - How to make these commands recognized by RefTeX, so that reftex-view-crossref works and new keys can be added with RefTeX facilities after the citation command has already been inserted?
This is the tricky part. You have to patch the functions reftex-figure-out-cite-format
and reftex-view-crossref
. Put this in your init file and restart Emacs; the original string-match
lines are commented for your reference:
(with-eval-after-load "reftex-cite"
(defun reftex-figure-out-cite-format (arg &optional no-insert format-key)
"Check if there is already a cite command at point and change cite format
in order to only add another reference in the same cite command."
(let ((macro (car (reftex-what-macro 1)))
(cite-format-value (reftex-get-cite-format))
key format)
(cond
(no-insert
;; Format does not really matter because nothing will be inserted.
(setq format "%l"))
((and (stringp macro)
;; (string-match "\\`\\\\cite\\|cite\\'" macro))
(string-match "\\`\\\\cite\\|cite\\(?:[s*]\\|texts?\\)?\\'" macro))
;; We are already inside a cite macro
(if (or (not arg) (not (listp arg)))
(setq format
(concat
(if (member (preceding-char) '(?\{ ?,))
""
reftex-cite-key-separator)
"%l"
(if (member (following-char) '(?\} ?,))
""
reftex-cite-key-separator)))
(setq format "%l")))
(t
;; Figure out the correct format
(setq format
(if (and (symbolp cite-format-value)
(assq cite-format-value reftex-cite-format-builtin))
(nth 2 (assq cite-format-value reftex-cite-format-builtin))
cite-format-value))
(when (listp format)
(setq key
(or format-key
(reftex-select-with-char
"" (concat "SELECT A CITATION FORMAT\n\n"
(mapconcat
(lambda (x)
(format "[%c] %s %s" (car x)
(if (> (car x) 31) " " "")
(cdr x)))
format "\n")))))
(if (assq key format)
(setq format (cdr (assq key format)))
(error "No citation format associated with key `%c'" key)))))
format)) )
(with-eval-after-load "reftex-dcr"
(defun reftex-view-crossref (&optional arg auto-how fail-quietly)
"View cross reference of macro at point. Point must be on the KEY
argument. When at a `\\ref' macro, show corresponding `\\label'
definition, also in external documents (`xr'). When on a label, show
a locations where KEY is referenced. Subsequent calls find additional
locations. When on a `\\cite', show the associated `\\bibitem' macro or
the BibTeX database entry. When on a `\\bibitem', show a `\\cite' macro
which uses this KEY. When on an `\\index', show other locations marked
by the same index entry.
To define additional cross referencing items, use the option
`reftex-view-crossref-extra'. See also `reftex-view-crossref-from-bibtex'.
With one or two C-u prefixes, enforce rescanning of the document.
With argument 2, select the window showing the cross reference.
AUTO-HOW is only for the automatic crossref display and is handed through
to the functions `reftex-view-cr-cite' and `reftex-view-cr-ref'."
(interactive "P")
;; See where we are.
(let* ((macro (car (reftex-what-macro-safe 1)))
(key (reftex-this-word "^{}%\n\r, \t"))
dw)
(if (or (null macro) (reftex-in-comment))
(or fail-quietly
(error "Not on a crossref macro argument"))
(setq reftex-call-back-to-this-buffer (current-buffer))
(cond
;; ((string-match "\\`\\\\cite\\|cite\\*?\\'\\|bibentry" macro)
((string-match "\\`\\\\cite\\|cite\\(?:[s*]\\|texts?\\)?\\'\\|bibentry" macro)
;; A citation macro: search for bibitems or BibTeX entries
(setq dw (reftex-view-cr-cite arg key auto-how)))
((string-match "\\`\\\\ref\\|ref\\(range\\)?\\*?\\'" macro)
;; A reference macro: search for labels
(setq dw (reftex-view-cr-ref arg key auto-how)))
(auto-how nil) ;; No further action for automatic display (speed)
((or (equal macro "\\label")
(member macro reftex-macros-with-labels))
;; A label macro: search for reference macros
(reftex-access-scan-info arg)
(setq dw (reftex-view-regexp-match
(format reftex-find-reference-format (regexp-quote key))
4 nil nil)))
((equal macro "\\bibitem")
;; A bibitem macro: search for citations
(reftex-access-scan-info arg)
(setq dw (reftex-view-regexp-match
(format reftex-find-citation-regexp-format (regexp-quote key))
4 nil nil)))
((member macro reftex-macros-with-index)
(reftex-access-scan-info arg)
(setq dw (reftex-view-regexp-match
(format reftex-find-index-entry-regexp-format
(regexp-quote key))
3 nil nil)))
(t
(reftex-access-scan-info arg)
(catch 'exit
(let ((list reftex-view-crossref-extra)
entry mre action group)
(while (setq entry (pop list))
(setq mre (car entry)
action (nth 1 entry)
group (nth 2 entry))
(when (string-match mre macro)
(setq dw (reftex-view-regexp-match
(format action key) group nil nil))
(throw 'exit t))))
(error "Not on a crossref macro argument"))))
(if (and (eq arg 2) (windowp dw)) (select-window dw))))) )
I tried this with this file and you see where it works and where not:
\documentclass{article}
\begin{filecontents}{biblatex-bib.bib}
@book{lamp:94,
author = {Leslie Lamport},
title = {LaTeX - {A} Document Preparation System: User's Guide
and Reference Manual, Second Edition},
publisher = {Pearson / Prentice Hall},
year = {1994},
isbn = {978-0-201-52983-8},
timestamp = {Fri, 08 Apr 2011 18:21:00 +0200},
}
@book{mitt:97,
author = {Michel Goossens and
Sebastian Rahtz and
Frank Mittelbach},
title = {The LaTeX Graphics Companion - Illustrating documents
with TeX and PostScript},
series = {Addison-Wesley series on tools and techniques
for computer typesetting},
publisher = {Addison-Wesley},
year = {1997},
isbn = {978-0-201-85469-5},
}
\end{filecontents}
\usepackage[style=authoryear]{biblatex}
\addbibresource{biblatex-bib.bib}
\begin{document}
%% =============== RefTeX standard
\cite{mitt:97}
==> \verb|C-c &| Ok, \verb|C-c [| Ok
\cites[Pre][Post]{mitt:97}[Pre][Post]{lamp:94}
==> \verb|C-c &| Ok, \verb|C-c [| Ok
\footcitetext[Pre][Post]{mitt:97}
==> \verb|C-c &| NOk, \verb|C-c [| NOk
\parencite*[Pre][Post]{mitt:97}
==> \verb|C-c &| Ok, \verb|C-c [| NOk
\parencites{mitt:97}
\parencites(GPre)()[Pre][]{mitt:97}[Pre][]{lamp:94}
\parencites(pre)()[pre][]{mitt:97}
\parencites(post)[post]{mitt:97}
==> \verb|C-c &| NOk, \verb|C-c [| NOk
%% ============== RefTeX patched
\parencites[Pre][Post]{mitt:97}[Pre][Post]{lamp:94}
==> \verb|C-c &| Ok, \verb|C-c [| Ok
\parencites(GPre)(GPost)[Pre][Post]{mitt:97}[Pre][Post]{lamp:94}
==> \verb|C-c &| NOk, \verb|C-c [| NOk
\end{document}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End:
The patches don't work when global optional arguments in ()
are present. Therefore, you have to patch the function reftex-what-macro
as well; but that would be beyond tex.sx. Please drop a line to [email protected]
. These issue should be fixed in Emacs 27.
3 - How to add, e.g. \cites
to RefTeX menu on the call to C-c [?
Check point 1.
4 - How to make fontification work for all the keys of a multicite command?
I'm afraid this is a "won't fix". Fontification is done by font-latex.el
shipped with AUCTeX which in general can only fontify fixed number of arguments.
\cites
or\Cites
but the behavior described above holds for\textcites
,\parencites
,\footcites
or\autocites
.