是否在特定段落之前 (原文如此!) 抑制 parskip?

是否在特定段落之前 (原文如此!) 抑制 parskip?

想象一下以下文档:

\documentclass{article}
\setlength{\parskip}{8pt}
\begin{document}
This is the first paragraph

This is the second paragraph

This is the third paragraph
\end{document}

我现在想修改第二段(不是第三段!!),以便第二段和第三段之间没有间距。

有很多方法可以修改第三段,使第二段和第三段之间没有空行 - 但我必须修改第二个。

不适合我的解决方案的最简单示例:

{\setlength{\parskip}{0pt}This is the third paragraph}

为什么?

此处看到的文档是所见即所得 (WYSIWYM) 编辑器 LyX 生成的 LaTeX 代码的最小示例。

在 LyX 中,我需要创建一个段落布局样式(用于第二段),以避免使用该样式的段落与任何其他样式的后续段落之间出现间距。

我只能修改第二段的输出,因为用户可以自由选择下一段的样式。所有其他段落样式都是“正常”的,并会生成 parskip,这是正常的期望行为。(除了我想要生成的特殊段落样式)

不幸的是,似乎没有办法在\n\n不修改源代码的情况下告诉 LyX 不要在每种风格之后生成。

任何想法都值得赞赏!

更新 1:

\vspace我发现单数长度的负数\parskip可能会起到作用,但不确定是否会有不可预见的后果:

\documentclass{article}
\setlength{\parskip}{8pt}
\begin{document}
This is the first paragraph

This is the second paragraph\vspace{-\parskip}

This is the third paragraph
\end{document}

当我在大型自动生成的文档中在这种情况下使用负 vspace 时,会发生什么?

答案1

虽然我\noparskip在第二段末尾显示,但它可以出现在段落的任何位置(包括最开头)并达到相同的效果。

编辑:我对使用简单负数的担心在于,在调用负数之前,\vspace较大的 可能会人为地导致分页。这是否是 Lyx 中的问题,我没有经验来判断。不过,我认为在关闭之前发出负数可能是一个安全的选择,但我会让其他人发表评论。\parskip\vspace\vspace\par

\documentclass{article}
\setlength{\parskip}{8pt}
\let\svpar\par
\edef\svparskip{\the\parskip}
\def\revertpar{\svpar\setlength\parskip{\svparskip}\let\par\svpar}
\def\noparskip{\leavevmode\setlength\parskip{0pt}%
  \def\par{\svpar\let\par\revertpar}}
\begin{document}
This is the first paragraph

This is the second paragraph\noparskip  

This is the third paragraph

This is the fourth paragraph
\end{document}

在此处输入图片描述

答案2

在@Inkane的大力帮助下,我尝试开发一个 Steven 代码版本,以便与 enumerate 和 itemize 环境更好地交互。它的使用方式与 Steven 的实现类似,但有以下变化:

  • 当下一段是枚举或逐项列举时,它不会阻止 parskip。
  • 它不会改变以下列表中的内部间距\noparskip

实现如下:

\makeatletter
\newlength\noparskip@parskip % used to store a backup of the parskip value
\newboolean{noparskip@triggered} % flag to indicate that noparskip was run in the current paragraph
\setboolean{noparskip@triggered}{false}
\newboolean{noparskip@active} % flag to indicate that parskip should be restored after this paragraph
\setboolean{noparskip@active}{false}
\let\noparskip@par\par % store a backup of the \par command
\@setpar{% redefine \par with the means of ltpar.dtx to stay compatible to enumerate and itemize
    \ifhmode% since we're counting occurrences of \par, \par\par would be a problem, so check that we are actually ending a paragraph
        \ifthenelse{\boolean{noparskip@active}}{%
            \setlength\parskip\noparskip@parskip% restore parskip
            \setboolean{noparskip@active}{false}% remember not the restore parskip again
        }{}%
        \ifthenelse{\boolean{noparskip@triggered}}{%
            \ifthenelse{\boolean{noparskip@active}}{}{
                % we are triggering noparskip and not currently in a noparskip already
                \setlength\noparskip@parskip\parskip % copy the current parskip into the backup variable
            }%
            \setboolean{noparskip@triggered}{false}% paragraph is ending, so noparskip is no longer triggered
            \setlength\parskip{0pt}% no parskip when the next paragraph begins
            \setboolean{noparskip@active}{true}% parskip must be restored by the next par
        }{}%
    \fi%
    \noparskip@par% run the original par command
}
\def\noparskip@backout{%
    \ifthenelse{\boolean{noparskip@active}}{%
        % a list is beginning and parskip is currently set to zero, wich would mess up the list
        \setlength\parskip{\noparskip@parskip}% restore parskip before the list begins
        \setboolean{noparskip@active}{false}%
    }{}%
    \setboolean{noparskip@triggered}{false}% there's no sense in keeping noparskip triggered throughout a list
}
\xpretocmd\begin{%
    \ifstrequal{#1}{enumerate}{\noparskip@backout}{}%
    \ifstrequal{#1}{itemize}{\noparskip@backout}{}%
    \ifstrequal{#1}{list}{\noparskip@backout}{}%
}{}{}
\def\noparskip{%
    \leavevmode% ensure that we are within a paragraph
    \setboolean{noparskip@triggered}{true}% trigger noparskip
}
\makeatother

它需要\usepackage{xpatch}运行。

相关内容