-- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
-- parent file : c:/data/develop/context/sources/luatex-fonts.lua
-- merge date : 07/25/16 21:49:08
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['l-lua']={
version=1.001,
comment="companion to luat-lib.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
_MAJORVERSION,_MINORVERSION=string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$")
_MAJORVERSION=tonumber(_MAJORVERSION) or 5
_MINORVERSION=tonumber(_MINORVERSION) or 1
_LUAVERSION=_MAJORVERSION+_MINORVERSION/10
if _LUAVERSION<5.2 and jit then
_MINORVERSION=2
_LUAVERSION=5.2
end
if not lpeg then
lpeg=require("lpeg")
end
if loadstring then
local loadnormal=load
function load(first,...)
if type(first)=="string" then
return loadstring(first,...)
else
return loadnormal(first,...)
end
end
else
loadstring=load
end
if not ipairs then
local function iterate(a,i)
i=i+1
local v=a[i]
if v~=nil then
return i,v
end
end
function ipairs(a)
return iterate,a,0
end
end
if not pairs then
function pairs(t)
return next,t
end
end
if not table.unpack then
table.unpack=_G.unpack
elseif not unpack then
_G.unpack=table.unpack
end
if not package.loaders then
package.loaders=package.searchers
end
local print,select,tostring=print,select,tostring
local inspectors={}
function setinspector(kind,inspector)
inspectors[kind]=inspector
end
function inspect(...)
for s=1,select("#",...) do
local value=select(s,...)
if value==nil then
print("nil")
else
local done=false
local kind=type(value)
local inspector=inspectors[kind]
if inspector then
done=inspector(value)
if done then
break
end
end
for kind,inspector in next,inspectors do
done=inspector(value)
if done then
break
end
end
if not done then
print(tostring(value))
end
end
end
end
local dummy=function() end
function optionalrequire(...)
local ok,result=xpcall(require,dummy,...)
if ok then
return result
end
end
if lua then
lua.mask=load([[τεχ = 1]]) and "utf" or "ascii"
end
local flush=io.flush
if flush then
local execute=os.execute if execute then function os.execute(...) flush() return execute(...) end end
local exec=os.exec if exec then function os.exec (...) flush() return exec (...) end end
local spawn=os.spawn if spawn then function os.spawn (...) flush() return spawn (...) end end
local popen=io.popen if popen then function io.popen (...) flush() return popen (...) end end
end
end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['l-lpeg']={
version=1.001,
comment="companion to luat-lib.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
lpeg=require("lpeg")
if not lpeg.print then function lpeg.print(...) print(lpeg.pcode(...)) end end
local type,next,tostring=type,next,tostring
local byte,char,gmatch,format=string.byte,string.char,string.gmatch,string.format
local floor=math.floor
local P,R,S,V,Ct,C,Cs,Cc,Cp,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.V,lpeg.Ct,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Cp,lpeg.Cmt
local lpegtype,lpegmatch,lpegprint=lpeg.type,lpeg.match,lpeg.print
if setinspector then
setinspector("lpeg",function(v) if lpegtype(v) then lpegprint(v) return true end end)
end
lpeg.patterns=lpeg.patterns or {}
local patterns=lpeg.patterns
local anything=P(1)
local endofstring=P(-1)
local alwaysmatched=P(true)
patterns.anything=anything
patterns.endofstring=endofstring
patterns.beginofstring=alwaysmatched
patterns.alwaysmatched=alwaysmatched
local sign=S('+-')
local zero=P('0')
local digit=R('09')
local octdigit=R("07")
local lowercase=R("az")
local uppercase=R("AZ")
local underscore=P("_")
local hexdigit=digit+lowercase+uppercase
local cr,lf,crlf=P("\r"),P("\n"),P("\r\n")
local newline=P("\r")*(P("\n")+P(true))+P("\n")
local escaped=P("\\")*anything
local squote=P("'")
local dquote=P('"')
local space=P(" ")
local period=P(".")
local comma=P(",")
local utfbom_32_be=P('\000\000\254\255')
local utfbom_32_le=P('\255\254\000\000')
local utfbom_16_be=P('\254\255')
local utfbom_16_le=P('\255\254')
local utfbom_8=P('\239\187\191')
local utfbom=utfbom_32_be+utfbom_32_le+utfbom_16_be+utfbom_16_le+utfbom_8
local utftype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")+alwaysmatched*Cc("utf-8")
local utfstricttype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")
local utfoffset=utfbom_32_be*Cc(4)+utfbom_32_le*Cc(4)+utfbom_16_be*Cc(2)+utfbom_16_le*Cc(2)+utfbom_8*Cc(3)+Cc(0)
local utf8next=R("\128\191")
patterns.utfbom_32_be=utfbom_32_be
patterns.utfbom_32_le=utfbom_32_le
patterns.utfbom_16_be=utfbom_16_be
patterns.utfbom_16_le=utfbom_16_le
patterns.utfbom_8=utfbom_8
patterns.utf_16_be_nl=P("\000\r\000\n")+P("\000\r")+P("\000\n")
patterns.utf_16_le_nl=P("\r\000\n\000")+P("\r\000")+P("\n\000")
patterns.utf_32_be_nl=P("\000\000\000\r\000\000\000\n")+P("\000\000\000\r")+P("\000\000\000\n")
patterns.utf_32_le_nl=P("\r\000\000\000\n\000\000\000")+P("\r\000\000\000")+P("\n\000\000\000")
patterns.utf8one=R("\000\127")
patterns.utf8two=R("\194\223")*utf8next
patterns.utf8three=R("\224\239")*utf8next*utf8next
patterns.utf8four=R("\240\244")*utf8next*utf8next*utf8next
patterns.utfbom=utfbom
patterns.utftype=utftype
patterns.utfstricttype=utfstricttype
patterns.utfoffset=utfoffset
local utf8char=patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four
local validutf8char=utf8char^0*endofstring*Cc(true)+Cc(false)
local utf8character=P(1)*R("\128\191")^0
patterns.utf8=utf8char
patterns.utf8char=utf8char
patterns.utf8character=utf8character
patterns.validutf8=validutf8char
patterns.validutf8char=validutf8char
local eol=S("\n\r")
local spacer=S(" \t\f\v")
local whitespace=eol+spacer
local nonspacer=1-spacer
local nonwhitespace=1-whitespace
patterns.eol=eol
patterns.spacer=spacer
patterns.whitespace=whitespace
patterns.nonspacer=nonspacer
patterns.nonwhitespace=nonwhitespace
local stripper=spacer^0*C((spacer^0*nonspacer^1)^0)
local fullstripper=whitespace^0*C((whitespace^0*nonwhitespace^1)^0)
local collapser=Cs(spacer^0/""*nonspacer^0*((spacer^0/" "*nonspacer^1)^0))
local b_collapser=Cs(whitespace^0/""*(nonwhitespace^1+whitespace^1/" ")^0)
local e_collapser=Cs((whitespace^1*P(-1)/""+nonwhitespace^1+whitespace^1/" ")^0)
local m_collapser=Cs((nonwhitespace^1+whitespace^1/" ")^0)
local b_stripper=Cs(spacer^0/""*(nonspacer^1+spacer^1/" ")^0)
local e_stripper=Cs((spacer^1*P(-1)/""+nonspacer^1+spacer^1/" ")^0)
local m_stripper=Cs((nonspacer^1+spacer^1/" ")^0)
patterns.stripper=stripper
patterns.fullstripper=fullstripper
patterns.collapser=collapser
patterns.b_collapser=b_collapser
patterns.m_collapser=m_collapser
patterns.e_collapser=e_collapser
patterns.b_stripper=b_stripper
patterns.m_stripper=m_stripper
patterns.e_stripper=e_stripper
patterns.lowercase=lowercase
patterns.uppercase=uppercase
patterns.letter=patterns.lowercase+patterns.uppercase
patterns.space=space
patterns.tab=P("\t")
patterns.spaceortab=patterns.space+patterns.tab
patterns.newline=newline
patterns.emptyline=newline^1
patterns.equal=P("=")
patterns.comma=comma
patterns.commaspacer=comma*spacer^0
patterns.period=period
patterns.colon=P(":")
patterns.semicolon=P(";")
patterns.underscore=underscore
patterns.escaped=escaped
patterns.squote=squote
patterns.dquote=dquote
patterns.nosquote=(escaped+(1-squote))^0
patterns.nodquote=(escaped+(1-dquote))^0
patterns.unsingle=(squote/"")*patterns.nosquote*(squote/"")
patterns.undouble=(dquote/"")*patterns.nodquote*(dquote/"")
patterns.unquoted=patterns.undouble+patterns.unsingle
patterns.unspacer=((patterns.spacer^1)/"")^0
patterns.singlequoted=squote*patterns.nosquote*squote
patterns.doublequoted=dquote*patterns.nodquote*dquote
patterns.quoted=patterns.doublequoted+patterns.singlequoted
patterns.digit=digit
patterns.octdigit=octdigit
patterns.hexdigit=hexdigit
patterns.sign=sign
patterns.cardinal=digit^1
patterns.integer=sign^-1*digit^1
patterns.unsigned=digit^0*period*digit^1
patterns.float=sign^-1*patterns.unsigned
patterns.cunsigned=digit^0*comma*digit^1
patterns.cpunsigned=digit^0*(period+comma)*digit^1
patterns.cfloat=sign^-1*patterns.cunsigned
patterns.cpfloat=sign^-1*patterns.cpunsigned
patterns.number=patterns.float+patterns.integer
patterns.cnumber=patterns.cfloat+patterns.integer
patterns.cpnumber=patterns.cpfloat+patterns.integer
patterns.oct=zero*octdigit^1
patterns.octal=patterns.oct
patterns.HEX=zero*P("X")*(digit+uppercase)^1
patterns.hex=zero*P("x")*(digit+lowercase)^1
patterns.hexadecimal=zero*S("xX")*hexdigit^1
patterns.hexafloat=sign^-1*zero*S("xX")*(hexdigit^0*period*hexdigit^1+hexdigit^1*period*hexdigit^0+hexdigit^1)*(S("pP")*sign^-1*hexdigit^1)^-1
patterns.decafloat=sign^-1*(digit^0*period*digit^1+digit^1*period*digit^0+digit^1)*S("eE")*sign^-1*digit^1
patterns.propername=(uppercase+lowercase+underscore)*(uppercase+lowercase+underscore+digit)^0*endofstring
patterns.somecontent=(anything-newline-space)^1
patterns.beginline=#(1-newline)
patterns.longtostring=Cs(whitespace^0/""*((patterns.quoted+nonwhitespace^1+whitespace^1/""*(P(-1)+Cc(" ")))^0))
local function anywhere(pattern)
return P { P(pattern)+1*V(1) }
end
lpeg.anywhere=anywhere
function lpeg.instringchecker(p)
p=anywhere(p)
return function(str)
return lpegmatch(p,str) and true or false
end
end
function lpeg.splitter(pattern,action)
return (((1-P(pattern))^1)/action+1)^0
end
function lpeg.tsplitter(pattern,action)
return Ct((((1-P(pattern))^1)/action+1)^0)
end
local splitters_s,splitters_m,splitters_t={},{},{}
local function splitat(separator,single)
local splitter=(single and splitters_s[separator]) or splitters_m[separator]
if not splitter then
separator=P(separator)
local other=C((1-separator)^0)
if single then
local any=anything
splitter=other*(separator*C(any^0)+"")
splitters_s[separator]=splitter
else
splitter=other*(separator*other)^0
splitters_m[separator]=splitter
end
end
return splitter
end
local function tsplitat(separator)
local splitter=splitters_t[separator]
if not splitter then
splitter=Ct(splitat(separator))
splitters_t[separator]=splitter
end
return splitter
end
lpeg.splitat=splitat
lpeg.tsplitat=tsplitat
function string.splitup(str,separator)
if not separator then
separator=","
end
return lpegmatch(splitters_m[separator] or splitat(separator),str)
end
local cache={}
function lpeg.split(separator,str)
local c=cache[separator]
if not c then
c=tsplitat(separator)
cache[separator]=c
end
return lpegmatch(c,str)
end
function string.split(str,separator)
if separator then
local c=cache[separator]
if not c then
c=tsplitat(separator)
cache[separator]=c
end
return lpegmatch(c,str)
else
return { str }
end
end
local spacing=patterns.spacer^0*newline
local empty=spacing*Cc("")
local nonempty=Cs((1-spacing)^1)*spacing^-1
local content=(empty+nonempty)^1
patterns.textline=content
local linesplitter=tsplitat(newline)
patterns.linesplitter=linesplitter
function string.splitlines(str)
return lpegmatch(linesplitter,str)
end
local cache={}
function lpeg.checkedsplit(separator,str)
local c=cache[separator]
if not c then
separator=P(separator)
local other=C((1-separator)^1)
c=Ct(separator^0*other*(separator^1*other)^0)
cache[separator]=c
end
return lpegmatch(c,str)
end
function string.checkedsplit(str,separator)
local c=cache[separator]
if not c then
separator=P(separator)
local other=C((1-separator)^1)
c=Ct(separator^0*other*(separator^1*other)^0)
cache[separator]=c
end
return lpegmatch(c,str)
end
local function f2(s) local c1,c2=byte(s,1,2) return c1*64+c2-12416 end
local function f3(s) local c1,c2,c3=byte(s,1,3) return (c1*64+c2)*64+c3-925824 end
local function f4(s) local c1,c2,c3,c4=byte(s,1,4) return ((c1*64+c2)*64+c3)*64+c4-63447168 end
local utf8byte=patterns.utf8one/byte+patterns.utf8two/f2+patterns.utf8three/f3+patterns.utf8four/f4
patterns.utf8byte=utf8byte
local cache={}
function lpeg.stripper(str)
if type(str)=="string" then
local s=cache[str]
if not s then
s=Cs(((S(str)^1)/""+1)^0)
cache[str]=s
end
return s
else
return Cs(((str^1)/""+1)^0)
end
end
local cache={}
function lpeg.keeper(str)
if type(str)=="string" then
local s=cache[str]
if not s then
s=Cs((((1-S(str))^1)/""+1)^0)
cache[str]=s
end
return s
else
return Cs((((1-str)^1)/""+1)^0)
end
end
function lpeg.frontstripper(str)
return (P(str)+P(true))*Cs(anything^0)
end
function lpeg.endstripper(str)
return Cs((1-P(str)*endofstring)^0)
end
function lpeg.replacer(one,two,makefunction,isutf)
local pattern
local u=isutf and utf8char or 1
if type(one)=="table" then
local no=#one
local p=P(false)
if no==0 then
for k,v in next,one do
p=p+P(k)/v
end
pattern=Cs((p+u)^0)
elseif no==1 then
local o=one[1]
one,two=P(o[1]),o[2]
pattern=Cs((one/two+u)^0)
else
for i=1,no do
local o=one[i]
p=p+P(o[1])/o[2]
end
pattern=Cs((p+u)^0)
end
else
pattern=Cs((P(one)/(two or "")+u)^0)
end
if makefunction then
return function(str)
return lpegmatch(pattern,str)
end
else
return pattern
end
end
function lpeg.finder(lst,makefunction,isutf)
local pattern
if type(lst)=="table" then
pattern=P(false)
if #lst==0 then
for k,v in next,lst do
pattern=pattern+P(k)
end
else
for i=1,#lst do
pattern=pattern+P(lst[i])
end
end
else
pattern=P(lst)
end
if isutf then
pattern=((utf8char or 1)-pattern)^0*pattern
else
pattern=(1-pattern)^0*pattern
end
if makefunction then
return function(str)
return lpegmatch(pattern,str)
end
else
return pattern
end
end
local splitters_f,splitters_s={},{}
function lpeg.firstofsplit(separator)
local splitter=splitters_f[separator]
if not splitter then
local pattern=P(separator)
splitter=C((1-pattern)^0)
splitters_f[separator]=splitter
end
return splitter
end
function lpeg.secondofsplit(separator)
local splitter=splitters_s[separator]
if not splitter then
local pattern=P(separator)
splitter=(1-pattern)^0*pattern*C(anything^0)
splitters_s[separator]=splitter
end
return splitter
end
local splitters_s,splitters_p={},{}
function lpeg.beforesuffix(separator)
local splitter=splitters_s[separator]
if not splitter then
local pattern=P(separator)
splitter=C((1-pattern)^0)*pattern*endofstring
splitters_s[separator]=splitter
end
return splitter
end
function lpeg.afterprefix(separator)
local splitter=splitters_p[separator]
if not splitter then
local pattern=P(separator)
splitter=pattern*C(anything^0)
splitters_p[separator]=splitter
end
return splitter
end
function lpeg.balancer(left,right)
left,right=P(left),P(right)
return P { left*((1-left-right)+V(1))^0*right }
end
local nany=utf8char/""
function lpeg.counter(pattern)
pattern=Cs((P(pattern)/" "+nany)^0)
return function(str)
return #lpegmatch(pattern,str)
end
end
utf=utf or (unicode and unicode.utf8) or {}
local utfcharacters=utf and utf.characters or string.utfcharacters
local utfgmatch=utf and utf.gmatch
local utfchar=utf and utf.char
lpeg.UP=lpeg.P
if utfcharacters then
function lpeg.US(str)
local p=P(false)
for uc in utfcharacters(str) do
p=p+P(uc)
end
return p
end
elseif utfgmatch then
function lpeg.US(str)
local p=P(false)
for uc in utfgmatch(str,".") do
p=p+P(uc)
end
return p
end
else
function lpeg.US(str)
local p=P(false)
local f=function(uc)
p=p+P(uc)
end
lpegmatch((utf8char/f)^0,str)
return p
end
end
local range=utf8byte*utf8byte+Cc(false)
function lpeg.UR(str,more)
local first,last
if type(str)=="number" then
first=str
last=more or first
else
first,last=lpegmatch(range,str)
if not last then
return P(str)
end
end
if first==last then
return P(str)
elseif utfchar and (last-first<8) then
local p=P(false)
for i=first,last do
p=p+P(utfchar(i))
end
return p
else
local f=function(b)
return b>=first and b<=last
end
return utf8byte/f
end
end
function lpeg.is_lpeg(p)
return p and lpegtype(p)=="pattern"
end
function lpeg.oneof(list,...)
if type(list)~="table" then
list={ list,... }
end
local p=P(list[1])
for l=2,#list do
p=p+P(list[l])
end
return p
end
local sort=table.sort
local function copyindexed(old)
local new={}
for i=1,#old do
new[i]=old
end
return new
end
local function sortedkeys(tab)
local keys,s={},0
for key,_ in next,tab do
s=s+1
keys[s]=key
end
sort(keys)
return keys
end
function lpeg.append(list,pp,delayed,checked)
local p=pp
if #list>0 then
local keys=copyindexed(list)
sort(keys)
for i=#keys,1,-1 do
local k=keys[i]
if p then
p=P(k)+p
else
p=P(k)
end
end
elseif delayed then
local keys=sortedkeys(list)
if p then
for i=1,#keys,1 do
local k=keys[i]
local v=list[k]
p=P(k)/list+p
end
else
for i=1,#keys do
local k=keys[i]
local v=list[k]
if p then
p=P(k)+p
else
p=P(k)
end
end
if p then
p=p/list
end
end
elseif checked then
local keys=sortedkeys(list)
for i=1,#keys do
local k=keys[i]
local v=list[k]
if p then
if k==v then
p=P(k)+p
else
p=P(k)/v+p
end
else
if k==v then
p=P(k)
else
p=P(k)/v
end
end
end
else
local keys=sortedkeys(list)
for i=1,#keys do
local k=keys[i]
local v=list[k]
if p then
p=P(k)/v+p
else
p=P(k)/v
end
end
end
return p
end
local p_false=P(false)
local p_true=P(true)
local function make(t)
local function making(t)
local p=p_false
local keys=sortedkeys(t)
for i=1,#keys do
local k=keys[i]
if k~="" then
local v=t[k]
if v==true then
p=p+P(k)*p_true
elseif v==false then
else
p=p+P(k)*making(v)
end
end
end
if t[""] then
p=p+p_true
end
return p
end
local p=p_false
local keys=sortedkeys(t)
for i=1,#keys do
local k=keys[i]
if k~="" then
local v=t[k]
if v==true then
p=p+P(k)*p_true
elseif v==false then
else
p=p+P(k)*making(v)
end
end
end
return p
end
local function collapse(t,x)
if type(t)~="table" then
return t,x
else
local n=next(t)
if n==nil then
return t,x
elseif next(t,n)==nil then
local k=n
local v=t[k]
if type(v)=="table" then
return collapse(v,x..k)
else
return v,x..k
end
else
local tt={}
for k,v in next,t do
local vv,kk=collapse(v,k)
tt[kk]=vv
end
return tt,x
end
end
end
function lpeg.utfchartabletopattern(list)
local tree={}
local n=#list
if n==0 then
for s in next,list do
local t=tree
local p,pk
for c in gmatch(s,".") do
if t==true then
t={ [c]=true,[""]=true }
p[pk]=t
p=t
t=false
elseif t==false then
t={ [c]=false }
p[pk]=t
p=t
t=false
else
local tc=t[c]
if not tc then
tc=false
t[c]=false
end
p=t
t=tc
end
pk=c
end
if t==false then
p[pk]=true
elseif t==true then
else
t[""]=true
end
end
else
for i=1,n do
local s=list[i]
local t=tree
local p,pk
for c in gmatch(s,".") do
if t==true then
t={ [c]=true,[""]=true }
p[pk]=t
p=t
t=false
elseif t==false then
t={ [c]=false }
p[pk]=t
p=t
t=false
else
local tc=t[c]
if not tc then
tc=false
t[c]=false
end
p=t
t=tc
end
pk=c
end
if t==false then
p[pk]=true
elseif t==true then
else
t[""]=true
end
end
end
return make(tree)
end
patterns.containseol=lpeg.finder(eol)
local function nextstep(n,step,result)
local m=n%step
local d=floor(n/step)
if d>0 then
local v=V(tostring(step))
local s=result.start
for i=1,d do
if s then
s=v*s
else
s=v
end
end
result.start=s
end
if step>1 and result.start then
local v=V(tostring(step/2))
result[tostring(step)]=v*v
end
if step>0 then
return nextstep(m,step/2,result)
else
return result
end
end
function lpeg.times(pattern,n)
return P(nextstep(n,2^16,{ "start",["1"]=pattern }))
end
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
local byte_to_HEX={}
local byte_to_hex={}
local byte_to_dec={}
local hex_to_byte={}
for i=0,255 do
local H=format("%02X",i)
local h=format("%02x",i)
local d=format("%03i",i)
local c=char(i)
byte_to_HEX[c]=H
byte_to_hex[c]=h
byte_to_dec[c]=d
hex_to_byte[h]=c
hex_to_byte[H]=c
end
local hextobyte=P(2)/hex_to_byte
local bytetoHEX=P(1)/byte_to_HEX
local bytetohex=P(1)/byte_to_hex
local bytetodec=P(1)/byte_to_dec
local hextobytes=Cs(hextobyte^0)
local bytestoHEX=Cs(bytetoHEX^0)
local bytestohex=Cs(bytetohex^0)
local bytestodec=Cs(bytetodec^0)
patterns.hextobyte=hextobyte
patterns.bytetoHEX=bytetoHEX
patterns.bytetohex=bytetohex
patterns.bytetodec=bytetodec
patterns.hextobytes=hextobytes
patterns.bytestoHEX=bytestoHEX
patterns.bytestohex=bytestohex
patterns.bytestodec=bytestodec
function string.toHEX(s)
if not s or s=="" then
return s
else
return lpegmatch(bytestoHEX,s)
end
end
function string.tohex(s)
if not s or s=="" then
return s
else
return lpegmatch(bytestohex,s)
end
end
function string.todec(s)
if not s or s=="" then
return s
else
return lpegmatch(bytestodec,s)
end
end
function string.tobytes(s)
if not s or s=="" then
return s
else
return lpegmatch(hextobytes,s)
end
end
end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['l-functions']={
version=1.001,
comment="companion to luat-lib.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
functions=functions or {}
function functions.dummy() end
end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['l-string']={
version=1.001,
comment="companion to luat-lib.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
local string=string
local sub,gmatch,format,char,byte,rep,lower=string.sub,string.gmatch,string.format,string.char,string.byte,string.rep,string.lower
local lpegmatch,patterns=lpeg.match,lpeg.patterns
local P,S,C,Ct,Cc,Cs=lpeg.P,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.Cs
local unquoted=patterns.squote*C(patterns.nosquote)*patterns.squote+patterns.dquote*C(patterns.nodquote)*patterns.dquote
function string.unquoted(str)
return lpegmatch(unquoted,str) or str
end
function string.quoted(str)
return format("%q",str)
end
function string.count(str,pattern)
local n=0
for _ in gmatch(str,pattern) do
n=n+1
end
return n
end
function string.limit(str,n,sentinel)
if #str>n then
sentinel=sentinel or "..."
return sub(str,1,(n-#sentinel))..sentinel
else
return str
end
end
local stripper=patterns.stripper
local fullstripper=patterns.fullstripper
local collapser=patterns.collapser
local longtostring=patterns.longtostring
function string.strip(str)
return lpegmatch(stripper,str) or ""
end
function string.fullstrip(str)
return lpegmatch(fullstripper,str) or ""
end
function string.collapsespaces(str)
return lpegmatch(collapser,str) or ""
end
function string.longtostring(str)
return lpegmatch(longtostring,str) or ""
end
local pattern=P(" ")^0*P(-1)
function string.is_empty(str)
if str=="" then
return true
else
return lpegmatch(pattern,str) and true or false
end
end
local anything=patterns.anything
local allescapes=Cc("%")*S(".-+%?()[]*")
local someescapes=Cc("%")*S(".-+%()[]")
local matchescapes=Cc(".")*S("*?")
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("$") )
function string.escapedpattern(str,simple)
return lpegmatch(simple and pattern_b or pattern_a,str)
end
function string.topattern(str,lowercase,strict)
if str=="" or type(str)~="string" then
return ".*"
elseif strict then
str=lpegmatch(pattern_c,str)
else
str=lpegmatch(pattern_b,str)
end
if lowercase then
return lower(str)
else
return str
end
end
function string.valid(str,default)
return (type(str)=="string" and str~="" and str) or default or nil
end
string.itself=function(s) return s end
local pattern_c=Ct(C(1)^0)
local pattern_b=Ct((C(1)/byte)^0)
function string.totable(str,bytes)
return lpegmatch(bytes and pattern_b or pattern_c,str)
end
local replacer=lpeg.replacer("@","%%")
function string.tformat(fmt,...)
return format(lpegmatch(replacer,fmt),...)
end
string.quote=string.quoted
string.unquote=string.unquoted
end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['l-table']={
version=1.001,
comment="companion to luat-lib.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
local type,next,tostring,tonumber,ipairs,select=type,next,tostring,tonumber,ipairs,select
local table,string=table,string
local concat,sort,insert,remove=table.concat,table.sort,table.insert,table.remove
local format,lower,dump=string.format,string.lower,string.dump
local getmetatable,setmetatable=getmetatable,setmetatable
local getinfo=debug.getinfo
local lpegmatch,patterns=lpeg.match,lpeg.patterns
local floor=math.floor
local stripper=patterns.stripper
function table.strip(tab)
local lst,l={},0
for i=1,#tab do
local s=lpegmatch(stripper,tab[i]) or ""
if s=="" then
else
l=l+1
lst[l]=s
end
end
return lst
end
function table.keys(t)
if t then
local keys,k={},0
for key in next,t do
k=k+1
keys[k]=key
end
return keys
else
return {}
end
end
local function compare(a,b)
local ta=type(a)
if ta=="number" then
local tb=type(b)
if ta==tb then
return a<b
elseif tb=="string" then
return tostring(a)<b
end
elseif ta=="string" then
local tb=type(b)
if ta==tb then
return a<b
else
return a<tostring(b)
end
end
return tostring(a)<tostring(b)
end
local function sortedkeys(tab)
if tab then
local srt,category,s={},0,0
for key in next,tab do
s=s+1
srt[s]=key
if category==3 then
elseif category==1 then
if type(key)~="string" then
category=3
end
elseif category==2 then
if type(key)~="number" then
category=3
end
else
local tkey=type(key)
if tkey=="string" then
category=1
elseif tkey=="number" then
category=2
else
category=3
end
end
end
if s<2 then
elseif category==3 then
sort(srt,compare)
else
sort(srt)
end
return srt
else
return {}
end
end
local function sortedhashonly(tab)
if tab then
local srt,s={},0
for key in next,tab do
if type(key)=="string" then
s=s+1
srt[s]=key
end
end
if s>1 then
sort(srt)
end
return srt
else
return {}
end
end
local function sortedindexonly(tab)
if tab then
local srt,s={},0
for key in next,tab do
if type(key)=="number" then
s=s+1
srt[s]=key
end
end
if s>1 then
sort(srt)
end
return srt
else
return {}
end
end
local function sortedhashkeys(tab,cmp)
if tab then
local srt,s={},0
for key in next,tab do
if key then
s=s+1
srt[s]=key
end
end
if s>1 then
sort(srt,cmp)
end
return srt
else
return {}
end
end
function table.allkeys(t)
local keys={}
for k,v in next,t do
for k in next,v do
keys[k]=true
end
end
return sortedkeys(keys)
end
table.sortedkeys=sortedkeys
table.sortedhashonly=sortedhashonly
table.sortedindexonly=sortedindexonly
table.sortedhashkeys=sortedhashkeys
local function nothing() end
local function sortedhash(t,cmp)
if t then
local s
if cmp then
s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
else
s=sortedkeys(t)
end
local m=#s
if m==1 then
return next,t
elseif m>0 then
local n=0
return function()
if n<m then
n=n+1
local k=s[n]
return k,t[k]
end
end
end
end
return nothing
end
table.sortedhash=sortedhash
table.sortedpairs=sortedhash
function table.append(t,list)
local n=#t
for i=1,#list do
n=n+1
t[n]=list[i]
end
return t
end
function table.prepend(t,list)
local nl=#list
local nt=nl+#t
for i=#t,1,-1 do
t[nt]=t[i]
nt=nt-1
end
for i=1,#list do
t[i]=list[i]
end
return t
end
function table.merge(t,...)
t=t or {}
for i=1,select("#",...) do
for k,v in next,(select(i,...)) do
t[k]=v
end
end
return t
end
function table.merged(...)
local t={}
for i=1,select("#",...) do
for k,v in next,(select(i,...)) do
t[k]=v
end
end
return t
end
function table.imerge(t,...)
local nt=#t
for i=1,select("#",...) do
local nst=select(i,...)
for j=1,#nst do
nt=nt+1
t[nt]=nst[j]
end
end
return t
end
function table.imerged(...)
local tmp,ntmp={},0
for i=1,select("#",...) do
local nst=select(i,...)
for j=1,#nst do
ntmp=ntmp+1
tmp[ntmp]=nst[j]
end
end
return tmp
end
local function fastcopy(old,metatabletoo)
if old then
local new={}
for k,v in next,old do
if type(v)=="table" then
new[k]=fastcopy(v,metatabletoo)
else
new[k]=v
end
end
if metatabletoo then
local mt=getmetatable(old)
if mt then
setmetatable(new,mt)
end
end
return new
else
return {}
end
end
local function copy(t,tables)
tables=tables or {}
local tcopy={}
if not tables[t] then
tables[t]=tcopy
end
for i,v in next,t do
if type(i)=="table" then
if tables[i] then
i=tables[i]
else
i=copy(i,tables)
end
end
if type(v)~="table" then
tcopy[i]=v
elseif tables[v] then
tcopy[i]=tables[v]
else
tcopy[i]=copy(v,tables)
end
end
local mt=getmetatable(t)
if mt then
setmetatable(tcopy,mt)
end
return tcopy
end
table.fastcopy=fastcopy
table.copy=copy
function table.derive(parent)
local child={}
if parent then
setmetatable(child,{ __index=parent })
end
return child
end
function table.tohash(t,value)
local h={}
if t then
if value==nil then value=true end
for _,v in next,t do
h[v]=value
end
end
return h
end
function table.fromhash(t)
local hsh,h={},0
for k,v in next,t do
if v then
h=h+1
hsh[h]=k
end
end
return hsh
end
local noquotes,hexify,handle,compact,inline,functions
local reserved=table.tohash {
'and','break','do','else','elseif','end','false','for','function','if',
'in','local','nil','not','or','repeat','return','then','true','until','while',
'NaN','goto',
}
local function simple_table(t)
local nt=#t
if nt>0 then
local n=0
for _,v in next,t do
n=n+1
end
if n==nt then
local tt={}
for i=1,nt do
local v=t[i]
local tv=type(v)
if tv=="number" then
if hexify then
tt[i]=format("0x%X",v)
else
tt[i]=tostring(v)
end
elseif tv=="string" then
tt[i]=format("%q",v)
elseif tv=="boolean" then
tt[i]=v and "true" or "false"
else
return nil
end
end
return tt
end
end
return nil
end
local propername=patterns.propername
local function dummy() end
local function do_serialize(root,name,depth,level,indexed)
if level>0 then
depth=depth.." "
if indexed then
handle(format("%s{",depth))
else
local tn=type(name)
if tn=="number" then
if hexify then
handle(format("%s[0x%X]={",depth,name))
else
handle(format("%s[%s]={",depth,name))
end
elseif tn=="string" then
if noquotes and not reserved[name] and lpegmatch(propername,name) then
handle(format("%s%s={",depth,name))
else
handle(format("%s[%q]={",depth,name))
end
elseif tn=="boolean" then
handle(format("%s[%s]={",depth,name and "true" or "false"))
else
handle(format("%s{",depth))
end
end
end
if root and next(root)~=nil then
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]
local tv=type(v)
local tk=type(k)
if compact and first and tk=="number" and k>=first and k<=last then
if tv=="number" then
if hexify then
handle(format("%s 0x%X,",depth,v))
else
handle(format("%s %s,",depth,v))
end
elseif tv=="string" then
handle(format("%s %q,",depth,v))
elseif tv=="table" then
if next(v)==nil then
handle(format("%s {},",depth))
elseif inline then
local st=simple_table(v)
if st then
handle(format("%s { %s },",depth,concat(st,", ")))
else
do_serialize(v,k,depth,level+1,true)
end
else
do_serialize(v,k,depth,level+1,true)
end
elseif tv=="boolean" then
handle(format("%s %s,",depth,v and "true" or "false"))
elseif tv=="function" then
if functions then
handle(format('%s load(%q),',depth,dump(v)))
else
handle(format('%s "function",',depth))
end
else
handle(format("%s %q,",depth,tostring(v)))
end
elseif k=="__p__" then
if false then
handle(format("%s __p__=nil,",depth))
end
elseif tv=="number" then
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=0x%X,",depth,k,v))
else
handle(format("%s [%s]=%s,",depth,k,v))
end
elseif tk=="boolean" then
if hexify then
handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
else
handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
end
elseif tk~="string" then
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
if hexify then
handle(format("%s %s=0x%X,",depth,k,v))
else
handle(format("%s %s=%s,",depth,k,v))
end
else
if hexify then
handle(format("%s [%q]=0x%X,",depth,k,v))
else
handle(format("%s [%q]=%s,",depth,k,v))
end
end
elseif tv=="string" then
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,v))
else
handle(format("%s [%s]=%q,",depth,k,v))
end
elseif tk=="boolean" then
handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
elseif tk~="string" then
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s=%q,",depth,k,v))
else
handle(format("%s [%q]=%q,",depth,k,v))
end
elseif tv=="table" then
if next(v)==nil then
if tk=="number" then
if hexify then
handle(format("%s [0x%X]={},",depth,k))
else
handle(format("%s [%s]={},",depth,k))
end
elseif tk=="boolean" then
handle(format("%s [%s]={},",depth,k and "true" or "false"))
elseif tk~="string" then
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s={},",depth,k))
else
handle(format("%s [%q]={},",depth,k))
end
elseif inline then
local st=simple_table(v)
if st then
if tk=="number" then
if hexify then
handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
else
handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
end
elseif tk=="boolean" then
handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
elseif tk~="string" then
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
else
handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
end
else
do_serialize(v,k,depth,level+1)
end
else
do_serialize(v,k,depth,level+1)
end
elseif tv=="boolean" then
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
else
handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
end
elseif tk=="boolean" then
handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
elseif tk~="string" then
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
else
handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
end
elseif tv=="function" then
if functions then
local f=getinfo(v).what=="C" and dump(dummy) or dump(v)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=load(%q),",depth,k,f))
else
handle(format("%s [%s]=load(%q),",depth,k,f))
end
elseif tk=="boolean" then
handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
elseif tk~="string" then
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s=load(%q),",depth,k,f))
else
handle(format("%s [%q]=load(%q),",depth,k,f))
end
end
else
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
else
handle(format("%s [%s]=%q,",depth,k,tostring(v)))
end
elseif tk=="boolean" then
handle(format(
|