![如何定义根据参数返回不同命令的命令](https://linux22.com/image/244799/%E5%A6%82%E4%BD%95%E5%AE%9A%E4%B9%89%E6%A0%B9%E6%8D%AE%E5%8F%82%E6%95%B0%E8%BF%94%E5%9B%9E%E4%B8%8D%E5%90%8C%E5%91%BD%E4%BB%A4%E7%9A%84%E5%91%BD%E4%BB%A4.png)
我想定义一个命令\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
。