我有一个自定义宏,\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
。