親ボックスの高さ/幅を取得する

親ボックスの高さ/幅を取得する

タイプセットされる入力テキストが構造化テンプレートとは別である場合、入力によってそのテキストを含むボックスの高さと幅を決定できますか?

入力例。置換する疑問符 (?) (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\framedheightwidthheight0pt

\starttext

\startframed[width=200pt,height=80pt,offset=10pt,rulethickness=0.5pt]
     Width: \framedwidth \par
    Height: \framedheight
\stopframed

\stoptext

ここに画像の説明を入力してください

widthおよびキーの値を取得するには、およびコマンドをheight使用できます。ここで、ConTeXt はキーで設定された値を返すことに注意してください。つまり、コマンドを設定すると、引数として返されます。\localwidth\localheightwidth=fit\localwidthfit

\starttext

\startframed[width=200pt,height=80pt,offset=10pt,rulethickness=0.5pt]
     Width: \localwidth \par
    Height: \localheight
\stopframed

\stoptext

ここに画像の説明を入力してください

最後の可能な値はフレームの背景に使用できますが、以前の方法とは異なり、などの設定でもフレームの正しいwidthまたは が取得されます。heightwidth=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 が指摘したように、ボックスを 2 回タイプセットすると (\setbox0#1の後に)、ボックス内のカウンターが増加するなど、予期しない副作用が発生する可能性があります。を使用したグループ内の#1を評価することでこの問題を軽減しようとしましたが、 などのグローバル定義に依存するパッケージが使用されている場合、ボックスのサイズが変更され、誤った結果が生じる可能性があります。\setbox0#1\globaldefs=-1tikz
  • コマンド\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

予想通り。

関連情報