在文中如何抑制定理头和枚举环境之间的垂直空间?David Carlisle 建议使用一段代码来帮助抑制定理头和枚举环境之间的垂直空间。该代码运行良好,但我最近意识到,当枚举环境嵌套时,它们之间现在会插入额外的垂直空间。如何避免这种情况(而不会失去在定理头后抑制垂直空间的功能)?
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[american]{babel}
\usepackage{enumitem}
\usepackage{amsthm}
\newtheoremstyle{mythmstyle}%
{0.5em}% space above
{0.5em}% space below
{}% body font
{}% indent amount
{\sffamily\bfseries}% head font
{}% punctuation after head
{\newline}% space after head
{\thmname{#1}\ \thmnumber{#2}\ \thmnote{(#3)}}% head spec
\theoremstyle{mythmstyle}
\newtheorem{theorem}{Theorem}
% list settings
\setlist{% general list settings (enumitem's itemize, enumerate, and description)
align=left,% left-aligned enumerate
labelsep=*,% align all item bodies vertically
leftmargin=*,% no left indent
topsep=1mm,% space before enumerate
itemsep=0mm% space between enumerate items
}
\setlist[enumerate,1]{label=\alph*)}% enumerate label on level 1
\setlist[enumerate,2]{label=\roman*)}% enumerate label on level 2
% vertical spacing after theorem heads (suggested by David Carlisle)
\makeatletter
\def\enumfix{%
\if@inlabel
\noindent\par\nobreak\vskip-\parskip\vskip-\baselineskip\hrule\@height\z@
\fi}
\let\oldenumerate\enumerate
\def\enumerate{\enumfix\oldenumerate}
\makeatother
\begin{document}
\begin{theorem}% perfectly fine with David's solution: no vertical space
\begin{enumerate}
\item Foo
\item Bar
\end{enumerate}
\end{theorem}
\bigskip
\begin{enumerate}
\item Foobar
\item \begin{enumerate}% vertically not correctly aligned; comment out David's code above to see how it should look like
\item Foo
\item Bar
\end{enumerate}
\end{enumerate}
\end{document}
答案1
我建议你为定理中的第一级枚举定义一个新的环境,这是唯一必须特殊处理的环境:
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[american]{babel}
\usepackage{enumitem}
\usepackage{amsthm}
\newtheoremstyle{mythmstyle}%
{0.5em}% space above
{0.5em}% space below
{}% body font
{}% indent amount
{\sffamily\bfseries}% head font
{}% punctuation after head
{\newline}% space after head
{\thmname{#1}\ \thmnumber{#2}\ \thmnote{(#3)}}% head spec
\theoremstyle{mythmstyle}
\newtheorem{theorem}{Theorem}
% list settings
\setlist{% general list settings (enumitem's itemize, enumerate, and description)
align=left,% left-aligned enumerate
labelsep=*,% align all item bodies vertically
leftmargin=*,% no left indent
topsep=0mm,% space before enumerate
itemsep=0mm% space between enumerate items
}
\setlist[enumerate,1]{label=\alph*)}% enumerate label on level 1
\setlist[enumerate,2]{label=\roman*)}% enumerate label on level 2
% vertical spacing after theorem heads (suggested by David Carlisle)
\makeatletter
\newenvironment{tenumerate}[1][]
{\if@inlabel
\noindent\par\nobreak\vskip-\parskip\vskip-\baselineskip\hrule\@height\z@
\fi
\enumerate[topsep=3pt,#1]}
{\endenumerate}
\makeatother
\begin{document}
\begin{theorem}% perfectly fine with David's solution: no vertical space
\begin{tenumerate}
\item Foo
\item Bar
\end{tenumerate}
\end{theorem}
\bigskip
\begin{enumerate}
\item Foobar
\item \begin{enumerate}
\item Foo
\item Bar
\end{enumerate}
\end{enumerate}
\end{document}
新方法
看来,不同的策略无需新环境即可发挥作用:
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[american]{babel}
\usepackage{enumitem}
\usepackage{amsthm}
\usepackage{etoolbox}
\newif\ifstarttheorem
\newtheoremstyle{mythmstyle}%
{0.5em}% space above
{0.5em}% space below
{}% body font
{}% indent amount
{\sffamily\bfseries\global\starttheoremtrue}% head font
{}% punctuation after head
{\newline}% space after head
{\thmname{#1}\ \thmnumber{#2}\ \thmnote{(#3)}}% head spec
\theoremstyle{mythmstyle}
\newtheorem{theorem}{Theorem}
% list settings
\setlist{% general list settings (enumitem's itemize, enumerate, and description)
align=left,% left-aligned enumerate
labelsep=*,% align all item bodies vertically
leftmargin=*,% no left indent
topsep=0mm,% space before enumerate
itemsep=0mm% space between enumerate items
}
\setlist[enumerate,1]{label=\alph*)}% enumerate label on level 1
\setlist[enumerate,2]{label=\roman*)}% enumerate label on level 2
% vertical spacing after theorem heads (suggested by David Carlisle)
\makeatletter
\preto\enumerate{%
\if@inlabel
\ifstarttheorem
\mbox{}\par\nobreak\vskip\glueexpr-\parskip-\baselineskip+3pt\relax\hrule\@height\z@
\global\starttheoremfalse
\fi
\fi}
\preto\endenumerate{\global\starttheoremfalse}
\makeatother
\begin{document}
This is not a theorem.
\begin{enumerate}
\item Foo
\item Bar
\end{enumerate}
\begin{theorem}
This is a theorem.
\begin{enumerate}
\item Foo
\item Bar
\end{enumerate}
\end{theorem}
This is not a theorem.
\begin{enumerate}
\item Foo
\item Bar
\end{enumerate}
\begin{theorem}
\begin{enumerate}
\item Foo
\item Bar
\end{enumerate}
\end{theorem}
\begin{theorem}
\begin{enumerate}
\item Foobar
\item \begin{enumerate}
\item Foo
\item Bar
\end{enumerate}
\end{enumerate}
\end{theorem}
\bigskip
\end{document}
每个定理环境都将一个条件设置为真;如果如果此条件为真,则enumerate
环境会受到 David 的特殊处理并将条件设置为假。为了避免误报,enumerate
在结束时也会将条件设置为假。