diff options
author | Karl Berry <karl@freefriends.org> | 2013-05-12 22:38:13 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2013-05-12 22:38:13 +0000 |
commit | 8907d5d0eb9a9b630b813f7d0ae7e406a1c4cb01 (patch) | |
tree | c075608e0fa6fbccc05bda8a8df1145ecca49cc9 /Master/texmf-dist/tex/luatex | |
parent | 0d9028560da113b542d8cd721f3164a00d492de2 (diff) |
luamplib (12may13)
git-svn-id: svn://tug.org/texlive/trunk@30423 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/luatex')
-rw-r--r-- | Master/texmf-dist/tex/luatex/luamplib/luamplib.lua | 314 | ||||
-rw-r--r-- | Master/texmf-dist/tex/luatex/luamplib/luamplib.sty | 68 |
2 files changed, 272 insertions, 110 deletions
diff --git a/Master/texmf-dist/tex/luatex/luamplib/luamplib.lua b/Master/texmf-dist/tex/luatex/luamplib/luamplib.lua index 71c45d440d7..45e7ceff864 100644 --- a/Master/texmf-dist/tex/luatex/luamplib/luamplib.lua +++ b/Master/texmf-dist/tex/luatex/luamplib/luamplib.lua @@ -8,31 +8,47 @@ -- -- See source file 'luamplib.dtx' for licencing and contact information. -- -module('luamplib', package.seeall) + +luamplib = luamplib or { } + + +local luamplib = luamplib +luamplib.showlog = luamplib.showlog or false +luamplib.lastlog = "" + local err, warn, info, log = luatexbase.provides_module({ name = "luamplib", - version = 1.09, - date = "2011/11/09", + version = 2.00, + date = "2013/05/07", description = "Lua package to typeset Metapost with LuaTeX's MPLib.", }) -local function term(...) - texio.write_nl('term', 'luamplib: ' .. string.format(...)) -end -local format, concat, abs = string.format, table.concat, math.abs +local format, abs = string.format, math.abs -local data = "" +local stringgsub = string.gsub +local stringfind = string.find +local stringmatch = string.match +local stringgmatch = string.gmatch +local tableconcat = table.concat +local texsprint = tex.sprint -local function resetdata() - data = "" -end -function addline(line) - data = data .. '\n' .. line -end -function processlines() - process(data) - resetdata() +local mplib = require ('mplib') +local kpse = require ('kpse') + +local file = file +if not file then + + + file = { } + + function file.replacesuffix(filename, suffix) + return (stringgsub(filename,"%.[%a%d]+$","")) .. "." .. suffix + end + + function file.stripsuffix(filename) + return (stringgsub(filename,"%.[%a%d]+$","")) + end end local mpkpse = kpse.new("luatex", "mpost") @@ -44,111 +60,177 @@ local function finder(name, mode, ftype) return mpkpse:find_file(name,ftype) end end +luamplib.finder = finder -local currentformat = "plain" -function setformat (name) - currentformat = name +function luamplib.resetlastlog() + luamplib.lastlog = "" end -function load() - local mpx = mplib.new { - find_file = finder, - ini_version = true, - } - mpx:execute(format("input %s ;", currentformat)) - return mpx +local mplibone = tonumber(mplib.version()) <= 1.50 + +if mplibone then + + luamplib.make = luamplib.make or function(name,mem_name,dump) + local t = os.clock() + local mpx = mplib.new { + ini_version = true, + find_file = luamplib.finder, + job_name = file.stripsuffix(name) + } + mpx:execute(format("input %s ;",name)) + if dump then + mpx:execute("dump ;") + info("format %s made and dumped for %s in %0.3f seconds",mem_name,name,os.clock()-t) + else + info("%s read in %0.3f seconds",name,os.clock()-t) + end + return mpx + end + + function luamplib.load(name) + local mem_name = file.replacesuffix(name,"mem") + local mpx = mplib.new { + ini_version = false, + mem_name = mem_name, + find_file = luamplib.finder + } + if not mpx and type(luamplib.make) == "function" then + -- when i have time i'll locate the format and dump + mpx = luamplib.make(name,mem_name) + end + if mpx then + info("using format %s",mem_name,false) + return mpx, nil + else + return nil, { status = 99, error = "out of memory or invalid format" } + end + end + +else + + + local preamble = [[ + boolean mplib ; mplib := true ; + let dump = endinput ; + input %s ; + ]] + + luamplib.make = luamplib.make or function() + end + + function luamplib.load(name) + local mpx = mplib.new { + ini_version = true, + find_file = luamplib.finder, + } + local result + if not mpx then + result = { status = 99, error = "out of memory"} + else + result = mpx:execute(format(preamble, file.replacesuffix(name,"mp"))) + end + luamplib.reporterror(result) + return mpx, result + end + +end + +local currentformat = "plain" + +local function setformat (name) --- used in .sty + currentformat = name end +luamplib.setformat = setformat -function report(result) +luamplib.reporterror = function (result) if not result then - err("no result object") + err("no result object returned") elseif result.status > 0 then - local t, e, l, f = result.term, result.error, result.log - if l then - log(l) - end + local t, e, l = result.term, result.error, result.log if t then - term(t) + info(t) end if e then - if result.status == 1 then - warn(e) - else - err(e) - end + err(e) end - if not t and not e and not l then - if result.status == 1 then - warn("unknown error, no error, terminal or log messages, maybe missing beginfig/endfig") - else - err("unknown error, no error, terminal or log messages, maybe missing beginfig/endfig") - end + if not t and not e and l then + luamplib.lastlog = luamplib.lastlog .. "\n " .. l + log(l) + else + err("unknown, no error, terminal or log messages") end else - return true + return false end - return false + return true end -function process(data) +local function process_indeed (mpx, data) local converted, result = false, {} - local mpx = load() + local mpx = luamplib.load(mpx) if mpx and data then local result = mpx:execute(data) - if report(result) then - if result.fig then - converted = convert(result) - else - warn("no figure output") - end + if not result then + err("no result object returned") + elseif result.status > 0 then + err("%s",(result.term or "no-term") .. "\n" .. (result.error or "no-error")) + elseif luamplib.showlog then + luamplib.lastlog = luamplib.lastlog .. "\n" .. result.term + info("%s",result.term or "no-term") + elseif result.fig then + converted = luamplib.convert(result) + else + err("unknown error, maybe no beginfig/endfig") end else err("Mem file unloadable. Maybe generated with a different version of mplib?") end return converted, result end +local process = function (data) + return process_indeed(currentformat, data) +end +luamplib.process = process local function getobjects(result,figure,f) return figure:objects() end -function convert(result, flusher) - flush(result, flusher) +local function convert(result, flusher) + luamplib.flush(result, flusher) return true -- done end +luamplib.convert = convert local function pdf_startfigure(n,llx,lly,urx,ury) - tex.sprint(format("\\mplibstarttoPDF{%s}{%s}{%s}{%s}",llx,lly,urx,ury)) + texsprint(format("\\mplibstarttoPDF{%f}{%f}{%f}{%f}",llx,lly,urx,ury)) end local function pdf_stopfigure() - tex.sprint("\\mplibstoptoPDF") + texsprint("\\mplibstoptoPDF") end -function pdf_literalcode(fmt,...) -- table - tex.sprint(format("\\mplibtoPDF{%s}",format(fmt,...))) +local function pdf_literalcode(fmt,...) -- table + texsprint(format("\\mplibtoPDF{%s}",format(fmt,...))) end +luamplib.pdf_literalcode = pdf_literalcode -function pdf_textfigure(font,size,text,width,height,depth) +local function pdf_textfigure(font,size,text,width,height,depth) text = text:gsub(".","\\hbox{%1}") -- kerning happens in metapost - tex.sprint(format("\\mplibtextext{%s}{%s}{%s}{%s}{%s}",font,size,text,0,-( 7200/ 7227)/65536*depth)) + texsprint(format("\\mplibtextext{%s}{%f}{%s}{%s}{%f}",font,size,text,0,-( 7200/ 7227)/65536*depth)) end +luamplib.pdf_textfigure = pdf_textfigure local bend_tolerance = 131/65536 local rx, sx, sy, ry, tx, ty, divider = 1, 0, 0, 1, 0, 0, 1 local function pen_characteristics(object) - if mplib.pen_info then - local t = mplib.pen_info(object) - rx, ry, sx, sy, tx, ty = t.rx, t.ry, t.sx, t.sy, t.tx, t.ty - divider = sx*sy - rx*ry - return not (sx==1 and rx==0 and ry==0 and sy==1 and tx==0 and ty==0), t.width - else - rx, sx, sy, ry, tx, ty, divider = 1, 0, 0, 1, 0, 0, 1 - return false, 1 - end + local t = mplib.pen_info(object) + rx, ry, sx, sy, tx, ty = t.rx, t.ry, t.sx, t.sy, t.tx, t.ty + divider = sx*sy - rx*ry + return not (sx==1 and rx==0 and ry==0 and sy==1 and tx==0 and ty==0), t.width end local function concat(px, py) -- no tx, ty here @@ -227,15 +309,77 @@ local function flushconcatpath(path,open) return t end -function flush(result,flusher) + +local mplibcodepreamble = [[ +vardef textext@#(expr n, w, h, d) = + image( + addto currentpicture doublepath unitsquare + xscaled w + yscaled (h+d) + withprescript "%%textext:"&decimal n&":"&decimal w&":"&decimal(h+d); + ) +enddef; +]] + +local factor = 65536*(7227/7200) + +local function settexboxes (data) + local i = tex.count[14] -- newbox register + for _,c,_ in stringgmatch(data,"(%A)btex(%A.-%A)etex(%A)") do + i = i + 1 + c = stringgsub(c,"^%s*(.-)%s*$","%1") + texsprint(format("\\setbox%i\\hbox{%s}",i,c)) + end +end + +luamplib.settexboxes = settexboxes + +local function gettexboxes (data) + local i = tex.count[14] -- the same newbox register + data = stringgsub(data,"(%A)btex%A.-%Aetex(%A)", + function(pre,post) + i = i + 1 + local box = tex.box[i] + local boxmetr = format("textext(%i,%f,%f,%f)", + i, + box and (box.width/factor) or 0, + box and (box.height/factor) or 0, + box and (box.depth/factor) or 0) + return pre .. boxmetr .. post + end) + return mplibcodepreamble .. data +end + +luamplib.gettexboxes = gettexboxes + +local function puttexboxes (object) + local n,tw,th = stringmatch( + object.prescript, + "%%%%textext:(%d+):([%d%.%+%-]+):([%d%.%+%-]+)") + if n and tw and th then + local op = object.path + local first, second, fourth = op[1], op[2], op[4] + local tx, ty = first.x_coord, first.y_coord + local sx, sy = (second.x_coord - tx)/tw, (fourth.y_coord - ty)/th + local rx, ry = (second.y_coord - ty)/tw, (fourth.x_coord - tx)/th + if sx == 0 then sx = 0.00001 end + if sy == 0 then sy = 0.00001 end + pdf_literalcode("q %f %f %f %f %f %f cm",sx,rx,ry,sy,tx,ty) + texsprint(format("\\mplibputtextbox{%i}",n)) + pdf_literalcode("Q") + end +end + + +local function flush(result,flusher) if result then local figures = result.fig if figures then for f=1, #figures do - log("flushing figure %s",f) + info("flushing figure %s",f) local figure = figures[f] local objects = getobjects(result,figure,f) - local fignum = tonumber((figure:filename()):match("([%d]+)$") or figure:charcode() or 0) + local fignum = tonumber(stringmatch(figure:filename(),"([%d]+)$") or figure:charcode() or 0) local miterlimit, linecap, linejoin, dashed = -1, -1, -1, false local bbox = figure:boundingbox() local llx, lly, urx, ury = bbox[1], bbox[2], bbox[3], bbox[4] -- faster than unpack @@ -248,9 +392,12 @@ function flush(result,flusher) pdf_literalcode("q") if objects then for o=1,#objects do - local object = objects[o] - local objecttype = object.type - if objecttype == "start_bounds" or objecttype == "stop_bounds" then + local object = objects[o] + local objecttype = object.type + local prescript = object.prescript --- [be]tex patch + if prescript and stringfind(prescript,"%%%%textext:") then + puttexboxes(object) + elseif objecttype == "start_bounds" or objecttype == "stop_bounds" then -- skip elseif objecttype == "start_clip" then pdf_literalcode("q") @@ -268,8 +415,11 @@ function flush(result,flusher) pdf_literalcode("Q") else local cs = object.color + local cr = nil if cs and #cs > 0 then - pdf_literalcode(colorconverter(cs)) + local start,stop = luamplib.colorconverter(cs) + pdf_literalcode(start) + cr = stop end local ml = object.miterlimit if ml and ml ~= miterlimit then @@ -288,7 +438,7 @@ function flush(result,flusher) end local dl = object.dash if dl then - local d = format("[%s] %i d",concat(dl.dashes or {}," "),dl.offset) + local d = format("[%s] %i d",tableconcat(dl.dashes or {}," "),dl.offset) if d ~= dashed then dashed = d pdf_literalcode(dashed) @@ -366,8 +516,9 @@ function flush(result,flusher) end end end +luamplib.flush = flush -function colorconverter(cr) +local function colorconverter(cr) local n = #cr if n == 4 then local c, m, y, k = cr[1], cr[2], cr[3], cr[4] @@ -380,5 +531,6 @@ function colorconverter(cr) return format("%.3f g %.3f G",s,s), "0 g 0 G" end end +luamplib.colorconverter = colorconverter -- -- End of File `luamplib.lua'. diff --git a/Master/texmf-dist/tex/luatex/luamplib/luamplib.sty b/Master/texmf-dist/tex/luatex/luamplib/luamplib.sty index e71631ad539..3f435d2b31f 100644 --- a/Master/texmf-dist/tex/luatex/luamplib/luamplib.sty +++ b/Master/texmf-dist/tex/luatex/luamplib/luamplib.sty @@ -14,9 +14,9 @@ \else \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{luamplib} - [2011/12/09 v1.09 mplib package for LuaTeX] + [2013/05/07 v2.0 mplib package for LuaTeX] \RequirePackage{luatexbase-modutils} - \RequirePackage{fancyvrb} + \RequirePackage{pdftexcmds} \fi \RequireLuaModule{luamplib} \def\mplibsetformat#1{% @@ -34,23 +34,29 @@ \PackageWarning{mplib}{MPLib only works in PDF mode, no figure will be output.} \fi \fi -\bgroup\expandafter\expandafter\expandafter\egroup -\expandafter\ifx\csname ProvidesPackage\endcsname\relax \def\mplibsetupcatcodes{% - \catcode`\{=12 \catcode`\}=12 \catcode`\#=12 \catcode`\^=12 \catcode`\~=12 - \catcode`\_=12 \catcode`\%=12 \catcode`\&=12 \catcode`\$=12 + \catcode`\{=12 \catcode`\}=12 \catcode`\#=12 + \catcode`\^=12 \catcode`\~=12 \catcode`\_=12 + %catcode`\%=12 %% don^^e2^^80^^99t in Plain! + \catcode`\&=12 \catcode`\$=12 } +\def\mplibputtextbox#1{\vbox to 0pt{\vss\hbox to 0pt{\raise\dp#1\box#1\hss}}} +\bgroup\expandafter\expandafter\expandafter\egroup +\expandafter\ifx\csname ProvidesPackage\endcsname\relax \def\mplibcode{% - \bgroup % - \mplibsetupcatcodes % + \bgroup + \mplibsetupcatcodes \mplibdocode % } \long\def\mplibdocode#1\endmplibcode{% - \egroup % - \mplibprocess{#1}% -} -\long\def\mplibprocess#1{% - \directlua{luamplib.process("\luatexluaescapestring{#1}")}% + \egroup + \directlua{ + luamplib.settexboxes([===[\unexpanded{#1}]===]) + }% + \directlua{ + local data = luamplib.gettexboxes([===[\unexpanded{#1}]===]) + luamplib.process(data) + }% } \else \begingroup @@ -69,24 +75,28 @@ \def^^I{\string^^I}% } \endgroup -\newcommand\mplibaddlines[1]{% - \begingroup % - \FV@hack % - \def\FV@ProcessLine##1{% - \directlua{luamplib.addline("\luatexluaescapestring{##1}")}% - }% - \csname FV@SV@#1\endcsname % - \endgroup % +\newenvironment{mplibcode}{\toks@{}\ltxdomplibcode}{} +\def\ltxdomplibcode{% + \bgroup + \mplibsetupcatcodes + \ltxdomplibcodeindeed % } -\newenvironment{mplibcode}{% - \VerbatimEnvironment % - \begin{SaveVerbatim}{memoire}% -}{% - \end{SaveVerbatim}% - \mplibaddlines{memoire}% - \directlua{luamplib.processlines()}% +\long\def\ltxdomplibcodeindeed#1\end{% + \egroup + \toks@\expandafter{\the\toks@#1}\ltxdomplibcodefinally% +}% +\def\ltxdomplibcodefinally#1{% + \ifnum\pdf@strcmp{#1}{mplibcode}=\z@ + \directlua{luamplib.settexboxes([===[\the\toks@]===])}% + \directlua{ + local data = luamplib.gettexboxes([===[\the\toks@]===]) + luamplib.process(data) + }% + \end{mplibcode}% + \else + \toks@\expandafter{\the\toks@\end{#1}}\expandafter\ltxdomplibcode + \fi% } - \fi \ifx\mplibscratchbox\undefined \newbox\mplibscratchbox \fi \def\mplibstarttoPDF#1#2#3#4{% |