summaryrefslogtreecommitdiff
path: root/tex/context/base/meta-pdh.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/meta-pdh.lua')
-rw-r--r--tex/context/base/meta-pdh.lua1220
1 files changed, 610 insertions, 610 deletions
diff --git a/tex/context/base/meta-pdh.lua b/tex/context/base/meta-pdh.lua
index 10fbad141..5040715c4 100644
--- a/tex/context/base/meta-pdh.lua
+++ b/tex/context/base/meta-pdh.lua
@@ -1,610 +1,610 @@
-if not modules then modules = { } end modules ['meta-pdf'] = {
- version = 1.001,
- comment = "companion to meta-pdf.mkiv",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
-if true then
- return -- or os.exit()
-end
-
--- This file contains the history of the converter. We keep it around as it
--- relates to the development of luatex.
-
--- This is the third version. Version 1 converted to Lua code,
--- version 2 gsubbed the file into TeX code, and version 3 uses
--- the new lpeg functionality and streams the result into TeX.
-
--- We will move old stuff to edu.
-
---~ old lpeg 0.4 lpeg 0.5
---~ 100 times test graphic 2.45 (T:1.07) 0.72 (T:0.24) 0.580 (0.560 no table) -- 0.54 optimized for one space (T:0.19)
---~ 100 times big graphic 10.44 4.30/3.35 nogb 2.914 (2.050 no table) -- 1.99 optimized for one space (T:0.85)
---~ 500 times test graphic T:1.29 T:1.16 (T:1.10 no table) -- T:1.10
-
--- only needed for mp output on disk
-
-local concat, format, find, gsub, gmatch = table.concat, string.format, string.find, string.gsub, string.gmatch
-local tostring, tonumber, select = tostring, tonumber, select
-local lpegmatch = lpeg.match
-
-local metapost = metapost
-
-metapost.mptopdf = metapost.mptopdf or { }
-local mptopdf = metapost.mptopdf
-
-mptopdf.parsers = { }
-mptopdf.parser = 'none'
-mptopdf.nofconverted = 0
-
-function mptopdf.reset()
- mptopdf.data = ""
- mptopdf.path = { }
- mptopdf.stack = { }
- mptopdf.texts = { }
- mptopdf.version = 0
- mptopdf.shortcuts = false
- mptopdf.resetpath()
-end
-
-function mptopdf.resetpath()
- mptopdf.stack.close = false
- mptopdf.stack.path = { }
- mptopdf.stack.concat = nil
- mptopdf.stack.special = false
-end
-
-mptopdf.reset()
-
-function mptopdf.parsers.none()
- -- no parser set
-end
-
-function mptopdf.parse()
- mptopdf.parsers[mptopdf.parser]()
-end
-
--- old code
-
-mptopdf.steps = { }
-
-mptopdf.descapes = {
- ['('] = "\\\\char40 ",
- [')'] = "\\\\char41 ",
- ['"'] = "\\\\char92 "
-}
-
-function mptopdf.descape(str)
- str = gsub(str,"\\(%d%d%d)",function(n)
- return "\\char" .. tonumber(n,8) .. " "
- end)
- return gsub(str,"\\([%(%)\\])",mptopdf.descapes)
-end
-
-function mptopdf.steps.descape(str)
- str = gsub(str,"\\(%d%d%d)",function(n)
- return "\\\\char" .. tonumber(n,8) .. " "
- end)
- return gsub(str,"\\([%(%)\\])",mptopdf.descapes)
-end
-
-function mptopdf.steps.strip() -- .3 per expr
- mptopdf.data = gsub(mptopdf.data,"^(.-)%%+Page:.-%c+(.*)%s+%a+%s+%%+EOF.*$", function(preamble, graphic)
- local bbox = "0 0 0 0"
- for b in gmatch(preamble,"%%%%%a+oundingBox: +(.-)%c+") do
- bbox = b
- end
- local name, version = gmatch(preamble,"%%%%Creator: +(.-) +(.-) ")
- mptopdf.version = tostring(version or "0")
- if find(preamble,"/hlw{0 dtransform") then
- mptopdf.shortcuts = true
- end
- -- the boundingbox specification needs to come before data, well, not really
- return bbox .. " boundingbox\n" .. "\nbegindata\n" .. graphic .. "\nenddata\n"
- end, 1)
- mptopdf.data = gsub(mptopdf.data,"%%%%MetaPostSpecials: +(.-)%c+", "%1 specials\n", 1)
- mptopdf.data = gsub(mptopdf.data,"%%%%MetaPostSpecial: +(.-)%c+", "%1 special\n")
- mptopdf.data = gsub(mptopdf.data,"%%.-%c+", "")
-end
-
-function mptopdf.steps.cleanup()
- if not mptopdf.shortcuts then
- mptopdf.data = gsub(mptopdf.data,"gsave%s+fill%s+grestore%s+stroke", "both")
- mptopdf.data = gsub(mptopdf.data,"([%d%.]+)%s+([%d%.]+)%s+dtransform%s+exch%s+truncate%s+exch%s+idtransform%s+pop%s+setlinewidth", function(wx,wy)
- if tonumber(wx) > 0 then return wx .. " setlinewidth" else return wy .. " setlinewidth" end
- end)
- mptopdf.data = gsub(mptopdf.data,"([%d%.]+)%s+([%d%.]+)%s+dtransform%s+truncate%s+idtransform%s+setlinewidth%s+pop", function(wx,wy)
- if tonumber(wx) > 0 then return wx .. " setlinewidth" else return wy .. " setlinewidth" end
- end)
- end
-end
-
-function mptopdf.steps.convert()
- mptopdf.data = gsub(mptopdf.data,"%c%((.-)%) (.-) (.-) fshow", function(str,font,scale)
- mptopdf.texts[mptopdf.texts+1] = {mptopdf.steps.descape(str), font, scale}
- return "\n" .. #mptopdf.texts .. " textext"
- end)
- mptopdf.data = gsub(mptopdf.data,"%[%s*(.-)%s*%]", function(str)
- return gsub(str,"%s+"," ")
- end)
- local t
- mptopdf.data = gsub(mptopdf.data,"%s*([^%a]-)%s*(%a+)", function(args,cmd)
- if cmd == "textext" then
- t = mptopdf.texts[tonumber(args)]
- return "metapost.mps.textext(" .. "\"" .. t[2] .. "\"," .. t[3] .. ",\"" .. t[1] .. "\")\n"
- else
- return "metapost.mps." .. cmd .. "(" .. gsub(args," +",",") .. ")\n"
- end
- end)
-end
-
-function mptopdf.steps.process()
- assert(loadstring(mptopdf.data))() -- () runs the loaded chunk
-end
-
-function mptopdf.parsers.gsub()
- mptopdf.steps.strip()
- mptopdf.steps.cleanup()
- mptopdf.steps.convert()
- mptopdf.steps.process()
-end
-
--- end of old code
-
--- from lua to tex
-
-function mptopdf.pdfcode(str)
- context.pdfliteral(str) -- \\MPScode
-end
-
-function mptopdf.texcode(str)
- context(str)
-end
-
--- auxiliary functions
-
-function mptopdf.flushconcat()
- if mptopdf.stack.concat then
- mptopdf.pdfcode(concat(mptopdf.stack.concat," ") .. " cm")
- mptopdf.stack.concat = nil
- end
-end
-
-function mptopdf.flushpath(cmd)
- -- faster: no local function and loop
- if #mptopdf.stack.path > 0 then
- local path = { }
- if mptopdf.stack.concat then
- local sx, sy = mptopdf.stack.concat[1], mptopdf.stack.concat[4]
- local rx, ry = mptopdf.stack.concat[2], mptopdf.stack.concat[3]
- local tx, ty = mptopdf.stack.concat[5], mptopdf.stack.concat[6]
- local d = (sx*sy) - (rx*ry)
- local function mpconcat(px, py)
- return (sy*(px-tx)-ry*(py-ty))/d, (sx*(py-ty)-rx*(px-tx))/d
- end
- local stackpath = mptopdf.stack.path
- for k=1,#stackpath do
- local v = stackpath[k]
- v[1],v[2] = mpconcat(v[1],v[2])
- if #v == 7 then
- v[3],v[4] = mpconcat(v[3],v[4])
- v[5],v[6] = mpconcat(v[5],v[6])
- end
- path[#path+1] = concat(v," ")
- end
- else
- local stackpath = mptopdf.stack.path
- for k=1,#stackpath do
- path[#path+1] = concat(stackpath[k]," ")
- end
- end
- mptopdf.flushconcat()
- mptopdf.texcode("\\MPSpath{" .. concat(path," ") .. "}")
- if mptopdf.stack.close then
- mptopdf.texcode("\\MPScode{h " .. cmd .. "}")
- else
- mptopdf.texcode("\\MPScode{" .. cmd .."}")
- end
- end
- mptopdf.resetpath()
-end
-
-function mptopdf.loaded(name)
- local ok, n
- mptopdf.reset()
- ok, mptopdf.data, n = resolvers.loadbinfile(name, 'tex') -- we need a binary load !
- return ok
-end
-
-if not mptopdf.parse then
- function mptopdf.parse() end -- forward declaration
-end
-
-function mptopdf.convertmpstopdf(name)
- if mptopdf.loaded(name) then
- mptopdf.nofconverted = mptopdf.nofconverted + 1
- statistics.starttiming(mptopdf)
- mptopdf.parse()
- mptopdf.reset()
- statistics.stoptiming(mptopdf)
- else
- context("file " .. name .. " not found")
- end
-end
-
--- mp interface
-
-metapost.mps = metapost.mps or { }
-local mps = metapost.mps or { }
-
-function mps.creator(a, b, c)
- mptopdf.version = tonumber(b)
-end
-
-function mps.creationdate(a)
- mptopdf.date= a
-end
-
-function mps.newpath()
- mptopdf.stack.path = { }
-end
-
-function mps.boundingbox(llx, lly, urx, ury)
- mptopdf.texcode("\\MPSboundingbox{" .. llx .. "}{" .. lly .. "}{" .. urx .. "}{" .. ury .. "}")
-end
-
-function mps.moveto(x,y)
- mptopdf.stack.path[#mptopdf.stack.path+1] = {x,y,"m"}
-end
-
-function mps.curveto(ax, ay, bx, by, cx, cy)
- mptopdf.stack.path[#mptopdf.stack.path+1] = {ax,ay,bx,by,cx,cy,"c"}
-end
-
-function mps.lineto(x,y)
- mptopdf.stack.path[#mptopdf.stack.path+1] = {x,y,"l"}
-end
-
-function mps.rlineto(x,y)
- local dx, dy = 0, 0
- if #mptopdf.stack.path > 0 then
- dx, dy = mptopdf.stack.path[#mptopdf.stack.path][1], mptopdf.stack.path[#mptopdf.stack.path][2]
- end
- mptopdf.stack.path[#mptopdf.stack.path+1] = {dx,dy,"l"}
-end
-
-function mps.translate(tx,ty)
- mptopdf.pdfcode("1 0 0 0 1 " .. tx .. " " .. ty .. " cm")
-end
-
-function mps.scale(sx,sy)
- mptopdf.stack.concat = {sx,0,0,sy,0,0}
-end
-
-function mps.concat(sx, rx, ry, sy, tx, ty)
- mptopdf.stack.concat = {sx,rx,ry,sy,tx,ty}
-end
-
-function mps.setlinejoin(d)
- mptopdf.pdfcode(d .. " j")
-end
-
-function mps.setlinecap(d)
- mptopdf.pdfcode(d .. " J")
-end
-
-function mps.setmiterlimit(d)
- mptopdf.pdfcode(d .. " M")
-end
-
-function mps.gsave()
- mptopdf.pdfcode("q")
-end
-
-function mps.grestore()
- mptopdf.pdfcode("Q")
-end
-
-function mps.setdash(...)
- local n = select("#",...)
- mptopdf.pdfcode("[" .. concat({...}," ",1,n-1) .. "] " .. select(n,...) .. " d")
-end
-
-function mps.resetdash()
- mptopdf.pdfcode("[ ] 0 d")
-end
-
-function mps.setlinewidth(d)
- mptopdf.pdfcode(d .. " w")
-end
-
-function mps.closepath()
- mptopdf.stack.close = true
-end
-
-function mps.fill()
- mptopdf.flushpath('f')
-end
-
-function mps.stroke()
- mptopdf.flushpath('S')
-end
-
-function mps.both()
- mptopdf.flushpath('B')
-end
-
-function mps.clip()
- mptopdf.flushpath('W n')
-end
-
-function mps.textext(font, scale, str) -- old parser
- local dx, dy = 0, 0
- if #mptopdf.stack.path > 0 then
- dx, dy = mptopdf.stack.path[1][1], mptopdf.stack.path[1][2]
- end
- mptopdf.flushconcat()
- mptopdf.texcode("\\MPStextext{"..font.."}{"..scale.."}{"..str.."}{"..dx.."}{"..dy.."}")
- mptopdf.resetpath()
-end
-
---~ function mps.handletext(font,scale.str,dx,dy)
---~ local one, two = string.match(str, "^(%d+)::::(%d+)")
---~ if one and two then
---~ mptopdf.texcode("\\MPTOPDFtextext{"..font.."}{"..scale.."}{"..one.."}{"..two.."}{"..dx.."}{"..dy.."}")
---~ else
---~ mptopdf.texcode("\\MPTOPDFtexcode{"..font.."}{"..scale.."}{"..str.."}{"..dx.."}{"..dy.."}")
---~ end
---~ end
-
-function mps.setrgbcolor(r,g,b) -- extra check
- r, g = tonumber(r), tonumber(g) -- needed when we use lpeg
- if r == 0.0123 and g < 0.1 then
- mptopdf.texcode("\\MPSspecial{" .. g*10000 .. "}{" .. b*10000 .. "}")
- elseif r == 0.123 and g < 0.1 then
- mptopdf.texcode("\\MPSspecial{" .. g* 1000 .. "}{" .. b* 1000 .. "}")
- else
- mptopdf.texcode("\\MPSrgb{" .. r .. "}{" .. g .. "}{" .. b .. "}")
- end
-end
-
-function mps.setcmykcolor(c,m,y,k)
- mptopdf.texcode("\\MPScmyk{" .. c .. "}{" .. m .. "}{" .. y .. "}{" .. k .. "}")
-end
-
-function mps.setgray(s)
- mptopdf.texcode("\\MPSgray{" .. s .. "}")
-end
-
-function mps.specials(version,signal,factor) -- 2.0 123 1000
-end
-
-function mps.special(...) -- 7 1 0.5 1 0 0 1 3
- local n = select("#",...)
- mptopdf.texcode("\\MPSbegin\\MPSset{" .. concat({...},"}\\MPSset{",2,n) .. "}\\MPSend")
-end
-
-function mps.begindata()
-end
-
-function mps.enddata()
-end
-
-function mps.showpage()
-end
-
-mps.n = mps.newpath -- n
-mps.p = mps.closepath -- h
-mps.l = mps.lineto -- l
-mps.r = mps.rlineto -- r
-mps.m = mps.moveto -- m
-mps.c = mps.curveto -- c
-mps.hlw = mps.setlinewidth
-mps.vlw = mps.setlinewidth
-
-mps.C = mps.setcmykcolor -- k
-mps.G = mps.setgray -- g
-mps.R = mps.setrgbcolor -- rg
-
-mps.lj = mps.setlinejoin -- j
-mps.ml = mps.setmiterlimit -- M
-mps.lc = mps.setlinecap -- J
-mps.sd = mps.setdash -- d
-mps.rd = mps.resetdash
-
-mps.S = mps.stroke -- S
-mps.F = mps.fill -- f
-mps.B = mps.both -- B
-mps.W = mps.clip -- W
-
-mps.q = mps.gsave -- q
-mps.Q = mps.grestore -- Q
-
-mps.s = mps.scale -- (not in pdf)
-mps.t = mps.concat -- (not the same as pdf anyway)
-
-mps.P = mps.showpage
-
--- experimental
-
-function mps.attribute(id,value)
- mptopdf.texcode("\\attribute " .. id .. "=" .. value .. " ")
--- mptopdf.texcode("\\dompattribute{" .. id .. "}{" .. value .. "}")
-end
-
--- lpeg parser
-
--- The lpeg based parser is rather optimized for the kind of output
--- that MetaPost produces. It's my first real lpeg code, which may
--- show. Because the parser binds to functions, we define it last.
-
-do -- assumes \let\c\char
-
- local byte = string.byte
- local digit = lpeg.R("09")
- local spec = digit^2 * lpeg.P("::::") * digit^2
- local text = lpeg.Cc("{") * (
- lpeg.P("\\") * ( (digit * digit * digit) / function(n) return "c" .. tonumber(n,8) end) +
- lpeg.P(" ") / function(n) return "\\c32" end + -- never in new mp
- lpeg.P(1) / function(n) return "\\c" .. byte(n) end
- ) * lpeg.Cc("}")
- local package = lpeg.Cs(spec + text^0)
-
- function mps.fshow(str,font,scale) -- lpeg parser
- mps.textext(font,scale,lpegmatch(package,str))
- end
-
-end
-
-do
-
- local eol = lpeg.S('\r\n')^1
- local sp = lpeg.P(' ')^1
- local space = lpeg.S(' \r\n')^1
- local number = lpeg.S('0123456789.-+')^1
- local nonspace = lpeg.P(1-lpeg.S(' \r\n'))^1
-
- local cnumber = lpeg.C(number)
- local cstring = lpeg.C(nonspace)
-
- local specials = (lpeg.P("%%MetaPostSpecials:") * sp * (cstring * sp^0)^0 * eol) / mps.specials
- local special = (lpeg.P("%%MetaPostSpecial:") * sp * (cstring * sp^0)^0 * eol) / mps.special
- local boundingbox = (lpeg.P("%%BoundingBox:") * sp * (cnumber * sp^0)^4 * eol) / mps.boundingbox
- local highresboundingbox = (lpeg.P("%%HiResBoundingBox:") * sp * (cnumber * sp^0)^4 * eol) / mps.boundingbox
-
- local setup = lpeg.P("%%BeginSetup") * (1 - lpeg.P("%%EndSetup") )^1
- local prolog = lpeg.P("%%BeginProlog") * (1 - lpeg.P("%%EndProlog"))^1
- local comment = lpeg.P('%')^1 * (1 - eol)^1
-
- local curveto = ((cnumber * sp)^6 * lpeg.P("curveto") ) / mps.curveto
- local lineto = ((cnumber * sp)^2 * lpeg.P("lineto") ) / mps.lineto
- local rlineto = ((cnumber * sp)^2 * lpeg.P("rlineto") ) / mps.rlineto
- local moveto = ((cnumber * sp)^2 * lpeg.P("moveto") ) / mps.moveto
- local setrgbcolor = ((cnumber * sp)^3 * lpeg.P("setrgbcolor") ) / mps.setrgbcolor
- local setcmykcolor = ((cnumber * sp)^4 * lpeg.P("setcmykcolor") ) / mps.setcmykcolor
- local setgray = ((cnumber * sp)^1 * lpeg.P("setgray") ) / mps.setgray
- local newpath = ( lpeg.P("newpath") ) / mps.newpath
- local closepath = ( lpeg.P("closepath") ) / mps.closepath
- local fill = ( lpeg.P("fill") ) / mps.fill
- local stroke = ( lpeg.P("stroke") ) / mps.stroke
- local clip = ( lpeg.P("clip") ) / mps.clip
- local both = ( lpeg.P("gsave fill grestore")) / mps.both
- local showpage = ( lpeg.P("showpage") )
- local setlinejoin = ((cnumber * sp)^1 * lpeg.P("setlinejoin") ) / mps.setlinejoin
- local setlinecap = ((cnumber * sp)^1 * lpeg.P("setlinecap") ) / mps.setlinecap
- local setmiterlimit = ((cnumber * sp)^1 * lpeg.P("setmiterlimit") ) / mps.setmiterlimit
- local gsave = ( lpeg.P("gsave") ) / mps.gsave
- local grestore = ( lpeg.P("grestore") ) / mps.grestore
-
- local setdash = (lpeg.P("[") * (cnumber * sp^0)^0 * lpeg.P("]") * sp * cnumber * sp * lpeg.P("setdash")) / mps.setdash
- local concat = (lpeg.P("[") * (cnumber * sp^0)^6 * lpeg.P("]") * sp * lpeg.P("concat") ) / mps.concat
- local scale = ( (cnumber * sp^0)^6 * sp * lpeg.P("concat") ) / mps.concat
-
- local fshow = (lpeg.P("(") * lpeg.C((1-lpeg.P(")"))^1) * lpeg.P(")") * space * cstring * space * cnumber * space * lpeg.P("fshow")) / mps.fshow
- local fshow = (lpeg.P("(") *
- lpeg.Cs( ( lpeg.P("\\(")/"\\050" + lpeg.P("\\)")/"\\051" + (1-lpeg.P(")")) )^1 )
- * lpeg.P(")") * space * cstring * space * cnumber * space * lpeg.P("fshow")) / mps.fshow
-
- local setlinewidth_x = (lpeg.P("0") * sp * cnumber * sp * lpeg.P("dtransform truncate idtransform setlinewidth pop")) / mps.setlinewidth
- local setlinewidth_y = (cnumber * sp * lpeg.P("0 dtransform exch truncate exch idtransform pop setlinewidth") ) / mps.setlinewidth
-
- local c = ((cnumber * sp)^6 * lpeg.P("c") ) / mps.curveto -- ^6 very inefficient, ^1 ok too
- local l = ((cnumber * sp)^2 * lpeg.P("l") ) / mps.lineto
- local r = ((cnumber * sp)^2 * lpeg.P("r") ) / mps.rlineto
- local m = ((cnumber * sp)^2 * lpeg.P("m") ) / mps.moveto
- local vlw = ((cnumber * sp)^1 * lpeg.P("vlw")) / mps.setlinewidth
- local hlw = ((cnumber * sp)^1 * lpeg.P("hlw")) / mps.setlinewidth
-
- local R = ((cnumber * sp)^3 * lpeg.P("R") ) / mps.setrgbcolor
- local C = ((cnumber * sp)^4 * lpeg.P("C") ) / mps.setcmykcolor
- local G = ((cnumber * sp)^1 * lpeg.P("G") ) / mps.setgray
-
- local lj = ((cnumber * sp)^1 * lpeg.P("lj") ) / mps.setlinejoin
- local ml = ((cnumber * sp)^1 * lpeg.P("ml") ) / mps.setmiterlimit
- local lc = ((cnumber * sp)^1 * lpeg.P("lc") ) / mps.setlinecap
-
- local n = lpeg.P("n") / mps.newpath
- local p = lpeg.P("p") / mps.closepath
- local S = lpeg.P("S") / mps.stroke
- local F = lpeg.P("F") / mps.fill
- local B = lpeg.P("B") / mps.both
- local W = lpeg.P("W") / mps.clip
- local P = lpeg.P("P") / mps.showpage
-
- local q = lpeg.P("q") / mps.gsave
- local Q = lpeg.P("Q") / mps.grestore
-
- local sd = (lpeg.P("[") * (cnumber * sp^0)^0 * lpeg.P("]") * sp * cnumber * sp * lpeg.P("sd")) / mps.setdash
- local rd = ( lpeg.P("rd")) / mps.resetdash
-
- local s = ( (cnumber * sp^0)^2 * lpeg.P("s") ) / mps.scale
- local t = (lpeg.P("[") * (cnumber * sp^0)^6 * lpeg.P("]") * sp * lpeg.P("t") ) / mps.concat
-
- -- experimental
-
- local attribute = ((cnumber * sp)^2 * lpeg.P("attribute")) / mps.attribute
- local A = ((cnumber * sp)^2 * lpeg.P("A")) / mps.attribute
-
- local preamble = (
- prolog + setup +
- boundingbox + highresboundingbox + specials + special +
- comment
- )
-
- local procset = (
- lj + ml + lc +
- c + l + m + n + p + r +
- A +
- R + C + G +
- S + F + B + W +
- vlw + hlw +
- Q + q +
- sd + rd +
- t + s +
- fshow +
- P
- )
-
- local verbose = (
- curveto + lineto + moveto + newpath + closepath + rlineto +
- setrgbcolor + setcmykcolor + setgray +
- attribute +
- setlinejoin + setmiterlimit + setlinecap +
- stroke + fill + clip + both +
- setlinewidth_x + setlinewidth_y +
- gsave + grestore +
- concat + scale +
- fshow +
- setdash + -- no resetdash
- showpage
- )
-
- -- order matters in terms of speed / we could check for procset first
-
- local captures_old = ( space + verbose + preamble )^0
- local captures_new = ( space + procset + preamble + verbose )^0
-
- function mptopdf.parsers.lpeg()
- if find(mptopdf.data,"%%%%BeginResource: procset mpost") then
- lpegmatch(captures_new,mptopdf.data)
- else
- lpegmatch(captures_old,mptopdf.data)
- end
- end
-
-end
-
-mptopdf.parser = 'lpeg'
-
--- status info
-
-statistics.register("mps conversion time",function()
- local n = mptopdf.nofconverted
- if n > 0 then
- return format("%s seconds, %s conversions", statistics.elapsedtime(mptopdf),n)
- else
- return nil
- end
-end)
+if not modules then modules = { } end modules ['meta-pdf'] = {
+ version = 1.001,
+ comment = "companion to meta-pdf.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+if true then
+ return -- or os.exit()
+end
+
+-- This file contains the history of the converter. We keep it around as it
+-- relates to the development of luatex.
+
+-- This is the third version. Version 1 converted to Lua code,
+-- version 2 gsubbed the file into TeX code, and version 3 uses
+-- the new lpeg functionality and streams the result into TeX.
+
+-- We will move old stuff to edu.
+
+--~ old lpeg 0.4 lpeg 0.5
+--~ 100 times test graphic 2.45 (T:1.07) 0.72 (T:0.24) 0.580 (0.560 no table) -- 0.54 optimized for one space (T:0.19)
+--~ 100 times big graphic 10.44 4.30/3.35 nogb 2.914 (2.050 no table) -- 1.99 optimized for one space (T:0.85)
+--~ 500 times test graphic T:1.29 T:1.16 (T:1.10 no table) -- T:1.10
+
+-- only needed for mp output on disk
+
+local concat, format, find, gsub, gmatch = table.concat, string.format, string.find, string.gsub, string.gmatch
+local tostring, tonumber, select = tostring, tonumber, select
+local lpegmatch = lpeg.match
+
+local metapost = metapost
+
+metapost.mptopdf = metapost.mptopdf or { }
+local mptopdf = metapost.mptopdf
+
+mptopdf.parsers = { }
+mptopdf.parser = 'none'
+mptopdf.nofconverted = 0
+
+function mptopdf.reset()
+ mptopdf.data = ""
+ mptopdf.path = { }
+ mptopdf.stack = { }
+ mptopdf.texts = { }
+ mptopdf.version = 0
+ mptopdf.shortcuts = false
+ mptopdf.resetpath()
+end
+
+function mptopdf.resetpath()
+ mptopdf.stack.close = false
+ mptopdf.stack.path = { }
+ mptopdf.stack.concat = nil
+ mptopdf.stack.special = false
+end
+
+mptopdf.reset()
+
+function mptopdf.parsers.none()
+ -- no parser set
+end
+
+function mptopdf.parse()
+ mptopdf.parsers[mptopdf.parser]()
+end
+
+-- old code
+
+mptopdf.steps = { }
+
+mptopdf.descapes = {
+ ['('] = "\\\\char40 ",
+ [')'] = "\\\\char41 ",
+ ['"'] = "\\\\char92 "
+}
+
+function mptopdf.descape(str)
+ str = gsub(str,"\\(%d%d%d)",function(n)
+ return "\\char" .. tonumber(n,8) .. " "
+ end)
+ return gsub(str,"\\([%(%)\\])",mptopdf.descapes)
+end
+
+function mptopdf.steps.descape(str)
+ str = gsub(str,"\\(%d%d%d)",function(n)
+ return "\\\\char" .. tonumber(n,8) .. " "
+ end)
+ return gsub(str,"\\([%(%)\\])",mptopdf.descapes)
+end
+
+function mptopdf.steps.strip() -- .3 per expr
+ mptopdf.data = gsub(mptopdf.data,"^(.-)%%+Page:.-%c+(.*)%s+%a+%s+%%+EOF.*$", function(preamble, graphic)
+ local bbox = "0 0 0 0"
+ for b in gmatch(preamble,"%%%%%a+oundingBox: +(.-)%c+") do
+ bbox = b
+ end
+ local name, version = gmatch(preamble,"%%%%Creator: +(.-) +(.-) ")
+ mptopdf.version = tostring(version or "0")
+ if find(preamble,"/hlw{0 dtransform") then
+ mptopdf.shortcuts = true
+ end
+ -- the boundingbox specification needs to come before data, well, not really
+ return bbox .. " boundingbox\n" .. "\nbegindata\n" .. graphic .. "\nenddata\n"
+ end, 1)
+ mptopdf.data = gsub(mptopdf.data,"%%%%MetaPostSpecials: +(.-)%c+", "%1 specials\n", 1)
+ mptopdf.data = gsub(mptopdf.data,"%%%%MetaPostSpecial: +(.-)%c+", "%1 special\n")
+ mptopdf.data = gsub(mptopdf.data,"%%.-%c+", "")
+end
+
+function mptopdf.steps.cleanup()
+ if not mptopdf.shortcuts then
+ mptopdf.data = gsub(mptopdf.data,"gsave%s+fill%s+grestore%s+stroke", "both")
+ mptopdf.data = gsub(mptopdf.data,"([%d%.]+)%s+([%d%.]+)%s+dtransform%s+exch%s+truncate%s+exch%s+idtransform%s+pop%s+setlinewidth", function(wx,wy)
+ if tonumber(wx) > 0 then return wx .. " setlinewidth" else return wy .. " setlinewidth" end
+ end)
+ mptopdf.data = gsub(mptopdf.data,"([%d%.]+)%s+([%d%.]+)%s+dtransform%s+truncate%s+idtransform%s+setlinewidth%s+pop", function(wx,wy)
+ if tonumber(wx) > 0 then return wx .. " setlinewidth" else return wy .. " setlinewidth" end
+ end)
+ end
+end
+
+function mptopdf.steps.convert()
+ mptopdf.data = gsub(mptopdf.data,"%c%((.-)%) (.-) (.-) fshow", function(str,font,scale)
+ mptopdf.texts[mptopdf.texts+1] = {mptopdf.steps.descape(str), font, scale}
+ return "\n" .. #mptopdf.texts .. " textext"
+ end)
+ mptopdf.data = gsub(mptopdf.data,"%[%s*(.-)%s*%]", function(str)
+ return gsub(str,"%s+"," ")
+ end)
+ local t
+ mptopdf.data = gsub(mptopdf.data,"%s*([^%a]-)%s*(%a+)", function(args,cmd)
+ if cmd == "textext" then
+ t = mptopdf.texts[tonumber(args)]
+ return "metapost.mps.textext(" .. "\"" .. t[2] .. "\"," .. t[3] .. ",\"" .. t[1] .. "\")\n"
+ else
+ return "metapost.mps." .. cmd .. "(" .. gsub(args," +",",") .. ")\n"
+ end
+ end)
+end
+
+function mptopdf.steps.process()
+ assert(loadstring(mptopdf.data))() -- () runs the loaded chunk
+end
+
+function mptopdf.parsers.gsub()
+ mptopdf.steps.strip()
+ mptopdf.steps.cleanup()
+ mptopdf.steps.convert()
+ mptopdf.steps.process()
+end
+
+-- end of old code
+
+-- from lua to tex
+
+function mptopdf.pdfcode(str)
+ context.pdfliteral(str) -- \\MPScode
+end
+
+function mptopdf.texcode(str)
+ context(str)
+end
+
+-- auxiliary functions
+
+function mptopdf.flushconcat()
+ if mptopdf.stack.concat then
+ mptopdf.pdfcode(concat(mptopdf.stack.concat," ") .. " cm")
+ mptopdf.stack.concat = nil
+ end
+end
+
+function mptopdf.flushpath(cmd)
+ -- faster: no local function and loop
+ if #mptopdf.stack.path > 0 then
+ local path = { }
+ if mptopdf.stack.concat then
+ local sx, sy = mptopdf.stack.concat[1], mptopdf.stack.concat[4]
+ local rx, ry = mptopdf.stack.concat[2], mptopdf.stack.concat[3]
+ local tx, ty = mptopdf.stack.concat[5], mptopdf.stack.concat[6]
+ local d = (sx*sy) - (rx*ry)
+ local function mpconcat(px, py)
+ return (sy*(px-tx)-ry*(py-ty))/d, (sx*(py-ty)-rx*(px-tx))/d
+ end
+ local stackpath = mptopdf.stack.path
+ for k=1,#stackpath do
+ local v = stackpath[k]
+ v[1],v[2] = mpconcat(v[1],v[2])
+ if #v == 7 then
+ v[3],v[4] = mpconcat(v[3],v[4])
+ v[5],v[6] = mpconcat(v[5],v[6])
+ end
+ path[#path+1] = concat(v," ")
+ end
+ else
+ local stackpath = mptopdf.stack.path
+ for k=1,#stackpath do
+ path[#path+1] = concat(stackpath[k]," ")
+ end
+ end
+ mptopdf.flushconcat()
+ mptopdf.texcode("\\MPSpath{" .. concat(path," ") .. "}")
+ if mptopdf.stack.close then
+ mptopdf.texcode("\\MPScode{h " .. cmd .. "}")
+ else
+ mptopdf.texcode("\\MPScode{" .. cmd .."}")
+ end
+ end
+ mptopdf.resetpath()
+end
+
+function mptopdf.loaded(name)
+ local ok, n
+ mptopdf.reset()
+ ok, mptopdf.data, n = resolvers.loadbinfile(name, 'tex') -- we need a binary load !
+ return ok
+end
+
+if not mptopdf.parse then
+ function mptopdf.parse() end -- forward declaration
+end
+
+function mptopdf.convertmpstopdf(name)
+ if mptopdf.loaded(name) then
+ mptopdf.nofconverted = mptopdf.nofconverted + 1
+ statistics.starttiming(mptopdf)
+ mptopdf.parse()
+ mptopdf.reset()
+ statistics.stoptiming(mptopdf)
+ else
+ context("file " .. name .. " not found")
+ end
+end
+
+-- mp interface
+
+metapost.mps = metapost.mps or { }
+local mps = metapost.mps or { }
+
+function mps.creator(a, b, c)
+ mptopdf.version = tonumber(b)
+end
+
+function mps.creationdate(a)
+ mptopdf.date= a
+end
+
+function mps.newpath()
+ mptopdf.stack.path = { }
+end
+
+function mps.boundingbox(llx, lly, urx, ury)
+ mptopdf.texcode("\\MPSboundingbox{" .. llx .. "}{" .. lly .. "}{" .. urx .. "}{" .. ury .. "}")
+end
+
+function mps.moveto(x,y)
+ mptopdf.stack.path[#mptopdf.stack.path+1] = {x,y,"m"}
+end
+
+function mps.curveto(ax, ay, bx, by, cx, cy)
+ mptopdf.stack.path[#mptopdf.stack.path+1] = {ax,ay,bx,by,cx,cy,"c"}
+end
+
+function mps.lineto(x,y)
+ mptopdf.stack.path[#mptopdf.stack.path+1] = {x,y,"l"}
+end
+
+function mps.rlineto(x,y)
+ local dx, dy = 0, 0
+ if #mptopdf.stack.path > 0 then
+ dx, dy = mptopdf.stack.path[#mptopdf.stack.path][1], mptopdf.stack.path[#mptopdf.stack.path][2]
+ end
+ mptopdf.stack.path[#mptopdf.stack.path+1] = {dx,dy,"l"}
+end
+
+function mps.translate(tx,ty)
+ mptopdf.pdfcode("1 0 0 0 1 " .. tx .. " " .. ty .. " cm")
+end
+
+function mps.scale(sx,sy)
+ mptopdf.stack.concat = {sx,0,0,sy,0,0}
+end
+
+function mps.concat(sx, rx, ry, sy, tx, ty)
+ mptopdf.stack.concat = {sx,rx,ry,sy,tx,ty}
+end
+
+function mps.setlinejoin(d)
+ mptopdf.pdfcode(d .. " j")
+end
+
+function mps.setlinecap(d)
+ mptopdf.pdfcode(d .. " J")
+end
+
+function mps.setmiterlimit(d)
+ mptopdf.pdfcode(d .. " M")
+end
+
+function mps.gsave()
+ mptopdf.pdfcode("q")
+end
+
+function mps.grestore()
+ mptopdf.pdfcode("Q")
+end
+
+function mps.setdash(...)
+ local n = select("#",...)
+ mptopdf.pdfcode("[" .. concat({...}," ",1,n-1) .. "] " .. select(n,...) .. " d")
+end
+
+function mps.resetdash()
+ mptopdf.pdfcode("[ ] 0 d")
+end
+
+function mps.setlinewidth(d)
+ mptopdf.pdfcode(d .. " w")
+end
+
+function mps.closepath()
+ mptopdf.stack.close = true
+end
+
+function mps.fill()
+ mptopdf.flushpath('f')
+end
+
+function mps.stroke()
+ mptopdf.flushpath('S')
+end
+
+function mps.both()
+ mptopdf.flushpath('B')
+end
+
+function mps.clip()
+ mptopdf.flushpath('W n')
+end
+
+function mps.textext(font, scale, str) -- old parser
+ local dx, dy = 0, 0
+ if #mptopdf.stack.path > 0 then
+ dx, dy = mptopdf.stack.path[1][1], mptopdf.stack.path[1][2]
+ end
+ mptopdf.flushconcat()
+ mptopdf.texcode("\\MPStextext{"..font.."}{"..scale.."}{"..str.."}{"..dx.."}{"..dy.."}")
+ mptopdf.resetpath()
+end
+
+--~ function mps.handletext(font,scale.str,dx,dy)
+--~ local one, two = string.match(str, "^(%d+)::::(%d+)")
+--~ if one and two then
+--~ mptopdf.texcode("\\MPTOPDFtextext{"..font.."}{"..scale.."}{"..one.."}{"..two.."}{"..dx.."}{"..dy.."}")
+--~ else
+--~ mptopdf.texcode("\\MPTOPDFtexcode{"..font.."}{"..scale.."}{"..str.."}{"..dx.."}{"..dy.."}")
+--~ end
+--~ end
+
+function mps.setrgbcolor(r,g,b) -- extra check
+ r, g = tonumber(r), tonumber(g) -- needed when we use lpeg
+ if r == 0.0123 and g < 0.1 then
+ mptopdf.texcode("\\MPSspecial{" .. g*10000 .. "}{" .. b*10000 .. "}")
+ elseif r == 0.123 and g < 0.1 then
+ mptopdf.texcode("\\MPSspecial{" .. g* 1000 .. "}{" .. b* 1000 .. "}")
+ else
+ mptopdf.texcode("\\MPSrgb{" .. r .. "}{" .. g .. "}{" .. b .. "}")
+ end
+end
+
+function mps.setcmykcolor(c,m,y,k)
+ mptopdf.texcode("\\MPScmyk{" .. c .. "}{" .. m .. "}{" .. y .. "}{" .. k .. "}")
+end
+
+function mps.setgray(s)
+ mptopdf.texcode("\\MPSgray{" .. s .. "}")
+end
+
+function mps.specials(version,signal,factor) -- 2.0 123 1000
+end
+
+function mps.special(...) -- 7 1 0.5 1 0 0 1 3
+ local n = select("#",...)
+ mptopdf.texcode("\\MPSbegin\\MPSset{" .. concat({...},"}\\MPSset{",2,n) .. "}\\MPSend")
+end
+
+function mps.begindata()
+end
+
+function mps.enddata()
+end
+
+function mps.showpage()
+end
+
+mps.n = mps.newpath -- n
+mps.p = mps.closepath -- h
+mps.l = mps.lineto -- l
+mps.r = mps.rlineto -- r
+mps.m = mps.moveto -- m
+mps.c = mps.curveto -- c
+mps.hlw = mps.setlinewidth
+mps.vlw = mps.setlinewidth
+
+mps.C = mps.setcmykcolor -- k
+mps.G = mps.setgray -- g
+mps.R = mps.setrgbcolor -- rg
+
+mps.lj = mps.setlinejoin -- j
+mps.ml = mps.setmiterlimit -- M
+mps.lc = mps.setlinecap -- J
+mps.sd = mps.setdash -- d
+mps.rd = mps.resetdash
+
+mps.S = mps.stroke -- S
+mps.F = mps.fill -- f
+mps.B = mps.both -- B
+mps.W = mps.clip -- W
+
+mps.q = mps.gsave -- q
+mps.Q = mps.grestore -- Q
+
+mps.s = mps.scale -- (not in pdf)
+mps.t = mps.concat -- (not the same as pdf anyway)
+
+mps.P = mps.showpage
+
+-- experimental
+
+function mps.attribute(id,value)
+ mptopdf.texcode("\\attribute " .. id .. "=" .. value .. " ")
+-- mptopdf.texcode("\\dompattribute{" .. id .. "}{" .. value .. "}")
+end
+
+-- lpeg parser
+
+-- The lpeg based parser is rather optimized for the kind of output
+-- that MetaPost produces. It's my first real lpeg code, which may
+-- show. Because the parser binds to functions, we define it last.
+
+do -- assumes \let\c\char
+
+ local byte = string.byte
+ local digit = lpeg.R("09")
+ local spec = digit^2 * lpeg.P("::::") * digit^2
+ local text = lpeg.Cc("{") * (
+ lpeg.P("\\") * ( (digit * digit * digit) / function(n) return "c" .. tonumber(n,8) end) +
+ lpeg.P(" ") / function(n) return "\\c32" end + -- never in new mp
+ lpeg.P(1) / function(n) return "\\c" .. byte(n) end
+ ) * lpeg.Cc("}")
+ local package = lpeg.Cs(spec + text^0)
+
+ function mps.fshow(str,font,scale) -- lpeg parser
+ mps.textext(font,scale,lpegmatch(package,str))
+ end
+
+end
+
+do
+
+ local eol = lpeg.S('\r\n')^1
+ local sp = lpeg.P(' ')^1
+ local space = lpeg.S(' \r\n')^1
+ local number = lpeg.S('0123456789.-+')^1
+ local nonspace = lpeg.P(1-lpeg.S(' \r\n'))^1
+
+ local cnumber = lpeg.C(number)
+ local cstring = lpeg.C(nonspace)
+
+ local specials = (lpeg.P("%%MetaPostSpecials:") * sp * (cstring * sp^0)^0 * eol) / mps.specials
+ local special = (lpeg.P("%%MetaPostSpecial:") * sp * (cstring * sp^0)^0 * eol) / mps.special
+ local boundingbox = (lpeg.P("%%BoundingBox:") * sp * (cnumber * sp^0)^4 * eol) / mps.boundingbox
+ local highresboundingbox = (lpeg.P("%%HiResBoundingBox:") * sp * (cnumber * sp^0)^4 * eol) / mps.boundingbox
+
+ local setup = lpeg.P("%%BeginSetup") * (1 - lpeg.P("%%EndSetup") )^1
+ local prolog = lpeg.P("%%BeginProlog") * (1 - lpeg.P("%%EndProlog"))^1
+ local comment = lpeg.P('%')^1 * (1 - eol)^1
+
+ local curveto = ((cnumber * sp)^6 * lpeg.P("curveto") ) / mps.curveto
+ local lineto = ((cnumber * sp)^2 * lpeg.P("lineto") ) / mps.lineto
+ local rlineto = ((cnumber * sp)^2 * lpeg.P("rlineto") ) / mps.rlineto
+ local moveto = ((cnumber * sp)^2 * lpeg.P("moveto") ) / mps.moveto
+ local setrgbcolor = ((cnumber * sp)^3 * lpeg.P("setrgbcolor") ) / mps.setrgbcolor
+ local setcmykcolor = ((cnumber * sp)^4 * lpeg.P("setcmykcolor") ) / mps.setcmykcolor
+ local setgray = ((cnumber * sp)^1 * lpeg.P("setgray") ) / mps.setgray
+ local newpath = ( lpeg.P("newpath") ) / mps.newpath
+ local closepath = ( lpeg.P("closepath") ) / mps.closepath
+ local fill = ( lpeg.P("fill") ) / mps.fill
+ local stroke = ( lpeg.P("stroke") ) / mps.stroke
+ local clip = ( lpeg.P("clip") ) / mps.clip
+ local both = ( lpeg.P("gsave fill grestore")) / mps.both
+ local showpage = ( lpeg.P("showpage") )
+ local setlinejoin = ((cnumber * sp)^1 * lpeg.P("setlinejoin") ) / mps.setlinejoin
+ local setlinecap = ((cnumber * sp)^1 * lpeg.P("setlinecap") ) / mps.setlinecap
+ local setmiterlimit = ((cnumber * sp)^1 * lpeg.P("setmiterlimit") ) / mps.setmiterlimit
+ local gsave = ( lpeg.P("gsave") ) / mps.gsave
+ local grestore = ( lpeg.P("grestore") ) / mps.grestore
+
+ local setdash = (lpeg.P("[") * (cnumber * sp^0)^0 * lpeg.P("]") * sp * cnumber * sp * lpeg.P("setdash")) / mps.setdash
+ local concat = (lpeg.P("[") * (cnumber * sp^0)^6 * lpeg.P("]") * sp * lpeg.P("concat") ) / mps.concat
+ local scale = ( (cnumber * sp^0)^6 * sp * lpeg.P("concat") ) / mps.concat
+
+ local fshow = (lpeg.P("(") * lpeg.C((1-lpeg.P(")"))^1) * lpeg.P(")") * space * cstring * space * cnumber * space * lpeg.P("fshow")) / mps.fshow
+ local fshow = (lpeg.P("(") *
+ lpeg.Cs( ( lpeg.P("\\(")/"\\050" + lpeg.P("\\)")/"\\051" + (1-lpeg.P(")")) )^1 )
+ * lpeg.P(")") * space * cstring * space * cnumber * space * lpeg.P("fshow")) / mps.fshow
+
+ local setlinewidth_x = (lpeg.P("0") * sp * cnumber * sp * lpeg.P("dtransform truncate idtransform setlinewidth pop")) / mps.setlinewidth
+ local setlinewidth_y = (cnumber * sp * lpeg.P("0 dtransform exch truncate exch idtransform pop setlinewidth") ) / mps.setlinewidth
+
+ local c = ((cnumber * sp)^6 * lpeg.P("c") ) / mps.curveto -- ^6 very inefficient, ^1 ok too
+ local l = ((cnumber * sp)^2 * lpeg.P("l") ) / mps.lineto
+ local r = ((cnumber * sp)^2 * lpeg.P("r") ) / mps.rlineto
+ local m = ((cnumber * sp)^2 * lpeg.P("m") ) / mps.moveto
+ local vlw = ((cnumber * sp)^1 * lpeg.P("vlw")) / mps.setlinewidth
+ local hlw = ((cnumber * sp)^1 * lpeg.P("hlw")) / mps.setlinewidth
+
+ local R = ((cnumber * sp)^3 * lpeg.P("R") ) / mps.setrgbcolor
+ local C = ((cnumber * sp)^4 * lpeg.P("C") ) / mps.setcmykcolor
+ local G = ((cnumber * sp)^1 * lpeg.P("G") ) / mps.setgray
+
+ local lj = ((cnumber * sp)^1 * lpeg.P("lj") ) / mps.setlinejoin
+ local ml = ((cnumber * sp)^1 * lpeg.P("ml") ) / mps.setmiterlimit
+ local lc = ((cnumber * sp)^1 * lpeg.P("lc") ) / mps.setlinecap
+
+ local n = lpeg.P("n") / mps.newpath
+ local p = lpeg.P("p") / mps.closepath
+ local S = lpeg.P("S") / mps.stroke
+ local F = lpeg.P("F") / mps.fill
+ local B = lpeg.P("B") / mps.both
+ local W = lpeg.P("W") / mps.clip
+ local P = lpeg.P("P") / mps.showpage
+
+ local q = lpeg.P("q") / mps.gsave
+ local Q = lpeg.P("Q") / mps.grestore
+
+ local sd = (lpeg.P("[") * (cnumber * sp^0)^0 * lpeg.P("]") * sp * cnumber * sp * lpeg.P("sd")) / mps.setdash
+ local rd = ( lpeg.P("rd")) / mps.resetdash
+
+ local s = ( (cnumber * sp^0)^2 * lpeg.P("s") ) / mps.scale
+ local t = (lpeg.P("[") * (cnumber * sp^0)^6 * lpeg.P("]") * sp * lpeg.P("t") ) / mps.concat
+
+ -- experimental
+
+ local attribute = ((cnumber * sp)^2 * lpeg.P("attribute")) / mps.attribute
+ local A = ((cnumber * sp)^2 * lpeg.P("A")) / mps.attribute
+
+ local preamble = (
+ prolog + setup +
+ boundingbox + highresboundingbox + specials + special +
+ comment
+ )
+
+ local procset = (
+ lj + ml + lc +
+ c + l + m + n + p + r +
+ A +
+ R + C + G +
+ S + F + B + W +
+ vlw + hlw +
+ Q + q +
+ sd + rd +
+ t + s +
+ fshow +
+ P
+ )
+
+ local verbose = (
+ curveto + lineto + moveto + newpath + closepath + rlineto +
+ setrgbcolor + setcmykcolor + setgray +
+ attribute +
+ setlinejoin + setmiterlimit + setlinecap +
+ stroke + fill + clip + both +
+ setlinewidth_x + setlinewidth_y +
+ gsave + grestore +
+ concat + scale +
+ fshow +
+ setdash + -- no resetdash
+ showpage
+ )
+
+ -- order matters in terms of speed / we could check for procset first
+
+ local captures_old = ( space + verbose + preamble )^0
+ local captures_new = ( space + procset + preamble + verbose )^0
+
+ function mptopdf.parsers.lpeg()
+ if find(mptopdf.data,"%%%%BeginResource: procset mpost") then
+ lpegmatch(captures_new,mptopdf.data)
+ else
+ lpegmatch(captures_old,mptopdf.data)
+ end
+ end
+
+end
+
+mptopdf.parser = 'lpeg'
+
+-- status info
+
+statistics.register("mps conversion time",function()
+ local n = mptopdf.nofconverted
+ if n > 0 then
+ return format("%s seconds, %s conversions", statistics.elapsedtime(mptopdf),n)
+ else
+ return nil
+ end
+end)