summaryrefslogtreecommitdiff
path: root/tex/context/base/mkxl/mlib-lua.lmt
blob: 19423e7b1d6ef80219b9c18ec7ae10ad889a2748 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
if not modules then modules = { } end modules ['mlib-lua'] = {
    version   = 1.001,
    comment   = "companion to mlib-ctx.mkiv",
    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
    copyright = "PRAGMA ADE / ConTeXt Development Team",
    license   = "see context related readme files",
}

local type = type
local insert, remove = table.insert, table.remove

local trace  = false  trackers.register("metapost.instance",function(v) trace = v end)

local report = logs.reporter("metapost","instance")

local codes = mplib.getcodes()
local types = mplib.gettypes()

table.hashed(codes)
table.hashed(types)

metapost.codes = codes
metapost.types = types

local scan   = mp.scan
local skip   = mp.skip
local get    = mp.get
local inject = mp.inject

local bpfactor   = number.dimenfactors.bp
local currentmpx = nil
local stack      = { }

local function reports(s) report("%a scan %s",  tostring(currentmpx),s) end -- temporary, till we're okay
local function reporti(s) report("%a inject %s",tostring(currentmpx),s) end -- temporary, till we're okay

local scannext       = mplib.scannext
local scanexpression = mplib.scanexpression
local scantoken      = mplib.scantoken
local scansymbol     = mplib.scansymbol
local scanproperty   = mplib.scanproperty
local scannumeric    = mplib.scannumeric
local scaninteger    = mplib.scaninteger
local scanboolean    = mplib.scanboolean
local scanstring     = mplib.scanstring
local scanpair       = mplib.scanpair
local scancolor      = mplib.scancolor
local scancmykcolor  = mplib.scancmykcolor
local scantransform  = mplib.scantransform
local scanpath       = mplib.scanpath
local scanpen        = mplib.scanpen

local skiptoken      = mplib.skiptoken

local gethashentry   = mplib.gethashentry

scan.next       = function(k)     if trace then reporti("next")       end return scannext      (currentmpx,k)     end
scan.expression = function(k)     if trace then reporti("expression") end return scanexpression(currentmpx,k)     end
scan.token      = function(k)     if trace then reporti("token")      end return scantoken     (currentmpx,k)     end
scan.symbol     = function(k,e)   if trace then reporti("symbol")     end return scansymbol    (currentmpx,k,e)   end
scan.property   = function(k)     if trace then reporti("property")   end return scanproperty  (currentmpx,k)     end
scan.numeric    = function()      if trace then reporti("numeric")    end return scannumeric   (currentmpx)       end
scan.integer    = function()      if trace then reporti("integer")    end return scaninteger   (currentmpx)       end
scan.boolean    = function()      if trace then reporti("boolean")    end return scanboolean   (currentmpx)       end
scan.string     = function()      if trace then reporti("string")     end return scanstring    (currentmpx)       end
scan.pair       = function(t)     if trace then reporti("pair")       end return scanpair      (currentmpx,t)     end
scan.color      = function(t)     if trace then reporti("color")      end return scancolor     (currentmpx,t)     end
scan.cmykcolor  = function(t)     if trace then reporti("cmykcolor")  end return scancmykcolor (currentmpx,t)     end
scan.transform  = function(t)     if trace then reporti("transform")  end return scantransform (currentmpx,t)     end
scan.path       = function(t,k,c) if trace then reporti("path")       end return scanpath      (currentmpx,t,k,c) end -- compact kind (prim) check
scan.pen        = function(t)     if trace then reporti("pen")        end return scanpen       (currentmpx,t)     end

skip.token      = function(t) return skiptoken   (currentmpx,t) end
get.hashentry   = function(n) return gethashentry(currentmpx,n) end

local solvepath = mplib.solvepath
local getstatus = mplib.getstatus
local expandtex = mplib.expandtex

mp.solve     = function(...) return solvepath(currentmpx,...) end
mp.expandtex = function(...) return expandtex(currentmpx,...) end

local injectpath      = mplib.injectpath
local injectnumeric   = mplib.injectnumeric
local injectpair      = mplib.injectpair
local injectboolean   = mplib.injectboolean
local injectinteger   = mplib.injectinteger
local injectstring    = mplib.injectstring
local injectcolor     = mplib.injectcolor
local injectcmykcolor = mplib.injectcmykcolor
local injecttransform = mplib.injecttransform
local injectwhatever  = mplib.injectwhatever

------.path      = function(t,cycle,curled)  if trace then reporti("path")      end return injectpath     (currentmpx,t,cycle,curled)  end
inject.numeric   = function(n)               if trace then reporti("numeric")   end return injectnumeric  (currentmpx,n)               end
inject.pair      = function(x,y)             if trace then reporti("pair")      end return injectpair     (currentmpx,x,y)             end
inject.boolean   = function(b)               if trace then reporti("boolean")   end return injectboolean  (currentmpx,b)               end
inject.integer   = function(i)               if trace then reporti("integer")   end return injectinteger  (currentmpx,i)               end
inject.string    = function(s)               if trace then reporti("string")    end return injectstring   (currentmpx,s)               end
inject.color     = function(r,g,b)           if trace then reporti("color")     end return injectcolor    (currentmpx,r,g,b)           end
inject.cmykcolor = function(c,m,y,k)         if trace then reporti("cmykcolor") end return injectcmykcolor(currentmpx,c,m,y,k)         end
inject.transform = function(x,y,xx,xy,yx,yy) if trace then reporti("transform") end return injecttransform(currentmpx,x,y,xx,xy,yx,yy) end
inject.whatever  = function(...)             if trace then reporti("whatever")  end return injectwhatever (currentmpx,...)             end

inject.triplet    = inject.color
inject.quadruplet = inject.cmykcolor

-- these can be optimized for zero:

inject.whd = function(w,h,d) injectcolor  (currentmpx,(w or 0)*bpfactor,(h or 0)*bpfactor,(d or 0)*bpfactor) end
inject.xy  = function(x,y)   injectpair   (currentmpx,(x or 0)*bpfactor,(y or 0)*bpfactor) end
inject.pt  = function(n)     injectnumeric(currentmpx,(n or 0)*bpfactor) end

local function same(p,n)
    local f = p[1]
    local l = p[n]
    local nf = #f
    local nl = #l
    if nf == nl then
        for i=1,nf do
            if f[i] ~= l[i] then
                return false
            end
        end
        return true
    end
    return false
end

-- function inject.path(p,close,connector)
--     local closed = false
--     local curled = false
--     local n = #p
-- print("spec",p,close,connector)
--     if close == nil then
--         closed = (p.close or p.cycle or p.closed) and true or false
--     else
--         closed = close
--     end
--     if connector then
--         if connector == "auto" then
--             connector = #p[1] > 2
--         end
--         if connector == false or connector == "--" then
--             curled = true
--      -- elseif connector == true or connector == ".." then
--      --     if close and not same(p,n) then
--      --         p[n+1] = p[1]
--      --     end
--         end
--     elseif p.curled then
--         curled = true
--     end
--     if trace then reporti("path") end
--     inspect(p)
--     print(p,closed,curled)
--     return injectpath(currentmpx,p,closed,curled)
-- end

function inject.path(p,connector,close)
    local closed = false
    local curled = false
    local n = #p
    if close == nil then
        closed = (p.close or p.cycle or p.closed) and true or false
    else
        closed = close
    end
    if connector then
        if connector == "auto" then
            connector = #p[1] > 2
        end
        if connector == false or connector == "--" then
            curled = true
        end
    elseif p.curled then
        curled = true
    end
    if trace then reporti("path") end
    return injectpath(currentmpx,p,closed,curled)
end

-- bonus:

scan  .number    = scan  .numeric
inject.number    = inject.numeric

table.setmetatablecall(inject,function(t,...)
    injectwhatever(currentmpx,...)
end)

-- experiment

function mp.autoinject(m)
    local t = type(m)
    if t == "table" then
        local n = #t
        if n == 2 then
            injectpair(currentmpx,m)
        elseif n == 3 then
            injectcolor(currentmpx,m)
        elseif n == 4 then
            injectcmykcolor(currentmpx,m)
        elseif n == 6 then
            injecttransform(currentmpx,m)
        end
    elseif t == "number" then
        injectnumeric(currentmpx,m)
    elseif t == "string" then
        injectstring(currentmpx,m)
    elseif t == "boolean" then
        injectboolean(currentmpx,m)
    end
end

function metapost.pushscriptrunner(mpx)
    if trace then
        report("%a => %a",tostring(currentmpx),tostring(mpx))
    end
    insert(stack,currentmpx)
    currentmpx = mpx
end

function metapost.popscriptrunner()
    local mpx = remove(stack)
    if trace then
        report("%a <= %a",tostring(mpx),tostring(currentmpx))
    end
    currentmpx = mpx
end

function metapost.currentmpx()
    return currentmpx
end

-- mplib.getstates(): zero is "normal"

function metapost.currentmpxstatus()
    return getstatus(currentmpx) or 0
end