Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- This file: -- http://anggtwu.net/LUA/Indent2.lua.html -- http://anggtwu.net/LUA/Indent2.lua -- (find-angg "LUA/Indent2.lua") -- Author: Eduardo Ochs <eduardoochs@gmail.com> -- -- This file defines the class Indent and the lowest-level methods of -- the class Pict. The middle-level methods of the class Pict are -- defined, and explained, here: -- -- (find-angg "LUA/Pict3.lua" "PictBounds-methods") -- (find-angg "LUA/Pict3.lua" "Pict-show") -- -- This file does not implement a ":show()" method for pict objects; -- see the link to "Pict-show" above. -- -- (defun e () (interactive) (find-angg "LUA/Indent2.lua")) -- (defun e1 () (interactive) (find-angg "LUA/ELpeg1.lua")) -- (defun i1 () (interactive) (find-angg "LUA/Indent1.lua")) -- (defun i2 () (interactive) (find-angg "LUA/Indent2.lua")) -- (defun p2 () (interactive) (find-angg "LUA/Pict2e2.lua")) -- (defun p3 () (interactive) (find-angg "LUA/Pict3.lua")) -- «.Indent» (to "Indent") -- «.Indent-tests» (to "Indent-tests") -- «.Pict» (to "Pict") -- «.Pict-tests» (to "Pict-tests") require "Stack1" -- (find-angg "LUA/Stack1.lua") require "ELpeg1" -- (find-angg "LUA/ELpeg1.lua" "Gram") spaces = function (n) return string.rep(" ", n) end flatten = function (o) local out = VTable {} local add -- recursive, defined in the next line add = function (x) if type(x) == "table" then map(add, x) else table.insert(out, x) end end add(o) return out end -- ___ _ _ -- |_ _|_ __ __| | ___ _ __ | |_ -- | || '_ \ / _` |/ _ \ '_ \| __| -- | || | | | (_| | __/ | | | |_ -- |___|_| |_|\__,_|\___|_| |_|\__| -- -- «Indent» (to ".Indent") Indent = Class { type = "Indent", from = function (bigstr) return Indent.from0(bigstr):concat() end, from0 = function (bigstr) return Indent.new():split(bigstr):runall() end, new = function () return Indent {stack=Stack.new(), prefixn=0, outs=VTable{}} end, makepat = function (open, close) local tocmd = function (tbl) return HTable(tbl) end local toitems = function (tbl) return VTable(tbl) end local gr,V = Gram.new() V.o = P(open) V.c = P(close) V.hs = S" \t" V.s = S" \t\n" V.ss = V.s^0 V.l = V.ss:C():Cg"l" V.r = V.ss:C():Cg"r" V.cmdbody = ((-V.c*P(1))^0):C():Cg"cmdbody" V.cmd = (V.l * V.o * V.cmdbody * V.c * V.r):Ct() / tocmd V.nl = P"\n":Ct() / tocmd V.hspaces = (V.hs^1):C() V.other = ((-V.s * -V.o * -V.c * P(1))^1):C() V.item = V.cmd + V.hspaces + V.nl + V.other V.toitems = (V.item^0):Ct() / toitems return gr:compile("toitems") end, setopenclose = function (open, close) Indent.__index.o = open Indent.__index.c = close Indent.__index.pat = Indent.makepat(open, close) end, __index = { -- o = "<", -- open -- c = ">", -- close -- pat = Indent.makepat("<", ">"), -- -- :ocfix(str) lets us write the delimiters as "<" and ">". -- For example, if o is "[." and c is ".]", -- then: ind:ocfix("foo <i:pop()> bar") -- returns: "foo [.i:pop().] bar" -- ocfix = function (ind,str) return (str:gsub("([<>])", {["<"]=ind.o, [">"]=ind.c})) end, -- split0 = function (ind,bigstr) return ind.pat:match(bigstr) end, split = function (ind,bigstr) ind.ins = ind:split0(bigstr); return ind end, prefix = function (ind,delta) return spaces(ind.prefixn + (delta or 0)) end, nl = function (ind,delta) return "\n"..ind:prefix(delta) end, ind = function (ind,delta) ind.stack:push(ind.prefixn) ind.prefixn = ind.prefixn+delta return ind end, pop = function (ind) ind.prefixn = ind.stack:pop(); return ind end, out = function (ind,o) table.insert(ind.outs, o); return ind end, concat = function (ind) return table.concat(ind.outs) end, -- runstr = function (ind,s) ind:out(s); return ind end, runnl = function (ind) ind:out(ind:nl()); return ind end, runcmd = function (ind,c) local l = c.l local r = c.r local o = l..r local cmd = format("local i,l,r,o=...; %s\nreturn o", c.cmdbody) local o2 = assert(loadstring(cmd))(ind, l, r, o) ind:out(o2) end, runo = function (ind,o) if type(o) == "string" then ind:runstr(o) elseif not o.cmdbody then ind:runnl() else ind:runcmd(o) end return ind end, runall = function (ind) for _,o in ipairs(ind.ins) do ind:runo(o) end return ind end, }, } Indent.setopenclose("<", ">") -- «Indent-tests» (to ".Indent-tests") --[[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Indent2.lua" bigstr = "abc def <foo> \nbar\nplic" bigstr = "abc def\nbar\nplic" bigstr = "aaa\nbbb\nccc<i:ind(2)>ddd\neee\nfff<i:pop()>ggg\nhhh" i = Indent.new():split(bigstr) = i = i.ins = i.outs = i:runall() = i.outs = i:concat() bigstr = "foo{<i:ind(2);o=i:nl()>\nbar<i:pop()>\n}" = Indent.from(bigstr) Indent.setopenclose("[", "]") Indent.setopenclose("<<.", ".>>") bigstr = "foo{[ i:ind(2);o=i:nl() ]\nbar[ i:pop() ]\n}" bigstr = "foo{<<. i:ind(2);o=i:nl() .>>\nbar<<. i:pop() .>>\n}" i = Indent.new():split(bigstr) = i = i.ins = Indent.from(bigstr) = Indent({}):ocfix("foo<o=i:nl()> bar") --]] -- ____ _ _ -- | _ \(_) ___| |_ -- | |_) | |/ __| __| -- | __/| | (__| |_ -- |_| |_|\___|\__| -- -- «Pict» (to ".Pict") -- Based on: (find-angg "LUA/Pict2e2.lua" "Pict") -- See: (find-angg "LUA/Pict3.lua" "Pict-show") -- Pict = Class { type = "Pict", __tostring = function (o) return o:tostring() end, __index = { tostring = function (o,percent) local bigstr = o:indent() if percent then bigstr = bigstr:gsub("\n", "%%\n") end return bigstr end, indent = function (o) return Indent.from(o:concat()) end, concat = function (o) return table.concat(flatten(o), "\n") end, -- output = function (p) output(p:tostring("%")) end, add = function (o,o2) table.insert(o, o2); return o end, print = function (o,o2) return p:add(o) end, printf = function (o,...) return p:add(format(...)) end, pprintf = function (o,...) return p:add(pformat(...)) end, -- glue_ = "<o=''>", ["{+1"] = "{<i:ind(1);o=''>", ["{+2"] = "{<i:ind(2);o=i:nl()>", ["}"] = "<i:pop();o=''>}", ["nl}"] = "<i:pop();o=i:nl()>}", ["$+1"] = "<i:ind(1);o='$'>", ["$$+2"] = "<i:ind(2);o='$$'>", ["{$+1"] = "<i:ind(1);o='{$'>", ["pop$"] = "<i:pop();o='$'>", ["pop$$"] = "<i:pop();o='$$'>", ["pop$}"] = "<i:pop();o='$}'>", ["+2nl"] = "<i:ind(2);o=i:nl()>", ["popnl"] = "<i:pop(); o=i:nl()>", -- cmd0 = function (o,str) return Indent({}):ocfix(str) end, cmd = function (o,tag) return Indent({}):ocfix(o[tag]) end, glue = function (o) return Pict {o:cmd0("glue_")} end, -- pre0 = function (o,prestr) return Pict({prestr, o}) end, preg = function (o,prestr) return Pict({prestr, o:cmd("glue_"), o}) end, pre = function (o,prestr) return prestr and o:preg(prestr) or o end, wrap0 = function (o,tag1,tag2) return Pict({o:cmd(tag1), o, o:cmd(tag2)}) end, wrapp = function (o,tag1,tag2,prestr) return o:wrap0(tag1,tag2):pre(prestr) end, wrap1 = function (o, prestr) return o:wrapp("{+1", "}", prestr) end, wrap2 = function (o, prestr) return o:wrapp("{+2", "nl}", prestr) end, wrap1d = function (o, prestr) return o:wrapp("{$+1", "pop$}", prestr) end, wrapsp = function (o, prestr) return o:wrapp("+2nl", "popnl", prestr) end, wrapbe = function (o,b,e) return Pict {b, o:wrapsp(), e} end, -- em = function (o) return o:wrap1("\\ensuremath") end, d = function (o) return o:wrapp("$+1", "pop$") end, dd = function (o) return o:wrapp("$$+2", "pop$$") end, def = function (o, name) return o:wrap2("\\def\\"..name) end, sa = function (o, name) return o:wrap2("\\sa{"..name.."}") end, color = function (o, color) return o:pre0("\\color{"..color.."}"):wrap1() end, Color = function (o, color) return o:wrap1("\\Color"..color) end, precolor0 = function (o, color) return o:pre0("\\color{"..color.."}") end, precolor = function (o, color) return o:pre0("\\color{"..color.."}"):wrap1() end, prethickness = function (o, th) return o:pre0("\\linethickness{"..th.."}") end, preunitlength = function (o, u) return o:pre0("\\unitlength="..u) end, bhbox = function (o) return o:wrap1d("\\bhbox") end, myvcenter = function (o) return o:wrap1("\\myvcenter") end, putat = function (o, xy) return o:wrap1(pformat("\\put%s", xy)) end, -- scalebox = function (o, scale) if not scale then return o end return o:em():wrap2("\\scalebox{"..scale.."}") end, }, } -- «Pict-tests» (to ".Pict-tests") --[[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Indent2.lua" = Pict {"bar"} :wrapp("{+2", "nl}", "\\foo") = Pict {"foo", "bar"} :wrap1() = Pict {"foo", "bar"} :wrap1("\\text") = Pict {"foo", "bar"} :wrap1("\\ensuremath") = Pict {"foo", "bar"} :wrap2() = Pict {"foo", "bar"} :wrap2("\\pre") = Pict {"foo", "bar"} :wrap2("\\pre") :tostring() = Pict {"foo", "bar"} :wrap2("\\pre") :tostring("%") = Pict {"foo", "bar"} :wrap2("\\pre") :concat() = Pict {"foo", "bar"} :d() = Pict {"foo", "bar"} :dd() = Pict {"foo", "bar"} :def("plic") = Pict {"foo", "bar"} :sa ("plic") = Pict {"foo", "bar"} :color("red") = Pict {"foo", "bar"} :Color("Red") = Pict {"foo", "bar"} :precolor("red") = Pict {"foo", "bar"} :prethickness("2pt") = Pict {"foo", "bar"} :preunitlength("2pt") = Pict {"foo", "bar"} :bhbox() = Pict {"foo", "bar"} :myvcenter() = Pict {"foo", "bar"} :putat("(2,3)") = Pict {"foo", "bar"} :wrapbe("aaa", "bbb") = Pict {"foo", "bar"} :wrapbe("aaa", "bbb"):wrapbe("ccc", "ddd") glue = "<o=''>" nl = "<o='\\n'>" p = "<o=i:prefix()>" b = "<i:ind(2);o=''>" e = "<i:pop();o=''>" = Pict {"aaa", glue, nl, b, "foo", "bar", glue, e, "bbb"} -- good = Pict {"aaa", nl, b, "foo", "bar", glue, e, "bbb"} -- good = Pict {"aaa", glue, nl, b, "foo", "bar", e, glue, "bbb"} = Pict {"aaa", glue, nl, b, "foo", "bar", e, nl, "bbb"} b = "<i:ind(2);o=i:nl()>" e = "<i:pop();o=i:nl()>" = Pict {"aaa", b, "foo", "bar", e, "bbb"} Indent.setopenclose("<<.", ".>>") = Pict {"foo", "bar"} :wrap2("\\pre") = Pict {"foo", "bar"} :wrap2("\\pre") :concat() --]] -- (find-angg "LUA/Indent1.lua" "flatten") -- Local Variables: -- coding: utf-8-unix -- End: