s-system-macros.mkxl /size: 12 Kb    last modification: 2021-10-28 13:51
1%D \module
2%D   [      file=s-system-tokens.mkxl,
3%D        version=2020.06.02,
4%D          title=\CONTEXT\ Style File,
5%D       subtitle=System Tokens Checking,
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%D This file is for Wolfgang and Hans and it's used in the transition from \MKIV\
15%D to the more robust \LMTX.
16
17% todo:  \permanent\protected\let\select\directselect : same value (add ref)
18%
19% todo: when mutable, remove immutable, decide on how immutable it really is
20%
21% todo: just for the fun of it we can compare the table generated here to mkiv but it
22% needs the same hash exposure as we use in luametatex so i'll do that after all lmtx
23% macros are checked (maybe i need to backport some more but it has a low priority)
24%
25% todo: do we need something similar for lua functions etc (problem: performance hit)
26%
27% todo: and how about metapost ... i need a mp.hashtokens in order to do that and I also
28% need to think about protection there (tricky as we use an avl hash there)
29%
30% public undefined : SmallCaps scitebuffer sciteinlinebuffer
31% single todos     : \ \- \\ \_
32
33\enablemode[texmacros]
34\enablemode[metapostmacros]
35% \enablemode[notmarked]
36\enablemode[everything]
37
38\startmodule[system-macros]
39
40\continueifinputfile{s-system-macros.mkxl}
41
42% \usemodule[article-basic] \setuplayout[tight] \setupbodyfont[7pt,tt]
43\usemodule[article-basic] \setuplayout[tight] \setupbodyfont[5pt,tt]
44
45\setupbackgrounds[page][background=color,backgroundcolor=darkgray] \setupcolors[textcolor=white]
46
47\setuppapersize
48  [A4,landscape]
49  [A4,landscape]
50
51\starttext
52
53\startluacode
54
55    if tex.modes.texmacros then
56
57        local context  = context
58        local ctx_NC   = context.NC
59        local ctx_NR   = context.NR
60        local ctx_bold = context.bold
61        local ctx_verb = context.verbatim
62
63        local find     = string.find
64        local gsub     = string.gsub
65        local create   = tokens.create
66
67        local crap     = "[$>%|%&%#" .. string.char(0xEF) .. "]"
68
69        local basefile  = resolvers.findfile("context.mkxl")
70        local swapnames = { }
71
72        local pattern   = file.join(file.pathpart(basefile),"/*.mk*")
73        local filenames = dir.glob(pattern)
74        for i=1,#filenames do
75            swapnames[file.basename(filenames[i])] = true
76        end
77
78        local pattern   = file.join(file.pathpart(basefile),"/*.l**")
79        local filenames = dir.glob(pattern)
80        for i=1,#filenames do
81            swapnames[file.basename(filenames[i])] = true
82        end
83
84        local hashnames = table.setmetatableindex(function(t,k)
85            local s = file.suffix(k)
86            local v = k
87            if s == "mkiv" then
88                local n = file.replacesuffix(k,"mkxl")
89                if swapnames[n] then
90                    v = n
91                end
92            elseif s == "mkvi" then
93                local n = file.replacesuffix(k,"mklx")
94                if swapnames[n] then
95                    v = n
96                end
97            elseif s == "lua" then
98                local n = file.replacesuffix(k,"lmt")
99                if swapnames[n] then
100                    v = n
101                end
102            end
103            t[k] = v
104            return v
105        end)
106
107        require("mtx-interface")
108
109        local data       = scripts.interface.editor("data")
110        local files      = data and data.common and data.common.filenames or { }
111        local macros     = { }
112        local flagged    = 0
113        local total      = 0
114        local list       = tex.hashtokens()
115        local all        = not tex.modes.notmarked
116        local everything = tex.modes.everything
117
118        local fmtname = resolvers.locateformat("cont-en.fmt")
119        if fmtname then
120            local logname = file.replacesuffix(fmtname,"log")
121            for filename in string.gmatch(io.loaddata(logname),"fullname=(%S+)") do
122                local s = file.suffix(filename)
123                local b = file.basename(filename)
124                if s ~= "lua" and s ~= "lmt" then
125                    local d = io.loaddata(filename)
126                    for m in string.gmatch(d,"\n[\\a-z]*[exg]*def\\([a-zA-Z_]+)") do
127                        macros[m] = b
128                    end
129                    for m in string.gmatch(d,"\n[\\a-z]*[g]*let\\([a-zA-Z_]+)") do
130                        macros[m] = b
131                    end
132                end
133            end
134        end
135
136        table.sort(list)
137
138        local function show(visible, check)
139         -- context.starttabulate { "|l|l|l|lj2|l|l|l|l|l|l|l|l|" }
140            context.starttabulate { "|l|l|l|lj2|l|l|l|l|l|l|l|l|" }
141            for i=1,#list do
142                local k = list[i]
143                if check(k) then
144                    local v = create(k)
145                    local mutable    = v.mutable    and "mutable"
146                    local immutable  = v.immutable  and "immutable"
147                    local frozen     = v.frozen     and "frozen"
148                    local permanent  = v.permanent  and "permanent"
149                    local primitive  = v.primitive  and "primitive"
150                    local instance   = v.instance   and "instance"
151                    local dealtwith  = mutable or immutable or mutable or frozen or permanent or primitive -- beware: we can have combinations
152                    local whatever   = find(k,"^[a-z][a-z][a-z]+_")
153                    local cscommand  = gsub(v.cmdname or "","_"," ")
154                    local undefined  = cscommand == "undefined cs"
155                    local marked     = (dealtwith and "+") or (whatever and "-") or (instance and "!")
156                    if everything or ((all or not marked) and not find(k,"^[pvm]_") and not find(k,"^![tT]")) then
157                        local parameters = v.parameters
158                        local noaligned  = v.noaligned  and "noaligned"
159                        local filename   = files[k] or macros[k]
160                        local csname     = context.escape(k)
161                        if undefined then
162                            marked = "?"
163                        end
164                        ctx_NC() if marked     then context(marked)     end
165                        ctx_NC() if primitive  then ctx_bold(csname)    else
166                                                    ctx_verb(csname)    end
167                        ctx_NC() if parameters then context(parameters > 0 and parameters or "-") end
168                        ctx_NC() if undefined  then context.red(false) end
169                                                    context(cscommand)
170                        ctx_NC() if primitive  then context(primitive)  end
171                        ctx_NC() if permanent  then context(permanent)  end
172                        ctx_NC() if immutable  then context(immutable)  end
173                        ctx_NC() if frozen     then context(frozen)     end
174                        ctx_NC() if mutable    then context(mutable)    end
175                        ctx_NC() if instance   then context(instance)   end
176                        ctx_NC() if noaligned  then context(noaligned)  end
177                        ctx_NC() if filename   then context(hashnames[filename]) end
178                        ctx_NC() ctx_NR()
179                    end
180                    if visible then
181                        total = total + 1
182                        if dealtwith then
183                            flagged = flagged + 1
184                        end
185                    end
186                end
187            end
188            context.stoptabulate()
189        end
190
191        context.starttitle { title = "Public \\TEX\\ commands" }
192            show(true, function(k) return find(k,"^[a-zA-Z]+$") end)
193        context.stoptitle()
194
195        context.starttitle { title = "Private \\TEX\\ commands" }
196            show(false, function(k) return not find(k,"^[a-zA-Z]+$") and not find(k,crap) end)
197        context.stoptitle()
198
199        tokens.setters.macro("NumberOfVisible", total)
200        tokens.setters.macro("NumberOfFlagged", flagged)
201
202    end
203
204\stopluacode
205
206\startmode[texmacros]
207
208    \page
209
210    \starttabulate[|c|l|]
211    \HL
212    \NC \type {+}   \NC mutable, immutable, frozen, permanent, primitive \NC \NR
213    \NC \type {-}   \NC protected by obscurity (underscores) \NC \NR
214    \NC \type {!}   \NC instance (can be frozen) \NC \NR
215    \NC \type {0-9} \NC the number of arguments (argument grabbing can be delegated) \NC \NR
216    \HL
217    \stoptabulate
218
219    \start \hsize 15cm \veryraggedright
220    Often frozen commands are redefined on demand and they can be overloaded. Mutable
221    doesn't mean that a user can change it without consequences, for instance the
222    \type {\current...} ones. Primitives come with the engine, permanent macros are
223    the core of \CONTEXT. Noaligned macros are special and dealt deep down when
224    scanning for alignment specific primitives.
225    \par \stop
226
227    \starttabulate[||r|]
228    \BC number of visible macros  \NC \NumberOfVisible \NC \NR
229    \BC number of flagged macros  \NC \NumberOfFlagged \NC \NR
230    \stoptabulate
231
232\stopmode
233
234\page
235
236\startluacode
237
238    if tex.modes.metapostmacros then
239
240        local context  = context
241     -- local ctx_NC   = context.NC
242     -- local ctx_NR   = context.NR
243     -- local ctx_bold = context.bold
244
245        local find     = string.find
246        local gsub     = string.gsub
247        local create   = tokens.create
248
249        context.starttitle { title = "\\METAFUN\\ commands" }
250
251            metapost.simple("prestine")
252
253            local mptotal    = 0
254            local codes      = metapost.codes
255            local types      = metapost.types
256            local parameters = metapost.knownparameters
257            local procodes   = mplib.propertycodes
258            local everything = tex.modes.everything
259
260            context.startcolumns { n = 5, distance = "1em" }
261                context.nohyphens(false)
262                context.obeyspaces(false)
263                local t = metapost.gethashentries("prestine",true) -- prestine:1
264                if t then
265                    table.sort(t,function(a,b) return a[3] < b[3] end)
266                    mptotal = #t
267                    for i=1,mptotal do
268                        local ti       = t[i]
269                        local code     = codes[ti[1]]
270                        local property = procodes[ti[2]]
271                        local name     = ti[3]
272                        local vtype    = ti[4]
273                        local vardef   = vtype and types[vtype] == "unsuffixedmacro"
274                        context.bgroup()
275                     -- context("%-15s\\quad",vardef and "(vardef) tag" or code)
276                        context("%s %-15s\\quad",parameters[name] and "+" or "\\nbsp",vardef and "(vardef) tag" or code)
277                        if property == "primitive" then
278                            context.bf(false)
279                            context.blue(false)
280                        elseif property == "permanent"  then
281                            context.bf(false)
282                            context.lightgreen(false)
283                        elseif property == "immutable"  then
284                            context.bf(false)
285                            context.lightcyan(false)
286                        elseif property == "mutable"  then
287                            context.bf(false)
288                            context.lightmagenta(false)
289                        elseif everything or not find(name,"^%a+_") then
290                            -- todo:
291                            if vardef then
292                                context.bf(false)
293                                context.lightred(false)
294                            end
295                        end
296                        context.verbatim(name)
297                        context.egroup()
298                        context.par()
299                    end
300                end
301            context.stopcolumns()
302
303        context.stoptitle()
304
305        tokens.setters.macro("NumberOfMetafun", mptotal)
306
307    end
308\stopluacode
309
310\startmode [metapostmacros]
311
312    \page
313
314    \starttabulate[|c|l|]
315    \HL
316    \NC \type {-3} \NC \bf \lightmagenta mutable   \NC \NR
317    \NC \type  {1} \NC \bf \blue         primitive \NC \NR
318    \NC \type  {2} \NC \bf \lightgreen   permanent \NC \NR
319    \NC \type  {3} \NC \bf \lightcyan    immutable \NC \NR
320    \NC \type  {+} \NC \bf (also) used as key      \NC \NR
321    \HL
322    \stoptabulate
323
324    \starttabulate[||r|]
325    \BC number of metafun entries \NC \NumberOfMetafun \NC \NR
326    \stoptabulate
327
328\stopmode
329
330\stopmodule
331