読者です 読者をやめる 読者になる 読者になる

物理とTeXに関する話題

TeXを利用した教材作成や、高校物理、受験全般についてのブログです。

tcolorboxの基本

この記事は TeX & LaTeX Advent Calendar 2015 の17日目の記事です。 16日目はdoraTeXさんでした。 18日目はVoDさんとなっています。

この記事中の画像は全てdoraTeXさん開発の TeX2img で作成しています。

TeXで枠囲みを作成するパッケージ

TeXユーザーの集い2015では,tcolorbox パッケージを利用した枠囲みの作成について紹介しましたが,それ以外にも枠囲みの作成を可能にする様々なパッケージがあります。

  • ページまたぎが可能な枠
    • tcolorbox:TikZ を用いてデザインを自由に作れる。
    • mdframed:枠の作成に TikZ を利用することができる。
    • itembkbx:emath が提供する。ページまたぎ可能な枠を作成。
  • ページまたぎができない枠
    • itembbox:ascmac が提供する。
    • niceframe:装飾付きの枠を作成。

tcolorboxの基本的な使い方

上で挙げたパッケージの内,option の数が最も多く,TikZ を自由に使える tcolorbox について,TeXユーザーの集い2015で発表しました。 マニュアルを読むのが最も確実な利用法習得の方法ですが,400ページを超える英語のマニュアルであるため,読む気があまりせず,読んでみてもなかなか内容が頭に入らないのが実際です(2周くらいするとスムーズに理解できます…笑)。 そこで今回の記事では,tcolorbox の基本的な利用方法について紹介したいと思います。

プリアンブル

pLaTeX で利用する際の典型的なプリアンブルは以下の通りです。

\documentclass[dvipdfmx]{jsarticle}
\usepackage{tcolorbox}

凝った内容の枠を作成する場合には,さらに library を読み込む必要があります。例えば,raster library と skins library を読み込みたい場合には,上記のプリアンブルに

\tcbuselibrary{raster,skins}

と書き加えます。

tcolorboxの作成

最もシンプルな tcolorbox を作成するには,

\begin{tcolorbox}
box contents
\end{tcolorbox}

とすれば, f:id:hkf-164:20151215141729p:plain のような出力が得られます。

さらに option を追加することで,box の見た目に様々な変化を加えることができます。

  • タイトルの追加title
\begin{tcolorbox}[title=box title]
box contents
\end{tcolorbox}

f:id:hkf-164:20151215142311p:plain

  • サイズの調整width height
\begin{tcolorbox}[title=box title, height=3cm]
box contents
\end{tcolorbox}

f:id:hkf-164:20151215143252p:plain

  • 色の変更
    • colback:box 本体の背景色の変更
    • colframe:box のフレームの色の変更
    • colbacktitle:タイトルの背景色の変更
    • coltitle:タイトル文字色の変更
    • coltext:本文の文字色の変更
\begin{tcolorbox}[colframe=forestgreen,
  colback=forestgreen!10!white,
  colbacktitle=forestgreen!40!white,
  coltitle=black, fonttitle=\bfseries,
  title=My box]
box contents
\end{tcolorbox}

f:id:hkf-164:20151215175831p:plain

  • ページまたぎbreakable

options として,breakableを追加するだけで box がページまたぎに対応します。この場合,breakable library を利用することになるので,プリアンブルに

\tcbuselibrary{breakable}

と書き加える必要があります。

  • 影をつけるdrop shadow drop fuzzy shadow drop lifted shadow

影をつける際には,利用する skin を enhanced にする必要があります。プリアンブルに

\tcbuselibrary{skins} %preamble

と書き加えた上で,options 部分に enhanced と書けば解決します。後に紹介する empty skin もそうですが,デフォルトの standard skin 以外の skin を利用する場合には skins library の読み込みが必須になります。

\begin{tcolorbox}[enhanced,
  colframe=salmon,
  colback=salmon!20!white,
  coltitle=black,
  drop fuzzy shadow, title=My box]
box contents
\end{tcolorbox}

f:id:hkf-164:20151215180619p:plain

  • 角の変更sharp corners
\begin{tcolorbox}[title=My box,
  sharp corners]
box contents
\end{tcolorbox}

f:id:hkf-164:20151215181025p:plain

sharp corners=northwestのように書けば,左上の角だけをシャープにすることも可能です。

  • タイトルの独立・位置変更

こちらのオプションを利用するにも enhanced skin を利用する必要があります。基本的に,枠の描画に TikZ を利用する際には enhanced skin を利用するのがよいでしょう。drop fuzzy shadowなどは TikZ を利用しているので,enhanced skin として TikZ を利用できるようにしています。

タイトルの独立には,attach boxed title to <position>を利用します。position の部分には,top center top left bottom rightのように,タイトルを移動させたい部分の名前を入れます。

\begin{tcolorbox}[enhanced,title=My title,
  attach boxed title to top center]
box cotents
\end{tcolorbox}

f:id:hkf-164:20151215182145p:plain

さらに,タイトルの位置を微調整するには,attach boxed title to top left={yshift*=<length>}のように書きます。yshift*を付けることで,タイトルが入った tcbox と重ならないように本文開始の縦位置が自動調整されます。

\begin{tcolorbox}[enhanced,title=My title,
  attach boxed title to top left=
  {xshift=3mm, yshift*=-\tcboxedtitleheight/2}]
box cotents
\end{tcolorbox}

f:id:hkf-164:20151215182706p:plain

オリジナルの box を作成する際には,この option が不可欠になります。

  • 余白の調整left right top bottom

box の本文領域とフレームの間のスペースを指定します。デフォルトでは,

top bottom left right
2mm 2mm 4mm 4mm

となっていますが,box をイチから作成する際にはこのスペースを適宜変更する必要があります。

\begin{tcolorbox}[title=My title,
  top=1mm, left=10mm, bottom=5mm]
box contents
\end{tcolorbox}

f:id:hkf-164:20151215232314p:plain

  • 上下分割

これは option ではありませんが,box の本文中で\tcblowerを利用すると,box を上下のパートに分割できます。

\begin{tcolorbox}[title=My box]
This is a tcolorbox.
\tcblower
This is the lower part.
\end{tcolorbox}

f:id:hkf-164:20151217004128p:plain

tcbox の作成

tcbox は,インラインで利用するための box です。環境で作成する tcolorbox と異なり,コマンドで作成します。

ほげ\dotfill\tcbox[box align=center]{ほげ}%
\dotfill\tcbox[box align=base]{ほげほげ}

f:id:hkf-164:20151215233740p:plain

option のbox align={position}で tcbox のインラインでの高さを調整できます。上の例にあるcenterbase以外にtop bottomがありますが,これらの使用頻度は低いです。

先ほど紹介したattach boxed title to <position>によるタイトルの位置変更は,タイトルを tcbox に入れることによって実現されています。

\tcbsetの利用

グルーピングされている全ての tcolorbox に適用させる options を指定することができます。

\tcbset{colback=blue!30!white, sharp corners}
\begin{tcolorbox}
box contents
\end{tcolorbox}
\begin{tcolorbox}[enhanced,title=My box, 
  colbacktitle=blue!50!white,
  fuzzy halo=1mm with blue!30!white]
box contents
\end{tcolorbox}

f:id:hkf-164:20151216080846p:plain

以上の options が使えればある程度の box は自由に使えると思います。枠の余白調整など,更に細かくカスタマイズしたい場合は,tcolorbox のマニュアルを御覧ください。

オリジナルの枠の作成

box を定義する
  • 新たな tcbox を定義する

\newcommandと同様にして,\newtcboxを用いることで新たな tcbox を定義することができます。

\tcbset{nobeforeafter, box align=base}
\newtcbox{\mybox}[1][]{colback=orange!30!white,
  colframe=orange, #1}
hoge\dotfill\mybox{hoge}%
\dotfill\mybox[title=mybox, colbacktitle=orange]{hogehoge}

f:id:hkf-164:20151216083923p:plain

  • 新たな tcolorbox を定義する

\newenviromnentを用いて環境を定義できるのと同様にして,\newtcolorboxを用いることで新たな tcolorbox を定義することができます。

\newtcolorbox{mybox}{colback=orange!30!white, colframe=orange}
\begin{mybox}
box contents
\end{mybox}
\begin{mybox}[title=My box, colbacktitle=orange]
box contents
\end{mybox}

f:id:hkf-164:20151216082236p:plain

この\newtcolorboxの弱点としては,省略可能引数を1つしか取れない点が挙げられます。より様々な引数を取れる box を作成するためには,xparse library を利用します。プリアンブルに

\tcbuselibrary{xparse} %preamble

と書くと,xparse パッケージが提供する\DeclareDocumentEnvironmentと同様にふるまう\DeclareTColorBoxが利用できるようになります。複雑な枠をイチから作成する際には,xparse library の利用が不可欠でしょう。その他に,\DeclareTotalTColorBox\DeclareTCBoxといったコマンドもありますが,詳細はtcolorbox マニュアルをご覧ください。

box の見た目を変える

enhanced skin を利用して,枠の見た目を変えることができます。options としては,frame styleを利用します。

\begin{tcolorbox}[enhanced,title=My title,
  frame style={left color=orange!50!white,
  right color=red!50!white}, 
  colback=orange!10!white,  coltitle=black]
box contents
\end{tcolorbox}

f:id:hkf-164:20151216094038p:plain

一方で,枠の形自体(box 描画の code)を変更するには,frame codeを利用します。

\tcbset{colframe=green!75!black, colback=green!10!white}
\begin{tcolorbox}[enhanced,frame code={
  \foreach \n in {north east,north west,south east,south west}
  {\path [fill=green!75!black] (interior.\n) circle (3mm); }; }]
box contents
\end{tcolorbox}

f:id:hkf-164:20151216110947p:plain

box 内部の描画形式を変形するにはinterior codeを(タイトル付きの場合はinterior titled code),上下分割の segmentation の描画形式を変更するにはsegmentation codeを,タイトル背景部の描画形式を変更するには,title codeを利用します。

色などを変更するだけの場合は,interior styletitle styleを利用します。

\tcbset{colframe=black, fonttitle=\bfseries}
\begin{tcolorbox}[enhanced,title=My title,
  title style={left color=black,
  right color=black!5!white}]
This is a tcolorbox. 
\tcblower
This is the lower part. 
\end{tcolorbox}

f:id:hkf-164:20151216112016p:plain

box をイチから作成する

枠描画などのデフォルト値をリセットして,イチから box を作成する手順を簡単に紹介します。

まず,枠描画のデフォルト値を全てリセットするために,empty skin を利用します。enhanced skin を利用する際と同様に,options の部分にemptyと書くだけです。デフォルトの skin は pgfpicture で描画される standard skin ですが,enhanced skin や empty skin を使えば tikzpicture で描画されるようになるので,TikZ のコマンドを利用した枠の描画が可能になります。

\begin{tcolorbox}[empty, borderline={2pt}{0pt}{black!10!white},
  coltitle=red!50!black, title=My title,
  left=1mm,right=1mm,top=1mm,bottom=1mm,middle=1mm]
This is a tcolorbox.
\tcblower
This is the lower part.
\end{tcolorbox}

f:id:hkf-164:20151216113145p:plain

このように empty skin を利用すると,枠,背景の塗り,タイトル背景の塗り,上下分割の線など,全てがなくなります。*1

このように一旦全てをカラにした上で,以下に紹介するunderlayオプションを利用して枠を作成します。

underlayを利用した描画

option のunderlayを利用することで,TikZ コマンドを用いて box に自由な描画を加えることができます。

\newtcolorbox{mybox}[1][]{enhanced, colbacktitle=white!35!black,
  colframe=black,fonttitle=\bfseries,
  underlay={\begin{tcbclipinterior}
  \draw[black!40!white,line width=1cm]
  (interior.south west)--(interior.north east);
  \end{tcbclipinterior}}}
\begin{mybox}
\lipsum[2]
\end{mybox}

f:id:hkf-164:20151216123518p:plain

同様にoverlayという option もあります。overlayは option の中で複数回利用できない(2度目以降のoverlayは無視される)のに対し,underlayは複数回の利用が可能です。また,watermarkというoption (box の背景に薄い文字を書く)はoverlayを利用しているので,overlaywatermarkを同時に利用することができません。

枠を描くエンジンは,

  1. shadow
  2. frame
  3. interior
  4. title area
  5. segmentation
  6. border line
  7. underlay
  8. overlay (watermark 含む)
  9. text content
  10. finish

の順番で描画を行うので,overlayunderlayの双方を使わない限りは見た目の差は現れません。underlayは,その名前からして枠の下に描画をするイメージですが,overlayに対して下に描くだけで,interior や segmentation に対しては上に描画をします。以上の理由から,普段はunderlayを利用しています。

複数箇所に分けて code を書く場合にはunderlayなら問題ありませんが,hooks library が提供するoverlay appoverlay preを利用するという手もあります。これなら watermark と被るという不都合が発生する心配もありません。

作成枠の例

以上の内容を用いると,作りたい枠を作成することができます。

\tcbuselibrary{xparse} %preamble
\DeclareTColorBox{simplesquarebox}{ o m O{.5} O{} }% 
  {empty, left=2mm, right=2mm, top=-1mm, attach boxed title to top left={xshift=1.2zw},
  boxed title style={empty,left=-2mm,right=-2mm}, colframe=black, coltitle=black, coltext=black, breakable,  
  underlay unbroken={\draw[black,line width=#3pt]
    (title.east) -- (title.east-|frame.east) -- (frame.south east) -- (frame.south west) -- (title.west-|frame.west) -- (title.west); },
  underlay first={\draw[black,line width=#3pt](title.east) -- (title.east-|frame.east) -- (frame.south east) ;
    \draw[black,line width=#3pt] (frame.south west) -- (title.west-|frame.west) -- (title.west); },
  underlay middle={\draw[black,line width=#3pt](frame.north east) -- (frame.south east) ;
    \draw[black,line width=#3pt](frame.south west) -- (frame.north west) ;},
  underlay last={\draw[black,line width=#3pt](frame.north east) -- (frame.south east) -- (frame.south west) -- (frame.north west) ;},
  fonttitle=\gtfamily, IfValueTF={#1}{title=【#2】〈#1}{title=【#2},#4}
\begin{simplesquarebox}{My box}
\lipsum[2]
\end{simplesquarebox}

f:id:hkf-164:20151216145335p:plain

上の例にあるように,breakable な box をunderlayを用いて作成する際には,代わりに以下の options を利用することになります。

  • underlay unbroken:box がページをまたがないときの描画を指定
  • underlay first:box がページをまたぐ際の最初のページの描画を指定
  • underlay middle:ページをまたぐ box における,ボックスの始まりも終わりもない真ん中の box の描画を指定
  • underlay last:ページをまたぐ box において,終りの部分を含むページにおける描画を指定

なお,上の simplesquarebox では,引数を4つ取れるようにしてあります。各引数は,

  1. 省略可能なサブタイトル
  2. 省略不可能なタイトル
  3. 枠の太さ(省略可。デフォルトは.5pt)
  4. 追加 options

となっています。これらをフルに活用すると,以下のような出力になります。

\begin{simplesquarebox}[subtitle]{My box}[1.5][watermark text={Watermark}]
\lipsum[2]
\end{simplesquarebox}

f:id:hkf-164:20151216150701p:plain

underlayの中では TikZ の描画コマンドが自由に使えるので,ここまで紹介した内容を利用すればどんな枠でも作成できます。ただ,曲線を含む枠は TikZ code が複雑になる,といった問題点もあります。

mdframed との比較

ページまたぎができて,TikZ も利用できる mdframed パッケージと今回紹介した tcolorbox を簡単に比較してみたいと思います。

  • options の豊富さ

上に見たように,tcolorbox は多くの options を利用することで box のサイズを変更したり,見た目を変えたりすることができます。mdframed でも同様に options でカスタマイズをすることができますが,tcolorbox に比べるとその量ははるかに少ないです。

  • library の読み込み

tcolorbox では,library を読み込むことで機能を拡張することができます。既に挙げた xparse や hooks がその一例です。

中でも mdframed では実現できない「複数の box を整列させる」ことを可能にする raster library は非常に便利です。以下に簡単に例を挙げます。

\tcbuselibrary{raster} %preamble
\begin{tcbraster}[raster columns=3,raster equal height,title=Box \thetcbrasternum]
\begin{tcolorbox} First \end{tcolorbox}
\begin{tcolorbox} Second \end{tcolorbox}
\begin{tcolorbox} Third \\ Third 2 \end{tcolorbox}
\end{tcbraster}

f:id:hkf-164:20151216231705p:plain

この raster library を利用することで,tcolorbox を用いた様々なレイアウトが可能になります。詳細は,TeXユーザの集い2015発表スライドを御覧ください。

  • 将来性

まず,mdframed パッケージが2013年7月以降,更新されていないのに対し,tcolorbox は新たな options が追加され続けている,という違いがあります。2013年5月の version 2.22 のマニュアルが153ページしかなかったのに対し,(本記事執筆時点で)最新の version 3.80 のマニュアルは428ページであり,実に2.5倍ほどの内容量の進化を遂げています。この点を踏まえると,tcolorbox の方が将来性があるといえるでしょう。

おわりに

現時点では tcolorbox はまだまだ広く普及しているとはいえない状況ですが,本記事を通して少しでも tcolorbox を利用してくださる方が増えればと願っております…!

*1:empty skin を用いる意義は「全てを空にする」ことですが,この例ではサンプルとして分かりやすくするために,tcolorbox の内外を明確にするべく borderline option を利用して境界線を描いておきました。この枠はあくまで境界線であって,tcolorbox の frame engine によって「tcolorbox の枠」として描かれたものではありません。