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 would like to define a command \mycommand such that \mycommand{X} produces \Xfirst\Xsecond\label{Xlabel}, where \Xfirst and \Xsecond are already defined commands. Of course, \mycommand{Y} should produce \Yfirst\Ysecond\label{Ylabel}, and \mycommand{Z} should produce what you expected, and so on. For instance, if I have

\newcommand{\Xfirst}{A}
\newcommand{\Xsecond}{xx}
\newcommand{\Yfirst}{B}
\newcommand{\Ysecond}{yy}

then using the command \mycommand{X} must be equivalent to writing Axx\label{Xlabel}, while writing \mycommand{Y} must be equivalent to writing Byy\label{Ylabel}. I think I can do it with (a lot of) ifs. Is there a more elegant form? How? Package hyperref should work well with the generated label.

An example following the suggestion of Ryan Reich (wrong link with hyperref).

\documentclass{article}
\usepackage{hyperref}
\newcommand{\Xfirst}{A}
\newcommand{\Xsecond}{xx}
\newcommand{\Yfirst}{B}
\newcommand{\Ysecond}{yy}
\newcommand\mycommand[1]{%
 \csname #1first\endcsname
 \csname #1second\endcsname
 \label{#1label}%
}
\begin{document}
    \section{Section}
    \mycommand{X}
    \pageref{Ylabel} % does not point to page 3
    \newpage
    Nothing.
    \newpage
    \mycommand{Y}
    \pageref{Xlabel}
\end{document}

Another attempt, using hypertarget and hyperlink. It seems to work.

\documentclass{article}
\usepackage{hyperref}
\newcommand{\Xfirst}{A}
\newcommand{\Xsecond}{xx}
\newcommand{\Yfirst}{B}
\newcommand{\Ysecond}{yy}
\newcommand\mycommand[1]{%
 \csname #1first\endcsname
 \csname #1second\endcsname
 \hypertarget{#1label}{}%
}
\begin{document}
    \section{Section}
    \label{section1}
    \mycommand{X}
    \hyperlink{Ylabel}{l1Y}
    \newpage
    \section{Another section}
    \label{section2}
    \hyperlink{Xlabel}{l2X}
    \hyperlink{Ylabel}{l2Y}
    \newpage
    \mycommand{Y}
    \hyperlink{Xlabel}{l3X}
    See Section 1 here~\ref{section1}.
    See Section 2 here~\ref{section2}.
\end{document}

A third attempt, with \phantomsection. It also seems to work. This is the better solution.

\documentclass{article}
\usepackage{hyperref}
\newcommand{\Xfirst}{A}
\newcommand{\Xsecond}{xx}
\newcommand{\Yfirst}{B}
\newcommand{\Ysecond}{yy}
\newcommand\mycommand[1]{%
 \csname #1first\endcsname
 \csname #1second\endcsname
 \phantomsection
 \label{#1label}{}%
}
\begin{document}
    \Huge
    \section{Section}
    \label{section1}
    \mycommand{X}
    X\pageref{Xlabel}
    Y\pageref{Ylabel}
    \newpage
    \section{Another section}
    \label{section2}
    X\pageref{Xlabel}
    Y\pageref{Ylabel}
    \newpage
    \mycommand{Y}
    X\pageref{Xlabel}
    Y\pageref{Ylabel}\par
    See Section 1 here~\ref{section1}.\par
    See Section 2 here~\ref{section2}.
\end{document}
share|improve this question
    
Your example with \hypertarget is much worse than my proposal with \phantomsection, since it does not automatically print either the section number or the page number. What are you actually trying to do? –  Ryan Reich Jan 17 '12 at 16:14
    
I understood that you said that \phanthomsection would not work together with \ref, so I tried another solution using hypertarget. That solution works, although it requieres some fine tunning yet. Then, I decided to try \phanthomsection anyway, and it also works. I agree in that the solution with \phanthomsection is much better, once you know it works. –  ASdeL Jan 17 '12 at 18:50
1  
What I meant was: if you use \phantomsection and then \label, the label will point to the phantom section rather than to the real previous section. That's what you want if you're using \pageref, but if you use \ref on such a label, it will give you a link to the location of the phantom, which is probably not what you want. –  Ryan Reich Jan 18 '12 at 0:19
add comment

1 Answer

up vote 7 down vote accepted

You can generate a variable-named macro using the "environment" \csname...\endcsname. For example, you could define:

\newcommand\mycommand[1]{%
 \csname #1first\endcsname
 \csname #1second\endcsname
 \label{#1label}%
}

which will produce exactly what you asked for.

Edit: Your example does display a bug, but not with my code. The same thing happens if you replace the calls to \mycommand with direct \labels (of Xlabel and Ylabel). This is because hyperref itself does not produce correct links with \pageref; this issue is discussed in this comp.text.tex post.

The basic reason for this is that, while \label saves the target reference's information in the .aux file, it does not produce a hypertarget at the place it is executed. The target for \pageref is therefore exactly the same as the target for \ref, namely, the \section (or equation, or whatever) that produced it. If you want to get around this, you must indicate to hyperref that you want the \label to refer not to the last \section, but to the present location. This is done by inserting \phantomsection right before \label. Thus, if this is your problem, you should use the following definition of \mycommand:

% Use this in case you *don't* install hyperref.
\providecommand\phantomsection{}
\newcommand\mycommand[1]{%
 \csname #1first\endcsname
 \csname #1second\endcsname
 \phantomsection
 \label{#1label}%
}

However, this will break uses of \ref, since they will now point to the location of the label rather than the labeled section. I don't think you can have it both ways without hacking \label.

share|improve this answer
    
Text is ok, but hyperref links seem to be wrong. Is that possible? –  ASdeL Jan 17 '12 at 2:56
    
You will have to be more specific about what you have and what is going wrong. Please provide a minimal compilable document. –  Ryan Reich Jan 17 '12 at 3:01
    
A was trying to add it here, but I could not. Sorry. I will add it in the main question. –  ASdeL Jan 17 '12 at 3:05
    
That is the best place for it anyway. –  Ryan Reich Jan 17 '12 at 3:07
    
hyperlink + hypertarget seems to work, as well as \phanthomsection. See examples in the main question. –  ASdeL Jan 17 '12 at 12:45
add comment

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.