Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I'm looking for a solution to my previous question "Relative chapter references", and find myself struggling with trying to get the target "type" of a label from the label itself.

Allow me to clarify: I want to determine whether a given label points to either a chapter, section, subsection, figure, table, etc.

Ideas? (cuz I'm plain out)

PS: the solution should be compatible with the hyperref package at the very least.

share|improve this question
    
Have you looked at the cleveref package? –  cmhughes Nov 5 '11 at 21:07
    
@cmhughes: I can only imagine \lcnamecref could be of any use... but lack the skill to turn it into something usefull I'm afraid :S... could you provide an example? –  mpr Nov 5 '11 at 21:28

1 Answer 1

up vote 8 down vote accepted
\documentclass{article}
\usepackage[ngerman]{babel}
\usepackage{hyperref}

\makeatletter

% Helper macro to extract the type (section,subsection...) or the type name
% out of the label reference. Works with hyperref only.
% Argument #1 is a macro of form \def\...#1...\@nil{...}
% Argument #2 is the label reference, e.g. "sect:test"
\newcommand*\@myautoref[2]{% \HyPsd@@@autoref from hyperref, modified
  \expandafter\ifx\csname r@#2\endcsname\relax
    ??%
  \else
    \expandafter\expandafter\expandafter\@@myautoref
        \csname r@#2\endcsname{}{}{}{}\@nil#1\@nil
  \fi
}
\def\@@myautoref#1#2#3#4#5\@nil#6\@nil{% \HyPsd@autorefname, modified
  #6#4.\@nil}% Argument #4 = type and number, e.g. "section.1" or "subsection.1.2"

% \myreftype results in the type name, e.g. "section" or "figure".
% The starred variant will remove a star, if existent, i.e. "section*" will become "section"
\newcommand\myreftype{%
  \@ifstar
    {\@myautoref\@@myreftype}%
    {\@myautoref\@myreftype}}
\def\@myreftype#1.#2\@nil{#1}
\def\@@myreftype#1.#2\@nil{\@@@myreftype#1*\@nil}
\def\@@@myreftype#1*#2\@nil{#1}

% \myautorefname results in the type prose name (plus space character),
% e.g. "section" in English or "Abschnitt" in German
% (like \autoref, but without number).
% \HyPsd@@autorefname is defined in the hyperref package.
\newcommand*\myautorefname[1]{\@myautoref\HyPsd@@autorefname{#1}}

% An alternative version of \myautorefname without space at the end.
% Since the \space is hard coded inside \HyPsd@@autorefname we use our
% own version called \@myautorefname instead.
% Furthermore we offer a starred variant which will work with labels to
% \section* etc., too.
\renewcommand*\myautorefname{%
  \@ifstar
    {\@myautoref\@@myautorefname}%
    {\@myautoref\@myautorefname}}
\def\@myautorefname#1.#2\@nil{% = \HyPsd@@autorefname without \space
  \ltx@IfUndefined{#1autorefname}%
    {\ltx@IfUndefined{#1name}%
      {}%
      {\csname#1name\endcsname}}%
    {\csname#1autorefname\endcsname}}
\def\@@myautorefname#1.#2\@nil{%
  \expandafter\@myautorefname\@@@myreftype#1*\@nil.\@nil}

\makeatother

\begin{document}

\myreftype{section:one}
\myreftype{subsection:one}
\myreftype{figure:one}
\myreftype{section:two}

\myreftype*{section:one}
\myreftype*{subsection:one}
\myreftype*{figure:one}
\myreftype*{section:two}

\myautorefname{section:one}
\myautorefname{subsection:one}
\myautorefname{figure:one}
\myautorefname{section:two}

\myautorefname*{section:one}
\myautorefname*{subsection:one}
\myautorefname*{figure:one}
\myautorefname*{section:two}

\section{Section One}
\label{section:one}

\subsection{Subsection One}
\label{subsection:one}

\begin{figure}
\caption{Figure One}
\label{figure:one}
\end{figure}

\section*{Section Two}
\label{section:two}

\end{document}

The code above is an extract of a solution I once wrote for a German LaTeX forum, see: http://www.mrunix.de/forums/showthread.php?t=71566

Please note that this one uses the facilities of hyperref alone. I'm not familiar with packages like varioref or cleverref, so there may be a better solution using one of those packages.

share|improve this answer
    
This works like a charm! One issue though, it seems as if \myautorefname always leaves a space after itself... is there any way of avoiding this? –  mpr Nov 6 '11 at 8:09
    
Do you need \myautorefname at all? I just put it in as further example of the usage of \@myautoref. However, the extra space is hard coded as \space inside \HyPsd@@autorefname. If you don't want it you can either copy the code of \HyPsd@@autorefname, save it as \@myautorefname, remove the \space and use this instead, or you can build a wrapper macro which operates inside a group and redefines \space to \relax. I'll add the first approach to my answer right now... –  Axel Sommerfeldt Nov 6 '11 at 8:29
    
I'm sorry, but your code fails to recognize starred versions of the command (I get section* if I call \myreftype but nothing if I call \myautorefname). Could it be possible to "ignore" the "starrification" of commands and have section* report as section? –  mpr Nov 6 '11 at 15:55
    
The section* comes from the hyperref package so nothing can be done about this without patching the hyperref package itself. (I don't know why it puts section* into the AUX file but surely there is a reason for it...) If you want to \autoref and \myautorefname work with section* too, you could add the code line \expandafter\def\csname section*autorefname\endcsname{\sectionautorefname} to your document preamble. –  Axel Sommerfeldt Nov 6 '11 at 16:36
    
I'm actually more interested in getting \myreftype to work properly since I define counters based on the return value of it. Is it not possible to remove an "optional" star from the end of a string or something like it? –  mpr Nov 6 '11 at 16:59

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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