如何让 mdframed 材料流到连续页面的顶部

如何让 mdframed 材料流到连续页面的顶部

假设您有以下布局: 多页插页示例

灰色区域表示普通文本。橙色区域由一个或多个给定高度的文本框(插入)组成。一些教科书布局在这种框架框中显示高级或次要文本材料,可能跨越几页。

几年前,我与 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

结果如下:

在此处输入图片描述

相关内容