summaryrefslogtreecommitdiff
path: root/tex
diff options
context:
space:
mode:
authorMarius <mariausol@gmail.com>2013-03-10 15:40:13 +0200
committerMarius <mariausol@gmail.com>2013-03-10 15:40:13 +0200
commit5f8fcb63f3e90458fa3b9feb9511b538340fd027 (patch)
tree2a064f6b42da2d7f74f3164d36b8409d6b170999 /tex
parent8bfadcb777942fb94f714df18d4172f0704dcbea (diff)
downloadcontext-5f8fcb63f3e90458fa3b9feb9511b538340fd027.tar.gz
beta 2013.03.10 14:36
Diffstat (limited to 'tex')
-rw-r--r--tex/context/base/cldf-ini.lua55
-rw-r--r--tex/context/base/colo-ini.lua35
-rw-r--r--tex/context/base/cont-new.mkii2
-rw-r--r--tex/context/base/cont-new.mkiv2
-rw-r--r--tex/context/base/context-version.pdfbin4131 -> 4139 bytes
-rw-r--r--tex/context/base/context-version.pngbin39754 -> 40397 bytes
-rw-r--r--tex/context/base/context.mkii2
-rw-r--r--tex/context/base/context.mkiv2
-rw-r--r--tex/context/base/file-job.lua13
-rw-r--r--tex/context/base/font-syn.lua3
-rw-r--r--tex/context/base/grph-inc.mkiv4
-rw-r--r--tex/context/base/l-lpeg.lua21
-rw-r--r--tex/context/base/l-lua.lua1
-rw-r--r--tex/context/base/l-table.lua325
-rw-r--r--tex/context/base/luat-lib.mkiv2
-rw-r--r--tex/context/base/lxml-lpt.lua7
-rw-r--r--tex/context/base/meta-ini.lua6
-rw-r--r--tex/context/base/mlib-pdf.lua41
-rw-r--r--tex/context/base/mlib-pps.lua108
-rw-r--r--tex/context/base/mlib-run.lua4
-rw-r--r--tex/context/base/status-files.pdfbin24806 -> 24788 bytes
-rw-r--r--tex/context/base/status-lua.pdfbin209211 -> 209468 bytes
-rw-r--r--tex/context/base/typo-del.mkiv1
-rw-r--r--tex/context/base/typo-prc.lua4
-rw-r--r--tex/context/base/util-fmt.lua22
-rw-r--r--tex/context/base/util-lua.lua11
-rw-r--r--tex/context/base/util-seq.lua2
-rw-r--r--tex/context/base/util-str.lua332
-rw-r--r--tex/context/base/util-tab.lua155
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua11
30 files changed, 858 insertions, 313 deletions
diff --git a/tex/context/base/cldf-ini.lua b/tex/context/base/cldf-ini.lua
index e3b7ed82a..f4b8ece4c 100644
--- a/tex/context/base/cldf-ini.lua
+++ b/tex/context/base/cldf-ini.lua
@@ -32,6 +32,7 @@ local format, gsub, validstring = string.format, string.gsub, string.valid
local next, type, tostring, tonumber, setmetatable = next, type, tostring, tonumber, setmetatable
local insert, remove, concat = table.insert, table.remove, table.concat
local lpegmatch, lpegC, lpegS, lpegP, lpegCc, patterns = lpeg.match, lpeg.C, lpeg.S, lpeg.P, lpeg.Cc, lpeg.patterns
+local formatters = string.formatters -- using formatteds is slower in this case
local texsprint = tex.sprint
local textprint = tex.tprint
@@ -533,7 +534,7 @@ local function caller(parent,f,a,...)
local typ = type(f)
if typ == "string" then
if a then
- flush(contentcatcodes,format(f,a,...)) -- was currentcatcodes
+ flush(contentcatcodes,formatters[f](a,...)) -- was currentcatcodes
elseif processlines and lpegmatch(containseol,f) then
local flushlines = parent.__flushlines or flushlines
flushlines(f)
@@ -606,13 +607,13 @@ end
function context.fprint(catcodes,fmt,first,...)
if type(catcodes) == "number" then
if first then
- flush(catcodes,format(fmt,first,...))
+ flush(catcodes,formatters[fmt](first,...))
else
flush(catcodes,fmt)
end
else
if fmt then
- flush(format(catcodes,fmt,first,...))
+ flush(formatters[catcodes](fmt,first,...))
else
flush(catcodes)
end
@@ -621,29 +622,29 @@ end
function tex.fprint(fmt,first,...) -- goodie
if first then
- flush(currentcatcodes,format(fmt,first,...))
+ flush(currentcatcodes,formatters[fmt](first,...))
else
flush(currentcatcodes,fmt)
end
end
-local formatters = string.formatters
+-- function context.formatted(catcodes,fmt,first,...) -- no longer to be used ... context(...) now uses formatted
+-- if type(catcodes) == "number" then -- and this was just a temporary helper that will go away
+-- if first then
+-- flush(catcodes,formatters[fmt](first,...))
+-- else
+-- flush(catcodes,fmt)
+-- end
+-- else
+-- if fmt then
+-- flush(formatters[catcodes](fmt,first,...))
+-- else
+-- flush(catcodes)
+-- end
+-- end
+-- end
-function context.formatted(catcodes,fmt,first,...)
- if type(catcodes) == "number" then
- if first then
- flush(catcodes,formatters[fmt](first,...))
- else
- flush(catcodes,fmt)
- end
- else
- if fmt then
- flush(formatters[catcodes](fmt,first,...))
- else
- flush(catcodes)
- end
- end
-end
+context.formatted = context.fprint
-- logging
@@ -697,7 +698,7 @@ local traced = function(normal,one,two,...)
normal(one,two,...)
local catcodes = type(one) == "number" and one
local arguments = catcodes and { two, ... } or { one, two, ... }
- local collapsed, c = { format("f : %s : ", catcodes or '-') }, 1
+ local collapsed, c = { formatters["f : %s : "](catcodes or '-') }, 1
for i=1,#arguments do
local argument = arguments[i]
local argtype = type(argument)
@@ -707,7 +708,7 @@ local traced = function(normal,one,two,...)
elseif argtype == "number" then
collapsed[c] = argument
else
- collapsed[c] = format("<<%s>>",tostring(argument))
+ collapsed[c] = formatters["<<%S>>"](argument)
end
end
currenttrace(concat(collapsed))
@@ -716,11 +717,11 @@ local traced = function(normal,one,two,...)
normal(one)
local argtype = type(one)
if argtype == "string" then
- currenttrace(format("f : - : %s",lpegmatch(visualizer,one)))
+ currenttrace(formatters["f : - : %s"](lpegmatch(visualizer,one)))
elseif argtype == "number" then
- currenttrace(format("f : - : %s",one))
+ currenttrace(formatters["f : - : %s"](one))
else
- currenttrace(format("f : - : <<%s>>",tostring(one)))
+ currenttrace(formatters["f : - : <<%S>>"](one))
end
end
end
@@ -924,7 +925,7 @@ local function caller(parent,f,a,...)
local typ = type(f)
if typ == "string" then
if a then
- flush(currentcatcodes,mpdrawing,"{",format(f,a,...),"}")
+ flush(currentcatcodes,mpdrawing,"{",formatters[f](a,...),"}")
else
flush(currentcatcodes,mpdrawing,"{",f,"}")
end
@@ -962,7 +963,7 @@ function metafun.stop()
end
function metafun.color(name)
- return format([[\MPcolor{%s}]],name)
+ return formatters[ [[\MPcolor{%s}]] ](name)
end
-- metafun.delayed
diff --git a/tex/context/base/colo-ini.lua b/tex/context/base/colo-ini.lua
index 1a994b567..29cce70f0 100644
--- a/tex/context/base/colo-ini.lua
+++ b/tex/context/base/colo-ini.lua
@@ -11,6 +11,7 @@ local concat, insert, remove = table.concat, table.insert, table.remove
local format, gmatch, gsub, lower, match, find = string.format, string.gmatch, string.gsub, string.lower, string.match, string.find
local P, R, C, Cc = lpeg.P, lpeg.R, lpeg.C, lpeg.Cc
local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
+local formatters = string.formatters
local trace_define = false trackers.register("colors.define",function(v) trace_define = v end)
@@ -470,38 +471,32 @@ local function mpcolor(model,ca,ta,default)
model = forcedmodel(model)
if tv then
if model == 2 then
- return format("transparent(%s,%s,(%s,%s,%s))",tv[1],tv[2],cv[3],cv[4],cv[5])
+ return formatters["transparent(%s,%s,(%s,%s,%s))"](tv[1],tv[2],cv[3],cv[4],cv[5])
elseif model == 3 then
- return format("transparent(%s,%s,(%s,%s,%s))",tv[1],tv[2],cv[3],cv[4],cv[5])
+ return formatters["transparent(%s,%s,(%s,%s,%s))"](tv[1],tv[2],cv[3],cv[4],cv[5])
elseif model == 4 then
- return format("transparent(%s,%s,cmyk(%s,%s,%s,%s))",tv[1],tv[2],cv[6],cv[7],cv[8],cv[9])
+ return formatters["transparent(%s,%s,cmyk(%s,%s,%s,%s))"](tv[1],tv[2],cv[6],cv[7],cv[8],cv[9])
elseif model == 5 then
- return format('transparent(%s,%s,multitonecolor("%s",%s,"%s","%s"))',tv[1],tv[2],cv[10],cv[11],cv[12],cv[13])
- else
- return format("transparent(%s,%s,(%s,%s,%s))",tv[1],tv[2],cv[3],cv[4],cv[5])
--- this will become (see ** in meta-ini.mkiv)
---
--- return format("transparent(%s,%s,(%s))",tv[1],tv[2],cv[2])
+ return formatters['transparent(%s,%s,multitonecolor("%s",%s,"%s","%s"))'](tv[1],tv[2],cv[10],cv[11],cv[12],cv[13])
+ else -- see ** in meta-ini.mkiv: return formatters["transparent(%s,%s,(%s))"](tv[1],tv[2],cv[2])
+ return formatters["transparent(%s,%s,(%s,%s,%s))"](tv[1],tv[2],cv[3],cv[4],cv[5])
end
else
if model == 2 then
- return format("(%s,%s,%s)",cv[3],cv[4],cv[5])
+ return formatters["(%s,%s,%s)"](cv[3],cv[4],cv[5])
elseif model == 3 then
- return format("(%s,%s,%s)",cv[3],cv[4],cv[5])
+ return formatters["(%s,%s,%s)"](cv[3],cv[4],cv[5])
elseif model == 4 then
- return format("cmyk(%s,%s,%s,%s)",cv[6],cv[7],cv[8],cv[9])
+ return formatters["cmyk(%s,%s,%s,%s)"](cv[6],cv[7],cv[8],cv[9])
elseif model == 5 then
- return format('multitonecolor("%s",%s,"%s","%s")',cv[10],cv[11],cv[12],cv[13])
- else
- return format("(%s,%s,%s)",cv[3],cv[4],cv[5])
--- this will become (see ** in meta-ini.mkiv)
---
--- return format("%s",(cv[2]))
+ return formatters['multitonecolor("%s",%s,"%s","%s")'](cv[10],cv[11],cv[12],cv[13])
+ else -- see ** in meta-ini.mkiv: return formatters["%s"]((cv[2]))
+ return formatters["(%s,%s,%s)"](cv[3],cv[4],cv[5])
end
end
else
default = default or 0 -- rgb !
- return format("(%s,%s,%s)",default,default,default)
+ return formatters["(%s,%s,%s)"](default,default,default)
end
end
@@ -510,7 +505,7 @@ local function mpnamedcolor(name)
end
local function mpoptions(model,ca,ta,default) -- will move to mlib-col
- return format("withcolor %s",mpcolor(model,ca,ta,default))
+ return formatters["withcolor %s"](mpcolor(model,ca,ta,default))
end
colors.mpcolor = mpcolor
diff --git a/tex/context/base/cont-new.mkii b/tex/context/base/cont-new.mkii
index aa4e3223d..a53a074c4 100644
--- a/tex/context/base/cont-new.mkii
+++ b/tex/context/base/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2013.03.08 01:14}
+\newcontextversion{2013.03.10 14:36}
%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/cont-new.mkiv b/tex/context/base/cont-new.mkiv
index debad7bae..cc4ded1f2 100644
--- a/tex/context/base/cont-new.mkiv
+++ b/tex/context/base/cont-new.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2013.03.08 01:14}
+\newcontextversion{2013.03.10 14:36}
%D This file is loaded at runtime, thereby providing an excellent place for
%D hacks, patches, extensions and new features.
diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf
index 398846f55..bbc4ff28d 100644
--- a/tex/context/base/context-version.pdf
+++ b/tex/context/base/context-version.pdf
Binary files differ
diff --git a/tex/context/base/context-version.png b/tex/context/base/context-version.png
index 3be5fcc66..43823ceb6 100644
--- a/tex/context/base/context-version.png
+++ b/tex/context/base/context-version.png
Binary files differ
diff --git a/tex/context/base/context.mkii b/tex/context/base/context.mkii
index 20aefca87..0a5bc9680 100644
--- a/tex/context/base/context.mkii
+++ b/tex/context/base/context.mkii
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2013.03.08 01:14}
+\edef\contextversion{2013.03.10 14:36}
%D For those who want to use this:
diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv
index 4fcd7ae07..8cb615107 100644
--- a/tex/context/base/context.mkiv
+++ b/tex/context/base/context.mkiv
@@ -25,7 +25,7 @@
%D up and the dependencies are more consistent.
\edef\contextformat {\jobname}
-\edef\contextversion{2013.03.08 01:14}
+\edef\contextversion{2013.03.10 14:36}
%D For those who want to use this:
diff --git a/tex/context/base/file-job.lua b/tex/context/base/file-job.lua
index 533103ec6..b5c4b2b05 100644
--- a/tex/context/base/file-job.lua
+++ b/tex/context/base/file-job.lua
@@ -823,15 +823,24 @@ function commands.getcommandline() -- has to happen at the tex end in order to e
inputfile = basename(inputfile)
end
+ local kindofrun = arguments.kindofrun
+ local currentrun = arguments.maxnofruns
+ local maxnofruns = arguments.currentrun
+
context.setupsystem {
[constants.directory] = validstring(arguments.setuppath),
[constants.inputfile] = inputfile,
[constants.file] = validstring(arguments.result),
[constants.random] = validstring(arguments.randomseed),
- [constants.n] = validstring(arguments.kindofrun),
- [constants.m] = validstring(arguments.currentrun),
+ -- old:
+ [constants.n] = validstring(kindofrun),
+ [constants.m] = validstring(currentrun),
}
+ environment.kindofrun = tonumber(kindofrun) or 0
+ environment.maxnofruns = tonumber(maxnofruns) or 0
+ environment.currentrun = tonumber(currentrun) or 0
+
if validstring(arguments.arguments) then
context.setupenv { arguments.arguments }
end
diff --git a/tex/context/base/font-syn.lua b/tex/context/base/font-syn.lua
index 3f90da91b..63564f4f9 100644
--- a/tex/context/base/font-syn.lua
+++ b/tex/context/base/font-syn.lua
@@ -15,6 +15,7 @@ local concat, sort, format = table.concat, table.sort, string.format
local serialize = table.serialize
local lpegmatch = lpeg.match
local unpack = unpack or table.unpack
+local formatters = string.formatters
local allocate = utilities.storage.allocate
local sparse = utilities.storage.sparse
@@ -581,7 +582,7 @@ local function checkduplicate(where) -- fails on "Romantik" but that's a border
for _, m in next, mapping do
for k, v in next, m do
local s = specifications[v]
- local hash = format("%s-%s-%s-%s-%s",s.familyname,s.weight or "*",s.style or "*",s.width or "*",s.variant or "*")
+ local hash = formatters["%s-%s-%s-%s-%s"](s.familyname,s.weight or "*",s.style or "*",s.width or "*",s.variant or "*")
local h = loaded[hash]
if h then
local ok = true
diff --git a/tex/context/base/grph-inc.mkiv b/tex/context/base/grph-inc.mkiv
index 54d024b85..8557bbb0b 100644
--- a/tex/context/base/grph-inc.mkiv
+++ b/tex/context/base/grph-inc.mkiv
@@ -567,6 +567,10 @@
{\startfoundexternalfigure\defaultfigurewidth\defaultfigureheight
\stopfoundexternalfigure}
+% \doifmodeelse{*\v!last}
+% {\settrue \c_grph_include_flush}
+% {\setfalse\c_grph_include_flush}%
+
\def\grph_include_finalize
{\global\setbox\foundexternalfigure\vbox
{\ifcase\figurestatus
diff --git a/tex/context/base/l-lpeg.lua b/tex/context/base/l-lpeg.lua
index 9bd9706bf..cfc26a5a5 100644
--- a/tex/context/base/l-lpeg.lua
+++ b/tex/context/base/l-lpeg.lua
@@ -829,3 +829,24 @@ end
-- local s = "12" .. string.rep("AB",20) .. "34" .. string.rep("AB",30) .. "56"
-- inspect(p)
-- print(lpeg.match(p,s))
+
+-- moved here (before util-str)
+
+local digit = R("09")
+local period = P(".")
+local zero = P("0")
+local trailingzeros = zero^0 * -digit -- suggested by Roberto R
+local case_1 = period * trailingzeros / ""
+local case_2 = period * (digit - trailingzeros)^1 * (trailingzeros / "")
+local number = digit^1 * (case_1 + case_2)
+local stripper = Cs((number + 1)^0)
+
+lpeg.patterns.stripzeros = stripper
+
+-- local sample = "bla 11.00 bla 11 bla 0.1100 bla 1.00100 bla 0.00 bla 0.001 bla 1.1100 bla 0.100100100 bla 0.00100100100"
+-- collectgarbage("collect")
+-- str = string.rep(sample,10000)
+-- local ts = os.clock()
+-- lpegmatch(stripper,str)
+-- print(#str, os.clock()-ts, lpegmatch(stripper,sample))
+
diff --git a/tex/context/base/l-lua.lua b/tex/context/base/l-lua.lua
index 5863960b3..9ac8192b0 100644
--- a/tex/context/base/l-lua.lua
+++ b/tex/context/base/l-lua.lua
@@ -12,6 +12,7 @@ local major, minor = string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$")
_MAJORVERSION = tonumber(major) or 5
_MINORVERSION = tonumber(minor) or 1
+_LUAVERSION = _MAJORVERSION + _MINORVERSION/10
-- lpeg
diff --git a/tex/context/base/l-table.lua b/tex/context/base/l-table.lua
index 92ef02503..c33cd195b 100644
--- a/tex/context/base/l-table.lua
+++ b/tex/context/base/l-table.lua
@@ -394,6 +394,8 @@ end
-- todo: %g faster on numbers than %s
+-- we can speed this up with repeaters and formatters (is indeed faster)
+
local propername = patterns.propername -- was find(name,"^%a[%w%_]*$")
local function dummy() end
@@ -711,6 +713,322 @@ local function serialize(_handle,root,name,specification) -- handle wins
handle("}")
end
+-- -- This is some 20% faster than using format (because formatters are much faster) but
+-- -- of course, inlining the format using .. is then again faster .. anyway, as we do
+-- -- some pretty printing as well there is not that much to gain unless we make a 'fast'
+-- -- ugly variant as well. But, we would have to move the formatter to l-string then.
+
+-- local formatters = string.formatters
+
+-- local function do_serialize(root,name,level,indexed)
+-- if level > 0 then
+-- if indexed then
+-- handle(formatters["%w{"](level))
+-- else
+-- local tn = type(name)
+-- if tn == "number" then
+-- if hexify then
+-- handle(formatters["%w[%04H]={"](level,name))
+-- else
+-- handle(formatters["%w[%s]={"](level,name))
+-- end
+-- elseif tn == "string" then
+-- if noquotes and not reserved[name] and lpegmatch(propername,name) then
+-- handle(formatters["%w%s={"](level,name))
+-- else
+-- handle(formatters["%w[%q]={"](level,name))
+-- end
+-- elseif tn == "boolean" then
+-- handle(formatters["%w[%S]={"](level,name))
+-- else
+-- handle(formatters["%w{"](level))
+-- end
+-- end
+-- end
+-- -- we could check for k (index) being number (cardinal)
+-- if root and next(root) then
+-- -- local first, last = nil, 0 -- #root cannot be trusted here (will be ok in 5.2 when ipairs is gone)
+-- -- if compact then
+-- -- -- NOT: for k=1,#root do (we need to quit at nil)
+-- -- for k,v in ipairs(root) do -- can we use next?
+-- -- if not first then first = k end
+-- -- last = last + 1
+-- -- end
+-- -- end
+-- local first, last = nil, 0
+-- if compact then
+-- last = #root
+-- for k=1,last do
+-- if root[k] == nil then
+-- last = k - 1
+-- break
+-- end
+-- end
+-- if last > 0 then
+-- first = 1
+-- end
+-- end
+-- local sk = sortedkeys(root)
+-- for i=1,#sk do
+-- local k = sk[i]
+-- local v = root[k]
+-- --~ if v == root then
+-- -- circular
+-- --~ else
+-- local t, tk = type(v), type(k)
+-- if compact and first and tk == "number" and k >= first and k <= last then
+-- if t == "number" then
+-- if hexify then
+-- handle(formatters["%w %04H,"](level,v))
+-- else
+-- handle(formatters["%w %s,"](level,v)) -- %.99g
+-- end
+-- elseif t == "string" then
+-- if reduce and tonumber(v) then
+-- handle(formatters["%w %s,"](level,v))
+-- else
+-- handle(formatters["%w %q,"](level,v))
+-- end
+-- elseif t == "table" then
+-- if not next(v) then
+-- handle(formatters["%w {},"](level))
+-- elseif inline then -- and #t > 0
+-- local st = simple_table(v)
+-- if st then
+-- handle(formatters["%w { %, t },"](level,st))
+-- else
+-- do_serialize(v,k,level+1,true)
+-- end
+-- else
+-- do_serialize(v,k,level+1,true)
+-- end
+-- elseif t == "boolean" then
+-- handle(formatters["%w %S,"](level,v))
+-- elseif t == "function" then
+-- if functions then
+-- handle(formatters['%w load(%q),'](level,dump(v)))
+-- else
+-- handle(formatters['%w "function",'](level))
+-- end
+-- else
+-- handle(formatters["%w %Q,"](level,v))
+-- end
+-- elseif k == "__p__" then -- parent
+-- if false then
+-- handle(formatters["%w __p__=nil,"](level))
+-- end
+-- elseif t == "number" then
+-- if tk == "number" then
+-- if hexify then
+-- handle(formatters["%w [%04H]=%04H,"](level,k,v))
+-- else
+-- handle(formatters["%w [%s]=%s,"](level,k,v)) -- %.99g
+-- end
+-- elseif tk == "boolean" then
+-- if hexify then
+-- handle(formatters["%w [%S]=%04H,"](level,k,v))
+-- else
+-- handle(formatters["%w [%S]=%s,"](level,k,v)) -- %.99g
+-- end
+-- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+-- if hexify then
+-- handle(formatters["%w %s=%04H,"](level,k,v))
+-- else
+-- handle(formatters["%w %s=%s,"](level,k,v)) -- %.99g
+-- end
+-- else
+-- if hexify then
+-- handle(formatters["%w [%q]=%04H,"](level,k,v))
+-- else
+-- handle(formatters["%w [%q]=%s,"](level,k,v)) -- %.99g
+-- end
+-- end
+-- elseif t == "string" then
+-- if reduce and tonumber(v) then
+-- if tk == "number" then
+-- if hexify then
+-- handle(formatters["%w [%04H]=%s,"](level,k,v))
+-- else
+-- handle(formatters["%w [%s]=%s,"](level,k,v))
+-- end
+-- elseif tk == "boolean" then
+-- handle(formatters["%w [%S]=%s,"](level,k,v))
+-- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+-- handle(formatters["%w %s=%s,"](level,k,v))
+-- else
+-- handle(formatters["%w [%q]=%s,"](level,k,v))
+-- end
+-- else
+-- if tk == "number" then
+-- if hexify then
+-- handle(formatters["%w [%04H]=%q,"](level,k,v))
+-- else
+-- handle(formatters["%w [%s]=%q,"](level,k,v))
+-- end
+-- elseif tk == "boolean" then
+-- handle(formatters["%w [%S]=%q,"](level,k,v))
+-- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+-- handle(formatters["%w %s=%q,"](level,k,v))
+-- else
+-- handle(formatters["%w [%q]=%q,"](level,k,v))
+-- end
+-- end
+-- elseif t == "table" then
+-- if not next(v) then
+-- if tk == "number" then
+-- if hexify then
+-- handle(formatters["%w [%04H]={},"](level,k))
+-- else
+-- handle(formatters["%w [%s]={},"](level,k))
+-- end
+-- elseif tk == "boolean" then
+-- handle(formatters["%w [%S]={},"](level,k))
+-- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+-- handle(formatters["%w %s={},"](level,k))
+-- else
+-- handle(formatters["%w [%q]={},"](level,k))
+-- end
+-- elseif inline then
+-- local st = simple_table(v)
+-- if st then
+-- if tk == "number" then
+-- if hexify then
+-- handle(formatters["%w [%04H]={ %, t },"](level,k,st))
+-- else
+-- handle(formatters["%w [%s]={ %, t },"](level,k,st))
+-- end
+-- elseif tk == "boolean" then
+-- handle(formatters["%w [%S]={ %, t },"](level,k,st))
+-- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+-- handle(formatters["%w %s={ %, t },"](level,k,st))
+-- else
+-- handle(formatters["%w [%q]={ %, t },"](level,k,st))
+-- end
+-- else
+-- do_serialize(v,k,level+1)
+-- end
+-- else
+-- do_serialize(v,k,level+1)
+-- end
+-- elseif t == "boolean" then
+-- if tk == "number" then
+-- if hexify then
+-- handle(formatters["%w [%04H]=%S,"](level,k,v))
+-- else
+-- handle(formatters["%w [%s]=%S,"](level,k,v))
+-- end
+-- elseif tk == "boolean" then
+-- handle(formatters["%w [%S]=%S,"](level,k,v))
+-- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+-- handle(formatters["%w %s=%S,"](level,k,v))
+-- else
+-- handle(formatters["%w [%q]=%S,"](level,k,v))
+-- end
+-- elseif t == "function" then
+-- if functions then
+-- local f = getinfo(v).what == "C" and dump(dummy) or dump(v)
+-- -- local f = getinfo(v).what == "C" and dump(function(...) return v(...) end) or dump(v)
+-- if tk == "number" then
+-- if hexify then
+-- handle(formatters["%w [%04H]=load(%q),"](level,k,f))
+-- else
+-- handle(formatters["%w [%s]=load(%q),"](level,k,f))
+-- end
+-- elseif tk == "boolean" then
+-- handle(formatters["%w [%S]=load(%q),"](level,k,f))
+-- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+-- handle(formatters["%w %s=load(%q),"](level,k,f))
+-- else
+-- handle(formatters["%w [%q]=load(%q),"](level,k,f))
+-- end
+-- end
+-- else
+-- if tk == "number" then
+-- if hexify then
+-- handle(formatters["%w [%04H]=%Q,"](level,k,v))
+-- else
+-- handle(formatters["%w [%s]=%Q,"](level,k,v))
+-- end
+-- elseif tk == "boolean" then
+-- handle(formatters["%w [%S]=%Q,"](level,k,v))
+-- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+-- handle(formatters["%w %s=%Q,"](level,k,v))
+-- else
+-- handle(formatters["%w [%q]=%Q,"](level,k,v))
+-- end
+-- end
+-- --~ end
+-- end
+-- end
+-- if level > 0 then
+-- handle(formatters["%w}"](level))
+-- end
+-- end
+
+-- local function serialize(_handle,root,name,specification) -- handle wins
+-- local tname = type(name)
+-- if type(specification) == "table" then
+-- noquotes = specification.noquotes
+-- hexify = specification.hexify
+-- handle = _handle or specification.handle or print
+-- reduce = specification.reduce or false
+-- functions = specification.functions
+-- compact = specification.compact
+-- inline = specification.inline and compact
+-- if functions == nil then
+-- functions = true
+-- end
+-- if compact == nil then
+-- compact = true
+-- end
+-- if inline == nil then
+-- inline = compact
+-- end
+-- else
+-- noquotes = false
+-- hexify = false
+-- handle = _handle or print
+-- reduce = false
+-- compact = true
+-- inline = true
+-- functions = true
+-- end
+-- if tname == "string" then
+-- if name == "return" then
+-- handle("return {")
+-- else
+-- handle(name .. "={")
+-- end
+-- elseif tname == "number" then
+-- if hexify then
+-- handle(format("[0x%04X]={",name))
+-- else
+-- handle("[" .. name .. "]={")
+-- end
+-- elseif tname == "boolean" then
+-- if name then
+-- handle("return {")
+-- else
+-- handle("{")
+-- end
+-- else
+-- handle("t={")
+-- end
+-- if root then
+-- -- The dummy access will initialize a table that has a delayed initialization
+-- -- using a metatable. (maybe explicitly test for metatable)
+-- if getmetatable(root) then -- todo: make this an option, maybe even per subtable
+-- local dummy = root._w_h_a_t_e_v_e_r_
+-- root._w_h_a_t_e_v_e_r_ = nil
+-- end
+-- -- Let's forget about empty tables.
+-- if next(root) then
+-- do_serialize(root,name,0)
+-- end
+-- end
+-- handle("}")
+-- end
+
-- name:
--
-- true : return { }
@@ -730,6 +1048,13 @@ function table.serialize(root,name,specification)
return concat(t,"\n")
end
+-- local a = { e = { 1,2,3,4,5,6}, a = 1, b = 2, c = "ccc", d = { a = 1, b = 2, c = "ccc", d = { a = 1, b = 2, c = "ccc" } } }
+-- local t = os.clock()
+-- for i=1,10000 do
+-- table.serialize(a)
+-- end
+-- print(os.clock()-t,table.serialize(a))
+
table.tohandle = serialize
-- sometimes tables are real use (zapfino extra pro is some 85M) in which
diff --git a/tex/context/base/luat-lib.mkiv b/tex/context/base/luat-lib.mkiv
index 4ece2a29a..b9ccd8b11 100644
--- a/tex/context/base/luat-lib.mkiv
+++ b/tex/context/base/luat-lib.mkiv
@@ -13,9 +13,9 @@
\writestatus{loading}{ConTeXt Lua Macros / Libraries}
+\registerctxluafile{util-str}{1.001}
\registerctxluafile{util-tab}{1.001}
\registerctxluafile{util-sto}{1.001} % could also be done in trac-deb.mkiv
-\registerctxluafile{util-str}{1.001} % uses util-sto
\registerctxluafile{util-pck}{1.001}
\registerctxluafile{util-seq}{1.001}
%registerctxluafile{util-mrg}{1.001} % not needed in context itself, only mtxrun
diff --git a/tex/context/base/lxml-lpt.lua b/tex/context/base/lxml-lpt.lua
index d73b87287..2be648075 100644
--- a/tex/context/base/lxml-lpt.lua
+++ b/tex/context/base/lxml-lpt.lua
@@ -15,6 +15,7 @@ local format, upper, lower, gmatch, gsub, find, rep = string.format, string.uppe
local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
local setmetatableindex = table.setmetatableindex
+local formatters = string.formatters -- no need (yet) as paths are cached anyway
-- beware, this is not xpath ... e.g. position is different (currently) and
-- we have reverse-sibling as reversed preceding sibling
@@ -608,15 +609,12 @@ local converter = Cs (
)
cleaner = Cs ( (
---~ lp_fastpos +
+ -- lp_fastpos +
lp_reserved +
lp_number +
lp_string +
1 )^1 )
-
---~ expr
-
local template_e = [[
local expr = xml.expressions
return function(list,ll,l,order)
@@ -671,6 +669,7 @@ local function errorrunner_e(str,cnv)
end
return false
end
+
local function errorrunner_f(str,arg)
report_lpath("error in finalizer: %s(%s)",str,arg or "")
return false
diff --git a/tex/context/base/meta-ini.lua b/tex/context/base/meta-ini.lua
index 928048776..05433121e 100644
--- a/tex/context/base/meta-ini.lua
+++ b/tex/context/base/meta-ini.lua
@@ -153,8 +153,12 @@ end
-- context.mathematics(f)
-- end
+-- formatters["\\times10^{%N}"](s) -- strips leading zeros too
+
local one = Cs((P("@")/"%%." * (R("09")^1) + P("@")/"%%" + 1)^0)
-local two = Cs((P("e")/"" * ((S("+-")^0 * R("09")^1)/function(s) return format("\\times10^{%s}",tonumber(s) or s) end) + 1)^1)
+local two = Cs((P("e")/"" * ((S("+-")^0 * R("09")^1) / function(s) return format("\\times10^{%s}",tonumber(s) or s) end) + 1)^1)
+
+-- local two = Cs((P("e")/"" * ((S("+-")^0 * R("09")^1) / formatters["\\times10^{%N}"]) + 1)^1)
function metapost.formatnumber(fmt,n) -- just lua format
context.mathematics(lpegmatch(two,format(lpegmatch(one,fmt),n)))
diff --git a/tex/context/base/mlib-pdf.lua b/tex/context/base/mlib-pdf.lua
index e22e3af30..205dbd35a 100644
--- a/tex/context/base/mlib-pdf.lua
+++ b/tex/context/base/mlib-pdf.lua
@@ -12,6 +12,7 @@ local format, concat, gsub = string.format, table.concat, string.gsub
local abs, sqrt, round = math.abs, math.sqrt, math.round
local setmetatable = setmetatable
local Cf, C, Cg, Ct, P, S, lpegmatch = lpeg.Cf, lpeg.C, lpeg.Cg, lpeg.Ct, lpeg.P, lpeg.S, lpeg.match
+local formatters = string.formatters
local report_metapost = logs.reporter("metapost")
@@ -97,7 +98,7 @@ end
function pdfflusher.comment(message)
if message then
- message = format("%% mps graphic %s: %s", metapost.n, message)
+ message = formatters["%% mps graphic %s: %s"](metapost.n,message)
if experiment then
context(pdfliteral(message))
else
@@ -189,11 +190,11 @@ local function flushnormalpath(path, t, open)
nt = nt + 1
pth = path[i]
if not ith then
- t[nt] = format("%f %f m",pth.x_coord,pth.y_coord)
+ t[nt] = formatters["%f %f m"](pth.x_coord,pth.y_coord)
elseif curved(ith,pth) then
- t[nt] = format("%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)
+ t[nt] = formatters["%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
- t[nt] = format("%f %f l",pth.x_coord,pth.y_coord)
+ t[nt] = formatters["%f %f l"](pth.x_coord,pth.y_coord)
end
ith = pth
end
@@ -201,15 +202,15 @@ local function flushnormalpath(path, t, open)
nt = nt + 1
local one = path[1]
if curved(pth,one) then
- t[nt] = format("%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 )
+ t[nt] = formatters["%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
- t[nt] = format("%f %f l",one.x_coord,one.y_coord)
+ t[nt] = formatters["%f %f l"](one.x_coord,one.y_coord)
end
elseif #path == 1 then
-- special case .. draw point
local one = path[1]
nt = nt + 1
- t[nt] = format("%f %f l",one.x_coord,one.y_coord)
+ t[nt] = formatters["%f %f l"](one.x_coord,one.y_coord)
end
return t
end
@@ -223,18 +224,18 @@ local function flushconcatpath(path, t, open)
nt = 0
end
nt = nt + 1
- t[nt] = format("%f %f %f %f %f %f cm", sx, rx, ry, sy, tx ,ty)
+ t[nt] = formatters["%f %f %f %f %f %f cm"](sx,rx,ry,sy,tx,ty)
for i=1,#path do
nt = nt + 1
pth = path[i]
if not ith then
- t[nt] = format("%f %f m",mpconcat(pth.x_coord,pth.y_coord))
+ t[nt] = formatters["%f %f m"](mpconcat(pth.x_coord,pth.y_coord))
elseif curved(ith,pth) then
local a, b = mpconcat(ith.right_x,ith.right_y)
local c, d = mpconcat(pth.left_x,pth.left_y)
- t[nt] = format("%f %f %f %f %f %f c",a,b,c,d,mpconcat(pth.x_coord,pth.y_coord))
+ t[nt] = formatters["%f %f %f %f %f %f c"](a,b,c,d,mpconcat(pth.x_coord,pth.y_coord))
else
- t[nt] = format("%f %f l",mpconcat(pth.x_coord, pth.y_coord))
+ t[nt] = formatters["%f %f l"](mpconcat(pth.x_coord, pth.y_coord))
end
ith = pth
end
@@ -244,15 +245,15 @@ local function flushconcatpath(path, t, open)
if curved(pth,one) then
local a, b = mpconcat(pth.right_x,pth.right_y)
local c, d = mpconcat(one.left_x,one.left_y)
- t[nt] = format("%f %f %f %f %f %f c",a,b,c,d,mpconcat(one.x_coord, one.y_coord))
+ t[nt] = formatters["%f %f %f %f %f %f c"](a,b,c,d,mpconcat(one.x_coord, one.y_coord))
else
- t[nt] = format("%f %f l",mpconcat(one.x_coord,one.y_coord))
+ t[nt] = formatters["%f %f l"](mpconcat(one.x_coord,one.y_coord))
end
elseif #path == 1 then
-- special case .. draw point
nt = nt + 1
local one = path[1]
- t[nt] = format("%f %f l",mpconcat(one.x_coord,one.y_coord))
+ t[nt] = formatters["%f %f l"](mpconcat(one.x_coord,one.y_coord))
end
return t
end
@@ -319,7 +320,7 @@ function metapost.flush(result,flusher,askedfig)
elseif objecttype == "text" then
t[#t+1] = "q"
local ot = object.transform -- 3,4,5,6,1,2
- t[#t+1] = format("%f %f %f %f %f %f cm",ot[3],ot[4],ot[5],ot[6],ot[1],ot[2]) -- TH: format("%f %f m %f %f %f %f 0 0 cm",unpack(ot))
+ t[#t+1] = formatters["%f %f %f %f %f %f cm"](ot[3],ot[4],ot[5],ot[6],ot[1],ot[2]) -- TH: formatters["%f %f m %f %f %f %f 0 0 cm"](unpack(ot))
flushfigure(t) -- flush accumulated literals
t = { }
textfigure(object.font,object.dsize,object.text,object.width,object.height,object.depth)
@@ -344,21 +345,21 @@ function metapost.flush(result,flusher,askedfig)
local ml = object.miterlimit
if ml and ml ~= miterlimit then
miterlimit = ml
- t[#t+1] = format("%f M",ml)
+ t[#t+1] = formatters["%f M"](ml)
end
local lj = object.linejoin
if lj and lj ~= linejoin then
linejoin = lj
- t[#t+1] = format("%i j",lj)
+ t[#t+1] = formatters["%i j"](lj)
end
local lc = object.linecap
if lc and lc ~= linecap then
linecap = lc
- t[#t+1] = format("%i J",lc)
+ t[#t+1] = formatters["%i J"](lc)
end
local dl = object.dash
if dl then
- local d = format("[%s] %f d",concat(dl.dashes or {}," "),dl.offset)
+ local d = formatters["[%s] %f d"](concat(dl.dashes or {}," "),dl.offset)
if d ~= dashed then
dashed = d
t[#t+1] = dashed
@@ -374,7 +375,7 @@ function metapost.flush(result,flusher,askedfig)
if pen then
if pen.type == 'elliptical' then
transformed, penwidth = pen_characteristics(original) -- boolean, value
- t[#t+1] = format("%f w",penwidth) -- todo: only if changed
+ t[#t+1] = formatters["%f w"](penwidth) -- todo: only if changed
if objecttype == 'fill' then
objecttype = 'both'
end
diff --git a/tex/context/base/mlib-pps.lua b/tex/context/base/mlib-pps.lua
index 78e35d8b0..3a6f0dc77 100644
--- a/tex/context/base/mlib-pps.lua
+++ b/tex/context/base/mlib-pps.lua
@@ -15,7 +15,6 @@ local round = math.round
local insert, concat = table.insert, table.concat
local Cs, Cf, C, Cg, Ct, P, S, V, Carg = lpeg.Cs, lpeg.Cf, lpeg.C, lpeg.Cg, lpeg.Ct, lpeg.P, lpeg.S, lpeg.V, lpeg.Carg
local lpegmatch = lpeg.match
-
local formatters = string.formatters
local mplib, metapost, lpdf, context = mplib, metapost, lpdf, context
@@ -665,7 +664,7 @@ function makempy.processgraphics(graphics)
local data = io.loaddata(mpyfile)
for figure in gmatch(data,"beginfig(.-)endfig") do
r = r + 1
- result[r] = format("begingraphictextfig%sendgraphictextfig ;\n", figure)
+ result[r] = formatters["begingraphictextfig%sendgraphictextfig ;\n"](figure)
end
io.savedata(mpyfile,concat(result,""))
end
@@ -800,91 +799,6 @@ local function cl_reset(t)
t[#t+1] = metapost.colorinitializer() -- only color
end
--- text
-
--- local tx_done = { }
---
--- local function tx_reset()
--- tx_done = { }
--- end
---
--- local function tx_analyze(object,prescript) -- todo: hash content and reuse them
--- local tx_stage = prescript.tx_stage
--- if tx_stage then
--- local tx_number = tonumber(prescript.tx_number)
--- if not tx_done[tx_number] then
--- tx_done[tx_number] = true
--- if trace_textexts then
--- report_textexts("setting %s %s (first pass)",tx_stage,tx_number)
--- end
--- local s = object.postscript or ""
--- local c = object.color -- only simple ones, no transparency
--- local a = prescript.tr_alternative
--- local t = prescript.tr_transparency
--- if not c then
--- -- no color
--- elseif #c == 1 then
--- if a and t then
--- s = format("\\directcolored[s=%f,a=%f,t=%f]%s",c[1],a,t,s)
--- else
--- s = format("\\directcolored[s=%f]%s",c[1],s)
--- end
--- elseif #c == 3 then
--- if a and t then
--- s = format("\\directcolored[r=%f,g=%f,b=%f,a=%f,t=%f]%s",c[1],c[2],c[3],a,t,s)
--- else
--- s = format("\\directcolored[r=%f,g=%f,b=%f]%s",c[1],c[2],c[3],s)
--- end
--- elseif #c == 4 then
--- if a and t then
--- s = format("\\directcolored[c=%f,m=%f,y=%f,k=%f,a=%f,t=%f]%s",c[1],c[2],c[3],c[4],a,t,s)
--- else
--- s = format("\\directcolored[c=%f,m=%f,y=%f,k=%f]%s",c[1],c[2],c[3],c[4],s)
--- end
--- end
--- context.MPLIBsettext(tx_number,s) -- combine colored in here, saves call
--- metapost.multipass = true
--- end
--- end
--- end
---
--- local function tx_process(object,prescript,before,after)
--- local tx_number = prescript.tx_number
--- if tx_number then
--- tx_number = tonumber(tx_number)
--- local tx_stage = prescript.tx_stage
--- if tx_stage == "final" then -- redundant test
--- if trace_textexts then
--- report_textexts("processing %s (second pass)",tx_number)
--- end
--- local sx,rx,ry,sy,tx,ty = cm(object) -- outside function !
--- before[#before+1] = function()
--- -- flush always happens, we can have a special flush function injected before
--- local box = textexts[tx_number]
--- if box then
--- context.MPLIBgettextscaledcm(tx_number,
--- format("%f",sx), -- bah ... %s no longer checks
--- format("%f",rx), -- bah ... %s no longer checks
--- format("%f",ry), -- bah ... %s no longer checks
--- format("%f",sy), -- bah ... %s no longer checks
--- format("%f",tx), -- bah ... %s no longer checks
--- format("%f",ty), -- bah ... %s no longer checks
--- sxsy(box.width,box.height,box.depth))
--- else
--- report_textexts("unknown %s",tx_number)
--- end
--- end
--- if not trace_textexts then
--- object.path = false -- else: keep it
--- end
--- object.color = false
--- object.grouped = true
--- end
--- end
--- end
-
--- experiment
-
local tx_hash = { }
local tx_last = 0
@@ -915,21 +829,21 @@ local function tx_analyze(object,prescript) -- todo: hash content and reuse them
-- no color
elseif #c == 1 then
if a and t then
- s = format("\\directcolored[s=%f,a=%f,t=%f]%s",c[1],a,t,s)
+ s = formatters["\\directcolored[s=%f,a=%f,t=%f]%s"](c[1],a,t,s)
else
- s = format("\\directcolored[s=%f]%s",c[1],s)
+ s = formatters["\\directcolored[s=%f]%s"](c[1],s)
end
elseif #c == 3 then
if a and t then
- s = format("\\directcolored[r=%f,g=%f,b=%f,a=%f,t=%f]%s",c[1],c[2],c[3],a,t,s)
+ s = formatters["\\directcolored[r=%f,g=%f,b=%f,a=%f,t=%f]%s"](c[1],c[2],c[3],a,t,s)
else
- s = format("\\directcolored[r=%f,g=%f,b=%f]%s",c[1],c[2],c[3],s)
+ s = formatters["\\directcolored[r=%f,g=%f,b=%f]%s"](c[1],c[2],c[3],s)
end
elseif #c == 4 then
if a and t then
- s = format("\\directcolored[c=%f,m=%f,y=%f,k=%f,a=%f,t=%f]%s",c[1],c[2],c[3],c[4],a,t,s)
+ s = formatters["\\directcolored[c=%f,m=%f,y=%f,k=%f,a=%f,t=%f]%s"](c[1],c[2],c[3],c[4],a,t,s)
else
- s = format("\\directcolored[c=%f,m=%f,y=%f,k=%f]%s",c[1],c[2],c[3],c[4],s)
+ s = formatters["\\directcolored[c=%f,m=%f,y=%f,k=%f]%s"](c[1],c[2],c[3],c[4],s)
end
end
context.MPLIBsettext(tx_last,s)
@@ -1022,7 +936,7 @@ end
local function gt_analyze(object,prescript)
local gt_stage = prescript.gt_stage
if gt_stage == "trial" then
- graphics[#graphics+1] = format("\\MPLIBgraphictext{%s}",object.postscript or "")
+ graphics[#graphics+1] = formatters["\\MPLIBgraphictext{%s}"](object.postscript or "")
metapost.intermediate.needed = true
metapost.multipass = true
end
@@ -1098,7 +1012,7 @@ local function sh_process(object,prescript,before,after)
else
-- fatal error
end
- before[#before+1], after[#after+1] = "q /Pattern cs", format("W n /%s sh Q",name)
+ before[#before+1], after[#after+1] = "q /Pattern cs", formatters["W n /%s sh Q"](name)
-- false, not nil, else mt triggered
object.colored = false -- hm, not object.color ?
object.type = false
@@ -1179,7 +1093,7 @@ local function tr_process(object,prescript,before,after)
if tr_alternative then
tr_alternative = tonumber(tr_alternative)
local tr_transparency = tonumber(prescript.tr_transparency)
- before[#before+1] = format("/Tr%s gs",registertransparency(nil,tr_alternative,tr_transparency,true))
+ before[#before+1] = formatters["/Tr%s gs"](registertransparency(nil,tr_alternative,tr_transparency,true))
after[#after+1] = "/Tr0 gs" -- outertransparency
end
local cs = object.color
@@ -1209,7 +1123,7 @@ local function tr_process(object,prescript,before,after)
local t = t_list[sp_name] -- string or attribute
local v = t and attributes.transparencies.value(t)
if v then
- before[#before+1] = format("/Tr%s gs",registertransparency(nil,v[1],v[2],true))
+ before[#before+1] = formatters["/Tr%s gs"](registertransparency(nil,v[1],v[2],true))
after[#after+1] = "/Tr0 gs" -- outertransparency
end
end
diff --git a/tex/context/base/mlib-run.lua b/tex/context/base/mlib-run.lua
index 35cbd40f5..5adf43b46 100644
--- a/tex/context/base/mlib-run.lua
+++ b/tex/context/base/mlib-run.lua
@@ -444,10 +444,10 @@ function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass,
if trace_tracingall then
mpx:execute("tracingall;")
end
--- table.insert(data,2,"")
+ -- table.insert(data,2,"")
for i=1,#data do
local d = data[i]
--- d = string.gsub(d,"\r","")
+ -- d = string.gsub(d,"\r","")
if d then
if trace_graphics then
mp_inp[mpx]:write(format("\n%% begin snippet %s\n",i))
diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf
index 6fb7f16c3..4803e083f 100644
--- a/tex/context/base/status-files.pdf
+++ b/tex/context/base/status-files.pdf
Binary files differ
diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf
index 19170f8b0..a0bbca101 100644
--- a/tex/context/base/status-lua.pdf
+++ b/tex/context/base/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/typo-del.mkiv b/tex/context/base/typo-del.mkiv
index 8dfb2d461..b48c71e58 100644
--- a/tex/context/base/typo-del.mkiv
+++ b/tex/context/base/typo-del.mkiv
@@ -476,6 +476,7 @@
\fi
\strut % new, needed below
\delimitedtextparameter#1% unhbox\scratchbox
+ \penalty\plustenthousand % new per 2013-03-09 WS mailing list
\hskip\d_typo_delimited_signal % +- \prewordbreak
\fi
\endgroup}
diff --git a/tex/context/base/typo-prc.lua b/tex/context/base/typo-prc.lua
index bb965ff66..ae9b541bf 100644
--- a/tex/context/base/typo-prc.lua
+++ b/tex/context/base/typo-prc.lua
@@ -9,7 +9,7 @@ if not modules then modules = { } end modules ['typo-prc'] = {
-- moved from strc-ini.lua
-local format = string.format
+local formatters = string.formatters
local lpegmatch, patterns, P, C, Cs = lpeg.match, lpeg.patterns, lpeg.P, lpeg.C, lpeg.Cs
-- processors: syntax: processor->data ... not ok yet
@@ -108,7 +108,7 @@ end
function processors.tostring(str)
local p, s = lpegmatch(splitter,str)
if registered[p] then
- return format("\\applyprocessor{%s}{%s}",p,s)
+ return formatters["\\applyprocessor{%s}{%s}"](p,s)
else
return str
end
diff --git a/tex/context/base/util-fmt.lua b/tex/context/base/util-fmt.lua
index e049d0b94..371a5dfce 100644
--- a/tex/context/base/util-fmt.lua
+++ b/tex/context/base/util-fmt.lua
@@ -14,28 +14,8 @@ local concat, format = table.concat, string.format
local tostring, type = tostring, type
local strip = string.strip
-local P, R, Cs = lpeg.P, lpeg.R, lpeg.Cs
local lpegmatch = lpeg.match
-
--- temporary here
-
-local digit = R("09")
-local period = P(".")
-local zero = P("0")
-local trailingzeros = zero^0 * -digit -- suggested by Roberto R
-local case_1 = period * trailingzeros / ""
-local case_2 = period * (digit - trailingzeros)^1 * (trailingzeros / "")
-local number = digit^1 * (case_1 + case_2)
-local stripper = Cs((number + 1)^0)
-
---~ local sample = "bla 11.00 bla 11 bla 0.1100 bla 1.00100 bla 0.00 bla 0.001 bla 1.1100 bla 0.100100100 bla 0.00100100100"
---~ collectgarbage("collect")
---~ str = string.rep(sample,10000)
---~ local ts = os.clock()
---~ lpegmatch(stripper,str)
---~ print(#str, os.clock()-ts, lpegmatch(stripper,sample))
-
-lpeg.patterns.stripzeros = stripper
+local stripper = lpeg.patterns.stripzeros
function formatters.stripzeros(str)
return lpegmatch(stripper,str)
diff --git a/tex/context/base/util-lua.lua b/tex/context/base/util-lua.lua
index 36daaff55..96101f8ec 100644
--- a/tex/context/base/util-lua.lua
+++ b/tex/context/base/util-lua.lua
@@ -7,6 +7,8 @@ if not modules then modules = { } end modules ['util-lua'] = {
license = "see context related readme files"
}
+-- we will remove the 5.1 code some day soon
+
local rep, sub, byte, dump, format = string.rep, string.sub, string.byte, string.dump, string.format
local load, loadfile, type = load, loadfile, type
@@ -126,6 +128,13 @@ if jit or status.luatex_version >= 74 then
return done
end
+ function luautilities.loadstripped(...)
+ local l = load(...)
+ if l then
+ return load(dump(l,true))
+ end
+ end
+
else
-- The next function was posted by Peter Cawley on the lua list and strips line
@@ -319,6 +328,8 @@ else
return done
end
+ luautilities.loadstripped = loadstring
+
end
-- local getmetatable, type = getmetatable, type
diff --git a/tex/context/base/util-seq.lua b/tex/context/base/util-seq.lua
index 0bf056365..27f95f0ee 100644
--- a/tex/context/base/util-seq.lua
+++ b/tex/context/base/util-seq.lua
@@ -258,7 +258,7 @@ compile = function(t,compiler,n) -- already referred to in sequencers.new
if compiled == "" then
runner = false
else
- runner = compiled and load(compiled)()
+ runner = compiled and load(compiled)() -- we can use loadstripped here
end
t.runner = runner
return runner
diff --git a/tex/context/base/util-str.lua b/tex/context/base/util-str.lua
index a4889d252..959955867 100644
--- a/tex/context/base/util-str.lua
+++ b/tex/context/base/util-str.lua
@@ -10,14 +10,18 @@ utilities = utilities or {}
utilities.strings = utilities.strings or { }
local strings = utilities.strings
-local load = load
local format, gsub, rep, sub = string.format, string.gsub, string.rep, string.sub
+local load, dump = load, string.dump
local concat = table.concat
-local P, V, C, S, R, Ct, Cs, Cp, Carg = lpeg.P, lpeg.V, lpeg.C, lpeg.S, lpeg.R, lpeg.Ct, lpeg.Cs, lpeg.Cp, lpeg.Carg
+local P, V, C, S, R, Ct, Cs, Cp, Carg, Cc = lpeg.P, lpeg.V, lpeg.C, lpeg.S, lpeg.R, lpeg.Ct, lpeg.Cs, lpeg.Cp, lpeg.Carg, lpeg.Cc
local patterns, lpegmatch = lpeg.patterns, lpeg.match
local utfchar, utfbyte = utf.char, utf.byte
-local setmetatableindex = table.setmetatableindex
---
+----- loadstripped = utilities.lua.loadstripped
+----- setmetatableindex = table.setmetatableindex
+
+local loadstripped = _LUAVERSION < 5.2 and load or function(str)
+ return load(dump(load(str),true)) -- it only makes sense in luajit and luatex where we have a stipped load
+end
local stripper = patterns.stripzeros
@@ -65,7 +69,7 @@ function strings.newrepeater(str,offset)
return t
end
t = { }
- setmetatableindex(t, function(t,k)
+ setmetatable(t, { __index = function(t,k)
if not k then
return ""
end
@@ -73,7 +77,7 @@ function strings.newrepeater(str,offset)
local s = n > 0 and rep(str,n) or ""
t[k] = s
return s
- end)
+ end })
s[offset] = t
return t
end
@@ -85,6 +89,8 @@ local extra, tab, start = 0, 0, 4, 0
local nspaces = strings.newrepeater(" ")
+string.nspaces = nspaces
+
local pattern =
Carg(1) / function(t)
extra, tab, start = 0, t or 7, 1
@@ -144,6 +150,13 @@ end
-- Work in progress. Interesting is that compared to the built-in this
-- is faster in luatex than in luajittex where we have a comparable speed.
+-- It only makes sense to use the formatter when a (somewhat) complex format
+-- is used a lot. Each formatter is a function so there is some overhead
+-- and not all formatted output is worth that overhead. Keep in mind that
+-- there is an extra function call involved. In principle we end up with a
+-- string concatination so one could inline such a sequence but often at the
+-- cost of less readabinity. So, it's a sort of (visual) compromise. Of course
+-- there is the benefit of more variants.
local n = 0
@@ -155,6 +168,20 @@ local n = 0
-- print(...,...,...) -- 1,1,1,2,3
-- end
+local template_shortcuts = [[
+local tostring = tostring
+local format = string.format
+local concat = table.concat
+local signed = number.signed
+local points = number.points
+local basepoints = number.basepoints
+local utfchar = utf.char
+local utfbyte = utf.byte
+local lpegmatch = lpeg.match
+local xmlescape = lpeg.patterns.xmlescape
+local spaces = string.nspaces
+]]
+
local prefix_any = C((S("+- .") + R("09"))^0)
local prefix_tab = C((1-R("az","AZ","09","%%"))^0)
@@ -163,23 +190,37 @@ local prefix_tab = C((1-R("az","AZ","09","%%"))^0)
local format_s = function(f)
n = n + 1
if f and f ~= "" then
- return format("format('%%%ss',(select(%s,...)))",f,n)
+ return format("format('%%%ss',a%s)",f,n)
+ else
+ return format("a%s",n)
+ end
+end
+
+local format_S = function(f) -- can be optimized
+ n = n + 1
+ if f and f ~= "" then
+ return format("format('%%%ss',tostring(a%s))",f,n)
else
- return format("(select(%s,...))",n)
+ return format("tostring(a%s)",n)
end
end
local format_q = function()
n = n + 1
- return format("format('%%q',(select(%s,...)))",n) -- maybe an own lpeg
+ return format("format('%%q',a%s)",n) -- maybe an own lpeg
+end
+
+local format_Q = function() -- can be optimized
+ n = n + 1
+ return format("format('%%q',tostring(a%s))",n)
end
local format_i = function(f)
n = n + 1
if f and f ~= "" then
- return format("format('%%%si',(select(%s,...)))",f,n)
+ return format("format('%%%si',a%s)",f,n)
else
- return format("(select(%s,...))",n)
+ return format("a%s",n)
end
end
@@ -196,79 +237,79 @@ end
local format_I = function(f)
n = n + 1
if f and f ~= "" then
- return format("format('%%s%%%si',signed((select(%s,...))))",f,n)
+ return format("format('%%s%%%si',signed(a%s))",f,n)
else
- return format("format('%%s%%i',signed((select(%s,...))))",n)
+ return format("format('%%s%%i',signed(a%s))",n)
end
end
local format_f = function(f)
n = n + 1
- return format("format('%%%sf',(select(%s,...)))",f,n)
+ return format("format('%%%sf',a%s)",f,n)
end
local format_g = function(f)
n = n + 1
- return format("format('%%%sg',(select(%s,...)))",f,n)
+ return format("format('%%%sg',a%s)",f,n)
end
local format_G = function(f)
n = n + 1
- return format("format('%%%sG',(select(%s,...)))",f,n)
+ return format("format('%%%sG',a%s)",f,n)
end
local format_e = function(f)
n = n + 1
- return format("format('%%%se',(select(%s,...)))",f,n)
+ return format("format('%%%se',a%s)",f,n)
end
local format_E = function(f)
n = n + 1
- return format("format('%%%sE',(select(%s,...)))",f,n)
+ return format("format('%%%sE',a%s)",f,n)
end
local format_x = function(f)
n = n + 1
- return format("format('%%%sx',(select(%s,...)))",f,n)
+ return format("format('%%%sx',a%s)",f,n)
end
local format_X = function(f)
n = n + 1
- return format("format('%%%sX',(select(%s,...)))",f,n)
+ return format("format('%%%sX',a%s)",f,n)
end
local format_o = function(f)
n = n + 1
- return format("format('%%%so',(select(%s,...)))",f,n)
+ return format("format('%%%so',a%s)",f,n)
end
local format_c = function()
n = n + 1
- return format("utfchar((select(%s,...)))",n)
+ return format("utfchar(a%s)",n)
end
local format_r = function(f)
n = n + 1
- return format("format('%%%s.0f',(select(%s,...)))",f,n)
+ return format("format('%%%s.0f',a%s)",f,n)
end
-local format_v = function(f)
+local format_h = function(f)
n = n + 1
if f == "-" then
f = sub(f,2)
- return format("format('%%%sx',utfbyte((select(%s,...))))",f == "" and "05" or f,n)
+ return format("format('%%%sx',utfbyte(a%s))",f == "" and "05" or f,n)
else
- return format("format('0x%%%sx',utfbyte((select(%s,...))))",f == "" and "05" or f,n)
+ return format("format('0x%%%sx',utfbyte(a%s))",f == "" and "05" or f,n)
end
end
-local format_V = function(f)
+local format_H = function(f)
n = n + 1
if f == "-" then
f = sub(f,2)
- return format("format('%%%sX',utfbyte((select(%s,...))))",f == "" and "05" or f,n)
+ return format("format('%%%sX',utfbyte(a%s))",f == "" and "05" or f,n)
else
- return format("format('0x%%%sX',utfbyte((select(%s,...))))",f == "" and "05" or f,n)
+ return format("format('0x%%%sX',utfbyte(a%s))",f == "" and "05" or f,n)
end
end
@@ -276,9 +317,9 @@ local format_u = function(f)
n = n + 1
if f == "-" then
f = sub(f,2)
- return format("format('%%%sx',utfbyte((select(%s,...))))",f == "" and "05" or f,n)
+ return format("format('%%%sx',utfbyte(a%s))",f == "" and "05" or f,n)
else
- return format("format('u+%%%sx',utfbyte((select(%s,...))))",f == "" and "05" or f,n)
+ return format("format('u+%%%sx',utfbyte(a%s))",f == "" and "05" or f,n)
end
end
@@ -286,57 +327,117 @@ local format_U = function(f)
n = n + 1
if f == "-" then
f = sub(f,2)
- return format("format('%%%sX',utfbyte((select(%s,...))))",f == "" and "05" or f,n)
+ return format("format('%%%sX',utfbyte(a%s))",f == "" and "05" or f,n)
else
- return format("format('U+%%%sX',utfbyte((select(%s,...))))",f == "" and "05" or f,n)
+ return format("format('U+%%%sX',utfbyte(a%s))",f == "" and "05" or f,n)
end
end
local format_p = function()
n = n + 1
- return format("points((select(%s,...)))",n)
+ return format("points(a%s)",n)
end
local format_b = function()
n = n + 1
- return format("basepoints((select(%s,...)))",n)
+ return format("basepoints(a%s)",n)
end
local format_t = function(f)
n = n + 1
if f and f ~= "" then
- return format("concat((select(%s,...)),%q)",n,f)
+ return format("concat(a%s,%q)",n,f)
else
- return format("concat((select(%s,...)))",n)
+ return format("concat(a%s)",n)
end
end
local format_l = function()
n = n + 1
- return format("(select(%s,...) and 'true' or 'false')",n)
+ return format("(a%s and 'true' or 'false')",n)
+end
+
+local format_L = function()
+ n = n + 1
+ return format("(a%s and 'TRUE' or 'FALSE')",n)
+end
+
+local format_N = function() -- strips leading zeros
+ n = n + 1
+ return format("tostring(tonumber(a%s) or a%s)",n,n)
end
local format_a = function(s)
return format("%q",s)
end
-local builder = Ct { "start",
- start = (P("%") * (
- V("s") + V("q")
- + V("i") + V("d")
- + V("f") + V("g") + V("G") + V("e") + V("E")
- + V("x") + V("X") + V("o")
- --
- + V("c")
- --
- + V("r")
- + V("v") + V("V") + V("u") + V("U")
- + V("p") + V("b")
- + V("t")
- + V("l")
- + V("I")
- )
- + V("a")
+local format_w = function(f) -- handy when doing depth related indent
+ n = n + 1
+ f = tonumber(f)
+ if f then
+ return format("spaces[%s+tonumber(a%s)]",f,n)
+ else
+ return format("spaces[tonumber(a%s)]",n)
+ end
+end
+
+local format_W = function(f) -- handy when doing depth related indent
+ return format("spaces[%s]",tonumber(f) or 0)
+end
+
+local extensions = { }
+
+local format_extension = function(name)
+ n = n + 1
+ local extension = extensions[name] or "tostring(%s)"
+ return format(extension,format("a%s",n))
+end
+
+function addextension(name,template,shortcuts)
+ extensions[name] = template
+ if shortcuts then
+ template_shortcuts = shortcuts .. "\n" .. template_shortcuts -- so we can't overload
+ end
+end
+
+lpeg.patterns.xmlescape = Cs((P("<")/"&lt;" + P(">")/"&gt;" + P("&")/"&amp;" + P('"')/"&quot;" + P(1))^0)
+lpeg.patterns.texescape = Cs((C(S("#$%\\{}"))/"\\%1" + P(1))^0)
+
+addextension("xml",[[lpegmatch(xmlescape,%s)]],[[local xmlescape = lpeg.patterns.xmlescape]])
+addextension("tex",[[lpegmatch(texescape,%s)]],[[local texescape = lpeg.patterns.texescape]])
+
+local builder = Cs { "start",
+ start = (
+ (
+ P("%") / ""
+ * (
+ V("!") -- new
+ + V("s") + V("q")
+ + V("i") + V("d")
+ + V("f") + V("g") + V("G") + V("e") + V("E")
+ + V("x") + V("X") + V("o")
+ --
+ + V("c")
+ + V("S") -- new
+ + V("Q") -- new
+ + V("N") -- new
+ --
+ + V("r")
+ + V("h") + V("H") + V("u") + V("U")
+ + V("p") + V("b")
+ + V("t")
+ + V("l") + V("L")
+ + V("I")
+ + V("h") -- new
+ + V("w") -- new
+ + V("W") -- new
+ --
+ + V("a") -- ignores probably messed up %
+ )
+ + V("a")
+ )
+-- * (P(-1) + Cc(".."))
+ * (P(-1) + Carg(1))
)^0,
--
["s"] = (prefix_any * P("s")) / format_s, -- %s => regular %s (string)
@@ -352,61 +453,132 @@ local builder = Ct { "start",
["X"] = (prefix_any * P("X")) / format_X, -- %X => regular %X (HEXADECIMAL)
["o"] = (prefix_any * P("o")) / format_o, -- %o => regular %o (octal)
--
+ ["S"] = (prefix_any * P("S")) / format_S, -- %S => %s (tostring)
+ ["Q"] = (prefix_any * P("Q")) / format_S, -- %Q => %q (tostring)
+ ["N"] = (prefix_any * P("N")) / format_N, -- %N => tonumber (strips leading zeros)
["c"] = (prefix_any * P("c")) / format_c, -- %c => utf character (extension to regular)
--
["r"] = (prefix_any * P("r")) / format_r, -- %r => round
- ["v"] = (prefix_any * P("v")) / format_v, -- %v => 0x0a1b2 (when - no 0x)
- ["V"] = (prefix_any * P("V")) / format_V, -- %V => 0x0A1B2 (when - no 0x)
+ ["h"] = (prefix_any * P("h")) / format_h, -- %h => 0x0a1b2 (when - no 0x) was v
+ ["H"] = (prefix_any * P("H")) / format_H, -- %H => 0x0A1B2 (when - no 0x) was V
["u"] = (prefix_any * P("u")) / format_u, -- %u => u+0a1b2 (when - no u+)
["U"] = (prefix_any * P("U")) / format_U, -- %U => U+0A1B2 (when - no U+)
["p"] = (prefix_any * P("p")) / format_p, -- %p => 12.345pt / maybe: P (and more units)
["b"] = (prefix_any * P("b")) / format_b, -- %b => 12.342bp / maybe: B (and more units)
["t"] = (prefix_tab * P("t")) / format_t, -- %t => concat
["l"] = (prefix_tab * P("l")) / format_l, -- %l => boolean
+ ["L"] = (prefix_tab * P("L")) / format_L, -- %L => BOOLEAN
["I"] = (prefix_any * P("I")) / format_I, -- %I => signed integer
--
- ["a"] = Cs(((1-P("%"))^1 + P("%%")/"%%")^1) / format_a, -- %a => text (including %%)
+ ["w"] = (prefix_any * P("w")) / format_w, -- %w => n spaces (optional prefix is added)
+ ["W"] = (prefix_any * P("W")) / format_W, -- %w => mandate prefix, no specifier
+ --
+ ["a"] = Cs(((1-P("%"))^1 + P("%%")/"%%%%")^1) / format_a, -- rest (including %%)
+ --
+ -- ["!"] = P("!xml!") / format_xml, -- %!xml! => hypertext escaped " < > &
+ ["!"] = P("!") * C((1-P("!"))^1) * P("!") / format_extension,
}
-- we can be clever and only alias what is needed
-local template = [[
-local format = string.format
-local concat = table.concat
-local signed = number.signed
-local points = number.points
-local basepoints = number.basepoints
-local utfchar = utf.char
-local utfbyte = utf.byte
-return function(...)
- return %s
-end
+local direct = Cs (
+ P("%")/""
+ * Cc([[local format = string.format return function(str) return format("%]])
+ * C(S("+- .") + R("09"))^0 * S("sqidfgGeExXo")
+ * Cc([[",str) end]])
+ * P(-1)
+ )
+
+local template = [[
+%s
+return function(%s) return %s end
]]
+local arguments = { "a1" } -- faster than previously used (select(n,...))
+
+setmetatable(arguments, { __index =
+ function(t,k)
+ local v = t[k-1] .. ",a" .. k
+ t[k] = v
+ return v
+ end
+})
+
local function make(t,str)
- n = 0
- local p = lpegmatch(builder,str)
--- inspect(p)
- local c = format(template,concat(p,".."))
--- inspect(c)
- formatter = load(c)()
- t[str] = formatter
- return formatter
+ local f
+ local p = lpegmatch(direct,str)
+ if p then
+ f = loadstripped(p)()
+ else
+ n = 0
+ p = lpegmatch(builder,str,1,"..") -- after this we know n
+ if n > 0 then
+ p = format(template,template_shortcuts,arguments[n],p)
+ -- print("builder>",p)
+ f = loadstripped(p)()
+ else
+ f = function() return str end
+ end
+ end
+ t[str] = f
+ return f
+end
+
+local function use(t,fmt,...)
+ return t[fmt](...)
end
local formatters = string.formatters or { }
string.formatters = formatters
-setmetatableindex(formatters,make)
+setmetatable(formatters, { __index = make, __call = use })
-function string.makeformatter(str)
+-- -- yes or no:
+--
+-- local function make(t,str)
+-- local f
+-- local p = lpegmatch(direct,str)
+-- if p then
+-- f = loadstripped(p)()
+-- else
+-- n = 0
+-- p = lpegmatch(builder,str,1,",") -- after this we know n
+-- if n > 0 then
+-- p = format(template,template_shortcuts,arguments[n],p)
+-- f = loadstripped(p)()
+-- else
+-- f = function() return str end
+-- end
+-- end
+-- t[str] = f
+-- return f
+-- end
+--
+-- local formatteds = string.formatteds or { }
+-- string.formatteds = formatteds
+--
+-- setmetatable(formatteds, { __index = make, __call = use })
+
+--
+
+-- print(formatters["hans %N and %N done"](123,"0123"))
+-- local test = formatters["1%%23%4w56%s78 %p %!xml! test and %!tex! more %s"]
+-- print(#string.dump(test))
+-- print(test(2,123,99999,"abc&def","# and $","okay","!!!"))
+-- local test = formatters["%s"]
+-- print(#string.dump(test))
+-- print(test("okay"))
+
+function string.makeformatter(str) -- redundant
return formatters[str]
end
-function string.formatter(str,...)
+function string.formatter(str,...) -- redundant
return formatters[str](...)
end
+string.addformatter = addextension
+
-- local p1 = "%s test %f done %p and %c and %V or %+t or %%"
-- local p2 = "%s test %f done %s and %s and 0x%05X or %s or %%"
--
diff --git a/tex/context/base/util-tab.lua b/tex/context/base/util-tab.lua
index 539d70d1b..9efdae4d6 100644
--- a/tex/context/base/util-tab.lua
+++ b/tex/context/base/util-tab.lua
@@ -10,12 +10,13 @@ utilities = utilities or {}
utilities.tables = utilities.tables or { }
local tables = utilities.tables
-local format, gmatch, rep, gsub = string.format, string.gmatch, string.rep, string.gsub
+local format, gmatch, gsub = string.format, string.gmatch, string.gsub
local concat, insert, remove = table.concat, table.insert, table.remove
local setmetatable, getmetatable, tonumber, tostring = setmetatable, getmetatable, tonumber, tostring
-local type, next, rawset, tonumber, load, select = type, next, rawset, tonumber, load, select
-local lpegmatch, P, Cs = lpeg.match, lpeg.P, lpeg.Cs
-local serialize = table.serialize
+local type, next, rawset, tonumber, tostring, load, select = type, next, rawset, tonumber, tostring, load, select
+local lpegmatch, P, Cs, Cc = lpeg.match, lpeg.P, lpeg.Cs, lpeg.Cc
+local serialize, sortedkeys, sortedpairs = table.serialize, table.sortedkeys, table.sortedpairs
+local formatters = string.formatters
local splitter = lpeg.tsplitat(".")
@@ -126,35 +127,131 @@ end
-- experimental
+local escape = Cs(Cc('"') * ((P('"')/'""' + P(1))^0) * Cc('"'))
+
+function table.tocsv(t,specification)
+ if t and #t > 0 then
+ local result = { }
+ local r = { }
+ specification = specification or { }
+ local fields = specification.fields
+ if type(fields) ~= "string" then
+ fields = sortedkeys(t[1])
+ end
+ local separator = specification.separator or ","
+ if specification.preamble == true then
+ for f=1,#fields do
+ r[f] = lpegmatch(escape,tostring(fields[f]))
+ end
+ result[1] = concat(r,separator)
+ end
+ for i=1,#t do
+ local ti = t[i]
+ for f=1,#fields do
+ local field = ti[fields[f]]
+ if type(field) == "string" then
+ r[f] = lpegmatch(escape,field)
+ else
+ r[f] = tostring(field)
+ end
+ end
+ result[#result+1] = concat(r,separator)
+ end
+ return concat(result,"\n")
+ else
+ return ""
+ end
+end
+
+-- local nspaces = utilities.strings.newrepeater(" ")
+-- local escape = Cs((P("<")/"&lt;" + P(">")/"&gt;" + P("&")/"&amp;" + P(1))^0)
+--
+-- local function toxml(t,d,result,step)
+-- for k, v in sortedpairs(t) do
+-- local s = nspaces[d]
+-- local tk = type(k)
+-- local tv = type(v)
+-- if tv == "table" then
+-- if tk == "number" then
+-- result[#result+1] = format("%s<entry n='%s'>",s,k)
+-- toxml(v,d+step,result,step)
+-- result[#result+1] = format("%s</entry>",s,k)
+-- else
+-- result[#result+1] = format("%s<%s>",s,k)
+-- toxml(v,d+step,result,step)
+-- result[#result+1] = format("%s</%s>",s,k)
+-- end
+-- elseif tv == "string" then
+-- if tk == "number" then
+-- result[#result+1] = format("%s<entry n='%s'>%s</entry>",s,k,lpegmatch(escape,v),k)
+-- else
+-- result[#result+1] = format("%s<%s>%s</%s>",s,k,lpegmatch(escape,v),k)
+-- end
+-- elseif tk == "number" then
+-- result[#result+1] = format("%s<entry n='%s'>%s</entry>",s,k,tostring(v),k)
+-- else
+-- result[#result+1] = format("%s<%s>%s</%s>",s,k,tostring(v),k)
+-- end
+-- end
+-- end
+--
+-- much faster
+
+local nspaces = utilities.strings.newrepeater(" ")
+
local function toxml(t,d,result,step)
- for k, v in table.sortedpairs(t) do
- if type(v) == "table" then
- if type(k) == "number" then
- result[#result+1] = format("%s<entry n='%s'>",d,k)
- toxml(v,d..step,result,step)
- result[#result+1] = format("%s</entry>",d,k)
+ for k, v in sortedpairs(t) do
+ local s = nspaces[d] -- inlining this is somewhat faster but gives more formatters
+ local tk = type(k)
+ local tv = type(v)
+ if tv == "table" then
+ if tk == "number" then
+ result[#result+1] = formatters["%s<entry n='%s'>"](s,k)
+ toxml(v,d+step,result,step)
+ result[#result+1] = formatters["%s</entry>"](s,k)
+ else
+ result[#result+1] = formatters["%s<%s>"](s,k)
+ toxml(v,d+step,result,step)
+ result[#result+1] = formatters["%s</%s>"](s,k)
+ end
+ elseif tv == "string" then
+ if tk == "number" then
+ result[#result+1] = formatters["%s<entry n='%s'>%!xml!</entry>"](s,k,v,k)
else
- result[#result+1] = format("%s<%s>",d,k)
- toxml(v,d..step,result,step)
- result[#result+1] = format("%s</%s>",d,k)
+ result[#result+1] = formatters["%s<%s>%!xml!</%s>"](s,k,v,k)
end
- elseif type(k) == "number" then
- result[#result+1] = format("%s<entry n='%s'>%s</entry>",d,k,v,k)
+ elseif tk == "number" then
+ result[#result+1] = formatters["%s<entry n='%s'>%S</entry>"](s,k,v,k)
else
- result[#result+1] = format("%s<%s>%s</%s>",d,k,tostring(v),k)
+ result[#result+1] = formatters["%s<%s>%S</%s>"](s,k,v,k)
end
end
end
-function table.toxml(t,name,nobanner,indent,spaces)
+-- function table.toxml(t,name,nobanner,indent,spaces)
+-- local noroot = name == false
+-- local result = (nobanner or noroot) and { } or { "<?xml version='1.0' standalone='yes' ?>" }
+-- local indent = rep(" ",indent or 0)
+-- local spaces = rep(" ",spaces or 1)
+-- if noroot then
+-- toxml( t, inndent, result, spaces)
+-- else
+-- toxml( { [name or "root"] = t }, indent, result, spaces)
+-- end
+-- return concat(result,"\n")
+-- end
+
+function table.toxml(t,specification)
+ specification = specification or { }
+ local name = specification.name
local noroot = name == false
- local result = (nobanner or noroot) and { } or { "<?xml version='1.0' standalone='yes' ?>" }
- local indent = rep(" ",indent or 0)
- local spaces = rep(" ",spaces or 1)
+ local result = (specification.nobanner or noroot) and { } or { "<?xml version='1.0' standalone='yes' ?>" }
+ local indent = specification.indent or 0
+ local spaces = specification.spaces or 1
if noroot then
- toxml( t, inndent, result, spaces)
+ toxml( t, indent, result, spaces)
else
- toxml( { [name or "root"] = t }, indent, result, spaces)
+ toxml( { [name or "data"] = t }, indent, result, spaces)
end
return concat(result,"\n")
end
@@ -204,27 +301,27 @@ local function fastserialize(t,r,outer) -- no mixes
local v = t[i]
local tv = type(v)
if tv == "string" then
- r[#r+1] = format("%q,",v)
+ r[#r+1] = formatters["%q,"](v)
elseif tv == "number" then
- r[#r+1] = format("%s,",v)
+ r[#r+1] = formatters["%s,"](v)
elseif tv == "table" then
fastserialize(v,r)
elseif tv == "boolean" then
- r[#r+1] = format("%s,",tostring(v))
+ r[#r+1] = formatters["%S,"](v)
end
end
else
for k, v in next, t do
local tv = type(v)
if tv == "string" then
- r[#r+1] = format("[%q]=%q,",k,v)
+ r[#r+1] = formatters["[%q]=%q,"](k,v)
elseif tv == "number" then
- r[#r+1] = format("[%q]=%s,",k,v)
+ r[#r+1] = formatters["[%q]=%s,"](k,v)
elseif tv == "table" then
- r[#r+1] = format("[%q]=",k)
+ r[#r+1] = formatters["[%q]="](k)
fastserialize(v,r)
elseif tv == "boolean" then
- r[#r+1] = format("[%q]=%s,",k,tostring(v))
+ r[#r+1] = formatters["[%q]=%S,"](k,v)
end
end
end
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 28859a963..1013f5467 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
-- merged file : luatex-fonts-merged.lua
-- parent file : luatex-fonts.lua
--- merge date : 03/08/13 01:14:04
+-- merge date : 03/10/13 14:36:13
do -- begin closure to overcome local limits and interference
@@ -564,6 +564,15 @@ end
function lpeg.times(pattern,n)
return P(nextstep(n,2^16,{ "start",["1"]=pattern }))
end
+local digit=R("09")
+local period=P(".")
+local zero=P("0")
+local trailingzeros=zero^0*-digit
+local case_1=period*trailingzeros/""
+local case_2=period*(digit-trailingzeros)^1*(trailingzeros/"")
+local number=digit^1*(case_1+case_2)
+local stripper=Cs((number+1)^0)
+lpeg.patterns.stripzeros=stripper
end -- closure