toks-aux.lmt /size: 11 Kb    last modification: 2024-01-16 09: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.glueoptioncodes         = getthem(tex.getglueoptionvalues        )
227tex.mathoptioncodes         = getthem(tex.getmathoptionvalues        )
228tex.penaltyoptioncodes      = getthem(tex.getpenaltyoptionvalues     )
229tex.flagcodes               = getthem(tex.getflagvalues,             "flagcode" )
230tex.frozenparcodes          = getthem(tex.getfrozenparvalues,        "frozenparcode")
231tex.groupcodes              = getthem(tex.getgroupvalues,            "groupcode")
232tex.hyphenationcodes        = getthem(tex.gethyphenationvalues,      "hyphenationcode")
233tex.mathcontrolcodes        = getthem(tex.getmathcontrolvalues,      "mathcontrolcode")
234---.mathflattencodes        = getthem(tex.getmathflattenvalues,      "mathflattencode")
235tex.noadoptioncodes         = getthem(tex.getnoadoptionvalues        )
236tex.normalizelinecodes      = getthem(tex.getnormalizelinevalues,    "normalizecode")     -- we keep the short name
237tex.normalizeparcodes       = getthem(tex.getnormalizeparvalues,     "normalizeparcode")
238tex.automigrationcodes      = getthem(tex.getautomigrationvalues,    "automigrationcode")
239tex.autoparagraphcodes      = getthem(tex.getautoparagraphvalues)
240tex.parcontextcodes         = getthem(tex.getparcontextvalues,       "parcontextcode")
241tex.partriggercodes         = getthem(tex.getpartriggervalues,       "partriggercode")
242tex.textcontrolcodes        = getthem(tex.gettextcontrolvalues       )
243tex.fitnesscodes            = getthem(tex.getfitnessvalues           )
244tex.parpassclasscodes       = getthem(tex.getparpassclassvalues,     "parpassclass" )
245tex.listanchorcodes         = getthem(tex.getlistanchorvalues,       "listanchorcode")
246tex.listsigncodes           = getthem(tex.getlistsignvalues,         "listsigncode")
247tex.listgeometrycodes       = getthem(tex.getlistgeometryvalues      )
248tex.classoptioncodes        = getthem(tex.getmathclassoptionvalues,  "classoptioncode")
249---.alignmentcontextcodes   = getthem(tex.getalignmentcontextvalues  )
250tex.specialmathclasscodes   = getthem(tex.getspecialmathclassvalues  )
251tex.directioncodes          = getthem(tex.getdirectionvalues         )
252tex.fillcodes               = getthem(tex.getfillvalues              )
253tex.mathparametercodes      = getthem(tex.getmathparametervalues     )
254tex.breakcodes              = getthem(tex.getbreakcontextvalues      )
255tex.buildcodes              = getthem(tex.getbuildcontextvalues      )
256tex.interactioncodes        = getthem(tex.getinteractionmodes,       "modecode")
257tex.charactertagcodes       = getthem(tex.getcharactertagvalues      )
258tex.protrusionboundarycodes = getthem(tex.getprotrusionboundaryvalues)
259tex.shapingpenaltiescodes   = getthem(tex.getshapingpenaltiesvalues  )
260
261function tex.stringtocodesbitmap(str,codes)
262    local bitmap = 0
263    if codes then
264        if not str or str == "" then
265            -- zero
266        elseif str == "all" then
267            for k in next, codes do
268                if type(k) == "number" then
269                    bitmap = bitmap | k
270                end
271            end
272        else
273            str = gsub(str,"[_ ]","")
274            for s in gmatch(str,"[^%,]+") do
275                local b = codes[s]
276                if b then
277                    bitmap = bitmap | b
278                end
279            end
280        end
281    end
282    return bitmap
283end
284