如何定义根据参数返回不同命令的命令

如何定义根据参数返回不同命令的命令

我想定义一个命令\mycommand,使得\mycommand{X}产生 \Xfirst\Xsecond\label{Xlabel},其中\Xfirst\Xsecond是已经定义的命令。当然,\mycommand{Y}应该产生\Yfirst\Ysecond\label{Ylabel},并且\mycommand{Z}应该产生您期望的结果,等等。例如,如果我有

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

那么使用命令\mycommand{X}必须等同于写入Axx\label{Xlabel},而写入\mycommand{Y}必须等同于写入Byy\label{Ylabel}。我想我可以用(很多)if 来做到这一点。有没有更优雅的形式?怎么做?包hyperref应该可以很好地与生成的标签配合使用。

遵循 Ryan Reich 建议的示例(超链接错误)。

\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}

再次尝试,使用超目标和超链接。似乎有效。

\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}

第三次尝试,使用\phantomsection。它似乎也有效。这是更好的解决方案。

\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}

答案1

您可以使用“环境”生成变量命名的宏\csname...\endcsname。例如,您可以定义:

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

它将会生成您所要求的结果。

编辑:您的示例确实显示了一个错误,但我的代码没有。如果您将对的调用替换\mycommand为直接\label调用(Xlabel 和 Ylabel),也会发生同样的事情。这是因为hyperref 本身无法产生正确的链接\pageref;这个问题在这个comp.text.tex帖子

这样做的基本原因是,虽然\label将目标引用的信息保存在 .aux 文件中,但它不是在执行的位置生成一个超目标。因此,的目标\pageref与的目标完全相同\ref,即生成它的\section(或equation,或其他)。如果您想解决这个问题,您必须指出hyperref您希望的\label不是引用最后一个\section,而是引用当前位置。这是通过\phantomsection在 之前插入 来实现的\label。因此,如果这是您的问题,则应使用 的以下定义\mycommand

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

但是,这会破坏 的使用\ref,因为它们现在将指向标签的位置,而不是标签部分。我认为如果不破解 ,您就无法同时实现这两种方式\label

相关内容