1
2
3
4
5
6
7
8
9
10
11
12
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
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
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")}}
172\def\getnamespaces {\ctxlua{commands.getnamespaces()}}
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{ssetupsmacros.mkiv}
190
191\usemodule[art01]
192
193\starttext
194
195
196
197
198
199
200
201\showallinstances
202
203\stoptext
204 |