Checking existence of a macro (control sequence) by Lua
Hello, is it possible to check whether a macro exists (or - is it a non-\undefined control sequence) with Lua? Suppose: ---- \starttext \def\MyMacro{Ahoj} \def\MyMac#1#2{Something} \startluacode IsDefined = function(ctl_seq) print("CS " .. ctl_seq .. (tex.IsCS(ctl_seq) -- Or what to come here? "is defined" or "is unknown") .. ".") end -- So the function should print to the console: IsDefined("MyMacro") --> "CS MyMacro is defined." IsDefined("MyMac") --> "CS MyMac is defined." IsDefined("bf") --> "CS bf is defined." IsDefined("dummy") --> "CS dummy is unknown." \stopluacode \stoptext ---- Is it possible? Best regards, Lukas
On 5/28/2020 12:49 AM, luigi scarso wrote:
On Thu, May 28, 2020 at 12:43 AM
mailto:context@vivaldi.net> wrote: Off-topic: your email are always marked as spam by my gmail . Are you sure that your address setup is ok ?
also, a reply to that vivaldi address always bounces (same for gmx accounts, so don't expect answers to those adresses) Hans ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl -----------------------------------------------------------------
On 28/05/20, 00:42, context@vivaldi.net wrote:
Hello,
is it possible to check whether a macro exists (or - is it a non-\undefined control sequence) with Lua? Suppose:
---- \starttext \def\MyMacro{Ahoj} \def\MyMac#1#2{Something}
\startluacode IsDefined = function(ctl_seq) print("CS " .. ctl_seq .. (tex.IsCS(ctl_seq) -- Or what to come here? "is defined" or "is unknown") .. ".") end
-- So the function should print to the console:
IsDefined("MyMacro") --> "CS MyMacro is defined." IsDefined("MyMac") --> "CS MyMac is defined." IsDefined("bf") --> "CS bf is defined." IsDefined("dummy") --> "CS dummy is unknown."
\stopluacode \stoptext ----
Is it possible?
Yes, that is what the token library is there for. \starttext \def\MyMacro{Ahoj} \def\MyMac#1#2{Something} \startluacode local str = { [true] = "defined", [false] = "undefined" } for _, macro in ipairs({ "MyMacro", "MyMac", "bf", "dummy" }) do context(macro .. " is " .. str[token.is_defined(macro)] .. "\\par") end \stopluacode \stoptext Cheers, Henri
Best regards,
Lukas ___________________________________________________________________________________ If your question is of interest to others as well, please add an entry to the Wiki!
maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context webpage : http://www.pragma-ade.nl / http://context.aanhet.net archive : https://bitbucket.org/phg/context-mirror/commits/ wiki : http://contextgarden.net ___________________________________________________________________________________
On 5/28/2020 12:42 AM, context@vivaldi.net wrote:
Hello,
is it possible to check whether a macro exists (or - is it a non-\undefined control sequence) with Lua? Suppose:
---- \starttext \def\MyMacro{Ahoj} \def\MyMac#1#2{Something}
\startluacode IsDefined = function(ctl_seq) print("CS " .. ctl_seq .. (tex.IsCS(ctl_seq) -- Or what to come here? "is defined" or "is unknown") .. ".") end
-- So the function should print to the console:
IsDefined("MyMacro") --> "CS MyMacro is defined." IsDefined("MyMac") --> "CS MyMac is defined." IsDefined("bf") --> "CS bf is defined." IsDefined("dummy") --> "CS dummy is unknown."
\stopluacode \stoptext ----
Is it possible? A lot is possible. Take this:
\def\MyMacroA{Ahoj A} \unexpanded\def\MyMacroB{Ahoj B} \frozen \def\MyMacroC{Ahoj C} % in lmtx % \def\MyMacroC{Ahoj C} % barks At the tex end you can check for several properties: \ifusercmd \hbox Y\else N\fi % in lmtx \iffrozen \hbox Y\else N\fi % in lmtx \ifusercmd \MyMacroA Y\else N\fi % in lmtx \iffrozen \MyMacroA Y\else N\fi % in lmtx \iffrozen \MyMacroC Y\else N\fi % in lmtx At the Lua end you can check for being defined: \startluacode local function whatever(s) context.type("\\" .. s) context(" is %s", tokens.defined(s) and "defined" or "undefined") context.par() end whatever("MyMacroA") whatever("MyMacroD") whatever(" ") whatever("-") \stopluacode alternatively you can say: \startluacode local t = token.create("MyMacro") print(t.cmdname == "undefined_cs") \stopluacode which is less efficient unless you want to access more properties. Hans ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl -----------------------------------------------------------------
Hello, thanks Henri and Hans for all solutions! On 2020-05-28 10:34, Hans Hagen wrote:
On 5/28/2020 12:42 AM, context@vivaldi.net wrote:
Hello,
is it possible to check whether a macro exists (or - is it a non-\undefined control sequence) with Lua? Suppose:
---- \starttext \def\MyMacro{Ahoj} \def\MyMac#1#2{Something}
\startluacode IsDefined = function(ctl_seq) print("CS " .. ctl_seq .. (tex.IsCS(ctl_seq) -- Or what to come here? "is defined" or "is unknown") .. ".") end
-- So the function should print to the console:
IsDefined("MyMacro") --> "CS MyMacro is defined." IsDefined("MyMac") --> "CS MyMac is defined." IsDefined("bf") --> "CS bf is defined." IsDefined("dummy") --> "CS dummy is unknown."
\stopluacode \stoptext ----
Is it possible? A lot is possible. Take this:
\def\MyMacroA{Ahoj A} \unexpanded\def\MyMacroB{Ahoj B} \frozen \def\MyMacroC{Ahoj C} % in lmtx % \def\MyMacroC{Ahoj C} % barks
At the tex end you can check for several properties:
\ifusercmd \hbox Y\else N\fi % in lmtx \iffrozen \hbox Y\else N\fi % in lmtx \ifusercmd \MyMacroA Y\else N\fi % in lmtx \iffrozen \MyMacroA Y\else N\fi % in lmtx \iffrozen \MyMacroC Y\else N\fi % in lmtx
At the Lua end you can check for being defined:
\startluacode local function whatever(s) context.type("\\" .. s) context(" is %s", tokens.defined(s) and "defined" or "undefined") context.par() end whatever("MyMacroA") whatever("MyMacroD") whatever(" ") whatever("-") \stopluacode
alternatively you can say:
\startluacode local t = token.create("MyMacro") print(t.cmdname == "undefined_cs") \stopluacode
which is less efficient unless you want to access more properties.
Hans
(@Hans: I'm using vivaldi's mail account in "good will" - I didn't suppose it would cause any unwanted actions, like resending mails or whatever.) Bets regards, Lukas
Hello, one more question - why macros \Undefined and \DoNothing show "defined" although I (tried to) undefine them? ---- \starttext \def\MyMacro{Ahoj} \def\MyMac#1#2{Something} \def\Undefined{} \let\Undefined\undefined \def\DoNothing{} \let\DoNothing\donothing \startluacode local str = { [true] = "defined", [false] = "undefined" } local function whatever(s) context.type("\\" .. s) context(" is " .. (tokens.defined(s) and "defined" or "undefined")) --% Hans' way context(" and is " .. str[token.is_defined(s)] .. ".") --% Henri's way context.par() end whatever("MyMacro") whatever("MyMacroD") whatever(" ") whatever("-") whatever("Undefined") whatever("DoNothing") \stopluacode %\Undefined % Causes "! Undefined control sequence" \stoptext ---- Gives: " \MyMacro is defined and is defined. \MyMacroD is undefined and is undefined. \ is defined and is defined. \- is defined and is defined. \Undefined is defined and is defined. \DoNothing is defined and is defined. " Lukas
On 5/28/2020 11:24 PM, context@vivaldi.net wrote:
Hello,
one more question - why macros \Undefined and \DoNothing show "defined" although I (tried to) undefine them?
---- \starttext \def\MyMacro{Ahoj} \def\MyMac#1#2{Something}
\def\Undefined{} \let\Undefined\undefined
\def\DoNothing{} \let\DoNothing\donothing
\startluacode local str = { [true] = "defined", [false] = "undefined" }
local function whatever(s) context.type("\\" .. s) context(" is " .. (tokens.defined(s) and "defined" or "undefined")) --% Hans' way context(" and is " .. str[token.is_defined(s)] .. ".") --% Henri's way context.par() end
whatever("MyMacro") whatever("MyMacroD") whatever(" ") whatever("-") whatever("Undefined") whatever("DoNothing") \stopluacode
%\Undefined % Causes "! Undefined control sequence" \stoptext ----
Gives:
" \MyMacro is defined and is defined. \MyMacroD is undefined and is undefined. \ is defined and is defined. \- is defined and is defined. \Undefined is defined and is defined. \DoNothing is defined and is defined. " Because the macro actually *is* defined: as soon as tex sees
\foo it reserves the name and gives it the meaning undefined, so even \undefined is defined. Anyway, that is why we have \ifdefined that does a different kind of checking. In retrospect, that is a better one, so I'll adapt that in lmtx. \starttext \let\MyMacroA\undefined \startluacode local function whatever(s) context.type("\\" .. s) context(" is " .. (tokens.defined(s,true) and "defined" or "undefined")) --% Hans' way context(" and has meaning " .. (tokens.defined(s) and "defined" or "undefined")) --% Hans' way context.par() end whatever("MyMacroA") whatever("MyMacroB") \stopluacode \stoptext \MyMacroA is defined and has meaning undefined \MyMacroB is undefined and has meaning undefined You can do this in current luatex/mkiv: if CONTEXTLMTXMODE == 0 then local d = tokens.defined local c = tokens.create function tokens.defined(s,b) if b then return d(s) else return c(s).cmd_name == "undefined_cmd" end end end Hans ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl -----------------------------------------------------------------
Hello Hans, thank you for explanation and the nice how-to solution! Best regards, Lukas
Because the macro actually *is* defined: as soon as tex sees
\foo
it reserves the name and gives it the meaning undefined, so even \undefined is defined.
Anyway, that is why we have \ifdefined that does a different kind of checking. In retrospect, that is a better one, so I'll adapt that in lmtx.
\starttext \let\MyMacroA\undefined
\startluacode local function whatever(s) context.type("\\" .. s) context(" is " .. (tokens.defined(s,true) and "defined" or "undefined")) --% Hans' way context(" and has meaning " .. (tokens.defined(s) and "defined" or "undefined")) --% Hans' way context.par() end
whatever("MyMacroA") whatever("MyMacroB") \stopluacode
\stoptext
\MyMacroA is defined and has meaning undefined \MyMacroB is undefined and has meaning undefined
You can do this in current luatex/mkiv:
if CONTEXTLMTXMODE == 0 then
local d = tokens.defined local c = tokens.create
function tokens.defined(s,b) if b then return d(s) else return c(s).cmd_name == "undefined_cmd" end end
end
Hans
participants (4)
-
context@vivaldi.net
-
Hans Hagen
-
Henri Menke
-
luigi scarso