I want to have a command which gets a label and returns the environment (or the last sectionining command etc.) after which I had the \label. I mean, like \autoref, but no need to convert from the TeX command/env. name to the name used for output (i.e. I can use \somethingname or \somethingautorefname myself if another command takes mylabel and gives me something.)

Note: I would like a solution that does not use packages offering this functionality, like hyperref or cleveref (although if a piece of code from their sources does the trick than that's a very good solution).

  • possible duplicate of Get label target type – lockstep Dec 6 '11 at 21:41
  • Well, it may be, but the thing is, I don't want to use any hyperref code, so the solution in the possible dupe is not relevant for me. – einpoklum Dec 6 '11 at 22:51
  • If you don't want to use any hyperref code, I suggest you a) clearly state so in the question b) remove the {hyperref} tag. ;-) – lockstep Dec 6 '11 at 22:53
  • 1
    Note: {labels} is not about the \label command. – lockstep Dec 6 '11 at 23:28

Is a cleveref solution acceptable?

EDIT: While cleveref is able to tell label types apart, it uses the same name for, e.g., sections and subsections by default. Use the \crefname and \Crefname macros to change name definitions. Also note that there's an inheritance mechanism for lower-level sectioning headings (e.g., subsubsections will inherit any changes done to subsections). See section 7.1.2 of the manual for details.





The  label type is \namecref{foo}.


The  label type is \namecref{bar}.


enter image description here

  • Well, I would rather have something minimal with no other packages, an illustration how \namecref and \autoref work. But I'll go have a look at \namecref's code, maybe I can figure something out. – einpoklum Dec 7 '11 at 7:14

It's important to understand that (La)TeX essentially processes files sequentially, in one pass from beginning to end. Since references to labels can appear earlier in the document than the label itself, it's clear that one run through LaTeX will not be enough. You need at least two runs, and you need to somehow pass information from the first run to the second (so that LaTeX can know about \label's it hasn't got to yet in the current pass).

This is what the .aux file is for. As well as writing information to this file during each run, LaTeX also reads in the contents of this file (if it exists) before it starts processing the document. In particular, \label commands cause label information to be written out to the .aux file as \newlabel lines. When the .aux file is re-read at the beginning of a later LaTeX run, the \newlabel command in the .aux file causes an \r@<labelname> macro to be defined, which contains the data written to the .aux file in the previous run.

Where does the \label information written to the .aux file come from? The current information needed to create a new label is always stored in the current value of the \@currentlabel macro. This gets updated by any LaTeX command that creates a new \label context. The most important of these is \refstepcounter, which steps a counter and updates the data in \@currentlabel accordingly.

The packages that automatically figure out the environment that a label refers to (cleveref, hyperref's \autoref, varioref, ntheorem...) all do so in more or less the same way. The basic idea is to redefine \refstepcounter to store additional data (such as the current environment name) in \@currentlabel, which then gets stored in the .aux file by a \label command. You can then write macros that retrieve this data from \r@<labelname>.

To understand this in more detail, I suggest you look at how \refstepcounter is redefined in the cleveref package in order to store additional data for the next \label. Then look at how e.g. the \cref@gettype macro retrieves the label type information from the resulting \r@<labelname> macro.

Needless to say, making all this work for every type of label (sections, equations, theorems, footnotes...), including those introduced by other packages, takes non-trivial effort. Many of them use mechanisms other than \refstepcounter to get the label information into \@currentlabel, all of which need to be redefined appropriately.

Copying just the \refstepcounter and \cref@gettype macros from cleveref might be sufficient for simple applications. But if you copy enough "piece[s] of code that do[es] the trick" to make it work reliably, you'll have copied roughly half of the package. You may well be better off using cleveref (or one of the other packages), which have already done all the hard work for you.

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.