短いまたは長い最後の行を完全な長方形の段落にスナップします

短いまたは長い最後の行を完全な長方形の段落にスナップします

段落をタイプセットするときに、最後の行が短すぎないようにしたい。または長すぎる。そのために、私は次のいずれかを生成する設定を探しています:

  • 完全に両端揃えされた、完全な長方形の段落。
  • 最後の行が 20% 以上 80% 未満で埋められている両端揃えの段落。

言い換えると、段落の最後の行が 20% 未満または 80% を超えて埋め込まれないようにし、代わりに完全に両端揃えにする必要があります。この効果は、\parfillskip 0ptそれらの段落 (のみ) に手動で追加することで実現できますが、私はまさにこれを自動化したいと考えています。

このドキュメントでは、良い例を 2 つと悪い例を 2 つ示します。

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

解決策は以下から構成されます前文のみの調整段落の始めや終わりに特別なコマンドは必要ありません。いくつかの関連するケースと同様に、 の特別な接着剤で解決できることを願っています\parfillskipが、それが可能かどうかはわかりません。


関連する質問、その解決策を試してみましたが、意図した出力は生成されませんでした。

答え1

このアプローチはセミ-自動ですが、段落を\fixitマクロで囲む必要があります。

改訂されたアプローチ

下記のオリジナルのアプローチのように段落を単語ごとに分析するのではなく、ここでは段落の内容を含む の長さを計測し、その長さに基づいて、末尾の や を\hbox使用するかどうかを決定します。\hspace{}\mbox\parfillskip0pt

マクロは、微調整が必​​要な場合にオプションの引数を提供します。これは、圧縮される行のオーバーランの最大値を表し、現在は.05(5%) に設定されています。圧縮されると思っていた行が、まったく新しい広い間隔の行に拡張された場合は、微調整が必​​要であることがわかります。デフォルト値を に設定すると、.0問題は発生しませんが、代わりに、末尾の空白行を削除するために圧縮できる行が拡張され、空白行が後続の行の 20% を占めることになります。

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

余白=1.5インチ

ここに画像の説明を入力してください

余白 = 1.7インチ

ここに画像の説明を入力してください

余白 = 1.9インチ

ここに画像の説明を入力してください

独自のアプローチ

しかし、マクロが行うことは、段落を単語ごとに最後の 4 語になるまで繰り返します。次に、最後の単語のうち何語が を超える必要があるかを判断し、とともに.2\linewidth内にそれらをまとめます。最後の 3 語が を超えない場合は、 内の 4 語すべてを使用します。\mbox\hspace{.2\linewidth}.2\linewidth\mbox

OP が要求していることは、テキストの長さを一挙に\sloppy変更すること (ほとんどの場合、望ましくないこと) について話しているので、ほぼ確実に必要になります。そのため、これを追加しました。.4\linewidth

このアプローチが破綻する原因の 1 つは、前に開いたグループが段落の最後の 4 語内で終了する場合です。これは、たとえば\textit段落の終わり近くで長いグループを閉じる場合などに当てはまります。

もう一つ注目すべき点は、完全に長方形の段落は一度もない\hspace段落の最後に追加されたため、このアプローチで作成できます。

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

ここに画像の説明を入力してください

関連情報