mlib-lmt.lmt /size: 7477 b    last modification: 2025-02-21 11:03
1if not modules then modules = { } end modules ['mlib-lmt'] = {
2    version   = 1.001,
3    comment   = "companion to mlib-ctx.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-- todo: check for possible inject usage
10
11local type = type
12local round, abs = math.round, math.abs
13
14local aux            = mp.aux
15local mpdirect       = aux.direct
16local mppath         = mp.path
17
18local scan           = mp.scan
19local scannumeric    = scan.numeric
20local scanpath       = scan.path
21
22local injectpath     = mp.inject.path
23local injectcolor    = mp.inject.color
24
25local getparameter   = metapost.getparameter
26local registerscript = metapost.registerscript
27
28function mp.lmt_function_x(xmin,xmax,xstep,code,shape) -- experimental
29    local code      = "return function(x) return " .. code .. " end"
30    local action    = load(code)
31    local points    = { }
32    local nofpoints = 0
33    if action then
34         action = action()
35    end
36    if shape == "steps" then
37        local halfx     = xstep / 2
38        local lastx     = xmin
39        local lasty     = action(xmin)
40        for xi = xmin, xmax, xstep do
41            local yi  = action(xi)
42            local xx  = lastx + halfx
43            nofpoints = nofpoints + 1 ; points[nofpoints] = { xx, lasty }
44            nofpoints = nofpoints + 1 ; points[nofpoints] = { xx, yi }
45            lastx     = xi
46            lasty     = yi
47        end
48        if points[nofpoints][1] ~= xmax then
49            local yi  = action(xmax)
50            local xx  = lastx + halfx
51            nofpoints = nofpoints + 1 ; points[nofpoints] = { xx, lasty }
52            nofpoints = nofpoints + 1 ; points[nofpoints] = { xx, yi }
53            lastx     = xi
54            lasty     = yi
55        end
56    else
57        for xi = xmin, xmax, xstep do
58            nofpoints = nofpoints + 1 ; points[nofpoints] = { xi, action(xi) }
59        end
60        if points[nofpoints][1] ~= xmax then
61            nofpoints = nofpoints + 1 ; points[nofpoints] = { xmax, action(xmax) }
62        end
63    end
64    mppath(points,shape == "curve" and ".." or "--",false)
65end
66
67function mp.lmt_mesh_set()
68    local mesh = getparameter { "mesh", "paths" }
69    structures.references.currentset.mesh = mesh
70end
71
72function mp.lmt_mesh_update()
73    local mesh = getparameter { "paths" } or getparameter { "mesh", "paths" }
74    mesh[scannumeric()] = scanpath(true)
75end
76
77-- moved here
78
79function mp.lmt_svg_include()
80    local labelfile = metapost.getparameter { "labelfile" }
81    if labelfile and labelfile ~= "" then
82        labelfile = resolvers.findbinfile(labelfile)
83    end
84    if labelfile and labelfile ~= "" then
85        local labels = table.load(labelfile) -- todo: same path as svg file
86        if type(labels) == "table" then
87            for i=1,#labels do
88                metapost.remaptext(labels[i])
89            end
90        end
91    end
92    local fontname = metapost.getparameter { "fontname" }
93    if fontname and fontname ~= "" then
94        local unicode = metapost.getparameter { "unicode" }
95        if unicode then
96            mpdirect (
97                metapost.svgglyphtomp(fontname,math.round(unicode))
98            )
99        end
100        return
101    end
102    local colorfile = metapost.getparameter { "colormap" }
103    local colormap  = false
104    if colorfile and colorfile ~= "" then
105        colormap = metapost.svgcolorremapper(colorfile)
106    end
107    local filename = metapost.getparameter { "filename" }
108    if filename and filename ~= "" then
109        local ok, data = resolvers.loadbinfile(filename)
110        mpdirect ( metapost.svgtomp {
111            data     = data,
112            remap    = true,
113            colormap = colormap,
114            id       = filename,
115        } )
116    else
117        local buffer = metapost.getparameter { "buffer" }
118        if buffer then
119            mpdirect ( metapost.svgtomp {
120                data     = buffers.getcontent(buffer),
121             -- remap    = true,
122                colormap = colormap,
123                id       = buffer or "buffer",
124            } )
125        else
126            local code = metapost.getparameter { "code" }
127            if code then
128                mpdirect ( metapost.svgtomp {
129                    data     = code,
130                    colormap = colormap,
131                    id       = "code",
132                } )
133            end
134        end
135    end
136end
137
138registerscript("remaptext", function()
139    local parameters = metapost.scanparameters(true) -- gobble the semi colon (avoid lookahead)
140    if parameters and parameters.label then
141        metapost.remaptext(parameters)
142    end
143end)
144
145do
146
147    local dropins        = fonts.dropins
148    local registerglyph  = dropins.registerglyph
149    local registerglyphs = dropins.registerglyphs
150
151    registerscript("registerglyph", function() registerglyph (metapost.getparameterset("mpsglyph"))  end)
152    registerscript("registerglyphs",function() registerglyphs(metapost.getparameterset("mpsglyphs")) end)
153
154end
155
156todecimal = xdecimal and xdecimal.new or tonumber -- bonus
157
158-- mail on list by Mikael Sundqvist and Taco's analysis of near duplicate points (2021/02/11+)
159
160registerscript("scrutinized", function()
161    local pth = scanpath()
162-- for i=1,#pth do
163--     pth[i].right_type = nil
164--     pth[i].left_type = nil
165-- end
166    local d   = 1/(10^scannumeric()) -- decimals
167    local p1  = pth[1]
168    local x1  = p1[1]
169    local y1  = p1[2]
170    local res = { pth[1] }
171    local r   = 1
172    for i=2,#pth do
173        local pi = pth[i]
174        x2 = pi[1]
175        y2 = pi[2]
176        if abs(x1-x2) > d or abs(y1-y2) > d then
177            r = r + 1 res[r] = pi
178            x1 = x2
179            y1 = y2
180        else
181            res[r][5] = pi[5]
182            res[r][6] = pi[6]
183        end
184    end
185    if pth.cycle then
186        res.cycle = true
187        if abs(x1-p1[1]) > d or abs(y1-p1[2]) > d then
188            -- keep
189        else
190            p1[3] = res[r][3]
191            p1[4] = res[r][4]
192            res[r] = nil
193        end
194    end
195    injectpath(res)
196end)
197
198local newtable = lua.newtable
199
200registerscript("recycled", function()
201    local pth = scanpath()
202    local n   = scannumeric()
203    local p   = #pth
204    n = n % p
205    if n == 0 or not pth.cycle then -- table.rotate
206        injectpath(pth)
207    else
208      local res = newtable(p,1)
209      local r   = 0
210      for i=p-n+1,p do
211          r = r + 1 ; res[r] = pth[i]
212      end
213      for i=1,p-n do
214          r = r + 1 ; res[r] = pth[i]
215      end
216-- for i=1,r do
217--     res[i].right_type = nil
218--     res[i].left_type  = nil
219-- end
220        res.cycle = true
221        injectpath(res)
222    end
223end)
224
225-- A goodie, mostly a side effect of updating the metafun manual.
226
227local labtorgb = attributes.colors.labtorgb
228local xyxtorgb = attributes.colors.xyztorgb
229local lchtorgb = attributes.colors.lchtorgb
230local hsvtorgb = attributes.colors.hsvtorgb
231local hwbtorgb = attributes.colors.hwbtorgb
232
233registerscript("labtorgb", function() injectcolor(labtorgb(scannumeric(),scannumeric(),scannumeric())) end)
234registerscript("xyztorgb", function() injectcolor(xyztorgb(scannumeric(),scannumeric(),scannumeric())) end)
235registerscript("lchtorgb", function() injectcolor(lchtorgb(scannumeric(),scannumeric(),scannumeric())) end)
236registerscript("hsvtorgb", function() injectcolor(hsvtorgb(scannumeric(),scannumeric(),scannumeric())) end)
237registerscript("hwbtorgb", function() injectcolor(hwbtorgb(scannumeric(),scannumeric(),scannumeric())) end)
238