3

Sorry if this question is a duplicate but I couldn't find a solution anywhere. I want to define a command with two arguments which does the following

\newcommand{ThecommandIwant}[2]{#1.\cref{#2}}

Now this doesn't produce what I want. For example it would produce #1.theorem/proposition the number corresponding to #2. Instead I want something that produces theorem/proposition #1.the number corresponding to #2.

Edit: #2 represents the label of the referred item (say a theorem). #1 will be something that I want to add eventually between "theorem" and the referred number. For example if \cref{#2} produces "theorem 1.2" I want my command to produce "theorem #1.1.2".

Here is an example

\usepackage{amsmath,cleveref}
%here I define my command called "ThecommandIwant"
\begin{document}
\begin{theorem}\label{a}
\end{theorem}
\begin{theorem}\label{b}
\end{theorem}
\ThecommandIwant{Train}{a} %prints theorem Train.1
\ThecommandIwant{Plane}{b} %prints theorem Plane.2
\end{document}

Thanks in advance.

  • 1
    Welcome to TeX.SE. The line of code (although) wrong) does not reveal what you really want to achieve. Please provide a compilable document. Perhaps it should be \newcommand{\ThecommandIwant}[2]{\cref{#1}.\ref{#2}} This depends on what #1 and #2 should represent, however? Apparently those are label names, but why two of them? – user31729 Feb 23 '18 at 23:17
  • @ChristianHupfer This wouldn't work. #2 represents the label of the referred item (say a theorem). #1 will be something that I want to add eventually between "theorem" and the referred number. For example if cref{#2} produces "theorem 1.2" I want my command to produce "theorem #1.1.2" – omar Feb 23 '18 at 23:21
  • 1
    Please provide the compilable document with a setup that shows what you want to achieve. At the moment, it is not clear – user31729 Feb 23 '18 at 23:23
  • @ChristianHupfer I added a concrete example. I hope this clarifies my question. – omar Feb 23 '18 at 23:29
  • That's not compilable – user31729 Feb 23 '18 at 23:33
4

enter image description here

I am not sure that this is possible with \crefformat or \creflabelformat from cleveref without heavy tricks at all, but I provide a solution with crossreftools, that extracts the information stored by cleveref to the .aux file and reconstructs the output according to the required output.

The underlying counter is auto-detected (!!!!) by \crtcrefcounter and handed over to \crtcrefname that prints the cross reference name according to the \crefname etc. settings.

The provided solution below is aware of linking if hyperref is used as well.

\documentclass{article}

\usepackage{amsthm}
\usepackage{hyperref}
\usepackage{cleveref}
\usepackage{crossreftools}

\newtheorem{theorem}{Theorem}

\makeatletter
\newcommand{\ThecommandIwant}[2]{%
  \@ifundefined{r@#2}{}{%
    \if@crt@hyperrefloaded
    \hyperlink{\crtrefanchor{#2}}{\crtcrefname{\crtcrefcounter{#2}} #1.\crtcrefnumber{#2}}%
    \else
    \crtcrefname{\crtcrefcounter{#2}} #1.\crtcrefnumber{#2}%
    \fi
  }%
}
\makeatother

\begin{document}

\begin{theorem}\label{a}
\end{theorem}

\clearpage
\begin{theorem}\label{b}
\end{theorem}

\clearpage
\ThecommandIwant{Train}{a} %prints theorem Train.1
\ThecommandIwant{Plane}{b} %prints theorem Plane.2

\end{document}
  • The cleveref package defines a \namecref and a \labelcref commands... – Hugo Raguet Feb 24 '18 at 12:11
  • @HugoRaguet: Yes, but they are not expandable... – user31729 Feb 24 '18 at 13:18
  • @ChristianHupfer: actually my poor knowledge of TeX is reached already. I do not know what expandable mean. But I can assure you that my answer below works well (now), at least on simple instances. – Hugo Raguet Feb 24 '18 at 16:32
3

With cleveref, define a suitable \crefformat.

\documentclass{article}
\usepackage{cleveref}

\makeatletter
\let\omarlabel\@gobble
\makeatother
\newcommand{\foo}[2]{%
  \begingroup
  \def\omarlabel{#1}%
  \cref{#2}%
  \endgroup
}
\crefdefaultlabelformat{#2\omarlabel.#1#3}

\newtheorem{theorem}{Theorem}

\begin{document}

\section{Test}\label{0}

\begin{theorem}\label{a}
\end{theorem}

\begin{theorem}\label{b}
\end{theorem}

\foo{Whatever}{0}

\foo{Train}{a} %prints theorem Train.1

\foo{Plane}{b} %prints theorem Plane.2

\cref{0}

\cref{a}

\cref{b}

\end{document}

The \omarlabel command, by default, gobbles the period, but \foo redefines it to be the stated additional label.

enter image description here

  • Thanks for your answer. Unfortunately your command always prints theorem (it doesn't read the "theorem" from cref package) – omar Feb 24 '18 at 0:03
  • 1
    @omar I can answer what you ask, not what you don't. However, I polished my crystal ball… – egreg Feb 24 '18 at 0:13
  • Thanks. Your crystal ball is quite elegant. It does exactly what I want. – omar Feb 24 '18 at 0:25
  • 2
    @omar 🔮 🙂 🦆🦆 – egreg Feb 24 '18 at 0:33
3

I find the answers of Christian Hupfer and egreg a bit complicated; the first needs an additional package, the second redefines all the labels, which is annoying. I propose simply

\newcommand*{\omaref}[2]{\namecref{#2}~#1.\labelcref{#2}}

or for better interaction with hyperref

\newcommand*{\omaref}[2]{%
    \hyperref[#2]{\namecref{#2}~#1.\labelcref*{#2}}
}
  • 1
    Did you try this? I get a warning about an undefined reference *, which is most likely from \namecref*, which is does not exist. \namecref*{#2} will try to use \namecref{*} basically -- this is not what is requested – user31729 Feb 24 '18 at 13:39
  • @ChristianHupfer: thank you, I accidentally let two typos in my answer. As you have pointed out the starred form of \namecref does not exist. I corrected it and it now works well. – Hugo Raguet Feb 24 '18 at 16:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.