Explicación

Explicación

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"?

ingrese la descripción de la imagen aquí

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 \baselineskipseparadas. Podemos usar TeX para ver esto en acción.

Aquí hay algo de TeX simple (compilar con texo pdftex)

\showboxdepth=1
\showboxbreadth=10000
\tracingonline=1

\setbox0=\vbox{
First line\hfil\break
Second line
}
\showbox0
\end

Cuando se compila, imprime el contenido del \vboxinterior 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 \box0tiene \vbox18.94444pt de altura, 0pt de profundidad y 469.75499pt de ancho. Eso es, (height+depth)xwidth. Dentro podemos ver las dos \hboxes correspondientes a las dos líneas del párrafo. Entre ellos hay un \glueque 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, \vtopy \vcenter. Ignoremos \vcenterya que es un poco extraño. \vboxy \vtopdifieren en dónde colocan suspunto de referencia—Ese es el punto que corresponde a su línea de base. A \vboxestablece 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 \vtopestablece 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

ingrese la descripción de la imagen aquí

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 \vtopy 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

ingrese la descripción de la imagen aquí

Suprimí la sangría y comencé la segunda línea con a gporque desciende por debajo de la línea de base. Miremos las cajas que se construyen. (Envolví todo en a \vboxy solía \showboxver el resultado. Por lo tanto, hay un vbox externo adicional debajo. Aumenté \showboxdepthen 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í:

  1. El segundo \vboxcorresponde a nuestro \vtop;
  2. \parskipSe insertó una A entre los párrafos; y
  3. No \baselineskipse insertó entre el \vtopy el siguiente \hboxque contiene Next line. En cambio hay un \lineskip. Esto \lineskipproviene del hecho de que la profundidad \vtopy la altura de los siguientes \hboxson mayores que \baselineskip. Si TeX hubiera intentado \baselineskipseparar sus líneas de base, se superpondrían.

Quizás ahora puedas ver el problema con tu propio código. La minipageopción [t]produce un archivo \vtop. Por lo tanto, TeX no garantiza que la línea de base de la línea inferior esté minipagealejada \baselineskipde la línea de base de la siguiente línea. En cambio, está insertando \lineskipun 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 \struten la última línea del \vtop, desactivar el salto entre líneas (es decir, inhibir el \lineskippegamento) y poner un \struten la primera línea del siguiente párrafo.

A \strutinserta 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 \onehalfspacingque cambia \baselineskippero no toca \box\strutbox.

Entonces, lo que debemos hacer es finalizar el cuadro más largo con una \vskiplongitud 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 \skipregistro temporal (elegí 0) para que sea \baselineskip- \ht\strutbox- \prevdepthdonde \prevdepthestá la profundidad del último cuadro en la lista vertical (es decir, la última línea de texto).

Dos advertencias finales.

  1. Esto no funciona con minipage, no investigué por qué.
  2. enumerateagregará espacio encima normalmente. Esto se inhibe mediante minipageel cual se ejecuta \@setminipage. Entiendo cómo \@setminipagefunciona, pero no entiendo cómo evitar este comportamiento simplemente usando enumitemlas 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}

ingrese la descripción de la imagen aquí

información relacionada