s-setups-macros.mkiv /size: 5315 b    last modification: 2020-07-01 14:35
1%D \module
2%D   [       file=setups-macros,
3%D        version=2018.01.15,
4%D          title=\CONTEXT\ Setup Definitions,
5%D       subtitle=Macro Properties,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14\startluacode
15
16    local find       = string.find
17    local gsub       = string.gsub
18    local topattern  = string.topattern
19    local concat     = table.concat
20    local sort       = table.sort
21    local sortedkeys = table.sortedkeys
22    local sortedhash = table.sortedhash
23    local getmacro   = tokens.getters.macro
24    local gethash    = tex.hashtokens
25
26    local lpegmatch, P, R, C, S = lpeg.match, lpeg.P, lpeg.R, lpeg.C, lpeg.S
27
28    local macros      = interfaces.macros or { }
29    interfaces.macros = macros
30
31    local hashtable   = nil
32
33 -- table.save("temp.lua",gethash())
34
35    local prefix   = P("??")
36    local initial  = R("09")^1 * P(">")
37    local name     = C(R("az","AZ") * (R("az","AZ","09")+S(" "))^0)
38    local parent   = P(":parent")
39    local eos      = P(-1)
40
41    local pattern1 = initial^0
42                   * name
43                   * parent^0
44                   * eos
45    local pattern2 = prefix
46                   * name
47                   * eos
48    local pattern3 = C(initial^1)
49                   * name
50                   * parent^1 -- so no e.g. measure here
51                   * eos
52
53
54    local function reload()
55         hashtable = gethash()
56         sort(hashtable)
57    end
58
59    interfaces.macros.reload = reload
60
61    function interfaces.macros.instances(str)
62        local namespace = getmacro("??"..str)
63        if namespace then
64            local found   = { }
65            local pattern = P(namespace) * pattern1
66            if not hashtable then
67                reload()
68            end
69            for i=1,#hashtable do
70                local hi = hashtable[i]
71                local pi = lpegmatch(pattern,hi)
72                if pi then
73                    found[pi] = true
74                end
75            end
76            return sortedkeys(found)
77        end
78    end
79
80    function interfaces.macros.namespaces()
81        local found = { }
82        if not hashtable then
83            reload()
84        end
85        for i=1,#hashtable do
86            local hi = hashtable[i]
87            local pi = lpegmatch(pattern2,hi)
88            if pi then
89                found[pi] = true
90            end
91        end
92        return sortedkeys(found)
93    end
94
95    function interfaces.macros.allinstances()
96        local found   = { }
97        local reverse = { }
98        local all     = { }
99        if not hashtable then
100            reload()
101        end
102        for i=1,#hashtable do
103            local hi = hashtable[i]
104            local pi = lpegmatch(pattern2,hi)
105            if pi then
106                found[pi] = true
107                reverse[getmacro("??"..pi)] = pi
108            end
109        end
110        for i=1,#hashtable do
111            local hi = hashtable[i]
112            local ni, pi = lpegmatch(pattern3,hi)
113            if ni and pi then
114                local ri = reverse[ni]
115                if ri and found[ri] then
116                    local a = all[ri]
117                    if a then
118                        a[pi] = true
119                    else
120                        all[ri] = { [pi] = true  }
121                    end
122                end
123            end
124        end
125        return all
126    end
127
128    function interfaces.macros.collect(str)
129        local asked   = gsub(str,"^\\","")
130        local found   = { }
131        local pattern = "^" .. topattern(asked) .. "$"
132        if not hashtable then
133            reload()
134        end
135        for i=1,#hashtable do
136            local hi = hashtable[i]
137            if find(hi,pattern) then
138                found[hi] = true
139            end
140        end
141        return sortedkeys(found)
142    end
143
144    function commands.getinstances(str,separator)
145        local i = interfaces.macros.instances(str)
146        if i then
147            context(concat(i,separator or ", "))
148        end
149    end
150    function commands.getnamespaces(separator)
151        local i = interfaces.macros.namespaces()
152        if i then
153            context(concat(i,separator or ", "))
154        end
155    end
156
157    function commands.showallinstances()
158        local i = interfaces.macros.allinstances()
159        if i then
160            local ctxcmd = context.showoneinstance
161            for k, v in sortedhash(i) do
162                ctxcmd(k,concat(sortedkeys(v),", "))
163            end
164        end
165    end
166
167\stopluacode
168
169\unprotect
170
171\def\getinstances #1{\ctxlua{commands.getinstances("#1")}} % expandable
172\def\getnamespaces  {\ctxlua{commands.getnamespaces()}}    % expandable
173
174\unexpanded\def\showoneinstance#1#2%
175  {\begingroup
176   \hangindent\emwidth
177   \hangafter\plusone
178   \veryraggedright
179   \dontleavehmode
180   \ttbf#1:\space
181   \tttf#2\par
182   \endgroup}
183
184\unexpanded\def\showallinstances
185  {\ctxlua{commands.showallinstances()}}
186
187\protect
188
189\continueifinputfile{s-setups-macros.mkiv}
190
191\usemodule[art-01]
192
193\starttext
194
195% \getinstances{measure} \page
196% \getinstances{framed}  \page
197% \getinstances{layout}  \page
198%
199% \getnamespaces         \page
200
201\showallinstances
202
203\stoptext
204