6

Is it possible to save the expansion of \cref in a macro? My try

\documentclass{article}
\usepackage{cleveref}

\begin{document}
\section{This is a section}
\label{sec}

\edef\temp{\expandafter\empty\cref{sec}}
\show\temp

\end{document}

fails with some obscure errors.

  • 2
    To give some background info: can you tell use what you are trying to do with the macro? – user36296 Jul 20 '17 at 12:57
  • 1
    This can't work, but perhaps there are other methods. They might depend on the intended usage. – egreg Jul 20 '17 at 12:57
  • The main reason is that I have something like \section{Comments on \cref{other_section}} and I would like that the bookmark in the PDF is resolved to Comments on Section 3. – gerw Jul 20 '17 at 12:58
  • see tex.stackexchange.com/a/138950/36296 – user36296 Jul 20 '17 at 13:20
7

In order to leave the first answer unmixed with a much shorter way I provide a second solution with the \crtcref and \crtCref macros from my crossreftools package:

\documentclass{article}
\usepackage{cleveref}
\usepackage{crossreftools}

\begin{document}

\section{This is a section}
\label{sec}

\edef\temp{\crtcref{sec}}

\edef\Temp{\crtCref{sec}}


Content of reference: \temp\ or \Temp
\end{document}

Note that \cref or \Cref are not expandable, whereas \crtcref and \crtCref are expandable, hyperlinked versions however are not.

enter image description here

Current version of crossreftools is 0.9 (being uploaded to CTAN today (2019/01/03), the \crtcref etc. macros are from v0.1 however, v.0.9 contains a small bug fix for \crtcref and \crtCref, reporting wrong reference numbers, v.0.8. an extra macro 'crtcrefcountervalue.

  • 1
    Doesn't work really well with subsections for me. Whereas the \Cref was "Section 2.1.2", the \crtCref is "Section 2" (using \crtnumberalso yields 2). – Norswap Dec 28 '18 at 18:23
  • @Norswap: Oh my, there is another new version of cleveref apparently that was released one week after crossreftools v.0.6 -- I will investigate and update accordingly. I am pretty sure that it worked previously!. Thanks for notifying me! – user31729 Dec 28 '18 at 18:37
  • @Norswap: Ok, I found a small typo in \crtcref and \crtCref, using the wrong information. Please note, that \cref itself still reports section for subsection etc. references, as long as there is no proper \crefname etc. setup -- I've uploaded crossreftools 0.7 to CTAN, it should be available soon there and on TeXLive/MikTeX – user31729 Dec 28 '18 at 22:33
  • Thanks for the quick reaction! Unfortunately, it still doesn't work after updating to 0.8. This time the section number(s) doesn't show at all. \crtnumber and \crtrefcountervalue both report "2" (should be "2.1.2" for at least one of those as I understand it). – Norswap Jan 3 at 14:32
  • 1
    Works like a charm with the new version 👍 – Norswap Jan 5 at 18:00
5

Neither \cref nor \cref* nor their uppercase variants are expandable, so storing them in a macro with \edef will not work.

This is a by-pass solution.

  1. cleveref stores labels with the @cref suffix, so \label{sec}generates the label names sec and sec@cref.
  2. The label for othersec (see code below) is

    \newlabel{othersec@cref}{{[section][2][]2}{1}}
    

    where {[section][2][]2} is the relevant information about the counter type (section here, [2] stands for the section number which is 2 here and, however, I could not figure out the meaning of []2 yet.

  3. \getrefnumber by refcount package extracts the content stored under the label name, which is more complicated in the case of cleveref, but using a 'splitter' macro named \split@@internal that leaves the content within the first [] only in the input stream, it is possible to extract the counter type, i.e. section here.

  4. cleveref defines \cref@section@name and \Cref@section@name as macros that holds the singular name of section and Section, similarly for other counters, depending on the arguments to \crefname and \Crefname.

Please note the wrapping {} pair around the cleveref label -- it is possible to use this with \split@internal and \split@@internal.

The macros \xcref and \Xcref are not wrappers for \cref or \Cref but a bypass.

I have repeated the the section value in the output of \xcref and \Xcref with \getrefnumber{#1} where the usual label is evaluated.

The code for \xcref and \Xcref checks for the existence of the label name as well, in order to provide 'nothing' if the label has not been defined yet -- this is important for the first compilation run of a document or after deletion of the .aux file.

Please note: The approach here might fail when \label is used with an optional argument which has been introduced by cleveref -- I have not tested this yet.


\documentclass{article}
\usepackage{hyperref}
\usepackage{cleveref}


\makeatletter
\def\split@@internal[#1][#2][#3]#4{#1}%

\def\split@internal#1{%
  \expandafter\split@@internal#1%
}




\newcommand{\Xcref}[1]{%
  \IfRefUndefinedExpandable{#1@cref}{%
  }{%
    \csname Cref@\expandafter\split@internal\getrefnumber{#1@cref}@name\endcsname\ \getrefnumber{#1}%
  }%
}

\newcommand{\xcref}[1]{%
  \IfRefUndefinedExpandable{#1@cref}{%
  }{%
    \csname cref@\expandafter\split@internal\getrefnumber{#1@cref}@name\endcsname\ \getrefnumber{#1}%
  }%
}

\makeatother


\begin{document}

\edef\tmp{\Xcref{othersec}}

\section{This is a section and is followed by \Xcref{othersec}}
\label{sec}

\section{Other section}\label{othersec}

or use \tmp




\end{document}

enter image description here

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.