我有块级命令,用 tikz 绘制的水平线包围一些内容。它在大多数情况下工作正常,但当我在分页符的位置使用它时,内容是一个columns
环境,ConTeXt 会生成一个几乎空白的页面。这是一个 MCVE:
\usemodule[tikz]
\usetikzlibrary[positioning,fit,calc]
\definestartstop[Solution][before={
\blank[0.5em,preference]
\starttikzpicture
\node[rectangle,draw=black,anchor=north west] (header) {\bfxx\ss Sample Solution};
\draw[line cap=rect,draw=black] (header.north east) ++(0,-\pgflinewidth/2) -- (\textwidth-\pgflinewidth,-\pgflinewidth/2);
\stoptikzpicture
\blank[0.5em,samepage]
},after={
\blank[0.125em,samepage]
\starttikzpicture
\draw[black] (0,0) -- (\textwidth-\pgflinewidth,0) -- ++(0,0.25cm);
\stoptikzpicture
}]
\starttext
\dontleavehmode \vfill
\blank[26.5cm]
Lorem Ipsum
\startSolution
\startcolumns[n=2]
\input Knuth
\stopcolumns
\stopSolution
\stoptext
生成的 PDF 如下所示:
第 1 和 2 页
第 3 页
如您所见,columns
尽管第二页(完全空白)上有足够的空间,但 ConTeXt 将整个块移至第三页。
从我的测试来看,问题似乎来自 tikz 和列的交互;如果我删除列,内容就会放在第二页;如果我用正常的替换 tikz 行,情况也是一样\hrule
。
我怎样才能解决这个问题?
答案1
这与 TikZ 无关。下面是一个显示相同行为的更简单示例:
\starttext
\dontleavehmode \vfill
\blank[26.5cm]
Lorem Ipsum
\vbox to \lineheight{Solution}
\startcolumns[n=2]
\input knuth
\stopcolumns
\stoptext
出现分页符的原因在于,在初始化期间\startcolumn
使用了:
\ifdim\dimexpr\pagetotal+\parskip+\openlineheight\relax<\pagegoal
\allowbreak
\else
\break
\fi
将其添加到测试文档中表明我们得到了相同的行为:
\starttext
\dontleavehmode \vfill
\blank[26.5cm]
Lorem Ipsum
\vbox to \lineheight{Solution}
\ifdim\dimexpr\pagetotal+\parskip+\openlineheight\relax<\pagegoal
\message{YES}%
\allowbreak
\else
\message{NO}%
\break
\fi
\input knuth
\stoptext
输出显示NO
,这意味着\break
正在插入 (而不是\allowbreak
)。
我还没有进一步测试,但我猜测会发生以下情况。ConTeXt(而不是 TeX)\startcolumn
在第一页时读取代码。然后检查页面上剩余的空间,并插入一个\break
。现在,在实际排版完成时,您会Solution
因为 而得到一个分页符\break
。
在以下两个例子中,我在\page
之前插入一个\vbox
(强制 TeX 弹出上一页),一切正常:
简单示例:
\starttext
\dontleavehmode \vfill
\blank[26.5cm]
Lorem Ipsum
\page
\vbox to \lineheight{Solution}
\ifdim\dimexpr\pagetotal+\parskip+\openlineheight\relax<\pagegoal
\message{YES}%
\allowbreak
\else
\message{NO}%
\break
\fi
\input knuth
\stoptext
原例:
\usemodule[tikz]
\usetikzlibrary[positioning,fit,calc]
\definestartstop[Solution][before={
\blank[0.5em,preference]
\starttikzpicture
\node[rectangle,draw=black,anchor=north west] (header) {\bfxx\ss Sample Solution};
\draw[line cap=rect,draw=black] (header.north east) ++(0,-\pgflinewidth/2) -- (\textwidth-\pgflinewidth,-\pgflinewidth/2);
\stoptikzpicture
\blank[0.5em,samepage]
},after={
\blank[0.125em,samepage]
\starttikzpicture
\draw[black] (0,0) -- (\textwidth-\pgflinewidth,0) -- ++(0,0.25cm);
\stoptikzpicture
}]
\starttext
\dontleavehmode \vfill
\blank[26.5cm]
Lorem Ipsum
\page
\startSolution
\startcolumns[n=2]
\input Knuth
\stopcolumns
\stopSolution
\stoptext
解决方法 1
现在我们知道了发生了什么,找到解决方法很简单。第一个解决方法是,如果页面上没有足够的空间,只需添加分页符即可。\testpagesync[n]
如果页面上没有足够的空间容纳行,可以使用强制分页符来完成此操作n
:
\definestartstop[Solution][before={
\testpagesync[5]
\blank[0.5em,preference]
\starttikzpicture
\node[rectangle,draw=black,anchor=north west] (header) {\bfxx\ss Sample Solution};
\draw[line cap=rect,draw=black] (header.north east) ++(0,-\pgflinewidth/2) -- (\textwidth-\pgflinewidth,-\pgflinewidth/2);
\stoptikzpicture
\blank[0.5em,samepage]
},after={
\blank[0.125em,samepage]
\starttikzpicture
\draw[black] (0,0) -- (\textwidth-\pgflinewidth,0) -- ++(0,0.25cm);
\stoptikzpicture
}]
解决方法 2
另一种解决方法是使用\startsimplecolumns ... \stopsimplecolumns
而不是\startcolumns ... \stopcolumns
。顾名思义,simplecolumns
适用于简单的列。因此,它们不处理浮点数等。根据用途,这可能就足够了。