3

When the content in an mdframed environment is overfull, mdframed will rather break the page instead of iteratively shrinking the vertical length up to the specified minimum.

The following output illustrates the problem; the framed environment on the left was generated using mdframed, which gave an Overfull \vbox warning, while that on the right was created using framed, which works as intended:

mdframed vs framed overfull \vbox handling

The corresponding preambles for both are

\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]

and

\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]

respectively. The document content is

\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}

So, the question is, is there a way to force mdframed to consider stretching or shrinking the vertical length before resorting to page break?

I use mdframed because mdframed provides better control of parameters over framed.

4
  • 2
    Try out tcolorbox instead. I have no idea if it works better in this respect, but as it is much more sophisticated then mdframed the chances are good. Something like this could be the starting point \usepackage[many]{tcolorbox} \newtcbtheorem[number within=section]{definition}{My Theorem} {colframe=black,colback=white,fonttitle=\bfseries,breakable}{th} Apr 1, 2015 at 16:46
  • Thank you for the suggestion. Stretchable vertical lengths within the content of a tcolorbox environment seem to work fine. Since completely switching from ntheorem + mdframed to tcolorbox is non-trivial for the existing documents, I would only resort to this solution if all else fails.
    – Isochronon
    Apr 1, 2015 at 19:08
  • @UlrikeFischer Okay, I am awestruck by the beautiful frames provided by tcolorbox, and proceeded to convert a total of 332 environments (definitions, theorems, corollaries and lemmata) across 19 files with a few clicks using regular expressions. If you would, please kindly write your suggestion as a short, proper answer. I am more than happy to accept it.
    – Isochronon
    Apr 2, 2015 at 23:27
  • @PYK You should really also post your solution as an answer. It is not, after all, part of your question. (You can still accept Ulrike Fischer's answer, but yours can serve as a more detailed extension of that.)
    – cfr
    Apr 3, 2015 at 1:45

2 Answers 2

1

Try out tcolorbox instead. I have no idea if it works better in this respect, but as it is much more sophisticated then mdframed the chances are good. Something like this could be the starting point

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

I have switched from using ntheorem + mdframed to ntheorem + tcolorbox, as the breakable library from tcolorbox has an advanced algorithm which tests whether or not a frame fits in a page by stretching or shrinking vertical spaces within its content before resorting to splitting the frame.

In case anyone would like to switch as well, here are some tips:

Shared counters

Instead of creating a new counter, you can access the counter initialized by a tcolorbox environment using the counter name tcb@cnt@<name> (tcolorbox 3.50, page 94). For example, the following code

\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

enables the counter from a tcolorbox environment to be reused in an ntheorem environment.

Regex for converting ntheorem to tcolorbox environments

A typical ntheorem environment with hyperref would look like this:

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

In order to convert the above syntax to a tcolorbox-compatible syntax like so

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

one could use the following regular expressions:

Match

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

and replace the saved matching strings with

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

Adapt the regex to suit your own needs. Most editors have a built-in regular expressions support.


Edit

For the sake of completeness, here is an example of the result of the conversion:

ntheorem + tcolorbox

The nice corollary frame is provided by tcolorbox; the ensuing proof and example with their neat endmarks are provided ntheorem. Notice the shared counter.

Also note that tcolorbox automatically trims the extra vertical space arising from ending the frame content with an amsmath equation environment.

tcolorbox is nice.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .