あるいは 〜私の TeX プログラム変換環境〜
前回までの説明で、ようやく「えるたそ」の Lua プログラム(元は (2)の eltaso.lua、Lua 内変換後は (9)の eltaso4.lua)を TeX のプログラムに変換する準備が整った。ここからは部分に分けて、元の Lua のコードを TeX のコードに変換した結果を示し、必要に応じて説明を行うことにする。(ただし前言の通り、詳細な変換の規則については敢えて省略する。)
1〜4行目: 変数一覧
冒頭の変数の一覧が記してある部分。Lua では単なるコメントだが、言語によっては変数宣言であるかも知れない。
-- [変数一覧] -- 整数: max, j, ires(戻り値) -- 文字列: dm, dc, dx, di, km, kc, kx, x, sres(戻り値) -- 配列: alpha_name, digit
% tceltaso.sty \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{tceltaso} %% 変数定義 %(整数型) \newcount\tclt@max \newcount\tclt@j \newcount\tclt@ires % 戻り値 %(文字列型) %\tclt@dm / \tclt@dc / \tclt@dx / \tclt@di %\tclt@km / \tclt@kc / \tclt@kx %\tclt@x %\tclt@sres % 戻り値 %(配列型) %\tclt@alpha@name/* %\tclt@digit/* %% \tclt@nameedef \def\tclt@nameedef#1{\expandafter\edef\csname#1\endcsname}
一番最初に書いてあるのはパッケージ宣言である。これは無くても特に動作には影響がないのであるが、一種の作法だと思って書いておこう。もしかしたら「パッケージがマトモに見える」というご利益があるかも ;-) ((その昔、現在の LaTeX2e と 旧版の LaTeX2.09 が並存していた頃には、この宣言は「LaTeX2e 専用である」ことを明示する意味を持っていた。(2.09 では \NeedsTeXFormat
は未定義なのでエラーになる。)))
なお、pLaTeX(系)専用のパッケージである場合は、\NeedsTeXFormat{pLaTeX2e}
という指定にする。こうしておくと、pLaTeX 以外の LaTeX で読み込もうとしたときは「pLaTeX じゃない」というエラーを出してくれる。*1
続いて、整数型の変数(整数レジスタとして表される)を \newcount
で定義する。文字列型と配列型の変数はマクロとして表されるので特に宣言の文は要らないが、情報を記しておいた方がいいだろう。大規模なパッケージの場合は、私は敢えて(本当は不要な)初期化文を入れることがある。
%(文字列型) \let\tclt@dm\@empty %空文字列で初期化 \let\tclt@dc\@empty %……
名前空間識別子を tclt
としたので、Lua での xxx_yyy
という識別子(配列変数や関数名も含む)は TeX では \tclt@xxx@yyy
という制御綴になる。
最後に、前回説明した \tclt@nameedef
のオマジナイを定義している。
6〜21行目: 配列宣言の初期化
j = 0 for _, x in ipairs({ "ぜっと", "えー", "びー", "しー", "でー", "いー", "えふ", "じー", "えいち", "あい", "じぇー", "けー", "える", "えむ", "えぬ", "おー", "ぴー", "きゅー", "あーる", "えす", "てぃー", "ゆー", "ぶい", "だぶりゅー", "えっくす", "わい" }) do _G["alpha_name/"..tostring(j)] = x j = j + 1 end j = 0 for _, x in ipairs({ "", "一", "二", "三", "四", "五", "六", "七", "八", "九" }) do _G["digit/"..tostring(j)] = x j = j + 1 end
%% \tclt@alpha@name/* : アルファベットの日本語読みの仮名表記 \tclt@j=0 \@for\tclt@x:=% ぜっと,% えー,びー,しー,でー,いー,えふ,じー,% えいち,あい,じぇー,けー,える,えむ,えぬ,% おー,ぴー,きゅー,あーる,えす,てぃー,ゆー,% ぶい,だぶりゅー,えっくす,わい% \do{% \tclt@nameedef{tclt@alpha@name/\the\tclt@j}{\tclt@x}% \advance\tclt@j 1 } %% \tclt@digit/* : 漢数字(1〜9) \tclt@j=0 \@for\tclt@x:=,一,二,三,四,五,六,七,八,九\do{% \tclt@nameedef{tclt@digit/\the\tclt@j}{\tclt@x}% \advance\tclt@j 1 }
名前参照の変数を用いた式の TeX への変換の方法についてはシリーズ(9)で説明した。ここの場合、右辺が文字列変数 x
(→\tclt@x
)なので、早速 \tclt@nameedef
を用いて展開させることになる。
元のコードの for-each 構文は素直に \@for
に置き換えればよい。
23〜39行目: 手続き knumeral()
function knumeral(_1) split_digit(_1) knum_pos(dm, "千"); km = sres knum_pos(dc, "百"); kc = sres knum_pos(dx, "十"); kx = sres sres = km .. kc .. kx .. _G["digit/"..di] end function split_digit(_1) -- TeXでは再実装が必要 dm, dc, dx, di = ("%04d"):format(_1):match("^(.)(.)(.)(.)$") end function knum_pos(_1, _2) if tonumber(_1) == 0 then sres = "" elseif tonumber(_1) == 1 then sres = _2 else sres = _G["digit/".._1] .. _2 end end
%% \tclt@knumeral{<整数n>} % 整数n(1〜9999)の漢数字表記. \def\tclt@knumeral#1{% \tclt@split@digit{#1}% \tclt@knum@pos{\tclt@dm}{千}\let\tclt@km\tclt@sres \tclt@knum@pos{\tclt@dc}{百}\let\tclt@kc\tclt@sres \tclt@knum@pos{\tclt@dx}{十}\let\tclt@kx\tclt@sres \edef\tclt@sres{\tclt@km\tclt@kc\tclt@kx\@nameuse{tclt@digit/\tclt@di}}% } \def\tclt@split@digit#1{% TODO:実装しろ % dm, dc, dx, di = % ("%04d"):format(_1):match("^(.)(.)(.)(.)$") } \def\tclt@knum@pos#1#2{% \ifnum#1=0 \def\tclt@sres{}% \else\ifnum#1=1 \def\tclt@sres{#2}% \else \edef\tclt@sres{\@nameuse{tclt@digit/#1}#2}% \fi\fi }
非常に単純に、手続きの定義をマクロの定義に、手続きの呼出をマクロの実行に置き換える。\tclt@split@digit
の実装については後で考えることにしよう。
文字列の代入文の右辺に配列要素がある場合は、単純に \edef
中で \@nameuse
を使えばよい。
km = sres
のような文字列のコピーの代入文は、定式通りに \edef\tclt@km{\tclt@sres}
としてもよいが、上掲のように \let
での定義コピーに置き換えることができる。ただし \let
が使えるのは文字列の場合に限り、整数変数の k = m
のような代入文は \tclt@k=\tclt@m
でなければならない。((ここで \let
を使うと \tclt@k
が \tclt@m
と同じレジスタを指すことになってしまい失敗する。))
41〜48行目: 手続き eltaso_name()
function eltaso_name(_1) knumeral(_1) remainder(_1, 26) sres = sres .. "反田" .. _G["alpha_name/"..tostring(ires)] end function remainder(_1, _2) -- TeXでは再実装が必要 ires = _1 % _2 end
%% \tclt@eltaso@name{<整数n>} % 整数n(1〜9999)に対する「えるたそ名」. \def\tclt@eltaso@name#1{% \tclt@knumeral{#1}% \tclt@remainder{#1}{26}% \edef\tclt@sres{\tclt@sres 反田\@nameuse{tclt@alpha@name/\the\tclt@ires}}% } \def\tclt@remainder#1#2{% TODO:実装しろ % ires = _1 % _2 }
ここでも \tclt@remainder
の実装は後回し。