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.

5
  • 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
    Commented Feb 23, 2018 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
    Commented Feb 23, 2018 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
    Commented Feb 23, 2018 at 23:23
  • @ChristianHupfer I added a concrete example. I hope this clarifies my question.
    – omar
    Commented Feb 23, 2018 at 23:29
  • That's not compilable
    – user31729
    Commented Feb 23, 2018 at 23:33

3 Answers 3

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}
3
  • The cleveref package defines a \namecref and a \labelcref commands... Commented Feb 24, 2018 at 12:11
  • @HugoRaguet: Yes, but they are not expandable...
    – user31729
    Commented Feb 24, 2018 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. Commented Feb 24, 2018 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

4
  • Thanks for your answer. Unfortunately your command always prints theorem (it doesn't read the "theorem" from cref package)
    – omar
    Commented Feb 24, 2018 at 0:03
  • 1
    @omar I can answer what you ask, not what you don't. However, I polished my crystal ball…
    – egreg
    Commented Feb 24, 2018 at 0:13
  • Thanks. Your crystal ball is quite elegant. It does exactly what I want.
    – omar
    Commented Feb 24, 2018 at 0:25
  • 2
    @omar 🔮 🙂 🦆🦆
    – egreg
    Commented Feb 24, 2018 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}}
}
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
    Commented Feb 24, 2018 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. Commented Feb 24, 2018 at 16:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .