如何将 \csname ... \endcsname 与 \ref 一起使用?

如何将 \csname ... \endcsname 与 \ref 一起使用?

我必须获取动态宏的值,其中索引由 给出\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}

再次非常感谢大家的评论和建议!

相关内容