\vtop \vsplit \vbox 的垂直顶部对齐

\vtop \vsplit \vbox 的垂直顶部对齐

嗯,我想有一个跨页迷你页面,所以我首先想到的是分割小页面所以可以,但我了解到你不能;所以我得可破坏的垂直框并在尝试的过程中了解到无法 vsplit 一个 parbox。现在我可以 \vsplit \vbox,但结果我不知道如何将其垂直对齐到顶部。我尝试了能找到的大多数常见 \vtop 语法模式,最终得出了这个 MWE:

\documentclass{article}
\usepackage{lipsum}
\usepackage{xcolor}
\usepackage{lua-visual-debug}
\pagecolor{yellow!10}
\begin{document}
\lipsum[1]

\newbox\myshortbox
\setbox\myshortbox=%
  \hbox {%to 0.2\textwidth {%
    \parbox[t]{0.2\textwidth}{%
      \hrule height 0pt width 0pt % ref for utter top alignment
      Blah blah blah,
      blah blah blah blah blah blah blah,
      Blah blah blah blah,
    }%
  }%
\newbox\mylongbox
\setbox\mylongbox=%
  \vbox { %\hbox {%to 0.7\textwidth{%
      \hsize=0.7\textwidth
      \hrule height 0pt width 0pt % ref for utter top alignment
      \lipsum[2-15]
    }%
\newbox\myspltbox % do a vsplit
\setbox\myspltbox=\vsplit\mylongbox to 0.5\textheight
\newbox\myvtopbox % align vertically on top
\setbox\myvtopbox=%
%   \vtop{\hsize=0.9\textwidth \copy\myshortbox\copy\myspltbox} %
% \box\myvtopbox % with this, below one another!
  \vtop{\hsize=0.2\textwidth \copy\myshortbox} %
\newbox\myvtopboxB %
\setbox\myvtopboxB=%
  \vtop{\hsize=0.7\textwidth \copy\myspltbox} %
\hbox{\box\myvtopbox \box\myvtopboxB}%

\end{document}

... 输出结果如下(单击可查看完整分辨率):

测试04a.png

... 而我希望短框与较长的分割框垂直对齐。我哪里做错了 - 我该如何实现这一点?

(在之前的尝试中,我认为我看到两个\parbox[t]s 可以对齐\vtop- 但我无法 vsplits \parbox,这就是我这样做的原因)。


下面我将转储代码,并附上导致上述 MWE 的注释——因为我在那里做了很多错误的假设,当我再次忘记所有关于盒子的事情时,我想再次参考这些假设:);希望没问题:

% http://www.tug.org/utilities/plain/cseq.html#vtop-rp
% https://tex.stackexchange.com/q/3202/minipage-spanning-across-pages
% https://tex.stackexchange.com/questions/36107/how-to-split-a-minipage
% https://tex.stackexchange.com/questions/20901/breakable-vboxes/
% http://stackoverflow.com/q/2034144/latex-how-to-create-boxes-fixed-w
% https://tex.stackexchange.com/q/34166/understanding-minipages-align-top
% https://tex.stackexchange.com/q/58310/top-aligning-text-of-two-parboxes
% https://tex.stackexchange.com/q/46480/setbox-vs-sbox-and-savebox
% https://tex.stackexchange.com/q/187692/why-cannot-i-vsplit-a-parbox
\documentclass{article}
\usepackage{lipsum}
% \usepackage{trace}
\usepackage{lua-visual-debug}
% \usepackage{unravel}

\begin{document}

\lipsum[1]

% "minipage environment because it guarantees that the text contained doesn't span pages"
% "rather the two pieces of the typeset minipage into two box registers."
% "However this can't be done with minipage, but only with lower level commands: \vbox and \vsplit."
% "A \vtop is indecomposable. TeX will not split it between two pages [93]."
% "A \box command adds the contents of the box to the current list, and it empties the box; The \copy command is similar to \box except \copy does not empty the box; Plain TeX has a \newbox command which reserves a box for a special purpose"
% "THE \setbox command puts material in a box register (\box0 to \box255). Box registers are local to a group. A box register is either void or it contains an \hbox, \vbox, or \vtop. Once material is placed in a box, it may be typeset or moved by \box, \copy, \vsplit, or one of the unbox commands"
%   \begingroup\setbox0\vbox\bgroup

%   %   % \traceon
%   %   % \unravel{\bgroup
%   %   \begin{minipage}[t]{0.2\textwidth}
%   %   Blah blah blah,
%   %   blah blah blah blah blah blah blah,
%   %   Blah blah blah blah,
%   %   \end{minipage}
%   %   % \egroup}
%   %   \begin{minipage}[t]{0.7\textwidth}
%   %   \lipsum[2-15]
%   %   \end{minipage}
%   %   % \traceoff

%   %   \vbox {% minipage[t]
%   %   % \hbox to 0.2\textwidth{% does not break text
%   %     \parbox{0.2\textwidth}{%
%   %     Blah blah blah,
%   %     blah blah blah blah blah blah blah,
%   %     Blah blah blah blah,
%   %     }%
%   %   }
%   %   \vbox {% minipage[t]
%   %     \parbox{0.7\textwidth}{%
%   %     \lipsum[2-15]
%   %     }%
%   %   }

%   \egroup
%   \typeout{\the\ht0,\the\textheight} % minipage 6.94444pt,550.0pt ; vtop, vbox: 1054.83333pt,550.0pt
%   \ifdim\ht0>0.5\textheight
%     \typeout{'ERE}
%     \setbox1\vsplit0 to 0.5\textheight
%     \vtop{\unvbox1}
%   \fi
%   \vtop{\unvbox0}

%   \endgroup

% \hbox{A} % left edge of page - not at parindent!

% "\setbox is the underlying TeX primitive so it does not read its arguments as a normal macro"; \parbox is LaTex2e
% "\sbox\boxa{aa} is like \setbox\boxa\hbox{....} so it supplies the \hbox"
% without the hbox with setbox here: "! A <box> was supposed to be here."
% can do without (\hbox) "to 0.2\textwidth"; parbox sets it
\newbox\myshortbox
% \setbox10=%
\setbox\myshortbox=%
  \hbox {%to 0.2\textwidth{%
    \parbox[t]{0.2\textwidth}{%
      \hrule height 0pt width 0pt % ref for utter top alignment
      Blah blah blah,
      blah blah blah blah blah blah blah,
      Blah blah blah blah,
    }%
  }%
%
%   \setbox\myshortbox=%
%   %   \hbox to 0.2\textwidth{ % doesn't break lines at all! regardless of \hsize; needs \vrule
%   %       \vrule height 0pt width 0pt % ref for utter top alignment
%     \vbox { % \vbox{\hsize - text breaking not really good
%         \hsize=0.2\textwidth
%         \hrule height 0pt width 0pt % ref for utter top alignment
%         Blah blah blah,
%         blah blah blah blah blah blah blah,
%         Blah blah blah blah,
%     }%
%   %

% NOTE: the long vboxes have a longer depth than height!
% NOTE: sizes of box registers dissapear as soon as another setbox kicks in!:

% \typeout{10: \the\ht10, \the\dp10; \the\textheight}
\typeout{10: \the\ht\myshortbox, \the\dp\myshortbox; \the\textheight}
% 10: 6.94444pt, 49.94444pt; 550.0pt

\newbox\mylongbox
% \setbox11=%
\setbox\mylongbox=%
  % if I use only hbox, or vbox{hbox, boxes will stick to the left margin
  % if I use only vbox, or \vbox {\hsize=0.7\textwidth, then boxes indent with \parindent
  \vbox { %\hbox {%to 0.7\textwidth{%
    %\parbox[t]{0.7\textwidth}{% cannot \vsplit parbox
      \hsize=0.7\textwidth
      \hrule height 0pt width 0pt % ref for utter top alignment
%       \lipsum[2]
      \lipsum[2-15]
    }%
  %}%}%
% \copy11 % typesets!
% \copy\mylongbox

% \typeout{10: \the\ht10, \the\dp10; 11: \the\ht11, \the\dp11; \the\textheight}
\typeout{10: \the\ht\myshortbox, \the\dp\myshortbox; 11: \the\ht\mylongbox, \the\dp\mylongbox; \the\textheight}
% 10: 0.0pt, 0.0pt; 11: 6.94444pt, 120.0pt; 550.0pt
% 10: 0.0pt, 0.0pt; 11: 6.94444pt, 1981.94444pt; 550.0pt

% if we want to split, probably should do it here:
%\global\splittopskip=0pt
%\splitmaxdepth=0.5\textheight
\newbox\myspltbox

% \setbox12=\vsplit11 to 0.5\textheight
% \setbox12=\vsplit\mylongbox to 0.5\textheight
\setbox\myspltbox=\vsplit\mylongbox to 0.5\textheight
% 10: 0.0pt, 0.0pt; 11: 0.0pt, 0.0pt; 12: 275.0pt, 1981.94444pt; 550.0pt % without splitmaxdepth
% 10: 0.0pt, 0.0pt; 11: 0.0pt, 0.0pt; 12: 275.0pt, 275.0pt; 550.0pt % with splitmaxdepth
% \copy11
% \copy\mylongbox

% \typeout{10: \the\ht10, \the\dp10; 11: \the\ht11, \the\dp11; 12: \the\ht12, \the\dp12; \the\textheight}
\typeout{10: \the\ht\myshortbox, \the\dp\myshortbox; 11: \the\ht\mylongbox, \the\dp\mylongbox; 12: \the\ht\myspltbox, \the\dp\myspltbox; \the\textheight}
% 10: 0.0pt, 0.0pt; 11: 0.0pt, 0.0pt; 12: 275.0pt, 275.0pt; 550.0pt

% \setbox13=\vtop{\hsize=0.9\textwidth \box10\box11} % nothing if splitting

% \typeout{10: \the\ht10, \the\dp10; 11: \the\ht11, \the\dp11; 13: \the\ht13, \the\dp13; \the\textheight}
\typeout{10: \the\ht\myshortbox, \the\dp\myshortbox; 11: \the\ht\mylongbox, \the\dp\mylongbox; 13: \the\ht\myvtopbox, \the\dp\myvtopbox; \the\textheight}
% 10: 0.0pt, 0.0pt; 11: 0.0pt, 0.0pt; 13: 6.94444pt, 120.0pt; 550.0pt

% note: two refs to box10 are not typeset twice! unless \copy is used (because \box is emptied after use)
% \unvbox13 % does not break from last paragraph
% \hbox{\box10\box13} % breaks from last paragraph
\vbox{ \box\myshortbox\box\myvtopbox} % breaks from last paragraph

\end{document}


%  \@iminipage [t]{0.2\textwidth }
%  \@iiiminipage {t}\relax [s]{0.2\textwidth }
%  [===== Step 76 =====] \@iiiminipage = macro:#1#2[#3]#4->\leavevmode \...
% <| {\begingroup
% ||
% |> \leavevmode \@pboxswfalse \setlength \@tempdima {0.2\textwidth }\def
% |> \@mpargs {{t}{\relax }[s]{0.2\textwidth }}\setbox \@tempboxa \vbox \bgroup
% |> \color@begingroup \hsize \@tempdima \textwidth \hsize \columnwidth \hsize
% |> \@parboxrestore \def \@mpfn {mpfootnote}\def \thempfn {\thempfootnot...

% [===== Step 77 =====] \leavevmode = macro:->\unhbox \voidb@x
% [===== Step 78 =====] \unhbox = \unhbox : \everypar={}
% [===== Step 91 =====] \textwidth = \dimen80= 345.0pt
% [===== Step 92 =====] Set \@tempdima(\dimen14)=68.99895pt
% [===== Step 94 =====] \def \@mpargs {{t}{\relax }[s]{0.2\textwidth }}
% [===== Step 95 =====] Set \@mpargs=macro:->{t}{\relax }[s]{0.2\textwi...
% <| {\begingroup
% ||
% |> \setbox \@tempboxa \vbox \bgroup \color@begingroup \hsize \@tempdima
% |> \textwidth \hsize \columnwidth \hsize \@parboxrestore \def \@mpfn
% |> {mpfootnote}\def \thempfn {\thempfootnote }\c@mpfootnote \z@ \let
% |> \@footnotetext \@mpfootnotetext \let \@listdepth \@mplistdepth
% [===== Step 99 =====] \setbox 12=\vbox {
% [===== Step 314 =====] back_input: \expandafter \@iiiparbox
% <| {\begingroup \setbox 12=\vbox {Blah blah blah, blah blah blah blah blah
% <| blah blah, Blah blah blah blah, \par }
% ||
% |> \@iiiparbox {t}{\relax }[s]{0.2\textwidth }{\unvbox \@tempboxa
% |> }\@checkend {minipage}\expandafter \endgroup \if@endpe \@doendpe \fi
% |> \if@ignore \@ignorefalse \ignorespaces \fi  \egroup
% [===== Step 315 =====] \@iiiparbox = \long macro:#1#2[#3]#4#5->\leavev...
% <| {\begingroup \setbox 12=\vbox {Blah blah blah, blah blah blah blah blah
% <| blah blah, Blah blah blah blah, \par }
% ||
% |> \leavevmode \@pboxswfalse \setlength \@tempdima {0.2\textwidth
% |> }\@begin@tempboxa \vbox {\hsize \@tempdima \@parboxrestore \unvbox
% |> \@tempboxa \@@par }\ifx \relax \relax \else \setlength \@tempdimb {\relax
% |> }\edef \@parboxto {to\the \@tempdimb }\fi \if tb\vbox \else \if tt\vtop
% |> \else \ifm... (284 chars)
% [===== Step 494 =====] \egroup = end-group character }
% <| {\begingroup \setbox 12=\vbox {Blah blah blah, blah blah blah blah blah
% <| blah blah, Blah blah blah blah, \par }\begingroup \setbox 12=\vbox {\par
% <| }\vtop {}\@end@tempboxa \endgroup  }
% ||
% |>
% [===== The end! =====]

答案1

这和您想要得到的东西类似吗?

\documentclass{article}
\usepackage{microtype}
\usepackage{kantlipsum}

\begin{document}
\kant[1]

\newbox\mylongbox
\setbox\mylongbox=\vbox{
   \hsize=0.7\textwidth
   \kant[2-4]
}

\noindent\parbox[t]{0.2\textwidth}{%
   Blah blah blah,
   blah blah blah blah blah blah blah,
   Blah blah blah blah,
}%
\newbox\myspltbox % do a vsplit
\setbox\myspltbox=\vsplit\mylongbox to 0.5\textheight
\hskip0.1\textwidth\vtop{\unvbox\myspltbox}

\moveright0.3\textwidth\box\mylongbox

\end{document}

在此处输入图片描述

答案2

大多数不对称的两列布局最好通过列表环境来处理。

在此处输入图片描述

这样就可以在主流程中自然地进行分页,而无需猜测在哪里进行 vsplit。但是,如果有可能在前几行发生分页,则您需要更加努力地防止这种情况发生,否则悬挂的 parbox 会覆盖页脚。

\documentclass{article}
\usepackage{microtype}
\usepackage{kantlipsum}

\newenvironment{foo}
              {\list{}{\leftmargin.3\textwidth}%
               \labelwidth.2\textwidth
               \labelsep.1\textwidth
               \def\makelabel##1{\smash{\parbox[t]{.2\textwidth}{##1}}\hfill}%
               }
               {\endlist}

\begin{document}
\kant[1]

\begin{foo}
\item[Blah blah blah,
   blah blah blah blah blah blah blah,
   Blah blah blah blah]
\kant[2-4]
\end{foo}

\end{document}

答案3

使用。这可以跨页面分解,并且可以利用和tcolorbox的所有优点,如边框、背景颜色等。tikztcolorbox

\documentclass{article}
\usepackage{xcolor}
\usepackage{kantlipsum}
\usepackage[many]{tcolorbox}

%% splitbox---
\tcbuselibrary{skins,breakable}
\newtcolorbox{splitbox}[1][]{
    colback=white,
    left=0.5ex,
    top=0pt,
    arc=0pt,
    outer arc=0pt,
    enlarge left by=0.25\textwidth,
    enlarge right by=-\dimexpr0.25\textwidth+\parindent\relax,
    right=\dimexpr0.25\textwidth+\parindent\relax,
    leftrule=0pt,
    rightrule=0pt,
    toprule=0pt,
    bottomrule=0pt,
    breakable,
    nobeforeafter,
    enhanced jigsaw,
    overlay unbroken and first={
      \node[anchor=north east,inner ysep=0pt,align=left,text width=0.245\textwidth]
        at ([yshift=-0.55ex]frame.north west) {#1};
    },
    before=\vskip2\itemsep\noindent
  }

\begin{document}
\kant[1]

\begin{splitbox}[%
   Blah blah blah,
   blah blah blah blah blah blah,
   Blah blah blah blah blah,
   ]%
\kant[2-4]
\end{splitbox}

\end{document}

在此处输入图片描述

答案4

我认为我找到了一种解决方法;上面的 MWE 中需要更改的只是以下代码:

\setbox\myvtopboxB=%
  \vtop{\hsize=0.7\textwidth \copy\myspltbox} %

...需要更改为:

\setbox\myvtopboxB=%
  \vtop{
    \hsize=0.7\textwidth 
    \hrule height 0pt width 0pt 
    \copy\myspltbox
  }

基本上,之所以使用这些规则,是因为我在本站的其他地方读到,如果将它们放在 vbox 的首位,它们可以用作“总”垂直顶部对齐(而不是文本首行的基线)的参考。这样,我得到了所需的输出:

测试04b.png

无论如何 - 感谢lua-visual-debug输出,我可以看到一个大框,显然是为两个元素启动的,在我看来,短框\vfil底部缺少一个。所以我尝试插入一个\vfil 到处,但它并没有改变任何事情——直到我再次注意到这些参考资料,并尝试将它们插入到盒子中——最终,这个成功了。

因此,如果有知识渊博的人最终能对此提供更博学的评论,那就太好了......

相关内容