
Nos casos em que o texto de entrada a ser composto é separado do modelo estruturado, a entrada pode determinar a altura e a largura da caixa que o contém?
Um exemplo de entrada. Pontos de interrogação (?) a serem substituídos (Lua ou TeX).
The width of the parent box is ?
The height of the parent box is ?
Vários modelos possíveis:
\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
As dimensões não têm sentido até que a caixa seja armazenada, então esse é provavelmente o lugar para começar.
Minha expansão do \aftergroup
+\lastbox
responder:
\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: }}}
}
Responder1
Ao usar \framed
para seus textos você pode obter a largura do conteúdo da caixa com os comandos \framedwidth
e . \framedheight
Uma restrição aqui é que você obtém apenas valores utilizáveis quando as configurações width
ou height
contêm um comprimento maior que 0pt
.
\starttext
\startframed[width=200pt,height=80pt,offset=10pt,rulethickness=0.5pt]
Width: \framedwidth \par
Height: \framedheight
\stopframed
\stoptext
Para obter os valores das chaves width
e height
você pode usar os comandos \localwidth
e . \localheight
Aqui você deve estar ciente de que o ConTeXt entrega qualquer valor que tenha sido definido com a chave, ou seja, quando você define width=fit
os \localwidth
comandos, ele fornece fit
como argumento.
\starttext
\startframed[width=200pt,height=80pt,offset=10pt,rulethickness=0.5pt]
Width: \localwidth \par
Height: \localheight
\stopframed
\stoptext
O último valor possível pode ser usado para o fundo de um quadro, mas ao contrário dos métodos anteriores, você obtém o valor correto width
do height
quadro, mesmo com configurações como 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
Responder2
Esta "solução" certamente não é universal e bem pensada, mas funciona para mim em casos simples, com TeX simples:
\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}
Depois, você pode digitar o modelo com a extensão \typeset{...}
. Na entrada, você pode usar e \parwd
para obter a largura, altura e profundidade da caixa pai, respectivamente. O argumento de\parht
\pardp
\typeset
tem que ser uma caixa(tem que começar com \hbox
, \vbox
...).
Por exemplo, eu tenho um arquivo chamado input.tex
que contém
width \parwd\ height \parht
.
Então, as seguintes linhas
\typeset{\hbox to50pt{\vbox to40pt{\hbox to30pt{\input input }}}}
\typeset{\vbox to50pt{\hbox to40pt{\vbox to30pt{\input input }}}}
imprimir (além de muitas caixas com excesso/falta de preenchimento)
width 30.0pt height 40.0pt
width 40.0pt height 30.0pt
corretamente. No entanto,
- Não tenho ideia de como isso se comporta bem para construções mais complexas;
- Editar:Conforme apontado por Henri Menke nos comentários, digitar a caixa duas vezes (com
\setbox0#1
seguido de#1
) pode levar a efeitos colaterais inesperados, por exemplo, se os contadores forem aumentados na caixa. Tentei reduzir esse problema avaliando\setbox0#1
in a group com\globaldefs=-1
, mas isso pode alterar as dimensões da caixa se forem usados pacotes que dependem de definições globais, comotikz
, produzindo resultados incorretos; - assume que os comandos
\parht
etc.não usado dentro de um grupoalém daqueles criados pelas caixas; - só funcionará se a caixa pai fornão está na lista vertical principalcomo utiliza
\lastbox
para determinar as dimensões da caixa, que fica vazia no modo vertical externo.
Para o último ponto, considere o exemplo acima, mas agora estamos interessados nas dimensões da caixa mais externa:
\typeset{\hbox to50pt{\vbox to40pt{\hbox to30pt{\input input }}}}
\typeset{\vbox to50pt{\hbox to40pt{\vbox to30pt{\input input }}}}
iria imprimir
width 0.0pt height 0.0pt
width 0.0pt height 0.0pt
porque a caixa mais externa está definida no modo vertical externo. Neste caso, você teria que embrulhar seu modelo com outra caixa, como
\typeset{\hbox{\hbox to50pt{\vbox to40pt{\hbox to30pt{}\input input }}}}
\typeset{\hbox{\vbox to50pt{\hbox to40pt{\vbox to30pt{}\input input }}}}
impressão
width 50.0pt height 40.0pt
width 40.0pt height 50.0pt
como esperado.