假设您有以下布局:
灰色区域表示普通文本。橙色区域由一个或多个给定高度的文本框(插入)组成。一些教科书布局在这种框架框中显示高级或次要文本材料,可能跨越几页。
几年前,我与 Massimiliano Dominici 合作开发了一个名为朗梅达尔为了处理这种情况,需要在连续页面的上部放置一些文本流。该包讨论了意大利 TeX 用户组期刊 ArsTeXnica 上的这篇文章(意大利语)。手册的英文翻译不完整这里。
自从包裹框架我一直在思考这个问题:是否可以利用 mdframed 文本分割算法来实现上面提出的布局?
实际上,诀窍应该是将 mdframed 内部生成的框放入连续的空图形中。单个图形占据的页面顶部部分应该是用户可以使用的配置参数。
答案1
首先我使用的文件:
\documentclass{article}
\usepackage[framemethod=tikz,middlelinecolor=red,middlelinewidth=2pt,,everyline=true]{mdframed}
\usepackage{kantlipsum}
\usepackage{afterpage}
\input{mdframedaddon}
\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}
结果如下所示。
我添加了新的键,它们被调用:
\mdfsetup{setheight=true,settoheight=.5\textheight}
输出按以下定义完成:
\renewrobustcmd*\mdf@makebox@out[2][\linewidth]{%
\begin{figure}[t]
\noindent\hb@xt@\z@{%
\noindent\makebox[\dimexpr #1\relax][l]{#2}%
\hss}%
\end{figure}
}%
然而,这导致您只能将其用作h
浮点环境的标识符。我相信您会改进这一点。
完整的工作在所包含的文件中完成mdframedaddon.tex
。
这是完整的文件:
\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}%
\mdf@dolist{\mdf@advancelength@verticalmarginwhole}%
{%
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
\mdf@dolist{\mdf@advancelength@freevspace@sub}{%calculate with \dimen@
outerlinewidth,middlelinewidth,innerlinewidth,%
innertopmargin,splitbottomskip}%
\ifbool{mdf@everyline}%
{%
\ifbool{mdf@bottomline}%
{%
\advance\dimen@ by -\mdf@innerlinewidth@length%
\advance\dimen@ by -\mdf@middlelinewidth@length%
\advance\dimen@ by -\mdf@outerlinewidth@length%
}{}%
}{}%
\notbool{mdf@topline}%
{%
\advance\dimen@ by \mdf@innerlinewidth@length%
\advance\dimen@ by \mdf@middlelinewidth@length%
\advance\dimen@ by \mdf@outerlinewidth@length%
}{}%
% \advance\[email protected]\pageshrink
\ifdimless{\ht\mdf@splitbox@one+\dp\mdf@splitbox@one}{\dimen@}%
{\mdf@PackageWarning{You got a bad break\MessageBreak
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}%
% \advance\dimen@ by -1.8\baselineskip\relax%needed????????????????????
}{}%
\setbox\mdf@splitbox@save=\vbox{\unvcopy\mdf@splitbox@one}%
\splitmaxdepth\z@ \splittopskip\mdf@splittopskip@length%
\mdf@ignorevbadness%
\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}%
\mdf@ignorevbadness%
\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}%
\mdf@dolist{\mdf@advancelength@freevspace@add}%
{%used \dimen@
innerbottommargin,innerlinewidth,middlelinewidth,outerlinewidth,%
}%
\ifbool{mdf@everyline}%
{%
\ifbool{mdf@topline}%
{%
\advance\dimen@ by \mdf@innerlinewidth@length\relax%
\advance\dimen@ by \mdf@middlelinewidth@length\relax%
\advance\dimen@ by \mdf@outerlinewidth@length\relax%
}{}%
}{}%
\notbool{mdf@bottomline}%
{%
\advance\dimen@ by -\mdf@innerlinewidth@length\relax%
\advance\dimen@ by -\mdf@middlelinewidth@length\relax%
\advance\dimen@ by -\mdf@outerlinewidth@length\relax%
\relax%
}{}%
\ifdimgreater{\dimen@}{\mdf@freevspace@length}%
{%have a middle box
\advance\mdf@freevspace@length by -\mdf@splitbottomskip@length\relax%
\ifbool{mdf@everyline}%
{%
\ifbool{mdf@topline}%
{%
\advance\mdf@freevspace@length by -\mdf@innerlinewidth@length\relax%
\advance\mdf@freevspace@length by -\mdf@middlelinewidth@length\relax%
\advance\mdf@freevspace@length by -\mdf@outerlinewidth@length\relax%
}{}%
\ifbool{mdf@bottomline}%
{%
\advance\mdf@freevspace@length by -\mdf@innerlinewidth@length\relax%
\advance\mdf@freevspace@length by -\mdf@middlelinewidth@length\relax%
\advance\mdf@freevspace@length by -\mdf@outerlinewidth@length\relax%
\relax
}{}%
}{}%
\setbox\mdf@splitbox@save=\vbox{\unvcopy\mdf@splitbox@one}%
\splitmaxdepth\z@ \splittopskip\mdf@splittopskip@length%
\mdf@ignorevbadness%
\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
\mdf@PackageWarning{You got a bad break\MessageBreak
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}%
{%
\mdf@PackageWarning{You got a bad break\MessageBreak
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
结果如下: