嵌套枚举(enumitem)会干扰抑制定理头后的垂直空间。

嵌套枚举(enumitem)会干扰抑制定理头后的垂直空间。

在文中如何抑制定理头和枚举环境之间的垂直空间?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在结束时也会将条件设置为假。

相关内容