Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
LaTeX: to define a macro that needs only one expansion to get the result
%% This is file 'ixquickmacro.sty'.
%% Copyright (c) 2019 Takayuki YATO (aka. "ZR")
%% GitHub:
%% Twitter: @zr_tex8r
%% This package is distributed under the MIT License.
%% package declaration
\ProvidesPackage{ixquickmacro}[2019/12/31 v0.2]
%--------------------------------------- environment check
% engine
{Your LuaTeX does not support \string\luadef}%
{Package loading is aborted.}%
%--------------------------------------- general
%% packages
%% unique tokens
\def\ixzqm@uniq{\@gobble\ixzqm@uniq@}% vanishing
%% constants
%% variables
%--------------------------------------- Lua part
\catcode10=12 \endlinechar=10 %
local M = {}; xx = M
local functable = lua.get_functions_table()
local rnumber = luatexbase.registernumber
local create, put_next = token.create, token.put_next
local insert, unpack = table.insert, table.unpack
functable[rnumber('ixzqm@lua@setglobal')] = function() = (token.scan_int() > 0)
functable[rnumber('ixzqm@lua@prepare')] = function()
-- save prefix info
-- TODO: what to do with 'global'?
local probe = token.create("ixzqm@probe")
M.protected = probe.protected
-- check if the target token (CS) is definable
M.targetcs = token.get_next()
put_next(create('let'), M.targetcs, create('ixzqm@uniq'),
create('ifx'), M.targetcs, create('ixzqm@uniq'),
create('ixzqm@next'), M.targetcs, create('fi'),
functable[rnumber("ixzqm@lua@declare")] = function()
local id = rnumber('ixzqm@lua@target')
local drive = create('ixzqm@drive')
local delegate = create('ixzqm@D/'..tostring(id))
functable[id] = function()
put_next(drive, delegate)
token.scan_int() -- trigger full expansion
-- write out luadef statement
local t = {create('luadef'), M.targetcs, create('ixzqm@lua@target')}
if then insert(t, 1, create('global')) end
if M.protected then insert(t, 1, create('protected')) end
%--------------------------------------- TeX part
%%<*> [\protected]\defquickmacro\CS{<body>}
% once pass through TeX processor
\def\ixzqm@probe{}% dummy def for picking up macro prefixes
% invoked as: \ixzqm@def@quick@macro@c \CS \fi \ixzqm@fail
\@gobbletwo\if\if \def\ixzqm@def@quick@macro@c#1\fi#2{\fi
% pick up the macro body
%% \ixzqm@fail
% Gobbles the macro body.
%% \ixzqm@drive\CS
% A execution of scan_int triggers the full expansion.
%--------------------------------------- done
%% EOF
\makeatletter %!!!!!!!!!!!!!!!!!!!!!!!!! TeX code BEGIN
% to show the expanded forms
%% \todayYMD *once-expands* to the desired token list.
% this code is "only fully-ecpandable"
%% \todayYMDp is truly unexpandable.
\makeatother %!!!!!!!!!!!!!!!!!!!!!!!!! TeX code END
% once->2019/12/31
% twice->2019/12/31
% full->2019/12/31

This comment has been minimized.

Copy link
Owner Author

zr-tex8r commented Dec 30, 2019


  • \defquickmacro\CS{<body>} : Defines locally \CS to be a token that once-expands to the “full expansion of <body>”.
  • \gdefquickmacro\CS{<body>} : Ditto except that the definition is global.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.