# How to have the mdframed material flow in the top part of consecutive pages

Suppose you have the following layout:

The gray area represents normal text. The orange area consists of one or more text boxes (inserts) of given height. Some textbook layouts present advanced or secondary text material in such framed boxes, possibly spanning several pages.

A couple of years ago I developed, in collaboration with Massimiliano Dominici, a package called longmedal to handle this need to have some text flow on the upper part of consecutive pages. The package is discussed in this article on ArsTeXnica, the Italian TeX User Group Journal (in Italian). An incomplete English translation of the manual is found here.

Ever since the package mdframed came out I've been thinking to make this question: Is it possible to exploit the mdframed text splitting algorithm to achieve the layout presented above?

In practice, the trick should be taking the boxes produced internally by mdframed and putting them into consecutive empty figures. The top-fraction of the page occupied by the single figure should be a configuration parameter the user can play with.

-
I think you can do this. My problem I don't know how can I print the output always on top. –  Marco Daniel Aug 6 '12 at 17:42
@MarcoDaniel Probably with \begin{figure}[H] ... \end{figure}, setting \topfraction appropriately. Also, I guess the package afterpage could help here. –  agodemar Aug 6 '12 at 17:49
afterpage sounds good. I will try it. –  Marco Daniel Aug 6 '12 at 17:51

First of all my file which I used:

\documentclass{article}
\usepackage[framemethod=tikz,middlelinecolor=red,middlelinewidth=2pt,,everyline=true]{mdframed}
\usepackage{kantlipsum}
\usepackage{afterpage}
\mdfsetup{setheight=true,settoheight=.5\textheight}
\setcounter{totalnumber}{1}
\setcounter{topnumber}{1}
\begin{document}
\kant[1]
\kant[2]
\begin{mdframed}
\kant[2]
\kant[1]
\kant[2]
\kant[2]
\kant[1]
\kant[2]
\end{mdframed}
\kant[1]

\kant[2]

\kant[3]

\kant[4]
\end{document}


The result can be seen below.

I added to new keys which are called by:

\mdfsetup{setheight=true,settoheight=.5\textheight}


The output is done by the following definition:

\renewrobustcmd*\mdf@makebox@out[2][\linewidth]{%
\begin{figure}[t]
\noindent\hb@xt@\z@{%
\noindent\makebox[\dimexpr #1\relax][l]{#2}%
\hss}%
\end{figure}
}%


However this results, that you can only use h as an identifier for float environments. I am sure you will improve this.

The complete work is done in the included file mdframedaddon.tex.

This is the complete file:

\makeatletter
\mdf@dolist{\mdf@do@lengthoption}{%
{settoheight==0.5\textheight},%
}
\mdf@dolist{\mdf@do@booloption}{%
{setheight==false},%
}

\renewrobustcmd*\mdf@makebox@out[2][\linewidth]{%
\begin{figure}[t]
\noindent\hb@xt@\z@{%
\noindent\makebox[\dimexpr #1\relax][l]{#2}%
\hss}%
\end{figure}
}%

\renewrobustcmd*\detected@mdf@put@frame{%
\ifmdf@nobreak%Option nobreak=true?
\def\mdf@reserved@a{\mdf@put@frame@standalone}%
\else
\def\mdf@reserved@a{\mdf@put@frame}%
\ifx\@captype\@undefined
\def\mdf@reserved@a{\mdf@put@frame}%
\else
\mdf@PackageInfo{mdframed inside float  ^^J
mdframed uses option nobreak \mdframedpackagename}%
\def\mdf@reserved@a{\mdf@put@frame@standalone}%
\fi
\if@minipage%
\mdf@PackageInfo{mdframed inside minipage  ^^J
mdframed uses option nobreak \mdframedpackagename}%
\def\mdf@reserved@a{\mdf@put@frame@standalone}%
\fi%
\ifinner%
\mdf@PackageInfo{mdframed inside a box ^^J
mdframed uses option nobreak \mdframedpackagename}%
\def\mdf@reserved@a{\mdf@put@frame@standalone}%
\fi%
\fi%
\ifbool{mdf@setheight}{\def\mdf@reserved@a{\mdf@put@frame@setheight}}{}
\mdf@reserved@a%
}

\def\mdf@put@frame@setheight{\relax%
\ifvoid\mdf@splitbox@one\relax
\mdf@PackageWarning{The environment is empty\MessageBreak}%
\let\mdf@reserved@a\relax%
\else
\setlength\mdfboundingboxwidth{\wd\mdf@splitbox@one}%
\setlength{\mdf@verticalmarginwhole@length}%
{\dimexpr\ht\mdf@splitbox@one+\dp\mdf@splitbox@one\relax}%
{%
outerlinewidth,middlelinewidth,innerlinewidth,%
innertopmargin,innerbottommargin,%
innerlinewidth,middlelinewidth,outerlinewidth}%
\mdf@keeplines@single%
\ifdimless{\mdf@verticalmarginwhole@length}{\mdf@settoheight@length}%
{%passt auf Seite%
\begingroup\mdf@@setzref\mdf@putbox@single\endgroup%Output no break
\let\mdf@reserved@a\relax%
}%
{%
\def\mdf@reserved@a{\mdf@put@frame@i@height}%passt nicht auf Seite
}
\fi
\mdf@reserved@a%
}

\def\mdf@put@frame@i@height{%Box must be splitted
\setlength{\dimen@}{.5\textheight}%
\let\mdf@reserved@a\relax
outerlinewidth,middlelinewidth,innerlinewidth,%
innertopmargin,splitbottomskip}%
\ifbool{mdf@everyline}%
{%
\ifbool{mdf@bottomline}%
{%
}{}%
}{}%
\notbool{mdf@topline}%
{%
}{}%
\ifdimless{\ht\mdf@splitbox@one+\dp\mdf@splitbox@one}{\dimen@}%
because the last box will be empty\MessageBreak
you have to change it manually\MessageBreak
by changing the text, the space\MessageBreak
or something else}%
}{}%
\setbox\mdf@splitbox@save=\vbox{\unvcopy\mdf@splitbox@one}%
\splitmaxdepth\z@ \splittopskip\mdf@splittopskip@length%
\setbox\mdf@splitbox@two\vsplit\mdf@splitbox@one to \dimen@
\setbox\mdf@splitbox@two\vbox{\unvbox\mdf@splitbox@two}%
\setbox\mdf@splitbox@one\vbox{\unvbox\mdf@splitbox@one}%
\ifvoid\mdf@splitbox@one\relax%
\mdf@PackageWarning{You got a bad break because the splittet box
is empty^^J
You have to change the page settings^^J
like enlargethispage or something else^^J
the package increases do
enlargethispage{baselineskip}\MessageBreak}%
\fi%
\ifdim\wd\mdf@splitbox@two=\wd\mdf@splitbox@one\relax
\else%
\mdf@PackageInfo{You first box width is to small^^J
mdframed fixed it\MessageBreak}%
\setbox\mdf@splitbox@two=\vbox%
{%
\hrule \@height\z@ \@width\mdfboundingboxwidth\relax
\unvcopy\mdf@splitbox@two%
}%
\fi%
\begingroup\mdf@@setzref\mdf@putbox@first\endgroup%%
\mdf@put@frame@ii@height%
}
\def\mdf@put@frame@ii@height{%
\setlength{\mdf@freevspace@length}{\mdf@settoheight@length}%
\ifbool{mdf@repeatframetitle}%
{%
\toggletrue{mdf@notfirstframetitle}%
\splitmaxdepth\z@ \splittopskip\z@%
\setbox\mdf@splitbox@one=\vbox{\break\unvbox\mdf@splitbox@one}%
\setbox0=\vsplit\mdf@splitbox@one to \z@\relax%
\setbox\mdf@splitbox@one=\vbox{\unvbox\mdf@splitbox@one}
\setbox\mdf@splitbox@one\vbox%
{%
\vbox to \mdf@frametitleaboveskip@length{}
\unvcopy\mdf@frametitlebox\relax%
\mdf@@frametitlerule\relax%
\unvbox\mdf@splitbox@one\relax%
}%
\setbox\mdf@splitbox@one=\vbox{\unvbox\mdf@splitbox@one}%
}{}%
\setlength{\dimen@}{\dimexpr\ht\mdf@splitbox@one+\dp\mdf@splitbox@one\relax}%
{%used \dimen@
innerbottommargin,innerlinewidth,middlelinewidth,outerlinewidth,%
}%
\ifbool{mdf@everyline}%
{%
\ifbool{mdf@topline}%
{%
}{}%
}{}%
\notbool{mdf@bottomline}%
{%
\relax%
}{}%
\ifdimgreater{\dimen@}{\mdf@freevspace@length}%
{%have a middle box
\ifbool{mdf@everyline}%
{%
\ifbool{mdf@topline}%
{%
}{}%
\ifbool{mdf@bottomline}%
{%
\relax
}{}%
}{}%
\setbox\mdf@splitbox@save=\vbox{\unvcopy\mdf@splitbox@one}%
\splitmaxdepth\z@ \splittopskip\mdf@splittopskip@length%
\setbox\mdf@splitbox@two\vsplit\mdf@splitbox@one to \mdf@freevspace@length
\setbox\mdf@splitbox@two\vbox{\unvbox\mdf@splitbox@two}
\setbox\mdf@splitbox@one\vbox{\unvbox\mdf@splitbox@one}
\ifvoid\mdf@splitbox@one\relax%
\mdf@PackageWarning{You got a bad break because the splittet box is
empty^^J
You have to change the page settings^^J
like enlargethispage or something else^^J
the package increases do
\enlargethispage{\baselineskip}\MessageBreak}%
\setbox\mdf@splitbox@one=\vbox{\unvcopy\mdf@splitbox@save}%
\enlargethispage{\baselineskip}%
\def\mdf@reserved@a{\mdf@put@frame@ii}%
\else
\setbox\mdf@splitbox@two=\vbox%
{%
\hrule \@height\z@ \@width\mdfboundingboxwidth\relax
\unvcopy\mdf@splitbox@two%
}%
\begingroup\mdf@@setzref\mdf@putbox@middle\endgroup%
\def\mdf@reserved@a{\mdf@put@frame@ii}%
\fi
}%End middle box case
{%start last box case
\ifvoid\mdf@splitbox@one
because the last split box is empty\MessageBreak
You have to change the settings}%%
\setbox\mdf@splitbox@one=\vbox%
{%
\unvbox\mdf@splitbox@one%
\hrule \@height\z@ \@width\mdfboundingboxwidth
}%
\fi%
\ifdimless{\ht\mdf@splitbox@one}{1sp}%
{%
because the last split box is empty\MessageBreak
You have to change the settings}%

\let\mdf@reserved@a\relax%
\setbox\mdf@splitbox@one=\vbox%
{%
\unvbox\mdf@splitbox@one%
\hrule \@height\z@ \@width\mdfboundingboxwidth
}%
}{}%
\begingroup\mdf@@setzref\mdf@putbox@second\endgroup%
\hrule \@height\z@ \@width\hsize%
\let\mdf@reserved@a\relax%
}%
\mdf@reserved@a%
}

\makeatother


And here the result:

-
+1, Impressive work. Is that \makeafter before \begin{document} necessary? –  agodemar Aug 10 '12 at 18:44
@agodemar: Thanks. I removed the useless \makeatletter –  Marco Daniel Aug 10 '12 at 19:09
Looking forward to seeing this addon included in some future version of mdframed. Meanwhile, I'll experiment with this code. –  agodemar Aug 10 '12 at 21:05