core-env.lua /size: 6427 b    last modification: 2021-10-28 13:50
1if not modules then modules = { } end modules ['core-env'] = {
2    version   = 1.001,
3    comment   = "companion to core-env.mkiv",
4    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5    copyright = "PRAGMA ADE / ConTeXt Development Team",
6    license   = "see context related readme files"
7}
8
9-- maybe this will move to the context name space although the
10-- plurals are unlikely to clash with future tex primitives
11--
12-- if tex.modes['xxxx'] then .... else .... end
13
14local rawset = rawset
15
16local P, C, S, lpegmatch, patterns = lpeg.P, lpeg.C, lpeg.S, lpeg.match, lpeg.patterns
17
18local context              = context
19local ctxcore              = context.core
20
21local texgetcount          = tex.getcount
22
23local allocate             = utilities.storage.allocate
24local setmetatableindex    = table.setmetatableindex
25local setmetatablenewindex = table.setmetatablenewindex
26local setmetatablecall     = table.setmetatablecall
27
28local createtoken          = token.create
29local isdefined            = tokens.isdefined
30
31texmodes                   = allocate { }  tex.modes        = texmodes
32texsystemmodes             = allocate { }  tex.systemmodes  = texsystemmodes
33texconstants               = allocate { }  tex.constants    = texconstants
34texconditionals            = allocate { }  tex.conditionals = texconditionals
35texifs                     = allocate { }  tex.ifs          = texifs
36texisdefined               = allocate { }  tex.isdefined    = texisdefined
37
38local modes                = { }
39local systemmodes          = { }
40
41-- we could use the built-in tex.is[count|dimen|skip|toks] here but caching
42-- at the lua end is not that bad (and we need more anyway)
43
44local cache = tokens.cache
45
46-- we can have a modes cache too
47
48local iftrue        = cache["iftrue"].mode
49
50local dimencode     = cache["scratchdimen"]  .command -- tokens.commands.register_dimen
51local countcode     = cache["scratchcounter"].command -- tokens.commands.register_int
52local tokencode     = cache["scratchtoks"]   .command -- tokens.commands.register_toks
53local skipcode      = cache["scratchskip"]   .command -- tokens.commands.register_glue
54local muskipcode    = cache["scratchmuskip"] .command -- tokens.commands.register_mu_glue
55local conditioncode = cache["iftrue"]        .command -- tokens.commands.if_test
56
57local types = {
58    [dimencode]     = "dimen",
59    [countcode]     = "count",
60    [tokencode]     = "token",
61    [skipcode]      = "skip",
62    [muskipcode]    = "muskip",
63 -- [attributecode] = "attribute",
64    [conditioncode] = "condition"
65}
66
67setmetatableindex(texmodes, function(t,k)
68    local m = modes[k]
69    if m then
70        return m()
71    elseif k then
72        local n = "mode>" .. k
73        if isdefined(n) then
74            rawset(modes,k, function() return texgetcount(n) == 1 end)
75            return texgetcount(n) == 1 -- 2 is prevented
76        else
77            return false
78        end
79    else
80        return false
81    end
82end)
83
84setmetatableindex(texsystemmodes, function(t,k)
85    local m = systemmodes[k]
86    if m then
87        return m()
88    else
89        local n = "mode>*" .. k
90        if isdefined(n) then
91            rawset(systemmodes,k,function() return texgetcount(n) == 1 end)
92            return texgetcount(n) == 1 -- 2 is prevented
93        else
94            return false
95        end
96    end
97end)
98
99do  -- we could do the same as in lmtx (use the mode)
100
101    local trialtypesettingstate = createtoken("trialtypesettingstate").index
102    local texgetcount           = tex.getcount
103
104    context.settrialtypesettingmethod(function()
105        return texgetcount(trialtypesettingstate) ~= 0
106    end)
107
108end
109
110setmetatablenewindex(texmodes,        function(t,k) report_mode("you cannot set the %s named %a this way","mode",       k) end)
111setmetatablenewindex(texsystemmodes,  function(t,k) report_mode("you cannot set the %s named %a this way","systemmode", k) end)
112setmetatablenewindex(texconstants,    function(t,k) report_mode("you cannot set the %s named %a this way","constant",   k) end)
113setmetatablenewindex(texconditionals, function(t,k) report_mode("you cannot set the %s named %a this way","conditional",k) end)
114setmetatablenewindex(texifs,          function(t,k) end)
115
116setmetatablenewindex(texifs, function(t,k)
117    -- just ignore
118end)
119
120setmetatableindex(texconstants, function(t,k)
121    return cache[k].mode ~= 0 and texgetcount(k) or 0
122end)
123
124setmetatableindex(texconditionals, function(t,k) -- 0 == true
125    return cache[k].mode ~= 0 and texgetcount(k) == 0
126end)
127
128setmetatableindex(texifs, function(t,k)
129    return cache[k].mode == iftrue
130end)
131
132tex.isdefined = isdefined
133
134function tex.isdimen(name)
135    local hit = cache[name]
136    return hit.command == dimencode and hit.index or true
137end
138
139function tex.iscount(name)
140    local hit = cache[name]
141    return hit.command == countcode and hit.index or true
142end
143
144function tex.istoken(name)
145    local hit = cache[name]
146    return hit.command == tokencode and hit.index or true
147end
148
149function tex.isskip(name)
150    local hit = cache[name]
151    return hit.command == skipcode and hit.index or true
152end
153
154function tex.ismuskip(name)
155    local hit = cache[name]
156    return hit.command == muskipcode and hit.index or true
157end
158
159function tex.type(name)
160    return types[cache[name].command] or "macro"
161end
162
163function context.setconditional(name,value)
164    if value then
165        ctxcore.settruevalue(name)
166    else
167        ctxcore.setfalsevalue(name)
168    end
169end
170
171function context.setmode(name,value)
172    if value then
173        ctxcore.setmode(name)
174    else
175        ctxcore.resetmode(name)
176    end
177end
178
179function context.setsystemmode(name,value)
180    if value then
181        ctxcore.setsystemmode(name)
182    else
183        ctxcore.resetsystemmode(name)
184    end
185end
186
187context.modes        = texmodes
188context.systemmodes  = texsystemmodes
189context.conditionals = texconditionals
190-------.constants    = texconstants
191-------.ifs          = texifs
192
193local sep = S("), ")
194local str = C((1-sep)^1)
195local tag = P("(") * C((1-S(")" ))^1) * P(")")
196local arg = P("(") * C((1-S("){"))^1) * P("{") * C((1-P("}"))^0) * P("}") * P(")")
197
198local pattern = (
199     P("lua") * tag        / ctxcore.luasetup
200  +  P("xml") * arg        / ctxcore.setupwithargument -- or xmlw as xmlsetup has swapped arguments
201  + (P("tex") * tag + str) / ctxcore.texsetup
202  +             sep^1
203)^1
204
205interfaces.implement {
206    name      = "autosetups",
207    actions   = function(str) lpegmatch(pattern,str) end,
208    arguments = "string"
209}
210