文字寄せ(中央・左右・両端揃え)

LaTeX の段落は、なぜワープロの段落より落ち着いて見えるのでしょうか。答えは 文字寄せ の一段下にあります。ワープロは行を一行ずつ埋めていきますが、LaTeX はどの行がどこで終わるかを決める前に段落全体を秤にかけます。既定は両端揃え。そこから離れる道は二つあり、\centering のような 宣言center のような 環境 が、まったく同じ寄せを、違う縦の空きとともに生みます。このページでは、両端揃えが既定である理由から、\centeringcenter の選び分け、\raggedright が黙ってハイフネーションをやめてしまう仕組みと ragged2e の解決、そして Overfull \hbox 警告への答え方までを一続きでたどります。

両端揃えが既定である理由——段落まるごとの行分割

何も指定しなければ、LaTeX は段落を 両端揃え(justified) に、左右の余白へぴったり合わせて組みます。これが既定なのは単なる慣習ではありません。TeX は行を上から順に埋めるのではなく、段落全体でもっとも損(demerits)の少ない改行位置の組み合わせ を選びます。このアルゴリズムを発表したのが、ドナルド・クヌースとマイケル・プラスの論文「Breaking Paragraphs into Lines」(Software: Practice and Experience 第11巻、1981年、1119–1184頁)です。一行ずつ貪欲に詰めていく方式は、序盤で得をしたぶんの皺寄せを最後の行に押しつけます。TeX は逆に、後半で大きく破綻しないよう 序盤の一行をわざと少し悪く 組むことができます。この最適化が動く余地は、単語間の空きが伸び縮みできるときにだけ生まれる——それこそが両端揃えの与える条件です。だから両端揃えが出発点なのです。

中身は具体的です。TeX は各行について、空きをどれだけ伸び縮みさせたかを badness という数値にし、改行位置に置かれた罰則を p とします。\linepenaltyl、badness を b とすると、その行の demerits は d = (l+b)^2 + p^2。段落の demerits はその総和に、隣り合う行の詰まり具合が不揃いなとき(\adjdemerits)や、ハイフンで終わる行が続いたとき(\doublehyphendemerits)の加算分を足したものです。クヌースとプラス自身がこれらの式を「quite arbitrary」と書いているのに、実際にはよく効きます。もう一つ知っておくと得なのは、行分割が 最大三回 試みられることです。一回目はハイフネーションをまったく使わずに組み、すべての行が \pretolerance に収まったときだけ採用します。二回目でようやくハイフネーションのパターンと、より緩い \tolerance が動員されます。つまり 余裕をもって収まる段落は、そもそもハイフンで割られません。それでも失敗したときだけ、\emergencystretch を使う三回目が走ります。

\centeringcenter 環境の違い

結論から言うと、寄せ方は まったく同じ で、違うのは 前後に入る縦の空き だけです。latex.ltx を開くと、center\trivlist \centering\item\relax と定義されています。つまりこの環境は \centering に見えないリストの外枠をかぶせただけのもので、リストである以上、本文との間に \topsep ぶんの間隔が自動で入ります。flushleft は同じやり方で \raggedright を、flushright\raggedleft を包んでいます。10pt の article で実測すると、center 環境は上下におよそ 8pt を足し、宣言は何も足しません。

宣言環境そろう側前後の縦の空き
\centeringcenter左右どちらもそろわず、行が中央に来る宣言はゼロ、環境は \topsep
\raggedrightflushleft左がそろい、右がぎざぎざになる同上
\raggedleftflushright右がそろい、左がぎざぎざになる同上
\justifyingjustify左右ともそろう(両端揃え)ragged2e が必要。宣言はゼロ
latex
\begin{figure}[htbp]
  \centering                 % declaration: adds no vertical space
  \includegraphics[width=0.6\textwidth]{plot}
  \caption{Measured values against the model}
  \label{fig:plot}
\end{figure}

figure の中で \begin{center} ではなく \centering を使うのはこのためです。フロートはすでに前後に自前の空きを持っているので、そこへ center 環境の \topsep が重なると、画像とキャプションの周りが間延びして見えます。同じ理屈で、tabular のセル、\parboxminipage\caption の中身も宣言側で寄せます。逆に、本文の流れの中に一行だけ標語を落とし込み、前後の空きごと欲しい ときは、center 環境のほうが短く言えます。

宣言にはもう一つ、事故のもとになる性質があります。宣言は新しい段落を始めません。 寄せ方が確定するのは段落が閉じる瞬間、つまり \par(空行)が読まれた時点で、そのとき有効だった値が その段落全体 に適用されます。だから次の一行は、多くの人の直感と食い違う結果になります。

latex
ww {\centering xx \\ yy} zz
% result: the line "ww xx" comes out centred, "yy zz" does not

実際に組むと、ww xx は中央にそろい、yy zz は左端から始まります。理由は二段構えです。まず \centering は、\\ の意味をその場で \@centercr書き換えます\@centercr は改行ではなく \par、つまり段落の終わりです。だから xx\centering が効いているうちに段落を閉じ、その段落が中央にそろいます。続く yy は新しい段落を開きますが、} でグループが閉じたところで \rightskip などが元に戻り、その段落が終わるときには両端揃えに戻っています。宣言を使うときの唯一の作法はここから出てきます。寄せたい段落の終わり——空行、または環境の \end——をグループの内側に入れること。

\raggedright がハイフネーションを止めてしまう理由と ragged2e

原因はコード一行です。\raggedright は行末の余りを埋めるグルー \rightskip0pt plus 1fil、すなわち 無限に伸びる空き に設定します。無限に伸びるものが各行の末尾にあると、どんなに短い行でも badness はゼロになります。そうなると TeX にとって、単語を割ってハイフンを入れることは demerits を増やすだけで何の得にもならない 選択です。だからハイフネーションを一切使わなくなり、右端が激しくぎざぎざになります。同じ文を幅 4cm で組んでみると、\raggedright は「一語だけで一行に収まらない」箇所を除いてハイフンを一つも入れず、行の長さが大きくばらつきました。

ragged2e パッケージが直すのは、まさにこの一点です。無限の伸びを 有限の 0pt plus 2em に置き換えるだけで、短すぎる行にはふたたび実質的な badness が付き、TeX はハイフネーションを検討しはじめます。用意されているのは頭文字が大文字の命令 \RaggedRight\RaggedLeft\Centering、環境 FlushLeftFlushRightCenter、そして両端揃えに戻すための \justifyingjustify 環境です。ハイフネーションを保ったまま文書全体を左寄せにするなら \usepackage[document]{ragged2e}\begin{document} の時点で \RaggedRight が実行され、同じ設定が \parboxtabular の p 列にも及びます。作者は Martin Schröder で、現在は Marei Peischl が保守しています。

latex
\usepackage[document]{ragged2e}   % whole document flush left, hyphenation kept

% or locally, only where it is needed:
\begin{FlushLeft}
  A paragraph set flush left with hyphenation still available,
  so the right edge stays gently ragged instead of jagged.
\end{FlushLeft}

\justifying                        % back to justified text

では、左寄せが本当に正解なのはいつでしょうか。決めるのは 一行の長さ です。多段組、傍注、tabular の狭い p 列のように行が短くなる場所で両端揃えを押し通すと、単語間の空きを大きく引き伸ばさざるを得ません。伸びた空きは行から行へとつながり、紙面に白い筋——組版で 川(rivers) と呼ばれるもの——を走らせて、読みやすさをむしろ損ないます。行が短いほど危険は大きく、狭い欄は実際に左寄せのほうがよく読めます。二段組の論文で本文は両端揃えのまま、キャプションと脚注だけ \RaggedRight にするのはよくある折衷です。逆に一段組で行が十分に長いなら、両端揃えには手を触れないのが賢明です。

Overfull \hbox 警告の直し方——\sloppy\emergencystretch

ログに Overfull \hbox (84.8932pt too wide) in paragraph at lines 10--10 のような行が出たら、それは その段落を許容範囲に収める改行位置の組み合わせが見つからなかった という報告です。TeX は諦めて、一行を余白へはみ出させたまま組みます。犯人はたいてい、長くて割れないもの——URL、連結された識別子、\texttt の中の長い語、あるいは単に狭い欄——です。寄せ方を疑う前に、まずその一語を疑ってください。

対処には順番があります。まずその一語を直す——\hyphenation{...} で分割位置を教える、\- を入れる、URL なら urlhyperref\url に任せる。これが根本的な解決です。それでも警告が残るなら \sloppy の出番です。\sloppy\tolerance を 9999 に、\emergencystretch を 3em に、\hfuzz を 0.5pt に緩めます。つまり 単語間の空きが間延びするのを受け入れて、はみ出しをなくす 取引です。文書全体にかけると本文の見た目まで緩むので、問題の段落だけを sloppypar 環境で囲むか、\emergencystretch=3em だけを設定するほうが穏やかです。厳しい設定に戻すのは \fussy\tolerance 200、\emergencystretch 0)。そして狭い欄でこの警告が続くなら、それはその欄を左寄せにせよという信号でもあります。

latex
% 1. tell LaTeX where the offending word may be split
\hyphenation{Bib-lio-the-ken-ver-bund}

% 2. relax the line breaker for one paragraph only
\begin{sloppypar}
  A paragraph containing a very long unbreakable token.
\end{sloppypar}

% 3. or globally, without going all the way to \sloppy
\emergencystretch=3em

段落の終わりに \\ を使ってはいけない理由

\\行を折るだけ で、段落を終わらせません。段落を終わらせるのは空行、すなわち \par です。この区別はそのまま寄せの話につながります。前節で見たとおり、寄せ方は段落が閉じる瞬間に決まるからです。実際に \\ で二つの文章を区切ると、後ろの文章は 新しい段落として扱われず、字下げも \parskip も付きません——一つの段落の途中で行が折れただけです。さらに悪いことに、段落の最後に \\ を置いて空行を続けると、ログが Underfull \hbox (badness 10000) in paragraph at lines 3--4 で埋まります。空っぽの行がもう一行できて、それが版面の幅いっぱいに引き伸ばされるためです。

では \\ はどこで使うのか。行を折りたい、それだけの場所 です。centerflushright の中で行を分ける、tabular で一行を終える、verse で詩行を区切る、長い \caption を折り返す——いずれも行の境目であって、段落の境目ではありません。ちなみに center ブロックの最終行のうしろに \\ を一つ足しても損はありません。余分な空きも警告も出ないのは、\@centercr\addvspace{-\parskip} で打ち消すからです。段落を分けるのは空行、行を折るのは \\——この一線を守るだけで、原因不明に見える寄せの不具合はかなり減ります。

どの寄せをどこに使うか——判断の順序

判断は好みからではなく、対象が何かから始めます。本文の段落は両端揃えのまま、短い部品——タイトル、キャプション、署名の行、表のセル——だけを局所的に寄せる。そして宣言と環境のどちらを使うかは、たった一つの問いに帰着します。前後の縦の空きが欲しいか、欲しくないか。 この順で決めれば、同じ問いに二度悩むことはまずありません。

  • 図表・表のセル・\parboxminipage の中身\centering のような宣言で寄せます。環境を使うと、すでにある空きの上に \topsep が積み重なります。
  • 本文の流れに置く一行の掲示や題字center 環境が自然です。前後の空きまで含めて欲しい結果だからです。
  • 欧文の左寄せ・右寄せ は標準命令ではなく ragged2e\RaggedRight\RaggedLeft を使い、ハイフネーションを生かしたままにします。
  • 狭い欄(多段組・傍注・tabular の p 列)では両端揃えに固執しません。行が短いほど左寄せが有利になります。
  • 宣言を使うときは、段落の終わりをグループの内側に置きます。 中に空行も \end も無いと、寄せが効かないか、触るつもりのなかった文章まで巻き込みます。
  • 段落を終わらせるのは空行、行を終わらせるのは \\ 混同すると Underfull \hbox と字下げの消失がまとめて襲ってきます。