Al componer párrafos, quiero asegurarme de que la última línea no sea demasiado corta.nidemasiado largo.Con ese fin, estoy buscando configuraciones que produzcan:
- un párrafo totalmente justificado y perfectamente rectangular;
- un párrafo justificado cuya última línea esté rellenada en más del 20% y menos del 80%.
En otras palabras, ningún párrafo debe tener una última línea que esté llena en menos del 20 % o más del 80 %; en su lugar, deben estar completamente justificadas. El efecto podría lograrse agregando manualmente \parfillskip 0pt
(solo) esos párrafos, pero esto es exactamente lo que quiero automatizar.
Este documento muestra dos buenos ejemplos y dos malos ejemplos:
\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}
Una solución debe consistir enajustes solo en el preámbulo. No se deben requerir comandos especiales al principio o al final de ningún párrafo. Espero que, como en varios casos relacionados, se pueda solucionar con un poco de pegamento especial \parfillskip
, pero no estoy seguro de que sea posible.
Preguntas relacionadas, cuyas soluciones he probado pero no producen el resultado deseado:
- Evite las últimas líneas casi llenasresuelvelargoúltimas líneas, pero nocortounos.
- Longitud mínima de la última línea de un párrafo.resuelvecortoúltimas líneas, pero nolargounos.
- ¿Existe alguna herramienta que convierta los párrafos en rectángulos?prefiere demasiado los rectángulos, incluso si la última línea sólo está llena hasta la mitad, lo que produce un espacio excesivo entre palabras como resultado.
Respuesta1
Este enfoque essemi-automático, en el sentido de que aún hay que encerrar el párrafo en una \fixit
macro.
ENFOQUE REVISADO
En lugar de diseccionar el párrafo palabra por palabra, como en el ENFOQUE ORIGINAL a continuación, aquí simplemente mido la longitud del \hbox
material que contiene el párrafo y decido, en función de la longitud, si empleo un final \hspace{}\mbox
y/o un \parfillskip0pt
.
La macro proporciona un argumento opcional si es necesario realizar ajustes. Representa el mayor desbordamiento de línea fraccional que se comprimirá, actualmente establecido en .05
(5%). Sabrá que es necesario modificarlo si una línea que pensaba que se comprimiría se expande a una línea completamente nueva y ampliamente espaciada. Establecer el valor predeterminado en .0
eliminará cualquier problema, pero a costa de que algunas líneas que de otro modo podrían comprimirse para eliminar las viudas finales se expanden para que la viuda ocupe el 20% de la línea siguiente.
\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}
Márgenes = 1,5 pulgadas
Márgenes = 1,7 pulgadas
Márgenes = 1,9 pulgadas
ENFOQUE ORIGINAL
Pero lo que hace la macro es regurgitar el párrafo palabra por palabra hasta llegar a las últimas 4 palabras. Luego, determina cuántas de esas últimas palabras deben exceder .2\linewidth
y las agrupa dentro de un \mbox
junto con un \hspace{.2\linewidth}
. Si las últimas 3 palabras no exceden .2\linewidth
, entonces usa las 4 en el archivo \mbox
.
Para lo que el OP solicita, \sloppy
casi con seguridad será necesario, ya que estamos hablando de cambiar la longitud del texto de .4\linewidth
una sola vez (lo cual casi siempre es algo no deseado). Entonces lo agregué.
Una cosa que romperá el enfoque es si un grupo previamente abierto finaliza dentro de las últimas 4 palabras del párrafo. Esto se aplicaría, por ejemplo, al cerrar un párrafo largo \textit
cerca del final de un párrafo.
La otra cosa a tener en cuenta es que un párrafo perfectamente rectangularnuncase creará con este enfoque, debido a lo agregado \hspace
al final del párrafo.
\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}