当要排版的输入文本与结构化模板分开时,输入是否可以确定其包含框的高度和宽度?
示例输入。要替换的问号(?)(Lua 或 TeX)。
The width of the parent box is ?
The height of the parent box is ?
几种可能的模板:
\ruledhbox to 10cm{\vbox to 4cm{ \input input }} % 10cm by 4cm
\ruledvbox to 4cm{\hsize=10cm \input input } % 10cm by 4cm
\framed
[width=10cm,
height=4cm,
align={middle,lohi},
offset=0.5cm]
{ \input input } % 9cm by 3cm
在箱子被存储之前,尺寸是没有意义的,所以这可能是开始的地方。
我对\aftergroup
+的扩展\lastbox
回答:
\typeset{\hbox to50pt{\vbox to40pt{\hbox to30pt{width: \parwd }}}}
{ \let\parht\askparent\let\parwd\askparent\let\pardp\askparent
\setbox0=\hbox to50pt{\vbox to40pt{\hbox to30pt{width: \parwd }}}
\hbox to50pt{\vbox to40pt{\hbox to30pt{width: \parwd }}}
}
{ \let\parht\askparent\let\parwd\askparent\let\pardp\askparent
\setbox0=\hbox to50pt{\vbox to40pt{\hbox to30pt{width: \parwd }}}
\hbox to50pt{\vbox to40pt{\hbox to30pt{width: \askparent }}}
}
{ \let\parht\askparent\let\parwd\askparent\let\pardp\askparent
\setbox0=\hbox to50pt{\vbox to40pt{\hbox to30pt{width: \parwd }}}
\hbox to50pt{\vbox to40pt{\hbox to30pt{width: } \afterafter }}
}
{ \let\parht\askparent\let\parwd\askparent\let\pardp\askparent
\setbox0=\hbox to50pt{\vbox to40pt{\hbox to30pt{width: \parwd }}}
\hbox to50pt{\vbox to40pt{\hbox to30pt{width: }} \after }
}
{ \let\parht\askparent\let\parwd\askparent\let\pardp\askparent
\setbox0=\hbox to50pt{\vbox to40pt{\hbox to30pt{width: \parwd }}}
\hbox to50pt{
\setbox\storelast=\vbox to40pt{\hbox to30pt{width: }}
\xdef\parht{\the\ht\storelast}
\xdef\parwd{\the\wd\storelast}
\xdef\pardp{\the\dp\storelast}
\ifvmode\nointerlineskip\fi\box\storelast}
}
{ \let\parht\askparent\let\parwd\askparent\let\pardp\askparent
\setbox0=\hbox to50pt{\vbox to40pt{\hbox to30pt{width: \parwd }}}
\hbox to50pt{
\setbox\storelast=\vbox to40pt{\hbox to30pt{width: }}
\xdef\parht{\the\ht\storelast}
\xdef\parwd{\the\wd\storelast}
\xdef\pardp{\the\dp\storelast}
\vbox to40pt{\hbox to30pt{width: }}}
}
答案1
当您使用来获取文本时,您可以使用和命令\framed
获取框中内容的宽度。此处的限制是,只有当或设置的长度大于 时,您才能获得可用的值。\framedwidth
\framedheight
width
height
0pt
\starttext
\startframed[width=200pt,height=80pt,offset=10pt,rulethickness=0.5pt]
Width: \framedwidth \par
Height: \framedheight
\stopframed
\stoptext
width
要获取和键的值,height
您可以使用\localwidth
和\localheight
命令。这里您应该注意,ConTeXt 会提供使用键设置的任何值,即当您设置width=fit
命令时,它会作为参数\localwidth
提供给您的值fit
。
\starttext
\startframed[width=200pt,height=80pt,offset=10pt,rulethickness=0.5pt]
Width: \localwidth \par
Height: \localheight
\stopframed
\stoptext
最后一个可能的值可用于框架的背景,但与以前的方法不同,即使使用类似的设置,您也可以获得正确的width
框架。height
width=fit
\defineoverlay
[boxdimensions]
[\vbox\bgroup
\hbox {Width: \overlaywidth}
\hbox{Height: \overlayheight}
\egroup]
\setupframed % don't make global framed settings in a document
[background=boxdimensions]
\starttext
\startframed[width=200pt,height=80pt,offset=10pt,rulethickness=0.5pt]
%
\stopframed
\stoptext
答案2
这个“解决方案”肯定不是通用的并且不是经过深思熟虑的,但它在简单的情况下对我有用,使用纯 TeX:
\newbox\storelast
\def\after{\setbox\storelast=\lastbox
{\globaldefs=1
\edef\parht{\the\ht\storelast}
\edef\parwd{\the\wd\storelast}
\edef\pardp{\the\dp\storelast}}
\ifvmode\nointerlineskip\fi\box\storelast}
\def\afterafter{\aftergroup\after}
\def\askparent{\aftergroup\afterafter}
\def\typeset#1{\let\parht\askparent\let\parwd\askparent\let\pardp\askparent
{\globaldefs=-1 \setbox0#1}#1}
之后,你可以用 排版模板\typeset{...}
。在输入中,你可以使用\parwd
、\parht
和\pardp
分别获取父框的宽度、高度和深度。 的参数\typeset
必须是一个盒子(必须以\hbox
,\vbox
... 开头)。
例如,我有一个名为的文件,input.tex
其中包含
width \parwd\ height \parht
。
然后,以下几行
\typeset{\hbox to50pt{\vbox to40pt{\hbox to30pt{\input input }}}}
\typeset{\vbox to50pt{\hbox to40pt{\vbox to30pt{\input input }}}}
打印(除了许多过满或未满的盒子)
width 30.0pt height 40.0pt
width 40.0pt height 30.0pt
正确。然而,
- 我不知道这对于更复杂的结构来说表现如何;
- 编辑:正如 Henri Menke 在评论中指出的那样,对框进行两次排版(使用 后跟
\setbox0#1
)#1
可能会导致意外的副作用,例如如果框中的计数器增加。我尝试通过使用 评估\setbox0#1
组中的 来减少该问题\globaldefs=-1
,但如果使用依赖于全局定义的包(例如 ),这可能会改变框的尺寸,从而tikz
产生不正确的结果; - 它假设命令
\parht
等是不在组内使用除了盒子创建的之外; - 它仅在父框为不在主垂直列表中因为它用来
\lastbox
确定盒子的尺寸,在外部垂直模式下它是空的。
对于最后一点,考虑上面的例子,但现在我们感兴趣的是最外层盒子的尺寸:
\typeset{\hbox to50pt{\vbox to40pt{\hbox to30pt{\input input }}}}
\typeset{\vbox to50pt{\hbox to40pt{\vbox to30pt{\input input }}}}
将打印
width 0.0pt height 0.0pt
width 0.0pt height 0.0pt
因为最外层的盒子设置为外部垂直模式。在这种情况下,你必须用另一个盒子包裹你的模板,比如
\typeset{\hbox{\hbox to50pt{\vbox to40pt{\hbox to30pt{}\input input }}}}
\typeset{\hbox{\vbox to50pt{\hbox to40pt{\vbox to30pt{}\input input }}}}
印刷
width 50.0pt height 40.0pt
width 40.0pt height 50.0pt
正如预期的那样。