マクロツイーター

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

TeX言語のマクロも“1回展開”にしたい話

1回展開を実現するにはLuaしないといけない問題

某アドベントカレンダーの最終日の記事では、LuaTeXで「“1回展開”のマクロ」を実現する方法について解説した。

ただし、この記事にある方法では、機能の実現の部分(具体的には「YYYY/MM/DD形式で出力する」という機能)をLuaで実装する必要がある。

-- Luaでの実装
function xx.todayYMD()
  tex.sprint(("%04d/%02d/%02d"):format(
      tex.year, tex.month, tex.day))
end

Lua言語自体はTeX言語よりもずっと習得しやすい言語ではあるが、それでも「LuaTeX上のLuaコードでTeXに関連した機能を実現する」にはそれなりの知識(例えばtexライブラリの使用法など)の習得が必要であり、決して自明ではない。

何より、(例の記事の流れに従うと)機能要件を実現するための「完全展開可能(ただし“先頭~”ではない)なTeX言語のコード」が既に得られている。

% TeX言語での実装
\def\todayYMD{%
  \the\year/\two@digits\month/\two@digits\day}

そうであれば、この「完全展開可能なコードから“1回展開”のマクロが作れる」ほうが、フツーのTeX言語者(※要定義)にとっては便利なのは間違いないだろう。

ixquickmacroパッケージ

というわけで、作ってみた

ixquickmacroパッケージは開発者用のパッケージで、以下の機能を提供する。

  • \defquickmacro\制御綴{<定義本体>}\制御綴を1回展開すると「<定義本体>の完全展開」になるように、\制御綴の意味をローカルに定義する。
  • \gdefquickmacro\制御綴{<定義本体>}\defquickmacroのグローバル定義版。

※現状では、引数をもつマクロはサポートされない。

このパッケージを利用すると、先に示した「TeX言語による完全展開可能な\todayYMDの定義」について、\def\defquickmacroに変えるだけで、“1回展開”の\todayYMDが実現できる。

\defquickmacro\todayYMD{%
  \the\year/\two@digits\month/\two@digits\day}

例の記事で使った\xInspectマクロをここでも利用して、“1回展開”が実現できているかを確かめてみよう。

\documentclass{article}
\usepackage{ixquickmacro}
\makeatletter %!!!!!!!!!!!!!!!!!!!!!!!!! TeX code BEGIN
% 例の \xInspect
\def\xInspect#1{\typeout{%
  once->\unexpanded\expandafter{#1}^^J%
  twice->\unexpanded\expandafter\expandafter\expandafter{#1}^^J%
  full->#1}}

%% "1回展開"な \todayYMD の定義
\defquickmacro\todayYMD{%
  % 中のコードは単に"完全展開可能"に過ぎない
  \the\year/\two@digits\month/\two@digits\day}

\makeatother  %!!!!!!!!!!!!!!!!!!!!!!!!! TeX code END
\begin{document}

\xInspect{\todayYMD}

\stop

このソースをlualatexでコンパイルすると、\xInspectによる端末出力は以下のようになる。

once->2019/12/31
twice->2019/12/31
full->2019/12/31

ixquickmacroパッケージを利用することで、Luaを知らなくても、TeX言語の知識だけで“1回展開”のマクロを作ることができた。スバラシイ。


*「ところで」
ZR「ん?」
*「マクロを“1回展開”にできると何が嬉しいわけ?」
ZR「何だろうねえ」
*「えっ!? 明確なメリットは存在しないの? だったら、この記事もtexadvent2019の記事も単なるくだらないTeX芸でしかないんじゃないの?」
ZR「というわけで、皆さん、来年も当(くだらない)ブログをよろしくお願いします!」