如何一起使用 \foreach 和 \newtheorem?

如何一起使用 \foreach 和 \newtheorem?

我想一起使用\foreachnewtheorem所以我用包分配了一个数组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]

在此处输入图片描述

评论

采用这种方法你会失去很多东西,比如应用不同定理样式的可能性,而且你也必然会稍微改变定理标签(这里将首字母大写)。

相关内容