2016年4月17日日曜日

定理環境をmdframedからtcolorboxへ乗り換え

追記:2016/05/02 以前に掲載していた定理環境のマクロでは、カウンターが変化しないような記述をしてしまっていたので、全面的に書き換えました。
追記:2016/06/06 tcolorboxのオプションを追加できるように書き直しをしました(tcolorboxを使った定理環境)。

LaTeXの話です。
これまで定理環境の修飾にmdframed.styを利用してきました。
しかし上の投稿で用いた記述をしていると、定理環境がページの下部にきたとき、まれに以下のように環境が新しいページに送られてしまい変なところで改ページが起こります。
TeX-LaTeX Stack Exchangeでも同様の不具合が報告されていて、mdframed.styの作者が回答して解決しているようなのですが、私の場合は上手く行きませんでした。タイトル部分の位置の計算に問題があるようです。

そういう訳で、mdframed.styよりも高い表現力を持つtcolorbox.styには興味を持っていました。今回は、mdframed.styで記述していた部分を、ソースの変更無しにtcolorboxで置き換えてみたので、その紹介をします。

tcolorbox.styで置き換えた結果は次のようになりました。

見た目はほとんど変わっていません。中のboxは別のtcolorbox環境です。
この定理環境のソースコードは次のようになります。

\usepackage{tcolorbox}
\usepackage{varwidth} 
\tcbuselibrary{breakable}
\tcbuselibrary{skins}

\definecolor{frameinnercolor}{RGB}{49,44,44}

\newcounter{theorem}
\numberwithin{theorem}{section}% numberwithinはamsmath.styで定義されている
\newenvironment{theorem}[2][]{%
%#1 = タイトル, #2 = 定理環境名
\refstepcounter{theorem}%
\newtcolorbox{theobox}[1][]{%
enhanced,frame empty,interior empty,
coltitle=white,fonttitle=\bfseries,colbacktitle=frameinnercolor,
extras broken={frame empty,interior empty},
borderline={0.5mm}{0mm}{frameinnercolor},
sharp corners=downhill,
breakable=true,
top=4mm,
before skip=3.5mm,
attach boxed title to top left={yshift=-3mm,xshift=3mm},
boxed title style={boxrule=0pt,sharp corners=all},varwidth boxed title,
title=##1,
}
\ifstrempty{#1}{% ifstremptyはetoolbox.styで定義.etoolbox.styはtcolorboxが読み込むので宣言不要
\begin{theobox}[#2~\thetheorem.]}
{\begin{theobox}[#2~\thetheorem:~{#1}]}
}{\end{theobox}}


\newenvironment{theo}[1][]%
{\begin{theorem}[#1]{定理}%
}{\end{theorem}}


\newenvironment{prop}[1][]%
{\begin{theorem}[#1]{命題}%
}{\end{theorem}}

\newenvironment{lem}[1][]%
{\begin{theorem}[#1]{補題}%
}{\end{theorem}}

多くのスタイルファイルで定義されている定理環境では、タイトルは省略可能な引数になっているのですが、tcoloboxのtheorems  libraryで作る定理環境は、タイトルやラベルが省略できない仕様になっており、省略したい場合は空の括弧を書いて置かなければならないようです。私が作っているノートでは、タイトルを省略可能なタイプの定理環境で記述しているため、theorems libraryを使わないで定理環境を作ってみました。

ここではtheoremという2つの引数を持つ環境を最初に定義しています.
第1の引数には省略可能なタイトル,第2の引数には定理環境名をそれぞれ入れるようにしています.その後でこのtheoremという環境を使ってtheoという環境を定義しています.これはtheorem環境の第2の引数に「定理」や「命題」などを入れることで新しい定理型環境を簡単に作れるようにしました.但しカウンターは全て共通しているので,通し番号をつける使い方しかできません.

breakableライブラリを使って複数ページにわたる枠囲みが表示できるようにしています。枠がページをまたぐときに、枠内の設定がデフォルトに戻ってしまうらしく、それを防ぐためにextras brokenオプションでページをまたいだ枠内の設定を行う必要がありました。

これで今までのノートのソースを変更することなくtcolorboxへの移行ができました。変な改ページも無くなったので現時点では満足しています。tcolorboxはマニュアルを見るとかなり色々なことが出来そうなので、もっと見栄えの良いノートを作りたくなってきました。


また、tcolorboxのカウンター機能を使えばもっとスマートになると思い、newtcolorboxの定義のオプションにauto counterを入れて次のような定理環境を作ってみました。
しかし私のノートでは、カウンターの番号が幾つかずれてしまい上手く機能しませんでした。原因は何なのだろう。
\usepackage{tcolorbox}
\usepackage{varwidth} 
\tcbuselibrary{breakable}
\tcbuselibrary{skins}

\definecolor{frameinnercolor}{RGB}{49,44,44}

\newtcolorbox[auto counter,number within=section]{theobox}[1][]{%
enhanced,frame empty,interior empty,
coltitle=white,fonttitle=\bfseries,colbacktitle=frameinnercolor,
extras broken={frame empty,interior empty},
borderline={0.5mm}{0mm}{frameinnercolor},
sharp corners=downhill,
breakable=true,
top=4mm,
before skip=3.5mm,
attach boxed title to top left={yshift=-3mm,xshift=3mm},
boxed title style={boxrule=0pt,sharp corners=all},varwidth boxed title,
title=#1,
}

\newenvironment{theorem}[2][]{%
%#1 = タイトル, #2 = 定理環境名
\ifstrempty{#1}{% ifstremptyはetoolbox.styで定義.etoolbox.styはtcolorboxが読み込むので宣言不要
\begin{theobox}[#2~\thetcbcounter.]}
{\begin{theobox}[#2~\thetcbcounter:~{#1}]}
}{\end{theobox}}