mdframed 不会尝试拉伸或收缩其内容内的垂直空间

mdframed 不会尝试拉伸或收缩其内容内的垂直空间

当环境中的内容mdframed过满时,mdframed将会破坏页面而不是迭代地将垂直长度缩小到指定的最小值。

以下输出说明了该问题;左侧的框架环境是使用 生成的mdframed,它给出了Overfull \vbox警告,而右侧的框架环境是使用 创建的framed,它可以按预期工作:

mdframed 与 framed 溢出 \vbox 处理

两者对应的序言如下

\documentclass[12pt,fleqn,a4paper]{article}
\usepackage{amsmath}
\usepackage[a4paper,textwidth=16cm,vscale=0.75,vcentering]{geometry}
\usepackage[ntheorem,framemethod=tikz]{mdframed}
\usepackage[amsmath]{ntheorem}
\usepackage{parskip}

% Modified theorem header
\makeatletter
    \def\theorem@checkbold{}
\makeatother

\makeatletter
    \renewtheoremstyle{break}%
        {\item[\rlap{\vbox{\hbox{\hskip\labelsep \theorem@headerfont
            ##1\ ##2\theorem@separator}\hbox{\strut}}}]}%
        {\item[\rlap{\vbox{\hbox{\hskip\labelsep \theorem@headerfont
            ##1\ ##2:\ ##3\theorem@separator}\hbox{\strut}}}]}%
\makeatother

% Remove extra vertical skip at the end of frames
\let\svendmdframed\endmdframed
\makeatletter
    \def\endmdframed{\svendmdframed\unskip}
\makeatother

% Definition
\theoremstyle{break}
\theorembodyfont{\upshape}
\theoremsymbol{}
\theoremseparator{\medskip}
\newmdtheoremenv[%
    skipabove           = 2.0ex plus0.25ex minus0.25ex  ,%
    skipbelow           = 2.0ex plus0.25ex minus0.25ex  ,%
    leftmargin          = 0pt   ,%
    rightmargin         = 0pt   ,%
    innerleftmargin     = 10pt  ,%
    innerrightmargin    = 10pt  ,%
    innertopmargin      = 10pt  ,%
    innerbottommargin   = 10pt  ,%
    footnoteinside      = false ,%
    nobreak             = true  ,%
]{definition}{Definition}[section]

\documentclass[12pt,fleqn,a4paper]{article}
\usepackage{amsmath}
\usepackage[a4paper,textwidth=16cm,vscale=0.75,vcentering]{geometry}
\usepackage{framed}
\usepackage[amsmath,framed]{ntheorem}
\usepackage{parskip}

% Modified theorem header
\makeatletter
    \def\theorem@checkbold{}
\makeatother

\makeatletter
    \renewtheoremstyle{break}%
        {\item[\rlap{\vbox{\hbox{\hskip\labelsep \theorem@headerfont
            ##1\ ##2\theorem@separator}\hbox{\strut}}}]}%
        {\item[\rlap{\vbox{\hbox{\hskip\labelsep \theorem@headerfont
            ##1\ ##2:\ ##3\theorem@separator}\hbox{\strut}}}]}%
\makeatother

% Definition
\theoremstyle{break}
\theorembodyfont{\upshape}
\theoremsymbol{}
\theoremseparator{\medskip}
\newframedtheorem{definition}{Definition}[section]

文档内容如下:

\begin{document}
    \begin{definition}[Basic set operations.]
        Donec vehicula augue euneque.

        \bigskip
        {\textbf{Set equality:}}\\
        Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit,
        \begin{equation}
            A + B = C.
        \end{equation}
        Curabitur dictum gravida mauris. Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna.

        \bigskip
        {\textbf{Set union:}}\\
        Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit,
        \begin{equation}
            A + B = C.
        \end{equation}
        Curabitur dictum gravida mauris. Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna.

        \bigskip
        {\textbf{Set intersection:}}\\
        Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit,
        \begin{equation}
            A + B = C.
        \end{equation}
        Curabitur dictum gravida mauris. Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna.

        \bigskip
        {\textbf{Set difference:}}\\
        Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit,
        \begin{equation}
            A + B = C.
        \end{equation}
        Curabitur dictum gravida mauris. Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna.

        \bigskip
        {\textbf{Set complement:}}\\
        Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit,
        \begin{equation}
            A + B = C.
        \end{equation}
        Curabitur dictum gravida mauris. Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna.

        \bigskip
        {\textbf{Cartesian product:}}\\
        Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit,
        \begin{equation}
            A + B = C.
        \end{equation}
    \end{definition}
\end{document}

所以,问题是,有没有办法mdframed在采取分页符之前强制考虑拉伸或收缩垂直长度?

我使用是mdframed因为mdframed可以更好地控制参数framed

答案1

试试tcolorbox吧。我不知道它在这方面是否效果更好,但由于它更加复杂,所以mdframed机会很大。像这样的东西可以作为起点

 \usepackage[many]{tcolorbox} 
 \newtcbtheorem[number within=section]{definition}{My Theorem} 
  {colframe=black,colback=white,fonttitle=\bfseries,breakable}{th}

答案2

我已经从使用 切换ntheorem + mdframedntheorem + tcolorbox,因为breakable中的库tcolorbox具有先进的算法,该算法可以在拆分框架之前通过拉伸或收缩其内容内的垂直空间来测试框架是否适合页面。

如果有人也想转换,这里有一些提示:

共享柜台

您无需创建新的计数器,而是可以tcolorbox使用计数器名称tcb@cnt@<name>(tcolorbox 3.50,第 94 页)。例如,以下代码

\usepackage[amsmath,thmmarks]{ntheorem}
\usepackage[many]{tcolorbox}

% tcolorbox 'Definition' environment
\newtcbtheorem[number within=section]{definition}{Definition}{}{def}

% ntheorem 'Example' environment
\makeatletter
    \newtheorem{example}[tcb@cnt@definition]{Example}
\makeatother

使得环境中的计数器tcolorbox可以在ntheorem环境中重复使用。

用于转换ntheoremtcolorbox环境的正则表达式

典型的ntheorem环境如下hyperref所示:

\begin{theorem}[Leibniz formula for determinants.]\phantomsection\label{thm:leibniz_formula}

为了将上述语法转换为tcolorbox-兼容语法,如下所示

\begin{theorem}{Leibniz formula for determinants.}{leibniz_formula}

可以使用以下正则表达式:

匹配

(?<=(\\begin\{theorem\}))\[(.*?)\]\\phantomsection\\label\{thm:(.*?)\}

并将保存的匹配字符串替换为

\{\2\}\{\3\}

调整正则表达式以满足您自己的需要。大多数编辑器都内置了正则表达式支持。


编辑

为了完整起见,下面是转换结果的一个例子:

ntheorem + tcolorbox

提供了很好的推论框架tcolorbox;提供了随后的证明和示例及其整洁的结束标记ntheorem。请注意共享计数器。

还请注意,tcolorbox会自动修剪因使用环境结束框架内容而产生的多余垂直空间amsmath equation

tcolorbox很好。

相关内容