段組み(multicol / twocolumn)

段組みは体裁の趣味ではなく、読みやすさのための仕掛けです。10pt の article の 1 行は幅 345pt、英文でおよそ 78 文字になりますが、タイポグラファの Robert Bringhurst は快適に読める行長を 45〜75 文字、理想は 66 文字としています。ページを 2 段に割ると、1 行はちょうどその範囲に戻ってきます。学術誌も予稿集も新聞も段組みなのはそのためで、LaTeX にはこれを実現する道具が性格の違う二つあります——クラスオプションの twocolumn と、multicol パッケージの multicols 環境です。見た目は交換可能そうですが、中身は別物です。このページでは実際につまずくところ、つまり段数の上限、最終ページがそろうかどうか、そして図が黙って消える二通りの理由を順に追います。

twocolumnmulticol はどちらを使うべきか

文書全体が 2 段組みで図表が入るなら twocolumn、一部だけ段組みにしたい・3 段以上ほしい・最終ページをそろえたいなら multicol です。分かれ目はフロート(図表)にあります。twocolumn は LaTeX のフロート機構をそのまま残すので、figure は段の中で浮動し、figure* はページ全幅に広がります。対して multicol は出力ルーチンごと置き換える実装で、段の高さをそろえる能力と引き換えに、段内のフロートを丸ごと諦めています。このページの議論はほとんどすべて、この一つの取引から派生します。

書き方段数効果
twocolumn2クラスオプション。本文全体が 2 段になり、最終ページはそろわない
\twocolumn[⟨text⟩]2本文中で使う。改ページしてから ⟨text⟩ を段の上に全幅で組む
\onecolumn1本文中で使う。改ページして 1 段組みに戻す
multicols2〜10環境。ページ途中で始まり途中で終わり、最後の段の高さをそろえる
multicols*2〜10同じだが最後の段はそろえず、左から順に詰めて終わる

文書全体を 2 段組みにする —— twocolumn オプション

クラスオプションに twocolumn を足すだけです。\documentclass[twocolumn]{article} と書けば本文全体が 2 段になります(既定は onecolumn)。多くの学会クラスは内部でこのオプションを前提に設計されています。文書の途中で切り替えたいときは本文中で \twocolumn\onecolumn を呼びますが、ここに二つの制約があります。どちらの命令も新しいページを始める ので、ページの途中では段数が変わりません。そして \twocolumn が作れるのは 常に 2 段だけ です。3 段が必要になった時点で、この道具では届きません。

latex
\documentclass[twocolumn]{article}

その \twocolumn には省略可能な引数があり、論文の顔をつくるのはたいていこちらです。\twocolumn[⟨全幅で組む内容⟩] と書くと、その中身だけが 2 段組みの上に 1 段(版面全幅)で 置かれます。タイトル・著者・所属・アブストラクトをページ幅いっぱいに広げ、その下から本文を 2 段で流す——学会論文で見慣れたあの体裁は、この一行でできています。

document.tex
\documentclass[twocolumn]{article}
\begin{document}
\twocolumn[%
  \begin{center}
    {\LARGE A Study of Narrow Measures}\\[4pt]
    A. Author \quad Institute of Typography
  \end{center}
  \vspace{1em}
]
The body starts here and is set in two columns.
\end{document}

段どうしの間隔は長さ \columnsep、その間に引く縦罫の太さは \columnseprule です。標準クラスの既定値は \columnsep10pt\columnseprule0pt(罫線なし)。数字を入れると冒頭の話が具体的になります。10pt の article\textwidth が 345pt なので、1 段の幅は (345 − 10) ÷ 2 = 167.5pt、英文でおよそ 38 文字です。Bringhurst が多段組みに勧める 40〜50 文字のすぐ下——つまり段間を広げるほど、削る余裕のない行長をさらに削ることになります。\columnsep をいじるときは、罫線を引いて視覚的に段を分ける代わりに間隔を詰める、という交換を考えるほうが実りがあります。

latex
\setlength{\columnsep}{20pt}      % wider gap between the columns
\setlength{\columnseprule}{0.4pt} % thin vertical rule inside the gap

図を段抜きで全幅に広げる —— figure*table*

アスタリスク付きの環境を使います。\begin{figure*}\begin{table*} は、両段にまたがってページ幅いっぱいに広がるフロートを作ります。中身の幅指定はここで一つ覚えておくと事故が減ります——\columnwidth は 1 段ぶんの幅、\textwidth は両段+段間を合わせた版面全体の幅。1 段に収める図は width=\columnwidth、段抜きの図は width=\textwidth が目安です。逆にすると、はみ出すか、妙に小さく組まれるかのどちらかになります。

document.tex
\documentclass[twocolumn]{article}
\usepackage{graphicx}
\begin{document}
% one column wide: an ordinary float
\begin{figure}
  \centering
  \includegraphics[width=\columnwidth]{plot}
  \caption{Fits inside a single column.}
\end{figure}

% spans both columns: starred float, default placement is [tp]
\begin{figure*}[t]
  \centering
  \includegraphics[width=\textwidth]{wide-plot}
  \caption{Spans the full text width.}
\end{figure*}
\end{document}

figure* を書いた場所に出てこない」「数ページ後ろに飛んだ」という相談は、置き場所の既定値を知ると腑に落ちます。LaTeX カーネルのソースは「二段抜きフロートの既定配置指定はすべて tp」と明記しています。つまり \begin{figure*} は黙って [tp]——ページ上端かフロート専用ページ——として扱われ、htbp ではありません。しかも LaTeX2e の参照マニュアルが述べるとおり、二段組みの全幅フロートには b(ページ下端)が使えません。上端が別のフロートで埋まっていれば後ろのページへ送られ続けます。どうしても下端に置きたいときは stfloatsdblfloatfix を読み込むと b が有効になります。

この待ち行列には、長く残っていた面白い不具合があります。2015 年のリリースより前、LaTeX は保留中のフロートを 単段用と段抜き用の二つの別々のリスト で管理していました。列が二本あれば追い越しが起きます——1 段幅の図 3 が、先に書かれた段抜きの図 2 を追い抜いて先に印刷される、という事故です。修正はまず fixltx2e パッケージとして配られ、二つのリストを一本化しました。2015 年に fixltx2e の修正はカーネル本体へ取り込まれたので、現行の TeX 環境ならもう何も読み込む必要はありません。図版の順序が狂ったという古い記事を見つけたら、まず日付を確認してください。

3 段以上と、そろう段 —— multicol パッケージ

\usepackage{multicol} を読み込み、段組みにしたい範囲を multicols 環境で囲み、引数に段数を渡します。これだけで 2 段から 10 段まで(10 段上限はバージョン 1.5 以降)が使え、環境はページの途中で始まり途中で終わり、終わりに達すると各段の高さを自動でそろえます。multicols は入れ子にもできます。改ページを強制しないので、1 段組みの本文の途中に用語集や索引だけを 3 段で挟む、といった使い方が自然にできます。

latex
\usepackage{multicol}
% ... later, in the body
\begin{multicols}{3}
  This text is broken into three balanced columns.
\end{multicols}

そもそも multicol は、索引のために生まれました。作者の Frank Mittelbach は 1989 年、doc パッケージのマクロを書いているときに「索引と参考文献を同じページに載せたい」と考えます。標準の 2 段組みではこれができません——\twocolumn は必ず改ページし、最終ページの右段は半分空いたまま終わるからです。彼はパッケージのドキュメントで、最初の版に 週末をまるごと一つ 費やしたこと、そして出発点が『The TeXbook』417 ページのアルゴリズムだったことを書き残しています(その一言は初版の文書に書かれたもので、以来さらに数百時間が注ぎ込まれた、とも添えられています)。段をそろえる機能は見た目の問題ではなく、紙面を節約するための機能 として構想されたわけです。

multicols は段数のあとに二つの省略可能な引数を取ります。一つ目 [⟨前置きテキスト⟩] は、段組みの直前に全幅で組まれる見出しや導入文です。二つ目 [⟨長さ⟩] は、段組みを開始するのに必要なページ下部の最低空き量で、既定値 \premulticols(50pt) をその場だけ上書きします。残りがそれより少なければ、環境は新しいページから始まります。前置きが長い文書でこれを渡さないと、Error saving partial pageSome text may be lost! と続く)というパッケージエラーで止まることがあります——\premulticols を増やせ、というのがその指示です。

latex
\begin{multicols}{3}
    [\section{Glossary}
     This heading and this sentence run the full text width.]
    [6cm]
  Everything after the optional arguments is split into three columns.
\end{multicols}

なぜ twocolumn の最終ページはそろわないのか

LaTeX が、次の段の存在を知る前に一つ目の段を完成させてしまうからです。2 段組みの出力ルーチン \@outputdblcol段ごとに 1 回 呼ばれます。左段が満ちるとその中身は \@leftcolumn という箱にしまわれ、組版が再開されます。右段が満ちて初めてページが組み立てられ、出力されます。つまり LaTeX が「残りの本文を手に持って、どう二つに割るか決める」瞬間は一度も訪れません。だから \end{document} の時点で残っていた分は、そのまま左段に流れ込んで止まり、右段が短いまま終わります。これは不具合ではなく、逐次的な組版の当然の帰結です。

multicol はこの順序をひっくり返します。それがすべての種明かしです。パッケージのドキュメントは処理を二段階に分けて説明しています——まず環境の中身を集め、それから終わりに達したところで balancing を行う。集め終わってから \vsplit で箱を切り分け、高さを変えながら試すからこそ、段がそろえられるわけです。バージョン 1.5 では品質判定も入りました。TeX の badness(0 が最良、10000 が無限に悪い)で各候補を測り、カウンタ columnbadness(既定 10000)より悪い解を捨てます。さらに finalcolumnbadness(既定 9999)があり、内容の少ない最終段を無理に引き伸ばして見苦しくするくらいなら短いまま終わらせる、という判断をします。

  • \raggedcolumns — 段の下端をそろえない。既定は \flushcolumns(そろえる)
  • カウンタ unbalance — 最右段以外を指定行数だけ長くする。環境ごとにリセットされる
  • カウンタ minrows(既定 1)— 最初の段に最低限入れる行数。1 行だけの段を避けたいとき
  • カウンタ columnbadness(既定 10000)— この値より badness が大きい解を却下する
  • カウンタ finalcolumnbadness(既定 9999)— 最終段を引き伸ばすかどうかの上限
  • \maxbalancingoverflow(既定 12pt)— そろえた結果がこれ以上はみ出すなら balancing を中止し、普通のページを作る

実務の判断はこうなります。twocolumn を使い続けたうえで最終ページだけそろえたいなら、出力ルーチンにパッチを当てる balance パッケージか flushend パッケージがあります。ただし TeX FAQ は、どちらもフロートが絡むと混乱しがち だと注意しており、うまくいかないときは図表の位置を手で調整することになる、と述べています。より確実なのは、文書の末尾だけを multicols 環境で包むか、そもそも右段が短いまま終わるのを受け入れることです——多くの学会スタイルは後者を許容しています。

段の切れ目を自分で決める —— \columnbreak と罫線

\columnbreak を置いた位置で現在の段が終わり、続きが次の段に送られます(バージョン 1.5u で追加)。1.9 からは \pagebreak と同じ形の省略可能引数を取り、\columnbreak[0](弱い希望)から \columnbreak[4](強制)まで指定できます。同じ 1.9 では、段を打ち切ったうえで短いまま終わらせる \newcolumn も加わりました。ここで \pagebreak を使ってはいけない理由も明快です——multicols の中で \pagebreak収集の段階そのもの を終わらせてしまうので、そのページの段が一斉に閉じられてしまいます。

latex
\setlength{\columnsep}{1.5em}      % gap between columns
\setlength{\columnseprule}{0.4pt}  % show a rule in the gap
\renewcommand{\columnseprulecolor}{\color{gray}}
\begin{multicols}{2}
  Text of the left column.
  \columnbreak                    % push the rest into the next column
  Text of the right column.
\end{multicols}

段間と罫線は twocolumn と同じ \columnsep\columnseprule で制御し、multicol はここに \columnseprulecolor を足しています(既定は \normalcolor、つまり本文色)。これらは環境に入る前に設定してください。そしてもう一つ、multicol が黙って変える設定があります——行分割の許容度です。LaTeX の通常の \tolerance は 200(\fussy)で、38 文字の行には厳しすぎます。そこでパッケージは環境内で \multicoltolerance(既定 9999)に切り替えます。10000=「何でもあり」の一歩手前という、狭い段のための現実的な妥協点です。それでも両端揃えの空きが目立つなら、環境内で \raggedright にするか、言語のハイフネーション設定を見直すのが定石です。

multicols の中で図が消えるのはなぜか

multicols の中では通常のフロートが実装されておらず、置かれたものは捨てられるからです。figuretable 環境、あるいは \marginpar を中に書くと、ログに Floats and marginpars not allowed inside 'multicols' environment! という警告が出ます。パッケージのドキュメントは結果を率直に書いています——そうしたフロートは消えてしまう、と。理由も明かされています。フロートを実装するには LaTeX の出力ルーチンを丸ごと作り直す必要があり、週末の仕事の範囲を超えていた、というのが Mittelbach の説明です。警告はエラーではないので、コンパイルは通ってしまいます。図が見当たらないのに Overfull も何も出ていないときは、まずこの一行をログで探してください。

書き方twocolumn ではmulticols の中では
figure / table段の中で通常どおり浮動する不可。警告だけ出て図表は消える
figure* / table*ページ全幅。既定は [tp]b は使えない使える。t b p が効くが、書いたページには絶対に出ない
\marginpar使える不可。同じ警告が出て消える
\columnbreakなし(改ページで代用する)その位置で段を打ち切る(1.5u 以降)
\pagebreakそのページを閉じる収集の段階を終えるので、そのページの段が一斉に閉じる
\columnseprule段間の縦罫。既定 0pt同じ。色は \columnseprulecolor で変えられる

アスタリスク付きのフロートは multicols の中でも使えますが、twocolumn のときとは振る舞いが違います。ドキュメントによれば、multicols 内の figure* は「1 段組みのページに置かれた普通のフロート」に近い扱いを受け、tbp を指定でき、参照するのは \dbltopfraction ではなく \topfraction です。ただし絶対的な制約が一つ——書かれたページには決して現れません。最も早くて次のページの上端なので、h を指定しても意味がありません。twocolumn では b が使えず multicols では使える、という逆転はここに由来します。

では段の中に小さな図を入れたいときはどうするか。フロートにしないこと が答えです。center 環境の中に \includegraphics を直接置けば、書いた位置にそのまま組まれます(環境内では \linewidth が段の幅になるので、width=\linewidth が使えます)。番号付きのキャプションが必要なら、caption パッケージの \captionof{figure}{…} で図表番号と相互参照を保ったまま付けられます。本文を回り込ませたいなら wrapfig という手もあります。ただし、段内のフロートが文書全体で必要 だと分かった時点で、それは multicol ではなく twocolumn を選ぶべきだという合図です。

latex
\usepackage{multicol}
\usepackage{graphicx}
\usepackage{caption}   % provides \captionof
% ... in the body
\begin{multicols}{2}
  Text before the picture.
  \begin{center}
    \includegraphics[width=\linewidth]{plot}
    \captionof{figure}{Not a float, so it stays where it is written.}
  \end{center}
  Text after the picture.
\end{multicols}