syst-mac.lmt /size: 3106 b    last modification: 2025-02-21 11:03
1if not modules then modules = { } end modules ['syst-mac'] = {
2    version   = 1.001,
3    comment   = "companion to syst-aux.mkiv",
4    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5    copyright = "PRAGMA ADE / ConTeXt Development Team",
6    license   = "see context related readme files"
7}
8
9-- This is kind of tricky and might not work for all csnames but as long as we use
10-- it in a controlled way, we're okay. The engine implementation might be changed
11-- a bit (no need to go through strings, but fetching a cs index and passing that
12-- back also takes time).
13
14-- Another approach is to have the predefined stack operate use private stacks and
15-- then the pop doesn't need the cs. But ... we then also need to store stuff in
16-- the format so that complicates maters more than I'm willing to do.
17
18local insert, remove = table.insert, table.remove
19
20local pushmacrotoken = token.pushmacro
21local popmacrotoken  = token.popmacro
22local scancsname     = token.scancsname
23local scancstoken    = token.scancstoken
24local createtoken    = token.create
25local gobbletoken    = token.gobble
26
27local context        = context
28local implement      = interfaces.implement
29
30local report         = logs.reporter("system","macrostack")
31
32local stack          = table.setmetatableindex("table")
33
34local function pushmacro(name,global)
35    local s = pushmacrotoken(name,global)
36    if s then
37        insert(stack[name],s)
38    else
39        report("no macro %a to push",name)
40        insert(stack[name],false)
41    end
42end
43
44local function popmacro(name)
45    local s = remove(stack[name])
46    if s then
47        popmacrotoken(s)
48    else
49        report("no macro %a to pop",name)
50    end
51end
52
53tokens.pushmacro = pushmacro
54tokens.popmacro  = popmacro
55
56local scancs = scancsname
57-- scancs = scancstoken -- saves a lookup and also seems to work okay, not much faster
58
59implement {
60    name      = "localpushmacro",
61    public    = true,
62    protected = true,
63    actions   = function()
64        pushmacro(scancs())
65    end
66}
67
68implement {
69    name      = "globalpushmacro",
70    public    = true,
71    protected = true,
72    actions   = function()
73        pushmacro(scancs(),true)
74    end
75}
76
77implement {
78    name      = "localpopmacro",
79    public    = true,
80    protected = true,
81    actions   = function()
82        popmacro(scancs())
83    end
84}
85
86implement {
87    name      = "globalpopmacro",
88    public    = true,
89    protected = true,
90    actions   = function()
91        popmacro(scancs())
92    end
93}
94
95implement {
96    name      = "showmacrostack",
97    public    = true,
98    protected = true,
99    actions   = function()
100        local n = scancs()
101        local s = stack[n]
102        local m = #s
103        report("%s : %i stack slots used",n,m)
104        for i=1,m do
105            report("% 3i %S",i,s[i])
106        end
107    end
108}
109
110implement {
111    name      = "gobblenested",
112    public    = true,
113    protected = true,
114    arguments = "3 strings",
115    actions   = function(start,stop,command)
116        gobbletoken(createtoken(start),createtoken(stop))
117        if command and command ~= "" then
118            context[command]()
119        end
120    end
121}
122