\sbox の奇妙な動作

\sbox の奇妙な動作

この質問は 2 つの関連する部分で構成されています。私はすでに元の問題を解決しましたが、それがどこから来たのか、なぜ解決策が機能するのかがまだわかりません。

パッケージを使用するsubcaptionと、2 つのサブテーブルを並べて配置できます。各サブテーブルには所定の幅が必要なので、さらに を使用してsavebox最初にテーブルを作成し、次にボックスの幅を測定して最適なサブテーブルの幅を取得し、最後にボックスの内容を印刷します。

\newsavebox{\tablebox}
\sbox{\tablebox}{
  \begin{tabular}{ccc}
      1st & 2nd & 3rd \\
      1   & 2   & 3   \\
      4   & 5   & 6   \\
      7   & 8   & 9   \\
  \end{tabular}
}
% create fitting subtable
\begin{subtable}{\wd\tablebox}
  \usebox{\tablebox}
  \caption{Subable}
\end{subtable}

しかし、pdflatex次のような警告が出始めました

段落 24 行目から 25 行目の \hbox が不足しています (悪さ 10000)

ここで、24 は がある行\useboxです。

これは意味がありません。なぜならサブテーブルの幅は正確に設定する必要があるからです。試行錯誤の結果、警告が発生するのは次の場合のみであることがわかりました。全て次の 3 つの条件が満たされます。

  1. 指定された構成は付録(つまり の後\appendix)で使用されます。
  2. パッケージcleverefがロードされました。
  3. %行末にはありません\usebox

これらがなぜ影響を与えるのか全く理解できません...

2 番目の疑問は、エラーの場所を特定しようとしているときに浮かびました。2 番目のテーブルを\rule同じサイズの に置き換えました。少なくとも、それを実現しようとしました。幅 ( {\wd\tablebox}) は問題ないように見えますが、置き換えたテーブルの高さ ( {\ht\tablebox}) が間違っています。あまりにも狭すぎます。なぜでしょうか。

最後に、説明したすべての効果を示す MWE です。実際のテーブルには警告はありませんが、同じ幅の%置換には警告があることに注意してください。\rule

\documentclass[english]{scrreprt}
\usepackage{babel}
\usepackage{subcaption}
\usepackage{cleveref}

\begin{document}
\appendix

\newsavebox{\tablebox}
\begin{table}
  % prepare table
  \sbox{\tablebox}{
    \begin{tabular}{ccc}
        1st & 2nd & 3rd \\
        1   & 2   & 3   \\
        4   & 5   & 6   \\
        7   & 8   & 9   \\
    \end{tabular}
  }
  % create fitting subtable
  \begin{subtable}{\wd\tablebox}
    \usebox{\tablebox}% no warning for this table
    \caption{Left Table}
  \end{subtable}
  %
  \hspace{2ex}
  %
  % create fitting subtable
  \begin{subtable}{\wd\tablebox}
    \rule{\wd\tablebox}{\ht\tablebox}
    \caption{Right Table}
  \end{subtable}

  \caption{Two Tables}
\end{table}

\end{document}

答え1

アンダーフル \hbox

問題は、cleveref不要なスペースを設定するパッケージです。行は、行全体を埋めるオブジェクトで始まります。通常、次の\caption呼び出しは前の段落を終了し、プロセス内の最新のスペースを削除します。ただし、前のコードによって\parスペースがある場合は、\caption\cleveref1つ段落の終わりのスペースは削除されます。他のスペースは改行を引き起こし、新しい行の先頭で削除されます。しかし、新しい行はすでに始まっており、完全に空であるため、LaTeX は . というエラーを出しますUnderfull \hbox

単純な TeX モデルの例:

\showboxdepth=1000
\showboxbreadth=1000
\tracingonline=1
\setbox0=\vbox{%
  \noindent
  \vrule height 1pt width \hsize\relax
  \space\space
}
\showbox0
\csname @@end\endcsname\end

TeX は警告として出力します:

Underfull \hbox (badness 10000) in paragraph at lines 5--8

\hbox(0.0+0.0)x469.75499
.\glue(\rightskip) 0.0

ボックス 0 には次の内容が含まれます。

> \box0=
\vbox(13.0+0.0)x469.75499
.\hbox(1.0+0.0)x469.75499
..\rule(1.0+*)x469.75499
..\glue(\rightskip) 0.0
.\penalty 300
.\glue(\baselineskip) 12.0
.\hbox(0.0+0.0)x469.75499
..\glue(\rightskip) 0.0

! OK.
l.9 \showbox0

垂直ボックス ( \vbox)内では\noindent、インデントなしで新しい段落が始まります。ボックスの最後で、TeX は段落を終了します (暗黙的に)。次に、TeX は最後のスペースを削除します (暗黙的に)。この場合、2 番目\parが削除され、代わりにスペースが追加されます。改行前の段落には次の内容が含まれます。\unskip\space\parfillskip

<\vrule ...> <\space> <\hskip\parfillskip>

ルールは行全体を埋めるため、TeX はルールの後の行をスペースの前で折り返します。新しい行の先頭ではスペースが削除されるため、との両方 <\space><\hskip\parfillskip>削除されます。行には、伸縮可能なコンポーネントを含まない自動的に挿入された のみが含まれます\rightskip。警告のボックスを参照してください。

\hbox(0.0+0.0)x469.75499
.\glue(\rightskip) 0.0

したがって、ボックスには線を埋めるものは何も含まれておらず、線は不足

回避策:

  • 行末をコメント化します (すでに見つけています)。
  • \par最後にスペースを入れると、垂直モードでは後続のスペースは無視されます。
  • 読み込みcleveref方法:

    \edef\RestoreEndlinechar{\endlinechar=\the\endlinechar\relax}
    \endlinechar=-1 %
    \usepackage{cleveref}
    \RestoreEndlinechar
    

    (警告メッセージ内のスペースが欠落している可能性があります。)

2013/03/22 v0.18.9の不要な行末は、cleveref.styの定義の\refstepcounter@noargs196 行目と 242 行目にあります。

不完全なルール

ボックスに深さがあることを忘れているだけです。 のデフォルトの動作は、tabular中央にベースラインがあることです。ただし、[b]最後の要素が通常の行であり でない場合は、オプションを使用して、通常は小さな深さにすることもできます\hline

\raisebox深みを生み出すのに役立ちます:

    \raisebox{-\dp\tablebox}{%
      \rule{\wd\tablebox}{\dimexpr\ht\tablebox+\dp\tablebox\relax}%
    }%

関連情報