toks-aux.lmt /size: 12 Kb    last modification: 2025-02-21 11:03
1if not modules then modules = { } end modules ['toks-aux'] = {
2    version   = 1.001,
3    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
4    copyright = "PRAGMA ADE / ConTeXt Development Team",
5    license   = "see context related readme files"
6}
7
8local type, tostring, next = type, tostring, next
9local max = math.max
10local formatters, gsub, char, gmatch = string.formatters, string.gsub, string.char, string.gmatch
11local concat, swapped = table.concat, table.swapped
12
13local allocate      = utilities.storage.allocate
14local texintegerdef = tex.integerdef
15
16do
17
18 -- tex.magicconstants = { -- we use tex.constants for something else
19 --     running  = -1073741824, -- null_flag
20 --     maxdimen =  1073741823, -- max_dimen
21 --  -- trueinch =     4736286, -- obsolete
22 -- }
23
24    local c = status.getconstants()
25    local t = { }
26    for k, v in next, c do
27        t[gsub(k,"_","")] = v
28    end
29
30    tex.magicconstants = table.setmetatableindex(t,c)
31
32end
33
34do
35
36    -- todo : locals from scanners
37
38    local function flags(t)
39        if type(t) == "string" then
40            t = token.create(t)
41        end
42        local r = { }
43        if t.frozen    then r[#r+1] = "frozen"    end
44        if t.permanent then r[#r+1] = "permanent" end
45        if t.immutable then r[#r+1] = "immutable" end
46        if t.primitive then r[#r+1] = "primitive" end
47        if t.mutable   then r[#r+1] = "mutable"   end
48        if t.noaligned then r[#r+1] = "noaligned" end
49        if t.instance  then r[#r+1] = "instance"  end
50        if t.tolerant  then r[#r+1] = "tolerant"  end
51        if t.protected then r[#r+1] = "protected" end
52        if t.constant  then r[#r+1] = "constant"  end
53        return r
54    end
55
56    tokens.flags= flags
57
58    interfaces.implement {
59        name      = "showluatokens",
60        public    = true,
61        protected = true,
62        actions   = function()
63            local f0 = formatters["%s: %s"]
64            local nl = logs.newline
65            local wr = logs.writer
66            local t  = token.peeknext() -- local t = token.scannext() token.putback(t)
67            local n  = ""
68            local w  = ""
69            local c  = t.cmdname
70            local tl = nil
71            if c == "left_brace" then
72                w = "given token list"
73                t = token.scantoks(false)
74            elseif c == "register_toks" then
75                token.scannext()
76                w = "token register"
77                n = t.csname or t.index
78                t = tex.gettoks(n,true)
79            elseif c == "internal_toks" then
80                token.scannext()
81                w = "internal token variable"
82                n = t.csname or t.index
83                t = tex.gettoks(n,true)
84            elseif t.active then
85                token.scannext()
86                local r = flags(t)
87                local m, l = token.getmeaning("\xEF\xBF\xBF"..t.csname,true,false,true)
88                r[#r+1] = "active character"
89                if type(m) == "table" then
90                    t = m
91                    tl = l
92                else
93                    t = { t }
94                end
95                w = concat(r, " ")
96                n = t.csname
97            else
98                n = token.scancsname()
99                local r = flags(t)
100                local m, l = token.getmeaning(n,true,false,true) -- last argument: we want original links
101                r[#r+1] = "control sequence"
102                if type(m) == "table" then
103                    t = m
104                    tl = l
105                else
106                    t = { t }
107                end
108                w = concat(r, " ")
109            end
110            wr(f0(w,n))
111            nl()
112            if type(t) == "table" then
113                local w1 = 4
114                local w2 = 1
115                local w3 = 3
116                local w4 = 3
117                for i=1,#t do
118                    local ti = t[i]
119                    local li = tl and tl[i]
120                    w1 = max(w1,#tostring(li or ti.id))
121                    w2 = max(w2,#tostring(ti.command))
122                    w3 = max(w3,#tostring(ti.index))
123                    w4 = max(w4,#ti.cmdname)
124                end
125                local f1 = formatters["%" .. w1 .. "i  %" .. w2 .. "i  %" .. w3 .. "i  %-" .. w4 .. "s  %s"]
126                local f2 = formatters["%" .. w1 .. "i  %" .. w2 .. "i  %" .. w3 .. "i  %-" .. w4 .. "s"]
127                local f3 = formatters["%" .. w1 .. "i  %" .. w2 .. "i  %" .. w3 .. "i  %-" .. w4 .. "s  %C"]
128                for i=1,#t do
129                    local ti = t[i]
130                    local li = tl and tl[i]
131                    local cs = ti.csname
132                    local id = li or ti.id
133                    local ix = ti.index
134                    local cd = ti.command
135                    local cn = ti.cmdname
136                    if cn == "prefix" and not cs then
137                        cs = "always enforced"
138                    end
139                    cn = gsub(cn,"_"," ")
140                    if cs then
141                        wr(f1(id,cd,ix,cn,cs))
142                    elseif cn == "letter" or cn == "other char" then
143                        wr(f3(id,cd,ix,cn,ix))
144                    elseif cn == "match" then
145                        -- needs checking for additions
146                        local s
147                            if ix == 32 then s = "optional spacer"     -- space
148                        elseif ix == 42 then s = "skip spaces"         -- *
149                        elseif ix == 43 then s = "keep braces"         -- +
150                        elseif ix == 45 then s = "thrash"              -- -
151                        elseif ix == 47 then s = "prune"               -- /
152                        elseif ix == 58 then s = "continue"            -- :
153                        elseif ix == 59 then s = "quit"                -- ;
154                        elseif ix == 61 then s = "mandate braces"      -- =
155                        elseif ix == 94 then s = "keep spaces"         -- ^
156                        elseif ix == 95 then s = "keep mandate braces" -- _
157                        else                 s = "argument " .. char(ix)
158                        end
159                        wr(f1(id,cd,ix,cn,s))
160                    else
161                        wr(f2(id,cd,ix,cn))
162                        if cn == "end match" then
163                            wr("--------------")
164                        end
165                    end
166                end
167                nl()
168            end
169        end
170    }
171
172end
173
174-- For the moment here, will move to initex only (also see node-ini.lua); we need
175-- to actually store these.
176
177local context = context
178
179local function getthem(getter,post)
180    local codes = { }
181    if getter then
182        for k, v in next, getter() do
183            codes[k] = gsub(v,"[_ ]","")
184        end
185        if post and post ~= "" then
186            if environment.initex then
187                for k, v in next, codes do
188                    texintegerdef(v .. post,k,"immutable")
189                end
190            end
191            interfaces.implement {
192                name      = post .. "string",
193                public    = true,
194                arguments = "integer",
195                actions   = function(i)
196                    context(codes[i] or "unknown")
197                end
198            }
199        end
200    end
201    return allocate(swapped(codes,codes))
202end
203
204-- For the moment we do it like this:
205
206local function setthem(codes,post)
207    for k, v in next, codes do
208        texintegerdef(k .. post,v,"immutable")
209    end
210    return allocate(swapped(codes,codes))
211end
212
213tex.userglyphoptioncodes = setthem({
214    textcheckitalic = 0x01000000,
215    mathcheckitalic = 0x02000000,
216},"glyphoptioncode")
217
218tex.userdiscoptioncodes = setthem({
219    textcheckitalic = 0x01000000,
220},"discoptioncode")
221
222-- Not all of these make sense at the tex end (can't be set).
223
224tex.glyphoptioncodes         = getthem(tex.getglyphoptionvalues,"glyphoptioncode")
225tex.discoptioncodes          = getthem(tex.getdiscoptionvalues,"discoptioncode")
226tex.ruleoptioncodes          = getthem(tex.getruleoptionvalues,"ruleoptioncode")
227tex.glueoptioncodes          = getthem(tex.getglueoptionvalues)
228tex.mathoptioncodes          = getthem(tex.getmathoptionvalues)
229tex.penaltyoptioncodes       = getthem(tex.getpenaltyoptionvalues)
230tex.flagcodes                = getthem(tex.getflagvalues,"flagcode")
231tex.frozenparcodes           = getthem(tex.getfrozenparvalues,"frozenparcode")
232tex.groupcodes               = getthem(tex.getgroupvalues,"groupcode")
233tex.hyphenationcodes         = getthem(tex.gethyphenationvalues,"hyphenationcode")
234tex.mathcontrolcodes         = getthem(tex.getmathcontrolvalues,"mathcontrolcode")
235---.mathflattencodes         = getthem(tex.getmathflattenvalues,"mathflattencode")
236tex.noadoptioncodes          = getthem(tex.getnoadoptionvalues)
237tex.normalizelinecodes       = getthem(tex.getnormalizelinevalues,"normalizecode") -- we keep the short name
238tex.normalizeparcodes        = getthem(tex.getnormalizeparvalues,"normalizeparcode")
239tex.automigrationcodes       = getthem(tex.getautomigrationvalues,"automigrationcode")
240tex.autoparagraphcodes       = getthem(tex.getautoparagraphvalues)
241tex.parcontextcodes          = getthem(tex.getparcontextvalues,"parcontextcode")
242tex.partriggercodes          = getthem(tex.getpartriggervalues,"partriggercode")
243tex.textcontrolcodes         = getthem(tex.gettextcontrolvalues)
244---.fitnesscodes             = getthem(tex.getfitnessvalues)
245---.parpassclasscodes        = getthem(tex.getparpassclassvalues,"parpassclass" )
246tex.listanchorcodes          = getthem(tex.getlistanchorvalues,"listanchorcode")
247tex.listsigncodes            = getthem(tex.getlistsignvalues,"listsigncode")
248tex.listgeometrycodes        = getthem(tex.getlistgeometryvalues)
249tex.classoptioncodes         = getthem(tex.getmathclassoptionvalues,"classoptioncode")
250---.alignmentcontextcodes    = getthem(tex.getalignmentcontextvalues)
251tex.specialmathclasscodes    = getthem(tex.getspecialmathclassvalues)
252tex.directioncodes           = getthem(tex.getdirectionvalues)
253tex.fillcodes                = getthem(tex.getfillvalues)
254tex.mathparametercodes       = getthem(tex.getmathparametervalues)
255tex.breakcodes               = getthem(tex.getbreakcontextvalues)
256tex.buildcodes               = getthem(tex.getbuildcontextvalues)
257tex.splitcodes               = getthem(tex.getvsplitcontextvalues)
258tex.interactioncodes         = getthem(tex.getinteractionmodes,"modecode")
259tex.charactertagcodes        = getthem(tex.getcharactertagvalues)
260tex.protrusionboundarycodes  = getthem(tex.getprotrusionboundaryvalues)
261tex.shapingpenaltiescodes    = getthem(tex.getshapingpenaltiesvalues)
262tex.mathscriptordercodes     = getthem(tex.getmathscriptordervalues)
263tex.mathscriptsmodecodes     = getthem(tex.getmathscriptsmodevalues,"scriptsmodecode")
264tex.doublescriptoptioncodes  = getthem(tex.getdoublescriptoptionvalues,"doublescriptmodecode")
265tex.charactercontrolcodes    = getthem(tex.getcharactercontrolvalues,"charactercontrolcode")
266tex.specificationoptioncodes = getthem(tex.getspecificationoptionvalues,"specificationoptioncode")
267tex.discpartcodes            = getthem(tex.getdiscpartvalues)
268tex.glyphdisccodes           = getthem(tex.getglyphdiscvalues)
269tex.runstatecodes            = getthem(tex.getrunstatevalues)
270tex.mvloptioncodes           = getthem(tex.getmvloptionvalues,"mvloptioncode")
271tex.balancecallbackcodes     = getthem(tex.getbalancecallbackvalues)
272tex.badnessmodecodes         = getthem(tex.getbadnessmodevalues,"badnessmodecode")
273
274local linebreakstatecodes    = getthem(tex.getlinebreakstatevalues)
275tex.linebreakstatecodes      = linebreakstatecodes
276
277linebreakstatecodes.text     = linebreakstatecodes.glyph | linebreakstatecodes.disc
278linebreakstatecodes.content  = linebreakstatecodes.text  | linebreakstatecodes.math
279
280function tex.stringtocodesbitmap(str,codes)
281    local bitmap = 0
282    if codes then
283        if not str or str == "" then
284            -- zero
285        elseif str == "all" then
286            for k in next, codes do
287                if type(k) == "number" then
288                    bitmap = bitmap | k
289                end
290            end
291        else
292            str = gsub(str,"[_ ]","")
293            for s in gmatch(str,"[^%,]+") do
294                local b = codes[s]
295                if b then
296                    bitmap = bitmap | b
297                end
298            end
299        end
300    end
301    return bitmap
302end
303
304if environment.initex then
305    for k, v in next, tex.getmathvariantvalues() do
306        texintegerdef("math"..v.."stylepreset",tex.getmathvariantpresets(k),"immutable")
307    end
308end
309