使 mdframed 段落在间距方面表现得像普通段落

使 mdframed 段落在间距方面表现得像普通段落

我使用该mdframed包突出显示两侧都有规则的段落。但是,-environmentmdframed会为其内部的段落创建一个框,因此其周围的间距与普通段落的间距不同。

下面的代码显示了这个问题:

\documentclass{article}
\usepackage{mdframed}

\parindent=0pt
\newenvironment{note}{%
    \begin{mdframed}[leftmargin=\dimexpr-0.5em-3pt, innerleftmargin=0.5em,
                     rightmargin=\dimexpr-0.5em-3pt, innerrightmargin=0.5em,
                     linewidth=3pt,linecolor=red, topline=false, bottomline=false]%
}{\end{mdframed}}

\begin{document}
\Huge XYZ

XYZ

\begin{note}
XYZ
\end{note}

XYZ

xyz

\begin{note}
xyz
\end{note}

xyz
\end{document}

我猜想可以通过调整环境的内部边距/跳过选项来解决这个问题mdframed,但找到正确的值来让它表现得更好似乎相当棘手确切地就像一个普通的段落。有什么想法可以实现自然的段落间距吗?

编辑:为了更清楚起见,问题的部分是框架段落前后的行距。选择大字体和短段落时,您可以最清楚地看到问题。在我的示例中,框架块从它之前段落的文本底部开始,但两者之间应该有一些额外的空间/粘连。

相反的问题出现在框架段落的底部,它与下一个段落之间的空间太大。

答案1

这是我的版本:

\documentclass{article}
\usepackage{mdframed,lipsum}

\parindent=0pt
\newmdenv[leftmargin=\dimexpr-0.5em-3pt, innerleftmargin=0.5em,
          rightmargin=\dimexpr-0.5em-3pt, innerrightmargin=0.5em,
          linewidth=3pt,linecolor=red, topline=false, bottomline=false,
          innertopmargin=0pt,innerbottommargin=0pt,skipbelow=0pt,skipabove=0pt,
         ]{notex}
\newenvironment{note}
 {\par\vskip\dimexpr\dp\strutbox-\prevdepth\relax\notex\strut\ignorespaces}
 {\par\xdef\notetpd{\the\prevdepth}\endnotex\vskip-\notetpd\relax}

\begin{document}
\leavevmode\llap{\smash{\vrule depth7\baselineskip height0pt\hskip1em}}%
\lipsum*[2]
\begin{note}
\lipsum[2]
\end{note}
\leavevmode\llap{\smash{\vrule height\baselineskip\hskip1em}}%
\lipsum[2]
\end{document}

黑色规则只是为了表明对齐是正确的(它们不能太靠近文本,因为mdframed应用了白色背景)。

在此处输入图片描述

顶线放大图

在此处输入图片描述

底线之一

在此处输入图片描述

一开始,我们确保跳过 TeX 插入的胶水,并在note环境中的第一条线上添加一个支柱,这样基线之间的距离就正确了。最后,我们做类似的事情,同时考虑环境中最后一行的深度note

简要说明

mdframed将其块设置为\vbox插入主垂直列表中的 a;这通常会扰乱行间间距,因为 a\vbox的参考点位于其中最后一个框的基线处。该包试图采取巧妙措施不添加不必要的空格,但在这种情况下这还不够。

因此我们需要模拟 TeX 的正常行为。一个基线与下一个基线之间的距离是和的总和\dp\strutbox\ht\strutbox我们可以在第一行插入一个支柱,note使其具有正确的高度;但添加\dp\strutbox垂直空间通常会太多,因为之前的最后一行note可能有下降线。所以我们结束段落,以便\prevdepth(内部参数)包含最后一个贡献框(准确地说是最后一行)的深度。所以我们可以添加

\vskip\dp\strutbox-\prevdepth

一切就绪。最后我们要做类似的事情。我们结束段落并定义\notetpd包含的值\prevdepth,这样我们就可以删除具有该值的垂直空间,使所有内容重新同步。

答案2

通过使用该命令,\mdflength您可以设置leftmarginrightmargin只关注其他参数,或者根本不需要设置它们,并且仍然可以获得正确的间距。

\documentclass{article}
\usepackage[margin=1in]{geometry}
\usepackage{mdframed}
\usepackage{lipsum}
%%  This takes the approach of your MWE where you set the widths of the
%%  line and margins
\newenvironment{mynoteA}{\noindent\hspace*{\parindent}}{}
\surroundwithmdframed[linewidth=3pt,
                      linecolor=red,
                      topline=false,bottomline=false,
                       innerleftmargin=0.5em,innerrightmargin=0.5em,
                      leftmargin=\dimexpr-\mdflength{linewidth}-\mdflength{innerleftmargin},
                      rightmargin=\dimexpr-\mdflength{linewidth}-\mdflength{innerrightmargin}]{mynoteA}
%%  Here you let `mdframed` decide the values of linewidth and inner
%%  margins, but still the frame is set correctly.
\newenvironment{mynoteB}{\noindent\hspace*{\parindent}}{}
\surroundwithmdframed[linecolor=red,
                      topline=false,bottomline=false,
                      leftmargin=\dimexpr-\mdflength{linewidth}-\mdflength{innerleftmargin},
                      rightmargin=\dimexpr-\mdflength{linewidth}-\mdflength{innerrightmargin}]{mynoteB}
%%
\pagestyle{empty}
\begin{document}

\textbf{\Large{}No frame:}\par
\lipsum[1]

\textbf{\Large{}Here you preset the margins:}
\begin{mynoteA}%
\lipsum[1-2]
\end{mynoteA}

\textbf{\Large{}Here you let \texttt{mdframed} choose the lengths}
\begin{mynoteB}%
\lipsum[1-2]
\end{mynoteB}

\end{document}

有一个小问题,当您不设置为 时,它会变得明显\parindent0pt我试图修补它:我添加了\hspace*{\parindent}以使段落正确缩进:当设置为 时,它会按预期\parindent工作0pt

这就是结果。

在此处输入图片描述

我选择使用\surroundwithmdframed将内容所需的格式与框架所需的格式分开。您不必走这条路。您可以像在 MWE 中一样将所有内容放在一个环境中。

根据您编辑的问题,您可以使用更多参数来创建更接近您想要的视觉效果: innertopmargin以及skipabove底部的类似参数。

相关内容