这是一个示例文档。
\documentclass[a4paper]{amsart}
\usepackage{tikz}
\theoremstyle{definition}
\newtheorem{baseTheorem}{Base Theorem}[section]
\foreach \x in % 1
{conjecture, definition, example} % 2
{\newtheorem{\x}[baseTheorem]{\MakeUppercase{\x}}} % 3
\begin{document}
\section{Even numbers}
\begin{definition}
A number is called \emph{even} if its remainder on division by $2$ is zero.
\end{definition}
\begin{example}
$2$ and $0$ are both even numbers.
\end{example}
\begin{conjecture}
The sum of two even numbers is again an even number.
\end{conjecture}
\end{document}
此文档无法编译。它会产生以下错误:
! Undefined control sequence.
<argument> \x
l.16 A
number is called \emph{even} if its remainder on division by $2$ i...
但是,如果将编号为 1、2 和 3 的行替换为以下行...
\newtheorem{conjecture}[baseTheorem]{\MakeUppercase{conjecture}}
\newtheorem{definition}[baseTheorem]{\MakeUppercase{definition}}
\newtheorem{example}[baseTheorem]{\MakeUppercase{example}}
... 然后文档就可以编译了,看起来和我预期的一样。(我真正想要的是将“Conjecture”等的首字母大写,而不是整个单词,但这是另一个问题。)
此外,如果将第 1 行和第 3 行的原始版本\x
更改为,则会得到不同的错误消息:\t
! Argument of \UseTextAccent has an extra }.
<inserted text>
\par
l.16 A
number is called \emph{even} if its remainder on division by $2$ ...
我推断问题可能是第三个参数\newtheorem
被逐字记录下来,并且仅在排版单个定理环境时才进行评估。我尝试了以下方法:
\foreach \x in
{conjecture, definition, example}
{\def\uppercased\MakeUppercase{\x} \newtheorem{\x}[baseTheorem]{\uppercased}}
但它并没有解决问题:
! Undefined control sequence.
<argument> \uppercased
l.16 A
number is called \emph{even} if its remainder on division by $2$ ...
我能做些什么?
答案1
\newtheorem
由于每个定理的设置都不是在定义点处,因此最后一个参数中的命令会被展开,因此每个定理都会尝试\x
在循环结束后很长时间使用其标题中的命令。您需要更改求值的顺序,例如,这有效:
\documentclass[a4paper]{amsart}
\usepackage{pgffor}
\theoremstyle{definition}
\newtheorem{baseTheorem}{Base Theorem}[section]
\foreach \x in % 1
{conjecture, definition, example} % 2
{\edef\tmp{\noexpand\newtheorem{\x}[baseTheorem]{\noexpand\MakeUppercase{\x}}}\tmp} % 3
\begin{document}
\section{Even numbers}
\begin{definition}
A number is called \emph{even} if its remainder on division by $2$ is zero.
\end{definition}
\begin{example}
$2$ and $0$ are both even numbers.
\end{example}
\begin{conjecture}
The sum of two even numbers is again an even number.
\end{conjecture}
\end{document}
答案2
尽管大卫·卡莱尔已经给出了问题的技术原因(\x
扩展为迟到)他的回答,你也可以使用内部.list
使用的处理程序,但是\foreach
- 没有对内容进行分组(这里不是问题,因为
\newtheorem
无论如何都定义了全局环境)并且 - 可以与已经扩展的内容一起使用
#1
(而不是作为宏序列)。
代码
\documentclass[a4paper]{amsart}
\usepackage{pgffor}
\theoremstyle{definition}
\newtheorem{baseTheorem}{Base Theorem}[section]
\pgfkeys{/utils/my Foreach/.code={\newtheorem{#1}[baseTheorem]{\MakeUppercase{#1}}},
/utils/my Foreach/.list={conjecture, definition, example}}
\begin{document}
\section{Even numbers}
\begin{definition}
A number is called \emph{even} if its remainder on division by $2$ is zero.
\end{definition}
\begin{example}
$2$ and $0$ are both even numbers.
\end{example}
\begin{conjecture}
The sum of two even numbers is again an even number.
\end{conjecture}
\end{document}
答案3
正如 David 已经解释过的,您需要获取字符串,而不是\x
扩展到字符串。使用 很容易expl3
。
\documentclass[a4paper]{amsart}
\usepackage{expl3}
\ExplSyntaxOn
% provide a "user interface"
\cs_set_eq:NN \Foreach \clist_map_inline:nn
\ExplSyntaxOff
\theoremstyle{definition}
\newtheorem{baseTheorem}{Base Theorem}[section]
\Foreach{conjecture, definition, example}
{\newtheorem{#1}[baseTheorem]{\MakeUppercase{#1}}}
\begin{document}
\section{Even numbers}
\begin{definition}
A number is called \emph{even} if its remainder on division by $2$ is zero.
\end{definition}
\begin{example}
$2$ and $0$ are both even numbers.
\end{example}
\begin{conjecture}
The sum of two even numbers is again an even number.
\end{conjecture}
\end{document}
答案4
(编辑) 2017:因为xint 1.1 (2014/10/28)
这里需要\usepackage{xinttools}
。代码已更新,以替换\usepackage{xint}
初始答案。
David 解释了原因,这里是使用 的替代方法,使用包的pgffor
(可扩展)实用程序\xintApplyUnbraced
信特(是的,我在这里无耻地不断宣传它)。想必将来的某个软件包版本将包含更多工具和更用户友好的语法,例如使用逗号分隔的值列表。
宏\Action
定义以空格开头:这样做是为了停止\xintApplyUnbraced
总是试图扩展的东西;空间被吞噬,并且\xintApplyUnbraced
会很开心。然后,当所有三个\newtheorem
语句都准备好时,它们才会被执行。
请注意,它\xintApplyUnbraced
是完全可扩展的,并且在某些情况下可以提供帮助。
每次使用都\xintApplyUnbraced
需要一个\Action
宏,没有为其保留名称,但文档可以反复使用,\Action
每次都有新定义。我使用\def
而不是, \newcommand
因为\Action
它更像是一个低级助手。
\documentclass[a4paper]{amsart}
\usepackage{xinttools}
\theoremstyle{definition}
\newtheorem{baseTheorem}{Base Theorem}[section]
% space at the start could be removed, but in some other situations
% it has its use. It means: don't execute the following code until
% all elements from the initial list have been fed to \Action
\def\Action #1{ \newtheorem{#1}[baseTheorem]{\MakeUppercase{#1}}}
\xintApplyUnbraced\Action{{conjecture}{definition}{example}}
\begin{document}
\section{Even numbers}
\begin{definition}
A number is called \emph{even} if its remainder on division by $2$ is zero.
\end{definition}
\begin{example}
$2$ and $0$ are both even numbers.
\end{example}
\begin{conjecture}
The sum of two even numbers is again an even number.
\end{conjecture}
\end{document}
输出: