
Diese Frage besteht aus zwei miteinander verbundenen Teilen. Ich habe das ursprüngliche Problem bereits gelöst, verstehe aber immer noch nicht, woher es kam oder warum die Lösung funktioniert.
Ich verwende das subcaption
Paket, um zwei Untertabellen nebeneinander platzieren zu können. Jede Untertabelle benötigt die vorgesehene Breite, daher verwende ich zusätzlich ein , savebox
um zuerst die Tabelle zu erstellen, dann die Breite der Box zu messen, um die optimale Untertabellenbreite zu erhalten und zu guter Letzt den Inhalt der Box auszudrucken.
\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}
Allerdings pdflatex
begann mir die folgende Warnung zu geben
Nicht voll \hbox (Badness 10000) im Absatz in den Zeilen 24--25
wobei 24 die Linie ist, \usebox
bei der sich das befindet.
Das macht keinen Sinn, da die Untertabelle genau die richtige Breite haben sollte. Durch Ausprobieren habe ich herausgefunden, dass die Warnung nur dann auftritt, wennalleeine der folgenden drei Bedingungen gilt:
- Die angegebene Konstruktion wird im Anhang (also nach
\appendix
) verwendet. - Das
cleveref
Paket wird geladen. %
Am Ende der Zeile steht „Nein“\usebox
.
Ich verstehe nicht, warum das alles überhaupt einen Einfluss hat …
Meine zweite Frage tauchte bei der Suche nach dem Fehler auf. Ich habe die zweite Tabelle durch eine \rule
gleich große ersetzt, zumindest habe ich das versucht. Während die Breite ( {\wd\tablebox}
) für mich in Ordnung aussieht, stimmt die Höhe der Ersetzung ( {\ht\tablebox}
) nicht. Sie ist viel zu schmal. Warum?
Zum Schluss noch ein MWE, das alle beschriebenen Effekte demonstriert. Bitte beachten Sie, dass es aufgrund der keine Warnung für die eigentliche Tabelle gibt, %
aber eine für den Ersatz \rule
mit der gleichen Breite:
\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}
Antwort1
Unterfüllt \hbox
Das Problem ist ein Paket cleveref
, das ein unerwünschtes Leerzeichen setzt. Die Zeile beginnt mit einem Objekt, das die gesamte Zeile füllt. Normalerweise beendet der folgende \caption
Aufruf den vorherigen Absatz und entfernt dabei das letzte Leerzeichen. Wenn jedoch durch einen Code von vorher \par
ein Leerzeichen gesetzt wurde , dann nur\caption
\cleveref
einsLeerzeichen werden am Ende des Absatzes entfernt. Das andere Leerzeichen verursacht einen Zeilenumbruch und wird am Anfang der neuen Zeile entfernt. Die neue Zeile hat jedoch bereits begonnen und ist ziemlich leer, und LaTeX beschwert sich mit Underfull \hbox
.
Ein Beispiel für ein einfaches TeX-Modell:
\showboxdepth=1000
\showboxbreadth=1000
\tracingonline=1
\setbox0=\vbox{%
\noindent
\vrule height 1pt width \hsize\relax
\space\space
}
\showbox0
\csname @@end\endcsname\end
TeX gibt als Warnung aus:
Underfull \hbox (badness 10000) in paragraph at lines 5--8
\hbox(0.0+0.0)x469.75499
.\glue(\rightskip) 0.0
Und Box 0 enthält:
> \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
Innerhalb des vertikalen Felds ( \vbox
) \noindent
beginnt ein neuer Absatz ohne Einzug. Am Ende des Felds beendet TeX den Absatz (implizit \par
). Dann entfernt TeX ein letztes Leerzeichen (implizit \unskip
), um das letzte Leerzeichen zu entfernen. In diesem Fall das zweite \space
und fügt stattdessen das Leerzeichen hinzu \parfillskip
. Dann enthält der Absatz vor dem Umbruch:
<\vrule ...> <\space> <\hskip\parfillskip>
Die Regel füllt die komplette Zeile, daher bricht TeX die Zeile nach der Regel vor dem Leerzeichen ab. Am Anfang der neuen Zeile werden Leerzeichen entfernt, daher werden sowohl als auch
<\space>
entfernt <\hskip\parfillskip>
. Die Zeile enthält nur die automatisch eingefügten \rightskip
, die keine dehnbaren Komponenten enthalten, siehe das Feld der Warnung:
\hbox(0.0+0.0)x469.75499
.\glue(\rightskip) 0.0
Die Box enthält also nichts, was die Zeile füllen würde. Die Zeile istunterfüllt.
Problemumgehungen:
- Kommentieren Sie das Zeilenende (Sie haben es bereits gefunden).
\par
am Ende, dann werden nachfolgende Leerzeichen im vertikalen Modus ignoriert.Laden
cleveref
über:\edef\RestoreEndlinechar{\endlinechar=\the\endlinechar\relax} \endlinechar=-1 % \usepackage{cleveref} \RestoreEndlinechar
(Leerzeichen in Warnmeldungen können fehlen.)
Das unerwünschte Zeilenende von cleveref.sty
2013/03/22 v0.18.9 befindet sich in der Definition von \refstepcounter@noargs
, Zeile 196 und 242.
Unvollständige Regel
Du hast einfach vergessen, dass eine Box eine Tiefe haben kann. Das Standardverhalten einer Box tabular
ist die Grundlinie in der Mitte. Aber auch mit Option [b]
kannst du eine normalerweise geringe Tiefe haben, wenn das letzte Element eine normale Zeile und keine Box ist \hline
.
\raisebox
kann helfen, eine Tiefe zu erzeugen:
\raisebox{-\dp\tablebox}{%
\rule{\wd\tablebox}{\dimexpr\ht\tablebox+\dp\tablebox\relax}%
}%