这个问题源于这个,这是我几周前问的。后来我发现了 cleveref 包,我想用它来方便地引用类似定理的环境,而不必记住给定的语句是定理、引理还是命题等。
这是一个小示例文档。当我编译此文档时,文本的最后一行以“以下是一些对 ?? 1.1、?? 1.2 和定理 1.3 的引用”开头。尝试使用\crefname
为不同环境设置引用名称(我不熟悉术语)不起作用。但是,如果% (*)
取消注释标有 的行,第二个“??”将变为“toybox”。所以这与 中有关\foreach
。但我找不到让它工作的方法。就好像 中的调用\crefname
被完全忽略了\foreach
。为什么会发生这种情况?
\documentclass[a4paper]{amsart}
\def\myTheoremEnvironments{%
theorem/theorems,%
cobblestone/cobblestones,%
toybox/toyboxes%
}
\usepackage{tikz, titlecaps, cleveref}
% Number all definition, theorem, etc. environments using the same counter.
% Start counting again at the start of each section.
% Style these environments using LaTeX's "definition" style.
\theoremstyle{definition}
\newtheorem{baseTheorem}{Base Theorem}[section]
\foreach \x/\y in \myTheoremEnvironments {
\edef\tmp{\noexpand\newtheorem{\x}[baseTheorem]{\noexpand\titlecap{\x}}}\tmp
\crefname{\x}{\x}{\y}
}
%\crefname{toybox}{toybox}{toyboxes} % (*)
\begin{document}
\section{Hello, and welcome to my document.}
\begin{cobblestone}
\label{csref}
Hello. I am an ``cobblestone'' environment.
\end{cobblestone}
\begin{toybox}
\label{tbref}
I am a ``toybox'' environment. What a strange name that is for an environment.
\end{toybox}
\begin{theorem}
\label{thmref}
People trying to do strange things with ``foreach'' should expect trouble.
\end{theorem}
Here are some references to \cref{csref}, \cref{tbref} and \cref{thmref}.
I could have tried using just one call to ``cref'' here,
but it's best not to run before you can walk.
\end{document}
答案1
最大的问题是\foreach
每个循环都在一个组内进行;虽然\newtheorem
定义是全局的,但\crefname
定义不是。
我建议采用一个可能更加用户友好的界面。
\documentclass[a4paper]{amsart}
\usepackage{titlecaps, cleveref}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\foreachpair}{smm}
{
\IfBooleanTF{#1}
{
\hammerite_foreachpair:on { #2 } { #3 }
}
{
\hammerite_foreachpair:nn { #2 } { #3 }
}
}
\cs_new_protected:Npn \hammerite_foreachpair:nn #1 #2
{
\cs_set:Npn \__hammerite_temp:nn ##1 ##2 { #2 }
\clist_map_inline:nn { #1 } { \__hammerite_dopair:n { ##1 } }
}
\cs_new:Npn \__hammerite_dopair:n #1
{
\__hammerite_dopair:wn #1 \q_stop
}
\cs_new:Npn \__hammerite_dopair:wn #1/#2 \q_stop
{
\__hammerite_temp:nn { #1 } { #2 }
}
\cs_generate_variant:Nn \hammerite_foreachpair:nn { o }
\ExplSyntaxOff
% Number all definition, theorem, etc. environments using the same counter.
% Start counting again at the start of each section.
% Style these environments using LaTeX's "definition" style.
\theoremstyle{definition}
\newtheorem{baseTheorem}{Base Theorem}[section]
\foreachpair
{
theorem/theorems,
cobblestone/cobblestones,
toybox/toyboxes,
}
{
\newtheorem{#1}[baseTheorem]{\titlecap{#1}}
\crefname{#1}{#1}{#2}
}
\begin{document}
\section{Hello, and welcome to my document.}
\begin{cobblestone}\label{csref}
Hello. I am an ``cobblestone'' environment.
\end{cobblestone}
\begin{toybox}\label{tbref}
I am a ``toybox'' environment. What a strange name that is for an environment.
\end{toybox}
\begin{theorem}\label{thmref}
People trying to do strange things with ``foreach'' should expect trouble.
\end{theorem}
Here are some references to \cref{csref}, \cref{tbref} and \cref{thmref}.
I could have tried using just one call to ``cref'' here,
but it's best not to run before you can walk.
\end{document}
如您所见,的第二个参数\foreachpair
是一个以逗号分隔的形式的项目列表<item-a>/<item-b>
;第二个参数就像一个命令定义,在每个循环中<item-a>
替换#1
并<item-b>
替换#2
。
还有另一种调用方式
\newcommand\myTheoremEnvironments{
theorem/theorems,
cobblestone/cobblestones,
toybox/toyboxes
}
\foreachpair* \myTheoremEnvironments
{
\newtheorem{#1}[baseTheorem]{\titlecap{#1}}
\crefname{#1}{#1}{#2}
}
答案2
\foreach
每次迭代都进行一组,而且\crefname
不扩展其第二个参数。
可以使用\xintForpair
from 包来规避这些问题新工具:
\documentclass[a4paper]{amsart}
\usepackage{tikz, titlecaps, cleveref}
% Number all definition, theorem, etc. environments using the same counter.
% Start counting again at the start of each section.
% Style these environments using LaTeX's "definition" style.
\theoremstyle{definition}
\newtheorem{baseTheorem}{Base Theorem}[section]
% Does not work:
% \def\myTheoremEnvironments{%
% theorem/theorems,%
% cobblestone/cobblestones,%
% toybox/toyboxes%
% }
% \foreach \x/\y in \myTheoremEnvironments {
% \edef\tmp{\noexpand\newtheorem{\x}[baseTheorem]{\noexpand\titlecap{\x}}}\tmp
% \crefname{\x}{\x}{\y}
% }
% alternative using \xintForpair:
\usepackage{xinttools}% http://ctan.org/pkg/xint
\xintForpair #1#2 in
{% spaces around commas or like the end of lines here,
% or around parentheses are removed automatically
(theorem,theorems),
(cobblestone,cobblestones),
(toybox,toyboxes)
}
\do
{% (spaces significant but do not matter)
\newtheorem{#1}[baseTheorem]{\titlecap{#1}}
\crefname{#1}{#1}{#2}
}
\begin{document}\thispagestyle{empty}
\section{Hello, and welcome to my document.}
\begin{cobblestone}
\label{csref}
Hello. I am an ``cobblestone'' environment.
\end{cobblestone}
\begin{toybox}
\label{tbref}
I am a ``toybox'' environment. What a strange name that is for an environment.
\end{toybox}
\begin{theorem}
\label{thmref}
People trying to do strange things with ``foreach'' should expect trouble.
\end{theorem}
Here are some references to \cref{csref}, \cref{tbref} and \cref{thmref}.
I could have tried using just one call to ``cref'' here,
but it's best not to run before you can walk.
\end{document}
答案3
[Y]你可以使用内部
.list
使用的处理程序,但是\foreach
- 不对其内容进行分组[…]并且
- 可以与已经扩展的内容一起使用
#1
(而不是作为宏序列)。
使用
\pgfkeys{/utils/my Foreach/.code args={#1/#2}{\newtheorem{#1}[baseTheorem]{\titlecap{#1}}%
\crefname{#1}{#1}{#2}},
/utils/my Foreach/.list/.expand once=\myTheoremEnvironments}
给出