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 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