summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2019-07-14 20:48:50 +0000
committerKarl Berry <karl@freefriends.org>2019-07-14 20:48:50 +0000
commit03b40659365a55ac7b166e6d8afe7dcf94047115 (patch)
tree41fc3ac8a6e0023ec7bb02ade93b05c594a33701 /Master/texmf-dist/tex
parent43f963c6e7c57e4278ebb7644cef82b408d66f95 (diff)
lualibs (14jul19)
git-svn-id: svn://tug.org/texlive/trunk@51642 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex')
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-basic-merged.lua12
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-basic.lua4
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-extended-merged.lua404
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-extended.lua4
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-string.lua12
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-util-jsn.lua465
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs.lua14
7 files changed, 678 insertions, 237 deletions
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic-merged.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic-merged.lua
index bc4e3290873..7d5e0d07b1a 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic-merged.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic-merged.lua
@@ -1,6 +1,6 @@
-- merged file : lualibs-basic-merged.lua
-- parent file : lualibs-basic.lua
--- merge date : Sat May 18 17:39:21 2019
+-- merge date : Sun Jul 14 15:31:33 2019
do -- begin closure to overcome local limits and interference
@@ -1294,9 +1294,11 @@ function string.is_empty(str)
end
end
local anything=patterns.anything
-local allescapes=Cc("%")*S(".-+%?()[]*")
-local someescapes=Cc("%")*S(".-+%()[]")
-local matchescapes=Cc(".")*S("*?")
+local moreescapes=Cc("%")*S(".-+%?()[]*$^{}")
+local allescapes=Cc("%")*S(".-+%?()[]*")
+local someescapes=Cc("%")*S(".-+%()[]")
+local matchescapes=Cc(".")*S("*?")
+local pattern_m=Cs ((moreescapes+anything )^0 )
local pattern_a=Cs ((allescapes+anything )^0 )
local pattern_b=Cs ((someescapes+matchescapes+anything )^0 )
local pattern_c=Cs (Cc("^")*(someescapes+matchescapes+anything )^0*Cc("$") )
@@ -1306,6 +1308,8 @@ end
function string.topattern(str,lowercase,strict)
if str=="" or type(str)~="string" then
return ".*"
+ elseif strict=="all" then
+ str=lpegmatch(pattern_m,str)
elseif strict then
str=lpegmatch(pattern_c,str)
else
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic.lua
index 40431c79e84..d04c8eebe49 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic.lua
@@ -29,8 +29,8 @@ local loadmodule = lualibs.loadmodule
local lualibs_basic_module = {
name = "lualibs-basic",
- version = 2.65,
- date = "2019-05-18",
+ version = 2.66,
+ date = "2019-07-04",
description = "ConTeXt Lua libraries -- basic collection.",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
copyright = "PRAGMA ADE / ConTeXt Development Team",
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended-merged.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended-merged.lua
index afd99067725..672787f9e50 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended-merged.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended-merged.lua
@@ -1,6 +1,6 @@
-- merged file : lualibs-extended-merged.lua
-- parent file : lualibs-extended.lua
--- merge date : Sat May 18 17:39:12 2019
+-- merge date : Sun Jul 14 15:31:26 2019
do -- begin closure to overcome local limits and interference
@@ -2762,121 +2762,325 @@ if not modules then modules={} end modules ['util-jsn']={
local P,V,R,S,C,Cc,Cs,Ct,Cf,Cg=lpeg.P,lpeg.V,lpeg.R,lpeg.S,lpeg.C,lpeg.Cc,lpeg.Cs,lpeg.Ct,lpeg.Cf,lpeg.Cg
local lpegmatch=lpeg.match
local format,gsub=string.format,string.gsub
+local formatters=string.formatters
local utfchar=utf.char
-local concat=table.concat
+local concat,sortedkeys=table.concat,table.sortedkeys
local tonumber,tostring,rawset,type,next=tonumber,tostring,rawset,type,next
local json=utilities.json or {}
utilities.json=json
-local lbrace=P("{")
-local rbrace=P("}")
-local lparent=P("[")
-local rparent=P("]")
-local comma=P(",")
-local colon=P(":")
-local dquote=P('"')
-local whitespace=lpeg.patterns.whitespace
-local optionalws=whitespace^0
-local escapes={
- ["b"]="\010",
- ["f"]="\014",
- ["n"]="\n",
- ["r"]="\r",
- ["t"]="\t",
-}
-local escape_un=P("\\u")/""*(C(R("09","AF","af")^-4)/function(s)
- return utfchar(tonumber(s,16))
-end)
-local escape_bs=P([[\]])/""*(P(1)/escapes)
-local jstring=dquote*Cs((escape_un+escape_bs+(1-dquote))^0)*dquote
-local jtrue=P("true")*Cc(true)
-local jfalse=P("false")*Cc(false)
-local jnull=P("null")*Cc(nil)
-local jnumber=(1-whitespace-rparent-rbrace-comma)^1/tonumber
-local key=jstring
-local jsonconverter={ "value",
- hash=lbrace*Cf(Ct("")*(V("pair")*(comma*V("pair"))^0+optionalws),rawset)*rbrace,
- pair=Cg(optionalws*key*optionalws*colon*V("value")),
- array=Ct(lparent*(V("value")*(comma*V("value"))^0+optionalws)*rparent),
- value=optionalws*(jstring+V("hash")+V("array")+jtrue+jfalse+jnull+jnumber)*optionalws,
-}
-function json.tolua(str)
- return lpegmatch(jsonconverter,str)
-end
-local escaper
-local function tojson(value,t,n)
- local kind=type(value)
- if kind=="table" then
- local done=false
- local size=#value
- if size==0 then
- for k,v in next,value do
- if done then
- n=n+1;t[n]=","
+do
+ local lbrace=P("{")
+ local rbrace=P("}")
+ local lparent=P("[")
+ local rparent=P("]")
+ local comma=P(",")
+ local colon=P(":")
+ local dquote=P('"')
+ local whitespace=lpeg.patterns.whitespace
+ local optionalws=whitespace^0
+ local escapes={
+ ["b"]="\010",
+ ["f"]="\014",
+ ["n"]="\n",
+ ["r"]="\r",
+ ["t"]="\t",
+ }
+ local escape_un=P("\\u")/""*(C(R("09","AF","af")^-4)/function(s)
+ return utfchar(tonumber(s,16))
+ end)
+ local escape_bs=P([[\]])/""*(P(1)/escapes)
+ local jstring=dquote*Cs((escape_un+escape_bs+(1-dquote))^0)*dquote
+ local jtrue=P("true")*Cc(true)
+ local jfalse=P("false")*Cc(false)
+ local jnull=P("null")*Cc(nil)
+ local jnumber=(1-whitespace-rparent-rbrace-comma)^1/tonumber
+ local key=jstring
+ local jsonconverter={ "value",
+ hash=lbrace*Cf(Ct("")*(V("pair")*(comma*V("pair"))^0+optionalws),rawset)*rbrace,
+ pair=Cg(optionalws*key*optionalws*colon*V("value")),
+ array=Ct(lparent*(V("value")*(comma*V("value"))^0+optionalws)*rparent),
+ value=optionalws*(jstring+V("hash")+V("array")+jtrue+jfalse+jnull+jnumber)*optionalws,
+ }
+ function json.tolua(str)
+ return lpegmatch(jsonconverter,str)
+ end
+ function json.load(filename)
+ local data=io.loaddata(filename)
+ if data then
+ return lpegmatch(jsonconverter,data)
+ end
+ end
+end
+do
+ local escaper
+ local f_start_hash=formatters[ '%w{' ]
+ local f_start_array=formatters[ '%w[' ]
+ local f_start_hash_new=formatters[ "\n"..'%w{' ]
+ local f_start_array_new=formatters[ "\n"..'%w[' ]
+ local f_start_hash_key=formatters[ "\n"..'%w"%s" : {' ]
+ local f_start_array_key=formatters[ "\n"..'%w"%s" : [' ]
+ local f_stop_hash=formatters[ "\n"..'%w}' ]
+ local f_stop_array=formatters[ "\n"..'%w]' ]
+ local f_key_val_seq=formatters[ "\n"..'%w"%s" : %s' ]
+ local f_key_val_str=formatters[ "\n"..'%w"%s" : "%s"' ]
+ local f_key_val_num=f_key_val_seq
+ local f_key_val_yes=formatters[ "\n"..'%w"%s" : true' ]
+ local f_key_val_nop=formatters[ "\n"..'%w"%s" : false' ]
+ local f_val_num=formatters[ "\n"..'%w%s' ]
+ local f_val_str=formatters[ "\n"..'%w"%s"' ]
+ local f_val_yes=formatters[ "\n"..'%wtrue' ]
+ local f_val_nop=formatters[ "\n"..'%wfalse' ]
+ local f_val_seq=f_val_num
+ local t={}
+ local n=0
+ local function is_simple_table(tt)
+ local l=#tt
+ if l>0 then
+ for i=1,l do
+ if type(tt[i])=="table" then
+ return false
+ end
+ end
+ local nn=n
+ n=n+1 t[n]="[ "
+ for i=1,l do
+ if i>1 then
+ n=n+1 t[n]=", "
+ end
+ local v=tt[i]
+ local tv=type(v)
+ if tv=="number" then
+ n=n+1 t[n]=v
+ elseif tv=="string" then
+ n=n+1 t[n]='"'
+ n=n+1 t[n]=lpegmatch(escaper,v) or v
+ n=n+1 t[n]='"'
+ elseif tv=="boolean" then
+ n=n+1 t[n]=v and "true" or "false"
else
- n=n+1;t[n]="{"
- done=true
+ n=n+1 t[n]=tostring(v)
end
- n=n+1;t[n]=format("%q:",k)
- t,n=tojson(v,t,n)
end
- if done then
- n=n+1;t[n]="}"
+ n=n+1 t[n]=" ]"
+ local s=concat(t,"",nn+1,n)
+ n=nn
+ return s
+ end
+ return false
+ end
+ local function tojsonpp(root,name,depth,level,size)
+ if root then
+ local indexed=size>0
+ n=n+1
+ if level==0 then
+ if indexed then
+ t[n]=f_start_array(depth)
+ else
+ t[n]=f_start_hash(depth)
+ end
+ elseif name then
+ if tn=="string" then
+ name=lpegmatch(escaper,name) or name
+ elseif tn~="number" then
+ name=tostring(name)
+ end
+ if indexed then
+ t[n]=f_start_array_key(depth,name)
+ else
+ t[n]=f_start_hash_key(depth,name)
+ end
else
- n=n+1;t[n]="{}"
+ if indexed then
+ t[n]=f_start_array_new(depth)
+ else
+ t[n]=f_start_hash_new(depth)
+ end
end
- elseif size==1 then
- n=n+1;t[n]="["
- t,n=tojson(value[1],t,n)
- n=n+1;t[n]="]"
- else
- for i=1,size do
+ depth=depth+1
+ if indexed then
+ for i=1,size do
+ if i>1 then
+ n=n+1 t[n]=","
+ end
+ local v=root[i]
+ local tv=type(v)
+ if tv=="number" then
+ n=n+1 t[n]=f_val_num(depth,v)
+ elseif tv=="string" then
+ v=lpegmatch(escaper,v) or v
+ n=n+1 t[n]=f_val_str(depth,v)
+ elseif tv=="table" then
+ if next(v) then
+ local st=is_simple_table(v)
+ if st then
+ n=n+1 t[n]=f_val_seq(depth,st)
+ else
+ tojsonpp(v,k,depth,level+1,0)
+ end
+ end
+ elseif tv=="boolean" then
+ n=n+1
+ if v then
+ t[n]=f_val_yes(depth,v)
+ else
+ t[n]=f_val_nop(depth,v)
+ end
+ end
+ end
+ elseif next(root) then
+ local sk=sortedkeys(root)
+ for i=1,#sk do
+ if i>1 then
+ n=n+1 t[n]=","
+ end
+ local k=sk[i]
+ local v=root[k]
+ local tv=type(v)
+ local tk=type(k)
+ if tv=="number" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_val_num(depth,k,v)
+ elseif tk=="string" then
+ k=lpegmatch(escaper,k) or k
+ n=n+1 t[n]=f_key_val_str(depth,k,v)
+ end
+ elseif tv=="string" then
+ if tk=="number" then
+ v=lpegmatch(escaper,v) or v
+ n=n+1 t[n]=f_key_val_num(depth,k,v)
+ elseif tk=="string" then
+ k=lpegmatch(escaper,k) or k
+ v=lpegmatch(escaper,v) or v
+ n=n+1 t[n]=f_key_val_str(depth,k,v)
+ end
+ elseif tv=="table" then
+ local l=#v
+ if l>0 then
+ local st=is_simple_table(v)
+ if not st then
+ tojsonpp(v,k,depth,level+1,l)
+ elseif tk=="number" then
+ n=n+1 t[n]=f_key_val_seq(depth,k,st)
+ elseif tk=="string" then
+ k=lpegmatch(escaper,k) or k
+ n=n+1 t[n]=f_key_val_seq(depth,k,st)
+ end
+ elseif next(v) then
+ tojsonpp(v,k,depth,level+1,0)
+ end
+ elseif tv=="boolean" then
+ if tk=="number" then
+ n=n+1
+ if v then
+ t[n]=f_key_val_yes(depth,k)
+ else
+ t[n]=f_key_val_nop(depth,k)
+ end
+ elseif tk=="string" then
+ k=lpegmatch(escaper,k) or k
+ n=n+1
+ if v then
+ t[n]=f_key_val_yes(depth,k)
+ else
+ t[n]=f_key_val_nop(depth,k)
+ end
+ end
+ end
+ end
+ end
+ n=n+1
+ if indexed then
+ t[n]=f_stop_array(depth-1)
+ else
+ t[n]=f_stop_hash(depth-1)
+ end
+ end
+ end
+ local function tojson(value,n)
+ local kind=type(value)
+ if kind=="table" then
+ local done=false
+ local size=#value
+ if size==0 then
+ for k,v in next,value do
+ if done then
+ n=n+1;t[n]=',"'
+ else
+ n=n+1;t[n]='{"'
+ done=true
+ end
+ n=n+1;t[n]=lpegmatch(escaper,k) or k
+ n=n+1;t[n]='":'
+ t,n=tojson(v,n)
+ end
if done then
- n=n+1;t[n]=","
+ n=n+1;t[n]="}"
else
- n=n+1;t[n]="["
- done=true
+ n=n+1;t[n]="{}"
+ end
+ elseif size==1 then
+ n=n+1;t[n]="["
+ t,n=tojson(value[1],n)
+ n=n+1;t[n]="]"
+ else
+ for i=1,size do
+ if done then
+ n=n+1;t[n]=","
+ else
+ n=n+1;t[n]="["
+ done=true
+ end
+ t,n=tojson(value[i],n)
+ end
+ n=n+1;t[n]="]"
+ end
+ elseif kind=="string" then
+ n=n+1;t[n]='"'
+ n=n+1;t[n]=lpegmatch(escaper,value) or value
+ n=n+1;t[n]='"'
+ elseif kind=="number" then
+ n=n+1;t[n]=value
+ elseif kind=="boolean" then
+ n=n+1;t[n]=tostring(value)
+ end
+ return t,n
+ end
+ local function jsontostring(value,pretty)
+ local kind=type(value)
+ if kind=="table" then
+ if not escaper then
+ local escapes={
+ ["\\"]="\\u005C",
+ ["\""]="\\u0022",
+ }
+ for i=0,0x1F do
+ escapes[utfchar(i)]=format("\\u%04X",i)
end
- t,n=tojson(value[i],t,n)
+ escaper=Cs((
+ (R('\0\x20')+S('\"\\'))/escapes+P(1)
+ )^1 )
end
- n=n+1;t[n]="]"
- end
- elseif kind=="string" then
- n=n+1;t[n]='"'
- n=n+1;t[n]=lpegmatch(escaper,value) or value
- n=n+1;t[n]='"'
- elseif kind=="number" then
- n=n+1;t[n]=value
- elseif kind=="boolean" then
- n=n+1;t[n]=tostring(value)
- end
- return t,n
-end
-function json.tostring(value)
- local kind=type(value)
- if kind=="table" then
- if not escaper then
- local escapes={
- ["\\"]="\\u005C",
- ["\""]="\\u0022",
- }
- for i=0,0x20 do
- escapes[utfchar(i)]=format("\\u%04X",i)
+ t={}
+ n=0
+ if pretty then
+ tojsonpp(value,name,0,0,#value)
+ value=concat(t,"",1,n)
+ else
+ tojson(value,0)
+ value=concat(t,"",1,n)
end
- escaper=Cs((
- (R('\0\x20')+S('\"\\'))/escapes+P(1)
- )^1 )
+ t=nil
+ n=0
+ return value
+ elseif kind=="string" or kind=="number" then
+ return lpegmatch(escaper,value) or value
+ else
+ return tostring(value)
end
- return concat((tojson(value,{},0)))
- elseif kind=="string" or kind=="number" then
- return lpegmatch(escaper,value) or value
- else
- return tostring(value)
end
-end
-function json.load(filename)
- local data=io.loaddata(filename)
- if data then
- return lpegmatch(jsonconverter,data)
+ json.tostring=jsontostring
+ function json.tojson(value)
+ return jsontostring(value,true)
end
end
return json
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended.lua
index 1f5fcc5a9d7..1013fe54580 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended.lua
@@ -30,8 +30,8 @@ lualibs = lualibs or { }
local lualibs_extended_module = {
name = "lualibs-extended",
- version = 2.65,
- date = "2019-05-18",
+ version = 2.66,
+ date = "2019-07-04",
description = "ConTeXt Lua libraries -- extended collection.",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
copyright = "PRAGMA ADE / ConTeXt Development Team",
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-string.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-string.lua
index 8ae8d8d1d76..1dee85e2894 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-string.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-string.lua
@@ -155,11 +155,13 @@ end
--- needs checking
local anything = patterns.anything
-local allescapes = Cc("%") * S(".-+%?()[]*") -- also {} and ^$ ?
-local someescapes = Cc("%") * S(".-+%()[]") -- also {} and ^$ ?
-local matchescapes = Cc(".") * S("*?") -- wildcard and single match
+local moreescapes = Cc("%") * S(".-+%?()[]*$^{}")
+local allescapes = Cc("%") * S(".-+%?()[]*") -- also {} and ^$ ?
+local someescapes = Cc("%") * S(".-+%()[]") -- also {} and ^$ ?
+local matchescapes = Cc(".") * S("*?") -- wildcard and single match
-local pattern_a = Cs ( ( allescapes + anything )^0 )
+local pattern_m = Cs ( ( moreescapes + anything )^0 )
+local pattern_a = Cs ( ( allescapes + anything )^0 )
local pattern_b = Cs ( ( someescapes + matchescapes + anything )^0 )
local pattern_c = Cs ( Cc("^") * ( someescapes + matchescapes + anything )^0 * Cc("$") )
@@ -170,6 +172,8 @@ end
function string.topattern(str,lowercase,strict)
if str == "" or type(str) ~= "string" then
return ".*"
+ elseif strict == "all" then
+ str = lpegmatch(pattern_m,str)
elseif strict then
str = lpegmatch(pattern_c,str)
else
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-jsn.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-jsn.lua
index acbf160904d..68c6a712edd 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-jsn.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-jsn.lua
@@ -20,155 +20,391 @@ if not modules then modules = { } end modules ['util-jsn'] = {
local P, V, R, S, C, Cc, Cs, Ct, Cf, Cg = lpeg.P, lpeg.V, lpeg.R, lpeg.S, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cf, lpeg.Cg
local lpegmatch = lpeg.match
local format, gsub = string.format, string.gsub
+local formatters = string.formatters
local utfchar = utf.char
-local concat = table.concat
+local concat, sortedkeys = table.concat, table.sortedkeys
local tonumber, tostring, rawset, type, next = tonumber, tostring, rawset, type, next
local json = utilities.json or { }
utilities.json = json
--- \\ \/ \b \f \n \r \t \uHHHH
-
-local lbrace = P("{")
-local rbrace = P("}")
-local lparent = P("[")
-local rparent = P("]")
-local comma = P(",")
-local colon = P(":")
-local dquote = P('"')
-
-local whitespace = lpeg.patterns.whitespace
-local optionalws = whitespace^0
-
-local escapes = {
- ["b"] = "\010",
- ["f"] = "\014",
- ["n"] = "\n",
- ["r"] = "\r",
- ["t"] = "\t",
-}
+do
--- todo: also handle larger utf16
+ -- \\ \/ \b \f \n \r \t \uHHHH
-local escape_un = P("\\u")/"" * (C(R("09","AF","af")^-4) / function(s)
- return utfchar(tonumber(s,16))
-end)
+ local lbrace = P("{")
+ local rbrace = P("}")
+ local lparent = P("[")
+ local rparent = P("]")
+ local comma = P(",")
+ local colon = P(":")
+ local dquote = P('"')
-local escape_bs = P([[\]]) / "" * (P(1) / escapes) -- if not found then P(1) is returned i.e. the to be escaped char
+ local whitespace = lpeg.patterns.whitespace
+ local optionalws = whitespace^0
-local jstring = dquote * Cs((escape_un + escape_bs + (1-dquote))^0) * dquote
-local jtrue = P("true") * Cc(true)
-local jfalse = P("false") * Cc(false)
-local jnull = P("null") * Cc(nil)
-local jnumber = (1-whitespace-rparent-rbrace-comma)^1 / tonumber
+ local escapes = {
+ ["b"] = "\010",
+ ["f"] = "\014",
+ ["n"] = "\n",
+ ["r"] = "\r",
+ ["t"] = "\t",
+ }
-local key = jstring
+ -- todo: also handle larger utf16
-local jsonconverter = { "value",
- hash = lbrace * Cf(Ct("") * (V("pair") * (comma * V("pair"))^0 + optionalws),rawset) * rbrace,
- pair = Cg(optionalws * key * optionalws * colon * V("value")),
- array = Ct(lparent * (V("value") * (comma * V("value"))^0 + optionalws) * rparent),
--- value = optionalws * (jstring + V("hash") + V("array") + jtrue + jfalse + jnull + jnumber + #rparent) * optionalws,
- value = optionalws * (jstring + V("hash") + V("array") + jtrue + jfalse + jnull + jnumber) * optionalws,
-}
+ local escape_un = P("\\u")/"" * (C(R("09","AF","af")^-4) / function(s)
+ return utfchar(tonumber(s,16))
+ end)
+
+ local escape_bs = P([[\]]) / "" * (P(1) / escapes) -- if not found then P(1) is returned i.e. the to be escaped char
+
+ local jstring = dquote * Cs((escape_un + escape_bs + (1-dquote))^0) * dquote
+ local jtrue = P("true") * Cc(true)
+ local jfalse = P("false") * Cc(false)
+ local jnull = P("null") * Cc(nil)
+ local jnumber = (1-whitespace-rparent-rbrace-comma)^1 / tonumber
+
+ local key = jstring
+
+ local jsonconverter = { "value",
+ hash = lbrace * Cf(Ct("") * (V("pair") * (comma * V("pair"))^0 + optionalws),rawset) * rbrace,
+ pair = Cg(optionalws * key * optionalws * colon * V("value")),
+ array = Ct(lparent * (V("value") * (comma * V("value"))^0 + optionalws) * rparent),
+ -- value = optionalws * (jstring + V("hash") + V("array") + jtrue + jfalse + jnull + jnumber + #rparent) * optionalws,
+ value = optionalws * (jstring + V("hash") + V("array") + jtrue + jfalse + jnull + jnumber) * optionalws,
+ }
+
+ -- local jsonconverter = { "value",
+ -- hash = lbrace * Cf(Ct("") * (V("pair") * (comma * V("pair"))^0 + optionalws),rawset) * rbrace,
+ -- pair = Cg(optionalws * V("string") * optionalws * colon * V("value")),
+ -- array = Ct(lparent * (V("value") * (comma * V("value"))^0 + optionalws) * rparent),
+ -- string = jstring,
+ -- value = optionalws * (V("string") + V("hash") + V("array") + jtrue + jfalse + jnull + jnumber) * optionalws,
+ -- }
+
+ -- lpeg.print(jsonconverter) -- size 181
--- local jsonconverter = { "value",
--- hash = lbrace * Cf(Ct("") * (V("pair") * (comma * V("pair"))^0 + optionalws),rawset) * rbrace,
--- pair = Cg(optionalws * V("string") * optionalws * colon * V("value")),
--- array = Ct(lparent * (V("value") * (comma * V("value"))^0 + optionalws) * rparent),
--- string = jstring,
--- value = optionalws * (V("string") + V("hash") + V("array") + jtrue + jfalse + jnull + jnumber) * optionalws,
--- }
+ function json.tolua(str)
+ return lpegmatch(jsonconverter,str)
+ end
--- lpeg.print(jsonconverter) -- size 181
+ function json.load(filename)
+ local data = io.loaddata(filename)
+ if data then
+ return lpegmatch(jsonconverter,data)
+ end
+ end
-function json.tolua(str)
- return lpegmatch(jsonconverter,str)
end
-local escaper
+do
-local function tojson(value,t,n) -- we could optimize #t
- local kind = type(value)
- if kind == "table" then
- local done = false
- local size = #value
- if size == 0 then
- for k, v in next, value do
- if done then
- n = n + 1 ; t[n] = ","
+ -- It's pretty bad that JSON doesn't allow the trailing comma ... it's a
+ -- typical example of a spec that then forces all generators to check for
+ -- this. It's a way to make sure programmers keep jobs.
+
+ local escaper
+
+ local f_start_hash = formatters[ '%w{' ]
+ local f_start_array = formatters[ '%w[' ]
+ local f_start_hash_new = formatters[ "\n" .. '%w{' ]
+ local f_start_array_new = formatters[ "\n" .. '%w[' ]
+ local f_start_hash_key = formatters[ "\n" .. '%w"%s" : {' ]
+ local f_start_array_key = formatters[ "\n" .. '%w"%s" : [' ]
+
+ local f_stop_hash = formatters[ "\n" .. '%w}' ]
+ local f_stop_array = formatters[ "\n" .. '%w]' ]
+
+ local f_key_val_seq = formatters[ "\n" .. '%w"%s" : %s' ]
+ local f_key_val_str = formatters[ "\n" .. '%w"%s" : "%s"' ]
+ local f_key_val_num = f_key_val_seq
+ local f_key_val_yes = formatters[ "\n" .. '%w"%s" : true' ]
+ local f_key_val_nop = formatters[ "\n" .. '%w"%s" : false' ]
+
+ local f_val_num = formatters[ "\n" .. '%w%s' ]
+ local f_val_str = formatters[ "\n" .. '%w"%s"' ]
+ local f_val_yes = formatters[ "\n" .. '%wtrue' ]
+ local f_val_nop = formatters[ "\n" .. '%wfalse' ]
+ local f_val_seq = f_val_num
+
+ -- no empty tables because unknown if table or hash
+
+ local t = { }
+ local n = 0
+
+ local function is_simple_table(tt) -- also used in util-tab so maybe public
+ local l = #tt
+ if l > 0 then
+ for i=1,l do
+ if type(tt[i]) == "table" then
+ return false
+ end
+ end
+ local nn = n
+ n = n + 1 t[n] = "[ "
+ for i=1,l do
+ if i > 1 then
+ n = n + 1 t[n] = ", "
+ end
+ local v = tt[i]
+ local tv = type(v)
+ if tv == "number" then
+ n = n + 1 t[n] = v
+ elseif tv == "string" then
+ n = n + 1 t[n] = '"'
+ n = n + 1 t[n] = lpegmatch(escaper,v) or v
+ n = n + 1 t[n] = '"'
+ elseif tv == "boolean" then
+ n = n + 1 t[n] = v and "true" or "false"
else
- n = n + 1 ; t[n] = "{"
- done = true
+ n = n + 1 t[n] = tostring(v)
end
- n = n + 1 ; t[n] = format("%q:",k)
- t, n = tojson(v,t,n)
end
- if done then
- n = n + 1 ; t[n] = "}"
+ n = n + 1 t[n] = " ]"
+ local s = concat(t,"",nn+1,n)
+ n = nn
+ return s
+ end
+ return false
+ end
+
+ local function tojsonpp(root,name,depth,level,size)
+ if root then
+ local indexed = size > 0
+ n = n + 1
+ if level == 0 then
+ if indexed then
+ t[n] = f_start_array(depth)
+ else
+ t[n] = f_start_hash(depth)
+ end
+ elseif name then
+ if tn == "string" then
+ name = lpegmatch(escaper,name) or name
+ elseif tn ~= "number" then
+ name = tostring(name)
+ end
+ if indexed then
+ t[n] = f_start_array_key(depth,name)
+ else
+ t[n] = f_start_hash_key(depth,name)
+ end
else
- n = n + 1 ; t[n] = "{}"
+ if indexed then
+ t[n] = f_start_array_new(depth)
+ else
+ t[n] = f_start_hash_new(depth)
+ end
end
- elseif size == 1 then
- -- we can optimize for non tables
- n = n + 1 ; t[n] = "["
- t, n = tojson(value[1],t,n)
- n = n + 1 ; t[n] = "]"
- else
- for i=1,size do
+ depth = depth + 1
+ if indexed then -- indexed
+ for i=1,size do
+ if i > 1 then
+ n = n + 1 t[n] = ","
+ end
+ local v = root[i]
+ local tv = type(v)
+ if tv == "number" then
+ n = n + 1 t[n] = f_val_num(depth,v)
+ elseif tv == "string" then
+ v = lpegmatch(escaper,v) or v
+ n = n + 1 t[n] = f_val_str(depth,v)
+ elseif tv == "table" then
+ if next(v) then
+ local st = is_simple_table(v)
+ if st then
+ n = n + 1 t[n] = f_val_seq(depth,st)
+ else
+ tojsonpp(v,k,depth,level+1,0)
+ end
+ end
+ elseif tv == "boolean" then
+ n = n + 1
+ if v then
+ t[n] = f_val_yes(depth,v)
+ else
+ t[n] = f_val_nop(depth,v)
+ end
+ end
+ end
+ elseif next(root) then
+ local sk = sortedkeys(root)
+ for i=1,#sk do
+ if i > 1 then
+ n = n + 1 t[n] = ","
+ end
+ local k = sk[i]
+ local v = root[k]
+ local tv = type(v)
+ local tk = type(k)
+ if tv == "number" then
+ if tk == "number" then
+ n = n + 1 t[n] = f_key_val_num(depth,k,v)
+ elseif tk == "string" then
+ k = lpegmatch(escaper,k) or k
+ n = n + 1 t[n] = f_key_val_str(depth,k,v)
+ end
+ elseif tv == "string" then
+ if tk == "number" then
+ v = lpegmatch(escaper,v) or v
+ n = n + 1 t[n] = f_key_val_num(depth,k,v)
+ elseif tk == "string" then
+ k = lpegmatch(escaper,k) or k
+ v = lpegmatch(escaper,v) or v
+ n = n + 1 t[n] = f_key_val_str(depth,k,v)
+ end
+ elseif tv == "table" then
+ local l = #v
+ if l > 0 then
+ local st = is_simple_table(v)
+ if not st then
+ tojsonpp(v,k,depth,level+1,l)
+ elseif tk == "number" then
+ n = n + 1 t[n] = f_key_val_seq(depth,k,st)
+ elseif tk == "string" then
+ k = lpegmatch(escaper,k) or k
+ n = n + 1 t[n] = f_key_val_seq(depth,k,st)
+ end
+ elseif next(v) then
+ tojsonpp(v,k,depth,level+1,0)
+ end
+ elseif tv == "boolean" then
+ if tk == "number" then
+ n = n + 1
+ if v then
+ t[n] = f_key_val_yes(depth,k)
+ else
+ t[n] = f_key_val_nop(depth,k)
+ end
+ elseif tk == "string" then
+ k = lpegmatch(escaper,k) or k
+ n = n + 1
+ if v then
+ t[n] = f_key_val_yes(depth,k)
+ else
+ t[n] = f_key_val_nop(depth,k)
+ end
+ end
+ end
+ end
+ end
+ n = n + 1
+ if indexed then
+ t[n] = f_stop_array(depth-1)
+ else
+ t[n] = f_stop_hash(depth-1)
+ end
+ end
+ end
+
+ local function tojson(value,n)
+ local kind = type(value)
+ if kind == "table" then
+ local done = false
+ local size = #value
+ if size == 0 then
+ for k, v in next, value do
+ if done then
+ -- n = n + 1 ; t[n] = ","
+ n = n + 1 ; t[n] = ',"'
+ else
+ -- n = n + 1 ; t[n] = "{"
+ n = n + 1 ; t[n] = '{"'
+ done = true
+ end
+ n = n + 1 ; t[n] = lpegmatch(escaper,k) or k
+ n = n + 1 ; t[n] = '":'
+ t, n = tojson(v,n)
+ end
if done then
- n = n + 1 ; t[n] = ","
+ n = n + 1 ; t[n] = "}"
else
- n = n + 1 ; t[n] = "["
- done = true
+ n = n + 1 ; t[n] = "{}"
end
- t, n = tojson(value[i],t,n)
+ elseif size == 1 then
+ -- we can optimize for non tables
+ n = n + 1 ; t[n] = "["
+ t, n = tojson(value[1],n)
+ n = n + 1 ; t[n] = "]"
+ else
+ for i=1,size do
+ if done then
+ n = n + 1 ; t[n] = ","
+ else
+ n = n + 1 ; t[n] = "["
+ done = true
+ end
+ t, n = tojson(value[i],n)
+ end
+ n = n + 1 ; t[n] = "]"
end
- n = n + 1 ; t[n] = "]"
+ elseif kind == "string" then
+ n = n + 1 ; t[n] = '"'
+ n = n + 1 ; t[n] = lpegmatch(escaper,value) or value
+ n = n + 1 ; t[n] = '"'
+ elseif kind == "number" then
+ n = n + 1 ; t[n] = value
+ elseif kind == "boolean" then
+ n = n + 1 ; t[n] = tostring(value)
end
- elseif kind == "string" then
- n = n + 1 ; t[n] = '"'
- n = n + 1 ; t[n] = lpegmatch(escaper,value) or value
- n = n + 1 ; t[n] = '"'
- elseif kind == "number" then
- n = n + 1 ; t[n] = value
- elseif kind == "boolean" then
- n = n + 1 ; t[n] = tostring(value)
+ return t, n
end
- return t, n
-end
-function json.tostring(value)
- -- todo optimize for non table
- local kind = type(value)
- if kind == "table" then
- if not escaper then
- local escapes = {
- ["\\"] = "\\u005C",
- ["\""] = "\\u0022",
- }
- for i=0,0x20 do
- escapes[utfchar(i)] = format("\\u%04X",i)
- end
- escaper = Cs( (
- (R('\0\x20') + S('\"\\')) / escapes
- + P(1)
- )^1 )
+ -- escaping keys can become an option
+
+ local function jsontostring(value,pretty)
+ -- todo optimize for non table
+ local kind = type(value)
+ if kind == "table" then
+ if not escaper then
+ local escapes = {
+ ["\\"] = "\\u005C",
+ ["\""] = "\\u0022",
+ }
+ for i=0,0x1F do
+ escapes[utfchar(i)] = format("\\u%04X",i)
+ end
+ escaper = Cs( (
+ (R('\0\x20') + S('\"\\')) / escapes
+ + P(1)
+ )^1 )
+ end
+ -- local to the closure (saves wrapping and local functions)
+ t = { }
+ n = 0
+ if pretty then
+ tojsonpp(value,name,0,0,#value)
+-- value = concat(t,"\n",1,n)
+ value = concat(t,"",1,n)
+ else
+ tojson(value,0)
+ value = concat(t,"",1,n)
+ end
+ t = nil
+ n = 0
+ return value
+ elseif kind == "string" or kind == "number" then
+ return lpegmatch(escaper,value) or value
+ else
+ return tostring(value)
end
- return concat((tojson(value,{},0)))
- elseif kind == "string" or kind == "number" then
- return lpegmatch(escaper,value) or value
- else
- return tostring(value)
end
+
+ json.tostring = jsontostring
+
+ function json.tojson(value)
+ return jsontostring(value,true)
+ end
+
end
--- local tmp = [[ { "t" : "foobar", "a" : true, "b" : [ 123 , 456E-10, { "a" : true, "b" : [ 123 , 456 ] } ] } ]]
+-- local tmp = [[ { "t\nt t" : "foo bar", "a" : true, "b" : [ 123 , 456E-10, { "a" : true, "b" : [ 123 , 456 ] } ] } ]]
-- tmp = json.tolua(tmp)
-- inspect(tmp)
--- tmp = json.tostring(tmp)
+-- tmp = json.tostring(tmp,true)
-- inspect(tmp)
-- tmp = json.tolua(tmp)
-- inspect(tmp)
@@ -176,13 +412,6 @@ end
-- inspect(tmp)
-- inspect(json.tostring(true))
-function json.load(filename)
- local data = io.loaddata(filename)
- if data then
- return lpegmatch(jsonconverter,data)
- end
-end
-
-- local s = [[\foo"bar"]]
-- local j = json.tostring { s = s }
-- local l = json.tolua(j)
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs.lua
index 089a7441dd2..02243c8df47 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs.lua
@@ -25,8 +25,8 @@ lualibs = lualibs or { }
lualibs.module_info = {
name = "lualibs",
- version = 2.65,
- date = "2019-05-18",
+ version = 2.66,
+ date = "2019-07-04",
description = "ConTeXt Lua standard libraries.",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
copyright = "PRAGMA ADE / ConTeXt Development Team",
@@ -79,13 +79,13 @@ do
lualibs.error, lualibs.warn, lualibs.info = error, warn, info
end
-if luatexbase and luatexbase.find_file then
- find_file = luatexbase.find_file
-else
- kpse.set_program_name"luatex"
- find_file = kpsefind_file
+local info = status.list()
+if info.kpse_used == 0 then
+ kpse.set_program_name("luatex")
end
+find_file = kpsefind_file
+
local loadmodule = loadmodule or function (name, t)
if not t then t = "library" end