
Esta questão consiste em duas partes relacionadas. Já resolvi o problema original, mas ainda não entendi de onde veio ou por que a solução funciona.
Eu uso o subcaption
pacote para poder colocar duas subtabelas uma ao lado da outra. Cada subtabela requer a largura pretendida, portanto, adicionalmente, uso a savebox
para primeiro criar a tabela, depois medir a largura da caixa para obter a largura ideal da subtabela e, por último, mas não menos importante, imprimir o conteúdo da caixa.
\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}
Porém, pdflatex
começou a me dar o seguinte aviso
\hbox insuficiente (badness 10000) no parágrafo das linhas 24--25
onde 24 é a linha em \usebox
que está.
Isso não faz sentido porque a subtabela deve ter a largura exatamente correta. Por tentativa e erro descobri que o aviso só ocorre quandotodosdas três condições a seguir são válidas:
- A construção fornecida é usada no apêndice (ou seja, depois
\appendix
). - O
cleveref
pacote está carregado. - Não há
%
no fim da\usebox
linha.
Não entendo por que isso tem alguma influência...
Minha segunda pergunta surgiu ao tentar localizar o erro. Troquei a segunda mesa por uma \rule
do mesmo tamanho, ou pelo menos foi o que tentei conseguir. Embora a largura ( {\wd\tablebox}
) pareça boa para mim, a altura da substituição ( {\ht\tablebox}
) está errada. É muito estreito. Por que?
Finalmente, um MWE que demonstra todos os efeitos descritos. Observe que não há nenhum aviso para a tabela real devido ao %
mas há um para a substituição \rule
com a mesma largura:
\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}
Responder1
\hbox insuficiente
O problema é o pacote cleveref
que define um espaço indesejado. A linha começa com um objeto que preenche toda a linha. Normalmente as seguintes \caption
chamadas \par
encerram o parágrafo anterior e removem o último espaço do processo. No entanto, se houver um espaço em \caption
algum código \cleveref
anterior, então apenasumo espaço é removido no final do parágrafo. O outro espaço causa uma quebra de linha e é removido no início da nova linha. Mas a nova linha já começou e está bastante vazia e o LaTeX reclama com Underfull \hbox
.
Um exemplo de modelo TeX simples:
\showboxdepth=1000
\showboxbreadth=1000
\tracingonline=1
\setbox0=\vbox{%
\noindent
\vrule height 1pt width \hsize\relax
\space\space
}
\showbox0
\csname @@end\endcsname\end
TeX imprime como aviso:
Underfull \hbox (badness 10000) in paragraph at lines 5--8
\hbox(0.0+0.0)x469.75499
.\glue(\rightskip) 0.0
E a caixa 0 contém:
> \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
Dentro da caixa vertical ( \vbox
) \noindent
inicia um novo parágrafo sem recuo. No final da caixa o TeX termina o parágrafo (implícito \par
). Então o TeX remove um último espaço (implícito \unskip
) para remover o último espaço. Neste caso, o segundo \space
e adiciona o espaço \parfillskip
. Então o parágrafo antes da quebra contém:
<\vrule ...> <\space> <\hskip\parfillskip>
A regra preenche a linha completa, portanto o TeX quebra a linha após a regra antes do espaço. No início da nova linha, os espaços são removidos, portanto, ambos
<\space>
e <\hskip\parfillskip>
são removidos. A linha contém apenas o componente inserido automaticamente \rightskip
que não contém componente extensível, veja a caixa do aviso:
\hbox(0.0+0.0)x469.75499
.\glue(\rightskip) 0.0
Assim, a caixa não contém nada que preencha a linha, a linha éinsuficiente.
Soluções alternativas:
- Comentando o final da linha (você já encontrou).
\par
no final, os espaços subsequentes serão ignorados no modo vertical.Carregando
cleveref
através de:\edef\RestoreEndlinechar{\endlinechar=\the\endlinechar\relax} \endlinechar=-1 % \usepackage{cleveref} \RestoreEndlinechar
(Podem faltar espaços nas mensagens de aviso.)
O final de linha indesejado de cleveref.sty
22/03/2013 v0.18.9 está localizado na definição de \refstepcounter@noargs
, linha 196 e 242.
Regra incompleta
Você simplesmente esqueceu que uma caixa pode ter profundidade. O comportamento padrão de a tabular
é a linha de base no meio. Mas também com a opção [b]
você pode ter uma profundidade geralmente pequena, se o último elemento for uma linha normal e não um arquivo \hline
.
\raisebox
pode ajudar a criar profundidade:
\raisebox{-\dp\tablebox}{%
\rule{\wd\tablebox}{\dimexpr\ht\tablebox+\dp\tablebox\relax}%
}%