我想一起使用\foreach
,newtheorem
所以我用包分配了一个数组listofitems
\setsepchar{;/,}\ignoreemptyitems
\readlist\baz
{
theorem, lemma, definition, corollary,
proposition, postulate, axiom, remark;
}
我输入的内容\newtheorem{\baz[1,3]}{\baz[1,3]}[chapter]
将创建一个环境,所以我想用循环definition
创建一系列amsthm
环境foreach
\foreach \a in {1,2,...,8}
{
\newtheorem{\baz[1,\a]}{\baz[1,\a]}
}
但是,它返回了错误\begin{document} ended by \end{definition}
,可能意味着amsthm
环境根本没有成功定义。
那么我该如何解决这个问题?
完整的 MWE 如下
\documentclass{book}
\usepackage{geometry,amsthm,listofitems,pgffor}
\setsepchar{;/,}\ignoreemptyitems
\readlist*\baz
{
theorem, lemma, definition, corollary, proposition, postulate, axiom, remark;
}
\foreach \x in {1,8}
{
\newtheorem{\baz[1,\x]}{\baz[1,\x]}
}
\newtheorem{\baz[1,3]}{\baz[1,3]}[chapter]
\begin{document}
\begin{definition}
\end{definition}
% \begin{theorem}
% \end{theorem}
\end{document}
答案1
您可以使用listofitems
表单来解决这个问题,而无需诉诸 L3 语法。正如其他人所提到的,\foreach
循环(或 forlistofitems
循环foreachitem
)属于它们自己的组。解决方案是将所需的 [扩展] 标记全局添加到标记列表 ( \mytoks
) 并在退出循环后执行标记列表\foreachitem
。
对于listofitems
数组来说,需要进行两次扩展才能恢复所需的标记。
另外,我在列表中间添加了一个分号分隔符,只是为了表明这种方法可以跨子列表起作用。
\documentclass{book}
\usepackage{geometry,amsthm,listofitems,pgffor}
\newtoks\mytoks
\newcommand\addtomytoks[1]{\global\mytoks\expandafter{\the\mytoks#1}}
\newcommand\xaddtomytoks[1]{\expandafter\addtomytoks\expandafter{#1}}
\newcommand\xxaddtomytoks[1]{\expandafter\xaddtomytoks\expandafter{#1}}
\newcommand\xxaddgrouptomytoks[1]{\xxaddtomytoks{%
\expandafter\expandafter\expandafter{#1}}}
\setsepchar{;/,}\ignoreemptyitems
\readlist*\baz
{
theorem, lemma, definition, corollary; proposition, postulate, axiom, remark;
}
\mytoks{}
\foreachitem\z\in\baz[]{%
\foreachitem\x\in\baz[\zcnt]{%
\addtomytoks{\newtheorem}%
\xxaddgrouptomytoks{\baz[\zcnt,\xcnt]}%
\xxaddgrouptomytoks{\baz[\zcnt,\xcnt]}%
}}
\the\mytoks
\begin{document}
\begin{definition}
\end{definition}
\begin{theorem}
\end{theorem}
\begin{postulate}
\end{postulate}
\end{document}
答案2
这是常见的问题:\foreach
周期中的每个项目都在一个组内执行,因此\newtheorem
一旦组结束,通过其定义的环境就会被遗忘。
我猜这个想法是批量定义
\newtheorem{theorem}{Theorem}
\newtheorem{lemma}[theorem]{Lemma}
...
我认为你不会从中获得很多,但出于学术兴趣,你可以这样做。
\documentclass{article}
\usepackage{amsthm}
\ExplSyntaxOn
\NewDocumentCommand{\definetheorems}{mom}
{% #1 = base, #2 = optional parent counter, #3 = list of other names
\IfNoValueTF{#2}
{
\exp_args:Nne \newtheorem{#1}{\text_titlecase:n { #1 }}
}
{
\exp_args:Nne \newtheorem{#1}{\text_titlecase:n { #1 }}[#2]
}
\clist_map_inline:nn { #3 }
{
\axia_newtheorem:nne { #1 } { ##1 } { \text_titlecase:n { ##1 } }
}
}
\cs_new_protected:Nn \axia_newtheorem:nnn
{
\newtheorem{#2}[#1]{#3}
}
\cs_generate_variant:Nn \axia_newtheorem:nnn { nne }
\ExplSyntaxOff
\definetheorems{theorem}[section]{
lemma, definition, corollary, proposition, postulate, axiom, remark
}
\begin{document}
\section{Test}
\begin{lemma}
This is a lemma.
\end{lemma}
\begin{axiom}
This is an axiom.
\end{axiom}
\begin{theorem}
This is a theorem.
\end{theorem}
\section{Again}
\begin{proposition}
This is a proposition.
\end{proposition}
\end{document}
如果调用没有可选参数,则输出如下[section]
:
评论
采用这种方法你会失去很多东西,比如应用不同定理样式的可能性,而且你也必然会稍微改变定理标签(这里将首字母大写)。