Ao compor parágrafos, quero garantir que a última linha não seja excessivamente curtanemexcessivamente longo.Para esse fim, estou procurando configurações que produzam:
- um parágrafo totalmente justificado e perfeitamente retangular;
- um parágrafo justificado cuja última linha esteja preenchida com mais de 20% e menos de 80%.
Em outras palavras, nenhum parágrafo deve ter uma última linha preenchida em menos de 20% ou mais de 80% – em vez disso, eles devem ser totalmente justificados. O efeito poderia ser alcançado adicionando manualmente \parfillskip 0pt
(apenas) esses parágrafos, mas é exatamente isso que quero automatizar.
Este documento mostra dois bons exemplos e dois maus exemplos:
\documentclass[a4paper]{article}
\usepackage[utf8]{inputenc}
% Page setup
\usepackage[a4paper,margin=3cm]{geometry}
% Typography
\usepackage{newtxtext,newtxmath}
\usepackage{microtype}
\parindent 0pt
\parskip\baselineskip
\begin{document}
\textbf{I'm looking for settings
that produce either a)~a~perfect rectangle
or b)~a paragraph whose last line
is filled more than 20\% and less than 80\%.}
\section*{Good examples}
\textbf{My perfect paragraph is a~rectangle:}
{
\parfillskip 0pt
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed rhoncus lorem eget ultricies bibendum. Duis luctus felis arcu, sit amet dapibus orci imperdiet id. Duis ullamcorper tortor eget leo fringilla, a lacinia nisl pulvinar. Etiam id facilisis augue. Sed convallis tempus ex, sed accumsan justo pulvinar vitae. Sed id sapien leo. Aliquam posuere ex lacus, ut posuere metus ullamcorper eu. Duis a imperdiet nibh. Donec tincidunt hendrerit nulla, et convallis metus imperdiet nec. Pellentesque massa enim, pharetra in pulvinar a, efficitur nec lorem. Cras mattis ex lorem, et euismod ligula rhoncus. Aenean ultricies quis velit non faucibus.
}
\textbf{However, this is not always achievable (and that's fine):}
{
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed rhoncus lorem eget ultricies bibendum. Duis luctus felis arcu, sit amet dapibus orci imperdiet id. Duis ullamcorper tortor eget leo fringilla, a lacinia nisl pulvinar. Etiam id facilisis augue. Sed convallis tempus ex, sed accumsan justo pulvinar vitae. Sed id sapien leo. Aliquam posuere ex lacus, ut posuere metus ullamcorper eu. Duis a imperdiet nibh. Donec tincidunt hendrerit nulla, et convallis metus imperdiet nec. Pellentesque massa enim, pharetra in pulvinar a, efficitur nec lorem. Cras mattis ex lorem, et euismod ligula rhoncus.
}
\section*{Bad examples}
\textbf{This last line is too short:}
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed rhoncus lorem eget ultricies bibendum. Duis luctus felis arcu, sit amet dapibus orci imperdiet id. Duis ullamcorper tortor eget leo fringilla, a lacinia nisl pulvinar. Etiam id facilisis augue. Sed convallis tempus ex, sed accumsan justo pulvinar vitae. Sed id sapien leo. Aliquam posuere ex lacus, ut posuere metus ullamcorper eu. Duis a imperdiet nibh. Donec tincidunt hendrerit nulla, et convallis metus imperdiet nec. Pellentesque massa enim, pharetra in pulvinar a, efficitur nec lorem.
\textbf{The above can be fixed with}
\verb!\parfillskip 0pt plus 0.80\textwidth!
\textbf{but that doesn't help for the case below.}
\textbf{This last line should have been justified (note the small gap at the end):}
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed rhoncus lorem eget ultricies bibendum. Duis luctus felis arcu, sit amet dapibus orci imperdiet id. Duis ullamcorper tortor eget leo fringilla, a lacinia nisl pulvinar. Etiam id facilisis augue. Sed convallis tempus ex, sed accumsan justo pulvinar vitae. Sed id sapien leo. Aliquam posuere ex lacus, ut posuere metus ullamcorper eu. Duis a imperdiet nibh. Donec tincidunt hendrerit nulla, et convallis metus imperdiet nec. Pellentesque massa enim, pharetra in pulvinar a, efficitur nec lorem. Cras mattis ex lorem, et euismod ligula rhoncus. Aenean ultricies quis velit non ut faucibus.
\textbf{The above can be fixed with}
\verb!\parfillskip 0pt!
\textbf{but that doesn't help for the case below.}
\end{document}
Uma solução deve consistir emajustes apenas no preâmbulo. Nenhum comando especial deve ser necessário no início ou no final de qualquer parágrafo. Espero que, como em vários casos relacionados, isso possa ser resolvido com um pouco de cola especial \parfillskip
, mas não tenho certeza se isso é possível.
Perguntas relacionadas, cujas soluções tentei, mas não produziram o resultado pretendido:
- Evite apenas as últimas linhas quase preenchidasresolvelongoúltimas linhas, mas nãocurtouns.
- Comprimento mínimo da última linha de um parágraforesolvecurtoúltimas linhas, mas nãolongouns.
- Existe uma ferramenta que transforma parágrafos em retângulos?prefere retângulos demais, mesmo que a última linha seja preenchida apenas até a metade, resultando em espaçamento excessivo entre palavras.
Responder1
Esta abordagem ésemi-automático, pois ainda é necessário incluir o parágrafo em uma \fixit
macro.
ABORDAGEM REVISADA
Em vez de dissecar o parágrafo palavra por palavra, como na ABORDAGEM ORIGINAL abaixo, aqui, eu apenas meço o comprimento do \hbox
material do parágrafo e decido, com base no comprimento, se devo empregar um final \hspace{}\mbox
e/ou um \parfillskip0pt
.
A macro fornece um argumento opcional se forem necessários ajustes. Representa a maior saturação de linha fracionária que será comprimida, atualmente definida como .05
(5%). Você saberá que precisa de ajustes se uma linha que você pensou que seria comprimida for expandida para uma nova linha totalmente espaçada. Definir o valor padrão como .0
eliminará quaisquer problemas, mas às custas de que algumas linhas que poderiam ser compactadas para eliminar as viúvas finais sejam expandidas para que a viúva ocupe 20% da linha subsequente.
\documentclass{article}
\usepackage[margin=1.5in,top=0cm,bottom=0cm]{geometry}
\newcommand\fixit[2][.05]{%
\setbox0=\hbox{\hspace{\parindent}#2}\fixithelp{#1}{#2}}
\newcommand\fixithelp[2]{%
\wd0=\dimexpr\wd0-\linewidth\relax%
\ifdim\wd0>0pt\relax%
\fixithelp{#1}{#2}%
\else%
\wd0=\dimexpr\wd0+\linewidth\relax
\ifdim\wd0>.9\linewidth\relax%
{\parfillskip0pt\relax#2\par}%
\else%
\ifdim\wd0>.8\linewidth\relax%
{\parfillskip0pt\relax#2\hspace{.2\linewidth}\par}%
\else%
\ifdim\wd0<#1\linewidth\relax%
{\parfillskip0pt\relax#2\par}%
\else%
\ifdim\wd0<.2\linewidth\relax%
{\parfillskip0pt\relax#2\hspace{.8\linewidth}\mbox{}\par}%
\else%
#2%
\fi
\fi
\fi
\fi
\fi%
}
\sloppy
\parskip1ex
\begin{document}
\noindent\rule{.2\linewidth}{2pt}\hfill\rule{.2\linewidth}{2pt}
\fixit{%
yakity yack, paragraphs, I want to \textit{ensure their last line} is neither
overly short nor overly long. To that end, I'm looking for settings that
produce either:}
\fixit{%
yack, yakity yack, paragraphs, I want to \textit{ensure their last line} is neither
overly short nor overly long. To that end, I'm looking for settings that
produce either:}
\fixit{%
yakity yack, yakity yack, paragraphs, I want to \textit{ensure their last line} is neither
overly short nor overly long. To that end, I'm looking for settings that
produce either:}
\fixit{%
yack, yakity yack, yakity yack, paragraphs, I want to \textit{ensure their last line} is neither
overly short nor overly long. To that end, I'm looking for settings that
produce either:}
\fixit{%
yackity yack, yakity yack, yakity yack, paragraphs, I want to \textit{ensure their last line} is neither
overly short nor overly long. To that end, I'm looking for settings that
produce either:}
\fixit{%
yack, yackity yack, yakity yack, yakity yack, paragraphs, I want to \textit{ensure their last line} is neither
overly short nor overly long. To that end, I'm looking for settings that
produce either:}
\fixit{%
yackity yack, yackity yack, yakity yack, yakity yack, paragraphs, I want to \textit{ensure their last line} is neither
overly short nor overly long. To that end, I'm looking for settings that
produce either:}
\fixit{%
yack, yackity yack, yackity yack, yakity yack, yakity yack, paragraphs, I want to \textit{ensure their last line} is neither
overly short nor overly long. To that end, I'm looking for settings that
produce either:}
\fixit{%
yackity yack, yackity yack, yackity yack, yakity yack, yakity yack, paragraphs, I want to \textit{ensure their last line} is neither
overly short nor overly long. To that end, I'm looking for settings that
produce either:}
\fixit{%
yack, yackity yack, yackity yack, yackity yack, yakity yack, yakity yack, paragraphs, I want to \textit{ensure their last line} is neither
overly short nor overly long. To that end, I'm looking for settings that
produce either:}
\fixit{%
yackity yack, yackity yack, yackity yack, yackity yack, yakity yack, yakity yack, paragraphs, I want to \textit{ensure their last line} is neither
overly short nor overly long. To that end, I'm looking for settings that
produce either:}
\fixit{%
yack, yackity yack, yackity yack, yackity yack, yackity yack, yakity yack, yakity yack, paragraphs, I want to \textit{ensure their last line} is neither
overly short nor overly long. To that end, I'm looking for settings that
produce either:}
\fixit{%
yackity yack, yackity yack, yackity yack, yackity yack, yackity yack, yakity yack, yakity yack, paragraphs, I want to \textit{ensure their last line} is neither
overly short nor overly long. To that end, I'm looking for settings that
produce either:}
\fixit{%
yack, yackity yack, yackity yack, yackity yack, yackity yack, yackity yack, yakity yack, yakity yack, paragraphs, I want to \textit{ensure their last line} is neither
overly short nor overly long. To that end, I'm looking for settings that
produce either:}
\fixit{%
yackity yack, yackity yack, yackity yack, yackity yack, yackity yack, yackity yack, yakity yack, yakity yack, paragraphs, I want to \textit{ensure their last line} is neither
overly short nor overly long. To that end, I'm looking for settings that
produce either:}
\fixit{%
yack, yackity yack, yackity yack, yackity yack, yackity yack, yackity yack, yackity yack, yakity yack, yakity yack, paragraphs, I want to \textit{ensure their last line} is neither
overly short nor overly long. To that end, I'm looking for settings that
produce either:}
\fixit{%
yackity yack, yackity yack, yackity yack, yackity yack, yackity yack, yackity yack, yackity yack, yakity yack, yakity yack, paragraphs, I want to \textit{ensure their last line} is neither
overly short nor overly long. To that end, I'm looking for settings that
produce either:}
\end{document}
Margens = 1,5 pol.
Margens = 1,7 pol.
Margens = 1,9 pol.
ABORDAGEM ORIGINAL
Mas o que a macro faz é regurgitar o parágrafo palavra por palavra até chegar às últimas 4 palavras. Em seguida, ele determina quantas dessas últimas palavras devem ser excedidas .2\linewidth
e as agrupa dentro de an \mbox
junto com a \hspace{.2\linewidth}
. Se as últimas 3 palavras não excederem .2\linewidth
, ele usará todas as 4 no \mbox
.
Para o que o OP solicita, \sloppy
quase certamente será necessário, já que estamos falando em alterar o comprimento do texto de .4\linewidth
uma só vez (o que quase sempre é algo indesejável). Então eu adicionei.
Uma coisa que quebrará a abordagem é se um grupo aberto anteriormente terminar nas últimas 4 palavras do parágrafo. Isso se aplicaria, por exemplo, ao fechar uma posição longa \textit
perto do final de um parágrafo.
A outra coisa a notar é que um parágrafo perfeitamente retangularnuncaser criado com esta abordagem, por causa do adicionado \hspace
no final do parágrafo.
\documentclass{article}
\newcommand\fixit[1]{\fixithelp#1 \cr\relax}
\def\fixithelp#1 #2 #3 #4 #5\relax{\ifx \cr#5\finishup#1 #2 #3 #4\relax%
\else#1 \fixithelp#2 #3 #4 #5\relax\fi}
\def\finishup#1 #2 #3 #4\relax{ %
\setbox0=\hbox{#4}%
\ifdim\wd0>.2\linewidth\relax #1 #2 #3 \mbox{#4\hspace{.2\linewidth}}\else%
\setbox0=\hbox{#3 #4}%
\ifdim\wd0>.2\linewidth\relax #1 #2 \mbox{#3 #4\hspace{.2\linewidth}}\else%
\setbox0=\hbox{#2 #3 #4}%
\ifdim\wd0>.2\linewidth\relax #1 \mbox{#2 #3 #4\hspace{.2\linewidth}}\else%
\mbox{#1 #2 #3 #4\hspace{.2\linewidth}}%
\fi%
\fi%
\fi%
}
\sloppy
\parskip1em
\begin{document}
\fixit{typesetting
paragraphs, I want to \textit{ensure their last line} is neither
overly short nor overly long. To that end, I'm looking for settings that
produce either:}
\fixit{%
paragraphs, I want to \textit{ensure their last line} is neither
overly short nor overly long. To that end, I'm looking for settings that
produce either:}
\fixit{%
paragraphs, I want to \textit{ensure their last line} is neither
overly short nor overly long. To that end, I'm looking for settings that
produce overlylongwords:}
\fixit{%
I want to \textit{ensure their last line} is neither
overly short nor overly long. To that end, I'm looking for settings that
produce overlylongwords:}
\fixit{%
typesetting paragraphs, I want to \textit{ensure their last line} is neither
overly short nor overly long. To that end, I'm looking for settings that
produce I I I I:}
\fixit{%
typesetting I want to \textit{ensure their last line} is neither
overly short nor overly long. To that end, I'm looking for settings that
produce I I I I:}
\end{document}