
В случаях, когда вводимый текст для набора отделен от структурированного шаблона, может ли ввод определять высоту и ширину содержащего его блока?
Пример ввода. Вопросительные знаки (?) для замены (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
правильно. Однако,
- Я понятия не имею, насколько хорошо это ведет себя для более сложных конструкций;
- Редактировать:Как отметил Анри Менке в комментариях, набор поля дважды (с
\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
как и ожидалось.