🔥

TeX でポスター作成する!

2024/03/20に公開

先日学会でポスター発表をしたのですが,その際ポスターを TeX で作るという苦行素敵な経験をしました.
当然のごとく何度も躓いた結果,今の実装に落ち着いたので,共有してみます.

対象読者

以下のすべての条件を満たす人が対象です.

  • TeX で通常の(article や book 等の)日本語組版ができる人
    • 数式や図表など,基本的な操作を想定しています.
  • TikZ が十分自由に使える人
    • 「自分のやりたい図が描ける」ことを基準とします.
  • TikZ を活用してオレオレポスター作成したい人

ドキュメントクラス

日本語組版するのに色々便利なので jlreq を用いますが,とくに強い制約はありません.
お好みのドキュメントクラスを選択してください.

\documentclass[paper=a0paper,fontsize=32pt,gutter=0pt,fore-edge=0pt,head_space=0pt,foot_space=0pt,lualatex]{jlreq}

クラスオプションで天地・のど・小口を 0 にしています.

インデント

\parindent = 0pt

ポスターでは段落頭のインデントはしない方が見栄え良いほか,後述の tcolorbox の仕様上,インデントがあると予期せぬレイアウトになってしまいます.
そのため \parindent (paragraph indentation) でインデントを消します.

フォント

\usepackage{cmbright}
\usepackage[sourcehan-jp,match,deluxe,jis2004]{luatexja-preset}
\usepackage[defaultsans]{opensans}

フォントは完全にお好みで設定しましょう.上記は LuaTeX を使用している場合の例です.

カラーパレット

\usepackage{xcolor}

\definecolor{cream-base}{rgb}{1,0.9530,0.8}
\colorlet{frame-fill}{cream-base!15!white}
\colorlet{text-fg}{black!80!white}
\colorlet{footnote-fg}{text-fg!75!white}
\definecolor{skyblue-base}{rgb}{0.3020,0.4627,1.0}
\colorlet{title-fg}{skyblue-base!85!black}
\colorlet{highlight-bg}{skyblue-base!20!white}
\definecolor{pink-base}{rgb}{0.9608,0.8627,0.8941}
\colorlet{page-fill}{pink-base!98!yellow!60!white}
\colorlet{frame-draw}{pink-base!95!red!98!black}
\colorlet{itemize-fg}{green!62!black}

使う色はプリアンブルにまとめておくと,印刷時に「ディスプレイで見てたのと色が違う……」と落ち込んだときに楽です.

タイトル・著者の位置

\usepackage{titling}
\pretitle{\begin{center}\Huge\sffamily\bfseries\color{text-fg}}
\posttitle{\end{center}\vspace{1.35em}}
\setlength{\droptitle}{-25mm}

\usepackage{authblk}
\renewcommand \Authsep{\ }
\renewcommand \Authand{}
\renewcommand \Authands{\ }
\renewcommand \Authfont{\sffamily\Large\color{text-fg}}
\renewcommand \Affilfont{\sffamily\normalsize\color{text-fg}}

\maketitle の位置をスマートに調整する方法が見つからなかったので,titling/authblk で強引に調整します.

tcolorbox でフレーム作り

ポスター内のセクション(フレーム)には tcolorbox が便利です.

\usepackage{tikz}
\usepackage{tcolorbox}
\tcbuselibrary{skins}

\tcbset{
    bulk style/.style={
        empty,
        nobeforeafter,box align=top,
        fonttitle=\Large\bfseries,
        top=1.3em,
        bottom=1.3em,
        left=1.3em,
        right=1.3em,
        toptitle=1em,
        bottomtitle=0mm,
        lefttitle=4.2em,
        coltitle=title-fg,
        frame code={%
            \path[draw=frame-draw, line width=2.4mm,fill=frame-fill, rounded corners=1.5mm] (frame.south west) rectangle (frame.north east);
        },
    },
    separated sidebyside/.style={lower separated=false, sidebyside, sidebyside align=top}
}
\tcbsetforeverylayer{coltext=text-fg}

tcolorbox の機能を使えば非常に自由度の高いデザインが実現できます.
とくに TikZ も使えるところが◎です.
詳しい使い方は CTAN のドキュメントを参照してください.

私はさらに

\usepackage{xparse}
\RenewDocumentEnvironment{frame}{o m}{\IfNoValueTF{#1}{\begin{tcolorbox}[bulk style,#2]}{\begin{tcolorbox}[bulk style,title=#1,#2]}}{\end{tcolorbox}}

とラップして使っています.

\newcommand \TestText{%
いろはにほへと…… ゑひもせす%
}

\begin{frame}[概要]{width=320mm,left skip=40mm,equal height group=1}
    \TestText
\end{frame}
\begin{frame}[背景]{width=478.1mm,left skip=15mm,separated sidebyside,equal height group=1}
    \TestText

    \tcblower

    \TestText
\end{frame}

\vspace{1em}

\begin{frame}{width=\linewidth,left skip=40mm,right skip=40mm,lower separated=false}
    \TestText

    \tcblower

    \TestText
\end{frame}

以下の点に注意しましょう.

  • 横の並び(row)は equal height group=<id> で同一の ID を指定すると高さが揃えられる.
  • かつ,フレームの間に空行を入れない(row = TeX の一行).
  • 縦の配置は vspace で調節する.(nobeforeafter を指定しているため,vspace でごり押す方が安全.)

width は目分量で(あるいは計算して)設定しています.
機械的に align したい場合は tcolorboxraster が使えます.

\tcbuselibrary{raster}

itemize のデザイン

itemize 環境のデザインは enumitem でいじることができます.

\usepackage{enumitem}
\setlist{nosep}
\setlist[itemize,1]{label={{\small\color{itemize-fg}}}, labelsep=0.25em}
\setlist[itemize,2]{label={\tikz[x=1em, y=1em]{%
    \path[fill=itemize-fg] (0,0) -- (0.6495,0.35) -- (0,0.7) -- cycle;
}}, labelsep=0.25em, leftmargin=1em, topsep=0.5em, before*=\small, itemsep=0.75em}

脚注のデザイン

調べたところ脚注のデザインを変更できる自由度の高いパッケージが見つからなかったので,強引に再定義してやります.

\renewcommand \thempfootnote{{\color{footnote-fg}\sffamily\raisebox{0.1em}{[\arabic{mpfootnote}]}}}
\renewcommand \thefootnote{{\color{footnote-fg}\sffamily\raisebox{0.1em}{[\arabic{footnote}]}}}
\def\@makefnmark{\hbox{\small\@thefnmark}}

% \usepackage{xparse}

\makeatletter

\let\myposter@tmp@footnote\footnote
\let\myposter@tmp@footnotetext\footnotetext

\RenewDocumentCommand \footnote{o m}{\IfNoValueTF{#1}{%
\myposter@tmp@footnote{\textsf{\color{footnote-fg}#2}}%
}{%
\myposter@tmp@footnote[#1]{\textsf{\color{footnote-fg}#2}}%
}}

\RenewDocumentCommand \footnotetext{o m}{\IfNoValueTF{#1}{%
\myposter@tmp@footnotetext{\textsf{\color{footnote-fg}#2}}%
}{%
\myposter@tmp@footnotetext[#1]{\textsf{\color{footnote-fg}#2}}%
}}

\let\footnoterule\relax

\makeatother

注意として,tcolorboxminipage 環境を用いていることから,\footnotefootnote ではなく mpfootnote をカウンタとして参照します.
一方 \footnotemark/\footnotetextfootnote カウンタを参照するため,両方の the* を再定義しています.

なお,tcolorbox の仕様上,separated sidebyside を指定した際に「脚注をフレームの底辺に置く(footmiscbottom オプションに相当)」ことができません.
左右それぞれの空きスペースを独立に計算できないためです.
separated sidebyside でない場合は,tcolorbox/tcb/space to を利用すれば可能となります.

用紙の背景デザイン

用紙の色やワンポイントのアクセントなどは皆大好き TikZ で解決しましょう.

\makeatletter
\let\myposter@tmp@maketitle\maketitle
\renewcommand \maketitle{%
\let\myposter@tmp@newpage\newpage
\let\newpage\relax
\myposter@tmp@maketitle
\let\newpage\myposter@tmp@newpage
}
\makeatother

% \usepackage{tikz}

\AtBeginDocument{%
\sffamily

\begin{tikzpicture}[remember picture,overlay]
    \path[fill=page-fill] (current page.north east) rectangle (current page.south west);
\end{tikzpicture}

\maketitle
\vspace{-32mm}
}

\maketitle はその前に "何かしら" があると強制的に改ページしてしまいます.
したがって,tikzpicture 環境を \maketitle の前に置くためには,一時的に \newpage\relax させる必要があります.

その他

強調表示

強調するときには,太字にするのも効果的ですが,背景色を変えて分かりやすくしたいこともあります.
それには tcolorboxtcbox コマンドが便利です.

\newcommand \highlight[1]{%
\tcbox[
    on line, frame engine=empty,
    colback=highlight-bg,
    arc=0pt, outer arc=0pt,
    top=0.12em, bottom=0.12em, left=0pt, right=0pt,
    leftrule=0pt, rightrule=0pt, toprule=0pt, bottomrule=0pt,
    boxsep=0.24em,
]{#1}%
}

% Usage: \highlight{強調したい文言}

もちろん生の TikZ でも同じことはできます.

TikZ の矢印

\draw 時のデフォルトの矢印は小さく細いです.
大きくしたい場合は arrows.meta でいい感じにいじりましょう.

\usetikzlibrary{arrows.meta}

\tikzset{
    big arrow/.style={very thick,arrows={-Stealth[scale=2.4]}},
    |/.tip={Bar[width=0.5em]},
    big mapsto/.style={very thick,arrows={|-Stealth[scale=2.4]}},
}

% Usage: \draw[big arrow] (0, 0) -- (1, 0);
%        \draw[big mapsto] (0, -1) -- (1, -1);

フォントサイズの確認

フォントサイズを確認したいときに便利なマクロです.

\makeatletter

\newcommand \myposter@printfontsize[1]{%
{\csname #1\endcsname #1 \f@size pt The quick brown fox jumps over the lazy dog.}
}
\newcommand \printfontsize{%
\myposter@printfontsize{tiny}

\myposter@printfontsize{scriptsize}

\myposter@printfontsize{footnotesize}

\myposter@printfontsize{small}

\myposter@printfontsize{normalsize}

\myposter@printfontsize{large}

\myposter@printfontsize{Large}

\myposter@printfontsize{LARGE}

\myposter@printfontsize{huge}

\myposter@printfontsize{Huge}
}

\makeatother

サンプル

最後に全体サンプルを置いておきます.

LuaTeX でタイプセットできます.
(e)(u)pTeX を使いたい人は,クラスオプションとフォント設定を書き換えてください.
また,フォント(Source Han * JP,Open Sans)が無い人も,よしなにお願いします.

サンプル
\documentclass[paper=a0paper,fontsize=32pt,gutter=0pt,fore-edge=0pt,head_space=0pt,foot_space=0pt,lualatex]{jlreq}
\parindent = 0pt

\makeatletter

\usepackage{cmbright}
\usepackage[sourcehan-jp,match,deluxe,jis2004]{luatexja-preset}
\usepackage[defaultsans]{opensans}

\usepackage{xcolor}

\definecolor{cream-base}{rgb}{1,0.9530,0.8}
\colorlet{frame-fill}{cream-base!15!white}
\colorlet{text-fg}{black!80!white}
\colorlet{footnote-fg}{text-fg!75!white}
\definecolor{skyblue-base}{rgb}{0.3020,0.4627,1.0}
\colorlet{title-fg}{skyblue-base!85!black}
\colorlet{highlight-bg}{skyblue-base!20!white}
\definecolor{pink-base}{rgb}{0.9608,0.8627,0.8941}
\colorlet{page-fill}{pink-base!98!yellow!60!white}
\colorlet{frame-draw}{pink-base!95!red!98!black}
\colorlet{itemize-fg}{green!62!black}

\usepackage{titling}
\pretitle{\begin{center}\Huge\sffamily\bfseries\color{text-fg}}
\posttitle{\end{center}\vspace{1.35em}}
\setlength{\droptitle}{-25mm}

\usepackage{authblk}
\renewcommand \Authsep{\ }
\renewcommand \Authand{}
\renewcommand \Authands{\ }
\renewcommand \Authfont{\sffamily\Large\color{text-fg}}
\renewcommand \Affilfont{\sffamily\normalsize\color{text-fg}}

\usepackage{tikz}
\usepackage{tcolorbox}
\tcbuselibrary{skins}

\tcbset{
    bulk style/.style={
        empty,
        nobeforeafter,box align=top,
        fonttitle=\Large\bfseries,
        top=1.3em,
        bottom=1.3em,
        left=1.3em,
        right=1.3em,
        toptitle=1em,
        bottomtitle=0mm,
        lefttitle=4.2em,
        coltitle=title-fg,
        frame code={%
            \path[draw=frame-draw, line width=2.4mm,fill=frame-fill, rounded corners=1.5mm] (frame.south west) rectangle (frame.north east);
        },
    },
    separated sidebyside/.style={lower separated=false, sidebyside, sidebyside align=top}
}
\tcbsetforeverylayer{coltext=text-fg}

\usepackage{xparse}
\RenewDocumentEnvironment{frame}{o m}{\IfNoValueTF{#1}{\begin{tcolorbox}[bulk style,#2]}{\begin{tcolorbox}[bulk style,title=#1,#2]}}{\end{tcolorbox}}

\newcommand \highlight[1]{%
\tcbox[
    on line, frame engine=empty,
    colback=highlight-bg,
    arc=0pt, outer arc=0pt,
    top=0.12em, bottom=0.12em, left=0pt, right=0pt,
    leftrule=0pt, rightrule=0pt, toprule=0pt, bottomrule=0pt,
    boxsep=0.24em,
]{#1}%
}

\usetikzlibrary{arrows.meta}

\tikzset{
    big arrow/.style={very thick,arrows={-Stealth[scale=2.4]}},
    |/.tip={Bar[width=0.5em]},
    big mapsto/.style={very thick,arrows={|-Stealth[scale=2.4]}},
}

\usepackage{enumitem}
\setlist{nosep}
\setlist[itemize,1]{label={{\small\color{itemize-fg}}}, labelsep=0.25em}
\setlist[itemize,2]{label={\tikz[x=1em, y=1em]{%
    \path[fill=itemize-fg] (0,0) -- (0.6495,0.35) -- (0,0.7) -- cycle;
}}, labelsep=0.25em, leftmargin=1em, topsep=0.5em, before*=\small, itemsep=0.75em}

\renewcommand \thempfootnote{{\color{footnote-fg}\sffamily\raisebox{0.1em}{[\arabic{mpfootnote}]}}}
\renewcommand \thefootnote{{\color{footnote-fg}\sffamily\raisebox{0.1em}{[\arabic{footnote}]}}}
\def\@makefnmark{\hbox{\small\@thefnmark}}
\let\myposter@tmp@footnote\footnote
\let\myposter@tmp@footnotetext\footnotetext
\RenewDocumentCommand \footnote{o m}{\IfNoValueTF{#1}{%
\myposter@tmp@footnote{\textsf{\color{footnote-fg}#2}}%
}{%
\myposter@tmp@footnote[#1]{\textsf{\color{footnote-fg}#2}}%
}}
\RenewDocumentCommand \footnotetext{o m}{\IfNoValueTF{#1}{%
\myposter@tmp@footnotetext{\textsf{\color{footnote-fg}#2}}%
}{%
\myposter@tmp@footnotetext[#1]{\textsf{\color{footnote-fg}#2}}%
}}
\let\footnoterule\relax

\newcommand \myposter@printfontsize[1]{%
{\csname #1\endcsname #1 \f@size pt The quick brown fox jumps over the lazy dog.}
}
\newcommand \printfontsize{%
\myposter@printfontsize{tiny}

\myposter@printfontsize{scriptsize}

\myposter@printfontsize{footnotesize}

\myposter@printfontsize{small}

\myposter@printfontsize{normalsize}

\myposter@printfontsize{large}

\myposter@printfontsize{Large}

\myposter@printfontsize{LARGE}

\myposter@printfontsize{huge}

\myposter@printfontsize{Huge}
}

\let\myposter@tmp@maketitle\maketitle
\renewcommand \maketitle{%
\let\myposter@tmp@newpage\newpage
\let\newpage\relax
\myposter@tmp@maketitle
\let\newpage\myposter@tmp@newpage
}

\AtBeginDocument{%
\sffamily

\begin{tikzpicture}[remember picture,overlay]
    \path[fill=page-fill] (current page.north east) rectangle (current page.south west);
\end{tikzpicture}

\maketitle
\vspace{-32mm}
}

\makeatother

\title{タイトル\\%
タイトル二行目}
\author[1]{著者 A}
\author[1]{著者 B}
\author[1]{著者 C}
\affil[1]{○○大学}
\date{}

\begin{document}

\newcommand \TestText{%
いろはにほへと ちりぬるを\\
わかよたれそ  つねならむ\\
うゐのおくやま けふこえて\\
あさきゆめみし ゑひもせす
}

\begin{frame}[概要]{width=320mm,left skip=40mm,equal height group=1}
    \TestText~\footnote{詠み人知らず. いろは歌.}
\end{frame}
\begin{frame}[背景]{width=478.1mm,left skip=15mm,separated sidebyside,equal height group=1}
    \TestText~\footnotemark[2]

    \tcblower

    \TestText~\footnotemark[2]
    \footnotetext[2]{詠み人知らず. いろは歌.}
\end{frame}

\vspace{1em}

\begin{frame}{width=\linewidth,left skip=40mm,right skip=40mm,lower separated=false}
    \begin{center}
        \begin{tikzpicture}[x=1em,y=1em]
            \node at (0, 0) {Hello, \TeX!};
            \node at (10, 0) {Hello, Ti\textit{k}Z!};
            \draw[big arrow] (3, 0) -- (7, 0);
            
            \node at (0, -2) {A};
            \node at (10, -2) {B};
            \draw[big mapsto] (3, -2) -- (7, -2);
        \end{tikzpicture}
    \end{center}

    \tcblower

    \begin{itemize}
        \item アイテム1
            \begin{itemize}
                \item サブアイテム
            \end{itemize}
        \item \highlight{アイテム2}
    \end{itemize}
\end{frame}

\end{document}

Discussion