mlib-lmt.lmt /size: 6145 b    last modification: 2021-10-28 13:51
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    local d    = 1/10^scannumeric() -- decimals
163    local p1   = pth[1]
164    local x1   = p1[1]
165    local y1   = p1[2]
166    local res  = { pth[1] }
167    local r    = 1
168    for i=2,#pth do
169        local pi = pth[i]
170        x2 = pi[1]
171        y2 = pi[2]
172        if abs(x1-x2) > d or abs(y1-y2) > d then
173            r = r + 1 res[r] = pi
174            x1 = x2
175            y1 = y2
176        else
177            res[r][5] = pi[5]
178            res[r][6] = pi[6]
179        end
180    end
181    if pth.cycle then
182        res.cycle = true
183        if abs(x1-p1[1]) > d or abs(y1-p1[2]) > d then
184            -- keep
185        else
186            res[r] = nil
187        end
188    end
189    injectpath(res)
190end)
191
192-- A goodie, mostly a side effect of updating the metafun manual.
193
194local labtorgb = attributes.colors.labtorgb
195
196registerscript("labtorgb", function()
197    injectcolor(labtorgb(scannumeric(),scannumeric(),scannumeric()))
198end)
199