syst-mac.lmt /size: 2971 b    last modification: 2023-12-21 09:44
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 createtoken    = token.create
24local gobbletoken    = token.gobble
25
26local context        = context
27local implement      = interfaces.implement
28
29local report         = logs.reporter("system","macrostack")
30
31local stack          = table.setmetatableindex("table")
32
33local function pushmacro(name,global)
34    local s = pushmacrotoken(name,global)
35    if s then
36        insert(stack[name],s)
37    else
38        report("no macro %a to push",name)
39        insert(stack[name],false)
40    end
41end
42
43local function popmacro(name)
44    local s = remove(stack[name])
45    if s then
46        popmacrotoken(s)
47    else
48        report("no macro %a to pop",name)
49    end
50end
51
52tokens.pushmacro = pushmacro
53tokens.popmacro  = popmacro
54
55implement {
56    name      = "localpushmacro",
57    public    = true,
58    protected = true,
59    actions   = function()
60        pushmacro(scancsname())
61    end
62}
63
64implement {
65    name      = "globalpushmacro",
66    public    = true,
67    protected = true,
68    actions   = function()
69        pushmacro(scancsname(),true)
70    end
71}
72
73implement {
74    name      = "localpopmacro",
75    public    = true,
76    protected = true,
77    actions   = function()
78        popmacro(scancsname())
79    end
80}
81
82implement {
83    name      = "globalpopmacro",
84    public    = true,
85    protected = true,
86    actions   = function()
87        popmacro(scancsname())
88    end
89}
90
91implement {
92    name      = "showmacrostack",
93    public    = true,
94    protected = true,
95    actions   = function()
96        local n = scancsname()
97        local s = stack[n]
98        local m = #s
99        report("%s : %i stack slots used",n,m)
100        for i=1,m do
101            report("% 3i %S",i,s[i])
102        end
103    end
104}
105
106implement {
107    name      = "gobblenested",
108    public    = true,
109    protected = true,
110    arguments = "3 strings",
111    actions   = function(start,stop,command)
112        gobbletoken(createtoken(start),createtoken(stop))
113        if command and command ~= "" then
114            context[command]()
115        end
116    end
117}
118