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
The packages that automatically figure out the environment that a label refers to (
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
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
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
\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.