Explicação

Explicação

Gostaria de integrar duas minipáginas dentro de um texto, mantendo o espaçamento entre linhas. Utilizando a \begin{minipage}[t]opção, o espaço acima das minipáginas está correto (círculo verde). Mas, infelizmente, o espaço abaixo é muito curto (círculo vermelho). Como posso ajustá-lo para o "salto de linha de base normal"?

insira a descrição da imagem aqui

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}   

Responder1

A explicação para o seu problema é bastante complexa. Se desejar, você pode simplesmente pular para a solução abaixo.

Explicação

Quando o TeX está compondo parágrafos, ele se comporta aproximadamente da seguinte maneira: primeiro ele divide o parágrafo em linhas (usando um algoritmo complexo com vários parâmetros). Essas linhas são colocadas em uma caixa horizontal (ou \hbox) e as caixas são colocadas na lista vertical principal. A lista vertical principal contém todo o material a partir do qual as páginas são criadas.

O TeX tenta garantir que as caixas horizontais sucessivas na lista vertical sejam espaçadas de forma que as linhas de base de cada caixa fiquem \baselineskipseparadas. Podemos usar o TeX para ver isso em ação.

Aqui estão alguns TeX simples (compilar com texou pdftex)

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

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

Quando compilado, imprime o conteúdo do \vboxinterior do parágrafo que foi dividido em duas linhas. Os \boxshow...parâmetros controlam como o TeX imprime o conteúdo da caixa. Aqui está a saída.

> \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 []

Isso pode ser um pouco complicado de ler no início, mas o que nos diz é que \box0tem \vbox18,94444 pontos de altura, 0 pontos de profundidade e 469,75499 pontos de largura. Aquilo é, (height+depth)xwidth. Dentro dele podemos ver os dois \hboxes correspondentes às duas linhas do parágrafo. Entre eles, há um \glueque corresponde a \baselineskip. Observe que a profundidade da caixa superior mais a cola mais a altura da caixa inferior é 12pt, ou seja \baselineskip.

Agora, o TeX também não quer que caixas sucessivas se fechem para evitar que se sobreponham. Para evitar isso, o TeX irá inserir algum espaço entre as caixas quando elas estiverem muito próximas umas das outras. O algoritmo exato não é importante aqui, mas a chave é que podemos desabilitar esse comportamento usando \nointerlineskip.

Agora você deve estar se perguntando como duas caixas de texto podem estar muito próximas uma da outra. Isso pode acontecer se você tiver uma caixa com profundidadeeuem cima de uma caixa com alturande tal modo queeu+n> \baselineskip.

Então, o que tudo isso tem a ver com sua pergunta? Bem, o TeX tem três tipos de caixas verticais, \vbox, \vtop, e \vcenter. Vamos ignorar, \vcenterpois é um pouco estranho. \vboxe \vtopdiferem em onde eles colocam seusponto de referência—esse é o ponto que corresponde à sua linha de base. A \vboxdefine seu ponto de referência como o ponto de referência da última caixa da lista (ou seja, geralmente a linha de base da última linha do parágrafo da caixa). Por outro lado, a \vtopdefine seu ponto de referência como o ponto de referência da primeira caixa da lista (ou seja, a linha de base da linha superior do parágrafo).

Podemos ver isso em ação.

\noindent
\vbox{
    \hsize=1in
    Top line\hfill\break
    Bottom line
}
\vtop{
    \hsize=1in
    Top line\hfill\break
    Bottom line
}
\end

insira a descrição da imagem aqui

Você pode ver como a linha inferior da caixa esquerda está alinhada com a linha superior da caixa direita.

Podemos imprimir a aparência dessas duas caixas como fizemos antes.

A caixa da esquerda:

\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 []

A caixa certa:

\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 []

A principal diferença está na altura e na profundidade dessas duas caixas (a linha superior de cada listagem).

Isso leva a um problema complicado. O que acontece se usarmos a \vtope a próxima linha da página for apenas uma linha normal de um parágrafo? Vamos dar uma olhada.

\parindent=0pt
\leavevmode
\vtop{
    \hsize=1in
    Top line\hfill\break
    g Bottom line
}

Next line
\end

insira a descrição da imagem aqui

Suprimi o recuo e comecei a segunda linha com a gporque ela desce abaixo da linha de base. Vejamos as caixas que são construídas. (Envolvi tudo em a \vboxe usei \showboxpara ver a saída. Portanto, há uma vbox externa extra abaixo. Aumentei \showboxdepthem 1 para ver a próxima caixa interna.)

\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

Existem vários pontos dignos de nota aqui:

  1. O segundo \vboxcorresponde ao nosso \vtop;
  2. Um \parskipfoi inserido entre os parágrafos; e
  3. Não \baselineskipfoi inserido entre o \vtope o seguinte \hboxque contémNext line . Em vez disso, há um arquivo \lineskip. Isso \lineskipvem do fato de que a profundidade \vtope a altura do seguinte \hboxsão maiores que \baselineskip. Se o TeX tivesse tentado \baselineskipseparar suas linhas de base, elas se sobreporiam.

Talvez agora você possa ver o problema com seu próprio código. A opção minipagewith [t]produz um arquivo \vtop. Portanto, o TeX não garante que a linha de base do resultado final minipageesteja \baselineskiplonge da linha de base da linha seguinte. Em vez disso, está inserindo \lineskipo que não tem espaço suficiente.

Você pode estar pensando que a solução é mudar minipagepara [b], mas então você terá uma situação análoga com a linha acima.

Solução

O método normal para lidar com isso é colocar um\strut na última linha do \vtop, desativar o salto entre linhas (ou seja, inibir a \lineskipcolagem) e colocar um \strutna primeira linha do próximo parágrafo.

A \strutinsere uma caixa (ou seja \box\strutbox) que tem altura + profundidade que geralmente é igual a \baselineskip. No entanto, isso não vai funcionar no seu caso. O motivo é que \onehalfspacingmuda, \baselineskipmas não toca \box\strutbox.

Então, o que precisamos fazer é terminar a caixa mais longa com um \vskipde comprimento apropriado, desligar o salto entre linhas e usar \strut. Então, qual é o comprimento apropriado? Bem, queremos \baselineskip= (altura de \box\strutbox) + (profundidade da última caixa em \vbox) + (nosso explícito \vskip).

Podemos calcular isso definindo um \skipregistro temporário (eu escolhi 0) como \baselineskip- \ht\strutbox- \prevdepthonde \prevdepthestá a profundidade da última caixa na lista vertical (portanto, a última linha do texto).

Duas advertências finais.

  1. Isso não funciona minipage, não investiguei o porquê.
  2. enumerateirá adicionar espaço acima dele normalmente. Isso é inibido por minipagewhich executa \@setminipage. Entendo como \@setminipagefunciona, mas não entendo como evitar esse comportamento apenas usando enumitemas opções do . Então, em vez disso, esse código é executado \@setminipage.

Aqui está o 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}

insira a descrição da imagem aqui

informação relacionada