マクロツイーター

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

TeX芸人実力判定問題、その6 (解答編-2)

【淀みなく宣伝】
2012/12/01 〜 2012/12/25

TeX & LaTeX Advent Calendar

こちらはいたって平常運行。

*  *  *

前回の続き)

\tcln@zeropad の実装

基本的に、「関数のようなものを(1)」で紹介されているロジック(「それでも(14)」でも利用した)をここでも利用する。ただし今回は 12 桁で表すので単純に考えると 14 個の引数が必要になってしまい、TeX で可能な上限の 9 個を超えてしまう。

% ((num.."/00000000000"):sub(1,13):gsub("^(.*)/(.*)$","%2%1"))
\def\tcln@zeropad#1\relax{% #1 は10進表記
  \tcln@zeropad@A#1/00000000000\relax
}
% ↓引数が14個(実際には無理)
\def\tcln@zeropad@A#1#2#3#4#5#6#7#8#9#A#B#C#D#E\relax{%
  \tcln@zeropad@B#1#2#3#4#5#6#7#8#9#A#B#C#D\relax % 最初の13文字を残したい
}
\def\tcln@zeropad@B#1/#2\relax{%
  #2#1%
}

そこで、「最初の 9 個の引数」を一旦グループにして後で再びバラすというトリックを用いることにする。

\def\tcln@zeropad#1{%
  \tcln@zeropad@a#1/00000000000\relax
}
\def\tcln@zeropad@a#1#2#3#4#5#6#7#8#9{%
  \tcln@zeropad@b{#1#2#3#4#5#6#7#8#9}% 最初の9個をグループにする
}
 % #1が最初の9文字、#2は10文字目、#5は13文字目、#6は14文字目以降
\def\tcln@zeropad@b#1#2#3#4#5#6\relax{%
  \tcln@zeropad@c#1#2#3#4#5\relax % これで最初の13文字を並べたことになる
}
\def\tcln@zeropad@c#1/#2\relax{%
  #2#1%
}
\tcln@kanji の実装

まずは 4 桁のブロックの処理を書こう。規則*1さえきちんと理解していれば簡単である。なお、4 桁が「0000」である場合はブロック全体を無出力とすべきだが、数字列が「0000」であるかの判定は、「数値と見做して値が 0 と等しいか」とすればよい。((代入が禁止されているので \ifx でやろうとしても上手くいかない。))

%% \tcln@onepos3{十} → 三十 ; \tcln@onepos0{百} →(空)
\def\tcln@onepos#1#2{%
  \ifcase#1 \or #2\else \csname tcln@digit/#1\endcsname#2\fi
}
%% \tcln@block{0103}{万} → 百三万 ; \tcln@block{0000}{億} →(空)
\def\tcln@block#1#2{%
  % #1が0000なら無出力
  \ifnum#1>0 \tcln@block@a#1#2\fi % #2はそのまま出力
}
\def\tcln@block@a#1#2#3#4{%
  \tcln@onepos#1{千}\tcln@onepos#2{百}%
  \tcln@onepos#3{十}\csname tcln@digit/#4\endcsname
}% tcln@digit/0 は空であることに注意

\tcln@block ができてしまうと \tcln@kanji の実装も容易である。

%% 丁度12桁の数字列を漢数字に変換する
\def\tcln@kanji#1#2#3#4#5#6#7#8#9#A#B#C{%
  \tcln@block{#1#2#3#4}{億}%
  \tcln@block{#5#6#7#8}{万}%
  \tcln@block{#9#A#B#C}{}%
}

おっと、また引数が 9 個を超えてしまった。なので処理を途中で分ける。

%% \tcln@kanji{000100000009} → 一億九
\def\tcln@kanji#1#2#3#4{%
  \tcln@block{#1#2#3#4}{億}\tcln@kanji@a
}
\def\tcln@kanji@a#1#2#3#4#5#6#7#8{%
  \tcln@block{#1#2#3#4}{万}\tcln@block{#5#6#7#8}{}%
}

*1:百の位が 2 なら「二百」、1 なら「百」、0 なら出力無しにする、等。