From 2e0934d99d3af014bd95c68d52f2d24816a11b8c Mon Sep 17 00:00:00 2001 From: Marius Date: Thu, 2 Dec 2010 13:20:14 +0200 Subject: beta 2010.12.02 12:05 --- tex/context/base/cont-new.tex | 2 +- tex/context/base/context.tex | 2 +- tex/context/base/luat-mac.lua | 14 +- tex/context/base/tabl-ntb.mkiv | 19 + tex/context/base/tabl-tab.mkiv | 2 +- tex/generic/context/luatex-fonts-merged.lua | 2 +- tex/generic/context/luatex-fonts.tex | 3 +- tex/generic/context/luatex-mplib.lua | 491 ----------------------- tex/generic/context/luatex-mplib.tex | 3 +- tex/generic/context/luatex-preprocessor-test.tex | 30 ++ tex/generic/context/luatex-preprocessor.lua | 163 ++++++++ tex/generic/context/luatex-preprocessor.tex | 14 + 12 files changed, 241 insertions(+), 504 deletions(-) delete mode 100644 tex/generic/context/luatex-mplib.lua create mode 100644 tex/generic/context/luatex-preprocessor-test.tex create mode 100644 tex/generic/context/luatex-preprocessor.lua create mode 100644 tex/generic/context/luatex-preprocessor.tex (limited to 'tex') diff --git a/tex/context/base/cont-new.tex b/tex/context/base/cont-new.tex index 2bc978f54..a9a9051d3 100644 --- a/tex/context/base/cont-new.tex +++ b/tex/context/base/cont-new.tex @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2010.12.02 08:51} +\newcontextversion{2010.12.02 12:05} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/context.tex b/tex/context/base/context.tex index 0e5c6fcb4..2f21c79c7 100644 --- a/tex/context/base/context.tex +++ b/tex/context/base/context.tex @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2010.12.02 08:51} +\edef\contextversion{2010.12.02 12:05} %D For those who want to use this: diff --git a/tex/context/base/luat-mac.lua b/tex/context/base/luat-mac.lua index 4a9e53b0e..8010f34a5 100644 --- a/tex/context/base/luat-mac.lua +++ b/tex/context/base/luat-mac.lua @@ -10,7 +10,7 @@ local P, V, S, R, C, Cs, Cmt = lpeg.P, lpeg.V, lpeg.S, lpeg.R, lpeg.C, lpeg.Cs, local lpegmatch, patterns = lpeg.match, lpeg.patterns local insert, remove = table.insert, table.remove -local rep = string.rep +local rep, sub = string.rep, string.sub local setmetatable = setmetatable local report_macros = logs.new("macros") @@ -55,7 +55,7 @@ local function pop() top = remove(stack) end -local leftbrace = P("{") +local leftbrace = P("{") -- will be in patterns local rightbrace = P("}") local escape = P("\\") @@ -64,8 +64,12 @@ local spaces = space^1 local newline = patterns.newline local nobrace = 1 - leftbrace - rightbrace +local longleft = leftbrace -- P("(") +local longright = rightbrace -- P(")") +local nolong = 1 - longleft - longright + local name = R("AZ","az")^1 -- @?! -- utf? -local longname = (leftbrace/"") * (nobrace^1) * (rightbrace/"") +local longname = (longleft/"") * (nolong^1) * (longright/"") local variable = P("#") * Cs(name + longname) local escapedname = escape * name local definer = escape * (P("def") + P("egdx") * P("def")) @@ -80,7 +84,7 @@ local declaration = variable / set local identifier = variable / get local function matcherror(str,pos) - report_macros("runaway definition at: %s",string.sub(str,pos-30,pos)) + report_macros("runaway definition at: %s",sub(str,pos-30,pos)) end local grammar = { "converter", @@ -132,7 +136,7 @@ function macros.preprocessed(str) return lpegmatch(parser,str) end -function macros.convertfile(oldname,newname) +function macros.convertfile(oldname,newname) -- beware, no testing on oldname == newname local data = resolvers.loadtexfile(oldname) data = interfaces.preprocessed(data) or "" io.savedata(newname,data) diff --git a/tex/context/base/tabl-ntb.mkiv b/tex/context/base/tabl-ntb.mkiv index d5eee61a0..34c4e8bb2 100644 --- a/tex/context/base/tabl-ntb.mkiv +++ b/tex/context/base/tabl-ntb.mkiv @@ -14,6 +14,7 @@ %D This is an unfinished, preliminary module. At least two %D runs are needed to get the table fixed. Ugly code. +% todo: TABLE TBL -> ntb % todo: special parsetb for argless variant % todo: protect \tbl... % todo: tblnx also count @@ -21,6 +22,24 @@ % todo: fast if % todo: avoid halign (just do it manual) and thereby globals + +% \unexpanded\def\startrow {\bTR} +% \unexpanded\def\stoprow {\eTR} +% \unexpanded\def\startcell#1\stopcell{\bTD#1\eTD} +% \let\stopcell \relax +% \let\startcelltable \bTABLE +% \let\stopcelltable \eTABLE + +% \starttext +% \startcelltable[|c|c|] +% \startrow \startcell a \stopcell \stoprow +% \startrow \startcell a \stopcell \stoprow +% \startrow \startcell a \stopcell \stoprow +% \startrow \startcell a \stopcell \stoprow +% \stopcelltable +% \stoptext + + % optie=rek beschrijven \writestatus{loading}{ConTeXt Table Macros / Natural Tables} diff --git a/tex/context/base/tabl-tab.mkiv b/tex/context/base/tabl-tab.mkiv index b5f79ff4b..fd05aae55 100644 --- a/tex/context/base/tabl-tab.mkiv +++ b/tex/context/base/tabl-tab.mkiv @@ -2269,7 +2269,7 @@ \to \localtabledefinitions \def\dochecktabledivision - {\ifcondition\istabledivision\else + {\ifconditional\istabledivision\else \dochucktableautorow \global\currenttablecolumn\zerocount \global\settrue\istabledivision diff --git a/tex/generic/context/luatex-fonts-merged.lua b/tex/generic/context/luatex-fonts-merged.lua index d8f9ccbdb..371a61edf 100644 --- a/tex/generic/context/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 12/02/10 08:51:01 +-- merge date : 12/02/10 12:05:11 do -- begin closure to overcome local limits and interference diff --git a/tex/generic/context/luatex-fonts.tex b/tex/generic/context/luatex-fonts.tex index 644d168f5..8ccc9f3d5 100644 --- a/tex/generic/context/luatex-fonts.tex +++ b/tex/generic/context/luatex-fonts.tex @@ -4,8 +4,7 @@ %D title=\LUATEX\ Support Macros, %D subtitle=Generic \OPENTYPE\ Font Handler, %D author=Hans Hagen, -%D date=\currentdate, -%D copyright=public domain] +%D copyright=see context related readme files] %D \subject{Welcome} %D diff --git a/tex/generic/context/luatex-mplib.lua b/tex/generic/context/luatex-mplib.lua deleted file mode 100644 index c6628acb3..000000000 --- a/tex/generic/context/luatex-mplib.lua +++ /dev/null @@ -1,491 +0,0 @@ -if not modules then modules = { } end modules ['luatex-mplib'] = { - version = 1.001, - comment = "companion to luatex-mplib.tex", - author = "Hans Hagen & Taco Hoekwater", - copyright = "ConTeXt Development Team", - license = "public domain", -} - ---[[ldx-- -

This module is a stripped down version of libraries that are used -by . It can be used in other macro packages and/or -serve as an example. Embedding in a macro package is upto others and -normally boils down to inputting supp-mpl.tex.

---ldx]]-- - -if metapost and metapost.version then - - --[[ldx-- -

Let's silently quit and make sure that no one loads it - manually in .

- --ldx]]-- - -else - - local format, concat, abs, match = string.format, table.concat, math.abs, string.match - - local mplib = require ('mplib') - local kpse = require ('kpse') - - --[[ldx-- -

We create a namespace and some variables to it. If a namespace is - already defined it wil not be initialized. This permits hooking - in code beforehand.

- -

We don't make a format automatically. After all, distributions - might have their own preferences and normally a format (mem) file will - have some special place in the tree. Also, there can already - be format files, different memort settings and other nasty pitfalls that - we don't want to interfere with. If you want, you can define a function - metapost.make(name,mem_name) that does the job.

- --ldx]]-- - - metapost = metapost or { } - metapost.version = 1.00 - metapost.showlog = metapost.showlog or false - metapost.lastlog = "" - - --[[ldx-- -

A few helpers, taken from l-file.lua.

- --ldx]]-- - - local file = file or { } - - function file.replacesuffix(filename, suffix) - return (string.gsub(filename,"%.[%a%d]+$","")) .. "." .. suffix - end - - function file.stripsuffix(filename) - return (string.gsub(filename,"%.[%a%d]+$","")) - end - - --[[ldx-- -

We use the library unless a finder is already - defined.

- --ldx]]-- - - local mpkpse = kpse.new("luatex","mpost") - - metapost.finder = metapost.finder or function(name, mode, ftype) - if mode == "w" then - return name - else - return mpkpse:find_file(name,ftype) - end - end - - --[[ldx-- -

You can use your own reported if needed, as long as it handles multiple - arguments and formatted strings.

- --ldx]]-- - - metapost.report = metapost.report or function(...) - texio.write(format("",format(...))) - end - - --[[ldx-- -

The rest of this module is not documented. More info can be found in the - manual, articles in user group journals and the files that - ship with .

- --ldx]]-- - - function metapost.resetlastlog() - metapost.lastlog = "" - end - - local mplibone = tonumber(mplib.version()) <= 1.50 - - if mplibone then - - metapost.make = metapost.make or function(name,mem_name,dump) - local t = os.clock() - local mpx = mplib.new { - ini_version = true, - find_file = metapost.finder, - job_name = file.stripsuffix(name) - } - mpx:execute(string.format("input %s ;",name)) - if dump then - mpx:execute("dump ;") - metapost.report("format %s made and dumped for %s in %0.3f seconds",mem_name,name,os.clock()-t) - else - metapost.report("%s read in %0.3f seconds",name,os.clock()-t) - end - return mpx - end - - function metapost.load(name) - local mem_name = file.replacesuffix(name,"mem") - local mpx = mplib.new { - ini_version = false, - mem_name = mem_name, - find_file = metapost.finder - } - if not mpx and type(metapost.make) == "function" then - -- when i have time i'll locate the format and dump - mpx = metapost.make(name,mem_name) - end - if mpx then - metapost.report("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 ; - ]] - - metapost.make = metapost.make or function() - end - - function metapost.load(name) - local mpx = mplib.new { - ini_version = true, - find_file = metapost.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 - metapost.reporterror(result) - return mpx, result - end - - end - - function metapost.unload(mpx) - if mpx then - mpx:finish() - end - end - - function metapost.reporterror(result) - if not result then - metapost.report("mp error: no result object returned") - elseif result.status > 0 then - local t, e, l = result.term, result.error, result.log - if t then - metapost.report("mp terminal: %s",t) - end - if e then - metapost.report("mp error: %s", e) - end - if not t and not e and l then - metapost.lastlog = metapost.lastlog .. "\n " .. l - metapost.report("mp log: %s",l) - else - metapost.report("mp error: unknown, no error, terminal or log messages") - end - else - return false - end - return true - end - - function metapost.process(mpx, data) - local converted, result = false, {} - mpx = metapost.load(mpx) - if mpx and data then - local result = mpx:execute(data) - if not result then - metapost.report("mp error: no result object returned") - elseif result.status > 0 then - metapost.report("mp error: %s",(result.term or "no-term") .. "\n" .. (result.error or "no-error")) - elseif metapost.showlog then - metapost.lastlog = metapost.lastlog .. "\n" .. result.term - metapost.report("mp info: %s",result.term or "no-term") - elseif result.fig then - converted = metapost.convert(result) - else - metapost.report("mp error: unknown error, maybe no beginfig/endfig") - end - else - metapost.report("mp error: mem file not found") - end - return converted, result - end - - local function getobjects(result,figure,f) - return figure:objects() - end - - function metapost.convert(result, flusher) - metapost.flush(result, flusher) - return true -- done - end - - --[[ldx-- -

We removed some message and tracing code. We might even remove the flusher

- --ldx]]-- - - local function pdf_startfigure(n,llx,lly,urx,ury) - tex.sprint(format("\\startMPLIBtoPDF{%s}{%s}{%s}{%s}",llx,lly,urx,ury)) - end - - local function pdf_stopfigure() - tex.sprint("\\stopMPLIBtoPDF") - end - - function pdf_literalcode(fmt,...) -- table - tex.sprint(format("\\MPLIBtoPDF{%s}",format(fmt,...))) - end - - 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)) - end - - 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) - 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 - return (sy*px-ry*py)/divider,(sx*py-rx*px)/divider - end - - local function curved(ith,pth) - local d = pth.left_x - ith.right_x - if abs(ith.right_x - ith.x_coord - d) <= bend_tolerance and abs(pth.x_coord - pth.left_x - d) <= bend_tolerance then - d = pth.left_y - ith.right_y - if abs(ith.right_y - ith.y_coord - d) <= bend_tolerance and abs(pth.y_coord - pth.left_y - d) <= bend_tolerance then - return false - end - end - return true - end - - local function flushnormalpath(path,open) - local pth, ith - for i=1,#path do - pth = path[i] - if not ith then - pdf_literalcode("%f %f m",pth.x_coord,pth.y_coord) - elseif curved(ith,pth) then - pdf_literalcode("%f %f %f %f %f %f c",ith.right_x,ith.right_y,pth.left_x,pth.left_y,pth.x_coord,pth.y_coord) - else - pdf_literalcode("%f %f l",pth.x_coord,pth.y_coord) - end - ith = pth - end - if not open then - local one = path[1] - if curved(pth,one) then - pdf_literalcode("%f %f %f %f %f %f c",pth.right_x,pth.right_y,one.left_x,one.left_y,one.x_coord,one.y_coord ) - else - pdf_literalcode("%f %f l",one.x_coord,one.y_coord) - end - elseif #path == 1 then - -- special case .. draw point - local one = path[1] - pdf_literalcode("%f %f l",one.x_coord,one.y_coord) - end - return t - end - - local function flushconcatpath(path,open) - pdf_literalcode("%f %f %f %f %f %f cm", sx, rx, ry, sy, tx ,ty) - local pth, ith - for i=1,#path do - pth = path[i] - if not ith then - pdf_literalcode("%f %f m",concat(pth.x_coord,pth.y_coord)) - elseif curved(ith,pth) then - local a, b = concat(ith.right_x,ith.right_y) - local c, d = concat(pth.left_x,pth.left_y) - pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concat(pth.x_coord, pth.y_coord)) - else - pdf_literalcode("%f %f l",concat(pth.x_coord, pth.y_coord)) - end - ith = pth - end - if not open then - local one = path[1] - if curved(pth,one) then - local a, b = concat(pth.right_x,pth.right_y) - local c, d = concat(one.left_x,one.left_y) - pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concat(one.x_coord, one.y_coord)) - else - pdf_literalcode("%f %f l",concat(one.x_coord,one.y_coord)) - end - elseif #path == 1 then - -- special case .. draw point - local one = path[1] - pdf_literalcode("%f %f l",concat(one.x_coord,one.y_coord)) - end - return t - end - - --[[ldx-- -

Support for specials has been removed.

- --ldx]]-- - - function metapost.flush(result,flusher) - if result then - local figures = result.fig - if figures then - for f=1, #figures do - metapost.report("flushing figure %s",f) - local figure = figures[f] - local objects = getobjects(result,figure,f) - local fignum = tonumber(match(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 - if urx < llx then - -- invalid - pdf_startfigure(fignum,0,0,0,0) - pdf_stopfigure() - else - pdf_startfigure(fignum,llx,lly,urx,ury) - 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 - -- skip - elseif objecttype == "start_clip" then - pdf_literalcode("q") - flushnormalpath(object.path,t,false) - pdf_literalcode("W n") - elseif objecttype == "stop_clip" then - pdf_literalcode("Q") - miterlimit, linecap, linejoin, dashed = -1, -1, -1, false - elseif objecttype == "special" then - -- not supported - elseif objecttype == "text" then - local ot = object.transform -- 3,4,5,6,1,2 - pdf_literalcode("q %f %f %f %f %f %f cm",ot[3],ot[4],ot[5],ot[6],ot[1],ot[2]) - pdf_textfigure(object.font,object.dsize,object.text,object.width,object.height,object.depth) - pdf_literalcode("Q") - else - local cs = object.color - if cs and #cs > 0 then - pdf_literalcode(metapost.colorconverter(cs)) - end - local ml = object.miterlimit - if ml and ml ~= miterlimit then - miterlimit = ml - pdf_literalcode("%f M",ml) - end - local lj = object.linejoin - if lj and lj ~= linejoin then - linejoin = lj - pdf_literalcode("%i j",lj) - end - local lc = object.linecap - if lc and lc ~= linecap then - linecap = lc - pdf_literalcode("%i J",lc) - end - local dl = object.dash - if dl then - local d = format("[%s] %i d",concat(dl.dashes or {}," "),dl.offset) - if d ~= dashed then - dashed = d - pdf_literalcode(dashed) - end - elseif dashed then - pdf_literalcode("[] 0 d") - dashed = false - end - local path = object.path - local transformed, penwidth = false, 1 - local open = path and path[1].left_type and path[#path].right_type - local pen = object.pen - if pen then - if pen.type == 'elliptical' then - transformed, penwidth = pen_characteristics(object) -- boolean, value - pdf_literalcode("%f w",penwidth) - if objecttype == 'fill' then - objecttype = 'both' - end - else -- calculated by mplib itself - objecttype = 'fill' - end - end - if transformed then - pdf_literalcode("q") - end - if path then - if transformed then - flushconcatpath(path,open) - else - flushnormalpath(path,open) - end - if objecttype == "fill" then - pdf_literalcode("h f") - elseif objecttype == "outline" then - pdf_literalcode((open and "S") or "h S") - elseif objecttype == "both" then - pdf_literalcode("h B") - end - end - if transformed then - pdf_literalcode("Q") - end - local path = object.htap - if path then - if transformed then - pdf_literalcode("q") - end - if transformed then - flushconcatpath(path,open) - else - flushnormalpath(path,open) - end - if objecttype == "fill" then - pdf_literalcode("h f") - elseif objecttype == "outline" then - pdf_literalcode((open and "S") or "h S") - elseif objecttype == "both" then - pdf_literalcode("h B") - end - if transformed then - pdf_literalcode("Q") - end - end - if cr then - pdf_literalcode(cr) - end - end - end - end - pdf_literalcode("Q") - pdf_stopfigure() - end - end - end - end - end - - function metapost.colorconverter(cr) - local n = #cr - if n == 4 then - local c, m, y, k = cr[1], cr[2], cr[3], cr[4] - return format("%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K",c,m,y,k,c,m,y,k), "0 g 0 G" - elseif n == 3 then - local r, g, b = cr[1], cr[2], cr[3] - return format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b), "0 g 0 G" - else - local s = cr[1] - return format("%.3f g %.3f G",s,s), "0 g 0 G" - end - end - -end diff --git a/tex/generic/context/luatex-mplib.tex b/tex/generic/context/luatex-mplib.tex index 206518d7d..691958646 100644 --- a/tex/generic/context/luatex-mplib.tex +++ b/tex/generic/context/luatex-mplib.tex @@ -4,8 +4,7 @@ %D title=\LUATEX\ Support Macros, %D subtitle=\METAPOST\ to \PDF\ conversion, %D author=Taco Hoekwater \& Hans Hagen, -%D date=\currentdate, -%D copyright=public domain] +%D copyright=see context related readme files] %D This is the companion to the \LUA\ module \type {supp-mpl.lua}. Further %D embedding is up to others. A simple example of usage in plain \TEX\ is: diff --git a/tex/generic/context/luatex-preprocessor-test.tex b/tex/generic/context/luatex-preprocessor-test.tex new file mode 100644 index 000000000..857b28f83 --- /dev/null +++ b/tex/generic/context/luatex-preprocessor-test.tex @@ -0,0 +1,30 @@ +\ifdefined\inputpreprocessed + + \def\TestOne[#1]% + {test one: [#1]\par} + + \def\TestTwo#some% + {test two: #some\par} + + \def\TestThree[#whatever][#more]% + {test three: [#more] and [#whatever]\par} + + \def\TestFour[#one]#two% + {\def\TestFive[#alpha][#one]% + {test four and five: [#one], [#two] and [#alpha]}\par} + + \def\TestSix[#{one}]#{two}% + {test six: [#{one}] and #{two}\par} + + \TestOne [one] + \TestTwo {one} + \TestThree[one][two] + \TestFour [one]{two} + \TestFive [one][two] + \TestSix [one]{two} + +\else + \input{luatex-preprocessor.tex} + \inputpreprocessed{luatex-preprocessor-test.tex} + \expandafter \end +\fi diff --git a/tex/generic/context/luatex-preprocessor.lua b/tex/generic/context/luatex-preprocessor.lua new file mode 100644 index 000000000..8faa0b47e --- /dev/null +++ b/tex/generic/context/luatex-preprocessor.lua @@ -0,0 +1,163 @@ +if not modules then modules = { } end modules ['luatex-preprocessor'] = { + version = 1.001, + comment = "companion to luatex-preprocessor.tex", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +--[[ldx +

This is a stripped down version of the preprocessor. In + we have a bit more, use a different logger, and +use a few optimizations. A few examples are shown at the end.

+--ldx]] + +local rep, sub, gmatch = string.rep, string.sub, string.gmatch +local insert, remove = table.insert, table.remove +local setmetatable = setmetatable + +local stack, top, n, hashes = { }, nil, 0, { } + +local function set(s) + if top then + n = n + 1 + if n > 9 then + texio.write_nl("number of arguments > 9, ignoring: " .. s) + else + local ns = #stack + local h = hashes[ns] + if not h then + h = rep("#",ns) + hashes[ns] = h + end + m = h .. n + top[s] = m + return m + end + end +end + +local function get(s) + local m = top and top[s] or s + return m +end + +local function push() + top = { } + n = 0 + local s = stack[#stack] + if s then + setmetatable(top,{ __index = s }) + end + insert(stack,top) +end + +local function pop() + top = remove(stack) +end + +local leftbrace = lpeg.P("{") +local rightbrace = lpeg.P("}") +local escape = lpeg.P("\\") + +local space = lpeg.P(" ") +local spaces = space^1 +local newline = lpeg.S("\r\n") +local nobrace = 1 - leftbrace - rightbrace + +local name = lpeg.R("AZ","az")^1 +local longname = (leftbrace/"") * (nobrace^1) * (rightbrace/"") +local variable = lpeg.P("#") * lpeg.Cs(name + longname) +local escapedname = escape * name +local definer = escape * (lpeg.P("def") + lpeg.P("egdx") * lpeg.P("def")) +local anything = lpeg.P(1) +local always = lpeg.P(true) + +local pushlocal = always / push +local poplocal = always / pop +local declaration = variable / set +local identifier = variable / get + +local function matcherror(str,pos) + texio.write_nl("runaway definition at: " .. sub(str,pos-30,pos)) +end + +local parser = lpeg.Cs { "converter", + definition = pushlocal + * definer + * escapedname + * (declaration + (1-leftbrace))^0 + * lpeg.V("braced") + * poplocal, + braced = leftbrace + * ( lpeg.V("definition") + + identifier + + lpeg.V("braced") + + nobrace + )^0 + * (rightbrace + lpeg.Cmt(always,matcherror)), + converter = (lpeg.V("definition") + anything)^1, +} + +--[[ldx +

We provide a few commands.

+--ldx]] + +-- local texkpse + +local function find_file(...) + -- texkpse = texkpse or kpse.new("luatex","tex") + -- return texkpse:find_file(...) or "" + return kpse.find_file(...) or "" +end + +commands = commands or { } + +function commands.preprocessed(str) + return lpeg.match(parser,str) +end + +function commands.inputpreprocessed(name) + local name = find_file(name) or "" + if name ~= "" then + -- we could use io.loaddata as it's loaded in luatex-plain + local f = io.open(name,'rb') + if f then + texio.write("("..name) + local d = commands.preprocessed(f:read("*a")) + if d and d ~= "" then + texio.write("processed: " .. name) + for s in gmatch(d,"[^\n\r]+") do + tex.print(s) -- we do a dumb feedback + end + end + f:close() + texio.write(")") + else + tex.error("preprocessor error, invalid file: " .. name) + end + else + tex.error("preprocessor error, unknown file: " .. name) + end +end + +function commands.preprocessfile(oldfile,newfile) -- no checking + if oldfile and oldfile ~= newfile then + local f = io.open(oldfile,'rb') + if f then + local g = io.open(newfile,'wb') + if g then + g:write(lpeg.match(parser,f:read("*a") or "")) + g:close() + end + f:close() + end + end +end + +--~ print(preprocessed([[\def\test#oeps{test:#oeps}]])) +--~ print(preprocessed([[\def\test#oeps{test:#{oeps}}]])) +--~ print(preprocessed([[\def\test#{oeps:1}{test:#{oeps:1}}]])) +--~ print(preprocessed([[\def\test#{oeps}{test:#oeps}]])) +--~ preprocessed([[\def\test#{oeps}{test:#oeps \halign{##\cr #oeps\cr}]]) +--~ print(preprocessed([[\def\test#{oeps}{test:#oeps \halign{##\cr #oeps\cr}}]])) diff --git a/tex/generic/context/luatex-preprocessor.tex b/tex/generic/context/luatex-preprocessor.tex new file mode 100644 index 000000000..fe4872d61 --- /dev/null +++ b/tex/generic/context/luatex-preprocessor.tex @@ -0,0 +1,14 @@ +%D \module +%D [ file=luatex-preprocessor, +%D version=2010.12.02, +%D title=\LUATEX\ Support Macros, +%D subtitle=Generic Preprocessor, +%D author=Hans Hagen, +%D copyright=public domain] + +\directlua{dofile(kpse.find_file('luatex-preprocessor.lua'))} + +\def\inputpreprocessed#1% + {\directlua{commands.inputpreprocessed("#1")}} + +\endinput -- cgit v1.2.3