使用键创建和引用变量

使用键创建和引用变量

我有一个自定义宏,\somemacro{}{}。在宏中,#1设置为唯一键(例如 11)并#2包含其他数据。此宏出现在我的整个文档中:

    This is some text. \somemacro{11}{This is information about animals.}
    \somemacro{15}{This is information about trees.} Here is some other text.
\chapter{Here is a new chapter}
    \somemacro{17}{This is information about the sky.}
    \somemacro{01}{This is information about space.}

有时,我需要通过引用键编号来交叉引用宏的出现。这类似于\ref\pageref,但值将是一个表示该键出现顺序的数字。例如,在上面的 中,#15出现在第二个,因此\whereiskey{15}将返回2#01在文档中出现在第四个,因此\whereiskey{01}将返回4

为此,我创建了一个计数器labelcounter,每次使用宏时,计数器都会递增。为了创建一个具有键和值的变量,我尝试使用一个计数器(因为它是我所知道的唯一一个具有名称和值的变量),并以键的值命名:

\documentclass{article}
\newcounter{labelcounter}
\setcounter{labelcounter}{0}
\newcommand{\somemacro}[2]{
    \stepcounter{labelcounter}
    \newcounter{#1}
    \setcounter{labelcounter}
    #2
}
\newcommand{\whereiskey}[1]{
    \arabic{#1}
}
\begin{document}
    \somemacro{08}{This is some text.}
    \somemacro{12}{This is some other text.}
    \somemacro{10}{This is some more text.}
    This number should say when \#12 appears: \whereiskey{10}.
\end{document}

这似乎不起作用。当我尝试编译时,它报告,

Missing number, treated as zero. \somemacro{08}{This is some text.}.
  • 我怎样才能让它工作?
  • 有没有更好的方法?

答案1

您没有指定labelcounter应将计数器设置为什么值。

但是,为每个实例定义一个新的计数器\somemacro绝对不是一个好主意。此外,\arabic{#1}将始终返回 0。

如果键是唯一的,您应该参考它们。

\newcounter{keycounter}
\makeatletter
\newcommand{\somemacro}[2]{%
  \@ifundefined{keyappeared@#1}
    {\stepcounter{keycounter}%
     \expandafter\xdef\csname keyappeared@#1\endcsname{\the\c@keycounter}%
    }{}%
  #2}
\newcommand{\whereiskey}[1]{%
  \@ifundefined{keyappeared@#1}
    {``wrong or not yet appeared key''}
    {\@nameuse{keyappeared@#1}}}
\makeatother

现在有了您的输入

\somemacro{08}{This is some text.}
\somemacro{12}{This is some other text.}
\somemacro{10}{This is some more text.}
This number should say when \#10 appears: \whereiskey{10}.

您将从 获得 3 \whereiskey{10}。如果相同的键出现两次,则不会增加keycounter

您也可以直接使用\label-\ref系统:

\newcounter{keycounter}
\makeatletter
\newcommand{\somemacro}[2]{%
  \@ifundefined{keyappeared@#1}
    {\refstepcounter{keycounter}\label{keyappeared@#1}%
     \global\expandafter\let\csname keyappeared@#1\endcsname\@empty
    }{}%
  #2}
\newcommand{\whereiskey}[1]{%
  \@ifundefined{keyappeared@#1}
    {\typeout{Possibly wrong key, run LaTeX again}}{}%
    \ref{keyappeared@#1}%
  }
\makeatother

\whereiskey这样就摆脱了命令必须出现在相应之后的限制\somemacro

相关内容