マクロツイーター

はてダから移行した記事の表示が崩れてますが、そのうちに直せればいいのに(えっ)

tabular のセルに斜線を入れる話

結局、例のアレは、「当初の質問」が解決しないまま終わってしまったようだ。なんかアレなので、ちょっと、「表のセルに斜線を入れる」話をしようと思う。

何故 slashbox ではアレなのか

そもそも、slashbox パッケージは、以下に示すような、“斜線の両側にラベルを入れた”セルを実現するためのものである。


つまり、「斜線だけを入れる」という用途は想定されていない。だから、ラベルを空にしたとしても、相変わらずラベルの領域の確保のため縦幅が大きくなり、“想定した結果”にはならないのである。また、slashbox は「TeX の機能」、すなわち「素の picture 環境の機能」だけを用いて斜線を描いている。*1このため、斜線の配置があまり適切にならない場合があるようである。

slashbox の改良版(または代替品*2)に相当するものとして、diagbox というパッケージがある。こちらは pict2e の機能により任意の長さと傾きの斜線が描けるため、slashbox よりも適切な結果が得られる。*3ただし、このパッケージも「斜線だけを入れる」という用途は想定していないので、その用途で使うのは難しい。

ざっと見た限りだと、この「斜線だけを入れる」という機能をもつパッケージは CTAN の範囲では存在しないようである。恐らく、日本以外に「セルに斜線を入れる」習慣がないため?

絶望の予感

もし、「セルに斜線を入れる」という機能をもつパッケージがあるとすれば、そこに期待する機能は以下のようなものだろう。

tabular 環境で作られた表が存在していて、その特定のセルを対象として「斜線を入れる」という命令を実行すると、対象のセルの矩形の対角線が描かれる。(そしてその他は何も変わらない。)

ところが、実際には、この機能を実現することは著しく困難で、恐らく不可能だと思わえる。それは以下の理由による。

  • LaTeX の tabular 環境(およびその拡張の多く)は “TeX の表組”(配列;align)の機能を利用している。
  • TeX の表組”自体には斜線を生成する機能はない。だから、セルの“中身を斜線にする”必要がある。
  • セルの横幅は、当然、そのセルのある列の横幅に等しく、これは(p 指定の列でない限り)その列の内容物の最大の横幅に一致する。縦幅についても同様に、そのセルの行の内容物の最大の縦幅に一致する。
  • 従って、特定のセルの処理中には、そのセルの縦幅・横幅を知ることは原理的に不可能である。そのため、正確に「セルの矩形の対角線」を描くこともできない。

そういうわけで、結局、「tabular の表のセルに対して、適切な斜線を自動的に決定して描く」ことは望めないのである。

姑息な解決方法

非常に残念な結果になった。だがしかし、これを逆手にとってみよう。

自動でそもそもできないのであれば、手動での“その場しのぎ”の方法も十分に理に適っている!

つまり、表の内容とレイアウトが完全に固まった後に、「現在のセルの大きさ」に合わせて決めた斜線を引けばいいのである。この方法であれば、「斜めの線を描く」機能さえあればよく、pict2e や PSTricks や TikZ 等の“どこにでもある”パッケージだけで事足りる。今の TeX 界は TikZ の時代のようなので、ここでは TikZ でやってみよう。

TikZ で姑息な手段

例えば、次の表の左上のセルに斜線を入れたいとしよう。

\begin{tabular}{|c||c|r|}\hline
%(*このセルに斜線を入れたい*)
 & 値段 & カロリー \\\hline
牛丼並盛 & 480円 & 600 kcal \\
牛丼テラ盛 & 1,980円 & 2,900 kcal \\\hline
\end{tabular}


TikZ を利用する場合に気をつけるべきなのは“外見のサイズ”の調整である。通常は、TikZ は描画の内容に応じて“外見のサイズ”を決定するので、適切な調整がされないと、どんな線分を描いても、セルとの間に隙間が空いてしまう。

%(当該のセルに次のコードを入れる)
\tikz{\draw(-1,0.3)--(1,-0.3);}


(ここで TikZ が把握した“外見”の領域に色を付けて示した。)

TikZ における“外見のサイズ”の制御については、以下の記事が詳しいのでそれを参照してほしい。

ここでの用途では、以下の処置が必要である。

  • セルの大きさを変更(拡張)してはいけないので、外見のサイズ(横幅・高さ・深さ)をゼロにする。すなわち、バウンディングボックスを“原点だけ”にしてしまう。
  • さらに、ベースラインと図の縦方向の相対位置を固定するため、base パラメタを指定する。

この処置を行った上で、適当な座標で試しに線分を描くと以下のようになる。

%(当該のセルに次のコードを入れる)
\tikz[baseline=0pt]{% 図内のベースライン位置を固定
\useasboundingbox(0,0);% 外見サイズをゼロにつぶす
\draw(-1.5,0.8)--(2,-0.5);}% まだ座標は正しくない


もちろん斜線の位置はまだ全然合ってないわけだが、重要なことは、上記の処置を行ったことで図内の原点の位置(赤い丸で示した)が表のセルの中の一定の箇所に固定されたことである。だから後は、結果を見ながら斜線の両端点の座標を調節すればよい。もちろん、その補助のために一時的にグリッドを描くことも可能である。

最終的に、「セルに斜線を入れた」ソースコードは次のようになる。

\begin{tabular}{|c||c|r|}\hline
  \tikz[baseline=0pt]{% 斜線
    \useasboundingbox(0,0);
    \draw(-1.03,0.40)--(1.03,-0.17);}
  & 値段 & カロリー \\\hline  
  牛丼並盛 & 480円 & 600 kcal \\
  牛丼テラ盛 & 1,980円 & 2,900 kcal \\\hline
\end{tabular}

*1:このことは、slashbox に“ドライバ依存”が無いことから判る。

*2:slashbox パッケージはライセンスが不明瞭なため TeX Live には含まれていない。

*3:その代わり、pict2e を利用するため“ドライバ依存”が起こる。