我正在编写一个使用 minipages 显示其内容的自定义命令:
\newcommand{\example}[1]{\noindent\begin{minipage}{\linewidth}#1\end{minipage}}
此命令周围的间距应与环境的间距相似align
:\abovedisplayskip
上方和\belowdisplayskip
之后,因此我添加了\par\vspace{…}
之前和之后:
\newcommand{\example}[1]{%
\par\vspace{\abovedisplayskip}
\noindent\begin{minipage}{\linewidth}#1\end{minipage}
\par\addvspace{\belowdisplayskip}}
但这并不完美:\parskip
即使命令周围没有空行,它也会在内容前后添加额外内容:
AAA % too much space (extra \parskip) after this
\example{\lipsum[1]}
BBB % too much space (extra \parskip) before that
我可以通过将定义更改为以下内容来删除第一个:
\newcommand{\example}[1]{%
\ifvmode\else\par\vspace{-\parskip}\fi\vspace{\abovedisplayskip}
\noindent\begin{minipage}{\linewidth}#1\end{minipage}
\par\addvspace{\belowdisplayskip}}
但是命令底部的等效修复是什么?如果我使用负空格,将\parskip
始终被抑制。理想情况下,我希望命令后面的文本不缩进,就像 一样\[\]
。
这是一个简单的例子:
\documentclass{minimal}
\usepackage{lipsum}
\setlength{\parskip}{50pt}
\newcommand{\example}[1]{%
\ifvmode\else\par\vspace{-\parskip}\fi\vspace{\abovedisplayskip}
\noindent\begin{minipage}{\linewidth}#1\end{minipage}
\par\addvspace{\belowdisplayskip}}
\begin{document}
% There should be small spaces after AAA and before BBB
AAA
\example{\lipsum[1]}
BBB
% There should be a large space after AAA and a small one before BBB
% And BBB shouldn't be indented
AAA
\example{\lipsum[1]}
BBB
% There should be a small space after AAA and a large one before BBB
AAA
\example{\lipsum[1]}
BBB
\end{document}
答案1
执行此操作的标准方法是将您的环境定义为trivlist
,几乎所有的乳胶显示环境(逐字,中心,引用,..)都被定义为trivlists(特殊的单项版本列表)正是出于这个原因。
trivlist 代码检测列表前是否有段落分隔符,如果有,则前后是否有段落间距,但如果列表前没有段落分隔符,则列表\par
后的内部将被隐藏,并且以下文本的段落缩进将被抑制。
\begin{center}\end{center}
例如定义为
\def\center{\trivlist \centering\item\relax}
\def\endcenter{\endtrivlist}
答案2
这是一个可能的解决方案。我正在定义一个宏\tentativepar
,它将和插入并\par
设置为。此外,它还临时重新定义和(插入在每个段落的开头)以重置原始值(及其本身)。\parskip
\parindent
0pt
\par
\everypar
最终效果是\tentativepar
将插入一个段落分隔符,而不会跳过或缩进除非紧接着是另一个\par
。
以下是一个例子:
\documentclass{article}
\setlength{\parskip}{50pt}
%% vv We need to store a couple of values
\newskip\savedparskip
\newskip\savedparindent
\newtoks\savedeverypar
\makeatletter
\newcommand*\tentativepar{%
\par
\savedparskip\parskip %% <- store original parskip
\savedparindent\parindent %% <- store original parindent
\expandafter\savedeverypar\expandafter{\the\everypar}
%% ^^ store original \everypar
\parskip0pt %% <- set parskip to 0pt
\parindent0pt %% <- set parindent to 0pt
%% vv restore everything that was saved after the first \par
\def\par{%
\@restorepar %% <- restore original \par
\expandafter\everypar\expandafter{\the\savedeverypar}%
\parskip\savedparskip %% <- reset parskip
\parindent\savedparindent %% <- reset parindent
\par %% still insert a paragraph break
}%
%% vv or at the stat of the next paragraph
\expandafter\everypar\expandafter{%
\the\savedeverypar
\@restorepar %% <- restore original \par
\expandafter\everypar\expandafter{\the\savedeverypar}%
\parskip\savedparskip %% <- reset parskip
\parindent\savedparindent %% <- reset parindent
}
}
\makeatother
\newcommand{\example}[1]{%
\ifvmode\else\tentativepar\fi
\vspace{\abovedisplayskip}
\noindent\begin{minipage}{.5\linewidth}#1\end{minipage}%
\vspace{\belowdisplayskip}
\tentativepar
}
\begin{document}
AAA
\example{There should be small spaces after AAA and before BBB}
BBB
AAA
\example{There should be a large space after AAA and a small one before BBB. And BBB shouldn't be indented.}
BBB
AAA
\example{There should be a small space after AAA and a large one before BBB}
BBB
CCC
\end{document}