
Me gustaría integrar dos minipáginas dentro de un texto, manteniendo el interlineado. Usando la \begin{minipage}[t]
opción, el espacio encima de las minipáginas es correcto (círculo verde). Desafortunadamente, el espacio de abajo es demasiado corto (círculo rojo). ¿Cómo puedo ajustarlo al "salto de línea de base normal"?
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}
Respuesta1
La explicación de su problema es bastante compleja. Si lo desea, puede pasar a la solución a continuación.
Explicación
Cuando TeX compone párrafos, se comporta aproximadamente de la siguiente manera: primero divide el párrafo en líneas (usando un algoritmo complejo con varios parámetros). Estas líneas se colocan en un cuadro horizontal (o \hbox
) y los cuadros se colocan en la lista vertical principal. La lista vertical principal contiene todo el material a partir del cual se crean las páginas.
TeX intenta asegurarse de que los cuadros horizontales sucesivos en la lista vertical estén espaciados de manera que las líneas de base de cada cuadro estén \baselineskip
separadas. Podemos usar TeX para ver esto en acción.
Aquí hay algo de TeX simple (compilar con tex
o pdftex
)
\showboxdepth=1
\showboxbreadth=10000
\tracingonline=1
\setbox0=\vbox{
First line\hfil\break
Second line
}
\showbox0
\end
Cuando se compila, imprime el contenido del \vbox
interior del párrafo que se ha dividido en dos líneas. Los \boxshow...
parámetros controlan cómo TeX imprime el contenido de la caja. Aquí está el resultado.
> \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 []
Esto puede ser un poco complicado de leer al principio, pero lo que nos dice es que \box0
tiene \vbox
18.94444pt de altura, 0pt de profundidad y 469.75499pt de ancho. Eso es, (height+depth)xwidth
. Dentro podemos ver las dos \hbox
es correspondientes a las dos líneas del párrafo. Entre ellos hay un \glue
que corresponde a \baselineskip
. Tenga en cuenta que la profundidad del cuadro superior más el pegamento más la altura del cuadro inferior es 12 puntos, que es \baselineskip
.
Ahora TeX tampoco quiere que los cuadros sucesivos se acerquen demasiado para evitar que se superpongan. Para evitar esto, TeX insertará algo de espacio entre las cajas cuando estén demasiado juntas. El algoritmo exacto no es importante aquí, pero la clave es que podemos desactivar este comportamiento usando \nointerlineskip
.
Ahora quizás te preguntes cómo es posible que dos cuadros de texto estén demasiado juntos. Esto puede suceder si tienes una caja con profundidad.metroencima de una caja con alturanortetal quemetro+norte> \baselineskip
.
Entonces, ¿qué tiene que ver todo esto con tu pregunta? Bueno, TeX tiene tres tipos de cuadros verticales, \vbox
, \vtop
y \vcenter
. Ignoremos \vcenter
ya que es un poco extraño. \vbox
y \vtop
difieren en dónde colocan suspunto de referencia—Ese es el punto que corresponde a su línea de base. A \vbox
establece su punto de referencia para que sea el punto de referencia del último cuadro de la lista (es decir, normalmente la línea base de la última línea del párrafo del cuadro). Por el contrario, a \vtop
establece su punto de referencia como el punto de referencia del primer cuadro de la lista (es decir, la línea base de la línea superior del párrafo).
Podemos ver esto en acción.
\noindent
\vbox{
\hsize=1in
Top line\hfill\break
Bottom line
}
\vtop{
\hsize=1in
Top line\hfill\break
Bottom line
}
\end
Puede ver cómo la línea inferior del cuadro izquierdo está alineada con la línea superior del cuadro derecho.
Podemos imprimir cómo se ven estos dos cuadros como lo hicimos antes.
El cuadro de la izquierda:
\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 []
El cuadro correcto:
\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 []
La diferencia clave está en la altura y la profundidad de estos dos cuadros (la línea superior de cada listado).
Esto lleva a un problema complicado. ¿Qué sucede si usamos a \vtop
y la siguiente línea de la página es solo una línea normal de un párrafo? Vamos a ver.
\parindent=0pt
\leavevmode
\vtop{
\hsize=1in
Top line\hfill\break
g Bottom line
}
Next line
\end
Suprimí la sangría y comencé la segunda línea con a g
porque desciende por debajo de la línea de base. Miremos las cajas que se construyen. (Envolví todo en a \vbox
y solía \showbox
ver el resultado. Por lo tanto, hay un vbox externo adicional debajo. Aumenté \showboxdepth
en 1 para ver el siguiente cuadro interno).
\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
Hay varias notas aquí:
- El segundo
\vbox
corresponde a nuestro\vtop
; \parskip
Se insertó una A entre los párrafos; y- No
\baselineskip
se insertó entre el\vtop
y el siguiente\hbox
que contieneNext line
. En cambio hay un\lineskip
. Esto\lineskip
proviene del hecho de que la profundidad\vtop
y la altura de los siguientes\hbox
son mayores que\baselineskip
. Si TeX hubiera intentado\baselineskip
separar sus líneas de base, se superpondrían.
Quizás ahora puedas ver el problema con tu propio código. La minipage
opción [t]
produce un archivo \vtop
. Por lo tanto, TeX no garantiza que la línea de base de la línea inferior esté minipage
alejada \baselineskip
de la línea de base de la siguiente línea. En cambio, está insertando \lineskip
un espacio que no es suficiente.
Quizás estés pensando que la solución es cambiar a minipage
, [b]
pero entonces tendrás una situación análoga a la línea anterior.
Solución
El método normal para solucionar esto es poner un \strut
en la última línea del \vtop
, desactivar el salto entre líneas (es decir, inhibir el \lineskip
pegamento) y poner un \strut
en la primera línea del siguiente párrafo.
A \strut
inserta un cuadro (es decir \box\strutbox
, ) que tiene altura + profundidad que suele ser igual a \baselineskip
. Sin embargo, esto no funcionará en su caso. El motivo es \onehalfspacing
que cambia \baselineskip
pero no toca \box\strutbox
.
Entonces, lo que debemos hacer es finalizar el cuadro más largo con una \vskip
longitud adecuada, desactivar el salto entre líneas y usar \strut
. ¿Cuál es entonces la longitud adecuada? Bueno, queremos \baselineskip
= (altura de \box\strutbox
) + (profundidad del último cuadro en \vbox
) + (nuestro explícito \vskip
).
Podemos calcular eso configurando un \skip
registro temporal (elegí 0
) para que sea \baselineskip
- \ht\strutbox
- \prevdepth
donde \prevdepth
está la profundidad del último cuadro en la lista vertical (es decir, la última línea de texto).
Dos advertencias finales.
- Esto no funciona con
minipage
, no investigué por qué. enumerate
agregará espacio encima normalmente. Esto se inhibe medianteminipage
el cual se ejecuta\@setminipage
. Entiendo cómo\@setminipage
funciona, pero no entiendo cómo evitar este comportamiento simplemente usandoenumitem
las opciones de. Entonces, en lugar de eso, este código se ejecuta\@setminipage
.
Aquí está el código completo.
\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}