3

What would be the easiest way to accomplish the following? I want a single command, say \vcref, which automatically becomes \citet if all of its arguments are in the list of references and otherwise becomes \cref. No you don't want to do this comments please. Thanks!

\documentclass{article}

\usepackage{natbib}
\usepackage{cleveref}
\bibliographystyle{whateverstyle}

\begin{document}
\bibliography{refcite}
\begin{equation} \label{myeq}
 y=x
\end{equation}
\citet{ugh} found that \cref{myeq} can hold.
\end{document}
Joseph Wright
  • 259,911
  • 34
  • 706
  • 1,036
JPi
  • 13,595

1 Answers1

5

I'm a proponent of addressing "should" after "could". You could go the other way (check if any of the arguments is a label, as defined by r@key) fairly easily:

\documentclass{article}
\usepackage{natbib}
\bibliographystyle{whateverstyle}

\usepackage{etoolbox}
\usepackage{amsmath}
\usepackage{hyperref}
\usepackage{cleveref}
\usepackage{autonum}        

\makeatletter
    \def\omniref{\@ifnextchar[{\citet}{\@ifstar{\citet}{\omni@ref}}}
    \def\omni@ref#1{%
        \newif\iflbl\lblfalse
        \def\do##1{\@ifundefined{r@##1}{}{\lbltrue}}%
        \docsvlist{#1}%
        \iflbl\cref{#1}\else\citet{#1}\fi}
    \AtBeginDocument{\@ifpackageloaded{autonum}{\autonum@generatePatchedReferenceCSL{omniref}}{}}
\makeatother

%

\begin{document}
\bibliography{refcite}
\begin{equation}\label{aeqn}
 y=x
\end{equation}
\omniref{vanLoosdrecht99} found that \omniref{aeqn,eqn2} can hold.

\begin{equation}\label{eqn2}
 y=x
\end{equation}

\begin{thebibliography}{1}

\bibitem[{van Loosdrecht and Henze(1999)}]{vanLoosdrecht99}
van Loosdrecht, M. C.~M., Henze, M., 1999. Maintenance, endogeneous
  respiration, lysis, decay and predation. Water Science and Technology 39~(1),
  107--117.

\end{thebibliography}
\end{document}

Edit

Assuming the bibliography entries are defined as b@citekey, the approach you proposed is doable as well. If all of the entries are cited in the bibliography, the following will use \citet; if not \cref will be used:

\documentclass{article}
\usepackage{natbib}
\bibliographystyle{whateverstyle}

\usepackage{etoolbox}
\usepackage{amsmath}
\usepackage{hyperref}
\usepackage{cleveref}
\usepackage{autonum}        

\makeatletter
    \def\omniref{\@ifnextchar[{\citet}{\@ifstar{\citet}{\omni@ref}}}
    \def\omni@ref#1{%
        \newif\ifbib\bibtrue
        \def\do##1{\@ifundefined{b@##1}{\bibfalse}{}}%
        \docsvlist{#1}%
        \ifbib\citet{#1}\else\cref{#1}\fi}
    \AtBeginDocument{\@ifpackageloaded{autonum}{\autonum@generatePatchedReferenceCSL{omniref}}{}}
\makeatother

%

\begin{document}
\bibliography{refcite}
\begin{equation}\label{aeqn}
 y=x
\end{equation}
\omniref{vanLoosdrecht99} found that \omniref{aeqn,eqn2} can hold.

\begin{equation}\label{eqn2}
 y=x
\end{equation}

\begin{thebibliography}{1}

\bibitem[{van Loosdrecht and Henze(1999)}]{vanLoosdrecht99}
van Loosdrecht, M. C.~M., Henze, M., 1999. Maintenance, endogeneous
  respiration, lysis, decay and predation. Water Science and Technology 39~(1),
  107--117.

\end{thebibliography}
\end{document}


\end{document}

Yields:

example

As for the "should": Obviously this deviates from convention and may make interpreting errors more difficult. The biggest potential issue is if you have a label and a citation with the same key, which may result in unexpected behavior. However, if you are using sufficiently different naming conventions for labels and citations such that you would still be able to infer the intention of the command and eliminate overlap (e.g., eqn:somthing, fig:somethingelse and Doe98) and you are aware of the other potential issues, I'd say go for it.

Edit

Since \citet accepts options and has a starred variant but \cref does not, an additional line was added to each to differentiate the two (if \omniref is followed by a star or has options, the \citet is used, otherwise the keys are compared). Also, missing %s were added to remove the additional white space.

Edit

As per the comments below, added compatibility with hyperref and autonum.

Guho
  • 6,115
  • Awesome, thanks! (+1) I'm going to test this and will $\checkmark$ afterwards. The first solution would be fine. – JPi Oct 17 '15 at 20:35
  • Absolutely totally awesome! You should turn this into a package! (Yes, my labels are sufficiently distinct that there is no chance of confusing the two.) The only downside is that it breaks with hyperref :(. – JPi Oct 17 '15 at 20:42
  • But it seems to work if I load hyperref before cleveref. Hmmm. – JPi Oct 17 '15 at 20:54
  • 1
    cleveref is an exception to the "rule" of load hyperref last. – Guho Oct 17 '15 at 21:15
  • Thanks. Your first approach works better. It doesn't work with autonum, but that is to be expected. – JPi Oct 17 '15 at 21:22
  • Looks like it gets dicey with the required load order. You also need amsmath. Required order: amsmath, hyperref, cleveref, and autonum. Finally, \omniref has to be registered with autonum using the \autonum@generatePatchedReferenceCSL command. I'll edit the answer to include this. – Guho Oct 17 '15 at 21:51
  • phenomenal! How come you don't have 100k points? Again, ought to be a package. – JPi Oct 17 '15 at 22:22