\sbox 的奇怪行為

\sbox 的奇怪行為

這個問題由兩個相關的部分組成。我已經解決了最初的問題,但我仍然不明白它從何而來,也不明白該解決方案為何有效。

我使用這個subcaption包,這樣我就可以將兩個子表放在一起。每個子表都需要預期的寬度,因此我另外使用 asavebox首先建立表,然後測量框的寬度以獲得最佳的子表寬度,最後但並非最不重要的是列印框的內容。

\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 未滿 (badness 10000)

其中 24 是所在行\usebox

這是沒有意義的,因為子表應該具有完全正確的寬度。透過反覆試驗,我發現警告僅在以下情況發生:全部滿足以下三個條件之一:

  1. 給定的構造在附錄中使用(即在 後面\appendix)。
  2. cleveref已載入。
  3. %該行的末尾沒有\usebox

我不明白為什麼這些都會產生影響......

我的第二個問題是在嘗試尋找錯誤時出現的。我用相同大小的桌子替換了第二張桌子\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的某些程式碼中有空格\cleveref,則僅段落末尾的空格被刪除。另一個空格會導致換行,並在新行的開頭被刪除。但是新的生產線已經開始並且非常空,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 結束了該段落(隱式\par)。然後 TeX 刪除最後一個空格(隱式\unskip)以刪除最後一個空格。在這種情況下,第二個\space並添加空格\parfillskip。那麼break之前的段落包含:

<\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@noargs,第 196 行和第 242 行。

規則不完整

您只是忘記了,盒子可以有深度。 a 的預設行為tabular是中間的基線。但[b]如果最後一個元素是普通行而不是\hline.

\raisebox可以幫助創建深度:

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

相關內容