
Ich möchte zwei Minipages in einen Text integrieren und dabei den Zeilenabstand beibehalten. Mit der \begin{minipage}[t]
Option ist der Abstand oberhalb der Minipages korrekt (grüner Kreis). Der Abstand darunter ist aber leider viel zu knapp (roter Kreis). Wie kann ich diesen auf den "normalen Grundlinienabstand" einstellen?
MWE:
\documentclass[a4paper,DIV=15,oneside,12pt]{scrartcl}
\usepackage[english]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{blindtext}
\usepackage{setspace}
\usepackage{enumitem}
\parskip 0pt
\parindent 0pt
\begin{document}
\pagestyle{empty}
\onehalfspacing
\blindtext\par
\begin{minipage}[t]{0.6\textwidth}
\blindtext
\end{minipage}\hfill
%Minipage 2
\begin{minipage}[t]{0.37\textwidth}
%\centering\rule{3cm}{2cm}
\begin{enumerate}[leftmargin=*,label=\alph{*}),itemsep=0pt,partopsep=0pt,topsep=0pt, parsep=0pt]
\item Test 1
\item Test 2
\end{enumerate}
\end{minipage}\par
\blindtext
\end{document}
Antwort1
Die Erklärung für Ihr Problem ist recht komplex. Wenn Sie möchten, können Sie einfach zur Lösung weiter unten springen.
Erläuterung
Wenn TeX Absätze setzt, verhält es sich ungefähr wie folgt: Zuerst wird der Absatz in Zeilen aufgeteilt (mithilfe eines komplexen Algorithmus mit einer Reihe von Parametern). Diese Zeilen werden in eine horizontale Box (oder \hbox
) gesetzt und die Boxen werden in die vertikale Hauptliste gesetzt. Die vertikale Hauptliste enthält das gesamte Material, aus dem die Seiten erstellt werden.
TeX versucht sicherzustellen, dass aufeinanderfolgende horizontale Kästchen in der vertikalen Liste so angeordnet sind, dass die Grundlinien jedes Kästchens \baselineskip
auseinander liegen. Wir können TeX verwenden, um dies in Aktion zu sehen.
Hier ist etwas einfaches TeX (kompilieren mit tex
oder pdftex
)
\showboxdepth=1
\showboxbreadth=10000
\tracingonline=1
\setbox0=\vbox{
First line\hfil\break
Second line
}
\showbox0
\end
Beim Kompilieren wird der Inhalt des Felds ausgedruckt, \vbox
in dem der Absatz in zwei Zeilen aufgeteilt wurde. Die \boxshow...
Parameter steuern, wie TeX den Inhalt des Felds druckt. Hier ist die Ausgabe.
> \box0=
\vbox(18.94444+0.0)x469.75499
.\hbox(6.94444+0.0)x469.75499, glue set 409.81047fil []
.\penalty 300
.\glue(\baselineskip) 5.05556
.\hbox(6.94444+0.0)x469.75499, glue set 420.31046fil []
Dies kann zunächst etwas kompliziert zu lesen sein, aber es sagt uns, dass dies \box0
ein ist, \vbox
das 18,94444pt hoch, 0pt tief und 469,75499pt breit ist. Das heißt (height+depth)xwidth
. Darin sehen wir die beiden \hbox
es, die den beiden Zeilen des Absatzes entsprechen. Dazwischen steht ein, \glue
das entspricht \baselineskip
. Beachten Sie, dass die Tiefe des oberen Felds plus der Kleber plus die Höhe des unteren Felds 12pt beträgt, also \baselineskip
.
TeX möchte nun auch nicht, dass aufeinanderfolgende Boxen zu nahe beieinander liegen, um eine Überlappung zu verhindern. Um dies zu verhindern, fügt TeX etwas Abstand zwischen die Boxen ein, wenn sie zu nahe beieinander liegen. Der genaue Algorithmus ist hier unwichtig, aber der Schlüssel ist, dass wir dieses Verhalten durch die Verwendung von deaktivieren können \nointerlineskip
.
Jetzt fragen Sie sich vielleicht, wie zwei Textfelder zu nahe beieinander liegen können. Das kann passieren, wenn Sie ein Feld mit Tiefe habenMauf einer Kiste mit HöheNso dassM+N> \baselineskip
.
Was hat das alles mit Ihrer Frage zu tun? Nun, TeX hat drei Arten von vertikalen Kästen, \vbox
, \vtop
, und \vcenter
. Lassen wir das mal außer Acht, \vcenter
da es ein bisschen seltsam ist. \vbox
und\vtop
unterscheiden sich darin, wo sie ihreAnhaltspunkt— das ist der Punkt, der ihrer Grundlinie entspricht. A \vbox
legt seinen Referenzpunkt auf den Referenzpunkt des letzten Felds in der Liste fest (also normalerweise die Grundlinie der letzten Zeile des Absatzes im Feld). Im Gegensatz dazu legt a \vtop
seinen Referenzpunkt auf den Referenzpunkt des ersten Felds in der Liste fest (also die Grundlinie der obersten Zeile im Absatz).
Wir können dies in Aktion sehen.
\noindent
\vbox{
\hsize=1in
Top line\hfill\break
Bottom line
}
\vtop{
\hsize=1in
Top line\hfill\break
Bottom line
}
\end
Sie können sehen, wie die untere Linie des linken Felds mit der oberen Linie des rechten Felds ausgerichtet ist.
Wir können wie zuvor ausdrucken, wie diese beiden Boxen aussehen.
Die linke Box:
\vbox(18.94444+0.0)x72.26999
.\hbox(6.94444+1.94444)x72.26999, glue set 16.4366fill []
.\penalty 300
.\glue(\baselineskip) 3.11111
.\hbox(6.94444+0.0)x72.26999, glue set 20.18652fil []
Die richtige Box:
\vbox(6.94444+12.0)x72.26999
.\hbox(6.94444+1.94444)x72.26999, glue set 16.4366fill []
.\penalty 300
.\glue(\baselineskip) 3.11111
.\hbox(6.94444+0.0)x72.26999, glue set 20.18652fil []
Der Hauptunterschied besteht in der Höhe und Tiefe dieser beiden Felder (der obersten Zeile jeder Auflistung).
Dies führt zu einem kniffligen Problem. Was passiert, wenn wir ein verwenden \vtop
und die nächste Zeile auf der Seite nur eine normale Zeile aus einem Absatz ist? Sehen wir uns das genauer an.
\parindent=0pt
\leavevmode
\vtop{
\hsize=1in
Top line\hfill\break
g Bottom line
}
Next line
\end
Ich habe die Einrückung unterdrückt und die zweite Zeile mit einem a begonnen, g
da sie unter die Grundlinie abfällt. Sehen wir uns die Boxen an, die erstellt werden. (Ich habe alles in ein a gepackt \vbox
und verwendet, \showbox
um die Ausgabe anzuzeigen. Daher gibt es unten eine zusätzliche äußere vbox. Ich habe \showboxdepth
um 1 erhöht, um die nächste innere Box anzuzeigen.)
\vbox(28.83333+0.0)x469.75499
.\vbox(6.94444+13.94444)x72.26999
..\hbox(6.94444+1.94444)x72.26999, glue set 36.4366fill []
..\penalty 300
..\glue(\baselineskip) 3.11111
..\hbox(6.94444+1.94444)x72.26999, glue set 11.85318fil []
.\glue(\parskip) 0.0 plus 1.0
.\glue(\lineskip) 1.0
.\hbox(6.94444+0.0)x469.75499, glue set 429.75491fil
..\hbox(0.0+0.0)x0.0
..\tenrm N
..\tenrm e
..\tenrm x
..\tenrm t
..\glue 3.33333 plus 1.66666 minus 1.11111
..\tenrm l
..\tenrm i
..\tenrm n
..\tenrm e
..\penalty 10000
..\glue(\parfillskip) 0.0 plus 1.0fil
..\glue(\rightskip) 0.0
Hier sind mehrere Punkte hervorzuheben:
- Die zweite
\vbox
entspricht unserer\vtop
; \parskip
Zwischen den Absätzen wurde ein A eingefügt.\baselineskip
Zwischen dem\vtop
und dem Folgenden,\hbox
das enthält, wurde kein eingefügtNext line
. Stattdessen steht ein\lineskip
. Das\lineskip
kommt daher, dass die Tiefe des\vtop
und die Höhe des Folgenden\hbox
größer sind als\baselineskip
. Wenn TeX versucht hätte, ihre Grundlinien\baselineskip
auseinander zu ziehen, würden sie sich überlappen.
Vielleicht können Sie jetzt das Problem mit Ihrem eigenen Code erkennen. Die Option minipage
mit der [t]
erzeugt ein \vtop
. TeX stellt also nicht sicher, dass die Grundlinie der untersten Zeile von der Grundlinie der folgenden Zeile entfernt minipage
ist . Stattdessen fügt es ein , was bei weitem nicht genug Platz ist.\baselineskip
\lineskip
Sie denken vielleicht, die Lösung sei, minipage
in zu wechseln [b]
, aber dann hätten Sie eine analoge Situation mit der Zeile oben.
Lösung
Die normale Methode, damit umzugehen, besteht darin, \strut
in die letzte Zeile des Absatzes ein einzufügen \vtop
, das Überspringen zwischen den Zeilen auszuschalten (d. h. die Verbindung zu unterdrücken ) und in die erste Zeile des nächsten Absatzes \lineskip
ein einzufügen .\strut
A \strut
fügt eine Box (nämlich \box\strutbox
) ein, die Höhe + Tiefe hat, was normalerweise gleich ist \baselineskip
. Dies wird in Ihrem Fall jedoch nicht funktionieren. Der Grund ist, \onehalfspacing
dass ändert sich \baselineskip
aber nicht berührt \box\strutbox
.
Wir müssen also die längere Box mit einem \vskip
der entsprechenden Länge beenden, Interline Skip ausschalten und verwenden \strut
. Was ist also die entsprechende Länge? Nun, wir wollen \baselineskip
= (Höhe von \box\strutbox
) + (Tiefe der letzten Box in \vbox
) + (unser explizites \vskip
).
Wir können das berechnen, indem wir ein temporäres \skip
Register (ich habe ausgewählt ) auf - - 0
setzen, wobei die Tiefe des letzten Felds in der vertikalen Liste ist (also die letzte Textzeile).\baselineskip
\ht\strutbox
\prevdepth
\prevdepth
Zwei letzte Vorbehalte.
- Dies funktioniert mit nicht
minipage
. Ich habe nicht untersucht, warum. enumerate
fügt normalerweise darüber Leerzeichen hinzu. Dies wird durchminipage
das Ausführen von verhindert\@setminipage
. Ich verstehe, wie\@setminipage
es funktioniert, aber ich verstehe nicht, wie man dieses Verhalten nur durch die Verwendungenumitem
der Optionen von verhindern kann. Stattdessen führt dieser Code also aus\@setminipage
.
Hier ist der vollständige Code.
\documentclass[a4paper,DIV=15,oneside,12pt]{scrartcl}
\usepackage[english]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{blindtext}
\usepackage{setspace}
\usepackage{enumitem}
\parskip 0pt
\parindent 0pt
\begin{document}
\pagestyle{empty}
\onehalfspacing
\blindtext\par
\noindent
\parbox[t]{0.6\textwidth}{
\blindtext
\skip0=\baselineskip
\advance\skip0 by-\prevdepth
\advance\skip0 by-\ht\strutbox\relax
\vskip\skip0
}\hfill
\parbox[t]{0.37\textwidth}{
\csname @setminipage\endcsname
\begin{enumerate}[leftmargin=*,label=\alph{*}),itemsep=0pt,partopsep=0pt,topsep=0pt, parsep=0pt]
\item Test 1
\item Test 2
\end{enumerate}
}
\par
\nointerlineskip
\strut\blindtext
\end{document}