我必须获取动态宏的值,其中索引由 给出\ref{mymarker}
。可以做到吗?我定义了一组带有预定义计数器“mycounter”的宏,如下所示
\expandafter\newcommand\csname mymacro\the\value{mycounter} \endcsname{mytext}
其中“mytext”取决于计数器的值。
之后我定义了一个新命令
\newcommand{\anotherref}[1]{\csname mymacro\ref{#1} \endcsname}
代码如下
\anotherref{mymarker}
不起作用。这个想法是,这个命令不应该给出与“mymarker”相关的计数器值\ref{mymarker}
,而是给出文本“mytext”,它也与“mymarker”相关。
答案1
下面的示例展示了使用包的实现refcount
。
\mymacrodef
使用for\mymacro<num>
的当前计数器值进行定义。定义以 开头。mycounter
<num>
\newcommand{\mymacro<num>}
\mymacroget{<num>}
呼叫\mymacro<num>
。\mymacroundefined
\mymacroget
如果找不到则使用\mymacro<num>
。\mymacroref{<label>}
从指定标签中提取数字并\mymacroget
使用该数字进行调用。如果引用<label>
未定义,\mymacroundefined
则使用。标签名称可能包含 babel 简写字符。\mymacrorefexp{<label>}
行为类似,\mymacroref
但有以下区别:该宏可以在可扩展上下文中使用,因为它只需两个扩展步骤即可扩展,请参见下面的示例。
Babel 不支持简写字符,因为这需要破坏可扩展性的分配。
- 如果引用未定义,则不会向用户发出警告,因为这会破坏可扩展性。如果可能,请
\refused{<label>}
在可扩展上下文之外使用,以便在出现未定义引用时收到警告。
这个例子:
\documentclass{article}
\usepackage{refcount}[2010/12/01]
\usepackage{ltxcmds}
\newcounter{mycounter}
\makeatletter
% \mymacrodef defines a macro \mymacro<number> that gets
% the number from the current counter setting for `myounter`.
\newcommand*{\mymacrodef}{%
\expandafter\newcommand
\csname mymacro\the\value{mycounter}\endcsname
}
% \mymacroget{<number>} calls \mymacro<number>
% if the macro exists and \mymacroundefined otherwise.
% It is expandable in two expansion steps.
\newcommand*{\mymacroget}[1]{%
\romannumeral-`\x
\ltx@ifundefined{mymacro\number#1}{%
\ltx@space
\mymacroundefined
}{%
\expandafter\ltx@space
\csname mymacro\number#1\endcsname
}%
}
\newcommand*{\mymacroundefined}{\textbf{??}}
% \mymacroref{<label>} is not expandable and gets the number
% from the reference <label>
\newcommand*{\mymacroref}[1]{%
\refused{#1}%
\IfRefUndefinedBabel{#1}{%
\mymacroundefined
}{%
% with babel shorthand support
\begingroup
\csname @safe@actives@true\endcsname
\expandafter\endgroup
\expandafter\mymacroget\expandafter{%
\number\getrefnumber{#1}%
}%
}%
}
\newcommand*{\mymacrorefexp}[1]{%
\romannumeral-`\x
\IfRefUndefinedExpandable{#1}{%
\ltx@space
\mymacroundefined
}{%
\expandafter\expandafter\expandafter\ltx@space
\mymacroget{\getrefnumber{#1}}%
}%
}
\makeatother
\begin{document}
\mymacrodef{Text zero.}
\refstepcounter{mycounter}
\mymacrodef{Text one.}
\label{mylabel}
\refstepcounter{mycounter}
\mymacrodef{Text one again.}
\begin{itemize}
\item[0:] \mymacroget{0}
\item[1:] \mymacroget{1}
\item[42:] \mymacroget{42}
\item[mylabel:] \mymacroref{mylabel}
\item[undef:] \mymacroref{undef}
% Expandable stuff. Define macro \my that has the meaning
% of the macro \mymacro<number>, where <number> is stored
% in label `mylabel':
\refused{mylabel}
\expandafter\expandafter\expandafter\let
\expandafter\expandafter\expandafter\my
\mymacrorefexp{mylabel}
\item[\texttt{\string\my}:] \texttt{\meaning\my}
\end{itemize}
\end{document}
答案2
这是我的玩具示例。我希望这对某些人有用。问题是定义命令\editor
并使用它来形成标题页。每个编辑都有自己的原始编号并代表某个国家。在正文中还提到了编辑的姓名、他们的编号和相应的国家。建议使用该包refcount
允许我以以下方式解决这个问题:
\documentclass{article}
\usepackage{refcount}
\makeatletter
% Definition of the command \editor{name}{country}
\newcounter{editor@index}
\newcommand\editor[2]{\refstepcounter{editor@index}
\expandafter\newcommand\csname
@editor@name\the\value{editor@index} \endcsname{#1}
\expandafter\newcommand\csname
@editor@country\the\value{editor@index} \endcsname{#2}%
}
% Definition of the commands \nameref{marker} and \countryref{marker}
\newcommand{\nameref}[1]{\csname
@editor@name\getrefnumber{#1} \endcsname}
\newcommand{\countryref}[1]{\csname
@editor@country\getrefnumber{#1} \endcsname}
\makeatother
\begin{document}
% With the command \editor one can define the list of editors.
% It can also be used in the redefinition of \maketitle with
% accessing to the name with
% \csname @editor@name\the\value{editor@index} \endcsname and to the
% country with \csname @editor@country\getrefnumber{#1} \endcsname.
% One can also mark the editors with \label.
\editor{John Smith}{UK}\label{JS}
\editor{John Doe}{USA}\label{JD}
% Now one can change the order of \editor and always have the correct
% referencing.
\nameref{JS} from~\countryref{JS} is referred as editor~\ref{JS}.
\nameref{JD} from~\countryref{JD} is referred as editor~\ref{JD}.
\end{document}
再次非常感谢大家的评论和建议!