TeX/LaTeXとデザインの関係

この記事はTeX & LaTeX Advent Calendar 2016の22日目の記事です.
21日目はwtsnjpさんでした.23日目はaminophenさんです.

はじめに

TeX & LaTeX Advent Calendar 2016 の重点テーマは「ホンキでTeXを語ろう」とのことですので,今回私は「TeX/LaTeXとデザインの関係」についてホンキで考えてみたことを投稿しようと思います.

TeX/LaTeXにおけるデザイン

そもそも「デザイン」とは何なのか? デザインという言葉は非常に広い意味を持つ言葉なので,ここでは何を示すかをハッキリさせなければならないでしょう. 例えば「TeX/LaTeXにおけるデザイン」と言った場合に,TeX/LaTeXはもともと出版物をつくるための言語ですから「文書の(見た目の)紙面設計」のことを想像する人もいれば「文書そのものの構造設計」のことを思い浮かべる人もいるでしょう.ましてやTeX & LaTeX Advent Calendarに関わる人であれば「TeXの言語設計」とか「TeX言語でのプログラミングデザイン」のことを考える人すらいることと思います.
どれも興味深いテーマではありますが,時間と知識と紙面の都合上,残念ながら今回は「文書・出版物の見た目の紙面設計」の意味のデザインのみについて考えたいと思います.その他についてはまた別の機会にでも.

さて,みなさんは普段TeX/LaTeXで文書を書いているとき,書いている文書・出版物のデザインについて何か考えたことはあるでしょうか? おそらく,多少は考えたことがあるが深くは考えたことがないという人が大半なのではないでしょうか.少なくとも私の周りはそんな感じです. というのも,そもそもLaTeXで出版物を作成することは(ヘビーユーザーでない限りは)「デザイン」という意味での自由度が比較的低いものであるからです.

みなさんもご存知のように,LaTeXには,articlebookreportなど,さまざまな文書クラスが存在します. ひとたびクラスを決めてしまえば,あとはそのクラスのルールに従って

  • タイトルや著者などのメタデータ
  • \section\subsectionなどの見出し・章分け
  • 通常のパラグラフ(文章)

などを記述するだけで,体裁の整った文書を出力することができるわけです. 場合によっては微妙な調整などが必要になることもあるものの,基本的にはすべてクラスファイルに任せておけば綺麗な文書を作成することができるのです. これによってエンドユーザーが「デザイン」について考える必要性は最小限に抑えられ,結果的に文章そのものの質を向上させることに専念することができます.

もちろん文書クラスを編集することでユーザーの望むデザインで文書を作成することもできますし,こういった意味では,TeXの文書ソースファイルとクラスファイルとの関係はHTMLとCSSの関係に似たものと考えることもできます.いわゆる「文章とデザインの分離」が果たされているわけです.

TeX/LaTeXとデザインの親和性

ところで,デザインにおいて初歩的かつとても重要な概念のひとつに「反復・繰り返し」があります. デザインについての入門書「デザイン入門教室 特別講義」によると,

「反復・繰り返し」とは、複数の写真や図版、文字などを同一のデザインルールのもとでレイアウトしていく技法です。 複数の要素に同じデザインルールを適用することで、それらに規則性が生まれ、その結果、全体にまとまり感や統一感が生まれます。

とのこと.これは統一感を演出するために非常に効果的です. 実はこれ,マクロ機能を持つLaTeXとはとても高い親和性があるのです.

以前私が学会でのポスター発表に使ったものを例にとって見てみましょう. 内容については,Lorem IpsumとLennaで代用しています.
LaTeXを用いてポスターを作成するには,beamerpostertikzposterなどのパッケージが存在しますが,この例ではbeamerposterを使用しています.

poster beamerposterによるポスターの例

各ブロックにはtcolorboxを用いて見出しをつけており,TikZを用いた装飾も施してあります. これは\newcommandによるマクロ定義によって行っているので,その定義を変更するだけで全体のスタイルを変更することができ,非常に便利です. 興味ある方はstyファイルを参照してみてください.クソ汚いコードですが.

この例で注目したいのは,以下の部分です.

lenna_panels レイアウトパターンを用いた例

ここでは,「2つの画像を横に並べて表示し,うち右側の画像の一部を拡大して表示する」というレイアウトパターンを計4回繰り返しています.画像を拡大表示する部分ではどのパターンでも同じ位置を拡大しています. 反復・繰り返しの典型的な例です. 画像のこういった提示方法は,複数の結果を比較したりすることの多い研究発表では特に頻繁に応用される方法です. 今回のこのパターンはTikZを用いて次のように書かれています.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
\begin{figure}
    \centering
    \begin{tikzpicture}[spy using outlines={rectangle, size=3.8cm, magnification=3, connect spies}]
        \node[anchor=south west, inner sep=0]
            (firstpic) at (0.0, 0.0)
            {\includegraphics[width=.5\textwidth]
            {./img/lenna.png}};
        \begin{scope}[x={(firstpic.south east)},y={(firstpic.north west)}]
            \node[anchor=north west] at (0.0,1.0) {\textcolor{white}{(A)}};
        \end{scope}
        \node[anchor=south west, inner sep=0]
            (sndpic) at (firstpic.south east)
            {\includegraphics[width=.5\textwidth]
            {./img/lenna_b.png}};
        \begin{scope}[x={(sndpic.south east)},y={(sndpic.north west)}]
            \node[anchor=north west] at (0.0,1.0) {\textcolor{white}{(B)}};
            \node (spytarget) at (0.54,0.46) {};
            \node (spygrass) at (sndpic.south west) {};
            \spy [red] on (spytarget) in node at (spygrass);
        \end{scope}
    \end{tikzpicture}
    \caption{Lenna}
    \label{fig:lenna}
\end{figure}

ちょっと詳しく見てみると,figure環境内にtikzpicture環境を記述しており,その内側には\nodeコマンドを用いて\includegraphicsにより画像を描画しています. それぞれの\nodeに対応するようにscopeを展開させ,「(A)」,「(B)」などのラベルやspyライブラリを用いた画像拡大などを記述しています. パターン1つ分を記述するだけでもそこそこ複雑なコードになるため,これが何パターンも繰り返されるとなるとコードの保守性・可読性が低くなることは明らかですね.

ところが,ここでLaTeXの持つマクロ機能が活きてくるのです.
このコードは,次のように共通部を括り出し,一般化することができます.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
\usepackage{graphicx}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usetikzlibrary{spy}

\newcommand*{\picTemplate}[2]{
    \begin{tikzpicture}[spy using outlines={rectangle, size=3.8cm, magnification=3, connect spies}]
        \node[anchor=south west, inner sep=0]
            (firstpic) at (0.0, 0.0)
            {\includegraphics[width=.5\textwidth]
            {#1}};
        \begin{scope}[x={(firstpic.south east)},y={(firstpic.north west)}]
            \node[anchor=north west] at (0.0,1.0) {\textcolor{white}{(A)}};
        \end{scope}
        \node[anchor=south west, inner sep=0]
            (sndpic) at (firstpic.south east)
            {\includegraphics[width=.5\textwidth]
            {#2}};
        \begin{scope}[x={(sndpic.south east)},y={(sndpic.north west)}]
            \node[anchor=north west] at (0.0,1.0) {\textcolor{white}{(B)}};
            \node (spytarget) at (0.54,0.46) {};
            \node (spygrass) at (sndpic.south west) {};
            \spy [red] on (spytarget) in node at (spygrass);
        \end{scope}
    \end{tikzpicture}
}

\newcommandにより\picTemplateというマクロを定義しています.
このコマンドは2つの引数をとり,両方とも画像のパスをとります. これらはそれぞれ(A),(B)の画像用のパスとして利用されるように定義しています.
これを用いると,1つのパターンは次のように記述するだけで利用できます.

1
2
3
4
5
6
\begin{figure}
    \centering
    \picTemplate{./img/lenna.png}{./img/lenna_b.png}
    \caption{Lenna}
    \label{fig:lenna}
\end{figure}

これなら可読性も高く,コマンドの定義部を変更するだけで同じレイアウトを用いる部分に変更を加えることができるので保守性も高くなります.
このように,LaTeXはマクロ機能を利用することで,反復・繰り返しという点ではデザイン(というよりもレイアウト)との親和性を高く運用することができるわけです. たまたまここではTikZを用いてレイアウトをしていますが,より単純な例にも当然適用可能であるわけで,そういう意味ではLaTeXで多数の似たようなパーツを扱う場合にはマクロを使わない手はないでしょう.

さいごに

今回はデザインの基本である「反復・繰り返し」に焦点を当て,ここにLaTeXのマクロ機能を応用することで,統一されたレイアウトを容易に扱えるということを紹介しました.
このようにカンタンに美しいポスターやスライドをつくれると,もう他のソフトウェアには戻れませんね…

ここで用いたコードはXeLaTeXでの動作を確認していますが,他の処理系では確認ができていません. たぶんそのままでも動くと思いますが,もしダメならそれっぽくいじってください…

参考文献