仅当后面没有文本时,在 itemize 后面添加空格

仅当后面没有文本时,在 itemize 后面添加空格

我将从我想做的一个例子开始。

Here is some enumeration:
\begin{enumerate}
    \item First item.
    \item Second item.
\end{enumerate}
And the text continues in the same paragraph.

Here is some enumeration:
\begin{enumerate}
    \item First item.
    \item Second item.
\end{enumerate}

And the text continues, but in a new paragraph.

上述代码应产生以下输出(注意末尾行之间的间距itemize)。

在某些情况下,我想插入一个枚举(逐项列举或枚举)里面一个段落,有时我想将其插入到末尾并在其后开始一个新段落,留下一个空格。我所说的“段落”不是开头,\paragraph{title}而只是代码中由空行分隔的一段文本,这也会在输出中产生由两个空格分隔的一段文本。

我脑海中的画面是,枚举是段落的一部分,我希望它的行为与段落中放入的其他内容相同。因此,如果它是段落中的最后一个元素,后面应该有一个空格,如果不是,那么后面就不应该有空格。(另外,我没有放空格我的枚举。)

我知道如何在枚举后始终添加空格或永远不添加任何内容。但我不知道如何以与段落结束时相同的方式调整行为。我现在的做法是默认不添加空格,如果\vspace{\parskip}以枚举结尾段落,则添加一些空格。

我怎样才能实现我所描述的?

完整示例:

\documentclass{article}
\usepackage{parskip}
\usepackage{enumitem}
\setlist[1]{
  label=(\arabic*),
  % What do I do here to insert a space if there is a
  % new paragraph
  % after=\vspace{\parskip},
}
\begin{document}
\noindent
\section{Non-working example (no space)}
Here is some enumeration:
\begin{enumerate}
    \item First item.
    \item Second item.
\end{enumerate}
And the text continues in the same paragraph.

Here is some enumeration:
\begin{enumerate}
    \item First item.
    \item Second item.
\end{enumerate}

And the text continues, but in a new paragraph.

\section{Desired output (manual space)}
Here is some enumeration:
\begin{enumerate}
    \item First item.
    \item Second item.
\end{enumerate}
And the text continues in the same paragraph.

Here is some enumeration:
\begin{enumerate}
    \item First item.
    \item Second item.
\end{enumerate}
\vspace{\parskip}

And the text continues, but in a new paragraph.

\end{document}

不工作的示例和手动更正

答案1

这样可以吗?

\documentclass{article}
\usepackage{enumitem}
\setlength{\parskip}{10ex}
\setlength{\parindent}{0pt}
\newenvironment{enumerateD}{\begin{enumerate}[topsep=-\parskip]}
{\end{enumerate}\leavevmode\ignorespacesafterend}

\begin{document}
Test
\begin{enumerateD}
        \item Item
        \item Item 2
\end{enumerateD}
test\\
test

Test
\begin{enumerateD}
        \item Item
        \item Item2
\end{enumerateD}

Test
\end{document}

解释

  1. 我们几乎被迫加载enumitem,因为否则我们无法轻易改变\topsep
  2. 首先我们\topsep设定消极的;默认情况下,列表在列表的开头和结尾处\parskip留出垂直空间\topsep + \parskip(如果您的列表开始一个新段落也是如此)。因此我们设置取消该默认设置。\partopsep\topsep\parskip
  3. 您不想使用\after来自的代码enumitem,因为这是执行的结束列表环境,这还为时过早。我们想在结束列表环境。
  4. 接下来,我们要检测后面的空行。这里有用的是列表环境以 结束一个段落\par并以垂直模式结束。通常,是否放入空行不会产生任何影响,因为\par在垂直模式下会被忽略。所以我们要做的就是用 强制回到水平模式\leavevmode。但是一旦我们处于水平模式,空格就会开始可见,因此为了避免在行首出现虚假空格,指示 也很有用\ignorespacesafterend
  5. 设置\parskip10ex只是为了使效果更明显。设置\parindent0pt是为了模仿 OP 所示的段落不缩进的期望输出。

mforbes 问道在评论中不使用时的解决方案\parskip。以下是一次尝试。

事实证明,在环境结束后自动测试字符有点困难。这是因为latex.ltx当你发出时,你会看到\end{envname}最后发生的事情是

    ...
    \UseHook{env/envname/after}    %% This is when the \AfterEndEnvironment hooks are run
    \if@ignore\@ignorefalse\ignorespaces\fi  %% Mechanism for \ignorespacesafterend
}

由于\if@ignore...\fi无法使用 After Environment Hook 中的任何代码来检测后续\par代码。这引出了我们的第一个观察结果:

为了达到我们想要的效果,我们必须修改\end{envname}机制本身。

接下来,我假设您希望\end{itemize}<space><newline><newline>\end{itemize}<newline><newline>的行为相同。换句话说,您希望允许在之前有空格,\par并且仍然检测到\par;相反,我还假设在您不想忽略空格的情况下,您也不希望这种行为。所以

需要允许空间被吞噬。为此,我们参考先前的答案。副作用是你必须发出\AtEndEnvironment{<envname>}{\ignorespacesafterend}才能激活此机制。

有关实施的更多信息:

  • 我们定义一个新的布尔值\@envendextrapar;代码检测(在吞噬空格之后)下一个标记是否为\par。如果是,它将此布尔值设置为真,否则不执行任何操作。
  • 用户有责任\AfterEndEnvironment{<envname>}{...}使用此布尔环境将代码放入。对于下面的示例代码,如果检测到,则会添加\par额外的空间。2cm
\documentclass{article}

\makeatletter
%%% From https://tex.stackexchange.com/a/432246/119
%%% A version of \futurelet that gobbles spaces
\def\futureletignorespaces#1#2{\def\nextaction{#2}%
  \def\checkspace{\ifx\nexttoken\@sptoken
    \expandafter\@firstoftwo
   \else
    \expandafter\@secondoftwo
   \fi
   {\afterassignment\futureletagain\let\nexttoken= }
   {\futurelet#1\nextaction}}%
  \futurelet\nexttoken\checkspace}
\def\futureletagain{\futurelet\nexttoken\checkspace}


\newif\if@envendextrapar
\@envendextraparfalse
\def\doEnvEnd#1{%
        \ifx\@envendextrapartest\par\relax\@envendextrapartrue\fi%
        \UseHook{env/#1/after}%
        \@envendextraparfalse%
        \if@ignore\@ignorefalse\ignorespaces\fi
}
\@namedef{end }#1{%
  \romannumeral
    \IfHookEmptyTF{env/#1/end}%
        {\expandafter\z@}%
        {\z@\UseHook{env/#1/end}}%
    \csname end#1\endcsname\@checkend{#1}%
    \expandafter\endgroup\if@endpe\@doendpe\fi
    \if@ignore\def\@tempa{\doEnvEnd{#1}}%
            \def\@tempb{\futureletignorespaces\@envendextrapartest\@tempa}%
    \else\def\@tempb{\UseHook{env/#1/after}}\fi%
    \@tempb
}
\AtEndEnvironment{itemize}{\ignorespacesafterend}  %% Required, see explanation
\AfterEndEnvironment{itemize}{\if@envendextrapar \vspace{2cm}\fi}
\makeatother 

\begin{document}

Test
\begin{itemize}
        \item First item
        \item Second item
\end{itemize}
Test again, no blank line.

Test start
\begin{itemize}
        \item Third item
        \item Fourth item
\end{itemize}

Test again, with blank line

\end{document}

相关内容