math-pre.lmt /size: 4998 b    last modification: 2024-01-16 10:22
1if not modules then modules = { } end modules ['math-pre'] = {
2    version   = 1.001,
3    optimize  = true,
4    comment   = "companion to math-ini.mkiv",
5    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
6    copyright = "PRAGMA ADE / ConTeXt Development Team",
7    license   = "see context related readme files"
8}
9
10local type, tonumber = type, tonumber
11local gmatch, find, topattern = string.gmatch, string.find, string.topattern
12
13local parameterlist = tex.getmathparametervalues()
14local mathstylelist = tex.getmathstylenamevalues()
15local parameterhash = table.swapped(parameterlist)
16local mathstylehash = table.swapped(mathstylelist)
17
18local axis = parameterhash.axis
19
20local getmath = tex.getmath
21local setmath = tex.setmath
22
23local function expandparameters(t)
24    local result = { }
25    local kind   = type(t)
26    local function expand(s)
27        s = topattern(s)
28        for i=1,#parameterlist do
29            local p = parameterlist[i]
30            if find(p,s) then
31                result[#result+1] = p
32            end
33        end
34    end
35    if kind == "string" then
36        for s in gmatch(t,"[^%s,]+") do
37            expand(s)
38        end
39    elseif kind == "table" then
40        for i=1,#t do
41            expand(t[i])
42        end
43    end
44    return result
45end
46
47function setmathparameters(t)
48    if t then
49        for i=1,#t do
50            local ti     = t[i]
51            local list   = ti.list
52            local factor = ti.factor or 1
53            local style  = ti.style
54            local value  = ti.value
55            local unit   = ti.unit
56
57            local function set(li,si,value)
58                if value then
59                    setmath(li,si,value)
60                elseif factor == 0 then
61                    setmath(li,si,0)
62                elseif unit == "axis" then
63                    setmath(li,si,factor * getmath(axis,i))
64                else
65                    setmath(li,si,factor * getmath(li,i))
66                end
67            end
68
69            for i=1,#list do
70                local li = parameterhash[list[i]]
71                if li then
72                    if style == "all" then
73                        for si=0,7 do
74                            set(li,si,value)
75                        end
76                    elseif type(style) == "string" then
77                        local si = mathstylehash[style]
78                        if si then
79                            set(li,si,value)
80                        end
81                    else
82                        for s=1,#style do
83                            local si = mathstylehash[style[s]]
84                            if si then
85                                set(li,si,value)
86                            end
87                        end
88                    end
89                end
90            end
91        end
92    end
93end
94
95-- example
96
97local stacklist = {
98    "fractionnumvgap",
99    "fractiondenomvgap",
100    "fractionnumup",
101    "fractiondenomdown",
102    "stackdenomdown",
103    "stacknumup",
104    "stackvgap",
105}
106
107local presets = {
108    less = {
109        {
110            factor = .5,
111         -- factor = 0,
112         -- value  = 655360,
113         -- unit   = "axis",
114            list   = stacklist,
115         -- style  = { "display" },
116         -- style  = "display",
117            style = "all"
118        },
119    },
120    more = {
121        {
122            factor = 2,
123            list   = stacklist,
124            style  = "all"
125        },
126    },
127    zero = {
128        {
129            factor = 0,
130            list   = stacklist,
131            style  = "all"
132        },
133    },
134}
135
136mathematics.presets = presets -- we might need to store these in the format file
137
138function mathematics.preset(list)
139    for s in gmatch(list,"[^%s,]+") do
140        setmathparameters(presets[s])
141    end
142end
143
144-- todo: append, prepend, inherit
145
146interfaces.implement {
147    name      = "definemathpreset",
148    public    = true,
149    protected = true,
150    arguments = { "optional", "hash" },
151    actions   = function(name,t)
152        if next(t) then
153            local factor = t.factor
154            local style  = t.style
155            local list   = t.list
156            local unit   = t.unit
157            if factor then
158                t.factor = tonumber(factor)
159            end
160            if style and style ~= "all" then
161                t.style = utilities.parsers.settings_to_array(style)
162            end
163            if list then
164             -- t.list = utilities.parsers.settings_to_array(list)
165                t.list = expandparameters(list)
166            end
167            if unit and unit ~= "axis" then
168                t.unit = nil
169            end
170            -- todo: value
171            local p = presets[name]
172            if p then
173                p[#p+1] = t
174            else
175                presets[name] = t
176            end
177        else
178            presets[name] = nil
179        end
180    end,
181}
182
183interfaces.implement {
184    name      = "presetmathematics",
185    public    = true,
186    protected = true,
187    arguments = "optional",
188    actions   = mathematics.preset,
189}
190