\sbox의 이상한 동작

\sbox의 이상한 동작

이 질문은 두 가지 관련 부분으로 구성됩니다. 원래 문제를 이미 해결했지만 문제가 어디서 왔는지, 솔루션이 작동하는 이유를 여전히 이해하지 못합니다.

subcaption나는 두 개의 하위 테이블을 서로 옆에 놓을 수 있도록 패키지를 사용합니다 . 각 하위 테이블에는 의도한 너비가 필요하므로 추가로 a를 사용하여 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행 단락의 Underfull\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. 그런 다음 나누기 전 단락에는 다음이 포함됩니다.

<\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 의 원치 않는 줄 끝은 라인 196 및 242 cleveref.sty의 정의에 있습니다 .\refstepcounter@noargs

불완전한 규칙

당신은 상자가 깊이를 가질 수 있다는 사실을 잊어버렸습니다. a의 기본 동작 tabular은 중간에 있는 기준선입니다. 그러나 옵션을 사용하면 [b]마지막 요소가 일반 행이고 \hline.

\raisebox깊이를 만드는 데 도움이 될 수 있습니다.

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

관련 정보