この記事は TeX & LaTeX Advent Calendar 2021 の22日目の記事です.
21日目は 7danmoroboshi さんでした. 23日目は wtsnjp さんです.
10日目にも投稿しているので, ご覧ください.
導入: LaTeX でのスライド作成
LaTeX を用いてスライド資料を作る方法はいくつかありますが, 代表的なものは beamer による方法だと思います.
beamer は比較的簡単にきれいなスライドが作成できるうえ, \pause
コマンド等による段階的な表示 (overlay specification) が容易なため, 使っている人は多いのではと思います. また, ドキュメントが豊富であるのも魅力的です.
一方で, 細かなカスタマイズをしようとするとかなり手間がかかりますし, 使いたいパッケージが使えないケース1もあります. 何より, コンパイルの時間が長すぎます.
overlay specification を使わないのであれば, 「スライドの見た目をしたページ」が出力できればそれで良いはずです.
スライドのような見た目の「箱」であれば, tcolorbox パッケージ で出力することができます.
この「箱」を単体で1ページとして出力できればいいわけですが, それは preview パッケージ によって実現可能です.
そこで本稿では, tcolorbox パッケージと preview パッケージを組み合わせてスライドを作る方法を紹介します.
tcolorbox パッケージの箱は, かなり柔軟にカスタマイズすることができます.
したがって, スライドの見た目を細かく変えたい人にはうってつけではないかと思います.
一方で, overlay specification を使うことはできません. この点は後述します.
tcolorbox と preview を用いたスライド作成
以下, LuaLaTeX によるコンパイルと日本語の利用を想定して, クラスファイルは ltjsarticle
としますが, あまり本質的ではないと思います.
基本的な構造
以下のような構造のファイルを作っておけば, ひとまず「箱が単体で1ページとして出力された pdf」を作ることができます.
\documentclass{ltjsarticle}
\usepackage{tcolorbox}
\usepackage[active,tightpage]{preview}
\PreviewEnvironment{minipage}
\begin{document}
\begin{minipage}{5cm}
\begin{tcolorbox}[
adjusted title=スライドタイトル
]
スライドの中身
\end{tcolorbox}
\end{minipage}
\end{document}
これにより, 以下の出力を得ます.
上の tex ファイルの中身を簡単に説明します.
\usepackage{tcolorbox}
は言うまでもなく, tcolorbox を読み込みます.
\usepackage[active,tightpage]{preview}
で preview パッケージを読み込みます.
オプションの active
はパッケージを有効化するという意味の, tightpage
は余白を出力しないという意味のオプションです (多分).
\PreviewEnvironment{minipage}
がミソで, これにより, 「minipage
環境の内部だけを独立した1ページとして出力する」ということができるようになります.
なぜかわかりませんが, ここを \PreviewEnvironment{tcolorbox}
にするとうまくいかなかったので, こうしています.
\begin{minipage}{5cm}
~ \end{minipage}
の中に, スライドの中身を書きます.
5cm
という引数でスライドの横幅の長さを指定しています. 今は適当に入力しています.
minipage
環境内部の
\begin{tcolorbox}[
adjusted title=スライドタイトル
]
スライドの中身
\end{tcolorbox}
の部分が, スライドの本体です.
今は adjusted title
というオプションしか書かれていませんが, この部分にさまざまなオプションを記入することで, スライドの見た目を変えることが可能です.
なぜ `title` オプションではなく `adjusted title` なのか
tcolorbox
には title
というオプションもあり, これを用いても箱のタイトルを設定することができます.
しかしこの場合, タイトルの文字列によってタイトル部分の高さが変わってしまいます.
例えば, title = Abc
とした箱と title = Xyz
とした箱では, yの下に伸びる部分の差で, タイトル部分の高さが異なってしまいます.
一方で, adjusted title = Abc
と adjusted title = Xyz
の場合, 同じ高さになります.
実は, adjusted title
によって高さを設定した場合, タイトルの文字列によらず, Ägypten
という文字列に合わせた高さになります.
スライドの場合, ページごとにタイトル部分の高さが異なるのは気持ちが悪いので, adjusted title
を利用していますが, そこを気にしなければ title
で十分です.
なお, 実際に使う場合には,
\renewenvironment{frame}[1]{
\begin{minipage}{5cm}
\begin{tcolorbox}[
adjusted title=#1
]
}{
\end{tcolorbox}
\end{minipage}
}
といった感じで frame
環境を定義して使うのが楽であると思いますが, 本稿ではそのような記述はしません.
以下, オプションの記入例を紹介します.
スライドの大きさの変更
スライドの幅は minipage
環境の引数として入力します.
スライドの高さは, tcolorbox
環境の height
オプションで記入します.
つまり, 以下のようにして大きさを指定できます.
\begin{minipage}{幅}
\begin{tcolorbox}[
adjusted title=スライドタイトル,
height=高さ
]
スライドの中身
\end{tcolorbox}
\end{minipage}
実際には, 次のように, \framewidth
という感じで長さをコマンドにするのが楽であると思います.
また, アスペクト比 (4:3なら0.75, 9:16なら0.5625) を予め計算しておいて, 高さは自動で計算するようにしておくと更に楽です.
\newlength{\framewidth}
\newlength{\frameheight}
\newcommand{\aspectratio}{0.75} % 16:9 なら 0.5625
\setlength{\framewidth}{12cm}
\setlength{\frameheight}{\aspectratio\framewidth}
\begin{minipage}{\framewidth}
\begin{tcolorbox}[
adjusted title=スライドタイトル,
height=\frameheight
]
スライドの中身
\end{tcolorbox}
\end{minipage}
これにより, 以下の出力を得ます.
少しスライドっぽくなりました.
なお, (本文の) フォントサイズをいじるのではなく, スライドサイズをいじることで, 相対的にフォントサイズを変更する, という仕様です (beamerもそう).
\framewidth
の値を変えることで, (スライドの/フォントの) 大きさが変わります.
タイトルのフォントサイズの変更
タイトルのフォントは, tcolorbox
の fonttitle
というオプションで変更できます.
\begin{minipage}{\framewidth}
\begin{tcolorbox}[
adjusted title=スライドタイトル,
height=\frameheight,
fonttitle=\Large
]
スライドの中身
\end{tcolorbox}
\end{minipage}
フォント (書体) そのものは fontspec パッケージなどを利用して変更すると良いと思います.
色の変更
背景とフォントの色は, 以下のオプションにより変更できます.
オプション | 意味 |
---|---|
colback |
中身の背景色 |
coltext |
中身のフォントの色 |
colbacktitle |
タイトルの背景色 |
coltitle |
タイトルのフォントの色 |
以下に例を記載します (オプションが増えてきたのでコメントをつけました).
わかりやすくするために奇抜な色合いにしています.
\begin{minipage}{\framewidth}
\begin{tcolorbox}[
% タイトル
adjusted title=スライドタイトル,
% 高さ
height=\frameheight,
% タイトルのフォント
fonttitle=\Large,
% 色
colback=lime,
coltext=black,
colbacktitle=blue,
coltitle=white
]
スライドの中身
\end{tcolorbox}
\end{minipage}
枠線の変更
上の図には余計な枠線がついていますね.
これを消して, ついでに角の丸みもなくしましょう.
boxrule
というオプションで枠線の太さを変更し, sharp corners
というオプションで角を直角にします.
\begin{minipage}{\framewidth}
\begin{tcolorbox}[
% タイトル
adjusted title=スライドタイトル,
% 高さ
height=\frameheight,
% タイトルのフォント
fonttitle=\Large,
% 色
colback=white,
coltext=black,
colbacktitle=blue,
coltitle=white,
% 枠線
boxrule=0mm,
sharp corners
]
スライドの中身
\end{tcolorbox}
\end{minipage}
ビューアによっては1ピクセル分の枠線が見えてしまうかもしれません. その場合は...
まず, プリアンブルの \usepackage{tcolorbox}
以降に \tcbuselibrary{skins}
と記載します.
\usepackage{tcolorbox}
\tcbuselibrary{skins}
その上で, tcolorbox
のオプションに, enhanced
と frame hidden
を追加します.
\begin{minipage}{\framewidth}
\begin{tcolorbox}[
% タイトル
adjusted title=スライドタイトル,
% 高さ
height=\frameheight,
% タイトルのフォント
fonttitle=\Large,
% 色
colback=white,
coltext=black,
colbacktitle=blue,
coltitle=white,
% 枠線
boxrule=0mm,
sharp corners,
enhanced,
frame hidden
]
スライドの中身
\end{tcolorbox}
\end{minipage}
余白の変更
余白は, 以下のオプションによって細かく指定できます.
オプション | 意味 |
---|---|
boxsep |
上下左右の余白 |
top |
中身の上部の余白 |
bottom |
中身の下部の余白 |
toptitle |
タイトルの上部の余白 |
bottomtitle |
タイトルの下部の余白 |
left |
左側の余白 |
right |
右側の余白 |
細かく余白を設定する場合, boxsep
は 0mm
にしておくと良いと思います.
\begin{minipage}{\framewidth}
\begin{tcolorbox}[
% タイトル
adjusted title=スライドタイトル,
% 高さ
height=\frameheight,
% タイトルのフォント
fonttitle=\Large,
% 色
colback=white,
coltext=black,
colbacktitle=blue,
coltitle=white,
% 枠線
boxrule=0mm,
sharp corners,
% 余白
boxsep=0mm,
top=1em,
bottom=1em,
right=1em,
left=1em,
toptitle=1ex,
bottomtitle=1ex,
]
スライドの中身
\end{tcolorbox}
\end{minipage}
ページ番号をつける
ちょっと面倒ですが, 「ページ番号を含む TikZ のノードを, tcolorbox の上に描く」という方法を採ります. もっと良い方法があるかもしれません.
まず, プリアンブルに, 以下を追記します:
% \usepackage{tcolorbox} 以降に...
\tcbuselibrary{skins}
\usepackage{totalcount}
\newcounter{framenumber}
\setcounter{framenumber}{0}
\DeclareTotalCounter{framenumber}
\tcbuselibrary{skins}
は, 大雑把に言って, tcolorbox の機能を拡張するためのおまじないです.
totalcount パッケージは, 総ページ数を記載するために利用します.
framenumber
というカウンタを定義しておき, \DeclareTotalCounter{framenumber}
とすることで, \totalframenumbers
というコマンドで最終的な framenumber
の値 (総ページ数) を取得することができます.
framenumber
の値を増やすには, \refstepcounter{framenumber}
とします.
さて, tcolorbox
環境の方は, 以下のようにします.
\begin{minipage}{\framewidth}
\begin{tcolorbox}[
% タイトル
adjusted title=スライドタイトル,
% 高さ
height=\frameheight,
% タイトルのフォント
fonttitle=\Large,
% 色
colback=white,
coltext=black,
colbacktitle=blue,
coltitle=white,
% 枠線
boxrule=0mm,
sharp corners,
% 余白
boxsep=0mm,
top=1em,
bottom=1em,
right=1em,
left=1em,
toptitle=1ex,
bottomtitle=1ex,
% ページ番号
enhanced,
before={\refstepcounter{framenumber}},
overlay={
\node[above left,scale=0.7,inner sep=2mm] at (frame.south east) {\color{gray}\theframenumber/\totalframenumbers};
}
]
スライドの中身
\end{tcolorbox}
\end{minipage}
増えたのは以下の3箇所です.
enhanced,
before={\refstepcounter{framenumber}},
overlay={
\node[above left,scale=0.7,inner sep=2mm] at (frame.south east) {\color{gray}\theframenumber/\totalframenumbers};
}
-
enhanced
によって, 拡張された機能を使うことができるようになります. 具体的には,overlay
が使えるようになります. -
before
は, 箱を描画する前に実行される内容を記述します. ここではframenumber
というカウンタの値を増やしています. -
overlay
の中はtikzpicture
環境と同じになっており, ここに TikZ のコマンドを書くことで,tcolorbox
の上から TikZ の図形が描画されます.
overlay
の中では, tcolorbox
環境そのものを frame
というノードとして利用できます. つまり, (frame.south east)
は tcolorbox
環境の右下の角です.
そこに \node
を置くことで, \theframenumber/\totalframenumbers
, つまり「ページ番号/総ページ数」を出力します.
1ページ目:
2ページ目:
その他にできること
tcolorbox
環境はかなり自由にカスタマイズできるので, 何でもできると言っても過言ではありません.
例えば, プレゼンのタイトル (表紙) ページのデザインや, セクション区切りのページのデザインも, 自由に考えることができます.
他にも, 目次を作ったり, 付録以下は総ページ数に含まないようにするとか, (頑張れば) いろいろできます.
tcolorbox パッケージのより詳しい使い方は, CTAN にある公式ドキュメントが一番参考になります.
また, 日本語での解説記事もたくさん存在しますので, 参考になると思います.
tcolorbox を使って, 自分だけの最強のスライドを作りましょう.
Q & A
上下左右に小さな余白があるのが気になる
上の方法で作った pdf ファイルには, 上下左右に小さな余白があるため, Adobe Acrobat などで全画面表示するとその余白が白く目立ってしまいます.
それが気になる場合, pagecolor パッケージによって pdf の背景色を黒にすることでごまかしましょう.
プリアンブルに以下を記述すると良いです.
\usepackage[pagecolor=black]{pagecolor}
pagecolor なし
pagecolor あり
箇条書きを beamer のようにカスタマイズしたい
enumitem パッケージを使いましょう.
overlay specification を使いたい
以下の記事を参考に, PowerPoint に変換しちゃいましょう.
カスタマイズの手間や学習コストはbeamerと大差ないのでは?
それはそう.
結局コンパイルに時間がかかるのでは?
それはそう.
-
例えば, enumitem パッケージがうまく動きません. ↩