キャラクタ表のマクロ2


どうしても、完成させたかったのでしつこくがんばってみました。
使う予定がないのですけど。
それでも、\@for マクロとか、カテゴリコードとか勉強になったので、よしとします。
画像作るときには、間違って jarticle 使っていましたが、jsarticle で問題ないです。というか、jsarticleの標準の余白が少なめなので、文字の箱が大きく取れて、具合がいいです。そういったことで、ソース例は、jsarticle にしてあります。

\documentclass{jsarticle}
\usepackage{chartable}
\begin{document}
\begin{table}[h]
 \caption{キャラクタ表}
 \begin{center}
  {\font\foct=octopus at 15pt \foct\chartable[9,32]}
 \end{center}
\end{table}
\end{document}

\chartable[9,32] の オプションは、\char9、\char32 を強調表示させるという意味です。ここで、32 の代わりに "20 という16進表記が使えるということを、今回初めて知りました。内部では \char"20 と使うこともできるらしいです*1

参考にしたのは、TeXブックといいたいとこですが、それよりも、latex.ltx(ltcntrl.dtx)やkeyval.styの方がたくさん参照したと思います*2。\charもいいけど、\chardef の方がプログラミングには楽だということが、大きな発見でした。

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{chartable}[2011/09/18 character table]

\usepackage[dvips,usenames]{color}
\usepackage{colordvi}

%\tracingonline=1%
%\tracingcommands=2%
%\tracingmacros=1%

% 新しいカウンタ n の作成
\newcount\charindex%キャラクタ番号カウンタ
\newcount\hexnum%16進数字のカウンタ
\newdimen\boxsz \boxsz=\hsize%文字用の箱の幅・高さ

% キャラクタ表マクロ
\def\chartable{\@ifnextchar[\@chartable{\@chartable[]}}%]

\def\@chartable[#1]{%
%
  \global\def\LIST{#1}%強調キャラクタ番号のリスト
  \global\divide\boxsz 17%
  \global\charindex=0%初期値0の代入
  \halign to\hsize\bgroup% \halign \bgroup --> body内で \egroup
  \tabskip 0pt plus 1pt
  &\vrule\chartstrut##&\hbox to\boxsz{\hfil##\hfil}\cr\hline%テンプレート
  \global\hexnum=0 \tablehead%ヘッダ
  \global\hexnum=0 \body%表本体部位
  \rightline{\tt$sp$:space(=category\ 10)}%
}

\def\chartstrut{\lower 7pt\vbox to\boxsz{}}

% 本体部位マクロ
\def\body{%
  \ifnum\charindex=256\egroup%256個処理したら終了
  \else\line\body%それ以外は行の出力と本体の再帰呼出し
  \fi}

% 行マクロ
%   :マクロを16個
\def\line{&\h\0&&\:&&\:&&\:&&\:&&\:&&\:&&\:&&\:&&\:&&\:&&\:&&\:&&\:&&\:&&\:&&\:&\cr\hline}

% テーブルヘッダマクロ
%
\def\tablehead{%
  &&&\0\h&&\0\h&&\0\h&&\0\h&&\0\h&&\0\h&&\0\h&&\0\h&&\0\h&&\0\h&&\0\h&&\0\h&&\0\h&&\0\h&&\0\h&&\0\h&\cr%
  \hline%
}

% 16進数表記マクロ
%   0A や A0 のように、一方が 0 なので、\0 マクロで 0 を出力して、
%   \h マクロで一方の16進数字を出力。
%   横方向(tablehead)は \0\h、
%   縦方向(line)は、\h\0 で出力。
%   \h を呼び出すと hexnum を内部で1つインクリメント。
%   \h を使う前には0クリアが必要。
%   
\def\0{$0$}

\def\h{%
  \newcount\hstr \hstr=\hexnum
  \ifnum\hexnum<10 \advance\hstr by48
  \else \advance\hstr by55 \fi
  $\char\hstr$%
  \global\advance\hexnum by1
}

% 罫線マクロ
%
\def\hline{%
  \noalign{\nointerlineskip}
  \multispan{35}\hrulefill&\cr
  \noalign{\nointerlineskip}}

% :マクロ
%   \char<n>を出力して、n のインクリメント
\def\:{\noboundary\character{\charindex}\noboundary \global\advance\charindex 1}

% キャラクタマクロ
%
\newcount\cc

\def\character#1{%
  \newif\ifget \getfalse
  \@for\item:=\LIST \do{\ifnum\item=#1\gettrue\fi}%強調文字の探索
%
  \chardef\@char=#1%
%
  \cc=\catcode\@char%
  \ifnum\cc=10 \ifget\textcolor{Red}{\tiny$sp$}\else{\tiny$sp$}\fi
  \else        \ifget\textcolor{Red}{\@char}\else\@char\fi \fi
}
\endinput

*1:yatexで入力してるので、''に置き換えられてしまいあわてましたが、cntrl-q" とするのですね。

*2:/tex/share/texmf/source/latex/base/ltcntrl.dtx、/tex/share/texmf/tex/latex/graphics/keyval.sty。