summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2017-02-23 18:12:36 +0100
committerContext Git Mirror Bot <phg42.2a@gmail.com>2017-02-23 18:12:36 +0100
commitc91d92093b72a73a92c3ae3c641137abe6fb64b9 (patch)
treebfbdc4359ae391d0d96e577fb544023464427e81
parente4223677ac0d23e4888e41efda0d2e6aabbe76bf (diff)
downloadcontext-c91d92093b72a73a92c3ae3c641137abe6fb64b9.tar.gz
2017-02-23 17:13:00
-rw-r--r--doc/context/documents/general/qrcs/setup-cs.pdfbin799320 -> 799458 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-de.pdfbin801319 -> 801458 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-en.pdfbin804334 -> 804461 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-fr.pdfbin799308 -> 799444 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-it.pdfbin799949 -> 800079 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-nl.pdfbin796736 -> 796876 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-ro.pdfbin796671 -> 796814 bytes
-rw-r--r--scripts/context/lua/mtxrun.lua525
-rw-r--r--scripts/context/stubs/mswin/mtxrun.lua525
-rw-r--r--scripts/context/stubs/unix/mtxrun525
-rw-r--r--scripts/context/stubs/win64/mtxrun.lua525
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkiv/anch-pos.lua2
-rw-r--r--tex/context/base/mkiv/char-fio.lua5
-rw-r--r--tex/context/base/mkiv/char-utf.lua11
-rw-r--r--tex/context/base/mkiv/char-utf.mkiv6
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/data-ini.lua10
-rw-r--r--tex/context/base/mkiv/font-dsp.lua214
-rw-r--r--tex/context/base/mkiv/font-lib.mkvi1
-rw-r--r--tex/context/base/mkiv/font-lig.lua52
-rw-r--r--tex/context/base/mkiv/font-otc.lua42
-rw-r--r--tex/context/base/mkiv/font-otj.lua2
-rw-r--r--tex/context/base/mkiv/font-otr.lua63
-rw-r--r--tex/context/base/mkiv/font-ots.lua55
-rw-r--r--tex/context/base/mkiv/luat-cnf.lua3
-rw-r--r--tex/context/base/mkiv/node-fin.lua2
-rw-r--r--tex/context/base/mkiv/publ-imp-apa.lua3
-rw-r--r--tex/context/base/mkiv/publ-imp-apa.mkvi8
-rw-r--r--tex/context/base/mkiv/publ-ini.lua29
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin25672 -> 25646 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin372476 -> 373036 bytes
-rw-r--r--tex/context/base/mkiv/trac-deb.lua12
-rw-r--r--tex/context/base/mkiv/util-deb.lua245
-rw-r--r--tex/context/base/mkiv/util-env.lua28
-rw-r--r--tex/context/base/mkiv/util-fil.lua7
-rw-r--r--tex/context/base/mkiv/util-lib.lua284
-rw-r--r--tex/context/base/mkiv/util-str.lua37
-rw-r--r--tex/context/interface/mkiv/i-context.pdfbin804334 -> 804461 bytes
-rw-r--r--tex/context/interface/mkiv/i-readme.pdfbin60772 -> 60772 bytes
-rw-r--r--tex/context/modules/mkiv/m-matrix.mkiv160
-rw-r--r--tex/context/modules/mkiv/s-inf-03.mkiv16
-rw-r--r--tex/generic/context/luatex/luatex-fonts-lig.lua2067
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua2387
-rw-r--r--tex/generic/context/luatex/luatex-fonts.lua1
47 files changed, 6950 insertions, 910 deletions
diff --git a/doc/context/documents/general/qrcs/setup-cs.pdf b/doc/context/documents/general/qrcs/setup-cs.pdf
index e26a63165..bb028e14d 100644
--- a/doc/context/documents/general/qrcs/setup-cs.pdf
+++ b/doc/context/documents/general/qrcs/setup-cs.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-de.pdf b/doc/context/documents/general/qrcs/setup-de.pdf
index bf2114679..4b739bb8f 100644
--- a/doc/context/documents/general/qrcs/setup-de.pdf
+++ b/doc/context/documents/general/qrcs/setup-de.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-en.pdf b/doc/context/documents/general/qrcs/setup-en.pdf
index 56f1b02a0..a62e63912 100644
--- a/doc/context/documents/general/qrcs/setup-en.pdf
+++ b/doc/context/documents/general/qrcs/setup-en.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-fr.pdf b/doc/context/documents/general/qrcs/setup-fr.pdf
index 9c188ce53..44854efd4 100644
--- a/doc/context/documents/general/qrcs/setup-fr.pdf
+++ b/doc/context/documents/general/qrcs/setup-fr.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-it.pdf b/doc/context/documents/general/qrcs/setup-it.pdf
index 47e23baef..71b9f0004 100644
--- a/doc/context/documents/general/qrcs/setup-it.pdf
+++ b/doc/context/documents/general/qrcs/setup-it.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-nl.pdf b/doc/context/documents/general/qrcs/setup-nl.pdf
index 9799f7635..40635c015 100644
--- a/doc/context/documents/general/qrcs/setup-nl.pdf
+++ b/doc/context/documents/general/qrcs/setup-nl.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-ro.pdf b/doc/context/documents/general/qrcs/setup-ro.pdf
index a570ab195..5a33bc8e0 100644
--- a/doc/context/documents/general/qrcs/setup-ro.pdf
+++ b/doc/context/documents/general/qrcs/setup-ro.pdf
Binary files differ
diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua
index bdb81b477..0c3355fcc 100644
--- a/scripts/context/lua/mtxrun.lua
+++ b/scripts/context/lua/mtxrun.lua
@@ -5632,7 +5632,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-str"] = package.loaded["util-str"] or true
--- original size: 36650, stripped down to: 19963
+-- original size: 37582, stripped down to: 20676
if not modules then modules={} end modules ['util-str']={
version=1.001,
@@ -5871,6 +5871,27 @@ function number.sparseexponent(f,n)
end
return tostring(n)
end
+local hf={}
+local hs={}
+setmetatable(hf,{ __index=function(t,k)
+ local v="%."..k.."f"
+ t[k]=v
+ return v
+end } )
+setmetatable(hs,{ __index=function(t,k)
+ local v="%"..k.."s"
+ t[k]=v
+ return v
+end } )
+function number.formattedfloat(n,b,a)
+ local s=format(hf[a],n)
+ local l=(b or 0)+(a or 0)+1
+ if #s<l then
+ return format(hs[l],s)
+ else
+ return s
+ end
+end
local template=[[
%s
%s
@@ -5898,6 +5919,7 @@ local autodouble=string.autodouble
local sequenced=table.sequenced
local formattednumber=number.formatted
local sparseexponent=number.sparseexponent
+local formattedfloat=number.formattedfloat
]]
else
environment={
@@ -5921,6 +5943,7 @@ else
sequenced=table.sequenced,
formattednumber=number.formatted,
sparseexponent=number.sparseexponent,
+ formattedfloat=number.formattedfloat
}
end
local arguments={ "a1" }
@@ -5931,6 +5954,7 @@ setmetatable(arguments,{ __index=function(t,k)
end
})
local prefix_any=C((S("+- .")+R("09"))^0)
+local prefix_sub=(C((S("+-")+R("09"))^0)+Cc(0))*P(".")*(C((S("+-")+R("09"))^0)+Cc(0))
local prefix_tab=P("{")*C((1-P("}"))^0)*P("}")+C((1-R("az","AZ","09","%%"))^0)
local format_s=function(f)
n=n+1
@@ -5981,6 +6005,10 @@ local format_F=function(f)
return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n)
end
end
+local format_k=function(b,a)
+ n=n+1
+ return format("formattedfloat(a%s,%i,%i)",n,b or 0,a or 0)
+end
local format_g=function(f)
n=n+1
return format("format('%%%sg',a%s)",f,n)
@@ -6189,7 +6217,8 @@ local builder=Cs { "start",
+V("s")+V("q")+V("i")+V("d")+V("f")+V("F")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o")
+V("c")+V("C")+V("S")
+V("Q")
-+V("N")
++V("N")
++V("k")
+V("r")+V("h")+V("H")+V("u")+V("U")+V("p")+V("b")+V("t")+V("T")+V("l")+V("L")+V("I")+V("w")
+V("W")
+V("a")
@@ -6216,6 +6245,7 @@ local builder=Cs { "start",
["S"]=(prefix_any*P("S"))/format_S,
["Q"]=(prefix_any*P("Q"))/format_S,
["N"]=(prefix_any*P("N"))/format_N,
+ ["k"]=(prefix_sub*P("k"))/format_k,
["c"]=(prefix_any*P("c"))/format_c,
["C"]=(prefix_any*P("C"))/format_C,
["r"]=(prefix_any*P("r"))/format_r,
@@ -7012,7 +7042,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-fil"] = package.loaded["util-fil"] or true
--- original size: 6316, stripped down to: 4866
+-- original size: 6362, stripped down to: 4907
if not modules then modules={} end modules ['util-fil']={
version=1.001,
@@ -7098,6 +7128,7 @@ end
files.readcardinal1=files.readbyte
files.readcardinal=files.readcardinal1
files.readinteger=files.readinteger1
+files.readsignedbyte=files.readinteger1
function files.readcardinal2(f)
local a,b=byte(f:read(2),1,2)
return 0x100*a+b
@@ -9795,7 +9826,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-deb"] = package.loaded["util-deb"] or true
--- original size: 4030, stripped down to: 2718
+-- original size: 8473, stripped down to: 6211
if not modules then modules={} end modules ['util-deb']={
version=1.001,
@@ -9805,75 +9836,219 @@ if not modules then modules={} end modules ['util-deb']={
license="see context related readme files"
}
local debug=require "debug"
-local getinfo=debug.getinfo
+local getinfo,sethook=debug.getinfo,debug.sethook
local type,next,tostring=type,next,tostring
-local format,find=string.format,string.find
-local is_boolean=string.is_boolean
+local format,find,sub,gsub=string.format,string.find,string.sub,string.gsub
+local insert,remove,sort=table.insert,table.remove,table.sort
utilities=utilities or {}
local debugger=utilities.debugger or {}
utilities.debugger=debugger
-local counters={}
-local names={}
local report=logs.reporter("debugger")
-local function hook()
- local f=getinfo(2)
- if f then
- local n="unknown"
- if f.what=="C" then
- n=f.name or '<anonymous>'
- if not names[n] then
- names[n]=format("%42s",n)
+local ticks=os.gettimeofday or os.clock
+local seconds=function(n) return n or 0 end
+local overhead=0
+local dummycalls=10*1000
+local nesting=0
+local names={}
+local function initialize()
+ if FFISUPPORTED and ffi then
+ if os.type=="windows" then
+ local okay,kernel=pcall(ffi.load,"kernel32")
+ if kernel then
+ local tonumber=ffi.number or tonumber
+ffi.cdef[[
+int QueryPerformanceFrequency(int64_t *lpFrequency);
+int QueryPerformanceCounter(int64_t *lpPerformanceCount);
+]]
+ local target=ffi.new("__int64[1]")
+ ticks=function()
+ if kernel.QueryPerformanceCounter(target)==1 then
+ return tonumber(target[0])
+ else
+ return 0
+ end
+ end
+ local target=ffi.new("__int64[1]")
+ seconds=function(ticks)
+ if kernel.QueryPerformanceFrequency(target)==1 then
+ return ticks/tonumber(target[0])
+ else
+ return 0
+ end
+ end
end
- else
- n=f.name or f.namewhat or f.what
- if not n or n=="" then
- n="?"
+ elseif os.type=="unix" then
+ local C=ffi.C
+ local tonumber=ffi.number or tonumber
+ffi.cdef [[
+struct timespec { long sec; long nsec; };
+int clock_gettime(int timerid, struct timespec *t);
+ ]]
+ local target=ffi.new("timespec[?]",1)
+ function ticks()
+ C.clock_gettime(2,target)
+ return tonumber(target[0].sec*1000000000+target[0].nsec)
+ end
+ seconds=function(ticks)
+ return ticks/1000000000
+ end
+ end
+ end
+ initialize=false
+end
+table.setmetatableindex(names,function(t,name)
+ local v=table.setmetatableindex(function(t,source)
+ local v=table.setmetatableindex(function(t,line)
+ local v={ total=0,count=0 }
+ t[line]=v
+ return v
+ end)
+ t[source]=v
+ return v
+ end)
+ t[name]=v
+ return v
+end)
+local function hook(where)
+ local f=getinfo(2,"nSl")
+ if f then
+ local source=f.short_src
+ if not source then
+ return
+ end
+ local line=f.linedefined or 0
+ local name=f.name
+ if not name then
+ local what=f.what
+ if what=="C" then
+ name="<anonymous>"
+ else
+ name=f.namewhat or what or "<unknown>"
end
- if not names[n] then
- names[n]=format("%42s : % 5i : %s",n,f.linedefined or 0,f.short_src or "unknown source")
+ end
+ local data=names[name][source][line]
+ if where=="call" then
+ data.count=data.count+1
+ insert(data,ticks())
+ elseif where=="return" then
+ local t=remove(data)
+ if t then
+ data.total=data.total+ticks()-t
end
end
- counters[n]=(counters[n] or 0)+1
end
end
-function debugger.showstats(printer,threshold)
- printer=printer or report
- threshold=threshold or 0
- local total,grandtotal,functions=0,0,0
+function debugger.showstats(printer)
+ local printer=printer or report
+ local calls=0
+ local functions=0
local dataset={}
- for name,count in next,counters do
- dataset[#dataset+1]={ name,count }
+ local length=0
+ local wholetime=0
+ for name,sources in next,names do
+ for source,lines in next,sources do
+ for line,data in next,lines do
+ if #name>length then
+ length=#name
+ end
+ local total=data.total
+ local count=data.count
+ local real=total
+ if real>0 then
+ real=total-(count*overhead/dummycalls)
+ if real<0 then
+ real=0
+ end
+ wholetime=wholetime+real
+ end
+ if line<0 then
+ line=0
+ end
+ dataset[#dataset+1]={ real,total,count,name,source,line }
+ end
+ end
+ end
+ sort(dataset,function(a,b)
+ if a[1]==b[1] then
+ if a[2]==b[2] then
+ if a[3]==b[3] then
+ if a[4]==b[4] then
+ if a[5]==b[5] then
+ return a[6]<b[6]
+ else
+ return a[5]<b[5]
+ end
+ else
+ return a[4]<b[4]
+ end
+ else
+ return b[3]<a[3]
+ end
+ else
+ return b[2]<a[2]
+ end
+ else
+ return b[1]<a[1]
+ end
+ end)
+ if length>50 then
+ length=50
end
- table.sort(dataset,function(a,b) return a[2]==b[2] and b[1]>a[1] or a[2]>b[2] end)
+ local fmt=string.formatters["%4.9k %4.9k %3.3k %8i %-"..length.."s %4i %s"]
for i=1,#dataset do
- local d=dataset[i]
- local name=d[1]
- local count=d[2]
- if count>threshold and not find(name,"for generator") then
- printer(format("%8i %s\n",count,names[name]))
- total=total+count
- end
- grandtotal=grandtotal+count
+ local data=dataset[i]
+ local real=data[1]
+ local total=data[2]
+ local count=data[3]
+ local name=data[4]
+ local source=data[5]
+ local line=data[6]
+ local percent=real/wholetime
+ calls=calls+count
functions=functions+1
+ name=gsub(name,"%s+"," ")
+ if #name>length then
+ name=sub(name,1,length)
+ end
+ printer(fmt(seconds(total),seconds(real),percent,count,name,line,source))
end
- printer("\n")
- printer(format("functions : % 10i\n",functions))
- printer(format("total : % 10i\n",total))
- printer(format("grand total: % 10i\n",grandtotal))
- printer(format("threshold : % 10i\n",threshold))
+ printer("")
+ printer(format("functions : %i",functions))
+ printer(format("calls : %i",calls))
+ printer(format("overhead : %f",seconds(overhead/1000)))
end
-function debugger.savestats(filename,threshold)
+function debugger.savestats(filename)
local f=io.open(filename,'w')
if f then
- debugger.showstats(function(str) f:write(str) end,threshold)
+ debugger.showstats(function(str) f:write(str,"\n") end)
f:close()
end
end
function debugger.enable()
- debug.sethook(hook,"c")
+ if nesting==0 then
+ running=true
+ if initialize then
+ initialize()
+ end
+ sethook(hook,"cr")
+ local function dummy() end
+ local t=ticks()
+ for i=1,dummycalls do
+ dummy()
+ end
+ overhead=ticks()-t
+ end
+ if nesting>0 then
+ nesting=nesting+1
+ end
end
function debugger.disable()
- debug.sethook()
+ if nesting>0 then
+ nesting=nesting-1
+ end
+ if nesting==0 then
+ sethook()
+ end
end
local function showtraceback(rep)
local level=2
@@ -10716,7 +10891,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-env"] = package.loaded["util-env"] or true
--- original size: 9028, stripped down to: 5176
+-- original size: 9552, stripped down to: 5176
if not modules then modules={} end modules ['util-env']={
version=1.001,
@@ -15055,7 +15230,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-ini"] = package.loaded["data-ini"] or true
--- original size: 11444, stripped down to: 7830
+-- original size: 11459, stripped down to: 7680
if not modules then modules={} end modules ['data-ini']={
version=1.001,
@@ -15200,11 +15375,6 @@ if not texroot or texroot=="" then
ossetenv('TEXROOT',texroot)
end
environment.texroot=file.collapsepath(texroot)
-if type(profiler)=="table" and not jit then
- directives.register("system.profile",function()
- profiler.start("luatex-profile.log")
- end)
-end
local prefixes=utilities.storage.allocate()
resolvers.prefixes=prefixes
local resolved={}
@@ -19454,7 +19624,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-lib"] = package.loaded["util-lib"] or true
--- original size: 11846, stripped down to: 6059
+-- original size: 13648, stripped down to: 7455
if not modules then modules={} end modules ['util-lib']={
version=1.001,
@@ -19463,35 +19633,51 @@ if not modules then modules={} end modules ['util-lib']={
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files",
}
-local gsub,find=string.gsub,string.find
-local pathpart,nameonly,joinfile=file.pathpart,file.nameonly,file.join
-local findfile,findfiles=resolvers and resolvers.findfile,resolvers and resolvers.findfiles
-local loaded=package.loaded
-local report_swiglib=logs.reporter("swiglib")
-local trace_swiglib=false trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
+local type=type
+local next=next
+local pcall=pcall
+local gsub=string.gsub
+local find=string.find
+local sort=table.sort
+local pathpart=file.pathpart
+local nameonly=file.nameonly
+local joinfile=file.join
+local removesuffix=file.removesuffix
+local findfile=resolvers.findfile
+local findfiles=resolvers.findfiles
+local expandpaths=resolvers.expandedpathlistfromvariable
+local qualifiedpath=file.is_qualified_path
+local isfile=lfs.isfile
local done=false
-local function requireswiglib(required,version)
- local trace_swiglib=trace_swiglib or package.helpers.trace
- local library=loaded[required]
- if library==nil then
- if trace_swiglib then
- report_swiglib("requiring library %a with version %a",required,version or "any")
+local function locate(required,version,trace,report,action)
+ if type(required)~="string" then
+ report("provide a proper library name")
+ return
+ end
+ if trace then
+ report("requiring library %a with version %a",required,version or "any")
+ end
+ local found_library=nil
+ if qualifiedpath(required) then
+ if isfile(required) then
+ found_library=required
end
+ else
local required_full=gsub(required,"%.","/")
local required_path=pathpart(required_full)
local required_base=nameonly(required_full)
local required_name=required_base.."."..os.libsuffix
local version=type(version)=="string" and version~="" and version or false
local engine=environment.ownmain or false
- if trace_swiglib and not done then
- local list=resolvers.expandedpathlistfromvariable("lib")
+ if trace and not done then
+ local list=expandpaths("lib")
for i=1,#list do
- report_swiglib("tds path %i: %s",i,list[i])
+ report("tds path %i: %s",i,list[i])
end
end
local function found(locate,asked_library,how,...)
- if trace_swiglib then
- report_swiglib("checking %s: %a",how,asked_library)
+ if trace then
+ report("checking %s: %a",how,asked_library)
end
return locate(asked_library,...)
end
@@ -19499,45 +19685,45 @@ local function requireswiglib(required,version)
local found=nil
if version then
local asked_library=joinfile(required_path,version,required_name)
- if trace_swiglib then
- report_swiglib("checking %s: %a","with version",asked_library)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
found=locate(asked_library,...)
end
if not found or found=="" then
local asked_library=joinfile(required_path,required_name)
- if trace_swiglib then
- report_swiglib("checking %s: %a","with version",asked_library)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
found=locate(asked_library,...)
end
return found and found~="" and found or false
end
local function attempt(checkpattern)
- if trace_swiglib then
- report_swiglib("checking tds lib paths strictly")
+ if trace then
+ report("checking tds lib paths strictly")
end
local found=findfile and check(findfile,"lib")
if found and (not checkpattern or find(found,checkpattern)) then
return found
end
- if trace_swiglib then
- report_swiglib("checking tds lib paths with wildcard")
+ if trace then
+ report("checking tds lib paths with wildcard")
end
local asked_library=joinfile(required_path,".*",required_name)
- if trace_swiglib then
- report_swiglib("checking %s: %a","latest version",asked_library)
+ if trace then
+ report("checking %s: %a","latest version",asked_library)
end
local list=findfiles(asked_library,"lib",true)
if list and #list>0 then
- table.sort(list)
+ sort(list)
local found=list[#list]
if found and (not checkpattern or find(found,checkpattern)) then
return found
end
end
- if trace_swiglib then
- report_swiglib("checking lib paths")
+ if trace then
+ report("checking lib paths")
end
package.extralibpath(environment.ownpath)
local paths=package.libpaths()
@@ -19549,89 +19735,132 @@ local function requireswiglib(required,version)
end
return false
end
- local found_library=nil
if engine then
- if trace_swiglib then
- report_swiglib("attemp 1, engine %a",engine)
+ if trace then
+ report("attemp 1, engine %a",engine)
end
found_library=attempt("/"..engine.."/")
if not found_library then
- if trace_swiglib then
- report_swiglib("attemp 2, no engine",asked_library)
+ if trace then
+ report("attemp 2, no engine",asked_library)
end
found_library=attempt()
end
else
found_library=attempt()
end
- if not found_library then
- if trace_swiglib then
- report_swiglib("not found: %a",required)
- end
+ end
+ if not found_library then
+ if trace then
+ report("not found: %a",required)
+ end
+ library=false
+ else
+ if trace then
+ report("found: %a",found_library)
+ end
+ local message,result=action(found_library,required_base)
+ if result then
+ library=result
+ else
library=false
+ report("load error: message %a, library %a",tostring(message),found_library or "no library")
+ end
+ end
+ if not library then
+ report("unknown: %a",required)
+ elseif trace then
+ report("stored: %a",required)
+ end
+ return library
+end
+do
+ local report_swiglib=logs.reporter("swiglib")
+ local trace_swiglib=false
+ local savedrequire=require
+ local loadedlibs={}
+ trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
+ function requireswiglib(required,version)
+ local library=loadedlibs[library]
+ if library==nil then
+ local trace_swiglib=trace_swiglib or package.helpers.trace
+ library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
+ dir.push(pathpart(name))
+ local opener="luaopen_"..base
+ local library,message=package.loadlib(name,opener)
+ local libtype=type(library)
+ if libtype=="function" then
+ library=library()
+ message=true
+ else
+ report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
+ library=false
+ end
+ dir.pop()
+ return message,library
+ end)
+ loadedlibs[required]=library or false
+ end
+ return library
+ end
+ function require(name,version)
+ if find(name,"^swiglib%.") then
+ return requireswiglib(name,version)
else
- local path=pathpart(found_library)
- local base=nameonly(found_library)
- dir.push(path)
+ return savedrequire(name)
+ end
+ end
+ local swiglibs={}
+ local initializer="core"
+ function swiglib(name,version)
+ local library=swiglibs[name]
+ if not library then
+ statistics.starttiming(swiglibs)
if trace_swiglib then
- report_swiglib("found: %a",found_library)
- end
- local message=nil
- local opener="luaopen_"..required_base
- library,message=package.loadlib(found_library,opener)
- local libtype=type(library)
- if libtype=="function" then
- library=library()
+ report_swiglib("loading %a",name)
+ end
+ if not find(name,"%."..initializer.."$") then
+ fullname="swiglib."..name.."."..initializer
else
- report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
- library=false
+ fullname="swiglib."..name
end
- dir.pop()
+ library=requireswiglib(fullname,version)
+ swiglibs[name]=library
+ statistics.stoptiming(swiglibs)
end
- if not library then
- report_swiglib("unknown: %a",required)
- elseif trace_swiglib then
- report_swiglib("stored: %a",required)
- end
- loaded[required]=library
- else
- report_swiglib("reused: %a",required)
+ return library
end
- return library
+ statistics.register("used swiglibs",function()
+ if next(swiglibs) then
+ return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
+ end
+ end)
end
-local savedrequire=require
-function require(name,version)
- if find(name,"^swiglib%.") then
- return requireswiglib(name,version)
- else
- return savedrequire(name)
+if FFISUPPORTED and ffi and ffi.load then
+ local report_ffilib=logs.reporter("ffilib")
+ local trace_ffilib=false
+ local savedffiload=ffi.load
+ trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
+ function ffilib(required,version)
+ return locate(required,version,trace_ffilib,report_ffilib,function(name)
+ local message,library=pcall(savedffiload,removesuffix(name))
+ if type(library)=="userdata" then
+ return message,library
+ else
+ return message,false
+ end
+ end)
end
-end
-local swiglibs={}
-local initializer="core"
-function swiglib(name,version)
- local library=swiglibs[name]
- if not library then
- statistics.starttiming(swiglibs)
- if trace_swiglib then
- report_swiglib("loading %a",name)
- end
- if not find(name,"%."..initializer.."$") then
- fullname="swiglib."..name.."."..initializer
+ function ffi.load(name)
+ local library=ffilib(name)
+ if type(library)=="userdata" then
+ return library
else
- fullname="swiglib."..name
+ report_ffilib("trying to load %a using normal loader",name)
+ return savedffiload(name)
end
- library=requireswiglib(fullname,version)
- swiglibs[name]=library
- statistics.stoptiming(swiglibs)
end
- return library
end
-statistics.register("used swiglibs",function()
- if next(swiglibs) then
- return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
- end
-end)
end -- of closure
@@ -19975,8 +20204,8 @@ end -- of closure
-- used libraries : l-lua.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 847975
--- stripped bytes : 308174
+-- original bytes : 855737
+-- stripped bytes : 310443
-- end library merge
diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua
index bdb81b477..0c3355fcc 100644
--- a/scripts/context/stubs/mswin/mtxrun.lua
+++ b/scripts/context/stubs/mswin/mtxrun.lua
@@ -5632,7 +5632,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-str"] = package.loaded["util-str"] or true
--- original size: 36650, stripped down to: 19963
+-- original size: 37582, stripped down to: 20676
if not modules then modules={} end modules ['util-str']={
version=1.001,
@@ -5871,6 +5871,27 @@ function number.sparseexponent(f,n)
end
return tostring(n)
end
+local hf={}
+local hs={}
+setmetatable(hf,{ __index=function(t,k)
+ local v="%."..k.."f"
+ t[k]=v
+ return v
+end } )
+setmetatable(hs,{ __index=function(t,k)
+ local v="%"..k.."s"
+ t[k]=v
+ return v
+end } )
+function number.formattedfloat(n,b,a)
+ local s=format(hf[a],n)
+ local l=(b or 0)+(a or 0)+1
+ if #s<l then
+ return format(hs[l],s)
+ else
+ return s
+ end
+end
local template=[[
%s
%s
@@ -5898,6 +5919,7 @@ local autodouble=string.autodouble
local sequenced=table.sequenced
local formattednumber=number.formatted
local sparseexponent=number.sparseexponent
+local formattedfloat=number.formattedfloat
]]
else
environment={
@@ -5921,6 +5943,7 @@ else
sequenced=table.sequenced,
formattednumber=number.formatted,
sparseexponent=number.sparseexponent,
+ formattedfloat=number.formattedfloat
}
end
local arguments={ "a1" }
@@ -5931,6 +5954,7 @@ setmetatable(arguments,{ __index=function(t,k)
end
})
local prefix_any=C((S("+- .")+R("09"))^0)
+local prefix_sub=(C((S("+-")+R("09"))^0)+Cc(0))*P(".")*(C((S("+-")+R("09"))^0)+Cc(0))
local prefix_tab=P("{")*C((1-P("}"))^0)*P("}")+C((1-R("az","AZ","09","%%"))^0)
local format_s=function(f)
n=n+1
@@ -5981,6 +6005,10 @@ local format_F=function(f)
return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n)
end
end
+local format_k=function(b,a)
+ n=n+1
+ return format("formattedfloat(a%s,%i,%i)",n,b or 0,a or 0)
+end
local format_g=function(f)
n=n+1
return format("format('%%%sg',a%s)",f,n)
@@ -6189,7 +6217,8 @@ local builder=Cs { "start",
+V("s")+V("q")+V("i")+V("d")+V("f")+V("F")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o")
+V("c")+V("C")+V("S")
+V("Q")
-+V("N")
++V("N")
++V("k")
+V("r")+V("h")+V("H")+V("u")+V("U")+V("p")+V("b")+V("t")+V("T")+V("l")+V("L")+V("I")+V("w")
+V("W")
+V("a")
@@ -6216,6 +6245,7 @@ local builder=Cs { "start",
["S"]=(prefix_any*P("S"))/format_S,
["Q"]=(prefix_any*P("Q"))/format_S,
["N"]=(prefix_any*P("N"))/format_N,
+ ["k"]=(prefix_sub*P("k"))/format_k,
["c"]=(prefix_any*P("c"))/format_c,
["C"]=(prefix_any*P("C"))/format_C,
["r"]=(prefix_any*P("r"))/format_r,
@@ -7012,7 +7042,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-fil"] = package.loaded["util-fil"] or true
--- original size: 6316, stripped down to: 4866
+-- original size: 6362, stripped down to: 4907
if not modules then modules={} end modules ['util-fil']={
version=1.001,
@@ -7098,6 +7128,7 @@ end
files.readcardinal1=files.readbyte
files.readcardinal=files.readcardinal1
files.readinteger=files.readinteger1
+files.readsignedbyte=files.readinteger1
function files.readcardinal2(f)
local a,b=byte(f:read(2),1,2)
return 0x100*a+b
@@ -9795,7 +9826,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-deb"] = package.loaded["util-deb"] or true
--- original size: 4030, stripped down to: 2718
+-- original size: 8473, stripped down to: 6211
if not modules then modules={} end modules ['util-deb']={
version=1.001,
@@ -9805,75 +9836,219 @@ if not modules then modules={} end modules ['util-deb']={
license="see context related readme files"
}
local debug=require "debug"
-local getinfo=debug.getinfo
+local getinfo,sethook=debug.getinfo,debug.sethook
local type,next,tostring=type,next,tostring
-local format,find=string.format,string.find
-local is_boolean=string.is_boolean
+local format,find,sub,gsub=string.format,string.find,string.sub,string.gsub
+local insert,remove,sort=table.insert,table.remove,table.sort
utilities=utilities or {}
local debugger=utilities.debugger or {}
utilities.debugger=debugger
-local counters={}
-local names={}
local report=logs.reporter("debugger")
-local function hook()
- local f=getinfo(2)
- if f then
- local n="unknown"
- if f.what=="C" then
- n=f.name or '<anonymous>'
- if not names[n] then
- names[n]=format("%42s",n)
+local ticks=os.gettimeofday or os.clock
+local seconds=function(n) return n or 0 end
+local overhead=0
+local dummycalls=10*1000
+local nesting=0
+local names={}
+local function initialize()
+ if FFISUPPORTED and ffi then
+ if os.type=="windows" then
+ local okay,kernel=pcall(ffi.load,"kernel32")
+ if kernel then
+ local tonumber=ffi.number or tonumber
+ffi.cdef[[
+int QueryPerformanceFrequency(int64_t *lpFrequency);
+int QueryPerformanceCounter(int64_t *lpPerformanceCount);
+]]
+ local target=ffi.new("__int64[1]")
+ ticks=function()
+ if kernel.QueryPerformanceCounter(target)==1 then
+ return tonumber(target[0])
+ else
+ return 0
+ end
+ end
+ local target=ffi.new("__int64[1]")
+ seconds=function(ticks)
+ if kernel.QueryPerformanceFrequency(target)==1 then
+ return ticks/tonumber(target[0])
+ else
+ return 0
+ end
+ end
end
- else
- n=f.name or f.namewhat or f.what
- if not n or n=="" then
- n="?"
+ elseif os.type=="unix" then
+ local C=ffi.C
+ local tonumber=ffi.number or tonumber
+ffi.cdef [[
+struct timespec { long sec; long nsec; };
+int clock_gettime(int timerid, struct timespec *t);
+ ]]
+ local target=ffi.new("timespec[?]",1)
+ function ticks()
+ C.clock_gettime(2,target)
+ return tonumber(target[0].sec*1000000000+target[0].nsec)
+ end
+ seconds=function(ticks)
+ return ticks/1000000000
+ end
+ end
+ end
+ initialize=false
+end
+table.setmetatableindex(names,function(t,name)
+ local v=table.setmetatableindex(function(t,source)
+ local v=table.setmetatableindex(function(t,line)
+ local v={ total=0,count=0 }
+ t[line]=v
+ return v
+ end)
+ t[source]=v
+ return v
+ end)
+ t[name]=v
+ return v
+end)
+local function hook(where)
+ local f=getinfo(2,"nSl")
+ if f then
+ local source=f.short_src
+ if not source then
+ return
+ end
+ local line=f.linedefined or 0
+ local name=f.name
+ if not name then
+ local what=f.what
+ if what=="C" then
+ name="<anonymous>"
+ else
+ name=f.namewhat or what or "<unknown>"
end
- if not names[n] then
- names[n]=format("%42s : % 5i : %s",n,f.linedefined or 0,f.short_src or "unknown source")
+ end
+ local data=names[name][source][line]
+ if where=="call" then
+ data.count=data.count+1
+ insert(data,ticks())
+ elseif where=="return" then
+ local t=remove(data)
+ if t then
+ data.total=data.total+ticks()-t
end
end
- counters[n]=(counters[n] or 0)+1
end
end
-function debugger.showstats(printer,threshold)
- printer=printer or report
- threshold=threshold or 0
- local total,grandtotal,functions=0,0,0
+function debugger.showstats(printer)
+ local printer=printer or report
+ local calls=0
+ local functions=0
local dataset={}
- for name,count in next,counters do
- dataset[#dataset+1]={ name,count }
+ local length=0
+ local wholetime=0
+ for name,sources in next,names do
+ for source,lines in next,sources do
+ for line,data in next,lines do
+ if #name>length then
+ length=#name
+ end
+ local total=data.total
+ local count=data.count
+ local real=total
+ if real>0 then
+ real=total-(count*overhead/dummycalls)
+ if real<0 then
+ real=0
+ end
+ wholetime=wholetime+real
+ end
+ if line<0 then
+ line=0
+ end
+ dataset[#dataset+1]={ real,total,count,name,source,line }
+ end
+ end
+ end
+ sort(dataset,function(a,b)
+ if a[1]==b[1] then
+ if a[2]==b[2] then
+ if a[3]==b[3] then
+ if a[4]==b[4] then
+ if a[5]==b[5] then
+ return a[6]<b[6]
+ else
+ return a[5]<b[5]
+ end
+ else
+ return a[4]<b[4]
+ end
+ else
+ return b[3]<a[3]
+ end
+ else
+ return b[2]<a[2]
+ end
+ else
+ return b[1]<a[1]
+ end
+ end)
+ if length>50 then
+ length=50
end
- table.sort(dataset,function(a,b) return a[2]==b[2] and b[1]>a[1] or a[2]>b[2] end)
+ local fmt=string.formatters["%4.9k %4.9k %3.3k %8i %-"..length.."s %4i %s"]
for i=1,#dataset do
- local d=dataset[i]
- local name=d[1]
- local count=d[2]
- if count>threshold and not find(name,"for generator") then
- printer(format("%8i %s\n",count,names[name]))
- total=total+count
- end
- grandtotal=grandtotal+count
+ local data=dataset[i]
+ local real=data[1]
+ local total=data[2]
+ local count=data[3]
+ local name=data[4]
+ local source=data[5]
+ local line=data[6]
+ local percent=real/wholetime
+ calls=calls+count
functions=functions+1
+ name=gsub(name,"%s+"," ")
+ if #name>length then
+ name=sub(name,1,length)
+ end
+ printer(fmt(seconds(total),seconds(real),percent,count,name,line,source))
end
- printer("\n")
- printer(format("functions : % 10i\n",functions))
- printer(format("total : % 10i\n",total))
- printer(format("grand total: % 10i\n",grandtotal))
- printer(format("threshold : % 10i\n",threshold))
+ printer("")
+ printer(format("functions : %i",functions))
+ printer(format("calls : %i",calls))
+ printer(format("overhead : %f",seconds(overhead/1000)))
end
-function debugger.savestats(filename,threshold)
+function debugger.savestats(filename)
local f=io.open(filename,'w')
if f then
- debugger.showstats(function(str) f:write(str) end,threshold)
+ debugger.showstats(function(str) f:write(str,"\n") end)
f:close()
end
end
function debugger.enable()
- debug.sethook(hook,"c")
+ if nesting==0 then
+ running=true
+ if initialize then
+ initialize()
+ end
+ sethook(hook,"cr")
+ local function dummy() end
+ local t=ticks()
+ for i=1,dummycalls do
+ dummy()
+ end
+ overhead=ticks()-t
+ end
+ if nesting>0 then
+ nesting=nesting+1
+ end
end
function debugger.disable()
- debug.sethook()
+ if nesting>0 then
+ nesting=nesting-1
+ end
+ if nesting==0 then
+ sethook()
+ end
end
local function showtraceback(rep)
local level=2
@@ -10716,7 +10891,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-env"] = package.loaded["util-env"] or true
--- original size: 9028, stripped down to: 5176
+-- original size: 9552, stripped down to: 5176
if not modules then modules={} end modules ['util-env']={
version=1.001,
@@ -15055,7 +15230,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-ini"] = package.loaded["data-ini"] or true
--- original size: 11444, stripped down to: 7830
+-- original size: 11459, stripped down to: 7680
if not modules then modules={} end modules ['data-ini']={
version=1.001,
@@ -15200,11 +15375,6 @@ if not texroot or texroot=="" then
ossetenv('TEXROOT',texroot)
end
environment.texroot=file.collapsepath(texroot)
-if type(profiler)=="table" and not jit then
- directives.register("system.profile",function()
- profiler.start("luatex-profile.log")
- end)
-end
local prefixes=utilities.storage.allocate()
resolvers.prefixes=prefixes
local resolved={}
@@ -19454,7 +19624,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-lib"] = package.loaded["util-lib"] or true
--- original size: 11846, stripped down to: 6059
+-- original size: 13648, stripped down to: 7455
if not modules then modules={} end modules ['util-lib']={
version=1.001,
@@ -19463,35 +19633,51 @@ if not modules then modules={} end modules ['util-lib']={
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files",
}
-local gsub,find=string.gsub,string.find
-local pathpart,nameonly,joinfile=file.pathpart,file.nameonly,file.join
-local findfile,findfiles=resolvers and resolvers.findfile,resolvers and resolvers.findfiles
-local loaded=package.loaded
-local report_swiglib=logs.reporter("swiglib")
-local trace_swiglib=false trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
+local type=type
+local next=next
+local pcall=pcall
+local gsub=string.gsub
+local find=string.find
+local sort=table.sort
+local pathpart=file.pathpart
+local nameonly=file.nameonly
+local joinfile=file.join
+local removesuffix=file.removesuffix
+local findfile=resolvers.findfile
+local findfiles=resolvers.findfiles
+local expandpaths=resolvers.expandedpathlistfromvariable
+local qualifiedpath=file.is_qualified_path
+local isfile=lfs.isfile
local done=false
-local function requireswiglib(required,version)
- local trace_swiglib=trace_swiglib or package.helpers.trace
- local library=loaded[required]
- if library==nil then
- if trace_swiglib then
- report_swiglib("requiring library %a with version %a",required,version or "any")
+local function locate(required,version,trace,report,action)
+ if type(required)~="string" then
+ report("provide a proper library name")
+ return
+ end
+ if trace then
+ report("requiring library %a with version %a",required,version or "any")
+ end
+ local found_library=nil
+ if qualifiedpath(required) then
+ if isfile(required) then
+ found_library=required
end
+ else
local required_full=gsub(required,"%.","/")
local required_path=pathpart(required_full)
local required_base=nameonly(required_full)
local required_name=required_base.."."..os.libsuffix
local version=type(version)=="string" and version~="" and version or false
local engine=environment.ownmain or false
- if trace_swiglib and not done then
- local list=resolvers.expandedpathlistfromvariable("lib")
+ if trace and not done then
+ local list=expandpaths("lib")
for i=1,#list do
- report_swiglib("tds path %i: %s",i,list[i])
+ report("tds path %i: %s",i,list[i])
end
end
local function found(locate,asked_library,how,...)
- if trace_swiglib then
- report_swiglib("checking %s: %a",how,asked_library)
+ if trace then
+ report("checking %s: %a",how,asked_library)
end
return locate(asked_library,...)
end
@@ -19499,45 +19685,45 @@ local function requireswiglib(required,version)
local found=nil
if version then
local asked_library=joinfile(required_path,version,required_name)
- if trace_swiglib then
- report_swiglib("checking %s: %a","with version",asked_library)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
found=locate(asked_library,...)
end
if not found or found=="" then
local asked_library=joinfile(required_path,required_name)
- if trace_swiglib then
- report_swiglib("checking %s: %a","with version",asked_library)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
found=locate(asked_library,...)
end
return found and found~="" and found or false
end
local function attempt(checkpattern)
- if trace_swiglib then
- report_swiglib("checking tds lib paths strictly")
+ if trace then
+ report("checking tds lib paths strictly")
end
local found=findfile and check(findfile,"lib")
if found and (not checkpattern or find(found,checkpattern)) then
return found
end
- if trace_swiglib then
- report_swiglib("checking tds lib paths with wildcard")
+ if trace then
+ report("checking tds lib paths with wildcard")
end
local asked_library=joinfile(required_path,".*",required_name)
- if trace_swiglib then
- report_swiglib("checking %s: %a","latest version",asked_library)
+ if trace then
+ report("checking %s: %a","latest version",asked_library)
end
local list=findfiles(asked_library,"lib",true)
if list and #list>0 then
- table.sort(list)
+ sort(list)
local found=list[#list]
if found and (not checkpattern or find(found,checkpattern)) then
return found
end
end
- if trace_swiglib then
- report_swiglib("checking lib paths")
+ if trace then
+ report("checking lib paths")
end
package.extralibpath(environment.ownpath)
local paths=package.libpaths()
@@ -19549,89 +19735,132 @@ local function requireswiglib(required,version)
end
return false
end
- local found_library=nil
if engine then
- if trace_swiglib then
- report_swiglib("attemp 1, engine %a",engine)
+ if trace then
+ report("attemp 1, engine %a",engine)
end
found_library=attempt("/"..engine.."/")
if not found_library then
- if trace_swiglib then
- report_swiglib("attemp 2, no engine",asked_library)
+ if trace then
+ report("attemp 2, no engine",asked_library)
end
found_library=attempt()
end
else
found_library=attempt()
end
- if not found_library then
- if trace_swiglib then
- report_swiglib("not found: %a",required)
- end
+ end
+ if not found_library then
+ if trace then
+ report("not found: %a",required)
+ end
+ library=false
+ else
+ if trace then
+ report("found: %a",found_library)
+ end
+ local message,result=action(found_library,required_base)
+ if result then
+ library=result
+ else
library=false
+ report("load error: message %a, library %a",tostring(message),found_library or "no library")
+ end
+ end
+ if not library then
+ report("unknown: %a",required)
+ elseif trace then
+ report("stored: %a",required)
+ end
+ return library
+end
+do
+ local report_swiglib=logs.reporter("swiglib")
+ local trace_swiglib=false
+ local savedrequire=require
+ local loadedlibs={}
+ trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
+ function requireswiglib(required,version)
+ local library=loadedlibs[library]
+ if library==nil then
+ local trace_swiglib=trace_swiglib or package.helpers.trace
+ library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
+ dir.push(pathpart(name))
+ local opener="luaopen_"..base
+ local library,message=package.loadlib(name,opener)
+ local libtype=type(library)
+ if libtype=="function" then
+ library=library()
+ message=true
+ else
+ report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
+ library=false
+ end
+ dir.pop()
+ return message,library
+ end)
+ loadedlibs[required]=library or false
+ end
+ return library
+ end
+ function require(name,version)
+ if find(name,"^swiglib%.") then
+ return requireswiglib(name,version)
else
- local path=pathpart(found_library)
- local base=nameonly(found_library)
- dir.push(path)
+ return savedrequire(name)
+ end
+ end
+ local swiglibs={}
+ local initializer="core"
+ function swiglib(name,version)
+ local library=swiglibs[name]
+ if not library then
+ statistics.starttiming(swiglibs)
if trace_swiglib then
- report_swiglib("found: %a",found_library)
- end
- local message=nil
- local opener="luaopen_"..required_base
- library,message=package.loadlib(found_library,opener)
- local libtype=type(library)
- if libtype=="function" then
- library=library()
+ report_swiglib("loading %a",name)
+ end
+ if not find(name,"%."..initializer.."$") then
+ fullname="swiglib."..name.."."..initializer
else
- report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
- library=false
+ fullname="swiglib."..name
end
- dir.pop()
+ library=requireswiglib(fullname,version)
+ swiglibs[name]=library
+ statistics.stoptiming(swiglibs)
end
- if not library then
- report_swiglib("unknown: %a",required)
- elseif trace_swiglib then
- report_swiglib("stored: %a",required)
- end
- loaded[required]=library
- else
- report_swiglib("reused: %a",required)
+ return library
end
- return library
+ statistics.register("used swiglibs",function()
+ if next(swiglibs) then
+ return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
+ end
+ end)
end
-local savedrequire=require
-function require(name,version)
- if find(name,"^swiglib%.") then
- return requireswiglib(name,version)
- else
- return savedrequire(name)
+if FFISUPPORTED and ffi and ffi.load then
+ local report_ffilib=logs.reporter("ffilib")
+ local trace_ffilib=false
+ local savedffiload=ffi.load
+ trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
+ function ffilib(required,version)
+ return locate(required,version,trace_ffilib,report_ffilib,function(name)
+ local message,library=pcall(savedffiload,removesuffix(name))
+ if type(library)=="userdata" then
+ return message,library
+ else
+ return message,false
+ end
+ end)
end
-end
-local swiglibs={}
-local initializer="core"
-function swiglib(name,version)
- local library=swiglibs[name]
- if not library then
- statistics.starttiming(swiglibs)
- if trace_swiglib then
- report_swiglib("loading %a",name)
- end
- if not find(name,"%."..initializer.."$") then
- fullname="swiglib."..name.."."..initializer
+ function ffi.load(name)
+ local library=ffilib(name)
+ if type(library)=="userdata" then
+ return library
else
- fullname="swiglib."..name
+ report_ffilib("trying to load %a using normal loader",name)
+ return savedffiload(name)
end
- library=requireswiglib(fullname,version)
- swiglibs[name]=library
- statistics.stoptiming(swiglibs)
end
- return library
end
-statistics.register("used swiglibs",function()
- if next(swiglibs) then
- return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
- end
-end)
end -- of closure
@@ -19975,8 +20204,8 @@ end -- of closure
-- used libraries : l-lua.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 847975
--- stripped bytes : 308174
+-- original bytes : 855737
+-- stripped bytes : 310443
-- end library merge
diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun
index bdb81b477..0c3355fcc 100644
--- a/scripts/context/stubs/unix/mtxrun
+++ b/scripts/context/stubs/unix/mtxrun
@@ -5632,7 +5632,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-str"] = package.loaded["util-str"] or true
--- original size: 36650, stripped down to: 19963
+-- original size: 37582, stripped down to: 20676
if not modules then modules={} end modules ['util-str']={
version=1.001,
@@ -5871,6 +5871,27 @@ function number.sparseexponent(f,n)
end
return tostring(n)
end
+local hf={}
+local hs={}
+setmetatable(hf,{ __index=function(t,k)
+ local v="%."..k.."f"
+ t[k]=v
+ return v
+end } )
+setmetatable(hs,{ __index=function(t,k)
+ local v="%"..k.."s"
+ t[k]=v
+ return v
+end } )
+function number.formattedfloat(n,b,a)
+ local s=format(hf[a],n)
+ local l=(b or 0)+(a or 0)+1
+ if #s<l then
+ return format(hs[l],s)
+ else
+ return s
+ end
+end
local template=[[
%s
%s
@@ -5898,6 +5919,7 @@ local autodouble=string.autodouble
local sequenced=table.sequenced
local formattednumber=number.formatted
local sparseexponent=number.sparseexponent
+local formattedfloat=number.formattedfloat
]]
else
environment={
@@ -5921,6 +5943,7 @@ else
sequenced=table.sequenced,
formattednumber=number.formatted,
sparseexponent=number.sparseexponent,
+ formattedfloat=number.formattedfloat
}
end
local arguments={ "a1" }
@@ -5931,6 +5954,7 @@ setmetatable(arguments,{ __index=function(t,k)
end
})
local prefix_any=C((S("+- .")+R("09"))^0)
+local prefix_sub=(C((S("+-")+R("09"))^0)+Cc(0))*P(".")*(C((S("+-")+R("09"))^0)+Cc(0))
local prefix_tab=P("{")*C((1-P("}"))^0)*P("}")+C((1-R("az","AZ","09","%%"))^0)
local format_s=function(f)
n=n+1
@@ -5981,6 +6005,10 @@ local format_F=function(f)
return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n)
end
end
+local format_k=function(b,a)
+ n=n+1
+ return format("formattedfloat(a%s,%i,%i)",n,b or 0,a or 0)
+end
local format_g=function(f)
n=n+1
return format("format('%%%sg',a%s)",f,n)
@@ -6189,7 +6217,8 @@ local builder=Cs { "start",
+V("s")+V("q")+V("i")+V("d")+V("f")+V("F")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o")
+V("c")+V("C")+V("S")
+V("Q")
-+V("N")
++V("N")
++V("k")
+V("r")+V("h")+V("H")+V("u")+V("U")+V("p")+V("b")+V("t")+V("T")+V("l")+V("L")+V("I")+V("w")
+V("W")
+V("a")
@@ -6216,6 +6245,7 @@ local builder=Cs { "start",
["S"]=(prefix_any*P("S"))/format_S,
["Q"]=(prefix_any*P("Q"))/format_S,
["N"]=(prefix_any*P("N"))/format_N,
+ ["k"]=(prefix_sub*P("k"))/format_k,
["c"]=(prefix_any*P("c"))/format_c,
["C"]=(prefix_any*P("C"))/format_C,
["r"]=(prefix_any*P("r"))/format_r,
@@ -7012,7 +7042,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-fil"] = package.loaded["util-fil"] or true
--- original size: 6316, stripped down to: 4866
+-- original size: 6362, stripped down to: 4907
if not modules then modules={} end modules ['util-fil']={
version=1.001,
@@ -7098,6 +7128,7 @@ end
files.readcardinal1=files.readbyte
files.readcardinal=files.readcardinal1
files.readinteger=files.readinteger1
+files.readsignedbyte=files.readinteger1
function files.readcardinal2(f)
local a,b=byte(f:read(2),1,2)
return 0x100*a+b
@@ -9795,7 +9826,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-deb"] = package.loaded["util-deb"] or true
--- original size: 4030, stripped down to: 2718
+-- original size: 8473, stripped down to: 6211
if not modules then modules={} end modules ['util-deb']={
version=1.001,
@@ -9805,75 +9836,219 @@ if not modules then modules={} end modules ['util-deb']={
license="see context related readme files"
}
local debug=require "debug"
-local getinfo=debug.getinfo
+local getinfo,sethook=debug.getinfo,debug.sethook
local type,next,tostring=type,next,tostring
-local format,find=string.format,string.find
-local is_boolean=string.is_boolean
+local format,find,sub,gsub=string.format,string.find,string.sub,string.gsub
+local insert,remove,sort=table.insert,table.remove,table.sort
utilities=utilities or {}
local debugger=utilities.debugger or {}
utilities.debugger=debugger
-local counters={}
-local names={}
local report=logs.reporter("debugger")
-local function hook()
- local f=getinfo(2)
- if f then
- local n="unknown"
- if f.what=="C" then
- n=f.name or '<anonymous>'
- if not names[n] then
- names[n]=format("%42s",n)
+local ticks=os.gettimeofday or os.clock
+local seconds=function(n) return n or 0 end
+local overhead=0
+local dummycalls=10*1000
+local nesting=0
+local names={}
+local function initialize()
+ if FFISUPPORTED and ffi then
+ if os.type=="windows" then
+ local okay,kernel=pcall(ffi.load,"kernel32")
+ if kernel then
+ local tonumber=ffi.number or tonumber
+ffi.cdef[[
+int QueryPerformanceFrequency(int64_t *lpFrequency);
+int QueryPerformanceCounter(int64_t *lpPerformanceCount);
+]]
+ local target=ffi.new("__int64[1]")
+ ticks=function()
+ if kernel.QueryPerformanceCounter(target)==1 then
+ return tonumber(target[0])
+ else
+ return 0
+ end
+ end
+ local target=ffi.new("__int64[1]")
+ seconds=function(ticks)
+ if kernel.QueryPerformanceFrequency(target)==1 then
+ return ticks/tonumber(target[0])
+ else
+ return 0
+ end
+ end
end
- else
- n=f.name or f.namewhat or f.what
- if not n or n=="" then
- n="?"
+ elseif os.type=="unix" then
+ local C=ffi.C
+ local tonumber=ffi.number or tonumber
+ffi.cdef [[
+struct timespec { long sec; long nsec; };
+int clock_gettime(int timerid, struct timespec *t);
+ ]]
+ local target=ffi.new("timespec[?]",1)
+ function ticks()
+ C.clock_gettime(2,target)
+ return tonumber(target[0].sec*1000000000+target[0].nsec)
+ end
+ seconds=function(ticks)
+ return ticks/1000000000
+ end
+ end
+ end
+ initialize=false
+end
+table.setmetatableindex(names,function(t,name)
+ local v=table.setmetatableindex(function(t,source)
+ local v=table.setmetatableindex(function(t,line)
+ local v={ total=0,count=0 }
+ t[line]=v
+ return v
+ end)
+ t[source]=v
+ return v
+ end)
+ t[name]=v
+ return v
+end)
+local function hook(where)
+ local f=getinfo(2,"nSl")
+ if f then
+ local source=f.short_src
+ if not source then
+ return
+ end
+ local line=f.linedefined or 0
+ local name=f.name
+ if not name then
+ local what=f.what
+ if what=="C" then
+ name="<anonymous>"
+ else
+ name=f.namewhat or what or "<unknown>"
end
- if not names[n] then
- names[n]=format("%42s : % 5i : %s",n,f.linedefined or 0,f.short_src or "unknown source")
+ end
+ local data=names[name][source][line]
+ if where=="call" then
+ data.count=data.count+1
+ insert(data,ticks())
+ elseif where=="return" then
+ local t=remove(data)
+ if t then
+ data.total=data.total+ticks()-t
end
end
- counters[n]=(counters[n] or 0)+1
end
end
-function debugger.showstats(printer,threshold)
- printer=printer or report
- threshold=threshold or 0
- local total,grandtotal,functions=0,0,0
+function debugger.showstats(printer)
+ local printer=printer or report
+ local calls=0
+ local functions=0
local dataset={}
- for name,count in next,counters do
- dataset[#dataset+1]={ name,count }
+ local length=0
+ local wholetime=0
+ for name,sources in next,names do
+ for source,lines in next,sources do
+ for line,data in next,lines do
+ if #name>length then
+ length=#name
+ end
+ local total=data.total
+ local count=data.count
+ local real=total
+ if real>0 then
+ real=total-(count*overhead/dummycalls)
+ if real<0 then
+ real=0
+ end
+ wholetime=wholetime+real
+ end
+ if line<0 then
+ line=0
+ end
+ dataset[#dataset+1]={ real,total,count,name,source,line }
+ end
+ end
+ end
+ sort(dataset,function(a,b)
+ if a[1]==b[1] then
+ if a[2]==b[2] then
+ if a[3]==b[3] then
+ if a[4]==b[4] then
+ if a[5]==b[5] then
+ return a[6]<b[6]
+ else
+ return a[5]<b[5]
+ end
+ else
+ return a[4]<b[4]
+ end
+ else
+ return b[3]<a[3]
+ end
+ else
+ return b[2]<a[2]
+ end
+ else
+ return b[1]<a[1]
+ end
+ end)
+ if length>50 then
+ length=50
end
- table.sort(dataset,function(a,b) return a[2]==b[2] and b[1]>a[1] or a[2]>b[2] end)
+ local fmt=string.formatters["%4.9k %4.9k %3.3k %8i %-"..length.."s %4i %s"]
for i=1,#dataset do
- local d=dataset[i]
- local name=d[1]
- local count=d[2]
- if count>threshold and not find(name,"for generator") then
- printer(format("%8i %s\n",count,names[name]))
- total=total+count
- end
- grandtotal=grandtotal+count
+ local data=dataset[i]
+ local real=data[1]
+ local total=data[2]
+ local count=data[3]
+ local name=data[4]
+ local source=data[5]
+ local line=data[6]
+ local percent=real/wholetime
+ calls=calls+count
functions=functions+1
+ name=gsub(name,"%s+"," ")
+ if #name>length then
+ name=sub(name,1,length)
+ end
+ printer(fmt(seconds(total),seconds(real),percent,count,name,line,source))
end
- printer("\n")
- printer(format("functions : % 10i\n",functions))
- printer(format("total : % 10i\n",total))
- printer(format("grand total: % 10i\n",grandtotal))
- printer(format("threshold : % 10i\n",threshold))
+ printer("")
+ printer(format("functions : %i",functions))
+ printer(format("calls : %i",calls))
+ printer(format("overhead : %f",seconds(overhead/1000)))
end
-function debugger.savestats(filename,threshold)
+function debugger.savestats(filename)
local f=io.open(filename,'w')
if f then
- debugger.showstats(function(str) f:write(str) end,threshold)
+ debugger.showstats(function(str) f:write(str,"\n") end)
f:close()
end
end
function debugger.enable()
- debug.sethook(hook,"c")
+ if nesting==0 then
+ running=true
+ if initialize then
+ initialize()
+ end
+ sethook(hook,"cr")
+ local function dummy() end
+ local t=ticks()
+ for i=1,dummycalls do
+ dummy()
+ end
+ overhead=ticks()-t
+ end
+ if nesting>0 then
+ nesting=nesting+1
+ end
end
function debugger.disable()
- debug.sethook()
+ if nesting>0 then
+ nesting=nesting-1
+ end
+ if nesting==0 then
+ sethook()
+ end
end
local function showtraceback(rep)
local level=2
@@ -10716,7 +10891,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-env"] = package.loaded["util-env"] or true
--- original size: 9028, stripped down to: 5176
+-- original size: 9552, stripped down to: 5176
if not modules then modules={} end modules ['util-env']={
version=1.001,
@@ -15055,7 +15230,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-ini"] = package.loaded["data-ini"] or true
--- original size: 11444, stripped down to: 7830
+-- original size: 11459, stripped down to: 7680
if not modules then modules={} end modules ['data-ini']={
version=1.001,
@@ -15200,11 +15375,6 @@ if not texroot or texroot=="" then
ossetenv('TEXROOT',texroot)
end
environment.texroot=file.collapsepath(texroot)
-if type(profiler)=="table" and not jit then
- directives.register("system.profile",function()
- profiler.start("luatex-profile.log")
- end)
-end
local prefixes=utilities.storage.allocate()
resolvers.prefixes=prefixes
local resolved={}
@@ -19454,7 +19624,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-lib"] = package.loaded["util-lib"] or true
--- original size: 11846, stripped down to: 6059
+-- original size: 13648, stripped down to: 7455
if not modules then modules={} end modules ['util-lib']={
version=1.001,
@@ -19463,35 +19633,51 @@ if not modules then modules={} end modules ['util-lib']={
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files",
}
-local gsub,find=string.gsub,string.find
-local pathpart,nameonly,joinfile=file.pathpart,file.nameonly,file.join
-local findfile,findfiles=resolvers and resolvers.findfile,resolvers and resolvers.findfiles
-local loaded=package.loaded
-local report_swiglib=logs.reporter("swiglib")
-local trace_swiglib=false trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
+local type=type
+local next=next
+local pcall=pcall
+local gsub=string.gsub
+local find=string.find
+local sort=table.sort
+local pathpart=file.pathpart
+local nameonly=file.nameonly
+local joinfile=file.join
+local removesuffix=file.removesuffix
+local findfile=resolvers.findfile
+local findfiles=resolvers.findfiles
+local expandpaths=resolvers.expandedpathlistfromvariable
+local qualifiedpath=file.is_qualified_path
+local isfile=lfs.isfile
local done=false
-local function requireswiglib(required,version)
- local trace_swiglib=trace_swiglib or package.helpers.trace
- local library=loaded[required]
- if library==nil then
- if trace_swiglib then
- report_swiglib("requiring library %a with version %a",required,version or "any")
+local function locate(required,version,trace,report,action)
+ if type(required)~="string" then
+ report("provide a proper library name")
+ return
+ end
+ if trace then
+ report("requiring library %a with version %a",required,version or "any")
+ end
+ local found_library=nil
+ if qualifiedpath(required) then
+ if isfile(required) then
+ found_library=required
end
+ else
local required_full=gsub(required,"%.","/")
local required_path=pathpart(required_full)
local required_base=nameonly(required_full)
local required_name=required_base.."."..os.libsuffix
local version=type(version)=="string" and version~="" and version or false
local engine=environment.ownmain or false
- if trace_swiglib and not done then
- local list=resolvers.expandedpathlistfromvariable("lib")
+ if trace and not done then
+ local list=expandpaths("lib")
for i=1,#list do
- report_swiglib("tds path %i: %s",i,list[i])
+ report("tds path %i: %s",i,list[i])
end
end
local function found(locate,asked_library,how,...)
- if trace_swiglib then
- report_swiglib("checking %s: %a",how,asked_library)
+ if trace then
+ report("checking %s: %a",how,asked_library)
end
return locate(asked_library,...)
end
@@ -19499,45 +19685,45 @@ local function requireswiglib(required,version)
local found=nil
if version then
local asked_library=joinfile(required_path,version,required_name)
- if trace_swiglib then
- report_swiglib("checking %s: %a","with version",asked_library)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
found=locate(asked_library,...)
end
if not found or found=="" then
local asked_library=joinfile(required_path,required_name)
- if trace_swiglib then
- report_swiglib("checking %s: %a","with version",asked_library)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
found=locate(asked_library,...)
end
return found and found~="" and found or false
end
local function attempt(checkpattern)
- if trace_swiglib then
- report_swiglib("checking tds lib paths strictly")
+ if trace then
+ report("checking tds lib paths strictly")
end
local found=findfile and check(findfile,"lib")
if found and (not checkpattern or find(found,checkpattern)) then
return found
end
- if trace_swiglib then
- report_swiglib("checking tds lib paths with wildcard")
+ if trace then
+ report("checking tds lib paths with wildcard")
end
local asked_library=joinfile(required_path,".*",required_name)
- if trace_swiglib then
- report_swiglib("checking %s: %a","latest version",asked_library)
+ if trace then
+ report("checking %s: %a","latest version",asked_library)
end
local list=findfiles(asked_library,"lib",true)
if list and #list>0 then
- table.sort(list)
+ sort(list)
local found=list[#list]
if found and (not checkpattern or find(found,checkpattern)) then
return found
end
end
- if trace_swiglib then
- report_swiglib("checking lib paths")
+ if trace then
+ report("checking lib paths")
end
package.extralibpath(environment.ownpath)
local paths=package.libpaths()
@@ -19549,89 +19735,132 @@ local function requireswiglib(required,version)
end
return false
end
- local found_library=nil
if engine then
- if trace_swiglib then
- report_swiglib("attemp 1, engine %a",engine)
+ if trace then
+ report("attemp 1, engine %a",engine)
end
found_library=attempt("/"..engine.."/")
if not found_library then
- if trace_swiglib then
- report_swiglib("attemp 2, no engine",asked_library)
+ if trace then
+ report("attemp 2, no engine",asked_library)
end
found_library=attempt()
end
else
found_library=attempt()
end
- if not found_library then
- if trace_swiglib then
- report_swiglib("not found: %a",required)
- end
+ end
+ if not found_library then
+ if trace then
+ report("not found: %a",required)
+ end
+ library=false
+ else
+ if trace then
+ report("found: %a",found_library)
+ end
+ local message,result=action(found_library,required_base)
+ if result then
+ library=result
+ else
library=false
+ report("load error: message %a, library %a",tostring(message),found_library or "no library")
+ end
+ end
+ if not library then
+ report("unknown: %a",required)
+ elseif trace then
+ report("stored: %a",required)
+ end
+ return library
+end
+do
+ local report_swiglib=logs.reporter("swiglib")
+ local trace_swiglib=false
+ local savedrequire=require
+ local loadedlibs={}
+ trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
+ function requireswiglib(required,version)
+ local library=loadedlibs[library]
+ if library==nil then
+ local trace_swiglib=trace_swiglib or package.helpers.trace
+ library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
+ dir.push(pathpart(name))
+ local opener="luaopen_"..base
+ local library,message=package.loadlib(name,opener)
+ local libtype=type(library)
+ if libtype=="function" then
+ library=library()
+ message=true
+ else
+ report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
+ library=false
+ end
+ dir.pop()
+ return message,library
+ end)
+ loadedlibs[required]=library or false
+ end
+ return library
+ end
+ function require(name,version)
+ if find(name,"^swiglib%.") then
+ return requireswiglib(name,version)
else
- local path=pathpart(found_library)
- local base=nameonly(found_library)
- dir.push(path)
+ return savedrequire(name)
+ end
+ end
+ local swiglibs={}
+ local initializer="core"
+ function swiglib(name,version)
+ local library=swiglibs[name]
+ if not library then
+ statistics.starttiming(swiglibs)
if trace_swiglib then
- report_swiglib("found: %a",found_library)
- end
- local message=nil
- local opener="luaopen_"..required_base
- library,message=package.loadlib(found_library,opener)
- local libtype=type(library)
- if libtype=="function" then
- library=library()
+ report_swiglib("loading %a",name)
+ end
+ if not find(name,"%."..initializer.."$") then
+ fullname="swiglib."..name.."."..initializer
else
- report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
- library=false
+ fullname="swiglib."..name
end
- dir.pop()
+ library=requireswiglib(fullname,version)
+ swiglibs[name]=library
+ statistics.stoptiming(swiglibs)
end
- if not library then
- report_swiglib("unknown: %a",required)
- elseif trace_swiglib then
- report_swiglib("stored: %a",required)
- end
- loaded[required]=library
- else
- report_swiglib("reused: %a",required)
+ return library
end
- return library
+ statistics.register("used swiglibs",function()
+ if next(swiglibs) then
+ return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
+ end
+ end)
end
-local savedrequire=require
-function require(name,version)
- if find(name,"^swiglib%.") then
- return requireswiglib(name,version)
- else
- return savedrequire(name)
+if FFISUPPORTED and ffi and ffi.load then
+ local report_ffilib=logs.reporter("ffilib")
+ local trace_ffilib=false
+ local savedffiload=ffi.load
+ trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
+ function ffilib(required,version)
+ return locate(required,version,trace_ffilib,report_ffilib,function(name)
+ local message,library=pcall(savedffiload,removesuffix(name))
+ if type(library)=="userdata" then
+ return message,library
+ else
+ return message,false
+ end
+ end)
end
-end
-local swiglibs={}
-local initializer="core"
-function swiglib(name,version)
- local library=swiglibs[name]
- if not library then
- statistics.starttiming(swiglibs)
- if trace_swiglib then
- report_swiglib("loading %a",name)
- end
- if not find(name,"%."..initializer.."$") then
- fullname="swiglib."..name.."."..initializer
+ function ffi.load(name)
+ local library=ffilib(name)
+ if type(library)=="userdata" then
+ return library
else
- fullname="swiglib."..name
+ report_ffilib("trying to load %a using normal loader",name)
+ return savedffiload(name)
end
- library=requireswiglib(fullname,version)
- swiglibs[name]=library
- statistics.stoptiming(swiglibs)
end
- return library
end
-statistics.register("used swiglibs",function()
- if next(swiglibs) then
- return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
- end
-end)
end -- of closure
@@ -19975,8 +20204,8 @@ end -- of closure
-- used libraries : l-lua.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 847975
--- stripped bytes : 308174
+-- original bytes : 855737
+-- stripped bytes : 310443
-- end library merge
diff --git a/scripts/context/stubs/win64/mtxrun.lua b/scripts/context/stubs/win64/mtxrun.lua
index bdb81b477..0c3355fcc 100644
--- a/scripts/context/stubs/win64/mtxrun.lua
+++ b/scripts/context/stubs/win64/mtxrun.lua
@@ -5632,7 +5632,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-str"] = package.loaded["util-str"] or true
--- original size: 36650, stripped down to: 19963
+-- original size: 37582, stripped down to: 20676
if not modules then modules={} end modules ['util-str']={
version=1.001,
@@ -5871,6 +5871,27 @@ function number.sparseexponent(f,n)
end
return tostring(n)
end
+local hf={}
+local hs={}
+setmetatable(hf,{ __index=function(t,k)
+ local v="%."..k.."f"
+ t[k]=v
+ return v
+end } )
+setmetatable(hs,{ __index=function(t,k)
+ local v="%"..k.."s"
+ t[k]=v
+ return v
+end } )
+function number.formattedfloat(n,b,a)
+ local s=format(hf[a],n)
+ local l=(b or 0)+(a or 0)+1
+ if #s<l then
+ return format(hs[l],s)
+ else
+ return s
+ end
+end
local template=[[
%s
%s
@@ -5898,6 +5919,7 @@ local autodouble=string.autodouble
local sequenced=table.sequenced
local formattednumber=number.formatted
local sparseexponent=number.sparseexponent
+local formattedfloat=number.formattedfloat
]]
else
environment={
@@ -5921,6 +5943,7 @@ else
sequenced=table.sequenced,
formattednumber=number.formatted,
sparseexponent=number.sparseexponent,
+ formattedfloat=number.formattedfloat
}
end
local arguments={ "a1" }
@@ -5931,6 +5954,7 @@ setmetatable(arguments,{ __index=function(t,k)
end
})
local prefix_any=C((S("+- .")+R("09"))^0)
+local prefix_sub=(C((S("+-")+R("09"))^0)+Cc(0))*P(".")*(C((S("+-")+R("09"))^0)+Cc(0))
local prefix_tab=P("{")*C((1-P("}"))^0)*P("}")+C((1-R("az","AZ","09","%%"))^0)
local format_s=function(f)
n=n+1
@@ -5981,6 +6005,10 @@ local format_F=function(f)
return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n)
end
end
+local format_k=function(b,a)
+ n=n+1
+ return format("formattedfloat(a%s,%i,%i)",n,b or 0,a or 0)
+end
local format_g=function(f)
n=n+1
return format("format('%%%sg',a%s)",f,n)
@@ -6189,7 +6217,8 @@ local builder=Cs { "start",
+V("s")+V("q")+V("i")+V("d")+V("f")+V("F")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o")
+V("c")+V("C")+V("S")
+V("Q")
-+V("N")
++V("N")
++V("k")
+V("r")+V("h")+V("H")+V("u")+V("U")+V("p")+V("b")+V("t")+V("T")+V("l")+V("L")+V("I")+V("w")
+V("W")
+V("a")
@@ -6216,6 +6245,7 @@ local builder=Cs { "start",
["S"]=(prefix_any*P("S"))/format_S,
["Q"]=(prefix_any*P("Q"))/format_S,
["N"]=(prefix_any*P("N"))/format_N,
+ ["k"]=(prefix_sub*P("k"))/format_k,
["c"]=(prefix_any*P("c"))/format_c,
["C"]=(prefix_any*P("C"))/format_C,
["r"]=(prefix_any*P("r"))/format_r,
@@ -7012,7 +7042,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-fil"] = package.loaded["util-fil"] or true
--- original size: 6316, stripped down to: 4866
+-- original size: 6362, stripped down to: 4907
if not modules then modules={} end modules ['util-fil']={
version=1.001,
@@ -7098,6 +7128,7 @@ end
files.readcardinal1=files.readbyte
files.readcardinal=files.readcardinal1
files.readinteger=files.readinteger1
+files.readsignedbyte=files.readinteger1
function files.readcardinal2(f)
local a,b=byte(f:read(2),1,2)
return 0x100*a+b
@@ -9795,7 +9826,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-deb"] = package.loaded["util-deb"] or true
--- original size: 4030, stripped down to: 2718
+-- original size: 8473, stripped down to: 6211
if not modules then modules={} end modules ['util-deb']={
version=1.001,
@@ -9805,75 +9836,219 @@ if not modules then modules={} end modules ['util-deb']={
license="see context related readme files"
}
local debug=require "debug"
-local getinfo=debug.getinfo
+local getinfo,sethook=debug.getinfo,debug.sethook
local type,next,tostring=type,next,tostring
-local format,find=string.format,string.find
-local is_boolean=string.is_boolean
+local format,find,sub,gsub=string.format,string.find,string.sub,string.gsub
+local insert,remove,sort=table.insert,table.remove,table.sort
utilities=utilities or {}
local debugger=utilities.debugger or {}
utilities.debugger=debugger
-local counters={}
-local names={}
local report=logs.reporter("debugger")
-local function hook()
- local f=getinfo(2)
- if f then
- local n="unknown"
- if f.what=="C" then
- n=f.name or '<anonymous>'
- if not names[n] then
- names[n]=format("%42s",n)
+local ticks=os.gettimeofday or os.clock
+local seconds=function(n) return n or 0 end
+local overhead=0
+local dummycalls=10*1000
+local nesting=0
+local names={}
+local function initialize()
+ if FFISUPPORTED and ffi then
+ if os.type=="windows" then
+ local okay,kernel=pcall(ffi.load,"kernel32")
+ if kernel then
+ local tonumber=ffi.number or tonumber
+ffi.cdef[[
+int QueryPerformanceFrequency(int64_t *lpFrequency);
+int QueryPerformanceCounter(int64_t *lpPerformanceCount);
+]]
+ local target=ffi.new("__int64[1]")
+ ticks=function()
+ if kernel.QueryPerformanceCounter(target)==1 then
+ return tonumber(target[0])
+ else
+ return 0
+ end
+ end
+ local target=ffi.new("__int64[1]")
+ seconds=function(ticks)
+ if kernel.QueryPerformanceFrequency(target)==1 then
+ return ticks/tonumber(target[0])
+ else
+ return 0
+ end
+ end
end
- else
- n=f.name or f.namewhat or f.what
- if not n or n=="" then
- n="?"
+ elseif os.type=="unix" then
+ local C=ffi.C
+ local tonumber=ffi.number or tonumber
+ffi.cdef [[
+struct timespec { long sec; long nsec; };
+int clock_gettime(int timerid, struct timespec *t);
+ ]]
+ local target=ffi.new("timespec[?]",1)
+ function ticks()
+ C.clock_gettime(2,target)
+ return tonumber(target[0].sec*1000000000+target[0].nsec)
+ end
+ seconds=function(ticks)
+ return ticks/1000000000
+ end
+ end
+ end
+ initialize=false
+end
+table.setmetatableindex(names,function(t,name)
+ local v=table.setmetatableindex(function(t,source)
+ local v=table.setmetatableindex(function(t,line)
+ local v={ total=0,count=0 }
+ t[line]=v
+ return v
+ end)
+ t[source]=v
+ return v
+ end)
+ t[name]=v
+ return v
+end)
+local function hook(where)
+ local f=getinfo(2,"nSl")
+ if f then
+ local source=f.short_src
+ if not source then
+ return
+ end
+ local line=f.linedefined or 0
+ local name=f.name
+ if not name then
+ local what=f.what
+ if what=="C" then
+ name="<anonymous>"
+ else
+ name=f.namewhat or what or "<unknown>"
end
- if not names[n] then
- names[n]=format("%42s : % 5i : %s",n,f.linedefined or 0,f.short_src or "unknown source")
+ end
+ local data=names[name][source][line]
+ if where=="call" then
+ data.count=data.count+1
+ insert(data,ticks())
+ elseif where=="return" then
+ local t=remove(data)
+ if t then
+ data.total=data.total+ticks()-t
end
end
- counters[n]=(counters[n] or 0)+1
end
end
-function debugger.showstats(printer,threshold)
- printer=printer or report
- threshold=threshold or 0
- local total,grandtotal,functions=0,0,0
+function debugger.showstats(printer)
+ local printer=printer or report
+ local calls=0
+ local functions=0
local dataset={}
- for name,count in next,counters do
- dataset[#dataset+1]={ name,count }
+ local length=0
+ local wholetime=0
+ for name,sources in next,names do
+ for source,lines in next,sources do
+ for line,data in next,lines do
+ if #name>length then
+ length=#name
+ end
+ local total=data.total
+ local count=data.count
+ local real=total
+ if real>0 then
+ real=total-(count*overhead/dummycalls)
+ if real<0 then
+ real=0
+ end
+ wholetime=wholetime+real
+ end
+ if line<0 then
+ line=0
+ end
+ dataset[#dataset+1]={ real,total,count,name,source,line }
+ end
+ end
+ end
+ sort(dataset,function(a,b)
+ if a[1]==b[1] then
+ if a[2]==b[2] then
+ if a[3]==b[3] then
+ if a[4]==b[4] then
+ if a[5]==b[5] then
+ return a[6]<b[6]
+ else
+ return a[5]<b[5]
+ end
+ else
+ return a[4]<b[4]
+ end
+ else
+ return b[3]<a[3]
+ end
+ else
+ return b[2]<a[2]
+ end
+ else
+ return b[1]<a[1]
+ end
+ end)
+ if length>50 then
+ length=50
end
- table.sort(dataset,function(a,b) return a[2]==b[2] and b[1]>a[1] or a[2]>b[2] end)
+ local fmt=string.formatters["%4.9k %4.9k %3.3k %8i %-"..length.."s %4i %s"]
for i=1,#dataset do
- local d=dataset[i]
- local name=d[1]
- local count=d[2]
- if count>threshold and not find(name,"for generator") then
- printer(format("%8i %s\n",count,names[name]))
- total=total+count
- end
- grandtotal=grandtotal+count
+ local data=dataset[i]
+ local real=data[1]
+ local total=data[2]
+ local count=data[3]
+ local name=data[4]
+ local source=data[5]
+ local line=data[6]
+ local percent=real/wholetime
+ calls=calls+count
functions=functions+1
+ name=gsub(name,"%s+"," ")
+ if #name>length then
+ name=sub(name,1,length)
+ end
+ printer(fmt(seconds(total),seconds(real),percent,count,name,line,source))
end
- printer("\n")
- printer(format("functions : % 10i\n",functions))
- printer(format("total : % 10i\n",total))
- printer(format("grand total: % 10i\n",grandtotal))
- printer(format("threshold : % 10i\n",threshold))
+ printer("")
+ printer(format("functions : %i",functions))
+ printer(format("calls : %i",calls))
+ printer(format("overhead : %f",seconds(overhead/1000)))
end
-function debugger.savestats(filename,threshold)
+function debugger.savestats(filename)
local f=io.open(filename,'w')
if f then
- debugger.showstats(function(str) f:write(str) end,threshold)
+ debugger.showstats(function(str) f:write(str,"\n") end)
f:close()
end
end
function debugger.enable()
- debug.sethook(hook,"c")
+ if nesting==0 then
+ running=true
+ if initialize then
+ initialize()
+ end
+ sethook(hook,"cr")
+ local function dummy() end
+ local t=ticks()
+ for i=1,dummycalls do
+ dummy()
+ end
+ overhead=ticks()-t
+ end
+ if nesting>0 then
+ nesting=nesting+1
+ end
end
function debugger.disable()
- debug.sethook()
+ if nesting>0 then
+ nesting=nesting-1
+ end
+ if nesting==0 then
+ sethook()
+ end
end
local function showtraceback(rep)
local level=2
@@ -10716,7 +10891,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-env"] = package.loaded["util-env"] or true
--- original size: 9028, stripped down to: 5176
+-- original size: 9552, stripped down to: 5176
if not modules then modules={} end modules ['util-env']={
version=1.001,
@@ -15055,7 +15230,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-ini"] = package.loaded["data-ini"] or true
--- original size: 11444, stripped down to: 7830
+-- original size: 11459, stripped down to: 7680
if not modules then modules={} end modules ['data-ini']={
version=1.001,
@@ -15200,11 +15375,6 @@ if not texroot or texroot=="" then
ossetenv('TEXROOT',texroot)
end
environment.texroot=file.collapsepath(texroot)
-if type(profiler)=="table" and not jit then
- directives.register("system.profile",function()
- profiler.start("luatex-profile.log")
- end)
-end
local prefixes=utilities.storage.allocate()
resolvers.prefixes=prefixes
local resolved={}
@@ -19454,7 +19624,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-lib"] = package.loaded["util-lib"] or true
--- original size: 11846, stripped down to: 6059
+-- original size: 13648, stripped down to: 7455
if not modules then modules={} end modules ['util-lib']={
version=1.001,
@@ -19463,35 +19633,51 @@ if not modules then modules={} end modules ['util-lib']={
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files",
}
-local gsub,find=string.gsub,string.find
-local pathpart,nameonly,joinfile=file.pathpart,file.nameonly,file.join
-local findfile,findfiles=resolvers and resolvers.findfile,resolvers and resolvers.findfiles
-local loaded=package.loaded
-local report_swiglib=logs.reporter("swiglib")
-local trace_swiglib=false trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
+local type=type
+local next=next
+local pcall=pcall
+local gsub=string.gsub
+local find=string.find
+local sort=table.sort
+local pathpart=file.pathpart
+local nameonly=file.nameonly
+local joinfile=file.join
+local removesuffix=file.removesuffix
+local findfile=resolvers.findfile
+local findfiles=resolvers.findfiles
+local expandpaths=resolvers.expandedpathlistfromvariable
+local qualifiedpath=file.is_qualified_path
+local isfile=lfs.isfile
local done=false
-local function requireswiglib(required,version)
- local trace_swiglib=trace_swiglib or package.helpers.trace
- local library=loaded[required]
- if library==nil then
- if trace_swiglib then
- report_swiglib("requiring library %a with version %a",required,version or "any")
+local function locate(required,version,trace,report,action)
+ if type(required)~="string" then
+ report("provide a proper library name")
+ return
+ end
+ if trace then
+ report("requiring library %a with version %a",required,version or "any")
+ end
+ local found_library=nil
+ if qualifiedpath(required) then
+ if isfile(required) then
+ found_library=required
end
+ else
local required_full=gsub(required,"%.","/")
local required_path=pathpart(required_full)
local required_base=nameonly(required_full)
local required_name=required_base.."."..os.libsuffix
local version=type(version)=="string" and version~="" and version or false
local engine=environment.ownmain or false
- if trace_swiglib and not done then
- local list=resolvers.expandedpathlistfromvariable("lib")
+ if trace and not done then
+ local list=expandpaths("lib")
for i=1,#list do
- report_swiglib("tds path %i: %s",i,list[i])
+ report("tds path %i: %s",i,list[i])
end
end
local function found(locate,asked_library,how,...)
- if trace_swiglib then
- report_swiglib("checking %s: %a",how,asked_library)
+ if trace then
+ report("checking %s: %a",how,asked_library)
end
return locate(asked_library,...)
end
@@ -19499,45 +19685,45 @@ local function requireswiglib(required,version)
local found=nil
if version then
local asked_library=joinfile(required_path,version,required_name)
- if trace_swiglib then
- report_swiglib("checking %s: %a","with version",asked_library)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
found=locate(asked_library,...)
end
if not found or found=="" then
local asked_library=joinfile(required_path,required_name)
- if trace_swiglib then
- report_swiglib("checking %s: %a","with version",asked_library)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
found=locate(asked_library,...)
end
return found and found~="" and found or false
end
local function attempt(checkpattern)
- if trace_swiglib then
- report_swiglib("checking tds lib paths strictly")
+ if trace then
+ report("checking tds lib paths strictly")
end
local found=findfile and check(findfile,"lib")
if found and (not checkpattern or find(found,checkpattern)) then
return found
end
- if trace_swiglib then
- report_swiglib("checking tds lib paths with wildcard")
+ if trace then
+ report("checking tds lib paths with wildcard")
end
local asked_library=joinfile(required_path,".*",required_name)
- if trace_swiglib then
- report_swiglib("checking %s: %a","latest version",asked_library)
+ if trace then
+ report("checking %s: %a","latest version",asked_library)
end
local list=findfiles(asked_library,"lib",true)
if list and #list>0 then
- table.sort(list)
+ sort(list)
local found=list[#list]
if found and (not checkpattern or find(found,checkpattern)) then
return found
end
end
- if trace_swiglib then
- report_swiglib("checking lib paths")
+ if trace then
+ report("checking lib paths")
end
package.extralibpath(environment.ownpath)
local paths=package.libpaths()
@@ -19549,89 +19735,132 @@ local function requireswiglib(required,version)
end
return false
end
- local found_library=nil
if engine then
- if trace_swiglib then
- report_swiglib("attemp 1, engine %a",engine)
+ if trace then
+ report("attemp 1, engine %a",engine)
end
found_library=attempt("/"..engine.."/")
if not found_library then
- if trace_swiglib then
- report_swiglib("attemp 2, no engine",asked_library)
+ if trace then
+ report("attemp 2, no engine",asked_library)
end
found_library=attempt()
end
else
found_library=attempt()
end
- if not found_library then
- if trace_swiglib then
- report_swiglib("not found: %a",required)
- end
+ end
+ if not found_library then
+ if trace then
+ report("not found: %a",required)
+ end
+ library=false
+ else
+ if trace then
+ report("found: %a",found_library)
+ end
+ local message,result=action(found_library,required_base)
+ if result then
+ library=result
+ else
library=false
+ report("load error: message %a, library %a",tostring(message),found_library or "no library")
+ end
+ end
+ if not library then
+ report("unknown: %a",required)
+ elseif trace then
+ report("stored: %a",required)
+ end
+ return library
+end
+do
+ local report_swiglib=logs.reporter("swiglib")
+ local trace_swiglib=false
+ local savedrequire=require
+ local loadedlibs={}
+ trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
+ function requireswiglib(required,version)
+ local library=loadedlibs[library]
+ if library==nil then
+ local trace_swiglib=trace_swiglib or package.helpers.trace
+ library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
+ dir.push(pathpart(name))
+ local opener="luaopen_"..base
+ local library,message=package.loadlib(name,opener)
+ local libtype=type(library)
+ if libtype=="function" then
+ library=library()
+ message=true
+ else
+ report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
+ library=false
+ end
+ dir.pop()
+ return message,library
+ end)
+ loadedlibs[required]=library or false
+ end
+ return library
+ end
+ function require(name,version)
+ if find(name,"^swiglib%.") then
+ return requireswiglib(name,version)
else
- local path=pathpart(found_library)
- local base=nameonly(found_library)
- dir.push(path)
+ return savedrequire(name)
+ end
+ end
+ local swiglibs={}
+ local initializer="core"
+ function swiglib(name,version)
+ local library=swiglibs[name]
+ if not library then
+ statistics.starttiming(swiglibs)
if trace_swiglib then
- report_swiglib("found: %a",found_library)
- end
- local message=nil
- local opener="luaopen_"..required_base
- library,message=package.loadlib(found_library,opener)
- local libtype=type(library)
- if libtype=="function" then
- library=library()
+ report_swiglib("loading %a",name)
+ end
+ if not find(name,"%."..initializer.."$") then
+ fullname="swiglib."..name.."."..initializer
else
- report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
- library=false
+ fullname="swiglib."..name
end
- dir.pop()
+ library=requireswiglib(fullname,version)
+ swiglibs[name]=library
+ statistics.stoptiming(swiglibs)
end
- if not library then
- report_swiglib("unknown: %a",required)
- elseif trace_swiglib then
- report_swiglib("stored: %a",required)
- end
- loaded[required]=library
- else
- report_swiglib("reused: %a",required)
+ return library
end
- return library
+ statistics.register("used swiglibs",function()
+ if next(swiglibs) then
+ return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
+ end
+ end)
end
-local savedrequire=require
-function require(name,version)
- if find(name,"^swiglib%.") then
- return requireswiglib(name,version)
- else
- return savedrequire(name)
+if FFISUPPORTED and ffi and ffi.load then
+ local report_ffilib=logs.reporter("ffilib")
+ local trace_ffilib=false
+ local savedffiload=ffi.load
+ trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
+ function ffilib(required,version)
+ return locate(required,version,trace_ffilib,report_ffilib,function(name)
+ local message,library=pcall(savedffiload,removesuffix(name))
+ if type(library)=="userdata" then
+ return message,library
+ else
+ return message,false
+ end
+ end)
end
-end
-local swiglibs={}
-local initializer="core"
-function swiglib(name,version)
- local library=swiglibs[name]
- if not library then
- statistics.starttiming(swiglibs)
- if trace_swiglib then
- report_swiglib("loading %a",name)
- end
- if not find(name,"%."..initializer.."$") then
- fullname="swiglib."..name.."."..initializer
+ function ffi.load(name)
+ local library=ffilib(name)
+ if type(library)=="userdata" then
+ return library
else
- fullname="swiglib."..name
+ report_ffilib("trying to load %a using normal loader",name)
+ return savedffiload(name)
end
- library=requireswiglib(fullname,version)
- swiglibs[name]=library
- statistics.stoptiming(swiglibs)
end
- return library
end
-statistics.register("used swiglibs",function()
- if next(swiglibs) then
- return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
- end
-end)
end -- of closure
@@ -19975,8 +20204,8 @@ end -- of closure
-- used libraries : l-lua.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 847975
--- stripped bytes : 308174
+-- original bytes : 855737
+-- stripped bytes : 310443
-- end library merge
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index 0e6e6851f..1c5dfe2d5 100644
--- a/tex/context/base/mkii/cont-new.mkii
+++ b/tex/context/base/mkii/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2017.02.20 17:55}
+\newcontextversion{2017.02.23 17:07}
%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/mkii/context.mkii b/tex/context/base/mkii/context.mkii
index 868227917..a89ce83ff 100644
--- a/tex/context/base/mkii/context.mkii
+++ b/tex/context/base/mkii/context.mkii
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2017.02.20 17:55}
+\edef\contextversion{2017.02.23 17:07}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/anch-pos.lua b/tex/context/base/mkiv/anch-pos.lua
index 6a9612d9e..2ba9e2420 100644
--- a/tex/context/base/mkiv/anch-pos.lua
+++ b/tex/context/base/mkiv/anch-pos.lua
@@ -90,8 +90,6 @@ local jobpositions = {
job.positions = jobpositions
-_plib_ = jobpositions -- might go
-
local default = { -- not r and paragraphs etc
__index = {
x = 0, -- x position baseline
diff --git a/tex/context/base/mkiv/char-fio.lua b/tex/context/base/mkiv/char-fio.lua
index ab2555935..fa69d9356 100644
--- a/tex/context/base/mkiv/char-fio.lua
+++ b/tex/context/base/mkiv/char-fio.lua
@@ -42,18 +42,19 @@ local reporting = "no"
-- per line by default
local enforced = {
- ["characters.filters.utf.reorder"] = true,
["characters.filters.utf.collapse"] = true,
["characters.filters.utf.decompose"] = true,
+ ["characters.filters.utf.reorder"] = false,
}
function utffilters.enable()
+ -- only used one time (normally)
for k, v in next, enforced do
if v then
if reporting == "yes" then
report("%a enabled",k)
end
- enableaction(textfileactions,v)
+ enableaction(textfileactions,k)
else
if reporting == "yes" then
report("%a not enabled",k)
diff --git a/tex/context/base/mkiv/char-utf.lua b/tex/context/base/mkiv/char-utf.lua
index ece9d7a76..f4a6d50e1 100644
--- a/tex/context/base/mkiv/char-utf.lua
+++ b/tex/context/base/mkiv/char-utf.lua
@@ -409,8 +409,8 @@ function utffilters.addgrapheme(result,first,second) -- can be U+ 0x string or u
graphemes[first][second] = result
end
local pair = first .. second
- if not composed[pair] then
- composed[pair] = result
+ if not collapsed[pair] then
+ collapsed[pair] = result
p_composed = nil
end
end
@@ -498,7 +498,8 @@ local function prepare()
for k, v in sortedhash(characters.data) do
local combining = v.combining -- v.ordering or v.combining
if combining then
- hash[utfchar(k)] = { utfchar(k), combining, 0 } -- slot 3 can be used in sort
+ local u = utfchar(k)
+ hash[u] = { u, combining, 0 } -- slot 3 can be used in sort
end
end
local e = utfchartabletopattern(exceptions)
@@ -522,7 +523,7 @@ end
-- local collapse = utffilters.collapse
-- local decompose = utffilters.decompose
--- local preprocess = utffilters.preprocess
+-- local reorder = utffilters.reorder
--
-- local c1, c2, c3 = "a", "̂", "̃"
-- local r2, r3 = "â", "ẫ"
@@ -540,7 +541,7 @@ end
-- for i=1,10000 do
-- collapse(data)
-- decompose(data)
--- -- preprocess(data)
+-- -- reorder(data)
-- end
-- print(os.clock()-t,decompose(collapse(data))==okay,decompose(collapse(str)))
-- end
diff --git a/tex/context/base/mkiv/char-utf.mkiv b/tex/context/base/mkiv/char-utf.mkiv
index fe9f402ef..3b77771a7 100644
--- a/tex/context/base/mkiv/char-utf.mkiv
+++ b/tex/context/base/mkiv/char-utf.mkiv
@@ -31,9 +31,9 @@
%D since the source files are rather simple, we postpone the
%D initialization till runtime.
-\appendtoks
- \clf_enableutf % not needed when we create a format so we do it now
-\to \everyjob
+% \appendtoks
+% \clf_enableutf % not needed when we create a format so we do it now
+% \to \everyjob
%D The next one influences input parsing.
%D
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 4c044c330..c67cf1c25 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2017.02.20 17:55}
+\newcontextversion{2017.02.23 17:07}
%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/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 31d79390a..dc66b5564 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -39,7 +39,7 @@
%D up and the dependencies are more consistent.
\edef\contextformat {\jobname}
-\edef\contextversion{2017.02.20 17:55}
+\edef\contextversion{2017.02.23 17:07}
\edef\contextkind {beta}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/data-ini.lua b/tex/context/base/mkiv/data-ini.lua
index 5ed2cce26..09357368c 100644
--- a/tex/context/base/mkiv/data-ini.lua
+++ b/tex/context/base/mkiv/data-ini.lua
@@ -217,11 +217,11 @@ end
environment.texroot = file.collapsepath(texroot)
-if type(profiler) == "table" and not jit then
- directives.register("system.profile",function()
- profiler.start("luatex-profile.log")
- end)
-end
+-- if type(profiler) == "table" and not jit then
+-- directives.register("system.profile",function()
+-- profiler.start("luatex-profile.log")
+-- end)
+-- end
-- a forward definition
diff --git a/tex/context/base/mkiv/font-dsp.lua b/tex/context/base/mkiv/font-dsp.lua
index 2d52c23a9..a5a1ae7c0 100644
--- a/tex/context/base/mkiv/font-dsp.lua
+++ b/tex/context/base/mkiv/font-dsp.lua
@@ -72,6 +72,7 @@ local streamreader = readers.streamreader
local setposition = streamreader.setposition
local getposition = streamreader.getposition
local skipshort = streamreader.skipshort
+local skipbytes = streamreader.skip
local readushort = streamreader.readcardinal2 -- 16-bit unsigned integer
local readulong = streamreader.readcardinal4 -- 24-bit unsigned integer
local readshort = streamreader.readinteger2 -- 16-bit signed integer
@@ -79,6 +80,9 @@ local readfword = readshort
local readstring = streamreader.readstring
local readtag = streamreader.readtag
local readbytes = streamreader.readbytes
+local readfixed = streamreader.readfixed4
+local read2dot14 = streamreader.read2dot14
+local readinteger = streamreader.readinteger1
local gsubhandlers = { }
local gposhandlers = { }
@@ -2434,3 +2438,213 @@ function readers.svg(f,fontdata,specification)
fontdata.hascolor = true
end
end
+
+-- This next few are work in progress. I have no fonts that have these tables so it's a
+-- gamble. I'll pick up this thread some day (if needed at all). See font-tst.tex for a
+-- possible test. Something for a rainy day and a stack of fresh cd's.
+
+function readers.fvar(f,fontdata,specification)
+ local datatable = fontdata.tables.fvar
+ if datatable then
+ local tableoffset = datatable.offset
+ setposition(f,tableoffset)
+ local majorversion = readushort(f) -- 1
+ local minorversion = readushort(f) -- 0
+ if majorversion ~= 1 and minorversion ~= 0 then
+ report("table version %a.%a of %a is not supported (yet), maybe font %s is bad",
+ majorversion,minorversion,"fvar",fontdata.filename)
+ return
+ end
+ local offsettoaxis = tableoffset + readushort(f)
+ local nofsizepairs = readushort(f) -- 2 count/size pairs
+ -- pair 1
+ local nofaxis = readushort(f)
+ local sizeofaxis = readushort(f)
+ -- pair 2
+ local nofinstances = readushort(f)
+ local sizeofinstances = readushort(f)
+ --
+ local extras = fontdata.extras
+ local axis = { }
+ local instances = { }
+ --
+ setposition(f,offsettoaxis)
+ --
+ local function readtuple(f)
+ local t = { }
+ for i=1,nofaxis do
+ t[i] = readfixed(f)
+ end
+ return t
+ end
+ --
+ for i=1,nofaxis do
+ axis[i] = {
+ tag = readtag(f), -- ital opsz slnt wdth wght
+ minimum = readfixed(f), -- we get weird values from a test font ... to be checked
+ default = readfixed(f), -- idem
+ maximum = readfixed(f), -- idem
+ flags = readushort(f),
+ nameid = extras[readushort(f)],
+ }
+ local n = sizeofaxis - 20
+ if n > 0 then
+ skipbytes(f,n)
+ elseif n < 0 then
+ -- error
+ end
+ end
+ --
+ for i=1,nofinstances do
+ local subfamid = readushort(f)
+ local flags = readushort(f)
+ local tuple = readtuple(f)
+ local psnameid = false
+ local nofbytes = 2 + 2 + #tuple * 2
+ if nofbytes < sizeofinstances then
+ psnameid = readushort(f)
+ nofbytes = nofbytes + 2
+ end
+ instances[i] = {
+ subfamily = extras[subfamid],
+ flags = flags,
+ tuple = tuple,
+ psname = extras[psnameid] or nil,
+ }
+ if nofbytes > 0 then
+ skipbytes(f,nofbytes)
+ end
+ end
+ --
+ fontdata.variable = {
+ axis = axis,
+ instances = instances,
+ }
+ end
+end
+
+-- function readers.gvar(f,fontdata,specification)
+-- end
+
+-- function readers.hvar(f,fontdata,specification)
+-- end
+
+-- function readers.vvar(f,fontdata,specification)
+-- end
+
+-- We don't need all these dimensions so we only mention those that make
+-- sense. Mapping to some function makes most sense.
+
+local tags = {
+ hasc = "", -- horizontal ascender OS/2.sTypoAscender
+ hdsc = "", -- horizontal descender OS/2.sTypoDescender
+ -- hlgp = "", -- horizontal line gap OS/2.sTypoLineGap
+ -- hcla = "", -- horizontal clipping ascent OS/2.usWinAscent
+ -- hcld = "", -- horizontal clipping descent OS/2.usWinDescent
+ vasc = "", -- vertical ascender vhea.ascent
+ vdsc = "", -- vertical descender vhea.descent
+ vlgp = "", -- vertical line gap vhea.lineGap
+ xhgt = "", -- x height OS/2.sxHeight
+ cpht = "", -- cap height OS/2.sCapHeight
+ -- sbxs = "", -- subscript em x size OS/2.ySubscriptXSize
+ -- sbys = "", -- subscript em y size OS/2.ySubscriptYSize
+ -- sbxo = "", -- subscript em x offset OS/2.ySubscriptXOffset
+ -- sbyo = "", -- subscript em y offset OS/2.ySubscriptYOffset
+ -- spxs = "", -- superscript em x size OS/2.ySuperscriptXSize
+ -- spys = "", -- superscript em y size OS/2.ySuperscriptYSize
+ -- spxo = "", -- superscript em x offset OS/2.ySuperscriptXOffset
+ -- spyo = "", -- superscript em y offset OS/2.ySuperscriptYOffset
+ -- strs = "", -- strikeout size OS/2.yStrikeoutSize
+ -- stro = "", -- strikeout offset OS/2.yStrikeoutPosition
+ -- unds = "", -- underline size post.underlineThickness
+ -- undo = "", -- underline offset post.underlinePosition
+}
+
+function readers.mvar(f,fontdata,specification)
+ local datatable = fontdata.tables.mvar
+ if datatable then
+ local tableoffset = datatable.offset
+ setposition(f,tableoffset)
+ local majorversion = readushort(f) -- 1
+ local minorversion = readushort(f) -- 0
+ if majorversion ~= 1 and minorversion ~= 0 then
+ report("table version %a.%a of %a is not supported (yet), maybe font %s is bad",
+ majorversion,minorversion,"fvar",fontdata.filename)
+ return
+ end
+ --
+ local nofaxis = readushort(f)
+ local recordsize = readushort(f)
+ local nofrecords = readushort(f)
+ local offsettostore = tableoffset + readushort(f)
+ local records = { }
+ local dimensions = { }
+ local store = { }
+ local regions = { }
+ --
+ for i=1,nofrecords do
+ local tag = readtag(f)
+ if tags[tag] then
+ dimensions[tag] = {
+ outer = readushort(f),
+ inner = readushort(f),
+ }
+ else
+ skipshort(f,2)
+ end
+ end
+ --
+ setposition(f,offsettostore)
+ local nofaxis = readushort(f)
+ local nofregions = readushort(f)
+ for i=1,nofregions do
+ local t = { }
+ for i=1,nofaxis do
+ t[i] = {
+ start = read2dot14(f),
+ peak = read2dot14(f),
+ stop = read2dot14(f),
+ }
+ end
+ regions[i] = t
+ end
+ --
+ local format = readushort(f) -- 1
+ local offset = offsettostore + readulong(f)
+ local nofdata = readushort(f)
+ local data = { }
+ for i=1,nofdata do
+ data[i] = readulong(f) + offset
+ end
+ for i=1,nofdata do
+ local offset = data[i]
+ setposition(f,offset)
+ local nofdeltas = readushort(f)
+ local nofshort = readushort(f)
+ local nofregions = readushort(f)
+ local deltas = { }
+ local regions = { }
+ local length = nofshort + nofregions
+ for i=1,nofregions do
+ regions[i] = readushort(f)
+ end
+ for i=1,nofdeltas do
+ local t = { }
+ for i=1,nofshort do
+ t[i] = readushort(f)
+ end
+ for i=1,nofregions do
+ t[nofshort+i] = readinteger(f)
+ end
+ deltas[i] = t
+ end
+ data[i] = {
+ regions = regions,
+ deltas = deltas,
+ }
+ end
+ end
+end
+
+-- function readers.vorg(f,fontdata,specification)
+-- end
diff --git a/tex/context/base/mkiv/font-lib.mkvi b/tex/context/base/mkiv/font-lib.mkvi
index ed7d896c5..316e70019 100644
--- a/tex/context/base/mkiv/font-lib.mkvi
+++ b/tex/context/base/mkiv/font-lib.mkvi
@@ -97,6 +97,7 @@
\registerctxluafile{font-ctx}{1.001} % after def as it overloads
\registerctxluafile{font-ext}{1.001}
+\registerctxluafile{font-lig}{1.001} % only for experiments so try to avoid it
\registerctxluafile{font-fbk}{1.001}
\registerctxluafile{font-aux}{1.001}
diff --git a/tex/context/base/mkiv/font-lig.lua b/tex/context/base/mkiv/font-lig.lua
new file mode 100644
index 000000000..823be9c3b
--- /dev/null
+++ b/tex/context/base/mkiv/font-lig.lua
@@ -0,0 +1,52 @@
+if not modules then modules = { } end modules ['font-lig'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files",
+}
+
+-- This module is not loaded but generated a file for plain TeX as a substitute
+-- for collapsing the input: "luatex-fonts-lig.lua" with "collapse=yes".
+
+local standalone = not characters
+
+if standalone then
+ require("char-def")
+ require("char-utf")
+ if characters.initialize then
+ characters.initialize()
+ end
+end
+
+local data = { } -- if we ever preload this i'll cache it
+
+for first, seconds in next, characters.graphemes do
+ for second, combined in next, seconds do
+ data[combined] = { first, second }
+ end
+end
+
+-- data['c'] = { 'a', 'b' }
+-- data['d'] = { 'c', 'c' }
+
+local feature = {
+ name = "collapse",
+ type = "ligature",
+ prepend = true,
+ dataset = {
+ { data = data },
+ { data = data },
+ }
+}
+
+if standalone then
+ local filename = "luatex-fonts-lig.lua"
+ local filedata = "-- this file is generated by context\n\n"
+ .. "fonts.handlers.otf.addfeature "
+ .. table.serialize(feature,false)
+ logs.report("fonts","pseudo ligature file %a saved",filename)
+ io.savedata(filename,filedata)
+else
+ fonts.handlers.otf.addfeature(feature)
+end
diff --git a/tex/context/base/mkiv/font-otc.lua b/tex/context/base/mkiv/font-otc.lua
index a55320903..a0dda593d 100644
--- a/tex/context/base/mkiv/font-otc.lua
+++ b/tex/context/base/mkiv/font-otc.lua
@@ -195,13 +195,15 @@ local function addfeature(data,feature,specifications)
local stepkey = coverup.stepkey
local register = coverup.register
- local function prepare_substitution(list,featuretype)
+ local function prepare_substitution(list,featuretype,nocheck)
local coverage = { }
local cover = coveractions[featuretype]
for code, replacement in next, list do
local unicode = tounicode(code)
local description = descriptions[unicode]
- if description then
+ if not nocheck and not description then
+ skip = skip + 1
+ else
if type(replacement) == "table" then
replacement = replacement[1]
end
@@ -212,20 +214,18 @@ local function addfeature(data,feature,specifications)
else
skip = skip + 1
end
- else
- skip = skip + 1
end
end
return coverage
end
- local function prepare_alternate(list,featuretype)
+ local function prepare_alternate(list,featuretype,nocheck)
local coverage = { }
local cover = coveractions[featuretype]
for code, replacement in next, list do
local unicode = tounicode(code)
local description = descriptions[unicode]
- if not description then
+ if not nocheck and not description then
skip = skip + 1
elseif type(replacement) == "table" then
local r = { }
@@ -248,13 +248,13 @@ local function addfeature(data,feature,specifications)
return coverage
end
- local function prepare_multiple(list,featuretype)
+ local function prepare_multiple(list,featuretype,nocheck)
local coverage = { }
local cover = coveractions[featuretype]
for code, replacement in next, list do
local unicode = tounicode(code)
local description = descriptions[unicode]
- if not description then
+ if not nocheck and not description then
skip = skip + 1
elseif type(replacement) == "table" then
local r, n = { }, 0
@@ -281,16 +281,19 @@ local function addfeature(data,feature,specifications)
end
end
end
+ inspect(coverage)
return coverage
end
- local function prepare_ligature(list,featuretype)
+ local function prepare_ligature(list,featuretype,nocheck)
local coverage = { }
local cover = coveractions[featuretype]
for code, ligature in next, list do
local unicode = tounicode(code)
local description = descriptions[unicode]
- if description then
+ if not nocheck and not description then
+ skip = skip + 1
+ else
if type(ligature) == "string" then
ligature = { lpegmatch(splitter,ligature) }
end
@@ -311,8 +314,6 @@ local function addfeature(data,feature,specifications)
else
skip = skip + 1
end
- else
- skip = skip + 1
end
end
return coverage
@@ -552,6 +553,7 @@ local function addfeature(data,feature,specifications)
local askedsteps = specification.steps or specification.subtables or { specification.data } or { }
local featuretype = normalized[specification.type or "substitution"] or "substitution"
local featureflags = specification.flags or noflags
+ local nocheck = specification.nocheck
local featureorder = specification.order or { feature }
local featurechain = (featuretype == "chainsubstitution" or featuretype == "chainposition") and 1 or 0
local nofsteps = 0
@@ -572,13 +574,13 @@ local function addfeature(data,feature,specifications)
local coverage = nil
local format = nil
if featuretype == "substitution" then
- coverage = prepare_substitution(list,featuretype)
+ coverage = prepare_substitution(list,featuretype,nocheck)
elseif featuretype == "ligature" then
- coverage = prepare_ligature(list,featuretype)
+ coverage = prepare_ligature(list,featuretype,nocheck)
elseif featuretype == "alternate" then
- coverage = prepare_alternate(list,featuretype)
+ coverage = prepare_alternate(list,featuretype,nocheck)
elseif featuretype == "multiple" then
- coverage = prepare_multiple(list,featuretype)
+ coverage = prepare_multiple(list,featuretype,nocheck)
elseif featuretype == "kern" then
format = "kern"
coverage = prepare_kern(list,featuretype)
@@ -605,16 +607,16 @@ local function addfeature(data,feature,specifications)
local format = nil
if featuretype == "substitution" then
category = "gsub"
- coverage = prepare_substitution(list,featuretype)
+ coverage = prepare_substitution(list,featuretype,nocheck)
elseif featuretype == "ligature" then
category = "gsub"
- coverage = prepare_ligature(list,featuretype)
+ coverage = prepare_ligature(list,featuretype,nocheck)
elseif featuretype == "alternate" then
category = "gsub"
- coverage = prepare_alternate(list,featuretype)
+ coverage = prepare_alternate(list,featuretype,nocheck)
elseif featuretype == "multiple" then
category = "gsub"
- coverage = prepare_multiple(list,featuretype)
+ coverage = prepare_multiple(list,featuretype,nocheck)
elseif featuretype == "kern" then
category = "gpos"
format = "kern"
diff --git a/tex/context/base/mkiv/font-otj.lua b/tex/context/base/mkiv/font-otj.lua
index fdee3513f..50330cb83 100644
--- a/tex/context/base/mkiv/font-otj.lua
+++ b/tex/context/base/mkiv/font-otj.lua
@@ -25,7 +25,7 @@ if not modules then modules = { } end modules ['font-otj'] = {
if not nodes.properties then return end
-local next, rawget = next, rawget
+local next, rawget, tonumber = next, rawget, tonumber
local fastcopy = table.fastcopy
local registertracker = trackers.register
diff --git a/tex/context/base/mkiv/font-otr.lua b/tex/context/base/mkiv/font-otr.lua
index a9d3a8b29..c5c5d8f32 100644
--- a/tex/context/base/mkiv/font-otr.lua
+++ b/tex/context/base/mkiv/font-otr.lua
@@ -65,11 +65,9 @@ if not modules then modules = { } end modules ['font-otr'] = {
-- require("char-ini")
-- end
-local next, type, unpack = next, type, unpack
-local byte, lower, char, strip, gsub = string.byte, string.lower, string.char, string.strip, string.gsub
-local bittest = bit32.btest
-local concat, remove, unpack, fastcopy = table.concat, table.remov, table.unpack, table.fastcopy
-local floor, abs, sqrt, round = math.floor, math.abs, math.sqrt, math.round
+local next, type = next, type
+local byte, lower, char, gsub = string.byte, string.lower, string.char, string.gsub
+local floor, round = math.floor, math.round
local P, R, S, C, Cs, Cc, Ct, Carg, Cmt = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Cc, lpeg.Ct, lpeg.Carg, lpeg.Cmt
local lpegmatch = lpeg.match
@@ -120,7 +118,7 @@ local readoffset = readushort
local read2dot14 = streamreader.read2dot14 -- 16-bit signed fixed number with the low 14 bits of fraction (2.14) (F2DOT14)
function streamreader.readtag(f)
- return lower(strip(readstring(f,4)))
+ return lower(stripstring(readstring(f,4)))
end
-- date represented in number of seconds since 12:00 midnight, January 1, 1904. The value is represented as a
@@ -174,6 +172,7 @@ local reservednames = { [0] =
"wwssubfamily",
"lightbackgroundpalette",
"darkbackgroundpalette",
+ "variationspostscriptnameprefix",
}
-- more at: https://www.microsoft.com/typography/otspec/name.htm
@@ -747,7 +746,8 @@ function readers.name(f,fontdata,specification)
local encoding = encodings[encoding]
local language = languages[language]
if encoding and language then
- local name = reservednames[readushort(f)]
+ local index = readushort(f)
+ local name = reservednames[index]
if name then
namelist[#namelist+1] = {
platform = platform,
@@ -758,7 +758,14 @@ function readers.name(f,fontdata,specification)
offset = start + readushort(f),
}
else
- skipshort(f,2)
+namelist[#namelist+1] = {
+ platform = platform,
+ encoding = encoding,
+ language = language,
+ length = readushort(f),
+ offset = start + readushort(f),
+}
+-- skipshort(f,2)
end
else
skipshort(f,3)
@@ -783,8 +790,9 @@ function readers.name(f,fontdata,specification)
--
-- we need to choose one we like, for instance an unicode one
--
- local names = { }
- local done = { }
+ local names = { }
+ local done = { }
+ local extras = { }
--
-- there is quite some logic in ff ... hard to follow so we start simple
-- and extend when we run into it (todo: proper reverse hash) .. we're only
@@ -795,7 +803,7 @@ function readers.name(f,fontdata,specification)
for i=1,#namelist do
local name = namelist[i]
local nametag = name.name
- if not done[nametag] then
+ if not done[nametag or i] then
local encoding = name.encoding
local language = name.language
if (not e or encoding == e) and (not l or language == l) then
@@ -808,13 +816,16 @@ function readers.name(f,fontdata,specification)
if decoder then
content = decoder(content)
end
- names[nametag] = {
- content = content,
- platform = platform,
- encoding = encoding,
- language = language,
- }
- done[nametag] = true
+ if nametag then
+ names[nametag] = {
+ content = content,
+ platform = platform,
+ encoding = encoding,
+ language = language,
+ }
+ end
+ extras[i-1] = content
+ done[nametag or i] = true
end
end
end
@@ -827,7 +838,8 @@ function readers.name(f,fontdata,specification)
filter("macintosh")
filter("unicode")
--
- fontdata.names = names
+ fontdata.names = names
+ fontdata.extras = extras
--
if specification.platformnames then
local collected = { }
@@ -1288,7 +1300,8 @@ local sequence = {
local supported = { }
for i=1,#sequence do
- local sp, se, sf = unpack(sequence[i])
+ local si = sequence[i]
+ local sp, se, sf = si[1], si[2], si[3]
local p = supported[sp]
if not p then
p = { }
@@ -1704,7 +1717,8 @@ function readers.cmap(f,fontdata,specification)
--
local ok = false
for i=1,#sequence do
- local sp, se, sf = unpack(sequence[i])
+ local si = sequence[i]
+ local sp, se, sf = si[1], si[2], si[3]
if checkcmap(f,fontdata,records,sp,se,sf) > 0 then
ok = true
end
@@ -2000,7 +2014,6 @@ local function readdata(f,offset,specification)
end
end
--
- --
readers["os/2"](f,fontdata,specification)
readers["head"](f,fontdata,specification)
readers["maxp"](f,fontdata,specification)
@@ -2023,6 +2036,12 @@ local function readdata(f,offset,specification)
readers["gpos"](f,fontdata,specification)
readers["math"](f,fontdata,specification)
--
+ -- readers["fvar"](f,fontdata,specification)
+ -- readers["hvar"](f,fontdata,specification)
+ -- readers["vvar"](f,fontdata,specification)
+ -- readers["mvar"](f,fontdata,specification)
+ -- readers["vorg"](f,fontdata,specification)
+ --
fontdata.locations = nil
fontdata.tables = nil
fontdata.cidmaps = nil
diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua
index 22dd082d1..742a0c561 100644
--- a/tex/context/base/mkiv/font-ots.lua
+++ b/tex/context/base/mkiv/font-ots.lua
@@ -125,7 +125,6 @@ local fonts = fonts
local otf = fonts.handlers.otf
local tracers = nodes.tracers
-local trace_lookups = false registertracker("otf.lookups", function(v) trace_lookups = v end)
local trace_singles = false registertracker("otf.singles", function(v) trace_singles = v end)
local trace_multiples = false registertracker("otf.multiples", function(v) trace_multiples = v end)
local trace_alternatives = false registertracker("otf.alternatives", function(v) trace_alternatives = v end)
@@ -738,7 +737,11 @@ end
local function get_alternative_glyph(start,alternatives,value)
local n = #alternatives
- if value == "random" then
+ if n == 1 then
+ -- we could actually change that into a gsub and save some memory in the
+ -- font loader but it makes tracing more messy
+ return alternatives[1], trace_alternatives and "1 (only one present)"
+ elseif value == "random" then
local r = getrandom and getrandom("glyph",1,n) or random(1,n)
return alternatives[r], trace_alternatives and formatters["value %a, taking %a"](value,r)
elseif value == "first" then
@@ -2356,7 +2359,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
size = l - f + 1
if size > 1 then
-- before/current/after | before/current | current/after
- local discfound = nil
+ local discfound -- = nil
local n = f + 1
-- last = getnext(last) -- the second in current (first already matched)
last = startnext -- the second in current (first already matched)
@@ -2485,7 +2488,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
-- sweeptype = nil
end
if prev then
- local discfound = nil
+ local discfound -- = nil
local n = f - 1
while n >= 1 do
if prev then
@@ -2597,7 +2600,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
end
-- maybe only if match
prev = getprev(prev)
- elseif seq[n][32] and id == glue_code and isspace(prev,threshold,id) then
+ elseif id == glue_code and seq[n][32] and isspace(prev,threshold,id) then
n = n - 1
prev = getprev(prev)
else
@@ -2619,14 +2622,12 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
-- after
if match and s > l then
local current = last and getnext(last)
- if not current then
- if sweeptype == "post" or sweeptype == "replace" then
- current = getnext(sweepnode)
- -- sweeptype = nil
- end
+ if not current and (sweeptype == "post" or sweeptype == "replace") then
+ current = getnext(sweepnode)
+ -- sweeptype = nil
end
if current then
- local discfound = nil
+ local discfound -- = nil
-- removed optimization for s-l == 1, we have to deal with marks anyway
local n = l + 1
while n <= s do
@@ -2731,7 +2732,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
end
-- maybe only if match
current = getnext(current)
- elseif seq[n][32] and id == glue_code and isspace(current,threshold,id) then
+ elseif id == glue_code and seq[n][32] and isspace(current,threshold,id) then
n = n + 1
current = getnext(current)
else
@@ -2910,6 +2911,14 @@ do -- overcome local limit
end
+-- Functions like kernrun, comprun etc evolved over time and in the end look rather
+-- complex. It's a bit of a compromis between extensive copying and creating subruns.
+-- The logic has been improved a lot by Kai and Ivo who use complex fonts which
+-- really helped to identify border cases on the one hand and get insight in the diverse
+-- ways fonts implement features (not always that consistent and efficient). At the same
+-- time I tried to keep the code relatively efficient so that the overhead in runtime
+-- stays acceptable.
+
local function report_disc(what,n)
report_run("%s: %s > %s",what,n,languages.serializediscretionary(n))
end
@@ -3014,7 +3023,7 @@ local function kernrun(disc,k_run,font,attr,...)
return nextstart, done
end
--- fonts like ebgaramond do ligatuires this way (less efficient than e.g. dejavu which
+-- fonts like ebgaramond do ligatures this way (less efficient than e.g. dejavu which
-- will do the testrun variant)
local function comprun(disc,c_run,...) -- vararg faster than the whole list
@@ -3741,6 +3750,14 @@ otf.helpers = otf.helpers or { }
otf.helpers.txtdirstate = txtdirstate
otf.helpers.pardirstate = pardirstate
+-- This is the main loop. We run over the node list dealing with a specific font. The
+-- attribute is a context specific thing. We could work on sub start-stop ranges instead
+-- but I wonder if there is that much speed gain (experiments showed that it made not
+-- much sense) and we need to keep track of directions anyway. Also at some point I
+-- want to play with font interactions and then we do need the full sweeps. Apart from
+-- optimizations the principles of processing the features hasn't changed much since
+-- the beginning.
+
local function featuresprocessor(head,font,attr)
local sequences = sequencelists[font] -- temp hack
@@ -3791,11 +3808,6 @@ local function featuresprocessor(head,font,attr)
local dirstack = { } -- could move outside function but we can have local runs
sweephead = { }
- -- We could work on sub start-stop ranges instead but I wonder if there is that
- -- much speed gain (experiments showed that it made not much sense) and we need
- -- to keep track of directions anyway. Also at some point I want to play with
- -- font interactions and then we do need the full sweeps.
-
-- Keeping track of the headnode is needed for devanagari. (I generalized it a bit
-- so that multiple cases are also covered.) We could prepend a temp node.
@@ -3906,6 +3918,9 @@ local function featuresprocessor(head,font,attr)
elseif char == false then
-- whatever glyph
start = getnext(start)
+ elseif id == glue_code then
+ -- happens often
+ start = getnext(start)
elseif id == disc_code then
local ok
if gpossing then
@@ -3977,6 +3992,10 @@ local function featuresprocessor(head,font,attr)
start = getnext(start)
end
elseif char == false then
+ -- whatever glyph
+ start = getnext(start)
+ elseif id == glue_code then
+ -- happens often
start = getnext(start)
elseif id == disc_code then
local ok
diff --git a/tex/context/base/mkiv/luat-cnf.lua b/tex/context/base/mkiv/luat-cnf.lua
index 9d37df7bb..c26b4775b 100644
--- a/tex/context/base/mkiv/luat-cnf.lua
+++ b/tex/context/base/mkiv/luat-cnf.lua
@@ -70,9 +70,8 @@ function texconfig.init()
"epdf", "fontloader", "kpse", "mplib",
},
obsolete = {
- "fontforge", -- can be filled by luat-log
+ "fontloader", -- can be filled by luat-log
"kpse",
- "token",
},
functions = {
"assert", "pcall", "xpcall", "error", "collectgarbage",
diff --git a/tex/context/base/mkiv/node-fin.lua b/tex/context/base/mkiv/node-fin.lua
index 03c8a7607..ffb2ae49e 100644
--- a/tex/context/base/mkiv/node-fin.lua
+++ b/tex/context/base/mkiv/node-fin.lua
@@ -327,7 +327,7 @@ local function selective(namespace,attribute,head,inheritance,default) -- two at
if id == glyph_code then
check = true
elseif id == disc_code then
- check = true -- notneeded when we flatten replace
+ check = true -- not needed when we flatten replace
elseif id == glue_code then
leader = getleader(stack)
if leader then
diff --git a/tex/context/base/mkiv/publ-imp-apa.lua b/tex/context/base/mkiv/publ-imp-apa.lua
index f2e7f11e1..ec46b7f7e 100644
--- a/tex/context/base/mkiv/publ-imp-apa.lua
+++ b/tex/context/base/mkiv/publ-imp-apa.lua
@@ -191,7 +191,7 @@ categories.inbook = {
optional = {
"withauthor", "translator",
"subtitle", "type", "file",
- "booktitle",
+ "booktitle", "subbooktitle",
-- APA ignores this: "chapter",
"editionset", "series",
"month",
@@ -217,6 +217,7 @@ categories.incollection = {
optional = {
"withauthor", "translator",
"subtitle", "type", "file",
+ "subbooktitle",
"editionset", "series",
-- APA ignores this: "chapter",
"month",
diff --git a/tex/context/base/mkiv/publ-imp-apa.mkvi b/tex/context/base/mkiv/publ-imp-apa.mkvi
index 6470bb089..77fcb8995 100644
--- a/tex/context/base/mkiv/publ-imp-apa.mkvi
+++ b/tex/context/base/mkiv/publ-imp-apa.mkvi
@@ -88,6 +88,14 @@
[\c!authorconversion=normalshort]
\definebtx
+ [apa:\s!list:director]
+ [apa:\s!list:author]
+
+\definebtx
+ [apa:\s!list:producer]
+ [apa:\s!list:author]
+
+\definebtx
[apa:\s!list:suffix]
[apa:\s!list]
diff --git a/tex/context/base/mkiv/publ-ini.lua b/tex/context/base/mkiv/publ-ini.lua
index 86dc6cea2..52642c89d 100644
--- a/tex/context/base/mkiv/publ-ini.lua
+++ b/tex/context/base/mkiv/publ-ini.lua
@@ -1984,6 +1984,33 @@ do
arguments = { "string", "string" }
}
+ local function identical(a,b)
+ local na, nb = #a, #b
+ if na ~= nb then
+ return false
+ end
+ if na > 0 then
+ for i=1,na do
+ if not identical(a[i],b[i]) then
+ return false
+ end
+ end
+ return true
+ end
+ local ha, hb = a.hash, b.hash
+ if ha then
+ return ha == hb
+ end
+ for k, v in next, a do
+ if k == "original" or k == "snippets" then
+ -- skip diagnostic info
+ elseif v ~= b[k] then
+ return false
+ end
+ end
+ return true
+ end
+
function lists.sameasprevious(dataset,i,name,order,method)
local rendering = renderings[dataset]
local list = rendering.list
@@ -2030,7 +2057,7 @@ do
if c_casted and c_casted == p_casted then
sameentry = true
elseif type(c_casted) == "table" and type(p_casted) == "table" then
- sameentry = table.identical(c_casted,p_casted)
+ sameentry = identical(c_casted,p_casted)
end
end
if trace_detail then
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 1441c0e6c..6d7f14ae0 100644
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index cc2383ec2..189773237 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/trac-deb.lua b/tex/context/base/mkiv/trac-deb.lua
index 782be154f..d1168a3a9 100644
--- a/tex/context/base/mkiv/trac-deb.lua
+++ b/tex/context/base/mkiv/trac-deb.lua
@@ -372,3 +372,15 @@ implement { name = "disableexperiments", actions = experiments.disable, argument
implement { name = "showdebuginfo", actions = lmx.showdebuginfo }
implement { name = "overloaderror", actions = lmx.overloaderror }
implement { name = "showlogcategories", actions = logs.show }
+
+directives.register("system.profile",function()
+ luatex.registerstopactions(function()
+ debugger.disable()
+ debugger.savestats("luatex-profile.log")
+ report_nl()
+ logs.report("system","profiler stopped, log saved in %a","luatex-profile.log")
+ report_nl()
+ end)
+ logs.report("system","profiler started")
+ debugger.enable()
+end)
diff --git a/tex/context/base/mkiv/util-deb.lua b/tex/context/base/mkiv/util-deb.lua
index ee732b3b5..040a7a9cf 100644
--- a/tex/context/base/mkiv/util-deb.lua
+++ b/tex/context/base/mkiv/util-deb.lua
@@ -12,87 +12,236 @@ if not modules then modules = { } end modules ['util-deb'] = {
local debug = require "debug"
-local getinfo = debug.getinfo
+local getinfo, sethook = debug.getinfo, debug.sethook
local type, next, tostring = type, next, tostring
-local format, find = string.format, string.find
-local is_boolean = string.is_boolean
+local format, find, sub, gsub = string.format, string.find, string.sub, string.gsub
+local insert, remove, sort = table.insert, table.remove, table.sort
utilities = utilities or { }
local debugger = utilities.debugger or { }
utilities.debugger = debugger
-local counters = { }
+local report = logs.reporter("debugger")
+
+local ticks = os.gettimeofday or os.clock
+local seconds = function(n) return n or 0 end
+local overhead = 0
+local dummycalls = 10*1000
+local nesting = 0
local names = { }
-local report = logs.reporter("debugger")
+local function initialize()
--- one
+ if FFISUPPORTED and ffi then
-local function hook()
- local f = getinfo(2) -- "nS"
- if f then
- local n = "unknown"
- if f.what == "C" then
- n = f.name or '<anonymous>'
- if not names[n] then
- names[n] = format("%42s",n)
+ if os.type == "windows" then
+ local okay, kernel = pcall(ffi.load,"kernel32")
+ if kernel then
+ local tonumber = ffi.number or tonumber
+ffi.cdef[[
+int QueryPerformanceFrequency(int64_t *lpFrequency);
+int QueryPerformanceCounter(int64_t *lpPerformanceCount);
+]]
+ local target = ffi.new("__int64[1]")
+ ticks = function()
+ if kernel.QueryPerformanceCounter(target) == 1 then
+ return tonumber(target[0])
+ else
+ return 0
+ end
+ end
+ local target = ffi.new("__int64[1]")
+ seconds = function(ticks)
+ if kernel.QueryPerformanceFrequency(target) == 1 then
+ return ticks / tonumber(target[0])
+ else
+ return 0
+ end
+ end
end
- else
- -- source short_src linedefined what name namewhat nups func
- n = f.name or f.namewhat or f.what
- if not n or n == "" then
- n = "?"
+ elseif os.type == "unix" then
+ local C = ffi.C
+ local tonumber = ffi.number or tonumber
+ -- 1 = CLOCK_MONOTONIC
+ -- 2 = CLOCK_PROCESS_CPUTIME_ID
+ffi.cdef [[
+struct timespec { long sec; long nsec; };
+int clock_gettime(int timerid, struct timespec *t);
+ ]]
+ local target = ffi.new("timespec[?]",1)
+ function ticks()
+ C.clock_gettime(2,target)
+ return tonumber(target[0].sec*1000000000 + target[0].nsec)
end
- if not names[n] then
- names[n] = format("%42s : % 5i : %s",n,f.linedefined or 0,f.short_src or "unknown source")
+ seconds = function(ticks)
+ return ticks/1000000000
end
+
end
- counters[n] = (counters[n] or 0) + 1
end
+
+ initialize = false
+
end
-function debugger.showstats(printer,threshold) -- hm, something has changed, rubish now
- printer = printer or report
- threshold = threshold or 0
- local total, grandtotal, functions = 0, 0, 0
- local dataset = { }
- for name, count in next, counters do
- dataset[#dataset+1] = { name, count }
+table.setmetatableindex(names,function(t,name)
+ local v = table.setmetatableindex(function(t,source)
+ local v = table.setmetatableindex(function(t,line)
+ local v = { total = 0, count = 0 }
+ t[line] = v
+ return v
+ end)
+ t[source] = v
+ return v
+ end)
+ t[name] = v
+ return v
+end)
+
+local function hook(where)
+ local f = getinfo(2,"nSl")
+ if f then
+ local source = f.short_src
+ if not source then
+ return
+ end
+ local line = f.linedefined or 0
+ local name = f.name
+ if not name then
+ local what = f.what
+ if what == "C" then
+ name = "<anonymous>"
+ else
+ name = f.namewhat or what or "<unknown>"
+ end
+ end
+ local data = names[name][source][line]
+ if where == "call" then
+ data.count = data.count + 1
+ insert(data,ticks())
+ elseif where == "return" then
+ local t = remove(data)
+ if t then
+ data.total = data.total + ticks() - t
+ end
+ end
end
- table.sort(dataset,function(a,b) return a[2] == b[2] and b[1] > a[1] or a[2] > b[2] end)
- for i=1,#dataset do
- local d = dataset[i]
- local name = d[1]
- local count = d[2]
- if count > threshold and not find(name,"for generator") then -- move up
- printer(format("%8i %s\n", count, names[name]))
- total = total + count
+end
+
+function debugger.showstats(printer)
+ local printer = printer or report
+ local calls = 0
+ local functions = 0
+ local dataset = { }
+ local length = 0
+ local wholetime = 0
+ for name, sources in next, names do
+ for source, lines in next, sources do
+ for line, data in next, lines do
+ if #name > length then
+ length = #name
+ end
+ local total = data.total
+ local count = data.count
+ local real = total
+ if real > 0 then
+ real = total - (count * overhead / dummycalls)
+ if real < 0 then
+ real = 0
+ end
+ wholetime = wholetime + real
+ end
+ if line < 0 then
+ line = 0
+ end
+ dataset[#dataset+1] = { real, total, count, name, source, line }
+ end
+ end
+ end
+ sort(dataset,function(a,b)
+ if a[1] == b[1] then
+ if a[2] == b[2] then
+ if a[3] == b[3] then
+ if a[4] == b[4] then
+ if a[5] == b[5] then
+ return a[6] < b[6]
+ else
+ return a[5] < b[5]
+ end
+ else
+ return a[4] < b[4]
+ end
+ else
+ return b[3] < a[3]
+ end
+ else
+ return b[2] < a[2]
+ end
+ else
+ return b[1] < a[1]
end
- grandtotal = grandtotal + count
+ end)
+ if length > 50 then
+ length = 50
+ end
+ local fmt = string.formatters["%4.9k %4.9k %3.3k %8i %-" .. length .. "s %4i %s"]
+ for i=1,#dataset do
+ local data = dataset[i]
+ local real = data[1]
+ local total = data[2]
+ local count = data[3]
+ local name = data[4]
+ local source = data[5]
+ local line = data[6]
+ local percent = real / wholetime
+ calls = calls + count
functions = functions + 1
+ name = gsub(name,"%s+"," ")
+ if #name > length then
+ name = sub(name,1,length)
+ end
+ printer(fmt(seconds(total),seconds(real),percent,count,name,line,source))
end
- printer("\n")
- printer(format("functions : % 10i\n", functions))
- printer(format("total : % 10i\n", total))
- printer(format("grand total: % 10i\n", grandtotal))
- printer(format("threshold : % 10i\n", threshold))
+ printer("")
+ printer(format("functions : %i", functions))
+ printer(format("calls : %i", calls))
+ printer(format("overhead : %f", seconds(overhead/1000)))
end
-function debugger.savestats(filename,threshold)
+function debugger.savestats(filename)
local f = io.open(filename,'w')
if f then
- debugger.showstats(function(str) f:write(str) end,threshold)
+ debugger.showstats(function(str) f:write(str,"\n") end)
f:close()
end
end
function debugger.enable()
- debug.sethook(hook,"c")
+ if nesting == 0 then
+ running = true
+ if initialize then
+ initialize()
+ end
+ sethook(hook,"cr")
+ local function dummy() end
+ local t = ticks()
+ for i=1,dummycalls do
+ dummy()
+ end
+ overhead = ticks() - t
+ end
+ if nesting > 0 then
+ nesting = nesting + 1
+ end
end
function debugger.disable()
- debug.sethook()
- -- counters[debug.getinfo(2,"f").func] = nil
+ if nesting > 0 then
+ nesting = nesting - 1
+ end
+ if nesting == 0 then
+ sethook()
+ end
end
-- debugger.enable()
diff --git a/tex/context/base/mkiv/util-env.lua b/tex/context/base/mkiv/util-env.lua
index fb3dda41f..0b832e72e 100644
--- a/tex/context/base/mkiv/util-env.lua
+++ b/tex/context/base/mkiv/util-env.lua
@@ -31,15 +31,23 @@ end
-- setlocale(nil,nil)
-- end
--
--- function os.pushlocale(...)
+-- function os.pushlocale(l,...)
-- insert(stack, {
--- collate = setlocale("collate"),
--- ctype = setlocale("ctype"),
--- monetary = setlocale("monetary"),
--- numeric = setlocale("numeric"),
--- time = setlocale("time"),
+-- collate = setlocale(nil,"collate"),
+-- ctype = setlocale(nil,"ctype"),
+-- monetary = setlocale(nil,"monetary"),
+-- numeric = setlocale(nil,"numeric"),
+-- time = setlocale(nil,"time"),
-- })
--- setlocale(...)
+-- if l then
+-- setlocale(l,...)
+-- else
+-- setlocale(status.lc_collate ,"collate"),
+-- setlocale(status.lc_ctype ,"ctype"),
+-- setlocale(status.lc_monetary,"monetary"),
+-- setlocale(status.lc_numeric ,"numeric"),
+-- setlocale(status.lc_time ,"time"),
+-- end
-- end
--
-- function os.poplocale(...)
@@ -51,6 +59,12 @@ end
-- end
-- end
--
+-- function os.setlocale()
+-- -- no way you can mess with it, use push/pop
+-- end
+--
+-- setlocale(nil,nil) -- setlocale("all","C")
+--
-- end
-- dirty tricks (we will replace the texlua call by luatex --luaonly)
diff --git a/tex/context/base/mkiv/util-fil.lua b/tex/context/base/mkiv/util-fil.lua
index cf97d9541..dba3b235c 100644
--- a/tex/context/base/mkiv/util-fil.lua
+++ b/tex/context/base/mkiv/util-fil.lua
@@ -101,9 +101,10 @@ function files.readinteger1(f) -- one byte
end
end
-files.readcardinal1 = files.readbyte -- one byte
-files.readcardinal = files.readcardinal1
-files.readinteger = files.readinteger1
+files.readcardinal1 = files.readbyte -- one byte
+files.readcardinal = files.readcardinal1
+files.readinteger = files.readinteger1
+files.readsignedbyte = files.readinteger1
function files.readcardinal2(f)
local a, b = byte(f:read(2),1,2)
diff --git a/tex/context/base/mkiv/util-lib.lua b/tex/context/base/mkiv/util-lib.lua
index 2601b2e57..e9a968228 100644
--- a/tex/context/base/mkiv/util-lib.lua
+++ b/tex/context/base/mkiv/util-lib.lua
@@ -6,9 +6,6 @@ if not modules then modules = { } end modules ['util-lib'] = {
license = "see context related readme files",
}
--- This is experimental code for Hans and Luigi. Don't depend on it! There
--- will be a plain variant.
-
--[[
The problem with library bindings is manyfold. They are of course platform
@@ -73,29 +70,41 @@ and then without.
]]--
--- seems to be clua in recent texlive
-
-local gsub, find = string.gsub, string.find
-local pathpart, nameonly, joinfile = file.pathpart, file.nameonly, file.join
-local findfile, findfiles = resolvers and resolvers.findfile, resolvers and resolvers.findfiles
-
-local loaded = package.loaded
+local type = type
+local next = next
+local pcall = pcall
+local gsub = string.gsub
+local find = string.find
+local sort = table.sort
+local pathpart = file.pathpart
+local nameonly = file.nameonly
+local joinfile = file.join
+local removesuffix = file.removesuffix
+local findfile = resolvers.findfile
+local findfiles = resolvers.findfiles
+local expandpaths = resolvers.expandedpathlistfromvariable
+local qualifiedpath = file.is_qualified_path
+local isfile = lfs.isfile
-local report_swiglib = logs.reporter("swiglib")
-local trace_swiglib = false trackers.register("resolvers.swiglib", function(v) trace_swiglib = v end)
+local done = false
-- We can check if there are more that one component, and if not, we can
-- append 'core'.
-local done = false
-
-local function requireswiglib(required,version)
- local trace_swiglib = trace_swiglib or package.helpers.trace
- local library = loaded[required]
- if library == nil then
- if trace_swiglib then
- report_swiglib("requiring library %a with version %a",required,version or "any")
+local function locate(required,version,trace,report,action)
+ if type(required) ~= "string" then
+ report("provide a proper library name")
+ return
+ end
+ if trace then
+ report("requiring library %a with version %a",required,version or "any")
+ end
+ local found_library = nil
+ if qualifiedpath(required) then
+ if isfile(required) then
+ found_library = required
end
+ else
-- initialize a few variables
local required_full = gsub(required,"%.","/") -- package.helpers.lualibfile
local required_path = pathpart(required_full)
@@ -104,16 +113,16 @@ local function requireswiglib(required,version)
local version = type(version) == "string" and version ~= "" and version or false
local engine = environment.ownmain or false
--
- if trace_swiglib and not done then
- local list = resolvers.expandedpathlistfromvariable("lib") -- fresh, no reuse
+ if trace and not done then
+ local list = expandpaths("lib") -- fresh, no reuse
for i=1,#list do
- report_swiglib("tds path %i: %s",i,list[i])
+ report("tds path %i: %s",i,list[i])
end
end
-- helpers
local function found(locate,asked_library,how,...)
- if trace_swiglib then
- report_swiglib("checking %s: %a",how,asked_library)
+ if trace then
+ report("checking %s: %a",how,asked_library)
end
return locate(asked_library,...)
end
@@ -121,15 +130,15 @@ local function requireswiglib(required,version)
local found = nil
if version then
local asked_library = joinfile(required_path,version,required_name)
- if trace_swiglib then
- report_swiglib("checking %s: %a","with version",asked_library)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
found = locate(asked_library,...)
end
if not found or found == "" then
local asked_library = joinfile(required_path,required_name)
- if trace_swiglib then
- report_swiglib("checking %s: %a","with version",asked_library)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
found = locate(asked_library,...)
end
@@ -140,32 +149,32 @@ local function requireswiglib(required,version)
-- match anyway.
local function attempt(checkpattern)
-- check cnf spec using name and version
- if trace_swiglib then
- report_swiglib("checking tds lib paths strictly")
+ if trace then
+ report("checking tds lib paths strictly")
end
local found = findfile and check(findfile,"lib")
if found and (not checkpattern or find(found,checkpattern)) then
return found
end
-- check cnf spec using wildcard
- if trace_swiglib then
- report_swiglib("checking tds lib paths with wildcard")
+ if trace then
+ report("checking tds lib paths with wildcard")
end
local asked_library = joinfile(required_path,".*",required_name)
- if trace_swiglib then
- report_swiglib("checking %s: %a","latest version",asked_library)
+ if trace then
+ report("checking %s: %a","latest version",asked_library)
end
local list = findfiles(asked_library,"lib",true)
if list and #list > 0 then
- table.sort(list)
+ sort(list)
local found = list[#list]
if found and (not checkpattern or find(found,checkpattern)) then
return found
end
end
-- Check lib paths using name and version.
- if trace_swiglib then
- report_swiglib("checking lib paths")
+ if trace then
+ report("checking lib paths")
end
package.extralibpath(environment.ownpath)
local paths = package.libpaths()
@@ -177,59 +186,80 @@ local function requireswiglib(required,version)
end
return false
end
- local found_library = nil
if engine then
- if trace_swiglib then
- report_swiglib("attemp 1, engine %a",engine)
+ if trace then
+ report("attemp 1, engine %a",engine)
end
found_library = attempt("/"..engine.."/")
if not found_library then
- if trace_swiglib then
- report_swiglib("attemp 2, no engine",asked_library)
+ if trace then
+ report("attemp 2, no engine",asked_library)
end
found_library = attempt()
end
else
found_library = attempt()
end
- -- load and initialize when found
- if not found_library then
- if trace_swiglib then
- report_swiglib("not found: %a",required)
- end
- library = false
- else
- local path = pathpart(found_library)
- local base = nameonly(found_library)
- dir.push(path)
- if trace_swiglib then
- report_swiglib("found: %a",found_library)
- end
- local message = nil
- local opener = "luaopen_" .. required_base
- library, message = package.loadlib(found_library,opener)
- local libtype = type(library)
- if libtype == "function" then
- library = library()
- else
- report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
- library = false
- end
- dir.pop()
- end
- -- cache result
- if not library then
- report_swiglib("unknown: %a",required)
- elseif trace_swiglib then
- report_swiglib("stored: %a",required)
+ end
+ -- load and initialize when found
+ if not found_library then
+ if trace then
+ report("not found: %a",required)
end
- loaded[required] = library
+ library = false
else
- report_swiglib("reused: %a",required)
+ if trace then
+ report("found: %a",found_library)
+ end
+ local message, result = action(found_library,required_base)
+ if result then
+ library = result
+ else
+ library = false
+ report("load error: message %a, library %a",tostring(message),found_library or "no library")
+ end
+ end
+ if not library then
+ report("unknown: %a",required)
+ elseif trace then
+ report("stored: %a",required)
end
return library
end
+do
+
+ local report_swiglib = logs.reporter("swiglib")
+ local trace_swiglib = false
+ local savedrequire = require
+ local loadedlibs = { }
+
+ trackers.register("resolvers.swiglib", function(v) trace_swiglib = v end)
+
+ function requireswiglib(required,version)
+ local library = loadedlibs[library]
+ if library == nil then
+ local trace_swiglib = trace_swiglib or package.helpers.trace
+ library = locate(required,version,trace_swiglib,report_swiglib,function(name,base)
+ dir.push(pathpart(name))
+ local opener = "luaopen_" .. base
+ local library, message = package.loadlib(name,opener)
+ local libtype = type(library)
+ if libtype == "function" then
+ library = library()
+ message = true
+ else
+ report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
+ library = false
+ end
+ dir.pop()
+ return message, library
+ end)
+ loadedlibs[required] = library or false
+ end
+ return library
+ end
+
--[[
For convenience we make the require loader function swiglib aware. Alternatively
@@ -237,15 +267,13 @@ we could put the specific loader in the global namespace.
]]--
-local savedrequire = require
-
-function require(name,version)
- if find(name,"^swiglib%.") then
- return requireswiglib(name,version)
- else
- return savedrequire(name)
+ function require(name,version)
+ if find(name,"^swiglib%.") then
+ return requireswiglib(name,version)
+ else
+ return savedrequire(name)
+ end
end
-end
--[[
@@ -255,43 +283,87 @@ recommended loader.
]]--
-local swiglibs = { }
-local initializer = "core"
+ local swiglibs = { }
+ local initializer = "core"
-function swiglib(name,version)
- local library = swiglibs[name]
- if not library then
- statistics.starttiming(swiglibs)
- if trace_swiglib then
- report_swiglib("loading %a",name)
- end
- if not find(name,"%." .. initializer .. "$") then
- fullname = "swiglib." .. name .. "." .. initializer
- else
- fullname = "swiglib." .. name
+ function swiglib(name,version)
+ local library = swiglibs[name]
+ if not library then
+ statistics.starttiming(swiglibs)
+ if trace_swiglib then
+ report_swiglib("loading %a",name)
+ end
+ if not find(name,"%." .. initializer .. "$") then
+ fullname = "swiglib." .. name .. "." .. initializer
+ else
+ fullname = "swiglib." .. name
+ end
+ library = requireswiglib(fullname,version)
+ swiglibs[name] = library
+ statistics.stoptiming(swiglibs)
end
- library = requireswiglib(fullname,version)
- swiglibs[name] = library
- statistics.stoptiming(swiglibs)
+ return library
end
- return library
+
+ statistics.register("used swiglibs", function()
+ if next(swiglibs) then
+ return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
+ end
+ end)
+
end
-statistics.register("used swiglibs", function()
- if next(swiglibs) then
- return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
+if FFISUPPORTED and ffi and ffi.load then
+
+--[[
+
+We use the same lookup logic for ffi loading.
+
+]]--
+
+ local report_ffilib = logs.reporter("ffilib")
+ local trace_ffilib = false
+ local savedffiload = ffi.load
+
+ trackers.register("resolvers.ffilib", function(v) trace_ffilib = v end)
+
+ function ffilib(required,version)
+ return locate(required,version,trace_ffilib,report_ffilib,function(name)
+ local message, library = pcall(savedffiload,removesuffix(name))
+ if type(library) == "userdata" then
+ return message, library
+ else
+ return message, false
+ end
+ end)
end
-end)
+
+ function ffi.load(name)
+ local library = ffilib(name)
+ if type(library) == "userdata" then
+ return library
+ else
+ report_ffilib("trying to load %a using normal loader",name)
+ return savedffiload(name)
+ end
+ end
+
+end
--[[
-So, we now have:
+-- So, we now have:
+
+trackers.enable("resolvers.ffilib")
+trackers.enable("resolvers.swiglib")
local gm = require("swiglib.gmwand.core")
local gm = swiglib("gmwand.core")
local sq = swiglib("mysql.core")
local sq = swiglib("mysql.core","5.6")
-Watch out, the last one is less explicit and lacks the swiglib prefix.
+ffilib("libmysql","5.6.14")
+
+-- Watch out, the last one is less explicit and lacks the swiglib prefix.
]]--
diff --git a/tex/context/base/mkiv/util-str.lua b/tex/context/base/mkiv/util-str.lua
index fb510257a..9e6be9999 100644
--- a/tex/context/base/mkiv/util-str.lua
+++ b/tex/context/base/mkiv/util-str.lua
@@ -449,6 +449,31 @@ function number.sparseexponent(f,n)
return tostring(n)
end
+local hf = { }
+local hs = { }
+
+setmetatable(hf, { __index = function(t,k)
+ local v = "%." .. k .. "f"
+ t[k] = v
+ return v
+end } )
+
+setmetatable(hs, { __index = function(t,k)
+ local v = "%" .. k .. "s"
+ t[k] = v
+ return v
+end } )
+
+function number.formattedfloat(n,b,a)
+ local s = format(hf[a],n)
+ local l = (b or 0) + (a or 0) + 1
+ if #s < l then
+ return format(hs[l],s)
+ else
+ return s
+ end
+end
+
local template = [[
%s
%s
@@ -479,6 +504,7 @@ local autodouble=string.autodouble
local sequenced=table.sequenced
local formattednumber=number.formatted
local sparseexponent=number.sparseexponent
+local formattedfloat=number.formattedfloat
]]
else
@@ -504,6 +530,7 @@ else
sequenced = table.sequenced,
formattednumber = number.formatted,
sparseexponent = number.sparseexponent,
+ formattedfloat = number.formattedfloat
}
end
@@ -521,6 +548,9 @@ setmetatable(arguments, { __index =
})
local prefix_any = C((S("+- .") + R("09"))^0)
+local prefix_sub = (C((S("+-") + R("09"))^0) + Cc(0))
+ * P(".")
+ * (C((S("+-") + R("09"))^0) + Cc(0))
local prefix_tab = P("{") * C((1-P("}"))^0) * P("}") + C((1-R("az","AZ","09","%%"))^0)
-- we've split all cases as then we can optimize them (let's omit the fuzzy u)
@@ -594,6 +624,11 @@ local format_F = function(f) -- beware, no cast to number
end
end
+local format_k = function(b,a) -- slow
+ n = n + 1
+ return format("formattedfloat(a%s,%i,%i)",n,b or 0, a or 0)
+end
+
local format_g = function(f)
n = n + 1
return format("format('%%%sg',a%s)",f,n)
@@ -855,6 +890,7 @@ local builder = Cs { "start",
+ V("S") -- new
+ V("Q") -- new
+ V("N") -- new
+ + V("k") -- new
--
+ V("r")
+ V("h") + V("H") + V("u") + V("U")
@@ -894,6 +930,7 @@ local builder = Cs { "start",
["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)
+ ["k"] = (prefix_sub * P("k")) / format_k, -- %k => like f but with n.m
["c"] = (prefix_any * P("c")) / format_c, -- %c => utf character (extension to regular)
["C"] = (prefix_any * P("C")) / format_C, -- %c => U+.... utf character
--
diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf
index 56f1b02a0..a62e63912 100644
--- a/tex/context/interface/mkiv/i-context.pdf
+++ b/tex/context/interface/mkiv/i-context.pdf
Binary files differ
diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf
index 09945eaec..e1648bc33 100644
--- a/tex/context/interface/mkiv/i-readme.pdf
+++ b/tex/context/interface/mkiv/i-readme.pdf
Binary files differ
diff --git a/tex/context/modules/mkiv/m-matrix.mkiv b/tex/context/modules/mkiv/m-matrix.mkiv
index b72453bdd..f59363e94 100644
--- a/tex/context/modules/mkiv/m-matrix.mkiv
+++ b/tex/context/modules/mkiv/m-matrix.mkiv
@@ -28,6 +28,7 @@ local formatters = string.formatters
local copy = table.copy
local insert = table.insert
local remove = table.remove
+local random = math.random
local context = context
@@ -92,8 +93,8 @@ function matrix.typeset(m,options)
if options.fences then
whatever = fences[options.fences] or whatever
elseif options.determinant then
- whatever = fences.brackets
- -- whatever = fences.bars
+ -- whatever = fences.brackets
+ whatever = fences.bars
end
local template = options.template or matrix.template
if template == "yes" then
@@ -125,10 +126,64 @@ end
-- interchange two rows (i-th, j-th)
-function matrix.swap(t,i,j)
- t[i], t[j] = t[j], t[i]
+-- function matrix.swaprows(t,i,j)
+-- if i <= #t and j <= #t then
+-- t[i], t[j] = t[j], t[i]
+-- return t
+-- else
+-- return "error: out of bound"
+-- end
+-- end
+
+function matrix.swaprows(t,i,j)
+ local ti = t[i]
+ if not ti then
+ return "error: no row i"
+ end
+ local tj = t[j]
+ if not tj then
+ return "error: no row j"
+ end
+ t[i], t[j] = tj, ti
+ return t
+end
+
+-- interchange two columns (i-th, j-th)
+
+-- function matrix.swapcolumns(t, i, j)
+-- if i <= #t[1] and j <= #t[1] then
+-- for k = 1, #t do
+-- t[k][i], t[k][j] = t[k][j], t[k][i]
+-- end
+-- return t
+-- else
+-- return "error: out of bound"
+-- end
+-- end
+
+function matrix.swapcolumns(t, i, j)
+ local t1 = t[1]
+ if not t1 then
+ return "error: no rows"
+ end
+ local n = #t1
+ if i <= n then
+ return "error: no row i"
+ end
+ if j <= n then
+ return "error: no row j"
+ end
+ for k = 1, #t do
+ local tk = t[k]
+ tk[i], tk[j] = tk[j], tk[i]
+ end
+ return t
end
+matrix.swapC = matrix.swapcolumns
+matrix.swapR = matrix.swaprows
+matrix.swap = matrix.swaprows
+
-- replace i-th row with factor * (i-th row)
function matrix.multiply(m,i,factor)
@@ -251,7 +306,7 @@ end
matrix.uppertri = uppertri
-function matrix.determinant(m)
+local function determinant(m)
if #m == #m[1] then
local d = 1
local t, s = uppertri(m,1)
@@ -264,6 +319,8 @@ function matrix.determinant(m)
end
end
+matrix.determinant = determinant
+
local function rowechelon(m,r)
local temp = copy(m)
local pRow = 1
@@ -328,6 +385,99 @@ end
matrix.rowechelon = rowechelon
matrix.rowEchelon = rowechelon
+-- make matrices until its determinant is not 0
+
+function matrix.make(n,m,low,high)
+ if not n then
+ n = 10
+ end
+ if not m then
+ m = 10
+ end
+ if not low then
+ low = 0
+ end
+ if not high then
+ high = 100
+ end
+ local t = { } -- make an empty n1 x n2 array
+ local again = true
+ for i=1,n do
+ t[i] = { }
+ end
+ while true do
+ for i=1,n do
+ local ti = t[i]
+ for j=1,m do
+ ti[j] = random(low,high)
+ end
+ end
+ if n ~= m or determinant(t,1) ~= 0 then
+ return t
+ end
+ end
+end
+
+-- extract submatrix by using
+
+local function submatrix(t,i,j)
+ local rows = #t
+ local columns = #t[1]
+ local sign = 1 -- not used
+ if i <= rows and j <= columns then
+ local c = copy(t)
+ remove(c,i)
+ for k=1,rows-1 do
+ remove(c[k],j)
+ end
+ return c
+ else
+ return "error: out of bound"
+ end
+end
+
+matrix.submatrix = submatrix
+
+-- calculating determinant using Laplace Expansion
+
+function matrix.laplace(t) -- not sure if this is the most effient but
+ local factors = { 1 } -- it's not used for number crunching anyway
+ local data = copy(t)
+ local det = 0
+ while #data > 0 do
+ local mat = { }
+ local siz = #data[1]
+ if siz == 0 then
+ return "error: no determinant"
+ elseif siz == 1 then
+ det = data[1][1]
+ return det
+ end
+ for i=1,siz do
+ mat[i] = data[1]
+ remove(data,1)
+ end
+ local factor = remove(factors,1)
+ local m1 = mat[1]
+ if siz == 2 then
+ local m2 = mat[2]
+ det = det + factor * (m1[1]*m2[2] - m1[2]*m2[1])
+ else
+ for j=1,#m1 do
+ local m1j = m1[j]
+ if m1j ~= 0 then
+ insert(factors, (-1)^(j+1) * factor * m1j)
+ local m = submatrix(mat,1,j)
+ for k, v in next, m do
+ insert(data,v)
+ end
+ end
+ end
+ end
+ end
+ return det
+end
+
-- solve the linear equation m X = c
local function solve(m,c)
diff --git a/tex/context/modules/mkiv/s-inf-03.mkiv b/tex/context/modules/mkiv/s-inf-03.mkiv
index 31333b8e5..d2acb7341 100644
--- a/tex/context/modules/mkiv/s-inf-03.mkiv
+++ b/tex/context/modules/mkiv/s-inf-03.mkiv
@@ -158,13 +158,11 @@ local upper = string.upper
local skipglobal = table.tohash {
"_G", "_M", "_ENV", "",
"context", "modules", "global", "arg", "utf", 1,
- "_ptbs_", "_pcol_", "_plib_", "_clib_", "_tlib_",
"kpse", "commands", "ffi",
}
local skipkeys = table.tohash {
- "_pcol_", "_plib_", "_clib_", "_tlib_", "_bpnf_", "_ptbs_",
- "_cldf_", "_cldn_", "_cldo_",
+ -- "_cldf_", "_cldn_", "_cldo_",
"_clmb_", "_clme_", "_clmm_", "_clmn_", "_clma_", "_clmh_",
"_G", "_M", "_ENV", "",
-- "global", "shortcuts",
@@ -215,11 +213,10 @@ local function childtables(key,tab,handler,depth)
if marked(v) then
t = "data"
handler(s,t,depth)
+ elseif done[v] then
+ -- logs.report("inf-03","key %a in %a already done",k,v)
else
-if done[v] then
- -- logs.report("inf-03","key %a in %a already done",k,v)
-else
- done[v] = true
+ done[v] = true
handler(s,t,depth)
if variant == 3 then
childtables(false,v,handler,depth+1)
@@ -229,7 +226,6 @@ else
childtables(s,v,handler,depth+1)
end
end
-end
else
handler(s,t,depth)
end
@@ -252,7 +248,7 @@ end
local function show(title,subtitle,alias,builtin,t,lib,libcolor,glo,glocolor,mark,obsolete)
-- todo: table as argument
--- print(title,subtitle,alias,builtin,t,lib,libcolor,glo,glocolor,mark,obsolete)
+ -- print(title,subtitle,alias,builtin,t,lib,libcolor,glo,glocolor,mark,obsolete)
local keys = sortedkeys(t) -- no sorted_pairs
if #keys > 0 then
local fulltitle = title
@@ -269,7 +265,7 @@ local function show(title,subtitle,alias,builtin,t,lib,libcolor,glo,glocolor,mar
end
context.startcolumns { n = 2 }
context.starttabulate { "|||" }
- local t_obsolete = t.obsolete
+ local t_obsolete = rawget(t,"obsolete") -- tricky a t.obsolete fails
if type(t_obsolete) ~= "table" then
t_obsolete = nil
end
diff --git a/tex/generic/context/luatex/luatex-fonts-lig.lua b/tex/generic/context/luatex/luatex-fonts-lig.lua
new file mode 100644
index 000000000..c5347aa19
--- /dev/null
+++ b/tex/generic/context/luatex/luatex-fonts-lig.lua
@@ -0,0 +1,2067 @@
+-- this file is generated by context
+
+fonts.handlers.otf.addfeature {
+ ["dataset"]={
+ {
+ ["data"]={
+ ["À"]={ "A", "̀" },
+ ["Á"]={ "A", "́" },
+ ["Â"]={ "A", "̂" },
+ ["Ã"]={ "A", "̃" },
+ ["Ä"]={ "A", "̈" },
+ ["Å"]={ "A", "̊" },
+ ["Ç"]={ "C", "̧" },
+ ["È"]={ "E", "̀" },
+ ["É"]={ "E", "́" },
+ ["Ê"]={ "E", "̂" },
+ ["Ë"]={ "E", "̈" },
+ ["Ì"]={ "I", "̀" },
+ ["Í"]={ "I", "́" },
+ ["Î"]={ "I", "̂" },
+ ["Ï"]={ "I", "̈" },
+ ["Ñ"]={ "N", "̃" },
+ ["Ò"]={ "O", "̀" },
+ ["Ó"]={ "O", "́" },
+ ["Ô"]={ "O", "̂" },
+ ["Õ"]={ "O", "̃" },
+ ["Ö"]={ "O", "̈" },
+ ["Ù"]={ "U", "̀" },
+ ["Ú"]={ "U", "́" },
+ ["Û"]={ "U", "̂" },
+ ["Ü"]={ "U", "̈" },
+ ["Ý"]={ "Y", "́" },
+ ["à"]={ "a", "̀" },
+ ["á"]={ "a", "́" },
+ ["â"]={ "a", "̂" },
+ ["ã"]={ "a", "̃" },
+ ["ä"]={ "a", "̈" },
+ ["å"]={ "a", "̊" },
+ ["ç"]={ "c", "̧" },
+ ["è"]={ "e", "̀" },
+ ["é"]={ "e", "́" },
+ ["ê"]={ "e", "̂" },
+ ["ë"]={ "e", "̈" },
+ ["ì"]={ "i", "̀" },
+ ["í"]={ "i", "́" },
+ ["î"]={ "i", "̂" },
+ ["ï"]={ "i", "̈" },
+ ["ñ"]={ "n", "̃" },
+ ["ò"]={ "o", "̀" },
+ ["ó"]={ "o", "́" },
+ ["ô"]={ "o", "̂" },
+ ["õ"]={ "o", "̃" },
+ ["ö"]={ "o", "̈" },
+ ["ù"]={ "u", "̀" },
+ ["ú"]={ "u", "́" },
+ ["û"]={ "u", "̂" },
+ ["ü"]={ "u", "̈" },
+ ["ý"]={ "y", "́" },
+ ["ÿ"]={ "y", "̈" },
+ ["Ā"]={ "A", "̄" },
+ ["ā"]={ "a", "̄" },
+ ["Ă"]={ "A", "̆" },
+ ["ă"]={ "a", "̆" },
+ ["Ą"]={ "A", "̨" },
+ ["ą"]={ "a", "̨" },
+ ["Ć"]={ "C", "́" },
+ ["ć"]={ "c", "́" },
+ ["Ĉ"]={ "C", "̂" },
+ ["ĉ"]={ "c", "̂" },
+ ["Ċ"]={ "C", "̇" },
+ ["ċ"]={ "c", "̇" },
+ ["Č"]={ "C", "̌" },
+ ["č"]={ "c", "̌" },
+ ["Ď"]={ "D", "̌" },
+ ["ď"]={ "d", "̌" },
+ ["Ē"]={ "E", "̄" },
+ ["ē"]={ "e", "̄" },
+ ["Ĕ"]={ "E", "̆" },
+ ["ĕ"]={ "e", "̆" },
+ ["Ė"]={ "E", "̇" },
+ ["ė"]={ "e", "̇" },
+ ["Ę"]={ "E", "̨" },
+ ["ę"]={ "e", "̨" },
+ ["Ě"]={ "E", "̌" },
+ ["ě"]={ "e", "̌" },
+ ["Ĝ"]={ "G", "̂" },
+ ["ĝ"]={ "g", "̂" },
+ ["Ğ"]={ "G", "̆" },
+ ["ğ"]={ "g", "̆" },
+ ["Ġ"]={ "G", "̇" },
+ ["ġ"]={ "g", "̇" },
+ ["Ģ"]={ "G", "̧" },
+ ["ģ"]={ "g", "̧" },
+ ["Ĥ"]={ "H", "̂" },
+ ["ĥ"]={ "h", "̂" },
+ ["Ĩ"]={ "I", "̃" },
+ ["ĩ"]={ "i", "̃" },
+ ["Ī"]={ "I", "̄" },
+ ["ī"]={ "i", "̄" },
+ ["Ĭ"]={ "I", "̆" },
+ ["ĭ"]={ "i", "̆" },
+ ["Į"]={ "I", "̨" },
+ ["į"]={ "i", "̨" },
+ ["İ"]={ "I", "̇" },
+ ["Ĵ"]={ "J", "̂" },
+ ["ĵ"]={ "j", "̂" },
+ ["Ķ"]={ "K", "̧" },
+ ["ķ"]={ "k", "̧" },
+ ["Ĺ"]={ "L", "́" },
+ ["ĺ"]={ "l", "́" },
+ ["Ļ"]={ "L", "̧" },
+ ["ļ"]={ "l", "̧" },
+ ["Ľ"]={ "L", "̌" },
+ ["ľ"]={ "l", "̌" },
+ ["Ń"]={ "N", "́" },
+ ["ń"]={ "n", "́" },
+ ["Ņ"]={ "N", "̧" },
+ ["ņ"]={ "n", "̧" },
+ ["Ň"]={ "N", "̌" },
+ ["ň"]={ "n", "̌" },
+ ["Ō"]={ "O", "̄" },
+ ["ō"]={ "o", "̄" },
+ ["Ŏ"]={ "O", "̆" },
+ ["ŏ"]={ "o", "̆" },
+ ["Ő"]={ "O", "̋" },
+ ["ő"]={ "o", "̋" },
+ ["Ŕ"]={ "R", "́" },
+ ["ŕ"]={ "r", "́" },
+ ["Ŗ"]={ "R", "̧" },
+ ["ŗ"]={ "r", "̧" },
+ ["Ř"]={ "R", "̌" },
+ ["ř"]={ "r", "̌" },
+ ["Ś"]={ "S", "́" },
+ ["ś"]={ "s", "́" },
+ ["Ŝ"]={ "S", "̂" },
+ ["ŝ"]={ "s", "̂" },
+ ["Ş"]={ "S", "̧" },
+ ["ş"]={ "s", "̧" },
+ ["Š"]={ "S", "̌" },
+ ["š"]={ "s", "̌" },
+ ["Ţ"]={ "T", "̧" },
+ ["ţ"]={ "t", "̧" },
+ ["Ť"]={ "T", "̌" },
+ ["ť"]={ "t", "̌" },
+ ["Ũ"]={ "U", "̃" },
+ ["ũ"]={ "u", "̃" },
+ ["Ū"]={ "U", "̄" },
+ ["ū"]={ "u", "̄" },
+ ["Ŭ"]={ "U", "̆" },
+ ["ŭ"]={ "u", "̆" },
+ ["Ů"]={ "U", "̊" },
+ ["ů"]={ "u", "̊" },
+ ["Ű"]={ "U", "̋" },
+ ["ű"]={ "u", "̋" },
+ ["Ų"]={ "U", "̨" },
+ ["ų"]={ "u", "̨" },
+ ["Ŵ"]={ "W", "̂" },
+ ["ŵ"]={ "w", "̂" },
+ ["Ŷ"]={ "Y", "̂" },
+ ["ŷ"]={ "y", "̂" },
+ ["Ÿ"]={ "Y", "̈" },
+ ["Ź"]={ "Z", "́" },
+ ["ź"]={ "z", "́" },
+ ["Ż"]={ "Z", "̇" },
+ ["ż"]={ "z", "̇" },
+ ["Ž"]={ "Z", "̌" },
+ ["ž"]={ "z", "̌" },
+ ["Ơ"]={ "O", "̛" },
+ ["ơ"]={ "o", "̛" },
+ ["Ư"]={ "U", "̛" },
+ ["ư"]={ "u", "̛" },
+ ["Ǎ"]={ "A", "̌" },
+ ["ǎ"]={ "a", "̌" },
+ ["Ǐ"]={ "I", "̌" },
+ ["ǐ"]={ "i", "̌" },
+ ["Ǒ"]={ "O", "̌" },
+ ["ǒ"]={ "o", "̌" },
+ ["Ǔ"]={ "U", "̌" },
+ ["ǔ"]={ "u", "̌" },
+ ["Ǖ"]={ "Ü", "̄" },
+ ["ǖ"]={ "ü", "̄" },
+ ["Ǘ"]={ "Ü", "́" },
+ ["ǘ"]={ "ü", "́" },
+ ["Ǚ"]={ "Ü", "̌" },
+ ["ǚ"]={ "ü", "̌" },
+ ["Ǜ"]={ "Ü", "̀" },
+ ["ǜ"]={ "ü", "̀" },
+ ["Ǟ"]={ "Ä", "̄" },
+ ["ǟ"]={ "ä", "̄" },
+ ["Ǡ"]={ "Ȧ", "̄" },
+ ["ǡ"]={ "ȧ", "̄" },
+ ["Ǣ"]={ "Æ", "̄" },
+ ["ǣ"]={ "æ", "̄" },
+ ["Ǧ"]={ "G", "̌" },
+ ["ǧ"]={ "g", "̌" },
+ ["Ǩ"]={ "K", "̌" },
+ ["ǩ"]={ "k", "̌" },
+ ["Ǫ"]={ "O", "̨" },
+ ["ǫ"]={ "o", "̨" },
+ ["Ǭ"]={ "Ǫ", "̄" },
+ ["ǭ"]={ "ǫ", "̄" },
+ ["Ǯ"]={ "Ʒ", "̌" },
+ ["ǯ"]={ "ʒ", "̌" },
+ ["ǰ"]={ "j", "̌" },
+ ["Ǵ"]={ "G", "́" },
+ ["ǵ"]={ "g", "́" },
+ ["Ǹ"]={ "N", "̀" },
+ ["ǹ"]={ "n", "̀" },
+ ["Ǻ"]={ "Å", "́" },
+ ["ǻ"]={ "å", "́" },
+ ["Ǽ"]={ "Æ", "́" },
+ ["ǽ"]={ "æ", "́" },
+ ["Ǿ"]={ "Ø", "́" },
+ ["ǿ"]={ "ø", "́" },
+ ["Ȁ"]={ "A", "̏" },
+ ["ȁ"]={ "a", "̏" },
+ ["Ȃ"]={ "A", "̑" },
+ ["ȃ"]={ "a", "̑" },
+ ["Ȅ"]={ "E", "̏" },
+ ["ȅ"]={ "e", "̏" },
+ ["Ȇ"]={ "E", "̑" },
+ ["ȇ"]={ "e", "̑" },
+ ["Ȉ"]={ "I", "̏" },
+ ["ȉ"]={ "i", "̏" },
+ ["Ȋ"]={ "I", "̑" },
+ ["ȋ"]={ "i", "̑" },
+ ["Ȍ"]={ "O", "̏" },
+ ["ȍ"]={ "o", "̏" },
+ ["Ȏ"]={ "O", "̑" },
+ ["ȏ"]={ "o", "̑" },
+ ["Ȑ"]={ "R", "̏" },
+ ["ȑ"]={ "r", "̏" },
+ ["Ȓ"]={ "R", "̑" },
+ ["ȓ"]={ "r", "̑" },
+ ["Ȕ"]={ "U", "̏" },
+ ["ȕ"]={ "u", "̏" },
+ ["Ȗ"]={ "U", "̑" },
+ ["ȗ"]={ "u", "̑" },
+ ["Ș"]={ "S", "̦" },
+ ["ș"]={ "s", "̦" },
+ ["Ț"]={ "T", "̦" },
+ ["ț"]={ "t", "̦" },
+ ["Ȟ"]={ "H", "̌" },
+ ["ȟ"]={ "h", "̌" },
+ ["Ȧ"]={ "A", "̇" },
+ ["ȧ"]={ "a", "̇" },
+ ["Ȩ"]={ "E", "̧" },
+ ["ȩ"]={ "e", "̧" },
+ ["Ȫ"]={ "Ö", "̄" },
+ ["ȫ"]={ "ö", "̄" },
+ ["Ȭ"]={ "Õ", "̄" },
+ ["ȭ"]={ "õ", "̄" },
+ ["Ȯ"]={ "O", "̇" },
+ ["ȯ"]={ "o", "̇" },
+ ["Ȱ"]={ "Ȯ", "̄" },
+ ["ȱ"]={ "ȯ", "̄" },
+ ["Ȳ"]={ "Y", "̄" },
+ ["ȳ"]={ "y", "̄" },
+ ["̈́"]={ "̈", "́" },
+ ["΅"]={ "¨", "́" },
+ ["Ά"]={ "Α", "́" },
+ ["Έ"]={ "Ε", "́" },
+ ["Ή"]={ "Η", "́" },
+ ["Ί"]={ "Ι", "́" },
+ ["Ό"]={ "Ο", "́" },
+ ["Ύ"]={ "Υ", "́" },
+ ["Ώ"]={ "Ω", "́" },
+ ["ΐ"]={ "ϊ", "́" },
+ ["Ϊ"]={ "Ι", "̈" },
+ ["Ϋ"]={ "Υ", "̈" },
+ ["ά"]={ "α", "́" },
+ ["έ"]={ "ε", "́" },
+ ["ή"]={ "η", "́" },
+ ["ί"]={ "ι", "́" },
+ ["ΰ"]={ "ϋ", "́" },
+ ["ϊ"]={ "ι", "̈" },
+ ["ϋ"]={ "υ", "̈" },
+ ["ό"]={ "ο", "́" },
+ ["ύ"]={ "υ", "́" },
+ ["ώ"]={ "ω", "́" },
+ ["ϓ"]={ "ϒ", "́" },
+ ["ϔ"]={ "ϒ", "̈" },
+ ["Ѐ"]={ "Е", "̀" },
+ ["Ё"]={ "Е", "̈" },
+ ["Ѓ"]={ "Г", "́" },
+ ["Ї"]={ "І", "̈" },
+ ["Ќ"]={ "К", "́" },
+ ["Ѝ"]={ "И", "̀" },
+ ["Ў"]={ "У", "̆" },
+ ["Й"]={ "И", "̆" },
+ ["й"]={ "и", "̆" },
+ ["ѐ"]={ "е", "̀" },
+ ["ё"]={ "е", "̈" },
+ ["ѓ"]={ "г", "́" },
+ ["ї"]={ "і", "̈" },
+ ["ќ"]={ "к", "́" },
+ ["ѝ"]={ "и", "̀" },
+ ["ў"]={ "у", "̆" },
+ ["Ѷ"]={ "Ѵ", "̏" },
+ ["ѷ"]={ "ѵ", "̏" },
+ ["Ӂ"]={ "Ж", "̆" },
+ ["ӂ"]={ "ж", "̆" },
+ ["Ӑ"]={ "А", "̆" },
+ ["ӑ"]={ "а", "̆" },
+ ["Ӓ"]={ "А", "̈" },
+ ["ӓ"]={ "а", "̈" },
+ ["Ӗ"]={ "Е", "̆" },
+ ["ӗ"]={ "е", "̆" },
+ ["Ӛ"]={ "Ә", "̈" },
+ ["ӛ"]={ "ә", "̈" },
+ ["Ӝ"]={ "Ж", "̈" },
+ ["ӝ"]={ "ж", "̈" },
+ ["Ӟ"]={ "З", "̈" },
+ ["ӟ"]={ "з", "̈" },
+ ["Ӣ"]={ "И", "̄" },
+ ["ӣ"]={ "и", "̄" },
+ ["Ӥ"]={ "И", "̈" },
+ ["ӥ"]={ "и", "̈" },
+ ["Ӧ"]={ "О", "̈" },
+ ["ӧ"]={ "о", "̈" },
+ ["Ӫ"]={ "Ө", "̈" },
+ ["ӫ"]={ "ө", "̈" },
+ ["Ӭ"]={ "Э", "̈" },
+ ["ӭ"]={ "э", "̈" },
+ ["Ӯ"]={ "У", "̄" },
+ ["ӯ"]={ "у", "̄" },
+ ["Ӱ"]={ "У", "̈" },
+ ["ӱ"]={ "у", "̈" },
+ ["Ӳ"]={ "У", "̋" },
+ ["ӳ"]={ "у", "̋" },
+ ["Ӵ"]={ "Ч", "̈" },
+ ["ӵ"]={ "ч", "̈" },
+ ["Ӹ"]={ "Ы", "̈" },
+ ["ӹ"]={ "ы", "̈" },
+ ["آ"]={ "ا", "ٓ" },
+ ["أ"]={ "ا", "ٔ" },
+ ["ؤ"]={ "و", "ٔ" },
+ ["إ"]={ "ا", "ٕ" },
+ ["ئ"]={ "ي", "ٔ" },
+ ["ۀ"]={ "ە", "ٔ" },
+ ["ۂ"]={ "ہ", "ٔ" },
+ ["ۓ"]={ "ے", "ٔ" },
+ ["ऩ"]={ "न", "़" },
+ ["ऱ"]={ "र", "़" },
+ ["ऴ"]={ "ळ", "़" },
+ ["क़"]={ "क", "़" },
+ ["ख़"]={ "ख", "़" },
+ ["ग़"]={ "ग", "़" },
+ ["ज़"]={ "ज", "़" },
+ ["ड़"]={ "ड", "़" },
+ ["ढ़"]={ "ढ", "़" },
+ ["फ़"]={ "फ", "़" },
+ ["य़"]={ "य", "़" },
+ ["ো"]={ "ে", "া" },
+ ["ৌ"]={ "ে", "ৗ" },
+ ["ড়"]={ "ড", "়" },
+ ["ঢ়"]={ "ঢ", "়" },
+ ["য়"]={ "য", "়" },
+ ["ਲ਼"]={ "ਲ", "਼" },
+ ["ਸ਼"]={ "ਸ", "਼" },
+ ["ਖ਼"]={ "ਖ", "਼" },
+ ["ਗ਼"]={ "ਗ", "਼" },
+ ["ਜ਼"]={ "ਜ", "਼" },
+ ["ਫ਼"]={ "ਫ", "਼" },
+ ["ୈ"]={ "େ", "ୖ" },
+ ["ୋ"]={ "େ", "ା" },
+ ["ୌ"]={ "େ", "ୗ" },
+ ["ଡ଼"]={ "ଡ", "଼" },
+ ["ଢ଼"]={ "ଢ", "଼" },
+ ["ஔ"]={ "ஒ", "ௗ" },
+ ["ொ"]={ "ெ", "ா" },
+ ["ோ"]={ "ே", "ா" },
+ ["ௌ"]={ "ெ", "ௗ" },
+ ["ై"]={ "ె", "ౖ" },
+ ["ೀ"]={ "ಿ", "ೕ" },
+ ["ೇ"]={ "ೆ", "ೕ" },
+ ["ೈ"]={ "ೆ", "ೖ" },
+ ["ೊ"]={ "ೆ", "ೂ" },
+ ["ೋ"]={ "ೊ", "ೕ" },
+ ["ൊ"]={ "െ", "ാ" },
+ ["ോ"]={ "േ", "ാ" },
+ ["ൌ"]={ "െ", "ൗ" },
+ ["ේ"]={ "ෙ", "්" },
+ ["ො"]={ "ෙ", "ා" },
+ ["ෝ"]={ "ො", "්" },
+ ["ෞ"]={ "ෙ", "ෟ" },
+ ["གྷ"]={ "ག", "ྷ" },
+ ["ཌྷ"]={ "ཌ", "ྷ" },
+ ["དྷ"]={ "ད", "ྷ" },
+ ["བྷ"]={ "བ", "ྷ" },
+ ["ཛྷ"]={ "ཛ", "ྷ" },
+ ["ཀྵ"]={ "ཀ", "ྵ" },
+ ["ཱི"]={ "ཱ", "ི" },
+ ["ཱུ"]={ "ཱ", "ུ" },
+ ["ྲྀ"]={ "ྲ", "ྀ" },
+ ["ླྀ"]={ "ླ", "ྀ" },
+ ["ཱྀ"]={ "ཱ", "ྀ" },
+ ["ྒྷ"]={ "ྒ", "ྷ" },
+ ["ྜྷ"]={ "ྜ", "ྷ" },
+ ["ྡྷ"]={ "ྡ", "ྷ" },
+ ["ྦྷ"]={ "ྦ", "ྷ" },
+ ["ྫྷ"]={ "ྫ", "ྷ" },
+ ["ྐྵ"]={ "ྐ", "ྵ" },
+ ["ဦ"]={ "ဥ", "ီ" },
+ ["ᬆ"]={ "ᬅ", "ᬵ" },
+ ["ᬈ"]={ "ᬇ", "ᬵ" },
+ ["ᬊ"]={ "ᬉ", "ᬵ" },
+ ["ᬌ"]={ "ᬋ", "ᬵ" },
+ ["ᬎ"]={ "ᬍ", "ᬵ" },
+ ["ᬒ"]={ "ᬑ", "ᬵ" },
+ ["ᬻ"]={ "ᬺ", "ᬵ" },
+ ["ᬽ"]={ "ᬼ", "ᬵ" },
+ ["ᭀ"]={ "ᬾ", "ᬵ" },
+ ["ᭁ"]={ "ᬿ", "ᬵ" },
+ ["ᭃ"]={ "ᭂ", "ᬵ" },
+ ["Ḁ"]={ "A", "̥" },
+ ["ḁ"]={ "a", "̥" },
+ ["Ḃ"]={ "B", "̇" },
+ ["ḃ"]={ "b", "̇" },
+ ["Ḅ"]={ "B", "̣" },
+ ["ḅ"]={ "b", "̣" },
+ ["Ḇ"]={ "B", "̱" },
+ ["ḇ"]={ "b", "̱" },
+ ["Ḉ"]={ "Ç", "́" },
+ ["ḉ"]={ "ç", "́" },
+ ["Ḋ"]={ "D", "̇" },
+ ["ḋ"]={ "d", "̇" },
+ ["Ḍ"]={ "D", "̣" },
+ ["ḍ"]={ "d", "̣" },
+ ["Ḏ"]={ "D", "̱" },
+ ["ḏ"]={ "d", "̱" },
+ ["Ḑ"]={ "D", "̧" },
+ ["ḑ"]={ "d", "̧" },
+ ["Ḓ"]={ "D", "̭" },
+ ["ḓ"]={ "d", "̭" },
+ ["Ḕ"]={ "Ē", "̀" },
+ ["ḕ"]={ "ē", "̀" },
+ ["Ḗ"]={ "Ē", "́" },
+ ["ḗ"]={ "ē", "́" },
+ ["Ḙ"]={ "E", "̭" },
+ ["ḙ"]={ "e", "̭" },
+ ["Ḛ"]={ "E", "̰" },
+ ["ḛ"]={ "e", "̰" },
+ ["Ḝ"]={ "Ȩ", "̆" },
+ ["ḝ"]={ "ȩ", "̆" },
+ ["Ḟ"]={ "F", "̇" },
+ ["ḟ"]={ "f", "̇" },
+ ["Ḡ"]={ "G", "̄" },
+ ["ḡ"]={ "g", "̄" },
+ ["Ḣ"]={ "H", "̇" },
+ ["ḣ"]={ "h", "̇" },
+ ["Ḥ"]={ "H", "̣" },
+ ["ḥ"]={ "h", "̣" },
+ ["Ḧ"]={ "H", "̈" },
+ ["ḧ"]={ "h", "̈" },
+ ["Ḩ"]={ "H", "̧" },
+ ["ḩ"]={ "h", "̧" },
+ ["Ḫ"]={ "H", "̮" },
+ ["ḫ"]={ "h", "̮" },
+ ["Ḭ"]={ "I", "̰" },
+ ["ḭ"]={ "i", "̰" },
+ ["Ḯ"]={ "Ï", "́" },
+ ["ḯ"]={ "ï", "́" },
+ ["Ḱ"]={ "K", "́" },
+ ["ḱ"]={ "k", "́" },
+ ["Ḳ"]={ "K", "̣" },
+ ["ḳ"]={ "k", "̣" },
+ ["Ḵ"]={ "K", "̱" },
+ ["ḵ"]={ "k", "̱" },
+ ["Ḷ"]={ "L", "̣" },
+ ["ḷ"]={ "l", "̣" },
+ ["Ḹ"]={ "Ḷ", "̄" },
+ ["ḹ"]={ "ḷ", "̄" },
+ ["Ḻ"]={ "L", "̱" },
+ ["ḻ"]={ "l", "̱" },
+ ["Ḽ"]={ "L", "̭" },
+ ["ḽ"]={ "l", "̭" },
+ ["Ḿ"]={ "M", "́" },
+ ["ḿ"]={ "m", "́" },
+ ["Ṁ"]={ "M", "̇" },
+ ["ṁ"]={ "m", "̇" },
+ ["Ṃ"]={ "M", "̣" },
+ ["ṃ"]={ "m", "̣" },
+ ["Ṅ"]={ "N", "̇" },
+ ["ṅ"]={ "n", "̇" },
+ ["Ṇ"]={ "N", "̣" },
+ ["ṇ"]={ "n", "̣" },
+ ["Ṉ"]={ "N", "̱" },
+ ["ṉ"]={ "n", "̱" },
+ ["Ṋ"]={ "N", "̭" },
+ ["ṋ"]={ "n", "̭" },
+ ["Ṍ"]={ "Õ", "́" },
+ ["ṍ"]={ "õ", "́" },
+ ["Ṏ"]={ "Õ", "̈" },
+ ["ṏ"]={ "õ", "̈" },
+ ["Ṑ"]={ "Ō", "̀" },
+ ["ṑ"]={ "ō", "̀" },
+ ["Ṓ"]={ "Ō", "́" },
+ ["ṓ"]={ "ō", "́" },
+ ["Ṕ"]={ "P", "́" },
+ ["ṕ"]={ "p", "́" },
+ ["Ṗ"]={ "P", "̇" },
+ ["ṗ"]={ "p", "̇" },
+ ["Ṙ"]={ "R", "̇" },
+ ["ṙ"]={ "r", "̇" },
+ ["Ṛ"]={ "R", "̣" },
+ ["ṛ"]={ "r", "̣" },
+ ["Ṝ"]={ "Ṛ", "̄" },
+ ["ṝ"]={ "ṛ", "̄" },
+ ["Ṟ"]={ "R", "̱" },
+ ["ṟ"]={ "r", "̱" },
+ ["Ṡ"]={ "S", "̇" },
+ ["ṡ"]={ "s", "̇" },
+ ["Ṣ"]={ "S", "̣" },
+ ["ṣ"]={ "s", "̣" },
+ ["Ṥ"]={ "Ś", "̇" },
+ ["ṥ"]={ "ś", "̇" },
+ ["Ṧ"]={ "Š", "̇" },
+ ["ṧ"]={ "š", "̇" },
+ ["Ṩ"]={ "Ṣ", "̇" },
+ ["ṩ"]={ "ṣ", "̇" },
+ ["Ṫ"]={ "T", "̇" },
+ ["ṫ"]={ "t", "̇" },
+ ["Ṭ"]={ "T", "̣" },
+ ["ṭ"]={ "t", "̣" },
+ ["Ṯ"]={ "T", "̱" },
+ ["ṯ"]={ "t", "̱" },
+ ["Ṱ"]={ "T", "̭" },
+ ["ṱ"]={ "t", "̭" },
+ ["Ṳ"]={ "U", "̤" },
+ ["ṳ"]={ "u", "̤" },
+ ["Ṵ"]={ "U", "̰" },
+ ["ṵ"]={ "u", "̰" },
+ ["Ṷ"]={ "U", "̭" },
+ ["ṷ"]={ "u", "̭" },
+ ["Ṹ"]={ "Ũ", "́" },
+ ["ṹ"]={ "ũ", "́" },
+ ["Ṻ"]={ "Ū", "̈" },
+ ["ṻ"]={ "ū", "̈" },
+ ["Ṽ"]={ "V", "̃" },
+ ["ṽ"]={ "v", "̃" },
+ ["Ṿ"]={ "V", "̣" },
+ ["ṿ"]={ "v", "̣" },
+ ["Ẁ"]={ "W", "̀" },
+ ["ẁ"]={ "w", "̀" },
+ ["Ẃ"]={ "W", "́" },
+ ["ẃ"]={ "w", "́" },
+ ["Ẅ"]={ "W", "̈" },
+ ["ẅ"]={ "w", "̈" },
+ ["Ẇ"]={ "W", "̇" },
+ ["ẇ"]={ "w", "̇" },
+ ["Ẉ"]={ "W", "̣" },
+ ["ẉ"]={ "w", "̣" },
+ ["Ẋ"]={ "X", "̇" },
+ ["ẋ"]={ "x", "̇" },
+ ["Ẍ"]={ "X", "̈" },
+ ["ẍ"]={ "x", "̈" },
+ ["Ẏ"]={ "Y", "̇" },
+ ["ẏ"]={ "y", "̇" },
+ ["Ẑ"]={ "Z", "̂" },
+ ["ẑ"]={ "z", "̂" },
+ ["Ẓ"]={ "Z", "̣" },
+ ["ẓ"]={ "z", "̣" },
+ ["Ẕ"]={ "Z", "̱" },
+ ["ẕ"]={ "z", "̱" },
+ ["ẖ"]={ "h", "̱" },
+ ["ẗ"]={ "t", "̈" },
+ ["ẘ"]={ "w", "̊" },
+ ["ẙ"]={ "y", "̊" },
+ ["ẛ"]={ "ſ", "̇" },
+ ["Ạ"]={ "A", "̣" },
+ ["ạ"]={ "a", "̣" },
+ ["Ả"]={ "A", "̉" },
+ ["ả"]={ "a", "̉" },
+ ["Ấ"]={ "Â", "́" },
+ ["ấ"]={ "â", "́" },
+ ["Ầ"]={ "Â", "̀" },
+ ["ầ"]={ "â", "̀" },
+ ["Ẩ"]={ "Â", "̉" },
+ ["ẩ"]={ "â", "̉" },
+ ["Ẫ"]={ "Â", "̃" },
+ ["ẫ"]={ "â", "̃" },
+ ["Ậ"]={ "Ạ", "̂" },
+ ["ậ"]={ "ạ", "̂" },
+ ["Ắ"]={ "Ă", "́" },
+ ["ắ"]={ "ă", "́" },
+ ["Ằ"]={ "Ă", "̀" },
+ ["ằ"]={ "ă", "̀" },
+ ["Ẳ"]={ "Ă", "̉" },
+ ["ẳ"]={ "ă", "̉" },
+ ["Ẵ"]={ "Ă", "̃" },
+ ["ẵ"]={ "ă", "̃" },
+ ["Ặ"]={ "Ạ", "̆" },
+ ["ặ"]={ "ạ", "̆" },
+ ["Ẹ"]={ "E", "̣" },
+ ["ẹ"]={ "e", "̣" },
+ ["Ẻ"]={ "E", "̉" },
+ ["ẻ"]={ "e", "̉" },
+ ["Ẽ"]={ "E", "̃" },
+ ["ẽ"]={ "e", "̃" },
+ ["Ế"]={ "Ê", "́" },
+ ["ế"]={ "ê", "́" },
+ ["Ề"]={ "Ê", "̀" },
+ ["ề"]={ "ê", "̀" },
+ ["Ể"]={ "Ê", "̉" },
+ ["ể"]={ "ê", "̉" },
+ ["Ễ"]={ "Ê", "̃" },
+ ["ễ"]={ "ê", "̃" },
+ ["Ệ"]={ "Ẹ", "̂" },
+ ["ệ"]={ "ẹ", "̂" },
+ ["Ỉ"]={ "I", "̉" },
+ ["ỉ"]={ "i", "̉" },
+ ["Ị"]={ "I", "̣" },
+ ["ị"]={ "i", "̣" },
+ ["Ọ"]={ "O", "̣" },
+ ["ọ"]={ "o", "̣" },
+ ["Ỏ"]={ "O", "̉" },
+ ["ỏ"]={ "o", "̉" },
+ ["Ố"]={ "Ô", "́" },
+ ["ố"]={ "ô", "́" },
+ ["Ồ"]={ "Ô", "̀" },
+ ["ồ"]={ "ô", "̀" },
+ ["Ổ"]={ "Ô", "̉" },
+ ["ổ"]={ "ô", "̉" },
+ ["Ỗ"]={ "Ô", "̃" },
+ ["ỗ"]={ "ô", "̃" },
+ ["Ộ"]={ "Ọ", "̂" },
+ ["ộ"]={ "ọ", "̂" },
+ ["Ớ"]={ "Ơ", "́" },
+ ["ớ"]={ "ơ", "́" },
+ ["Ờ"]={ "Ơ", "̀" },
+ ["ờ"]={ "ơ", "̀" },
+ ["Ở"]={ "Ơ", "̉" },
+ ["ở"]={ "ơ", "̉" },
+ ["Ỡ"]={ "Ơ", "̃" },
+ ["ỡ"]={ "ơ", "̃" },
+ ["Ợ"]={ "Ơ", "̣" },
+ ["ợ"]={ "ơ", "̣" },
+ ["Ụ"]={ "U", "̣" },
+ ["ụ"]={ "u", "̣" },
+ ["Ủ"]={ "U", "̉" },
+ ["ủ"]={ "u", "̉" },
+ ["Ứ"]={ "Ư", "́" },
+ ["ứ"]={ "ư", "́" },
+ ["Ừ"]={ "Ư", "̀" },
+ ["ừ"]={ "ư", "̀" },
+ ["Ử"]={ "Ư", "̉" },
+ ["ử"]={ "ư", "̉" },
+ ["Ữ"]={ "Ư", "̃" },
+ ["ữ"]={ "ư", "̃" },
+ ["Ự"]={ "Ư", "̣" },
+ ["ự"]={ "ư", "̣" },
+ ["Ỳ"]={ "Y", "̀" },
+ ["ỳ"]={ "y", "̀" },
+ ["Ỵ"]={ "Y", "̣" },
+ ["ỵ"]={ "y", "̣" },
+ ["Ỷ"]={ "Y", "̉" },
+ ["ỷ"]={ "y", "̉" },
+ ["Ỹ"]={ "Y", "̃" },
+ ["ỹ"]={ "y", "̃" },
+ ["ἀ"]={ "α", "̓" },
+ ["ἁ"]={ "α", "̔" },
+ ["ἂ"]={ "ἀ", "̀" },
+ ["ἃ"]={ "ἁ", "̀" },
+ ["ἄ"]={ "ἀ", "́" },
+ ["ἅ"]={ "ἁ", "́" },
+ ["ἆ"]={ "ἀ", "͂" },
+ ["ἇ"]={ "ἁ", "͂" },
+ ["Ἀ"]={ "Α", "̓" },
+ ["Ἁ"]={ "Α", "̔" },
+ ["Ἂ"]={ "Ἀ", "̀" },
+ ["Ἃ"]={ "Ἁ", "̀" },
+ ["Ἄ"]={ "Ἀ", "́" },
+ ["Ἅ"]={ "Ἁ", "́" },
+ ["Ἆ"]={ "Ἀ", "͂" },
+ ["Ἇ"]={ "Ἁ", "͂" },
+ ["ἐ"]={ "ε", "̓" },
+ ["ἑ"]={ "ε", "̔" },
+ ["ἒ"]={ "ἐ", "̀" },
+ ["ἓ"]={ "ἑ", "̀" },
+ ["ἔ"]={ "ἐ", "́" },
+ ["ἕ"]={ "ἑ", "́" },
+ ["Ἐ"]={ "Ε", "̓" },
+ ["Ἑ"]={ "Ε", "̔" },
+ ["Ἒ"]={ "Ἐ", "̀" },
+ ["Ἓ"]={ "Ἑ", "̀" },
+ ["Ἔ"]={ "Ἐ", "́" },
+ ["Ἕ"]={ "Ἑ", "́" },
+ ["ἠ"]={ "η", "̓" },
+ ["ἡ"]={ "η", "̔" },
+ ["ἢ"]={ "ἠ", "̀" },
+ ["ἣ"]={ "ἡ", "̀" },
+ ["ἤ"]={ "ἠ", "́" },
+ ["ἥ"]={ "ἡ", "́" },
+ ["ἦ"]={ "ἠ", "͂" },
+ ["ἧ"]={ "ἡ", "͂" },
+ ["Ἠ"]={ "Η", "̓" },
+ ["Ἡ"]={ "Η", "̔" },
+ ["Ἢ"]={ "Ἠ", "̀" },
+ ["Ἣ"]={ "Ἡ", "̀" },
+ ["Ἤ"]={ "Ἠ", "́" },
+ ["Ἥ"]={ "Ἡ", "́" },
+ ["Ἦ"]={ "Ἠ", "͂" },
+ ["Ἧ"]={ "Ἡ", "͂" },
+ ["ἰ"]={ "ι", "̓" },
+ ["ἱ"]={ "ι", "̔" },
+ ["ἲ"]={ "ἰ", "̀" },
+ ["ἳ"]={ "ἱ", "̀" },
+ ["ἴ"]={ "ἰ", "́" },
+ ["ἵ"]={ "ἱ", "́" },
+ ["ἶ"]={ "ἰ", "͂" },
+ ["ἷ"]={ "ἱ", "͂" },
+ ["Ἰ"]={ "Ι", "̓" },
+ ["Ἱ"]={ "Ι", "̔" },
+ ["Ἲ"]={ "Ἰ", "̀" },
+ ["Ἳ"]={ "Ἱ", "̀" },
+ ["Ἴ"]={ "Ἰ", "́" },
+ ["Ἵ"]={ "Ἱ", "́" },
+ ["Ἶ"]={ "Ἰ", "͂" },
+ ["Ἷ"]={ "Ἱ", "͂" },
+ ["ὀ"]={ "ο", "̓" },
+ ["ὁ"]={ "ο", "̔" },
+ ["ὂ"]={ "ὀ", "̀" },
+ ["ὃ"]={ "ὁ", "̀" },
+ ["ὄ"]={ "ὀ", "́" },
+ ["ὅ"]={ "ὁ", "́" },
+ ["Ὀ"]={ "Ο", "̓" },
+ ["Ὁ"]={ "Ο", "̔" },
+ ["Ὂ"]={ "Ὀ", "̀" },
+ ["Ὃ"]={ "Ὁ", "̀" },
+ ["Ὄ"]={ "Ὀ", "́" },
+ ["Ὅ"]={ "Ὁ", "́" },
+ ["ὐ"]={ "υ", "̓" },
+ ["ὑ"]={ "υ", "̔" },
+ ["ὒ"]={ "ὐ", "̀" },
+ ["ὓ"]={ "ὑ", "̀" },
+ ["ὔ"]={ "ὐ", "́" },
+ ["ὕ"]={ "ὑ", "́" },
+ ["ὖ"]={ "ὐ", "͂" },
+ ["ὗ"]={ "ὑ", "͂" },
+ ["Ὑ"]={ "Υ", "̔" },
+ ["Ὓ"]={ "Ὑ", "̀" },
+ ["Ὕ"]={ "Ὑ", "́" },
+ ["Ὗ"]={ "Ὑ", "͂" },
+ ["ὠ"]={ "ω", "̓" },
+ ["ὡ"]={ "ω", "̔" },
+ ["ὢ"]={ "ὠ", "̀" },
+ ["ὣ"]={ "ὡ", "̀" },
+ ["ὤ"]={ "ὠ", "́" },
+ ["ὥ"]={ "ὡ", "́" },
+ ["ὦ"]={ "ὠ", "͂" },
+ ["ὧ"]={ "ὡ", "͂" },
+ ["Ὠ"]={ "Ω", "̓" },
+ ["Ὡ"]={ "Ω", "̔" },
+ ["Ὢ"]={ "Ὠ", "̀" },
+ ["Ὣ"]={ "Ὡ", "̀" },
+ ["Ὤ"]={ "Ὠ", "́" },
+ ["Ὥ"]={ "Ὡ", "́" },
+ ["Ὦ"]={ "Ὠ", "͂" },
+ ["Ὧ"]={ "Ὡ", "͂" },
+ ["ὰ"]={ "α", "̀" },
+ ["ὲ"]={ "ε", "̀" },
+ ["ὴ"]={ "η", "̀" },
+ ["ὶ"]={ "ι", "̀" },
+ ["ὸ"]={ "ο", "̀" },
+ ["ὺ"]={ "υ", "̀" },
+ ["ὼ"]={ "ω", "̀" },
+ ["ᾀ"]={ "ἀ", "ͅ" },
+ ["ᾁ"]={ "ἁ", "ͅ" },
+ ["ᾂ"]={ "ἂ", "ͅ" },
+ ["ᾃ"]={ "ἃ", "ͅ" },
+ ["ᾄ"]={ "ἄ", "ͅ" },
+ ["ᾅ"]={ "ἅ", "ͅ" },
+ ["ᾆ"]={ "ἆ", "ͅ" },
+ ["ᾇ"]={ "ἇ", "ͅ" },
+ ["ᾈ"]={ "Ἀ", "ͅ" },
+ ["ᾉ"]={ "Ἁ", "ͅ" },
+ ["ᾊ"]={ "Ἂ", "ͅ" },
+ ["ᾋ"]={ "Ἃ", "ͅ" },
+ ["ᾌ"]={ "Ἄ", "ͅ" },
+ ["ᾍ"]={ "Ἅ", "ͅ" },
+ ["ᾎ"]={ "Ἆ", "ͅ" },
+ ["ᾏ"]={ "Ἇ", "ͅ" },
+ ["ᾐ"]={ "ἠ", "ͅ" },
+ ["ᾑ"]={ "ἡ", "ͅ" },
+ ["ᾒ"]={ "ἢ", "ͅ" },
+ ["ᾓ"]={ "ἣ", "ͅ" },
+ ["ᾔ"]={ "ἤ", "ͅ" },
+ ["ᾕ"]={ "ἥ", "ͅ" },
+ ["ᾖ"]={ "ἦ", "ͅ" },
+ ["ᾗ"]={ "ἧ", "ͅ" },
+ ["ᾘ"]={ "Ἠ", "ͅ" },
+ ["ᾙ"]={ "Ἡ", "ͅ" },
+ ["ᾚ"]={ "Ἢ", "ͅ" },
+ ["ᾛ"]={ "Ἣ", "ͅ" },
+ ["ᾜ"]={ "Ἤ", "ͅ" },
+ ["ᾝ"]={ "Ἥ", "ͅ" },
+ ["ᾞ"]={ "Ἦ", "ͅ" },
+ ["ᾟ"]={ "Ἧ", "ͅ" },
+ ["ᾠ"]={ "ὠ", "ͅ" },
+ ["ᾡ"]={ "ὡ", "ͅ" },
+ ["ᾢ"]={ "ὢ", "ͅ" },
+ ["ᾣ"]={ "ὣ", "ͅ" },
+ ["ᾤ"]={ "ὤ", "ͅ" },
+ ["ᾥ"]={ "ὥ", "ͅ" },
+ ["ᾦ"]={ "ὦ", "ͅ" },
+ ["ᾧ"]={ "ὧ", "ͅ" },
+ ["ᾨ"]={ "Ὠ", "ͅ" },
+ ["ᾩ"]={ "Ὡ", "ͅ" },
+ ["ᾪ"]={ "Ὢ", "ͅ" },
+ ["ᾫ"]={ "Ὣ", "ͅ" },
+ ["ᾬ"]={ "Ὤ", "ͅ" },
+ ["ᾭ"]={ "Ὥ", "ͅ" },
+ ["ᾮ"]={ "Ὦ", "ͅ" },
+ ["ᾯ"]={ "Ὧ", "ͅ" },
+ ["ᾰ"]={ "α", "̆" },
+ ["ᾱ"]={ "α", "̄" },
+ ["ᾲ"]={ "ὰ", "ͅ" },
+ ["ᾳ"]={ "α", "ͅ" },
+ ["ᾴ"]={ "ά", "ͅ" },
+ ["ᾶ"]={ "α", "͂" },
+ ["ᾷ"]={ "ᾶ", "ͅ" },
+ ["Ᾰ"]={ "Α", "̆" },
+ ["Ᾱ"]={ "Α", "̄" },
+ ["Ὰ"]={ "Α", "̀" },
+ ["ᾼ"]={ "Α", "ͅ" },
+ ["῁"]={ "¨", "͂" },
+ ["ῂ"]={ "ὴ", "ͅ" },
+ ["ῃ"]={ "η", "ͅ" },
+ ["ῄ"]={ "ή", "ͅ" },
+ ["ῆ"]={ "η", "͂" },
+ ["ῇ"]={ "ῆ", "ͅ" },
+ ["Ὲ"]={ "Ε", "̀" },
+ ["Ὴ"]={ "Η", "̀" },
+ ["ῌ"]={ "Η", "ͅ" },
+ ["῍"]={ "᾿", "̀" },
+ ["῎"]={ "᾿", "́" },
+ ["῏"]={ "᾿", "͂" },
+ ["ῐ"]={ "ι", "̆" },
+ ["ῑ"]={ "ι", "̄" },
+ ["ῒ"]={ "ϊ", "̀" },
+ ["ῖ"]={ "ι", "͂" },
+ ["ῗ"]={ "ϊ", "͂" },
+ ["Ῐ"]={ "Ι", "̆" },
+ ["Ῑ"]={ "Ι", "̄" },
+ ["Ὶ"]={ "Ι", "̀" },
+ ["῝"]={ "῾", "̀" },
+ ["῞"]={ "῾", "́" },
+ ["῟"]={ "῾", "͂" },
+ ["ῠ"]={ "υ", "̆" },
+ ["ῡ"]={ "υ", "̄" },
+ ["ῢ"]={ "ϋ", "̀" },
+ ["ῤ"]={ "ρ", "̓" },
+ ["ῥ"]={ "ρ", "̔" },
+ ["ῦ"]={ "υ", "͂" },
+ ["ῧ"]={ "ϋ", "͂" },
+ ["Ῠ"]={ "Υ", "̆" },
+ ["Ῡ"]={ "Υ", "̄" },
+ ["Ὺ"]={ "Υ", "̀" },
+ ["Ῥ"]={ "Ρ", "̔" },
+ ["῭"]={ "¨", "̀" },
+ ["ῲ"]={ "ὼ", "ͅ" },
+ ["ῳ"]={ "ω", "ͅ" },
+ ["ῴ"]={ "ώ", "ͅ" },
+ ["ῶ"]={ "ω", "͂" },
+ ["ῷ"]={ "ῶ", "ͅ" },
+ ["Ὸ"]={ "Ο", "̀" },
+ ["Ὼ"]={ "Ω", "̀" },
+ ["ῼ"]={ "Ω", "ͅ" },
+ ["↚"]={ "←", "̸" },
+ ["↛"]={ "→", "̸" },
+ ["↮"]={ "↔", "̸" },
+ ["⇍"]={ "⇐", "̸" },
+ ["⇎"]={ "⇔", "̸" },
+ ["⇏"]={ "⇒", "̸" },
+ ["∄"]={ "∃", "̸" },
+ ["∉"]={ "∈", "̸" },
+ ["∌"]={ "∋", "̸" },
+ ["∤"]={ "∣", "̸" },
+ ["∦"]={ "∥", "̸" },
+ ["≁"]={ "∼", "̸" },
+ ["≄"]={ "≃", "̸" },
+ ["≇"]={ "≅", "̸" },
+ ["≉"]={ "≈", "̸" },
+ ["≠"]={ "=", "̸" },
+ ["≢"]={ "≡", "̸" },
+ ["≭"]={ "≍", "̸" },
+ ["≮"]={ "<", "̸" },
+ ["≯"]={ ">", "̸" },
+ ["≰"]={ "≤", "̸" },
+ ["≱"]={ "≥", "̸" },
+ ["≴"]={ "≲", "̸" },
+ ["≵"]={ "≳", "̸" },
+ ["≸"]={ "≶", "̸" },
+ ["≹"]={ "≷", "̸" },
+ ["⊀"]={ "≺", "̸" },
+ ["⊁"]={ "≻", "̸" },
+ ["⊄"]={ "⊂", "̸" },
+ ["⊅"]={ "⊃", "̸" },
+ ["⊈"]={ "⊆", "̸" },
+ ["⊉"]={ "⊇", "̸" },
+ ["⊬"]={ "⊢", "̸" },
+ ["⊭"]={ "⊨", "̸" },
+ ["⊮"]={ "⊩", "̸" },
+ ["⊯"]={ "⊫", "̸" },
+ ["⋠"]={ "≼", "̸" },
+ ["⋡"]={ "≽", "̸" },
+ ["⋢"]={ "⊑", "̸" },
+ ["⋣"]={ "⊒", "̸" },
+ ["⋪"]={ "⊲", "̸" },
+ ["⋫"]={ "⊳", "̸" },
+ ["⋬"]={ "⊴", "̸" },
+ ["⋭"]={ "⊵", "̸" },
+ ["⫝̸"]={ "⫝", "̸" },
+ ["が"]={ "か", "゙" },
+ ["ぎ"]={ "き", "゙" },
+ ["ぐ"]={ "く", "゙" },
+ ["げ"]={ "け", "゙" },
+ ["ご"]={ "こ", "゙" },
+ ["ざ"]={ "さ", "゙" },
+ ["じ"]={ "し", "゙" },
+ ["ず"]={ "す", "゙" },
+ ["ぜ"]={ "せ", "゙" },
+ ["ぞ"]={ "そ", "゙" },
+ ["だ"]={ "た", "゙" },
+ ["ぢ"]={ "ち", "゙" },
+ ["づ"]={ "つ", "゙" },
+ ["で"]={ "て", "゙" },
+ ["ど"]={ "と", "゙" },
+ ["ば"]={ "は", "゙" },
+ ["ぱ"]={ "は", "゚" },
+ ["び"]={ "ひ", "゙" },
+ ["ぴ"]={ "ひ", "゚" },
+ ["ぶ"]={ "ふ", "゙" },
+ ["ぷ"]={ "ふ", "゚" },
+ ["べ"]={ "へ", "゙" },
+ ["ぺ"]={ "へ", "゚" },
+ ["ぼ"]={ "ほ", "゙" },
+ ["ぽ"]={ "ほ", "゚" },
+ ["ゔ"]={ "う", "゙" },
+ ["ゞ"]={ "ゝ", "゙" },
+ ["ガ"]={ "カ", "゙" },
+ ["ギ"]={ "キ", "゙" },
+ ["グ"]={ "ク", "゙" },
+ ["ゲ"]={ "ケ", "゙" },
+ ["ゴ"]={ "コ", "゙" },
+ ["ザ"]={ "サ", "゙" },
+ ["ジ"]={ "シ", "゙" },
+ ["ズ"]={ "ス", "゙" },
+ ["ゼ"]={ "セ", "゙" },
+ ["ゾ"]={ "ソ", "゙" },
+ ["ダ"]={ "タ", "゙" },
+ ["ヂ"]={ "チ", "゙" },
+ ["ヅ"]={ "ツ", "゙" },
+ ["デ"]={ "テ", "゙" },
+ ["ド"]={ "ト", "゙" },
+ ["バ"]={ "ハ", "゙" },
+ ["パ"]={ "ハ", "゚" },
+ ["ビ"]={ "ヒ", "゙" },
+ ["ピ"]={ "ヒ", "゚" },
+ ["ブ"]={ "フ", "゙" },
+ ["プ"]={ "フ", "゚" },
+ ["ベ"]={ "ヘ", "゙" },
+ ["ペ"]={ "ヘ", "゚" },
+ ["ボ"]={ "ホ", "゙" },
+ ["ポ"]={ "ホ", "゚" },
+ ["ヴ"]={ "ウ", "゙" },
+ ["ヷ"]={ "ワ", "゙" },
+ ["ヸ"]={ "ヰ", "゙" },
+ ["ヹ"]={ "ヱ", "゙" },
+ ["ヺ"]={ "ヲ", "゙" },
+ ["ヾ"]={ "ヽ", "゙" },
+ ["יִ"]={ "י", "ִ" },
+ ["ײַ"]={ "ײ", "ַ" },
+ ["שׁ"]={ "ש", "ׁ" },
+ ["שׂ"]={ "ש", "ׂ" },
+ ["שּׁ"]={ "שּ", "ׁ" },
+ ["שּׂ"]={ "שּ", "ׂ" },
+ ["אַ"]={ "א", "ַ" },
+ ["אָ"]={ "א", "ָ" },
+ ["אּ"]={ "א", "ּ" },
+ ["בּ"]={ "ב", "ּ" },
+ ["גּ"]={ "ג", "ּ" },
+ ["דּ"]={ "ד", "ּ" },
+ ["הּ"]={ "ה", "ּ" },
+ ["וּ"]={ "ו", "ּ" },
+ ["זּ"]={ "ז", "ּ" },
+ ["טּ"]={ "ט", "ּ" },
+ ["יּ"]={ "י", "ּ" },
+ ["ךּ"]={ "ך", "ּ" },
+ ["כּ"]={ "כ", "ּ" },
+ ["לּ"]={ "ל", "ּ" },
+ ["מּ"]={ "מ", "ּ" },
+ ["נּ"]={ "נ", "ּ" },
+ ["סּ"]={ "ס", "ּ" },
+ ["ףּ"]={ "ף", "ּ" },
+ ["פּ"]={ "פ", "ּ" },
+ ["צּ"]={ "צ", "ּ" },
+ ["קּ"]={ "ק", "ּ" },
+ ["רּ"]={ "ר", "ּ" },
+ ["שּ"]={ "ש", "ּ" },
+ ["תּ"]={ "ת", "ּ" },
+ ["וֹ"]={ "ו", "ֹ" },
+ ["בֿ"]={ "ב", "ֿ" },
+ ["כֿ"]={ "כ", "ֿ" },
+ ["פֿ"]={ "פ", "ֿ" },
+ ["𑂚"]={ "𑂙", "𑂺" },
+ ["𑂜"]={ "𑂛", "𑂺" },
+ ["𑂫"]={ "𑂥", "𑂺" },
+ ["𑄮"]={ "𑄱", "𑄧" },
+ ["𑄯"]={ "𑄲", "𑄧" },
+ ["𑍋"]={ "𑍇", "𑌾" },
+ ["𑍌"]={ "𑍇", "𑍗" },
+ ["𑒻"]={ "𑒹", "𑒺" },
+ ["𑒼"]={ "𑒹", "𑒰" },
+ ["𑒾"]={ "𑒹", "𑒽" },
+ ["𑖺"]={ "𑖸", "𑖯" },
+ ["𑖻"]={ "𑖹", "𑖯" },
+ ["𝅗𝅥"]={ "𝅗", "𝅥" },
+ ["𝅘𝅥"]={ "𝅘", "𝅥" },
+ ["𝅘𝅥𝅮"]={ "𝅘𝅥", "𝅮" },
+ ["𝅘𝅥𝅯"]={ "𝅘𝅥", "𝅯" },
+ ["𝅘𝅥𝅰"]={ "𝅘𝅥", "𝅰" },
+ ["𝅘𝅥𝅱"]={ "𝅘𝅥", "𝅱" },
+ ["𝅘𝅥𝅲"]={ "𝅘𝅥", "𝅲" },
+ ["𝆹𝅥"]={ "𝆹", "𝅥" },
+ ["𝆺𝅥"]={ "𝆺", "𝅥" },
+ ["𝆹𝅥𝅮"]={ "𝆹𝅥", "𝅮" },
+ ["𝆺𝅥𝅮"]={ "𝆺𝅥", "𝅮" },
+ ["𝆹𝅥𝅯"]={ "𝆹𝅥", "𝅯" },
+ ["𝆺𝅥𝅯"]={ "𝆺𝅥", "𝅯" },
+ },
+ },
+ {
+ ["data"]={
+ ["À"]={ "A", "̀" },
+ ["Á"]={ "A", "́" },
+ ["Â"]={ "A", "̂" },
+ ["Ã"]={ "A", "̃" },
+ ["Ä"]={ "A", "̈" },
+ ["Å"]={ "A", "̊" },
+ ["Ç"]={ "C", "̧" },
+ ["È"]={ "E", "̀" },
+ ["É"]={ "E", "́" },
+ ["Ê"]={ "E", "̂" },
+ ["Ë"]={ "E", "̈" },
+ ["Ì"]={ "I", "̀" },
+ ["Í"]={ "I", "́" },
+ ["Î"]={ "I", "̂" },
+ ["Ï"]={ "I", "̈" },
+ ["Ñ"]={ "N", "̃" },
+ ["Ò"]={ "O", "̀" },
+ ["Ó"]={ "O", "́" },
+ ["Ô"]={ "O", "̂" },
+ ["Õ"]={ "O", "̃" },
+ ["Ö"]={ "O", "̈" },
+ ["Ù"]={ "U", "̀" },
+ ["Ú"]={ "U", "́" },
+ ["Û"]={ "U", "̂" },
+ ["Ü"]={ "U", "̈" },
+ ["Ý"]={ "Y", "́" },
+ ["à"]={ "a", "̀" },
+ ["á"]={ "a", "́" },
+ ["â"]={ "a", "̂" },
+ ["ã"]={ "a", "̃" },
+ ["ä"]={ "a", "̈" },
+ ["å"]={ "a", "̊" },
+ ["ç"]={ "c", "̧" },
+ ["è"]={ "e", "̀" },
+ ["é"]={ "e", "́" },
+ ["ê"]={ "e", "̂" },
+ ["ë"]={ "e", "̈" },
+ ["ì"]={ "i", "̀" },
+ ["í"]={ "i", "́" },
+ ["î"]={ "i", "̂" },
+ ["ï"]={ "i", "̈" },
+ ["ñ"]={ "n", "̃" },
+ ["ò"]={ "o", "̀" },
+ ["ó"]={ "o", "́" },
+ ["ô"]={ "o", "̂" },
+ ["õ"]={ "o", "̃" },
+ ["ö"]={ "o", "̈" },
+ ["ù"]={ "u", "̀" },
+ ["ú"]={ "u", "́" },
+ ["û"]={ "u", "̂" },
+ ["ü"]={ "u", "̈" },
+ ["ý"]={ "y", "́" },
+ ["ÿ"]={ "y", "̈" },
+ ["Ā"]={ "A", "̄" },
+ ["ā"]={ "a", "̄" },
+ ["Ă"]={ "A", "̆" },
+ ["ă"]={ "a", "̆" },
+ ["Ą"]={ "A", "̨" },
+ ["ą"]={ "a", "̨" },
+ ["Ć"]={ "C", "́" },
+ ["ć"]={ "c", "́" },
+ ["Ĉ"]={ "C", "̂" },
+ ["ĉ"]={ "c", "̂" },
+ ["Ċ"]={ "C", "̇" },
+ ["ċ"]={ "c", "̇" },
+ ["Č"]={ "C", "̌" },
+ ["č"]={ "c", "̌" },
+ ["Ď"]={ "D", "̌" },
+ ["ď"]={ "d", "̌" },
+ ["Ē"]={ "E", "̄" },
+ ["ē"]={ "e", "̄" },
+ ["Ĕ"]={ "E", "̆" },
+ ["ĕ"]={ "e", "̆" },
+ ["Ė"]={ "E", "̇" },
+ ["ė"]={ "e", "̇" },
+ ["Ę"]={ "E", "̨" },
+ ["ę"]={ "e", "̨" },
+ ["Ě"]={ "E", "̌" },
+ ["ě"]={ "e", "̌" },
+ ["Ĝ"]={ "G", "̂" },
+ ["ĝ"]={ "g", "̂" },
+ ["Ğ"]={ "G", "̆" },
+ ["ğ"]={ "g", "̆" },
+ ["Ġ"]={ "G", "̇" },
+ ["ġ"]={ "g", "̇" },
+ ["Ģ"]={ "G", "̧" },
+ ["ģ"]={ "g", "̧" },
+ ["Ĥ"]={ "H", "̂" },
+ ["ĥ"]={ "h", "̂" },
+ ["Ĩ"]={ "I", "̃" },
+ ["ĩ"]={ "i", "̃" },
+ ["Ī"]={ "I", "̄" },
+ ["ī"]={ "i", "̄" },
+ ["Ĭ"]={ "I", "̆" },
+ ["ĭ"]={ "i", "̆" },
+ ["Į"]={ "I", "̨" },
+ ["į"]={ "i", "̨" },
+ ["İ"]={ "I", "̇" },
+ ["Ĵ"]={ "J", "̂" },
+ ["ĵ"]={ "j", "̂" },
+ ["Ķ"]={ "K", "̧" },
+ ["ķ"]={ "k", "̧" },
+ ["Ĺ"]={ "L", "́" },
+ ["ĺ"]={ "l", "́" },
+ ["Ļ"]={ "L", "̧" },
+ ["ļ"]={ "l", "̧" },
+ ["Ľ"]={ "L", "̌" },
+ ["ľ"]={ "l", "̌" },
+ ["Ń"]={ "N", "́" },
+ ["ń"]={ "n", "́" },
+ ["Ņ"]={ "N", "̧" },
+ ["ņ"]={ "n", "̧" },
+ ["Ň"]={ "N", "̌" },
+ ["ň"]={ "n", "̌" },
+ ["Ō"]={ "O", "̄" },
+ ["ō"]={ "o", "̄" },
+ ["Ŏ"]={ "O", "̆" },
+ ["ŏ"]={ "o", "̆" },
+ ["Ő"]={ "O", "̋" },
+ ["ő"]={ "o", "̋" },
+ ["Ŕ"]={ "R", "́" },
+ ["ŕ"]={ "r", "́" },
+ ["Ŗ"]={ "R", "̧" },
+ ["ŗ"]={ "r", "̧" },
+ ["Ř"]={ "R", "̌" },
+ ["ř"]={ "r", "̌" },
+ ["Ś"]={ "S", "́" },
+ ["ś"]={ "s", "́" },
+ ["Ŝ"]={ "S", "̂" },
+ ["ŝ"]={ "s", "̂" },
+ ["Ş"]={ "S", "̧" },
+ ["ş"]={ "s", "̧" },
+ ["Š"]={ "S", "̌" },
+ ["š"]={ "s", "̌" },
+ ["Ţ"]={ "T", "̧" },
+ ["ţ"]={ "t", "̧" },
+ ["Ť"]={ "T", "̌" },
+ ["ť"]={ "t", "̌" },
+ ["Ũ"]={ "U", "̃" },
+ ["ũ"]={ "u", "̃" },
+ ["Ū"]={ "U", "̄" },
+ ["ū"]={ "u", "̄" },
+ ["Ŭ"]={ "U", "̆" },
+ ["ŭ"]={ "u", "̆" },
+ ["Ů"]={ "U", "̊" },
+ ["ů"]={ "u", "̊" },
+ ["Ű"]={ "U", "̋" },
+ ["ű"]={ "u", "̋" },
+ ["Ų"]={ "U", "̨" },
+ ["ų"]={ "u", "̨" },
+ ["Ŵ"]={ "W", "̂" },
+ ["ŵ"]={ "w", "̂" },
+ ["Ŷ"]={ "Y", "̂" },
+ ["ŷ"]={ "y", "̂" },
+ ["Ÿ"]={ "Y", "̈" },
+ ["Ź"]={ "Z", "́" },
+ ["ź"]={ "z", "́" },
+ ["Ż"]={ "Z", "̇" },
+ ["ż"]={ "z", "̇" },
+ ["Ž"]={ "Z", "̌" },
+ ["ž"]={ "z", "̌" },
+ ["Ơ"]={ "O", "̛" },
+ ["ơ"]={ "o", "̛" },
+ ["Ư"]={ "U", "̛" },
+ ["ư"]={ "u", "̛" },
+ ["Ǎ"]={ "A", "̌" },
+ ["ǎ"]={ "a", "̌" },
+ ["Ǐ"]={ "I", "̌" },
+ ["ǐ"]={ "i", "̌" },
+ ["Ǒ"]={ "O", "̌" },
+ ["ǒ"]={ "o", "̌" },
+ ["Ǔ"]={ "U", "̌" },
+ ["ǔ"]={ "u", "̌" },
+ ["Ǖ"]={ "Ü", "̄" },
+ ["ǖ"]={ "ü", "̄" },
+ ["Ǘ"]={ "Ü", "́" },
+ ["ǘ"]={ "ü", "́" },
+ ["Ǚ"]={ "Ü", "̌" },
+ ["ǚ"]={ "ü", "̌" },
+ ["Ǜ"]={ "Ü", "̀" },
+ ["ǜ"]={ "ü", "̀" },
+ ["Ǟ"]={ "Ä", "̄" },
+ ["ǟ"]={ "ä", "̄" },
+ ["Ǡ"]={ "Ȧ", "̄" },
+ ["ǡ"]={ "ȧ", "̄" },
+ ["Ǣ"]={ "Æ", "̄" },
+ ["ǣ"]={ "æ", "̄" },
+ ["Ǧ"]={ "G", "̌" },
+ ["ǧ"]={ "g", "̌" },
+ ["Ǩ"]={ "K", "̌" },
+ ["ǩ"]={ "k", "̌" },
+ ["Ǫ"]={ "O", "̨" },
+ ["ǫ"]={ "o", "̨" },
+ ["Ǭ"]={ "Ǫ", "̄" },
+ ["ǭ"]={ "ǫ", "̄" },
+ ["Ǯ"]={ "Ʒ", "̌" },
+ ["ǯ"]={ "ʒ", "̌" },
+ ["ǰ"]={ "j", "̌" },
+ ["Ǵ"]={ "G", "́" },
+ ["ǵ"]={ "g", "́" },
+ ["Ǹ"]={ "N", "̀" },
+ ["ǹ"]={ "n", "̀" },
+ ["Ǻ"]={ "Å", "́" },
+ ["ǻ"]={ "å", "́" },
+ ["Ǽ"]={ "Æ", "́" },
+ ["ǽ"]={ "æ", "́" },
+ ["Ǿ"]={ "Ø", "́" },
+ ["ǿ"]={ "ø", "́" },
+ ["Ȁ"]={ "A", "̏" },
+ ["ȁ"]={ "a", "̏" },
+ ["Ȃ"]={ "A", "̑" },
+ ["ȃ"]={ "a", "̑" },
+ ["Ȅ"]={ "E", "̏" },
+ ["ȅ"]={ "e", "̏" },
+ ["Ȇ"]={ "E", "̑" },
+ ["ȇ"]={ "e", "̑" },
+ ["Ȉ"]={ "I", "̏" },
+ ["ȉ"]={ "i", "̏" },
+ ["Ȋ"]={ "I", "̑" },
+ ["ȋ"]={ "i", "̑" },
+ ["Ȍ"]={ "O", "̏" },
+ ["ȍ"]={ "o", "̏" },
+ ["Ȏ"]={ "O", "̑" },
+ ["ȏ"]={ "o", "̑" },
+ ["Ȑ"]={ "R", "̏" },
+ ["ȑ"]={ "r", "̏" },
+ ["Ȓ"]={ "R", "̑" },
+ ["ȓ"]={ "r", "̑" },
+ ["Ȕ"]={ "U", "̏" },
+ ["ȕ"]={ "u", "̏" },
+ ["Ȗ"]={ "U", "̑" },
+ ["ȗ"]={ "u", "̑" },
+ ["Ș"]={ "S", "̦" },
+ ["ș"]={ "s", "̦" },
+ ["Ț"]={ "T", "̦" },
+ ["ț"]={ "t", "̦" },
+ ["Ȟ"]={ "H", "̌" },
+ ["ȟ"]={ "h", "̌" },
+ ["Ȧ"]={ "A", "̇" },
+ ["ȧ"]={ "a", "̇" },
+ ["Ȩ"]={ "E", "̧" },
+ ["ȩ"]={ "e", "̧" },
+ ["Ȫ"]={ "Ö", "̄" },
+ ["ȫ"]={ "ö", "̄" },
+ ["Ȭ"]={ "Õ", "̄" },
+ ["ȭ"]={ "õ", "̄" },
+ ["Ȯ"]={ "O", "̇" },
+ ["ȯ"]={ "o", "̇" },
+ ["Ȱ"]={ "Ȯ", "̄" },
+ ["ȱ"]={ "ȯ", "̄" },
+ ["Ȳ"]={ "Y", "̄" },
+ ["ȳ"]={ "y", "̄" },
+ ["̈́"]={ "̈", "́" },
+ ["΅"]={ "¨", "́" },
+ ["Ά"]={ "Α", "́" },
+ ["Έ"]={ "Ε", "́" },
+ ["Ή"]={ "Η", "́" },
+ ["Ί"]={ "Ι", "́" },
+ ["Ό"]={ "Ο", "́" },
+ ["Ύ"]={ "Υ", "́" },
+ ["Ώ"]={ "Ω", "́" },
+ ["ΐ"]={ "ϊ", "́" },
+ ["Ϊ"]={ "Ι", "̈" },
+ ["Ϋ"]={ "Υ", "̈" },
+ ["ά"]={ "α", "́" },
+ ["έ"]={ "ε", "́" },
+ ["ή"]={ "η", "́" },
+ ["ί"]={ "ι", "́" },
+ ["ΰ"]={ "ϋ", "́" },
+ ["ϊ"]={ "ι", "̈" },
+ ["ϋ"]={ "υ", "̈" },
+ ["ό"]={ "ο", "́" },
+ ["ύ"]={ "υ", "́" },
+ ["ώ"]={ "ω", "́" },
+ ["ϓ"]={ "ϒ", "́" },
+ ["ϔ"]={ "ϒ", "̈" },
+ ["Ѐ"]={ "Е", "̀" },
+ ["Ё"]={ "Е", "̈" },
+ ["Ѓ"]={ "Г", "́" },
+ ["Ї"]={ "І", "̈" },
+ ["Ќ"]={ "К", "́" },
+ ["Ѝ"]={ "И", "̀" },
+ ["Ў"]={ "У", "̆" },
+ ["Й"]={ "И", "̆" },
+ ["й"]={ "и", "̆" },
+ ["ѐ"]={ "е", "̀" },
+ ["ё"]={ "е", "̈" },
+ ["ѓ"]={ "г", "́" },
+ ["ї"]={ "і", "̈" },
+ ["ќ"]={ "к", "́" },
+ ["ѝ"]={ "и", "̀" },
+ ["ў"]={ "у", "̆" },
+ ["Ѷ"]={ "Ѵ", "̏" },
+ ["ѷ"]={ "ѵ", "̏" },
+ ["Ӂ"]={ "Ж", "̆" },
+ ["ӂ"]={ "ж", "̆" },
+ ["Ӑ"]={ "А", "̆" },
+ ["ӑ"]={ "а", "̆" },
+ ["Ӓ"]={ "А", "̈" },
+ ["ӓ"]={ "а", "̈" },
+ ["Ӗ"]={ "Е", "̆" },
+ ["ӗ"]={ "е", "̆" },
+ ["Ӛ"]={ "Ә", "̈" },
+ ["ӛ"]={ "ә", "̈" },
+ ["Ӝ"]={ "Ж", "̈" },
+ ["ӝ"]={ "ж", "̈" },
+ ["Ӟ"]={ "З", "̈" },
+ ["ӟ"]={ "з", "̈" },
+ ["Ӣ"]={ "И", "̄" },
+ ["ӣ"]={ "и", "̄" },
+ ["Ӥ"]={ "И", "̈" },
+ ["ӥ"]={ "и", "̈" },
+ ["Ӧ"]={ "О", "̈" },
+ ["ӧ"]={ "о", "̈" },
+ ["Ӫ"]={ "Ө", "̈" },
+ ["ӫ"]={ "ө", "̈" },
+ ["Ӭ"]={ "Э", "̈" },
+ ["ӭ"]={ "э", "̈" },
+ ["Ӯ"]={ "У", "̄" },
+ ["ӯ"]={ "у", "̄" },
+ ["Ӱ"]={ "У", "̈" },
+ ["ӱ"]={ "у", "̈" },
+ ["Ӳ"]={ "У", "̋" },
+ ["ӳ"]={ "у", "̋" },
+ ["Ӵ"]={ "Ч", "̈" },
+ ["ӵ"]={ "ч", "̈" },
+ ["Ӹ"]={ "Ы", "̈" },
+ ["ӹ"]={ "ы", "̈" },
+ ["آ"]={ "ا", "ٓ" },
+ ["أ"]={ "ا", "ٔ" },
+ ["ؤ"]={ "و", "ٔ" },
+ ["إ"]={ "ا", "ٕ" },
+ ["ئ"]={ "ي", "ٔ" },
+ ["ۀ"]={ "ە", "ٔ" },
+ ["ۂ"]={ "ہ", "ٔ" },
+ ["ۓ"]={ "ے", "ٔ" },
+ ["ऩ"]={ "न", "़" },
+ ["ऱ"]={ "र", "़" },
+ ["ऴ"]={ "ळ", "़" },
+ ["क़"]={ "क", "़" },
+ ["ख़"]={ "ख", "़" },
+ ["ग़"]={ "ग", "़" },
+ ["ज़"]={ "ज", "़" },
+ ["ड़"]={ "ड", "़" },
+ ["ढ़"]={ "ढ", "़" },
+ ["फ़"]={ "फ", "़" },
+ ["य़"]={ "य", "़" },
+ ["ো"]={ "ে", "া" },
+ ["ৌ"]={ "ে", "ৗ" },
+ ["ড়"]={ "ড", "়" },
+ ["ঢ়"]={ "ঢ", "়" },
+ ["য়"]={ "য", "়" },
+ ["ਲ਼"]={ "ਲ", "਼" },
+ ["ਸ਼"]={ "ਸ", "਼" },
+ ["ਖ਼"]={ "ਖ", "਼" },
+ ["ਗ਼"]={ "ਗ", "਼" },
+ ["ਜ਼"]={ "ਜ", "਼" },
+ ["ਫ਼"]={ "ਫ", "਼" },
+ ["ୈ"]={ "େ", "ୖ" },
+ ["ୋ"]={ "େ", "ା" },
+ ["ୌ"]={ "େ", "ୗ" },
+ ["ଡ଼"]={ "ଡ", "଼" },
+ ["ଢ଼"]={ "ଢ", "଼" },
+ ["ஔ"]={ "ஒ", "ௗ" },
+ ["ொ"]={ "ெ", "ா" },
+ ["ோ"]={ "ே", "ா" },
+ ["ௌ"]={ "ெ", "ௗ" },
+ ["ై"]={ "ె", "ౖ" },
+ ["ೀ"]={ "ಿ", "ೕ" },
+ ["ೇ"]={ "ೆ", "ೕ" },
+ ["ೈ"]={ "ೆ", "ೖ" },
+ ["ೊ"]={ "ೆ", "ೂ" },
+ ["ೋ"]={ "ೊ", "ೕ" },
+ ["ൊ"]={ "െ", "ാ" },
+ ["ോ"]={ "േ", "ാ" },
+ ["ൌ"]={ "െ", "ൗ" },
+ ["ේ"]={ "ෙ", "්" },
+ ["ො"]={ "ෙ", "ා" },
+ ["ෝ"]={ "ො", "්" },
+ ["ෞ"]={ "ෙ", "ෟ" },
+ ["གྷ"]={ "ག", "ྷ" },
+ ["ཌྷ"]={ "ཌ", "ྷ" },
+ ["དྷ"]={ "ད", "ྷ" },
+ ["བྷ"]={ "བ", "ྷ" },
+ ["ཛྷ"]={ "ཛ", "ྷ" },
+ ["ཀྵ"]={ "ཀ", "ྵ" },
+ ["ཱི"]={ "ཱ", "ི" },
+ ["ཱུ"]={ "ཱ", "ུ" },
+ ["ྲྀ"]={ "ྲ", "ྀ" },
+ ["ླྀ"]={ "ླ", "ྀ" },
+ ["ཱྀ"]={ "ཱ", "ྀ" },
+ ["ྒྷ"]={ "ྒ", "ྷ" },
+ ["ྜྷ"]={ "ྜ", "ྷ" },
+ ["ྡྷ"]={ "ྡ", "ྷ" },
+ ["ྦྷ"]={ "ྦ", "ྷ" },
+ ["ྫྷ"]={ "ྫ", "ྷ" },
+ ["ྐྵ"]={ "ྐ", "ྵ" },
+ ["ဦ"]={ "ဥ", "ီ" },
+ ["ᬆ"]={ "ᬅ", "ᬵ" },
+ ["ᬈ"]={ "ᬇ", "ᬵ" },
+ ["ᬊ"]={ "ᬉ", "ᬵ" },
+ ["ᬌ"]={ "ᬋ", "ᬵ" },
+ ["ᬎ"]={ "ᬍ", "ᬵ" },
+ ["ᬒ"]={ "ᬑ", "ᬵ" },
+ ["ᬻ"]={ "ᬺ", "ᬵ" },
+ ["ᬽ"]={ "ᬼ", "ᬵ" },
+ ["ᭀ"]={ "ᬾ", "ᬵ" },
+ ["ᭁ"]={ "ᬿ", "ᬵ" },
+ ["ᭃ"]={ "ᭂ", "ᬵ" },
+ ["Ḁ"]={ "A", "̥" },
+ ["ḁ"]={ "a", "̥" },
+ ["Ḃ"]={ "B", "̇" },
+ ["ḃ"]={ "b", "̇" },
+ ["Ḅ"]={ "B", "̣" },
+ ["ḅ"]={ "b", "̣" },
+ ["Ḇ"]={ "B", "̱" },
+ ["ḇ"]={ "b", "̱" },
+ ["Ḉ"]={ "Ç", "́" },
+ ["ḉ"]={ "ç", "́" },
+ ["Ḋ"]={ "D", "̇" },
+ ["ḋ"]={ "d", "̇" },
+ ["Ḍ"]={ "D", "̣" },
+ ["ḍ"]={ "d", "̣" },
+ ["Ḏ"]={ "D", "̱" },
+ ["ḏ"]={ "d", "̱" },
+ ["Ḑ"]={ "D", "̧" },
+ ["ḑ"]={ "d", "̧" },
+ ["Ḓ"]={ "D", "̭" },
+ ["ḓ"]={ "d", "̭" },
+ ["Ḕ"]={ "Ē", "̀" },
+ ["ḕ"]={ "ē", "̀" },
+ ["Ḗ"]={ "Ē", "́" },
+ ["ḗ"]={ "ē", "́" },
+ ["Ḙ"]={ "E", "̭" },
+ ["ḙ"]={ "e", "̭" },
+ ["Ḛ"]={ "E", "̰" },
+ ["ḛ"]={ "e", "̰" },
+ ["Ḝ"]={ "Ȩ", "̆" },
+ ["ḝ"]={ "ȩ", "̆" },
+ ["Ḟ"]={ "F", "̇" },
+ ["ḟ"]={ "f", "̇" },
+ ["Ḡ"]={ "G", "̄" },
+ ["ḡ"]={ "g", "̄" },
+ ["Ḣ"]={ "H", "̇" },
+ ["ḣ"]={ "h", "̇" },
+ ["Ḥ"]={ "H", "̣" },
+ ["ḥ"]={ "h", "̣" },
+ ["Ḧ"]={ "H", "̈" },
+ ["ḧ"]={ "h", "̈" },
+ ["Ḩ"]={ "H", "̧" },
+ ["ḩ"]={ "h", "̧" },
+ ["Ḫ"]={ "H", "̮" },
+ ["ḫ"]={ "h", "̮" },
+ ["Ḭ"]={ "I", "̰" },
+ ["ḭ"]={ "i", "̰" },
+ ["Ḯ"]={ "Ï", "́" },
+ ["ḯ"]={ "ï", "́" },
+ ["Ḱ"]={ "K", "́" },
+ ["ḱ"]={ "k", "́" },
+ ["Ḳ"]={ "K", "̣" },
+ ["ḳ"]={ "k", "̣" },
+ ["Ḵ"]={ "K", "̱" },
+ ["ḵ"]={ "k", "̱" },
+ ["Ḷ"]={ "L", "̣" },
+ ["ḷ"]={ "l", "̣" },
+ ["Ḹ"]={ "Ḷ", "̄" },
+ ["ḹ"]={ "ḷ", "̄" },
+ ["Ḻ"]={ "L", "̱" },
+ ["ḻ"]={ "l", "̱" },
+ ["Ḽ"]={ "L", "̭" },
+ ["ḽ"]={ "l", "̭" },
+ ["Ḿ"]={ "M", "́" },
+ ["ḿ"]={ "m", "́" },
+ ["Ṁ"]={ "M", "̇" },
+ ["ṁ"]={ "m", "̇" },
+ ["Ṃ"]={ "M", "̣" },
+ ["ṃ"]={ "m", "̣" },
+ ["Ṅ"]={ "N", "̇" },
+ ["ṅ"]={ "n", "̇" },
+ ["Ṇ"]={ "N", "̣" },
+ ["ṇ"]={ "n", "̣" },
+ ["Ṉ"]={ "N", "̱" },
+ ["ṉ"]={ "n", "̱" },
+ ["Ṋ"]={ "N", "̭" },
+ ["ṋ"]={ "n", "̭" },
+ ["Ṍ"]={ "Õ", "́" },
+ ["ṍ"]={ "õ", "́" },
+ ["Ṏ"]={ "Õ", "̈" },
+ ["ṏ"]={ "õ", "̈" },
+ ["Ṑ"]={ "Ō", "̀" },
+ ["ṑ"]={ "ō", "̀" },
+ ["Ṓ"]={ "Ō", "́" },
+ ["ṓ"]={ "ō", "́" },
+ ["Ṕ"]={ "P", "́" },
+ ["ṕ"]={ "p", "́" },
+ ["Ṗ"]={ "P", "̇" },
+ ["ṗ"]={ "p", "̇" },
+ ["Ṙ"]={ "R", "̇" },
+ ["ṙ"]={ "r", "̇" },
+ ["Ṛ"]={ "R", "̣" },
+ ["ṛ"]={ "r", "̣" },
+ ["Ṝ"]={ "Ṛ", "̄" },
+ ["ṝ"]={ "ṛ", "̄" },
+ ["Ṟ"]={ "R", "̱" },
+ ["ṟ"]={ "r", "̱" },
+ ["Ṡ"]={ "S", "̇" },
+ ["ṡ"]={ "s", "̇" },
+ ["Ṣ"]={ "S", "̣" },
+ ["ṣ"]={ "s", "̣" },
+ ["Ṥ"]={ "Ś", "̇" },
+ ["ṥ"]={ "ś", "̇" },
+ ["Ṧ"]={ "Š", "̇" },
+ ["ṧ"]={ "š", "̇" },
+ ["Ṩ"]={ "Ṣ", "̇" },
+ ["ṩ"]={ "ṣ", "̇" },
+ ["Ṫ"]={ "T", "̇" },
+ ["ṫ"]={ "t", "̇" },
+ ["Ṭ"]={ "T", "̣" },
+ ["ṭ"]={ "t", "̣" },
+ ["Ṯ"]={ "T", "̱" },
+ ["ṯ"]={ "t", "̱" },
+ ["Ṱ"]={ "T", "̭" },
+ ["ṱ"]={ "t", "̭" },
+ ["Ṳ"]={ "U", "̤" },
+ ["ṳ"]={ "u", "̤" },
+ ["Ṵ"]={ "U", "̰" },
+ ["ṵ"]={ "u", "̰" },
+ ["Ṷ"]={ "U", "̭" },
+ ["ṷ"]={ "u", "̭" },
+ ["Ṹ"]={ "Ũ", "́" },
+ ["ṹ"]={ "ũ", "́" },
+ ["Ṻ"]={ "Ū", "̈" },
+ ["ṻ"]={ "ū", "̈" },
+ ["Ṽ"]={ "V", "̃" },
+ ["ṽ"]={ "v", "̃" },
+ ["Ṿ"]={ "V", "̣" },
+ ["ṿ"]={ "v", "̣" },
+ ["Ẁ"]={ "W", "̀" },
+ ["ẁ"]={ "w", "̀" },
+ ["Ẃ"]={ "W", "́" },
+ ["ẃ"]={ "w", "́" },
+ ["Ẅ"]={ "W", "̈" },
+ ["ẅ"]={ "w", "̈" },
+ ["Ẇ"]={ "W", "̇" },
+ ["ẇ"]={ "w", "̇" },
+ ["Ẉ"]={ "W", "̣" },
+ ["ẉ"]={ "w", "̣" },
+ ["Ẋ"]={ "X", "̇" },
+ ["ẋ"]={ "x", "̇" },
+ ["Ẍ"]={ "X", "̈" },
+ ["ẍ"]={ "x", "̈" },
+ ["Ẏ"]={ "Y", "̇" },
+ ["ẏ"]={ "y", "̇" },
+ ["Ẑ"]={ "Z", "̂" },
+ ["ẑ"]={ "z", "̂" },
+ ["Ẓ"]={ "Z", "̣" },
+ ["ẓ"]={ "z", "̣" },
+ ["Ẕ"]={ "Z", "̱" },
+ ["ẕ"]={ "z", "̱" },
+ ["ẖ"]={ "h", "̱" },
+ ["ẗ"]={ "t", "̈" },
+ ["ẘ"]={ "w", "̊" },
+ ["ẙ"]={ "y", "̊" },
+ ["ẛ"]={ "ſ", "̇" },
+ ["Ạ"]={ "A", "̣" },
+ ["ạ"]={ "a", "̣" },
+ ["Ả"]={ "A", "̉" },
+ ["ả"]={ "a", "̉" },
+ ["Ấ"]={ "Â", "́" },
+ ["ấ"]={ "â", "́" },
+ ["Ầ"]={ "Â", "̀" },
+ ["ầ"]={ "â", "̀" },
+ ["Ẩ"]={ "Â", "̉" },
+ ["ẩ"]={ "â", "̉" },
+ ["Ẫ"]={ "Â", "̃" },
+ ["ẫ"]={ "â", "̃" },
+ ["Ậ"]={ "Ạ", "̂" },
+ ["ậ"]={ "ạ", "̂" },
+ ["Ắ"]={ "Ă", "́" },
+ ["ắ"]={ "ă", "́" },
+ ["Ằ"]={ "Ă", "̀" },
+ ["ằ"]={ "ă", "̀" },
+ ["Ẳ"]={ "Ă", "̉" },
+ ["ẳ"]={ "ă", "̉" },
+ ["Ẵ"]={ "Ă", "̃" },
+ ["ẵ"]={ "ă", "̃" },
+ ["Ặ"]={ "Ạ", "̆" },
+ ["ặ"]={ "ạ", "̆" },
+ ["Ẹ"]={ "E", "̣" },
+ ["ẹ"]={ "e", "̣" },
+ ["Ẻ"]={ "E", "̉" },
+ ["ẻ"]={ "e", "̉" },
+ ["Ẽ"]={ "E", "̃" },
+ ["ẽ"]={ "e", "̃" },
+ ["Ế"]={ "Ê", "́" },
+ ["ế"]={ "ê", "́" },
+ ["Ề"]={ "Ê", "̀" },
+ ["ề"]={ "ê", "̀" },
+ ["Ể"]={ "Ê", "̉" },
+ ["ể"]={ "ê", "̉" },
+ ["Ễ"]={ "Ê", "̃" },
+ ["ễ"]={ "ê", "̃" },
+ ["Ệ"]={ "Ẹ", "̂" },
+ ["ệ"]={ "ẹ", "̂" },
+ ["Ỉ"]={ "I", "̉" },
+ ["ỉ"]={ "i", "̉" },
+ ["Ị"]={ "I", "̣" },
+ ["ị"]={ "i", "̣" },
+ ["Ọ"]={ "O", "̣" },
+ ["ọ"]={ "o", "̣" },
+ ["Ỏ"]={ "O", "̉" },
+ ["ỏ"]={ "o", "̉" },
+ ["Ố"]={ "Ô", "́" },
+ ["ố"]={ "ô", "́" },
+ ["Ồ"]={ "Ô", "̀" },
+ ["ồ"]={ "ô", "̀" },
+ ["Ổ"]={ "Ô", "̉" },
+ ["ổ"]={ "ô", "̉" },
+ ["Ỗ"]={ "Ô", "̃" },
+ ["ỗ"]={ "ô", "̃" },
+ ["Ộ"]={ "Ọ", "̂" },
+ ["ộ"]={ "ọ", "̂" },
+ ["Ớ"]={ "Ơ", "́" },
+ ["ớ"]={ "ơ", "́" },
+ ["Ờ"]={ "Ơ", "̀" },
+ ["ờ"]={ "ơ", "̀" },
+ ["Ở"]={ "Ơ", "̉" },
+ ["ở"]={ "ơ", "̉" },
+ ["Ỡ"]={ "Ơ", "̃" },
+ ["ỡ"]={ "ơ", "̃" },
+ ["Ợ"]={ "Ơ", "̣" },
+ ["ợ"]={ "ơ", "̣" },
+ ["Ụ"]={ "U", "̣" },
+ ["ụ"]={ "u", "̣" },
+ ["Ủ"]={ "U", "̉" },
+ ["ủ"]={ "u", "̉" },
+ ["Ứ"]={ "Ư", "́" },
+ ["ứ"]={ "ư", "́" },
+ ["Ừ"]={ "Ư", "̀" },
+ ["ừ"]={ "ư", "̀" },
+ ["Ử"]={ "Ư", "̉" },
+ ["ử"]={ "ư", "̉" },
+ ["Ữ"]={ "Ư", "̃" },
+ ["ữ"]={ "ư", "̃" },
+ ["Ự"]={ "Ư", "̣" },
+ ["ự"]={ "ư", "̣" },
+ ["Ỳ"]={ "Y", "̀" },
+ ["ỳ"]={ "y", "̀" },
+ ["Ỵ"]={ "Y", "̣" },
+ ["ỵ"]={ "y", "̣" },
+ ["Ỷ"]={ "Y", "̉" },
+ ["ỷ"]={ "y", "̉" },
+ ["Ỹ"]={ "Y", "̃" },
+ ["ỹ"]={ "y", "̃" },
+ ["ἀ"]={ "α", "̓" },
+ ["ἁ"]={ "α", "̔" },
+ ["ἂ"]={ "ἀ", "̀" },
+ ["ἃ"]={ "ἁ", "̀" },
+ ["ἄ"]={ "ἀ", "́" },
+ ["ἅ"]={ "ἁ", "́" },
+ ["ἆ"]={ "ἀ", "͂" },
+ ["ἇ"]={ "ἁ", "͂" },
+ ["Ἀ"]={ "Α", "̓" },
+ ["Ἁ"]={ "Α", "̔" },
+ ["Ἂ"]={ "Ἀ", "̀" },
+ ["Ἃ"]={ "Ἁ", "̀" },
+ ["Ἄ"]={ "Ἀ", "́" },
+ ["Ἅ"]={ "Ἁ", "́" },
+ ["Ἆ"]={ "Ἀ", "͂" },
+ ["Ἇ"]={ "Ἁ", "͂" },
+ ["ἐ"]={ "ε", "̓" },
+ ["ἑ"]={ "ε", "̔" },
+ ["ἒ"]={ "ἐ", "̀" },
+ ["ἓ"]={ "ἑ", "̀" },
+ ["ἔ"]={ "ἐ", "́" },
+ ["ἕ"]={ "ἑ", "́" },
+ ["Ἐ"]={ "Ε", "̓" },
+ ["Ἑ"]={ "Ε", "̔" },
+ ["Ἒ"]={ "Ἐ", "̀" },
+ ["Ἓ"]={ "Ἑ", "̀" },
+ ["Ἔ"]={ "Ἐ", "́" },
+ ["Ἕ"]={ "Ἑ", "́" },
+ ["ἠ"]={ "η", "̓" },
+ ["ἡ"]={ "η", "̔" },
+ ["ἢ"]={ "ἠ", "̀" },
+ ["ἣ"]={ "ἡ", "̀" },
+ ["ἤ"]={ "ἠ", "́" },
+ ["ἥ"]={ "ἡ", "́" },
+ ["ἦ"]={ "ἠ", "͂" },
+ ["ἧ"]={ "ἡ", "͂" },
+ ["Ἠ"]={ "Η", "̓" },
+ ["Ἡ"]={ "Η", "̔" },
+ ["Ἢ"]={ "Ἠ", "̀" },
+ ["Ἣ"]={ "Ἡ", "̀" },
+ ["Ἤ"]={ "Ἠ", "́" },
+ ["Ἥ"]={ "Ἡ", "́" },
+ ["Ἦ"]={ "Ἠ", "͂" },
+ ["Ἧ"]={ "Ἡ", "͂" },
+ ["ἰ"]={ "ι", "̓" },
+ ["ἱ"]={ "ι", "̔" },
+ ["ἲ"]={ "ἰ", "̀" },
+ ["ἳ"]={ "ἱ", "̀" },
+ ["ἴ"]={ "ἰ", "́" },
+ ["ἵ"]={ "ἱ", "́" },
+ ["ἶ"]={ "ἰ", "͂" },
+ ["ἷ"]={ "ἱ", "͂" },
+ ["Ἰ"]={ "Ι", "̓" },
+ ["Ἱ"]={ "Ι", "̔" },
+ ["Ἲ"]={ "Ἰ", "̀" },
+ ["Ἳ"]={ "Ἱ", "̀" },
+ ["Ἴ"]={ "Ἰ", "́" },
+ ["Ἵ"]={ "Ἱ", "́" },
+ ["Ἶ"]={ "Ἰ", "͂" },
+ ["Ἷ"]={ "Ἱ", "͂" },
+ ["ὀ"]={ "ο", "̓" },
+ ["ὁ"]={ "ο", "̔" },
+ ["ὂ"]={ "ὀ", "̀" },
+ ["ὃ"]={ "ὁ", "̀" },
+ ["ὄ"]={ "ὀ", "́" },
+ ["ὅ"]={ "ὁ", "́" },
+ ["Ὀ"]={ "Ο", "̓" },
+ ["Ὁ"]={ "Ο", "̔" },
+ ["Ὂ"]={ "Ὀ", "̀" },
+ ["Ὃ"]={ "Ὁ", "̀" },
+ ["Ὄ"]={ "Ὀ", "́" },
+ ["Ὅ"]={ "Ὁ", "́" },
+ ["ὐ"]={ "υ", "̓" },
+ ["ὑ"]={ "υ", "̔" },
+ ["ὒ"]={ "ὐ", "̀" },
+ ["ὓ"]={ "ὑ", "̀" },
+ ["ὔ"]={ "ὐ", "́" },
+ ["ὕ"]={ "ὑ", "́" },
+ ["ὖ"]={ "ὐ", "͂" },
+ ["ὗ"]={ "ὑ", "͂" },
+ ["Ὑ"]={ "Υ", "̔" },
+ ["Ὓ"]={ "Ὑ", "̀" },
+ ["Ὕ"]={ "Ὑ", "́" },
+ ["Ὗ"]={ "Ὑ", "͂" },
+ ["ὠ"]={ "ω", "̓" },
+ ["ὡ"]={ "ω", "̔" },
+ ["ὢ"]={ "ὠ", "̀" },
+ ["ὣ"]={ "ὡ", "̀" },
+ ["ὤ"]={ "ὠ", "́" },
+ ["ὥ"]={ "ὡ", "́" },
+ ["ὦ"]={ "ὠ", "͂" },
+ ["ὧ"]={ "ὡ", "͂" },
+ ["Ὠ"]={ "Ω", "̓" },
+ ["Ὡ"]={ "Ω", "̔" },
+ ["Ὢ"]={ "Ὠ", "̀" },
+ ["Ὣ"]={ "Ὡ", "̀" },
+ ["Ὤ"]={ "Ὠ", "́" },
+ ["Ὥ"]={ "Ὡ", "́" },
+ ["Ὦ"]={ "Ὠ", "͂" },
+ ["Ὧ"]={ "Ὡ", "͂" },
+ ["ὰ"]={ "α", "̀" },
+ ["ὲ"]={ "ε", "̀" },
+ ["ὴ"]={ "η", "̀" },
+ ["ὶ"]={ "ι", "̀" },
+ ["ὸ"]={ "ο", "̀" },
+ ["ὺ"]={ "υ", "̀" },
+ ["ὼ"]={ "ω", "̀" },
+ ["ᾀ"]={ "ἀ", "ͅ" },
+ ["ᾁ"]={ "ἁ", "ͅ" },
+ ["ᾂ"]={ "ἂ", "ͅ" },
+ ["ᾃ"]={ "ἃ", "ͅ" },
+ ["ᾄ"]={ "ἄ", "ͅ" },
+ ["ᾅ"]={ "ἅ", "ͅ" },
+ ["ᾆ"]={ "ἆ", "ͅ" },
+ ["ᾇ"]={ "ἇ", "ͅ" },
+ ["ᾈ"]={ "Ἀ", "ͅ" },
+ ["ᾉ"]={ "Ἁ", "ͅ" },
+ ["ᾊ"]={ "Ἂ", "ͅ" },
+ ["ᾋ"]={ "Ἃ", "ͅ" },
+ ["ᾌ"]={ "Ἄ", "ͅ" },
+ ["ᾍ"]={ "Ἅ", "ͅ" },
+ ["ᾎ"]={ "Ἆ", "ͅ" },
+ ["ᾏ"]={ "Ἇ", "ͅ" },
+ ["ᾐ"]={ "ἠ", "ͅ" },
+ ["ᾑ"]={ "ἡ", "ͅ" },
+ ["ᾒ"]={ "ἢ", "ͅ" },
+ ["ᾓ"]={ "ἣ", "ͅ" },
+ ["ᾔ"]={ "ἤ", "ͅ" },
+ ["ᾕ"]={ "ἥ", "ͅ" },
+ ["ᾖ"]={ "ἦ", "ͅ" },
+ ["ᾗ"]={ "ἧ", "ͅ" },
+ ["ᾘ"]={ "Ἠ", "ͅ" },
+ ["ᾙ"]={ "Ἡ", "ͅ" },
+ ["ᾚ"]={ "Ἢ", "ͅ" },
+ ["ᾛ"]={ "Ἣ", "ͅ" },
+ ["ᾜ"]={ "Ἤ", "ͅ" },
+ ["ᾝ"]={ "Ἥ", "ͅ" },
+ ["ᾞ"]={ "Ἦ", "ͅ" },
+ ["ᾟ"]={ "Ἧ", "ͅ" },
+ ["ᾠ"]={ "ὠ", "ͅ" },
+ ["ᾡ"]={ "ὡ", "ͅ" },
+ ["ᾢ"]={ "ὢ", "ͅ" },
+ ["ᾣ"]={ "ὣ", "ͅ" },
+ ["ᾤ"]={ "ὤ", "ͅ" },
+ ["ᾥ"]={ "ὥ", "ͅ" },
+ ["ᾦ"]={ "ὦ", "ͅ" },
+ ["ᾧ"]={ "ὧ", "ͅ" },
+ ["ᾨ"]={ "Ὠ", "ͅ" },
+ ["ᾩ"]={ "Ὡ", "ͅ" },
+ ["ᾪ"]={ "Ὢ", "ͅ" },
+ ["ᾫ"]={ "Ὣ", "ͅ" },
+ ["ᾬ"]={ "Ὤ", "ͅ" },
+ ["ᾭ"]={ "Ὥ", "ͅ" },
+ ["ᾮ"]={ "Ὦ", "ͅ" },
+ ["ᾯ"]={ "Ὧ", "ͅ" },
+ ["ᾰ"]={ "α", "̆" },
+ ["ᾱ"]={ "α", "̄" },
+ ["ᾲ"]={ "ὰ", "ͅ" },
+ ["ᾳ"]={ "α", "ͅ" },
+ ["ᾴ"]={ "ά", "ͅ" },
+ ["ᾶ"]={ "α", "͂" },
+ ["ᾷ"]={ "ᾶ", "ͅ" },
+ ["Ᾰ"]={ "Α", "̆" },
+ ["Ᾱ"]={ "Α", "̄" },
+ ["Ὰ"]={ "Α", "̀" },
+ ["ᾼ"]={ "Α", "ͅ" },
+ ["῁"]={ "¨", "͂" },
+ ["ῂ"]={ "ὴ", "ͅ" },
+ ["ῃ"]={ "η", "ͅ" },
+ ["ῄ"]={ "ή", "ͅ" },
+ ["ῆ"]={ "η", "͂" },
+ ["ῇ"]={ "ῆ", "ͅ" },
+ ["Ὲ"]={ "Ε", "̀" },
+ ["Ὴ"]={ "Η", "̀" },
+ ["ῌ"]={ "Η", "ͅ" },
+ ["῍"]={ "᾿", "̀" },
+ ["῎"]={ "᾿", "́" },
+ ["῏"]={ "᾿", "͂" },
+ ["ῐ"]={ "ι", "̆" },
+ ["ῑ"]={ "ι", "̄" },
+ ["ῒ"]={ "ϊ", "̀" },
+ ["ῖ"]={ "ι", "͂" },
+ ["ῗ"]={ "ϊ", "͂" },
+ ["Ῐ"]={ "Ι", "̆" },
+ ["Ῑ"]={ "Ι", "̄" },
+ ["Ὶ"]={ "Ι", "̀" },
+ ["῝"]={ "῾", "̀" },
+ ["῞"]={ "῾", "́" },
+ ["῟"]={ "῾", "͂" },
+ ["ῠ"]={ "υ", "̆" },
+ ["ῡ"]={ "υ", "̄" },
+ ["ῢ"]={ "ϋ", "̀" },
+ ["ῤ"]={ "ρ", "̓" },
+ ["ῥ"]={ "ρ", "̔" },
+ ["ῦ"]={ "υ", "͂" },
+ ["ῧ"]={ "ϋ", "͂" },
+ ["Ῠ"]={ "Υ", "̆" },
+ ["Ῡ"]={ "Υ", "̄" },
+ ["Ὺ"]={ "Υ", "̀" },
+ ["Ῥ"]={ "Ρ", "̔" },
+ ["῭"]={ "¨", "̀" },
+ ["ῲ"]={ "ὼ", "ͅ" },
+ ["ῳ"]={ "ω", "ͅ" },
+ ["ῴ"]={ "ώ", "ͅ" },
+ ["ῶ"]={ "ω", "͂" },
+ ["ῷ"]={ "ῶ", "ͅ" },
+ ["Ὸ"]={ "Ο", "̀" },
+ ["Ὼ"]={ "Ω", "̀" },
+ ["ῼ"]={ "Ω", "ͅ" },
+ ["↚"]={ "←", "̸" },
+ ["↛"]={ "→", "̸" },
+ ["↮"]={ "↔", "̸" },
+ ["⇍"]={ "⇐", "̸" },
+ ["⇎"]={ "⇔", "̸" },
+ ["⇏"]={ "⇒", "̸" },
+ ["∄"]={ "∃", "̸" },
+ ["∉"]={ "∈", "̸" },
+ ["∌"]={ "∋", "̸" },
+ ["∤"]={ "∣", "̸" },
+ ["∦"]={ "∥", "̸" },
+ ["≁"]={ "∼", "̸" },
+ ["≄"]={ "≃", "̸" },
+ ["≇"]={ "≅", "̸" },
+ ["≉"]={ "≈", "̸" },
+ ["≠"]={ "=", "̸" },
+ ["≢"]={ "≡", "̸" },
+ ["≭"]={ "≍", "̸" },
+ ["≮"]={ "<", "̸" },
+ ["≯"]={ ">", "̸" },
+ ["≰"]={ "≤", "̸" },
+ ["≱"]={ "≥", "̸" },
+ ["≴"]={ "≲", "̸" },
+ ["≵"]={ "≳", "̸" },
+ ["≸"]={ "≶", "̸" },
+ ["≹"]={ "≷", "̸" },
+ ["⊀"]={ "≺", "̸" },
+ ["⊁"]={ "≻", "̸" },
+ ["⊄"]={ "⊂", "̸" },
+ ["⊅"]={ "⊃", "̸" },
+ ["⊈"]={ "⊆", "̸" },
+ ["⊉"]={ "⊇", "̸" },
+ ["⊬"]={ "⊢", "̸" },
+ ["⊭"]={ "⊨", "̸" },
+ ["⊮"]={ "⊩", "̸" },
+ ["⊯"]={ "⊫", "̸" },
+ ["⋠"]={ "≼", "̸" },
+ ["⋡"]={ "≽", "̸" },
+ ["⋢"]={ "⊑", "̸" },
+ ["⋣"]={ "⊒", "̸" },
+ ["⋪"]={ "⊲", "̸" },
+ ["⋫"]={ "⊳", "̸" },
+ ["⋬"]={ "⊴", "̸" },
+ ["⋭"]={ "⊵", "̸" },
+ ["⫝̸"]={ "⫝", "̸" },
+ ["が"]={ "か", "゙" },
+ ["ぎ"]={ "き", "゙" },
+ ["ぐ"]={ "く", "゙" },
+ ["げ"]={ "け", "゙" },
+ ["ご"]={ "こ", "゙" },
+ ["ざ"]={ "さ", "゙" },
+ ["じ"]={ "し", "゙" },
+ ["ず"]={ "す", "゙" },
+ ["ぜ"]={ "せ", "゙" },
+ ["ぞ"]={ "そ", "゙" },
+ ["だ"]={ "た", "゙" },
+ ["ぢ"]={ "ち", "゙" },
+ ["づ"]={ "つ", "゙" },
+ ["で"]={ "て", "゙" },
+ ["ど"]={ "と", "゙" },
+ ["ば"]={ "は", "゙" },
+ ["ぱ"]={ "は", "゚" },
+ ["び"]={ "ひ", "゙" },
+ ["ぴ"]={ "ひ", "゚" },
+ ["ぶ"]={ "ふ", "゙" },
+ ["ぷ"]={ "ふ", "゚" },
+ ["べ"]={ "へ", "゙" },
+ ["ぺ"]={ "へ", "゚" },
+ ["ぼ"]={ "ほ", "゙" },
+ ["ぽ"]={ "ほ", "゚" },
+ ["ゔ"]={ "う", "゙" },
+ ["ゞ"]={ "ゝ", "゙" },
+ ["ガ"]={ "カ", "゙" },
+ ["ギ"]={ "キ", "゙" },
+ ["グ"]={ "ク", "゙" },
+ ["ゲ"]={ "ケ", "゙" },
+ ["ゴ"]={ "コ", "゙" },
+ ["ザ"]={ "サ", "゙" },
+ ["ジ"]={ "シ", "゙" },
+ ["ズ"]={ "ス", "゙" },
+ ["ゼ"]={ "セ", "゙" },
+ ["ゾ"]={ "ソ", "゙" },
+ ["ダ"]={ "タ", "゙" },
+ ["ヂ"]={ "チ", "゙" },
+ ["ヅ"]={ "ツ", "゙" },
+ ["デ"]={ "テ", "゙" },
+ ["ド"]={ "ト", "゙" },
+ ["バ"]={ "ハ", "゙" },
+ ["パ"]={ "ハ", "゚" },
+ ["ビ"]={ "ヒ", "゙" },
+ ["ピ"]={ "ヒ", "゚" },
+ ["ブ"]={ "フ", "゙" },
+ ["プ"]={ "フ", "゚" },
+ ["ベ"]={ "ヘ", "゙" },
+ ["ペ"]={ "ヘ", "゚" },
+ ["ボ"]={ "ホ", "゙" },
+ ["ポ"]={ "ホ", "゚" },
+ ["ヴ"]={ "ウ", "゙" },
+ ["ヷ"]={ "ワ", "゙" },
+ ["ヸ"]={ "ヰ", "゙" },
+ ["ヹ"]={ "ヱ", "゙" },
+ ["ヺ"]={ "ヲ", "゙" },
+ ["ヾ"]={ "ヽ", "゙" },
+ ["יִ"]={ "י", "ִ" },
+ ["ײַ"]={ "ײ", "ַ" },
+ ["שׁ"]={ "ש", "ׁ" },
+ ["שׂ"]={ "ש", "ׂ" },
+ ["שּׁ"]={ "שּ", "ׁ" },
+ ["שּׂ"]={ "שּ", "ׂ" },
+ ["אַ"]={ "א", "ַ" },
+ ["אָ"]={ "א", "ָ" },
+ ["אּ"]={ "א", "ּ" },
+ ["בּ"]={ "ב", "ּ" },
+ ["גּ"]={ "ג", "ּ" },
+ ["דּ"]={ "ד", "ּ" },
+ ["הּ"]={ "ה", "ּ" },
+ ["וּ"]={ "ו", "ּ" },
+ ["זּ"]={ "ז", "ּ" },
+ ["טּ"]={ "ט", "ּ" },
+ ["יּ"]={ "י", "ּ" },
+ ["ךּ"]={ "ך", "ּ" },
+ ["כּ"]={ "כ", "ּ" },
+ ["לּ"]={ "ל", "ּ" },
+ ["מּ"]={ "מ", "ּ" },
+ ["נּ"]={ "נ", "ּ" },
+ ["סּ"]={ "ס", "ּ" },
+ ["ףּ"]={ "ף", "ּ" },
+ ["פּ"]={ "פ", "ּ" },
+ ["צּ"]={ "צ", "ּ" },
+ ["קּ"]={ "ק", "ּ" },
+ ["רּ"]={ "ר", "ּ" },
+ ["שּ"]={ "ש", "ּ" },
+ ["תּ"]={ "ת", "ּ" },
+ ["וֹ"]={ "ו", "ֹ" },
+ ["בֿ"]={ "ב", "ֿ" },
+ ["כֿ"]={ "כ", "ֿ" },
+ ["פֿ"]={ "פ", "ֿ" },
+ ["𑂚"]={ "𑂙", "𑂺" },
+ ["𑂜"]={ "𑂛", "𑂺" },
+ ["𑂫"]={ "𑂥", "𑂺" },
+ ["𑄮"]={ "𑄱", "𑄧" },
+ ["𑄯"]={ "𑄲", "𑄧" },
+ ["𑍋"]={ "𑍇", "𑌾" },
+ ["𑍌"]={ "𑍇", "𑍗" },
+ ["𑒻"]={ "𑒹", "𑒺" },
+ ["𑒼"]={ "𑒹", "𑒰" },
+ ["𑒾"]={ "𑒹", "𑒽" },
+ ["𑖺"]={ "𑖸", "𑖯" },
+ ["𑖻"]={ "𑖹", "𑖯" },
+ ["𝅗𝅥"]={ "𝅗", "𝅥" },
+ ["𝅘𝅥"]={ "𝅘", "𝅥" },
+ ["𝅘𝅥𝅮"]={ "𝅘𝅥", "𝅮" },
+ ["𝅘𝅥𝅯"]={ "𝅘𝅥", "𝅯" },
+ ["𝅘𝅥𝅰"]={ "𝅘𝅥", "𝅰" },
+ ["𝅘𝅥𝅱"]={ "𝅘𝅥", "𝅱" },
+ ["𝅘𝅥𝅲"]={ "𝅘𝅥", "𝅲" },
+ ["𝆹𝅥"]={ "𝆹", "𝅥" },
+ ["𝆺𝅥"]={ "𝆺", "𝅥" },
+ ["𝆹𝅥𝅮"]={ "𝆹𝅥", "𝅮" },
+ ["𝆺𝅥𝅮"]={ "𝆺𝅥", "𝅮" },
+ ["𝆹𝅥𝅯"]={ "𝆹𝅥", "𝅯" },
+ ["𝆺𝅥𝅯"]={ "𝆺𝅥", "𝅯" },
+ },
+ },
+ },
+ ["name"]="collapse",
+ ["prepend"]=true,
+ ["type"]="ligature",
+} \ No newline at end of file
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index e59c57a1c..07c490253 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 : c:/data/develop/context/sources/luatex-fonts-merged.lua
-- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date : 02/20/17 17:55:09
+-- merge date : 02/23/17 17:07:53
do -- begin closure to overcome local limits and interference
@@ -3743,6 +3743,27 @@ function number.sparseexponent(f,n)
end
return tostring(n)
end
+local hf={}
+local hs={}
+setmetatable(hf,{ __index=function(t,k)
+ local v="%."..k.."f"
+ t[k]=v
+ return v
+end } )
+setmetatable(hs,{ __index=function(t,k)
+ local v="%"..k.."s"
+ t[k]=v
+ return v
+end } )
+function number.formattedfloat(n,b,a)
+ local s=format(hf[a],n)
+ local l=(b or 0)+(a or 0)+1
+ if #s<l then
+ return format(hs[l],s)
+ else
+ return s
+ end
+end
local template=[[
%s
%s
@@ -3770,6 +3791,7 @@ local autodouble=string.autodouble
local sequenced=table.sequenced
local formattednumber=number.formatted
local sparseexponent=number.sparseexponent
+local formattedfloat=number.formattedfloat
]]
else
environment={
@@ -3793,6 +3815,7 @@ else
sequenced=table.sequenced,
formattednumber=number.formatted,
sparseexponent=number.sparseexponent,
+ formattedfloat=number.formattedfloat
}
end
local arguments={ "a1" }
@@ -3803,6 +3826,7 @@ setmetatable(arguments,{ __index=function(t,k)
end
})
local prefix_any=C((S("+- .")+R("09"))^0)
+local prefix_sub=(C((S("+-")+R("09"))^0)+Cc(0))*P(".")*(C((S("+-")+R("09"))^0)+Cc(0))
local prefix_tab=P("{")*C((1-P("}"))^0)*P("}")+C((1-R("az","AZ","09","%%"))^0)
local format_s=function(f)
n=n+1
@@ -3853,6 +3877,10 @@ local format_F=function(f)
return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n)
end
end
+local format_k=function(b,a)
+ n=n+1
+ return format("formattedfloat(a%s,%i,%i)",n,b or 0,a or 0)
+end
local format_g=function(f)
n=n+1
return format("format('%%%sg',a%s)",f,n)
@@ -4061,7 +4089,8 @@ local builder=Cs { "start",
+V("s")+V("q")+V("i")+V("d")+V("f")+V("F")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o")
+V("c")+V("C")+V("S")
+V("Q")
-+V("N")
++V("N")
++V("k")
+V("r")+V("h")+V("H")+V("u")+V("U")+V("p")+V("b")+V("t")+V("T")+V("l")+V("L")+V("I")+V("w")
+V("W")
+V("a")
@@ -4088,6 +4117,7 @@ local builder=Cs { "start",
["S"]=(prefix_any*P("S"))/format_S,
["Q"]=(prefix_any*P("Q"))/format_S,
["N"]=(prefix_any*P("N"))/format_N,
+ ["k"]=(prefix_sub*P("k"))/format_k,
["c"]=(prefix_any*P("c"))/format_c,
["C"]=(prefix_any*P("C"))/format_C,
["r"]=(prefix_any*P("r"))/format_r,
@@ -4289,6 +4319,7 @@ end
files.readcardinal1=files.readbyte
files.readcardinal=files.readcardinal1
files.readinteger=files.readinteger1
+files.readsignedbyte=files.readinteger1
function files.readcardinal2(f)
local a,b=byte(f:read(2),1,2)
return 0x100*a+b
@@ -8038,11 +8069,9 @@ if not modules then modules={} end modules ['font-otr']={
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
-local next,type,unpack=next,type,unpack
-local byte,lower,char,strip,gsub=string.byte,string.lower,string.char,string.strip,string.gsub
-local bittest=bit32.btest
-local concat,remove,unpack,fastcopy=table.concat,table.remov,table.unpack,table.fastcopy
-local floor,abs,sqrt,round=math.floor,math.abs,math.sqrt,math.round
+local next,type=next,type
+local byte,lower,char,gsub=string.byte,string.lower,string.char,string.gsub
+local floor,round=math.floor,math.round
local P,R,S,C,Cs,Cc,Ct,Carg,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Carg,lpeg.Cmt
local lpegmatch=lpeg.match
local setmetatableindex=table.setmetatableindex
@@ -8082,7 +8111,7 @@ local readufword=readushort
local readoffset=readushort
local read2dot14=streamreader.read2dot14
function streamreader.readtag(f)
- return lower(strip(readstring(f,4)))
+ return lower(stripstring(readstring(f,4)))
end
local function readlongdatetime(f)
local a,b,c,d,e,f,g,h=readbytes(f,8)
@@ -8123,6 +8152,7 @@ local reservednames={ [0]="copyright",
"wwssubfamily",
"lightbackgroundpalette",
"darkbackgroundpalette",
+ "variationspostscriptnameprefix",
}
local platforms={ [0]="unicode",
"macintosh",
@@ -8323,7 +8353,8 @@ function readers.name(f,fontdata,specification)
local encoding=encodings[encoding]
local language=languages[language]
if encoding and language then
- local name=reservednames[readushort(f)]
+ local index=readushort(f)
+ local name=reservednames[index]
if name then
namelist[#namelist+1]={
platform=platform,
@@ -8334,7 +8365,13 @@ function readers.name(f,fontdata,specification)
offset=start+readushort(f),
}
else
- skipshort(f,2)
+namelist[#namelist+1]={
+ platform=platform,
+ encoding=encoding,
+ language=language,
+ length=readushort(f),
+ offset=start+readushort(f),
+}
end
else
skipshort(f,3)
@@ -8351,12 +8388,13 @@ function readers.name(f,fontdata,specification)
end
local names={}
local done={}
+ local extras={}
local function filter(platform,e,l)
local namelist=namelists[platform]
for i=1,#namelist do
local name=namelist[i]
local nametag=name.name
- if not done[nametag] then
+ if not done[nametag or i] then
local encoding=name.encoding
local language=name.language
if (not e or encoding==e) and (not l or language==l) then
@@ -8369,13 +8407,16 @@ function readers.name(f,fontdata,specification)
if decoder then
content=decoder(content)
end
- names[nametag]={
- content=content,
- platform=platform,
- encoding=encoding,
- language=language,
- }
- done[nametag]=true
+ if nametag then
+ names[nametag]={
+ content=content,
+ platform=platform,
+ encoding=encoding,
+ language=language,
+ }
+ end
+ extras[i-1]=content
+ done[nametag or i]=true
end
end
end
@@ -8386,6 +8427,7 @@ function readers.name(f,fontdata,specification)
filter("macintosh")
filter("unicode")
fontdata.names=names
+ fontdata.extras=extras
if specification.platformnames then
local collected={}
for platform,namelist in next,namelists do
@@ -8760,7 +8802,8 @@ local sequence={
}
local supported={}
for i=1,#sequence do
- local sp,se,sf=unpack(sequence[i])
+ local si=sequence[i]
+ local sp,se,sf=si[1],si[2],si[3]
local p=supported[sp]
if not p then
p={}
@@ -9136,7 +9179,8 @@ function readers.cmap(f,fontdata,specification)
end
local ok=false
for i=1,#sequence do
- local sp,se,sf=unpack(sequence[i])
+ local si=sequence[i]
+ local sp,se,sf=si[1],si[2],si[3]
if checkcmap(f,fontdata,records,sp,se,sf)>0 then
ok=true
end
@@ -11595,6 +11639,7 @@ local streamreader=readers.streamreader
local setposition=streamreader.setposition
local getposition=streamreader.getposition
local skipshort=streamreader.skipshort
+local skipbytes=streamreader.skip
local readushort=streamreader.readcardinal2
local readulong=streamreader.readcardinal4
local readshort=streamreader.readinteger2
@@ -11602,6 +11647,9 @@ local readfword=readshort
local readstring=streamreader.readstring
local readtag=streamreader.readtag
local readbytes=streamreader.readbytes
+local readfixed=streamreader.readfixed4
+local read2dot14=streamreader.read2dot14
+local readinteger=streamreader.readinteger1
local gsubhandlers={}
local gposhandlers={}
local lookupidoffset=-1
@@ -13701,6 +13749,166 @@ function readers.svg(f,fontdata,specification)
fontdata.hascolor=true
end
end
+function readers.fvar(f,fontdata,specification)
+ local datatable=fontdata.tables.fvar
+ if datatable then
+ local tableoffset=datatable.offset
+ setposition(f,tableoffset)
+ local majorversion=readushort(f)
+ local minorversion=readushort(f)
+ if majorversion~=1 and minorversion~=0 then
+ report("table version %a.%a of %a is not supported (yet), maybe font %s is bad",
+ majorversion,minorversion,"fvar",fontdata.filename)
+ return
+ end
+ local offsettoaxis=tableoffset+readushort(f)
+ local nofsizepairs=readushort(f)
+ local nofaxis=readushort(f)
+ local sizeofaxis=readushort(f)
+ local nofinstances=readushort(f)
+ local sizeofinstances=readushort(f)
+ local extras=fontdata.extras
+ local axis={}
+ local instances={}
+ setposition(f,offsettoaxis)
+ local function readtuple(f)
+ local t={}
+ for i=1,nofaxis do
+ t[i]=readfixed(f)
+ end
+ return t
+ end
+ for i=1,nofaxis do
+ axis[i]={
+ tag=readtag(f),
+ minimum=readfixed(f),
+ default=readfixed(f),
+ maximum=readfixed(f),
+ flags=readushort(f),
+ nameid=extras[readushort(f)],
+ }
+ local n=sizeofaxis-20
+ if n>0 then
+ skipbytes(f,n)
+ elseif n<0 then
+ end
+ end
+ for i=1,nofinstances do
+ local subfamid=readushort(f)
+ local flags=readushort(f)
+ local tuple=readtuple(f)
+ local psnameid=false
+ local nofbytes=2+2+#tuple*2
+ if nofbytes<sizeofinstances then
+ psnameid=readushort(f)
+ nofbytes=nofbytes+2
+ end
+ instances[i]={
+ subfamily=extras[subfamid],
+ flags=flags,
+ tuple=tuple,
+ psname=extras[psnameid] or nil,
+ }
+ if nofbytes>0 then
+ skipbytes(f,nofbytes)
+ end
+ end
+ fontdata.variable={
+ axis=axis,
+ instances=instances,
+ }
+ end
+end
+local tags={
+ hasc="",
+ hdsc="",
+ vasc="",
+ vdsc="",
+ vlgp="",
+ xhgt="",
+ cpht="",
+}
+function readers.mvar(f,fontdata,specification)
+ local datatable=fontdata.tables.mvar
+ if datatable then
+ local tableoffset=datatable.offset
+ setposition(f,tableoffset)
+ local majorversion=readushort(f)
+ local minorversion=readushort(f)
+ if majorversion~=1 and minorversion~=0 then
+ report("table version %a.%a of %a is not supported (yet), maybe font %s is bad",
+ majorversion,minorversion,"fvar",fontdata.filename)
+ return
+ end
+ local nofaxis=readushort(f)
+ local recordsize=readushort(f)
+ local nofrecords=readushort(f)
+ local offsettostore=tableoffset+readushort(f)
+ local records={}
+ local dimensions={}
+ local store={}
+ local regions={}
+ for i=1,nofrecords do
+ local tag=readtag(f)
+ if tags[tag] then
+ dimensions[tag]={
+ outer=readushort(f),
+ inner=readushort(f),
+ }
+ else
+ skipshort(f,2)
+ end
+ end
+ setposition(f,offsettostore)
+ local nofaxis=readushort(f)
+ local nofregions=readushort(f)
+ for i=1,nofregions do
+ local t={}
+ for i=1,nofaxis do
+ t[i]={
+ start=read2dot14(f),
+ peak=read2dot14(f),
+ stop=read2dot14(f),
+ }
+ end
+ regions[i]=t
+ end
+ local format=readushort(f)
+ local offset=offsettostore+readulong(f)
+ local nofdata=readushort(f)
+ local data={}
+ for i=1,nofdata do
+ data[i]=readulong(f)+offset
+ end
+ for i=1,nofdata do
+ local offset=data[i]
+ setposition(f,offset)
+ local nofdeltas=readushort(f)
+ local nofshort=readushort(f)
+ local nofregions=readushort(f)
+ local deltas={}
+ local regions={}
+ local length=nofshort+nofregions
+ for i=1,nofregions do
+ regions[i]=readushort(f)
+ end
+ for i=1,nofdeltas do
+ local t={}
+ for i=1,nofshort do
+ t[i]=readushort(f)
+ end
+ for i=1,nofregions do
+ t[nofshort+i]=readinteger(f)
+ end
+ deltas[i]=t
+ end
+ data[i]={
+ regions=regions,
+ deltas=deltas,
+ }
+ end
+ end
+end
end -- closure
@@ -16773,7 +16981,7 @@ if not modules then modules={} end modules ['font-otj']={
license="see context related readme files",
}
if not nodes.properties then return end
-local next,rawget=next,rawget
+local next,rawget,tonumber=next,rawget,tonumber
local fastcopy=table.fastcopy
local registertracker=trackers.register
local trace_injections=false registertracker("fonts.injections",function(v) trace_injections=v end)
@@ -18490,7 +18698,6 @@ local attributes=attributes
local fonts=fonts
local otf=fonts.handlers.otf
local tracers=nodes.tracers
-local trace_lookups=false registertracker("otf.lookups",function(v) trace_lookups=v end)
local trace_singles=false registertracker("otf.singles",function(v) trace_singles=v end)
local trace_multiples=false registertracker("otf.multiples",function(v) trace_multiples=v end)
local trace_alternatives=false registertracker("otf.alternatives",function(v) trace_alternatives=v end)
@@ -18905,7 +19112,9 @@ local function multiple_glyphs(head,start,multiple,ignoremarks,what)
end
local function get_alternative_glyph(start,alternatives,value)
local n=#alternatives
- if value=="random" then
+ if n==1 then
+ return alternatives[1],trace_alternatives and "1 (only one present)"
+ elseif value=="random" then
local r=getrandom and getrandom("glyph",1,n) or random(1,n)
return alternatives[r],trace_alternatives and formatters["value %a, taking %a"](value,r)
elseif value=="first" then
@@ -20311,7 +20520,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
local l=ck[5]
size=l-f+1
if size>1 then
- local discfound=nil
+ local discfound
local n=f+1
last=startnext
while n<=l do
@@ -20432,7 +20641,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
prev=getprev(sweepnode)
end
if prev then
- local discfound=nil
+ local discfound
local n=f-1
while n>=1 do
if prev then
@@ -20541,7 +20750,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
end
end
prev=getprev(prev)
- elseif seq[n][32] and id==glue_code and isspace(prev,threshold,id) then
+ elseif id==glue_code and seq[n][32] and isspace(prev,threshold,id) then
n=n-1
prev=getprev(prev)
else
@@ -20562,13 +20771,11 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
end
if match and s>l then
local current=last and getnext(last)
- if not current then
- if sweeptype=="post" or sweeptype=="replace" then
- current=getnext(sweepnode)
- end
+ if not current and (sweeptype=="post" or sweeptype=="replace") then
+ current=getnext(sweepnode)
end
if current then
- local discfound=nil
+ local discfound
local n=l+1
while n<=s do
if current then
@@ -20668,7 +20875,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
else
end
current=getnext(current)
- elseif seq[n][32] and id==glue_code and isspace(current,threshold,id) then
+ elseif id==glue_code and seq[n][32] and isspace(current,threshold,id) then
n=n+1
current=getnext(current)
else
@@ -21511,6 +21718,8 @@ local function featuresprocessor(head,font,attr)
end
elseif char==false then
start=getnext(start)
+ elseif id==glue_code then
+ start=getnext(start)
elseif id==disc_code then
local ok
if gpossing then
@@ -21574,6 +21783,8 @@ local function featuresprocessor(head,font,attr)
end
elseif char==false then
start=getnext(start)
+ elseif id==glue_code then
+ start=getnext(start)
elseif id==disc_code then
local ok
if gpossing then
@@ -24278,13 +24489,15 @@ local function addfeature(data,feature,specifications)
local coveractions=coverup.actions
local stepkey=coverup.stepkey
local register=coverup.register
- local function prepare_substitution(list,featuretype)
+ local function prepare_substitution(list,featuretype,nocheck)
local coverage={}
local cover=coveractions[featuretype]
for code,replacement in next,list do
local unicode=tounicode(code)
local description=descriptions[unicode]
- if description then
+ if not nocheck and not description then
+ skip=skip+1
+ else
if type(replacement)=="table" then
replacement=replacement[1]
end
@@ -24295,19 +24508,17 @@ local function addfeature(data,feature,specifications)
else
skip=skip+1
end
- else
- skip=skip+1
end
end
return coverage
end
- local function prepare_alternate(list,featuretype)
+ local function prepare_alternate(list,featuretype,nocheck)
local coverage={}
local cover=coveractions[featuretype]
for code,replacement in next,list do
local unicode=tounicode(code)
local description=descriptions[unicode]
- if not description then
+ if not nocheck and not description then
skip=skip+1
elseif type(replacement)=="table" then
local r={}
@@ -24329,13 +24540,13 @@ local function addfeature(data,feature,specifications)
end
return coverage
end
- local function prepare_multiple(list,featuretype)
+ local function prepare_multiple(list,featuretype,nocheck)
local coverage={}
local cover=coveractions[featuretype]
for code,replacement in next,list do
local unicode=tounicode(code)
local description=descriptions[unicode]
- if not description then
+ if not nocheck and not description then
skip=skip+1
elseif type(replacement)=="table" then
local r,n={},0
@@ -24362,15 +24573,18 @@ local function addfeature(data,feature,specifications)
end
end
end
+ inspect(coverage)
return coverage
end
- local function prepare_ligature(list,featuretype)
+ local function prepare_ligature(list,featuretype,nocheck)
local coverage={}
local cover=coveractions[featuretype]
for code,ligature in next,list do
local unicode=tounicode(code)
local description=descriptions[unicode]
- if description then
+ if not nocheck and not description then
+ skip=skip+1
+ else
if type(ligature)=="string" then
ligature={ lpegmatch(splitter,ligature) }
end
@@ -24391,8 +24605,6 @@ local function addfeature(data,feature,specifications)
else
skip=skip+1
end
- else
- skip=skip+1
end
end
return coverage
@@ -24620,6 +24832,7 @@ local function addfeature(data,feature,specifications)
local askedsteps=specification.steps or specification.subtables or { specification.data } or {}
local featuretype=normalized[specification.type or "substitution"] or "substitution"
local featureflags=specification.flags or noflags
+ local nocheck=specification.nocheck
local featureorder=specification.order or { feature }
local featurechain=(featuretype=="chainsubstitution" or featuretype=="chainposition") and 1 or 0
local nofsteps=0
@@ -24640,13 +24853,13 @@ local function addfeature(data,feature,specifications)
local coverage=nil
local format=nil
if featuretype=="substitution" then
- coverage=prepare_substitution(list,featuretype)
+ coverage=prepare_substitution(list,featuretype,nocheck)
elseif featuretype=="ligature" then
- coverage=prepare_ligature(list,featuretype)
+ coverage=prepare_ligature(list,featuretype,nocheck)
elseif featuretype=="alternate" then
- coverage=prepare_alternate(list,featuretype)
+ coverage=prepare_alternate(list,featuretype,nocheck)
elseif featuretype=="multiple" then
- coverage=prepare_multiple(list,featuretype)
+ coverage=prepare_multiple(list,featuretype,nocheck)
elseif featuretype=="kern" then
format="kern"
coverage=prepare_kern(list,featuretype)
@@ -24673,16 +24886,16 @@ local function addfeature(data,feature,specifications)
local format=nil
if featuretype=="substitution" then
category="gsub"
- coverage=prepare_substitution(list,featuretype)
+ coverage=prepare_substitution(list,featuretype,nocheck)
elseif featuretype=="ligature" then
category="gsub"
- coverage=prepare_ligature(list,featuretype)
+ coverage=prepare_ligature(list,featuretype,nocheck)
elseif featuretype=="alternate" then
category="gsub"
- coverage=prepare_alternate(list,featuretype)
+ coverage=prepare_alternate(list,featuretype,nocheck)
elseif featuretype=="multiple" then
category="gsub"
- coverage=prepare_multiple(list,featuretype)
+ coverage=prepare_multiple(list,featuretype,nocheck)
elseif featuretype=="kern" then
category="gpos"
format="kern"
@@ -27332,6 +27545,2076 @@ end -- closure
do -- begin closure to overcome local limits and interference
+
+fonts.handlers.otf.addfeature {
+ ["dataset"]={
+ {
+ ["data"]={
+ ["À"]={ "A","̀" },
+ ["Á"]={ "A","́" },
+ ["Â"]={ "A","̂" },
+ ["Ã"]={ "A","̃" },
+ ["Ä"]={ "A","̈" },
+ ["Å"]={ "A","̊" },
+ ["Ç"]={ "C","̧" },
+ ["È"]={ "E","̀" },
+ ["É"]={ "E","́" },
+ ["Ê"]={ "E","̂" },
+ ["Ë"]={ "E","̈" },
+ ["Ì"]={ "I","̀" },
+ ["Í"]={ "I","́" },
+ ["Î"]={ "I","̂" },
+ ["Ï"]={ "I","̈" },
+ ["Ñ"]={ "N","̃" },
+ ["Ò"]={ "O","̀" },
+ ["Ó"]={ "O","́" },
+ ["Ô"]={ "O","̂" },
+ ["Õ"]={ "O","̃" },
+ ["Ö"]={ "O","̈" },
+ ["Ù"]={ "U","̀" },
+ ["Ú"]={ "U","́" },
+ ["Û"]={ "U","̂" },
+ ["Ü"]={ "U","̈" },
+ ["Ý"]={ "Y","́" },
+ ["à"]={ "a","̀" },
+ ["á"]={ "a","́" },
+ ["â"]={ "a","̂" },
+ ["ã"]={ "a","̃" },
+ ["ä"]={ "a","̈" },
+ ["å"]={ "a","̊" },
+ ["ç"]={ "c","̧" },
+ ["è"]={ "e","̀" },
+ ["é"]={ "e","́" },
+ ["ê"]={ "e","̂" },
+ ["ë"]={ "e","̈" },
+ ["ì"]={ "i","̀" },
+ ["í"]={ "i","́" },
+ ["î"]={ "i","̂" },
+ ["ï"]={ "i","̈" },
+ ["ñ"]={ "n","̃" },
+ ["ò"]={ "o","̀" },
+ ["ó"]={ "o","́" },
+ ["ô"]={ "o","̂" },
+ ["õ"]={ "o","̃" },
+ ["ö"]={ "o","̈" },
+ ["ù"]={ "u","̀" },
+ ["ú"]={ "u","́" },
+ ["û"]={ "u","̂" },
+ ["ü"]={ "u","̈" },
+ ["ý"]={ "y","́" },
+ ["ÿ"]={ "y","̈" },
+ ["Ā"]={ "A","̄" },
+ ["ā"]={ "a","̄" },
+ ["Ă"]={ "A","̆" },
+ ["ă"]={ "a","̆" },
+ ["Ą"]={ "A","̨" },
+ ["ą"]={ "a","̨" },
+ ["Ć"]={ "C","́" },
+ ["ć"]={ "c","́" },
+ ["Ĉ"]={ "C","̂" },
+ ["ĉ"]={ "c","̂" },
+ ["Ċ"]={ "C","̇" },
+ ["ċ"]={ "c","̇" },
+ ["Č"]={ "C","̌" },
+ ["č"]={ "c","̌" },
+ ["Ď"]={ "D","̌" },
+ ["ď"]={ "d","̌" },
+ ["Ē"]={ "E","̄" },
+ ["ē"]={ "e","̄" },
+ ["Ĕ"]={ "E","̆" },
+ ["ĕ"]={ "e","̆" },
+ ["Ė"]={ "E","̇" },
+ ["ė"]={ "e","̇" },
+ ["Ę"]={ "E","̨" },
+ ["ę"]={ "e","̨" },
+ ["Ě"]={ "E","̌" },
+ ["ě"]={ "e","̌" },
+ ["Ĝ"]={ "G","̂" },
+ ["ĝ"]={ "g","̂" },
+ ["Ğ"]={ "G","̆" },
+ ["ğ"]={ "g","̆" },
+ ["Ġ"]={ "G","̇" },
+ ["ġ"]={ "g","̇" },
+ ["Ģ"]={ "G","̧" },
+ ["ģ"]={ "g","̧" },
+ ["Ĥ"]={ "H","̂" },
+ ["ĥ"]={ "h","̂" },
+ ["Ĩ"]={ "I","̃" },
+ ["ĩ"]={ "i","̃" },
+ ["Ī"]={ "I","̄" },
+ ["ī"]={ "i","̄" },
+ ["Ĭ"]={ "I","̆" },
+ ["ĭ"]={ "i","̆" },
+ ["Į"]={ "I","̨" },
+ ["į"]={ "i","̨" },
+ ["İ"]={ "I","̇" },
+ ["Ĵ"]={ "J","̂" },
+ ["ĵ"]={ "j","̂" },
+ ["Ķ"]={ "K","̧" },
+ ["ķ"]={ "k","̧" },
+ ["Ĺ"]={ "L","́" },
+ ["ĺ"]={ "l","́" },
+ ["Ļ"]={ "L","̧" },
+ ["ļ"]={ "l","̧" },
+ ["Ľ"]={ "L","̌" },
+ ["ľ"]={ "l","̌" },
+ ["Ń"]={ "N","́" },
+ ["ń"]={ "n","́" },
+ ["Ņ"]={ "N","̧" },
+ ["ņ"]={ "n","̧" },
+ ["Ň"]={ "N","̌" },
+ ["ň"]={ "n","̌" },
+ ["Ō"]={ "O","̄" },
+ ["ō"]={ "o","̄" },
+ ["Ŏ"]={ "O","̆" },
+ ["ŏ"]={ "o","̆" },
+ ["Ő"]={ "O","̋" },
+ ["ő"]={ "o","̋" },
+ ["Ŕ"]={ "R","́" },
+ ["ŕ"]={ "r","́" },
+ ["Ŗ"]={ "R","̧" },
+ ["ŗ"]={ "r","̧" },
+ ["Ř"]={ "R","̌" },
+ ["ř"]={ "r","̌" },
+ ["Ś"]={ "S","́" },
+ ["ś"]={ "s","́" },
+ ["Ŝ"]={ "S","̂" },
+ ["ŝ"]={ "s","̂" },
+ ["Ş"]={ "S","̧" },
+ ["ş"]={ "s","̧" },
+ ["Š"]={ "S","̌" },
+ ["š"]={ "s","̌" },
+ ["Ţ"]={ "T","̧" },
+ ["ţ"]={ "t","̧" },
+ ["Ť"]={ "T","̌" },
+ ["ť"]={ "t","̌" },
+ ["Ũ"]={ "U","̃" },
+ ["ũ"]={ "u","̃" },
+ ["Ū"]={ "U","̄" },
+ ["ū"]={ "u","̄" },
+ ["Ŭ"]={ "U","̆" },
+ ["ŭ"]={ "u","̆" },
+ ["Ů"]={ "U","̊" },
+ ["ů"]={ "u","̊" },
+ ["Ű"]={ "U","̋" },
+ ["ű"]={ "u","̋" },
+ ["Ų"]={ "U","̨" },
+ ["ų"]={ "u","̨" },
+ ["Ŵ"]={ "W","̂" },
+ ["ŵ"]={ "w","̂" },
+ ["Ŷ"]={ "Y","̂" },
+ ["ŷ"]={ "y","̂" },
+ ["Ÿ"]={ "Y","̈" },
+ ["Ź"]={ "Z","́" },
+ ["ź"]={ "z","́" },
+ ["Ż"]={ "Z","̇" },
+ ["ż"]={ "z","̇" },
+ ["Ž"]={ "Z","̌" },
+ ["ž"]={ "z","̌" },
+ ["Ơ"]={ "O","̛" },
+ ["ơ"]={ "o","̛" },
+ ["Ư"]={ "U","̛" },
+ ["ư"]={ "u","̛" },
+ ["Ǎ"]={ "A","̌" },
+ ["ǎ"]={ "a","̌" },
+ ["Ǐ"]={ "I","̌" },
+ ["ǐ"]={ "i","̌" },
+ ["Ǒ"]={ "O","̌" },
+ ["ǒ"]={ "o","̌" },
+ ["Ǔ"]={ "U","̌" },
+ ["ǔ"]={ "u","̌" },
+ ["Ǖ"]={ "Ü","̄" },
+ ["ǖ"]={ "ü","̄" },
+ ["Ǘ"]={ "Ü","́" },
+ ["ǘ"]={ "ü","́" },
+ ["Ǚ"]={ "Ü","̌" },
+ ["ǚ"]={ "ü","̌" },
+ ["Ǜ"]={ "Ü","̀" },
+ ["ǜ"]={ "ü","̀" },
+ ["Ǟ"]={ "Ä","̄" },
+ ["ǟ"]={ "ä","̄" },
+ ["Ǡ"]={ "Ȧ","̄" },
+ ["ǡ"]={ "ȧ","̄" },
+ ["Ǣ"]={ "Æ","̄" },
+ ["ǣ"]={ "æ","̄" },
+ ["Ǧ"]={ "G","̌" },
+ ["ǧ"]={ "g","̌" },
+ ["Ǩ"]={ "K","̌" },
+ ["ǩ"]={ "k","̌" },
+ ["Ǫ"]={ "O","̨" },
+ ["ǫ"]={ "o","̨" },
+ ["Ǭ"]={ "Ǫ","̄" },
+ ["ǭ"]={ "ǫ","̄" },
+ ["Ǯ"]={ "Ʒ","̌" },
+ ["ǯ"]={ "ʒ","̌" },
+ ["ǰ"]={ "j","̌" },
+ ["Ǵ"]={ "G","́" },
+ ["ǵ"]={ "g","́" },
+ ["Ǹ"]={ "N","̀" },
+ ["ǹ"]={ "n","̀" },
+ ["Ǻ"]={ "Å","́" },
+ ["ǻ"]={ "å","́" },
+ ["Ǽ"]={ "Æ","́" },
+ ["ǽ"]={ "æ","́" },
+ ["Ǿ"]={ "Ø","́" },
+ ["ǿ"]={ "ø","́" },
+ ["Ȁ"]={ "A","̏" },
+ ["ȁ"]={ "a","̏" },
+ ["Ȃ"]={ "A","̑" },
+ ["ȃ"]={ "a","̑" },
+ ["Ȅ"]={ "E","̏" },
+ ["ȅ"]={ "e","̏" },
+ ["Ȇ"]={ "E","̑" },
+ ["ȇ"]={ "e","̑" },
+ ["Ȉ"]={ "I","̏" },
+ ["ȉ"]={ "i","̏" },
+ ["Ȋ"]={ "I","̑" },
+ ["ȋ"]={ "i","̑" },
+ ["Ȍ"]={ "O","̏" },
+ ["ȍ"]={ "o","̏" },
+ ["Ȏ"]={ "O","̑" },
+ ["ȏ"]={ "o","̑" },
+ ["Ȑ"]={ "R","̏" },
+ ["ȑ"]={ "r","̏" },
+ ["Ȓ"]={ "R","̑" },
+ ["ȓ"]={ "r","̑" },
+ ["Ȕ"]={ "U","̏" },
+ ["ȕ"]={ "u","̏" },
+ ["Ȗ"]={ "U","̑" },
+ ["ȗ"]={ "u","̑" },
+ ["Ș"]={ "S","̦" },
+ ["ș"]={ "s","̦" },
+ ["Ț"]={ "T","̦" },
+ ["ț"]={ "t","̦" },
+ ["Ȟ"]={ "H","̌" },
+ ["ȟ"]={ "h","̌" },
+ ["Ȧ"]={ "A","̇" },
+ ["ȧ"]={ "a","̇" },
+ ["Ȩ"]={ "E","̧" },
+ ["ȩ"]={ "e","̧" },
+ ["Ȫ"]={ "Ö","̄" },
+ ["ȫ"]={ "ö","̄" },
+ ["Ȭ"]={ "Õ","̄" },
+ ["ȭ"]={ "õ","̄" },
+ ["Ȯ"]={ "O","̇" },
+ ["ȯ"]={ "o","̇" },
+ ["Ȱ"]={ "Ȯ","̄" },
+ ["ȱ"]={ "ȯ","̄" },
+ ["Ȳ"]={ "Y","̄" },
+ ["ȳ"]={ "y","̄" },
+ ["̈́"]={ "̈","́" },
+ ["΅"]={ "¨","́" },
+ ["Ά"]={ "Α","́" },
+ ["Έ"]={ "Ε","́" },
+ ["Ή"]={ "Η","́" },
+ ["Ί"]={ "Ι","́" },
+ ["Ό"]={ "Ο","́" },
+ ["Ύ"]={ "Υ","́" },
+ ["Ώ"]={ "Ω","́" },
+ ["ΐ"]={ "ϊ","́" },
+ ["Ϊ"]={ "Ι","̈" },
+ ["Ϋ"]={ "Υ","̈" },
+ ["ά"]={ "α","́" },
+ ["έ"]={ "ε","́" },
+ ["ή"]={ "η","́" },
+ ["ί"]={ "ι","́" },
+ ["ΰ"]={ "ϋ","́" },
+ ["ϊ"]={ "ι","̈" },
+ ["ϋ"]={ "υ","̈" },
+ ["ό"]={ "ο","́" },
+ ["ύ"]={ "υ","́" },
+ ["ώ"]={ "ω","́" },
+ ["ϓ"]={ "ϒ","́" },
+ ["ϔ"]={ "ϒ","̈" },
+ ["Ѐ"]={ "Е","̀" },
+ ["Ё"]={ "Е","̈" },
+ ["Ѓ"]={ "Г","́" },
+ ["Ї"]={ "І","̈" },
+ ["Ќ"]={ "К","́" },
+ ["Ѝ"]={ "И","̀" },
+ ["Ў"]={ "У","̆" },
+ ["Й"]={ "И","̆" },
+ ["й"]={ "и","̆" },
+ ["ѐ"]={ "е","̀" },
+ ["ё"]={ "е","̈" },
+ ["ѓ"]={ "г","́" },
+ ["ї"]={ "і","̈" },
+ ["ќ"]={ "к","́" },
+ ["ѝ"]={ "и","̀" },
+ ["ў"]={ "у","̆" },
+ ["Ѷ"]={ "Ѵ","̏" },
+ ["ѷ"]={ "ѵ","̏" },
+ ["Ӂ"]={ "Ж","̆" },
+ ["ӂ"]={ "ж","̆" },
+ ["Ӑ"]={ "А","̆" },
+ ["ӑ"]={ "а","̆" },
+ ["Ӓ"]={ "А","̈" },
+ ["ӓ"]={ "а","̈" },
+ ["Ӗ"]={ "Е","̆" },
+ ["ӗ"]={ "е","̆" },
+ ["Ӛ"]={ "Ә","̈" },
+ ["ӛ"]={ "ә","̈" },
+ ["Ӝ"]={ "Ж","̈" },
+ ["ӝ"]={ "ж","̈" },
+ ["Ӟ"]={ "З","̈" },
+ ["ӟ"]={ "з","̈" },
+ ["Ӣ"]={ "И","̄" },
+ ["ӣ"]={ "и","̄" },
+ ["Ӥ"]={ "И","̈" },
+ ["ӥ"]={ "и","̈" },
+ ["Ӧ"]={ "О","̈" },
+ ["ӧ"]={ "о","̈" },
+ ["Ӫ"]={ "Ө","̈" },
+ ["ӫ"]={ "ө","̈" },
+ ["Ӭ"]={ "Э","̈" },
+ ["ӭ"]={ "э","̈" },
+ ["Ӯ"]={ "У","̄" },
+ ["ӯ"]={ "у","̄" },
+ ["Ӱ"]={ "У","̈" },
+ ["ӱ"]={ "у","̈" },
+ ["Ӳ"]={ "У","̋" },
+ ["ӳ"]={ "у","̋" },
+ ["Ӵ"]={ "Ч","̈" },
+ ["ӵ"]={ "ч","̈" },
+ ["Ӹ"]={ "Ы","̈" },
+ ["ӹ"]={ "ы","̈" },
+ ["آ"]={ "ا","ٓ" },
+ ["أ"]={ "ا","ٔ" },
+ ["ؤ"]={ "و","ٔ" },
+ ["إ"]={ "ا","ٕ" },
+ ["ئ"]={ "ي","ٔ" },
+ ["ۀ"]={ "ە","ٔ" },
+ ["ۂ"]={ "ہ","ٔ" },
+ ["ۓ"]={ "ے","ٔ" },
+ ["ऩ"]={ "न","़" },
+ ["ऱ"]={ "र","़" },
+ ["ऴ"]={ "ळ","़" },
+ ["क़"]={ "क","़" },
+ ["ख़"]={ "ख","़" },
+ ["ग़"]={ "ग","़" },
+ ["ज़"]={ "ज","़" },
+ ["ड़"]={ "ड","़" },
+ ["ढ़"]={ "ढ","़" },
+ ["फ़"]={ "फ","़" },
+ ["य़"]={ "य","़" },
+ ["ো"]={ "ে","া" },
+ ["ৌ"]={ "ে","ৗ" },
+ ["ড়"]={ "ড","়" },
+ ["ঢ়"]={ "ঢ","়" },
+ ["য়"]={ "য","়" },
+ ["ਲ਼"]={ "ਲ","਼" },
+ ["ਸ਼"]={ "ਸ","਼" },
+ ["ਖ਼"]={ "ਖ","਼" },
+ ["ਗ਼"]={ "ਗ","਼" },
+ ["ਜ਼"]={ "ਜ","਼" },
+ ["ਫ਼"]={ "ਫ","਼" },
+ ["ୈ"]={ "େ","ୖ" },
+ ["ୋ"]={ "େ","ା" },
+ ["ୌ"]={ "େ","ୗ" },
+ ["ଡ଼"]={ "ଡ","଼" },
+ ["ଢ଼"]={ "ଢ","଼" },
+ ["ஔ"]={ "ஒ","ௗ" },
+ ["ொ"]={ "ெ","ா" },
+ ["ோ"]={ "ே","ா" },
+ ["ௌ"]={ "ெ","ௗ" },
+ ["ై"]={ "ె","ౖ" },
+ ["ೀ"]={ "ಿ","ೕ" },
+ ["ೇ"]={ "ೆ","ೕ" },
+ ["ೈ"]={ "ೆ","ೖ" },
+ ["ೊ"]={ "ೆ","ೂ" },
+ ["ೋ"]={ "ೊ","ೕ" },
+ ["ൊ"]={ "െ","ാ" },
+ ["ോ"]={ "േ","ാ" },
+ ["ൌ"]={ "െ","ൗ" },
+ ["ේ"]={ "ෙ","්" },
+ ["ො"]={ "ෙ","ා" },
+ ["ෝ"]={ "ො","්" },
+ ["ෞ"]={ "ෙ","ෟ" },
+ ["གྷ"]={ "ག","ྷ" },
+ ["ཌྷ"]={ "ཌ","ྷ" },
+ ["དྷ"]={ "ད","ྷ" },
+ ["བྷ"]={ "བ","ྷ" },
+ ["ཛྷ"]={ "ཛ","ྷ" },
+ ["ཀྵ"]={ "ཀ","ྵ" },
+ ["ཱི"]={ "ཱ","ི" },
+ ["ཱུ"]={ "ཱ","ུ" },
+ ["ྲྀ"]={ "ྲ","ྀ" },
+ ["ླྀ"]={ "ླ","ྀ" },
+ ["ཱྀ"]={ "ཱ","ྀ" },
+ ["ྒྷ"]={ "ྒ","ྷ" },
+ ["ྜྷ"]={ "ྜ","ྷ" },
+ ["ྡྷ"]={ "ྡ","ྷ" },
+ ["ྦྷ"]={ "ྦ","ྷ" },
+ ["ྫྷ"]={ "ྫ","ྷ" },
+ ["ྐྵ"]={ "ྐ","ྵ" },
+ ["ဦ"]={ "ဥ","ီ" },
+ ["ᬆ"]={ "ᬅ","ᬵ" },
+ ["ᬈ"]={ "ᬇ","ᬵ" },
+ ["ᬊ"]={ "ᬉ","ᬵ" },
+ ["ᬌ"]={ "ᬋ","ᬵ" },
+ ["ᬎ"]={ "ᬍ","ᬵ" },
+ ["ᬒ"]={ "ᬑ","ᬵ" },
+ ["ᬻ"]={ "ᬺ","ᬵ" },
+ ["ᬽ"]={ "ᬼ","ᬵ" },
+ ["ᭀ"]={ "ᬾ","ᬵ" },
+ ["ᭁ"]={ "ᬿ","ᬵ" },
+ ["ᭃ"]={ "ᭂ","ᬵ" },
+ ["Ḁ"]={ "A","̥" },
+ ["ḁ"]={ "a","̥" },
+ ["Ḃ"]={ "B","̇" },
+ ["ḃ"]={ "b","̇" },
+ ["Ḅ"]={ "B","̣" },
+ ["ḅ"]={ "b","̣" },
+ ["Ḇ"]={ "B","̱" },
+ ["ḇ"]={ "b","̱" },
+ ["Ḉ"]={ "Ç","́" },
+ ["ḉ"]={ "ç","́" },
+ ["Ḋ"]={ "D","̇" },
+ ["ḋ"]={ "d","̇" },
+ ["Ḍ"]={ "D","̣" },
+ ["ḍ"]={ "d","̣" },
+ ["Ḏ"]={ "D","̱" },
+ ["ḏ"]={ "d","̱" },
+ ["Ḑ"]={ "D","̧" },
+ ["ḑ"]={ "d","̧" },
+ ["Ḓ"]={ "D","̭" },
+ ["ḓ"]={ "d","̭" },
+ ["Ḕ"]={ "Ē","̀" },
+ ["ḕ"]={ "ē","̀" },
+ ["Ḗ"]={ "Ē","́" },
+ ["ḗ"]={ "ē","́" },
+ ["Ḙ"]={ "E","̭" },
+ ["ḙ"]={ "e","̭" },
+ ["Ḛ"]={ "E","̰" },
+ ["ḛ"]={ "e","̰" },
+ ["Ḝ"]={ "Ȩ","̆" },
+ ["ḝ"]={ "ȩ","̆" },
+ ["Ḟ"]={ "F","̇" },
+ ["ḟ"]={ "f","̇" },
+ ["Ḡ"]={ "G","̄" },
+ ["ḡ"]={ "g","̄" },
+ ["Ḣ"]={ "H","̇" },
+ ["ḣ"]={ "h","̇" },
+ ["Ḥ"]={ "H","̣" },
+ ["ḥ"]={ "h","̣" },
+ ["Ḧ"]={ "H","̈" },
+ ["ḧ"]={ "h","̈" },
+ ["Ḩ"]={ "H","̧" },
+ ["ḩ"]={ "h","̧" },
+ ["Ḫ"]={ "H","̮" },
+ ["ḫ"]={ "h","̮" },
+ ["Ḭ"]={ "I","̰" },
+ ["ḭ"]={ "i","̰" },
+ ["Ḯ"]={ "Ï","́" },
+ ["ḯ"]={ "ï","́" },
+ ["Ḱ"]={ "K","́" },
+ ["ḱ"]={ "k","́" },
+ ["Ḳ"]={ "K","̣" },
+ ["ḳ"]={ "k","̣" },
+ ["Ḵ"]={ "K","̱" },
+ ["ḵ"]={ "k","̱" },
+ ["Ḷ"]={ "L","̣" },
+ ["ḷ"]={ "l","̣" },
+ ["Ḹ"]={ "Ḷ","̄" },
+ ["ḹ"]={ "ḷ","̄" },
+ ["Ḻ"]={ "L","̱" },
+ ["ḻ"]={ "l","̱" },
+ ["Ḽ"]={ "L","̭" },
+ ["ḽ"]={ "l","̭" },
+ ["Ḿ"]={ "M","́" },
+ ["ḿ"]={ "m","́" },
+ ["Ṁ"]={ "M","̇" },
+ ["ṁ"]={ "m","̇" },
+ ["Ṃ"]={ "M","̣" },
+ ["ṃ"]={ "m","̣" },
+ ["Ṅ"]={ "N","̇" },
+ ["ṅ"]={ "n","̇" },
+ ["Ṇ"]={ "N","̣" },
+ ["ṇ"]={ "n","̣" },
+ ["Ṉ"]={ "N","̱" },
+ ["ṉ"]={ "n","̱" },
+ ["Ṋ"]={ "N","̭" },
+ ["ṋ"]={ "n","̭" },
+ ["Ṍ"]={ "Õ","́" },
+ ["ṍ"]={ "õ","́" },
+ ["Ṏ"]={ "Õ","̈" },
+ ["ṏ"]={ "õ","̈" },
+ ["Ṑ"]={ "Ō","̀" },
+ ["ṑ"]={ "ō","̀" },
+ ["Ṓ"]={ "Ō","́" },
+ ["ṓ"]={ "ō","́" },
+ ["Ṕ"]={ "P","́" },
+ ["ṕ"]={ "p","́" },
+ ["Ṗ"]={ "P","̇" },
+ ["ṗ"]={ "p","̇" },
+ ["Ṙ"]={ "R","̇" },
+ ["ṙ"]={ "r","̇" },
+ ["Ṛ"]={ "R","̣" },
+ ["ṛ"]={ "r","̣" },
+ ["Ṝ"]={ "Ṛ","̄" },
+ ["ṝ"]={ "ṛ","̄" },
+ ["Ṟ"]={ "R","̱" },
+ ["ṟ"]={ "r","̱" },
+ ["Ṡ"]={ "S","̇" },
+ ["ṡ"]={ "s","̇" },
+ ["Ṣ"]={ "S","̣" },
+ ["ṣ"]={ "s","̣" },
+ ["Ṥ"]={ "Ś","̇" },
+ ["ṥ"]={ "ś","̇" },
+ ["Ṧ"]={ "Š","̇" },
+ ["ṧ"]={ "š","̇" },
+ ["Ṩ"]={ "Ṣ","̇" },
+ ["ṩ"]={ "ṣ","̇" },
+ ["Ṫ"]={ "T","̇" },
+ ["ṫ"]={ "t","̇" },
+ ["Ṭ"]={ "T","̣" },
+ ["ṭ"]={ "t","̣" },
+ ["Ṯ"]={ "T","̱" },
+ ["ṯ"]={ "t","̱" },
+ ["Ṱ"]={ "T","̭" },
+ ["ṱ"]={ "t","̭" },
+ ["Ṳ"]={ "U","̤" },
+ ["ṳ"]={ "u","̤" },
+ ["Ṵ"]={ "U","̰" },
+ ["ṵ"]={ "u","̰" },
+ ["Ṷ"]={ "U","̭" },
+ ["ṷ"]={ "u","̭" },
+ ["Ṹ"]={ "Ũ","́" },
+ ["ṹ"]={ "ũ","́" },
+ ["Ṻ"]={ "Ū","̈" },
+ ["ṻ"]={ "ū","̈" },
+ ["Ṽ"]={ "V","̃" },
+ ["ṽ"]={ "v","̃" },
+ ["Ṿ"]={ "V","̣" },
+ ["ṿ"]={ "v","̣" },
+ ["Ẁ"]={ "W","̀" },
+ ["ẁ"]={ "w","̀" },
+ ["Ẃ"]={ "W","́" },
+ ["ẃ"]={ "w","́" },
+ ["Ẅ"]={ "W","̈" },
+ ["ẅ"]={ "w","̈" },
+ ["Ẇ"]={ "W","̇" },
+ ["ẇ"]={ "w","̇" },
+ ["Ẉ"]={ "W","̣" },
+ ["ẉ"]={ "w","̣" },
+ ["Ẋ"]={ "X","̇" },
+ ["ẋ"]={ "x","̇" },
+ ["Ẍ"]={ "X","̈" },
+ ["ẍ"]={ "x","̈" },
+ ["Ẏ"]={ "Y","̇" },
+ ["ẏ"]={ "y","̇" },
+ ["Ẑ"]={ "Z","̂" },
+ ["ẑ"]={ "z","̂" },
+ ["Ẓ"]={ "Z","̣" },
+ ["ẓ"]={ "z","̣" },
+ ["Ẕ"]={ "Z","̱" },
+ ["ẕ"]={ "z","̱" },
+ ["ẖ"]={ "h","̱" },
+ ["ẗ"]={ "t","̈" },
+ ["ẘ"]={ "w","̊" },
+ ["ẙ"]={ "y","̊" },
+ ["ẛ"]={ "ſ","̇" },
+ ["Ạ"]={ "A","̣" },
+ ["ạ"]={ "a","̣" },
+ ["Ả"]={ "A","̉" },
+ ["ả"]={ "a","̉" },
+ ["Ấ"]={ "Â","́" },
+ ["ấ"]={ "â","́" },
+ ["Ầ"]={ "Â","̀" },
+ ["ầ"]={ "â","̀" },
+ ["Ẩ"]={ "Â","̉" },
+ ["ẩ"]={ "â","̉" },
+ ["Ẫ"]={ "Â","̃" },
+ ["ẫ"]={ "â","̃" },
+ ["Ậ"]={ "Ạ","̂" },
+ ["ậ"]={ "ạ","̂" },
+ ["Ắ"]={ "Ă","́" },
+ ["ắ"]={ "ă","́" },
+ ["Ằ"]={ "Ă","̀" },
+ ["ằ"]={ "ă","̀" },
+ ["Ẳ"]={ "Ă","̉" },
+ ["ẳ"]={ "ă","̉" },
+ ["Ẵ"]={ "Ă","̃" },
+ ["ẵ"]={ "ă","̃" },
+ ["Ặ"]={ "Ạ","̆" },
+ ["ặ"]={ "ạ","̆" },
+ ["Ẹ"]={ "E","̣" },
+ ["ẹ"]={ "e","̣" },
+ ["Ẻ"]={ "E","̉" },
+ ["ẻ"]={ "e","̉" },
+ ["Ẽ"]={ "E","̃" },
+ ["ẽ"]={ "e","̃" },
+ ["Ế"]={ "Ê","́" },
+ ["ế"]={ "ê","́" },
+ ["Ề"]={ "Ê","̀" },
+ ["ề"]={ "ê","̀" },
+ ["Ể"]={ "Ê","̉" },
+ ["ể"]={ "ê","̉" },
+ ["Ễ"]={ "Ê","̃" },
+ ["ễ"]={ "ê","̃" },
+ ["Ệ"]={ "Ẹ","̂" },
+ ["ệ"]={ "ẹ","̂" },
+ ["Ỉ"]={ "I","̉" },
+ ["ỉ"]={ "i","̉" },
+ ["Ị"]={ "I","̣" },
+ ["ị"]={ "i","̣" },
+ ["Ọ"]={ "O","̣" },
+ ["ọ"]={ "o","̣" },
+ ["Ỏ"]={ "O","̉" },
+ ["ỏ"]={ "o","̉" },
+ ["Ố"]={ "Ô","́" },
+ ["ố"]={ "ô","́" },
+ ["Ồ"]={ "Ô","̀" },
+ ["ồ"]={ "ô","̀" },
+ ["Ổ"]={ "Ô","̉" },
+ ["ổ"]={ "ô","̉" },
+ ["Ỗ"]={ "Ô","̃" },
+ ["ỗ"]={ "ô","̃" },
+ ["Ộ"]={ "Ọ","̂" },
+ ["ộ"]={ "ọ","̂" },
+ ["Ớ"]={ "Ơ","́" },
+ ["ớ"]={ "ơ","́" },
+ ["Ờ"]={ "Ơ","̀" },
+ ["ờ"]={ "ơ","̀" },
+ ["Ở"]={ "Ơ","̉" },
+ ["ở"]={ "ơ","̉" },
+ ["Ỡ"]={ "Ơ","̃" },
+ ["ỡ"]={ "ơ","̃" },
+ ["Ợ"]={ "Ơ","̣" },
+ ["ợ"]={ "ơ","̣" },
+ ["Ụ"]={ "U","̣" },
+ ["ụ"]={ "u","̣" },
+ ["Ủ"]={ "U","̉" },
+ ["ủ"]={ "u","̉" },
+ ["Ứ"]={ "Ư","́" },
+ ["ứ"]={ "ư","́" },
+ ["Ừ"]={ "Ư","̀" },
+ ["ừ"]={ "ư","̀" },
+ ["Ử"]={ "Ư","̉" },
+ ["ử"]={ "ư","̉" },
+ ["Ữ"]={ "Ư","̃" },
+ ["ữ"]={ "ư","̃" },
+ ["Ự"]={ "Ư","̣" },
+ ["ự"]={ "ư","̣" },
+ ["Ỳ"]={ "Y","̀" },
+ ["ỳ"]={ "y","̀" },
+ ["Ỵ"]={ "Y","̣" },
+ ["ỵ"]={ "y","̣" },
+ ["Ỷ"]={ "Y","̉" },
+ ["ỷ"]={ "y","̉" },
+ ["Ỹ"]={ "Y","̃" },
+ ["ỹ"]={ "y","̃" },
+ ["ἀ"]={ "α","̓" },
+ ["ἁ"]={ "α","̔" },
+ ["ἂ"]={ "ἀ","̀" },
+ ["ἃ"]={ "ἁ","̀" },
+ ["ἄ"]={ "ἀ","́" },
+ ["ἅ"]={ "ἁ","́" },
+ ["ἆ"]={ "ἀ","͂" },
+ ["ἇ"]={ "ἁ","͂" },
+ ["Ἀ"]={ "Α","̓" },
+ ["Ἁ"]={ "Α","̔" },
+ ["Ἂ"]={ "Ἀ","̀" },
+ ["Ἃ"]={ "Ἁ","̀" },
+ ["Ἄ"]={ "Ἀ","́" },
+ ["Ἅ"]={ "Ἁ","́" },
+ ["Ἆ"]={ "Ἀ","͂" },
+ ["Ἇ"]={ "Ἁ","͂" },
+ ["ἐ"]={ "ε","̓" },
+ ["ἑ"]={ "ε","̔" },
+ ["ἒ"]={ "ἐ","̀" },
+ ["ἓ"]={ "ἑ","̀" },
+ ["ἔ"]={ "ἐ","́" },
+ ["ἕ"]={ "ἑ","́" },
+ ["Ἐ"]={ "Ε","̓" },
+ ["Ἑ"]={ "Ε","̔" },
+ ["Ἒ"]={ "Ἐ","̀" },
+ ["Ἓ"]={ "Ἑ","̀" },
+ ["Ἔ"]={ "Ἐ","́" },
+ ["Ἕ"]={ "Ἑ","́" },
+ ["ἠ"]={ "η","̓" },
+ ["ἡ"]={ "η","̔" },
+ ["ἢ"]={ "ἠ","̀" },
+ ["ἣ"]={ "ἡ","̀" },
+ ["ἤ"]={ "ἠ","́" },
+ ["ἥ"]={ "ἡ","́" },
+ ["ἦ"]={ "ἠ","͂" },
+ ["ἧ"]={ "ἡ","͂" },
+ ["Ἠ"]={ "Η","̓" },
+ ["Ἡ"]={ "Η","̔" },
+ ["Ἢ"]={ "Ἠ","̀" },
+ ["Ἣ"]={ "Ἡ","̀" },
+ ["Ἤ"]={ "Ἠ","́" },
+ ["Ἥ"]={ "Ἡ","́" },
+ ["Ἦ"]={ "Ἠ","͂" },
+ ["Ἧ"]={ "Ἡ","͂" },
+ ["ἰ"]={ "ι","̓" },
+ ["ἱ"]={ "ι","̔" },
+ ["ἲ"]={ "ἰ","̀" },
+ ["ἳ"]={ "ἱ","̀" },
+ ["ἴ"]={ "ἰ","́" },
+ ["ἵ"]={ "ἱ","́" },
+ ["ἶ"]={ "ἰ","͂" },
+ ["ἷ"]={ "ἱ","͂" },
+ ["Ἰ"]={ "Ι","̓" },
+ ["Ἱ"]={ "Ι","̔" },
+ ["Ἲ"]={ "Ἰ","̀" },
+ ["Ἳ"]={ "Ἱ","̀" },
+ ["Ἴ"]={ "Ἰ","́" },
+ ["Ἵ"]={ "Ἱ","́" },
+ ["Ἶ"]={ "Ἰ","͂" },
+ ["Ἷ"]={ "Ἱ","͂" },
+ ["ὀ"]={ "ο","̓" },
+ ["ὁ"]={ "ο","̔" },
+ ["ὂ"]={ "ὀ","̀" },
+ ["ὃ"]={ "ὁ","̀" },
+ ["ὄ"]={ "ὀ","́" },
+ ["ὅ"]={ "ὁ","́" },
+ ["Ὀ"]={ "Ο","̓" },
+ ["Ὁ"]={ "Ο","̔" },
+ ["Ὂ"]={ "Ὀ","̀" },
+ ["Ὃ"]={ "Ὁ","̀" },
+ ["Ὄ"]={ "Ὀ","́" },
+ ["Ὅ"]={ "Ὁ","́" },
+ ["ὐ"]={ "υ","̓" },
+ ["ὑ"]={ "υ","̔" },
+ ["ὒ"]={ "ὐ","̀" },
+ ["ὓ"]={ "ὑ","̀" },
+ ["ὔ"]={ "ὐ","́" },
+ ["ὕ"]={ "ὑ","́" },
+ ["ὖ"]={ "ὐ","͂" },
+ ["ὗ"]={ "ὑ","͂" },
+ ["Ὑ"]={ "Υ","̔" },
+ ["Ὓ"]={ "Ὑ","̀" },
+ ["Ὕ"]={ "Ὑ","́" },
+ ["Ὗ"]={ "Ὑ","͂" },
+ ["ὠ"]={ "ω","̓" },
+ ["ὡ"]={ "ω","̔" },
+ ["ὢ"]={ "ὠ","̀" },
+ ["ὣ"]={ "ὡ","̀" },
+ ["ὤ"]={ "ὠ","́" },
+ ["ὥ"]={ "ὡ","́" },
+ ["ὦ"]={ "ὠ","͂" },
+ ["ὧ"]={ "ὡ","͂" },
+ ["Ὠ"]={ "Ω","̓" },
+ ["Ὡ"]={ "Ω","̔" },
+ ["Ὢ"]={ "Ὠ","̀" },
+ ["Ὣ"]={ "Ὡ","̀" },
+ ["Ὤ"]={ "Ὠ","́" },
+ ["Ὥ"]={ "Ὡ","́" },
+ ["Ὦ"]={ "Ὠ","͂" },
+ ["Ὧ"]={ "Ὡ","͂" },
+ ["ὰ"]={ "α","̀" },
+ ["ὲ"]={ "ε","̀" },
+ ["ὴ"]={ "η","̀" },
+ ["ὶ"]={ "ι","̀" },
+ ["ὸ"]={ "ο","̀" },
+ ["ὺ"]={ "υ","̀" },
+ ["ὼ"]={ "ω","̀" },
+ ["ᾀ"]={ "ἀ","ͅ" },
+ ["ᾁ"]={ "ἁ","ͅ" },
+ ["ᾂ"]={ "ἂ","ͅ" },
+ ["ᾃ"]={ "ἃ","ͅ" },
+ ["ᾄ"]={ "ἄ","ͅ" },
+ ["ᾅ"]={ "ἅ","ͅ" },
+ ["ᾆ"]={ "ἆ","ͅ" },
+ ["ᾇ"]={ "ἇ","ͅ" },
+ ["ᾈ"]={ "Ἀ","ͅ" },
+ ["ᾉ"]={ "Ἁ","ͅ" },
+ ["ᾊ"]={ "Ἂ","ͅ" },
+ ["ᾋ"]={ "Ἃ","ͅ" },
+ ["ᾌ"]={ "Ἄ","ͅ" },
+ ["ᾍ"]={ "Ἅ","ͅ" },
+ ["ᾎ"]={ "Ἆ","ͅ" },
+ ["ᾏ"]={ "Ἇ","ͅ" },
+ ["ᾐ"]={ "ἠ","ͅ" },
+ ["ᾑ"]={ "ἡ","ͅ" },
+ ["ᾒ"]={ "ἢ","ͅ" },
+ ["ᾓ"]={ "ἣ","ͅ" },
+ ["ᾔ"]={ "ἤ","ͅ" },
+ ["ᾕ"]={ "ἥ","ͅ" },
+ ["ᾖ"]={ "ἦ","ͅ" },
+ ["ᾗ"]={ "ἧ","ͅ" },
+ ["ᾘ"]={ "Ἠ","ͅ" },
+ ["ᾙ"]={ "Ἡ","ͅ" },
+ ["ᾚ"]={ "Ἢ","ͅ" },
+ ["ᾛ"]={ "Ἣ","ͅ" },
+ ["ᾜ"]={ "Ἤ","ͅ" },
+ ["ᾝ"]={ "Ἥ","ͅ" },
+ ["ᾞ"]={ "Ἦ","ͅ" },
+ ["ᾟ"]={ "Ἧ","ͅ" },
+ ["ᾠ"]={ "ὠ","ͅ" },
+ ["ᾡ"]={ "ὡ","ͅ" },
+ ["ᾢ"]={ "ὢ","ͅ" },
+ ["ᾣ"]={ "ὣ","ͅ" },
+ ["ᾤ"]={ "ὤ","ͅ" },
+ ["ᾥ"]={ "ὥ","ͅ" },
+ ["ᾦ"]={ "ὦ","ͅ" },
+ ["ᾧ"]={ "ὧ","ͅ" },
+ ["ᾨ"]={ "Ὠ","ͅ" },
+ ["ᾩ"]={ "Ὡ","ͅ" },
+ ["ᾪ"]={ "Ὢ","ͅ" },
+ ["ᾫ"]={ "Ὣ","ͅ" },
+ ["ᾬ"]={ "Ὤ","ͅ" },
+ ["ᾭ"]={ "Ὥ","ͅ" },
+ ["ᾮ"]={ "Ὦ","ͅ" },
+ ["ᾯ"]={ "Ὧ","ͅ" },
+ ["ᾰ"]={ "α","̆" },
+ ["ᾱ"]={ "α","̄" },
+ ["ᾲ"]={ "ὰ","ͅ" },
+ ["ᾳ"]={ "α","ͅ" },
+ ["ᾴ"]={ "ά","ͅ" },
+ ["ᾶ"]={ "α","͂" },
+ ["ᾷ"]={ "ᾶ","ͅ" },
+ ["Ᾰ"]={ "Α","̆" },
+ ["Ᾱ"]={ "Α","̄" },
+ ["Ὰ"]={ "Α","̀" },
+ ["ᾼ"]={ "Α","ͅ" },
+ ["῁"]={ "¨","͂" },
+ ["ῂ"]={ "ὴ","ͅ" },
+ ["ῃ"]={ "η","ͅ" },
+ ["ῄ"]={ "ή","ͅ" },
+ ["ῆ"]={ "η","͂" },
+ ["ῇ"]={ "ῆ","ͅ" },
+ ["Ὲ"]={ "Ε","̀" },
+ ["Ὴ"]={ "Η","̀" },
+ ["ῌ"]={ "Η","ͅ" },
+ ["῍"]={ "᾿","̀" },
+ ["῎"]={ "᾿","́" },
+ ["῏"]={ "᾿","͂" },
+ ["ῐ"]={ "ι","̆" },
+ ["ῑ"]={ "ι","̄" },
+ ["ῒ"]={ "ϊ","̀" },
+ ["ῖ"]={ "ι","͂" },
+ ["ῗ"]={ "ϊ","͂" },
+ ["Ῐ"]={ "Ι","̆" },
+ ["Ῑ"]={ "Ι","̄" },
+ ["Ὶ"]={ "Ι","̀" },
+ ["῝"]={ "῾","̀" },
+ ["῞"]={ "῾","́" },
+ ["῟"]={ "῾","͂" },
+ ["ῠ"]={ "υ","̆" },
+ ["ῡ"]={ "υ","̄" },
+ ["ῢ"]={ "ϋ","̀" },
+ ["ῤ"]={ "ρ","̓" },
+ ["ῥ"]={ "ρ","̔" },
+ ["ῦ"]={ "υ","͂" },
+ ["ῧ"]={ "ϋ","͂" },
+ ["Ῠ"]={ "Υ","̆" },
+ ["Ῡ"]={ "Υ","̄" },
+ ["Ὺ"]={ "Υ","̀" },
+ ["Ῥ"]={ "Ρ","̔" },
+ ["῭"]={ "¨","̀" },
+ ["ῲ"]={ "ὼ","ͅ" },
+ ["ῳ"]={ "ω","ͅ" },
+ ["ῴ"]={ "ώ","ͅ" },
+ ["ῶ"]={ "ω","͂" },
+ ["ῷ"]={ "ῶ","ͅ" },
+ ["Ὸ"]={ "Ο","̀" },
+ ["Ὼ"]={ "Ω","̀" },
+ ["ῼ"]={ "Ω","ͅ" },
+ ["↚"]={ "←","̸" },
+ ["↛"]={ "→","̸" },
+ ["↮"]={ "↔","̸" },
+ ["⇍"]={ "⇐","̸" },
+ ["⇎"]={ "⇔","̸" },
+ ["⇏"]={ "⇒","̸" },
+ ["∄"]={ "∃","̸" },
+ ["∉"]={ "∈","̸" },
+ ["∌"]={ "∋","̸" },
+ ["∤"]={ "∣","̸" },
+ ["∦"]={ "∥","̸" },
+ ["≁"]={ "∼","̸" },
+ ["≄"]={ "≃","̸" },
+ ["≇"]={ "≅","̸" },
+ ["≉"]={ "≈","̸" },
+ ["≠"]={ "=","̸" },
+ ["≢"]={ "≡","̸" },
+ ["≭"]={ "≍","̸" },
+ ["≮"]={ "<","̸" },
+ ["≯"]={ ">","̸" },
+ ["≰"]={ "≤","̸" },
+ ["≱"]={ "≥","̸" },
+ ["≴"]={ "≲","̸" },
+ ["≵"]={ "≳","̸" },
+ ["≸"]={ "≶","̸" },
+ ["≹"]={ "≷","̸" },
+ ["⊀"]={ "≺","̸" },
+ ["⊁"]={ "≻","̸" },
+ ["⊄"]={ "⊂","̸" },
+ ["⊅"]={ "⊃","̸" },
+ ["⊈"]={ "⊆","̸" },
+ ["⊉"]={ "⊇","̸" },
+ ["⊬"]={ "⊢","̸" },
+ ["⊭"]={ "⊨","̸" },
+ ["⊮"]={ "⊩","̸" },
+ ["⊯"]={ "⊫","̸" },
+ ["⋠"]={ "≼","̸" },
+ ["⋡"]={ "≽","̸" },
+ ["⋢"]={ "⊑","̸" },
+ ["⋣"]={ "⊒","̸" },
+ ["⋪"]={ "⊲","̸" },
+ ["⋫"]={ "⊳","̸" },
+ ["⋬"]={ "⊴","̸" },
+ ["⋭"]={ "⊵","̸" },
+ ["⫝̸"]={ "⫝","̸" },
+ ["が"]={ "か","゙" },
+ ["ぎ"]={ "き","゙" },
+ ["ぐ"]={ "く","゙" },
+ ["げ"]={ "け","゙" },
+ ["ご"]={ "こ","゙" },
+ ["ざ"]={ "さ","゙" },
+ ["じ"]={ "し","゙" },
+ ["ず"]={ "す","゙" },
+ ["ぜ"]={ "せ","゙" },
+ ["ぞ"]={ "そ","゙" },
+ ["だ"]={ "た","゙" },
+ ["ぢ"]={ "ち","゙" },
+ ["づ"]={ "つ","゙" },
+ ["で"]={ "て","゙" },
+ ["ど"]={ "と","゙" },
+ ["ば"]={ "は","゙" },
+ ["ぱ"]={ "は","゚" },
+ ["び"]={ "ひ","゙" },
+ ["ぴ"]={ "ひ","゚" },
+ ["ぶ"]={ "ふ","゙" },
+ ["ぷ"]={ "ふ","゚" },
+ ["べ"]={ "へ","゙" },
+ ["ぺ"]={ "へ","゚" },
+ ["ぼ"]={ "ほ","゙" },
+ ["ぽ"]={ "ほ","゚" },
+ ["ゔ"]={ "う","゙" },
+ ["ゞ"]={ "ゝ","゙" },
+ ["ガ"]={ "カ","゙" },
+ ["ギ"]={ "キ","゙" },
+ ["グ"]={ "ク","゙" },
+ ["ゲ"]={ "ケ","゙" },
+ ["ゴ"]={ "コ","゙" },
+ ["ザ"]={ "サ","゙" },
+ ["ジ"]={ "シ","゙" },
+ ["ズ"]={ "ス","゙" },
+ ["ゼ"]={ "セ","゙" },
+ ["ゾ"]={ "ソ","゙" },
+ ["ダ"]={ "タ","゙" },
+ ["ヂ"]={ "チ","゙" },
+ ["ヅ"]={ "ツ","゙" },
+ ["デ"]={ "テ","゙" },
+ ["ド"]={ "ト","゙" },
+ ["バ"]={ "ハ","゙" },
+ ["パ"]={ "ハ","゚" },
+ ["ビ"]={ "ヒ","゙" },
+ ["ピ"]={ "ヒ","゚" },
+ ["ブ"]={ "フ","゙" },
+ ["プ"]={ "フ","゚" },
+ ["ベ"]={ "ヘ","゙" },
+ ["ペ"]={ "ヘ","゚" },
+ ["ボ"]={ "ホ","゙" },
+ ["ポ"]={ "ホ","゚" },
+ ["ヴ"]={ "ウ","゙" },
+ ["ヷ"]={ "ワ","゙" },
+ ["ヸ"]={ "ヰ","゙" },
+ ["ヹ"]={ "ヱ","゙" },
+ ["ヺ"]={ "ヲ","゙" },
+ ["ヾ"]={ "ヽ","゙" },
+ ["יִ"]={ "י","ִ" },
+ ["ײַ"]={ "ײ","ַ" },
+ ["שׁ"]={ "ש","ׁ" },
+ ["שׂ"]={ "ש","ׂ" },
+ ["שּׁ"]={ "שּ","ׁ" },
+ ["שּׂ"]={ "שּ","ׂ" },
+ ["אַ"]={ "א","ַ" },
+ ["אָ"]={ "א","ָ" },
+ ["אּ"]={ "א","ּ" },
+ ["בּ"]={ "ב","ּ" },
+ ["גּ"]={ "ג","ּ" },
+ ["דּ"]={ "ד","ּ" },
+ ["הּ"]={ "ה","ּ" },
+ ["וּ"]={ "ו","ּ" },
+ ["זּ"]={ "ז","ּ" },
+ ["טּ"]={ "ט","ּ" },
+ ["יּ"]={ "י","ּ" },
+ ["ךּ"]={ "ך","ּ" },
+ ["כּ"]={ "כ","ּ" },
+ ["לּ"]={ "ל","ּ" },
+ ["מּ"]={ "מ","ּ" },
+ ["נּ"]={ "נ","ּ" },
+ ["סּ"]={ "ס","ּ" },
+ ["ףּ"]={ "ף","ּ" },
+ ["פּ"]={ "פ","ּ" },
+ ["צּ"]={ "צ","ּ" },
+ ["קּ"]={ "ק","ּ" },
+ ["רּ"]={ "ר","ּ" },
+ ["שּ"]={ "ש","ּ" },
+ ["תּ"]={ "ת","ּ" },
+ ["וֹ"]={ "ו","ֹ" },
+ ["בֿ"]={ "ב","ֿ" },
+ ["כֿ"]={ "כ","ֿ" },
+ ["פֿ"]={ "פ","ֿ" },
+ ["𑂚"]={ "𑂙","𑂺" },
+ ["𑂜"]={ "𑂛","𑂺" },
+ ["𑂫"]={ "𑂥","𑂺" },
+ ["𑄮"]={ "𑄱","𑄧" },
+ ["𑄯"]={ "𑄲","𑄧" },
+ ["𑍋"]={ "𑍇","𑌾" },
+ ["𑍌"]={ "𑍇","𑍗" },
+ ["𑒻"]={ "𑒹","𑒺" },
+ ["𑒼"]={ "𑒹","𑒰" },
+ ["𑒾"]={ "𑒹","𑒽" },
+ ["𑖺"]={ "𑖸","𑖯" },
+ ["𑖻"]={ "𑖹","𑖯" },
+ ["𝅗𝅥"]={ "𝅗","𝅥" },
+ ["𝅘𝅥"]={ "𝅘","𝅥" },
+ ["𝅘𝅥𝅮"]={ "𝅘𝅥","𝅮" },
+ ["𝅘𝅥𝅯"]={ "𝅘𝅥","𝅯" },
+ ["𝅘𝅥𝅰"]={ "𝅘𝅥","𝅰" },
+ ["𝅘𝅥𝅱"]={ "𝅘𝅥","𝅱" },
+ ["𝅘𝅥𝅲"]={ "𝅘𝅥","𝅲" },
+ ["𝆹𝅥"]={ "𝆹","𝅥" },
+ ["𝆺𝅥"]={ "𝆺","𝅥" },
+ ["𝆹𝅥𝅮"]={ "𝆹𝅥","𝅮" },
+ ["𝆺𝅥𝅮"]={ "𝆺𝅥","𝅮" },
+ ["𝆹𝅥𝅯"]={ "𝆹𝅥","𝅯" },
+ ["𝆺𝅥𝅯"]={ "𝆺𝅥","𝅯" },
+ },
+ },
+ {
+ ["data"]={
+ ["À"]={ "A","̀" },
+ ["Á"]={ "A","́" },
+ ["Â"]={ "A","̂" },
+ ["Ã"]={ "A","̃" },
+ ["Ä"]={ "A","̈" },
+ ["Å"]={ "A","̊" },
+ ["Ç"]={ "C","̧" },
+ ["È"]={ "E","̀" },
+ ["É"]={ "E","́" },
+ ["Ê"]={ "E","̂" },
+ ["Ë"]={ "E","̈" },
+ ["Ì"]={ "I","̀" },
+ ["Í"]={ "I","́" },
+ ["Î"]={ "I","̂" },
+ ["Ï"]={ "I","̈" },
+ ["Ñ"]={ "N","̃" },
+ ["Ò"]={ "O","̀" },
+ ["Ó"]={ "O","́" },
+ ["Ô"]={ "O","̂" },
+ ["Õ"]={ "O","̃" },
+ ["Ö"]={ "O","̈" },
+ ["Ù"]={ "U","̀" },
+ ["Ú"]={ "U","́" },
+ ["Û"]={ "U","̂" },
+ ["Ü"]={ "U","̈" },
+ ["Ý"]={ "Y","́" },
+ ["à"]={ "a","̀" },
+ ["á"]={ "a","́" },
+ ["â"]={ "a","̂" },
+ ["ã"]={ "a","̃" },
+ ["ä"]={ "a","̈" },
+ ["å"]={ "a","̊" },
+ ["ç"]={ "c","̧" },
+ ["è"]={ "e","̀" },
+ ["é"]={ "e","́" },
+ ["ê"]={ "e","̂" },
+ ["ë"]={ "e","̈" },
+ ["ì"]={ "i","̀" },
+ ["í"]={ "i","́" },
+ ["î"]={ "i","̂" },
+ ["ï"]={ "i","̈" },
+ ["ñ"]={ "n","̃" },
+ ["ò"]={ "o","̀" },
+ ["ó"]={ "o","́" },
+ ["ô"]={ "o","̂" },
+ ["õ"]={ "o","̃" },
+ ["ö"]={ "o","̈" },
+ ["ù"]={ "u","̀" },
+ ["ú"]={ "u","́" },
+ ["û"]={ "u","̂" },
+ ["ü"]={ "u","̈" },
+ ["ý"]={ "y","́" },
+ ["ÿ"]={ "y","̈" },
+ ["Ā"]={ "A","̄" },
+ ["ā"]={ "a","̄" },
+ ["Ă"]={ "A","̆" },
+ ["ă"]={ "a","̆" },
+ ["Ą"]={ "A","̨" },
+ ["ą"]={ "a","̨" },
+ ["Ć"]={ "C","́" },
+ ["ć"]={ "c","́" },
+ ["Ĉ"]={ "C","̂" },
+ ["ĉ"]={ "c","̂" },
+ ["Ċ"]={ "C","̇" },
+ ["ċ"]={ "c","̇" },
+ ["Č"]={ "C","̌" },
+ ["č"]={ "c","̌" },
+ ["Ď"]={ "D","̌" },
+ ["ď"]={ "d","̌" },
+ ["Ē"]={ "E","̄" },
+ ["ē"]={ "e","̄" },
+ ["Ĕ"]={ "E","̆" },
+ ["ĕ"]={ "e","̆" },
+ ["Ė"]={ "E","̇" },
+ ["ė"]={ "e","̇" },
+ ["Ę"]={ "E","̨" },
+ ["ę"]={ "e","̨" },
+ ["Ě"]={ "E","̌" },
+ ["ě"]={ "e","̌" },
+ ["Ĝ"]={ "G","̂" },
+ ["ĝ"]={ "g","̂" },
+ ["Ğ"]={ "G","̆" },
+ ["ğ"]={ "g","̆" },
+ ["Ġ"]={ "G","̇" },
+ ["ġ"]={ "g","̇" },
+ ["Ģ"]={ "G","̧" },
+ ["ģ"]={ "g","̧" },
+ ["Ĥ"]={ "H","̂" },
+ ["ĥ"]={ "h","̂" },
+ ["Ĩ"]={ "I","̃" },
+ ["ĩ"]={ "i","̃" },
+ ["Ī"]={ "I","̄" },
+ ["ī"]={ "i","̄" },
+ ["Ĭ"]={ "I","̆" },
+ ["ĭ"]={ "i","̆" },
+ ["Į"]={ "I","̨" },
+ ["į"]={ "i","̨" },
+ ["İ"]={ "I","̇" },
+ ["Ĵ"]={ "J","̂" },
+ ["ĵ"]={ "j","̂" },
+ ["Ķ"]={ "K","̧" },
+ ["ķ"]={ "k","̧" },
+ ["Ĺ"]={ "L","́" },
+ ["ĺ"]={ "l","́" },
+ ["Ļ"]={ "L","̧" },
+ ["ļ"]={ "l","̧" },
+ ["Ľ"]={ "L","̌" },
+ ["ľ"]={ "l","̌" },
+ ["Ń"]={ "N","́" },
+ ["ń"]={ "n","́" },
+ ["Ņ"]={ "N","̧" },
+ ["ņ"]={ "n","̧" },
+ ["Ň"]={ "N","̌" },
+ ["ň"]={ "n","̌" },
+ ["Ō"]={ "O","̄" },
+ ["ō"]={ "o","̄" },
+ ["Ŏ"]={ "O","̆" },
+ ["ŏ"]={ "o","̆" },
+ ["Ő"]={ "O","̋" },
+ ["ő"]={ "o","̋" },
+ ["Ŕ"]={ "R","́" },
+ ["ŕ"]={ "r","́" },
+ ["Ŗ"]={ "R","̧" },
+ ["ŗ"]={ "r","̧" },
+ ["Ř"]={ "R","̌" },
+ ["ř"]={ "r","̌" },
+ ["Ś"]={ "S","́" },
+ ["ś"]={ "s","́" },
+ ["Ŝ"]={ "S","̂" },
+ ["ŝ"]={ "s","̂" },
+ ["Ş"]={ "S","̧" },
+ ["ş"]={ "s","̧" },
+ ["Š"]={ "S","̌" },
+ ["š"]={ "s","̌" },
+ ["Ţ"]={ "T","̧" },
+ ["ţ"]={ "t","̧" },
+ ["Ť"]={ "T","̌" },
+ ["ť"]={ "t","̌" },
+ ["Ũ"]={ "U","̃" },
+ ["ũ"]={ "u","̃" },
+ ["Ū"]={ "U","̄" },
+ ["ū"]={ "u","̄" },
+ ["Ŭ"]={ "U","̆" },
+ ["ŭ"]={ "u","̆" },
+ ["Ů"]={ "U","̊" },
+ ["ů"]={ "u","̊" },
+ ["Ű"]={ "U","̋" },
+ ["ű"]={ "u","̋" },
+ ["Ų"]={ "U","̨" },
+ ["ų"]={ "u","̨" },
+ ["Ŵ"]={ "W","̂" },
+ ["ŵ"]={ "w","̂" },
+ ["Ŷ"]={ "Y","̂" },
+ ["ŷ"]={ "y","̂" },
+ ["Ÿ"]={ "Y","̈" },
+ ["Ź"]={ "Z","́" },
+ ["ź"]={ "z","́" },
+ ["Ż"]={ "Z","̇" },
+ ["ż"]={ "z","̇" },
+ ["Ž"]={ "Z","̌" },
+ ["ž"]={ "z","̌" },
+ ["Ơ"]={ "O","̛" },
+ ["ơ"]={ "o","̛" },
+ ["Ư"]={ "U","̛" },
+ ["ư"]={ "u","̛" },
+ ["Ǎ"]={ "A","̌" },
+ ["ǎ"]={ "a","̌" },
+ ["Ǐ"]={ "I","̌" },
+ ["ǐ"]={ "i","̌" },
+ ["Ǒ"]={ "O","̌" },
+ ["ǒ"]={ "o","̌" },
+ ["Ǔ"]={ "U","̌" },
+ ["ǔ"]={ "u","̌" },
+ ["Ǖ"]={ "Ü","̄" },
+ ["ǖ"]={ "ü","̄" },
+ ["Ǘ"]={ "Ü","́" },
+ ["ǘ"]={ "ü","́" },
+ ["Ǚ"]={ "Ü","̌" },
+ ["ǚ"]={ "ü","̌" },
+ ["Ǜ"]={ "Ü","̀" },
+ ["ǜ"]={ "ü","̀" },
+ ["Ǟ"]={ "Ä","̄" },
+ ["ǟ"]={ "ä","̄" },
+ ["Ǡ"]={ "Ȧ","̄" },
+ ["ǡ"]={ "ȧ","̄" },
+ ["Ǣ"]={ "Æ","̄" },
+ ["ǣ"]={ "æ","̄" },
+ ["Ǧ"]={ "G","̌" },
+ ["ǧ"]={ "g","̌" },
+ ["Ǩ"]={ "K","̌" },
+ ["ǩ"]={ "k","̌" },
+ ["Ǫ"]={ "O","̨" },
+ ["ǫ"]={ "o","̨" },
+ ["Ǭ"]={ "Ǫ","̄" },
+ ["ǭ"]={ "ǫ","̄" },
+ ["Ǯ"]={ "Ʒ","̌" },
+ ["ǯ"]={ "ʒ","̌" },
+ ["ǰ"]={ "j","̌" },
+ ["Ǵ"]={ "G","́" },
+ ["ǵ"]={ "g","́" },
+ ["Ǹ"]={ "N","̀" },
+ ["ǹ"]={ "n","̀" },
+ ["Ǻ"]={ "Å","́" },
+ ["ǻ"]={ "å","́" },
+ ["Ǽ"]={ "Æ","́" },
+ ["ǽ"]={ "æ","́" },
+ ["Ǿ"]={ "Ø","́" },
+ ["ǿ"]={ "ø","́" },
+ ["Ȁ"]={ "A","̏" },
+ ["ȁ"]={ "a","̏" },
+ ["Ȃ"]={ "A","̑" },
+ ["ȃ"]={ "a","̑" },
+ ["Ȅ"]={ "E","̏" },
+ ["ȅ"]={ "e","̏" },
+ ["Ȇ"]={ "E","̑" },
+ ["ȇ"]={ "e","̑" },
+ ["Ȉ"]={ "I","̏" },
+ ["ȉ"]={ "i","̏" },
+ ["Ȋ"]={ "I","̑" },
+ ["ȋ"]={ "i","̑" },
+ ["Ȍ"]={ "O","̏" },
+ ["ȍ"]={ "o","̏" },
+ ["Ȏ"]={ "O","̑" },
+ ["ȏ"]={ "o","̑" },
+ ["Ȑ"]={ "R","̏" },
+ ["ȑ"]={ "r","̏" },
+ ["Ȓ"]={ "R","̑" },
+ ["ȓ"]={ "r","̑" },
+ ["Ȕ"]={ "U","̏" },
+ ["ȕ"]={ "u","̏" },
+ ["Ȗ"]={ "U","̑" },
+ ["ȗ"]={ "u","̑" },
+ ["Ș"]={ "S","̦" },
+ ["ș"]={ "s","̦" },
+ ["Ț"]={ "T","̦" },
+ ["ț"]={ "t","̦" },
+ ["Ȟ"]={ "H","̌" },
+ ["ȟ"]={ "h","̌" },
+ ["Ȧ"]={ "A","̇" },
+ ["ȧ"]={ "a","̇" },
+ ["Ȩ"]={ "E","̧" },
+ ["ȩ"]={ "e","̧" },
+ ["Ȫ"]={ "Ö","̄" },
+ ["ȫ"]={ "ö","̄" },
+ ["Ȭ"]={ "Õ","̄" },
+ ["ȭ"]={ "õ","̄" },
+ ["Ȯ"]={ "O","̇" },
+ ["ȯ"]={ "o","̇" },
+ ["Ȱ"]={ "Ȯ","̄" },
+ ["ȱ"]={ "ȯ","̄" },
+ ["Ȳ"]={ "Y","̄" },
+ ["ȳ"]={ "y","̄" },
+ ["̈́"]={ "̈","́" },
+ ["΅"]={ "¨","́" },
+ ["Ά"]={ "Α","́" },
+ ["Έ"]={ "Ε","́" },
+ ["Ή"]={ "Η","́" },
+ ["Ί"]={ "Ι","́" },
+ ["Ό"]={ "Ο","́" },
+ ["Ύ"]={ "Υ","́" },
+ ["Ώ"]={ "Ω","́" },
+ ["ΐ"]={ "ϊ","́" },
+ ["Ϊ"]={ "Ι","̈" },
+ ["Ϋ"]={ "Υ","̈" },
+ ["ά"]={ "α","́" },
+ ["έ"]={ "ε","́" },
+ ["ή"]={ "η","́" },
+ ["ί"]={ "ι","́" },
+ ["ΰ"]={ "ϋ","́" },
+ ["ϊ"]={ "ι","̈" },
+ ["ϋ"]={ "υ","̈" },
+ ["ό"]={ "ο","́" },
+ ["ύ"]={ "υ","́" },
+ ["ώ"]={ "ω","́" },
+ ["ϓ"]={ "ϒ","́" },
+ ["ϔ"]={ "ϒ","̈" },
+ ["Ѐ"]={ "Е","̀" },
+ ["Ё"]={ "Е","̈" },
+ ["Ѓ"]={ "Г","́" },
+ ["Ї"]={ "І","̈" },
+ ["Ќ"]={ "К","́" },
+ ["Ѝ"]={ "И","̀" },
+ ["Ў"]={ "У","̆" },
+ ["Й"]={ "И","̆" },
+ ["й"]={ "и","̆" },
+ ["ѐ"]={ "е","̀" },
+ ["ё"]={ "е","̈" },
+ ["ѓ"]={ "г","́" },
+ ["ї"]={ "і","̈" },
+ ["ќ"]={ "к","́" },
+ ["ѝ"]={ "и","̀" },
+ ["ў"]={ "у","̆" },
+ ["Ѷ"]={ "Ѵ","̏" },
+ ["ѷ"]={ "ѵ","̏" },
+ ["Ӂ"]={ "Ж","̆" },
+ ["ӂ"]={ "ж","̆" },
+ ["Ӑ"]={ "А","̆" },
+ ["ӑ"]={ "а","̆" },
+ ["Ӓ"]={ "А","̈" },
+ ["ӓ"]={ "а","̈" },
+ ["Ӗ"]={ "Е","̆" },
+ ["ӗ"]={ "е","̆" },
+ ["Ӛ"]={ "Ә","̈" },
+ ["ӛ"]={ "ә","̈" },
+ ["Ӝ"]={ "Ж","̈" },
+ ["ӝ"]={ "ж","̈" },
+ ["Ӟ"]={ "З","̈" },
+ ["ӟ"]={ "з","̈" },
+ ["Ӣ"]={ "И","̄" },
+ ["ӣ"]={ "и","̄" },
+ ["Ӥ"]={ "И","̈" },
+ ["ӥ"]={ "и","̈" },
+ ["Ӧ"]={ "О","̈" },
+ ["ӧ"]={ "о","̈" },
+ ["Ӫ"]={ "Ө","̈" },
+ ["ӫ"]={ "ө","̈" },
+ ["Ӭ"]={ "Э","̈" },
+ ["ӭ"]={ "э","̈" },
+ ["Ӯ"]={ "У","̄" },
+ ["ӯ"]={ "у","̄" },
+ ["Ӱ"]={ "У","̈" },
+ ["ӱ"]={ "у","̈" },
+ ["Ӳ"]={ "У","̋" },
+ ["ӳ"]={ "у","̋" },
+ ["Ӵ"]={ "Ч","̈" },
+ ["ӵ"]={ "ч","̈" },
+ ["Ӹ"]={ "Ы","̈" },
+ ["ӹ"]={ "ы","̈" },
+ ["آ"]={ "ا","ٓ" },
+ ["أ"]={ "ا","ٔ" },
+ ["ؤ"]={ "و","ٔ" },
+ ["إ"]={ "ا","ٕ" },
+ ["ئ"]={ "ي","ٔ" },
+ ["ۀ"]={ "ە","ٔ" },
+ ["ۂ"]={ "ہ","ٔ" },
+ ["ۓ"]={ "ے","ٔ" },
+ ["ऩ"]={ "न","़" },
+ ["ऱ"]={ "र","़" },
+ ["ऴ"]={ "ळ","़" },
+ ["क़"]={ "क","़" },
+ ["ख़"]={ "ख","़" },
+ ["ग़"]={ "ग","़" },
+ ["ज़"]={ "ज","़" },
+ ["ड़"]={ "ड","़" },
+ ["ढ़"]={ "ढ","़" },
+ ["फ़"]={ "फ","़" },
+ ["य़"]={ "य","़" },
+ ["ো"]={ "ে","া" },
+ ["ৌ"]={ "ে","ৗ" },
+ ["ড়"]={ "ড","়" },
+ ["ঢ়"]={ "ঢ","়" },
+ ["য়"]={ "য","়" },
+ ["ਲ਼"]={ "ਲ","਼" },
+ ["ਸ਼"]={ "ਸ","਼" },
+ ["ਖ਼"]={ "ਖ","਼" },
+ ["ਗ਼"]={ "ਗ","਼" },
+ ["ਜ਼"]={ "ਜ","਼" },
+ ["ਫ਼"]={ "ਫ","਼" },
+ ["ୈ"]={ "େ","ୖ" },
+ ["ୋ"]={ "େ","ା" },
+ ["ୌ"]={ "େ","ୗ" },
+ ["ଡ଼"]={ "ଡ","଼" },
+ ["ଢ଼"]={ "ଢ","଼" },
+ ["ஔ"]={ "ஒ","ௗ" },
+ ["ொ"]={ "ெ","ா" },
+ ["ோ"]={ "ே","ா" },
+ ["ௌ"]={ "ெ","ௗ" },
+ ["ై"]={ "ె","ౖ" },
+ ["ೀ"]={ "ಿ","ೕ" },
+ ["ೇ"]={ "ೆ","ೕ" },
+ ["ೈ"]={ "ೆ","ೖ" },
+ ["ೊ"]={ "ೆ","ೂ" },
+ ["ೋ"]={ "ೊ","ೕ" },
+ ["ൊ"]={ "െ","ാ" },
+ ["ോ"]={ "േ","ാ" },
+ ["ൌ"]={ "െ","ൗ" },
+ ["ේ"]={ "ෙ","්" },
+ ["ො"]={ "ෙ","ා" },
+ ["ෝ"]={ "ො","්" },
+ ["ෞ"]={ "ෙ","ෟ" },
+ ["གྷ"]={ "ག","ྷ" },
+ ["ཌྷ"]={ "ཌ","ྷ" },
+ ["དྷ"]={ "ད","ྷ" },
+ ["བྷ"]={ "བ","ྷ" },
+ ["ཛྷ"]={ "ཛ","ྷ" },
+ ["ཀྵ"]={ "ཀ","ྵ" },
+ ["ཱི"]={ "ཱ","ི" },
+ ["ཱུ"]={ "ཱ","ུ" },
+ ["ྲྀ"]={ "ྲ","ྀ" },
+ ["ླྀ"]={ "ླ","ྀ" },
+ ["ཱྀ"]={ "ཱ","ྀ" },
+ ["ྒྷ"]={ "ྒ","ྷ" },
+ ["ྜྷ"]={ "ྜ","ྷ" },
+ ["ྡྷ"]={ "ྡ","ྷ" },
+ ["ྦྷ"]={ "ྦ","ྷ" },
+ ["ྫྷ"]={ "ྫ","ྷ" },
+ ["ྐྵ"]={ "ྐ","ྵ" },
+ ["ဦ"]={ "ဥ","ီ" },
+ ["ᬆ"]={ "ᬅ","ᬵ" },
+ ["ᬈ"]={ "ᬇ","ᬵ" },
+ ["ᬊ"]={ "ᬉ","ᬵ" },
+ ["ᬌ"]={ "ᬋ","ᬵ" },
+ ["ᬎ"]={ "ᬍ","ᬵ" },
+ ["ᬒ"]={ "ᬑ","ᬵ" },
+ ["ᬻ"]={ "ᬺ","ᬵ" },
+ ["ᬽ"]={ "ᬼ","ᬵ" },
+ ["ᭀ"]={ "ᬾ","ᬵ" },
+ ["ᭁ"]={ "ᬿ","ᬵ" },
+ ["ᭃ"]={ "ᭂ","ᬵ" },
+ ["Ḁ"]={ "A","̥" },
+ ["ḁ"]={ "a","̥" },
+ ["Ḃ"]={ "B","̇" },
+ ["ḃ"]={ "b","̇" },
+ ["Ḅ"]={ "B","̣" },
+ ["ḅ"]={ "b","̣" },
+ ["Ḇ"]={ "B","̱" },
+ ["ḇ"]={ "b","̱" },
+ ["Ḉ"]={ "Ç","́" },
+ ["ḉ"]={ "ç","́" },
+ ["Ḋ"]={ "D","̇" },
+ ["ḋ"]={ "d","̇" },
+ ["Ḍ"]={ "D","̣" },
+ ["ḍ"]={ "d","̣" },
+ ["Ḏ"]={ "D","̱" },
+ ["ḏ"]={ "d","̱" },
+ ["Ḑ"]={ "D","̧" },
+ ["ḑ"]={ "d","̧" },
+ ["Ḓ"]={ "D","̭" },
+ ["ḓ"]={ "d","̭" },
+ ["Ḕ"]={ "Ē","̀" },
+ ["ḕ"]={ "ē","̀" },
+ ["Ḗ"]={ "Ē","́" },
+ ["ḗ"]={ "ē","́" },
+ ["Ḙ"]={ "E","̭" },
+ ["ḙ"]={ "e","̭" },
+ ["Ḛ"]={ "E","̰" },
+ ["ḛ"]={ "e","̰" },
+ ["Ḝ"]={ "Ȩ","̆" },
+ ["ḝ"]={ "ȩ","̆" },
+ ["Ḟ"]={ "F","̇" },
+ ["ḟ"]={ "f","̇" },
+ ["Ḡ"]={ "G","̄" },
+ ["ḡ"]={ "g","̄" },
+ ["Ḣ"]={ "H","̇" },
+ ["ḣ"]={ "h","̇" },
+ ["Ḥ"]={ "H","̣" },
+ ["ḥ"]={ "h","̣" },
+ ["Ḧ"]={ "H","̈" },
+ ["ḧ"]={ "h","̈" },
+ ["Ḩ"]={ "H","̧" },
+ ["ḩ"]={ "h","̧" },
+ ["Ḫ"]={ "H","̮" },
+ ["ḫ"]={ "h","̮" },
+ ["Ḭ"]={ "I","̰" },
+ ["ḭ"]={ "i","̰" },
+ ["Ḯ"]={ "Ï","́" },
+ ["ḯ"]={ "ï","́" },
+ ["Ḱ"]={ "K","́" },
+ ["ḱ"]={ "k","́" },
+ ["Ḳ"]={ "K","̣" },
+ ["ḳ"]={ "k","̣" },
+ ["Ḵ"]={ "K","̱" },
+ ["ḵ"]={ "k","̱" },
+ ["Ḷ"]={ "L","̣" },
+ ["ḷ"]={ "l","̣" },
+ ["Ḹ"]={ "Ḷ","̄" },
+ ["ḹ"]={ "ḷ","̄" },
+ ["Ḻ"]={ "L","̱" },
+ ["ḻ"]={ "l","̱" },
+ ["Ḽ"]={ "L","̭" },
+ ["ḽ"]={ "l","̭" },
+ ["Ḿ"]={ "M","́" },
+ ["ḿ"]={ "m","́" },
+ ["Ṁ"]={ "M","̇" },
+ ["ṁ"]={ "m","̇" },
+ ["Ṃ"]={ "M","̣" },
+ ["ṃ"]={ "m","̣" },
+ ["Ṅ"]={ "N","̇" },
+ ["ṅ"]={ "n","̇" },
+ ["Ṇ"]={ "N","̣" },
+ ["ṇ"]={ "n","̣" },
+ ["Ṉ"]={ "N","̱" },
+ ["ṉ"]={ "n","̱" },
+ ["Ṋ"]={ "N","̭" },
+ ["ṋ"]={ "n","̭" },
+ ["Ṍ"]={ "Õ","́" },
+ ["ṍ"]={ "õ","́" },
+ ["Ṏ"]={ "Õ","̈" },
+ ["ṏ"]={ "õ","̈" },
+ ["Ṑ"]={ "Ō","̀" },
+ ["ṑ"]={ "ō","̀" },
+ ["Ṓ"]={ "Ō","́" },
+ ["ṓ"]={ "ō","́" },
+ ["Ṕ"]={ "P","́" },
+ ["ṕ"]={ "p","́" },
+ ["Ṗ"]={ "P","̇" },
+ ["ṗ"]={ "p","̇" },
+ ["Ṙ"]={ "R","̇" },
+ ["ṙ"]={ "r","̇" },
+ ["Ṛ"]={ "R","̣" },
+ ["ṛ"]={ "r","̣" },
+ ["Ṝ"]={ "Ṛ","̄" },
+ ["ṝ"]={ "ṛ","̄" },
+ ["Ṟ"]={ "R","̱" },
+ ["ṟ"]={ "r","̱" },
+ ["Ṡ"]={ "S","̇" },
+ ["ṡ"]={ "s","̇" },
+ ["Ṣ"]={ "S","̣" },
+ ["ṣ"]={ "s","̣" },
+ ["Ṥ"]={ "Ś","̇" },
+ ["ṥ"]={ "ś","̇" },
+ ["Ṧ"]={ "Š","̇" },
+ ["ṧ"]={ "š","̇" },
+ ["Ṩ"]={ "Ṣ","̇" },
+ ["ṩ"]={ "ṣ","̇" },
+ ["Ṫ"]={ "T","̇" },
+ ["ṫ"]={ "t","̇" },
+ ["Ṭ"]={ "T","̣" },
+ ["ṭ"]={ "t","̣" },
+ ["Ṯ"]={ "T","̱" },
+ ["ṯ"]={ "t","̱" },
+ ["Ṱ"]={ "T","̭" },
+ ["ṱ"]={ "t","̭" },
+ ["Ṳ"]={ "U","̤" },
+ ["ṳ"]={ "u","̤" },
+ ["Ṵ"]={ "U","̰" },
+ ["ṵ"]={ "u","̰" },
+ ["Ṷ"]={ "U","̭" },
+ ["ṷ"]={ "u","̭" },
+ ["Ṹ"]={ "Ũ","́" },
+ ["ṹ"]={ "ũ","́" },
+ ["Ṻ"]={ "Ū","̈" },
+ ["ṻ"]={ "ū","̈" },
+ ["Ṽ"]={ "V","̃" },
+ ["ṽ"]={ "v","̃" },
+ ["Ṿ"]={ "V","̣" },
+ ["ṿ"]={ "v","̣" },
+ ["Ẁ"]={ "W","̀" },
+ ["ẁ"]={ "w","̀" },
+ ["Ẃ"]={ "W","́" },
+ ["ẃ"]={ "w","́" },
+ ["Ẅ"]={ "W","̈" },
+ ["ẅ"]={ "w","̈" },
+ ["Ẇ"]={ "W","̇" },
+ ["ẇ"]={ "w","̇" },
+ ["Ẉ"]={ "W","̣" },
+ ["ẉ"]={ "w","̣" },
+ ["Ẋ"]={ "X","̇" },
+ ["ẋ"]={ "x","̇" },
+ ["Ẍ"]={ "X","̈" },
+ ["ẍ"]={ "x","̈" },
+ ["Ẏ"]={ "Y","̇" },
+ ["ẏ"]={ "y","̇" },
+ ["Ẑ"]={ "Z","̂" },
+ ["ẑ"]={ "z","̂" },
+ ["Ẓ"]={ "Z","̣" },
+ ["ẓ"]={ "z","̣" },
+ ["Ẕ"]={ "Z","̱" },
+ ["ẕ"]={ "z","̱" },
+ ["ẖ"]={ "h","̱" },
+ ["ẗ"]={ "t","̈" },
+ ["ẘ"]={ "w","̊" },
+ ["ẙ"]={ "y","̊" },
+ ["ẛ"]={ "ſ","̇" },
+ ["Ạ"]={ "A","̣" },
+ ["ạ"]={ "a","̣" },
+ ["Ả"]={ "A","̉" },
+ ["ả"]={ "a","̉" },
+ ["Ấ"]={ "Â","́" },
+ ["ấ"]={ "â","́" },
+ ["Ầ"]={ "Â","̀" },
+ ["ầ"]={ "â","̀" },
+ ["Ẩ"]={ "Â","̉" },
+ ["ẩ"]={ "â","̉" },
+ ["Ẫ"]={ "Â","̃" },
+ ["ẫ"]={ "â","̃" },
+ ["Ậ"]={ "Ạ","̂" },
+ ["ậ"]={ "ạ","̂" },
+ ["Ắ"]={ "Ă","́" },
+ ["ắ"]={ "ă","́" },
+ ["Ằ"]={ "Ă","̀" },
+ ["ằ"]={ "ă","̀" },
+ ["Ẳ"]={ "Ă","̉" },
+ ["ẳ"]={ "ă","̉" },
+ ["Ẵ"]={ "Ă","̃" },
+ ["ẵ"]={ "ă","̃" },
+ ["Ặ"]={ "Ạ","̆" },
+ ["ặ"]={ "ạ","̆" },
+ ["Ẹ"]={ "E","̣" },
+ ["ẹ"]={ "e","̣" },
+ ["Ẻ"]={ "E","̉" },
+ ["ẻ"]={ "e","̉" },
+ ["Ẽ"]={ "E","̃" },
+ ["ẽ"]={ "e","̃" },
+ ["Ế"]={ "Ê","́" },
+ ["ế"]={ "ê","́" },
+ ["Ề"]={ "Ê","̀" },
+ ["ề"]={ "ê","̀" },
+ ["Ể"]={ "Ê","̉" },
+ ["ể"]={ "ê","̉" },
+ ["Ễ"]={ "Ê","̃" },
+ ["ễ"]={ "ê","̃" },
+ ["Ệ"]={ "Ẹ","̂" },
+ ["ệ"]={ "ẹ","̂" },
+ ["Ỉ"]={ "I","̉" },
+ ["ỉ"]={ "i","̉" },
+ ["Ị"]={ "I","̣" },
+ ["ị"]={ "i","̣" },
+ ["Ọ"]={ "O","̣" },
+ ["ọ"]={ "o","̣" },
+ ["Ỏ"]={ "O","̉" },
+ ["ỏ"]={ "o","̉" },
+ ["Ố"]={ "Ô","́" },
+ ["ố"]={ "ô","́" },
+ ["Ồ"]={ "Ô","̀" },
+ ["ồ"]={ "ô","̀" },
+ ["Ổ"]={ "Ô","̉" },
+ ["ổ"]={ "ô","̉" },
+ ["Ỗ"]={ "Ô","̃" },
+ ["ỗ"]={ "ô","̃" },
+ ["Ộ"]={ "Ọ","̂" },
+ ["ộ"]={ "ọ","̂" },
+ ["Ớ"]={ "Ơ","́" },
+ ["ớ"]={ "ơ","́" },
+ ["Ờ"]={ "Ơ","̀" },
+ ["ờ"]={ "ơ","̀" },
+ ["Ở"]={ "Ơ","̉" },
+ ["ở"]={ "ơ","̉" },
+ ["Ỡ"]={ "Ơ","̃" },
+ ["ỡ"]={ "ơ","̃" },
+ ["Ợ"]={ "Ơ","̣" },
+ ["ợ"]={ "ơ","̣" },
+ ["Ụ"]={ "U","̣" },
+ ["ụ"]={ "u","̣" },
+ ["Ủ"]={ "U","̉" },
+ ["ủ"]={ "u","̉" },
+ ["Ứ"]={ "Ư","́" },
+ ["ứ"]={ "ư","́" },
+ ["Ừ"]={ "Ư","̀" },
+ ["ừ"]={ "ư","̀" },
+ ["Ử"]={ "Ư","̉" },
+ ["ử"]={ "ư","̉" },
+ ["Ữ"]={ "Ư","̃" },
+ ["ữ"]={ "ư","̃" },
+ ["Ự"]={ "Ư","̣" },
+ ["ự"]={ "ư","̣" },
+ ["Ỳ"]={ "Y","̀" },
+ ["ỳ"]={ "y","̀" },
+ ["Ỵ"]={ "Y","̣" },
+ ["ỵ"]={ "y","̣" },
+ ["Ỷ"]={ "Y","̉" },
+ ["ỷ"]={ "y","̉" },
+ ["Ỹ"]={ "Y","̃" },
+ ["ỹ"]={ "y","̃" },
+ ["ἀ"]={ "α","̓" },
+ ["ἁ"]={ "α","̔" },
+ ["ἂ"]={ "ἀ","̀" },
+ ["ἃ"]={ "ἁ","̀" },
+ ["ἄ"]={ "ἀ","́" },
+ ["ἅ"]={ "ἁ","́" },
+ ["ἆ"]={ "ἀ","͂" },
+ ["ἇ"]={ "ἁ","͂" },
+ ["Ἀ"]={ "Α","̓" },
+ ["Ἁ"]={ "Α","̔" },
+ ["Ἂ"]={ "Ἀ","̀" },
+ ["Ἃ"]={ "Ἁ","̀" },
+ ["Ἄ"]={ "Ἀ","́" },
+ ["Ἅ"]={ "Ἁ","́" },
+ ["Ἆ"]={ "Ἀ","͂" },
+ ["Ἇ"]={ "Ἁ","͂" },
+ ["ἐ"]={ "ε","̓" },
+ ["ἑ"]={ "ε","̔" },
+ ["ἒ"]={ "ἐ","̀" },
+ ["ἓ"]={ "ἑ","̀" },
+ ["ἔ"]={ "ἐ","́" },
+ ["ἕ"]={ "ἑ","́" },
+ ["Ἐ"]={ "Ε","̓" },
+ ["Ἑ"]={ "Ε","̔" },
+ ["Ἒ"]={ "Ἐ","̀" },
+ ["Ἓ"]={ "Ἑ","̀" },
+ ["Ἔ"]={ "Ἐ","́" },
+ ["Ἕ"]={ "Ἑ","́" },
+ ["ἠ"]={ "η","̓" },
+ ["ἡ"]={ "η","̔" },
+ ["ἢ"]={ "ἠ","̀" },
+ ["ἣ"]={ "ἡ","̀" },
+ ["ἤ"]={ "ἠ","́" },
+ ["ἥ"]={ "ἡ","́" },
+ ["ἦ"]={ "ἠ","͂" },
+ ["ἧ"]={ "ἡ","͂" },
+ ["Ἠ"]={ "Η","̓" },
+ ["Ἡ"]={ "Η","̔" },
+ ["Ἢ"]={ "Ἠ","̀" },
+ ["Ἣ"]={ "Ἡ","̀" },
+ ["Ἤ"]={ "Ἠ","́" },
+ ["Ἥ"]={ "Ἡ","́" },
+ ["Ἦ"]={ "Ἠ","͂" },
+ ["Ἧ"]={ "Ἡ","͂" },
+ ["ἰ"]={ "ι","̓" },
+ ["ἱ"]={ "ι","̔" },
+ ["ἲ"]={ "ἰ","̀" },
+ ["ἳ"]={ "ἱ","̀" },
+ ["ἴ"]={ "ἰ","́" },
+ ["ἵ"]={ "ἱ","́" },
+ ["ἶ"]={ "ἰ","͂" },
+ ["ἷ"]={ "ἱ","͂" },
+ ["Ἰ"]={ "Ι","̓" },
+ ["Ἱ"]={ "Ι","̔" },
+ ["Ἲ"]={ "Ἰ","̀" },
+ ["Ἳ"]={ "Ἱ","̀" },
+ ["Ἴ"]={ "Ἰ","́" },
+ ["Ἵ"]={ "Ἱ","́" },
+ ["Ἶ"]={ "Ἰ","͂" },
+ ["Ἷ"]={ "Ἱ","͂" },
+ ["ὀ"]={ "ο","̓" },
+ ["ὁ"]={ "ο","̔" },
+ ["ὂ"]={ "ὀ","̀" },
+ ["ὃ"]={ "ὁ","̀" },
+ ["ὄ"]={ "ὀ","́" },
+ ["ὅ"]={ "ὁ","́" },
+ ["Ὀ"]={ "Ο","̓" },
+ ["Ὁ"]={ "Ο","̔" },
+ ["Ὂ"]={ "Ὀ","̀" },
+ ["Ὃ"]={ "Ὁ","̀" },
+ ["Ὄ"]={ "Ὀ","́" },
+ ["Ὅ"]={ "Ὁ","́" },
+ ["ὐ"]={ "υ","̓" },
+ ["ὑ"]={ "υ","̔" },
+ ["ὒ"]={ "ὐ","̀" },
+ ["ὓ"]={ "ὑ","̀" },
+ ["ὔ"]={ "ὐ","́" },
+ ["ὕ"]={ "ὑ","́" },
+ ["ὖ"]={ "ὐ","͂" },
+ ["ὗ"]={ "ὑ","͂" },
+ ["Ὑ"]={ "Υ","̔" },
+ ["Ὓ"]={ "Ὑ","̀" },
+ ["Ὕ"]={ "Ὑ","́" },
+ ["Ὗ"]={ "Ὑ","͂" },
+ ["ὠ"]={ "ω","̓" },
+ ["ὡ"]={ "ω","̔" },
+ ["ὢ"]={ "ὠ","̀" },
+ ["ὣ"]={ "ὡ","̀" },
+ ["ὤ"]={ "ὠ","́" },
+ ["ὥ"]={ "ὡ","́" },
+ ["ὦ"]={ "ὠ","͂" },
+ ["ὧ"]={ "ὡ","͂" },
+ ["Ὠ"]={ "Ω","̓" },
+ ["Ὡ"]={ "Ω","̔" },
+ ["Ὢ"]={ "Ὠ","̀" },
+ ["Ὣ"]={ "Ὡ","̀" },
+ ["Ὤ"]={ "Ὠ","́" },
+ ["Ὥ"]={ "Ὡ","́" },
+ ["Ὦ"]={ "Ὠ","͂" },
+ ["Ὧ"]={ "Ὡ","͂" },
+ ["ὰ"]={ "α","̀" },
+ ["ὲ"]={ "ε","̀" },
+ ["ὴ"]={ "η","̀" },
+ ["ὶ"]={ "ι","̀" },
+ ["ὸ"]={ "ο","̀" },
+ ["ὺ"]={ "υ","̀" },
+ ["ὼ"]={ "ω","̀" },
+ ["ᾀ"]={ "ἀ","ͅ" },
+ ["ᾁ"]={ "ἁ","ͅ" },
+ ["ᾂ"]={ "ἂ","ͅ" },
+ ["ᾃ"]={ "ἃ","ͅ" },
+ ["ᾄ"]={ "ἄ","ͅ" },
+ ["ᾅ"]={ "ἅ","ͅ" },
+ ["ᾆ"]={ "ἆ","ͅ" },
+ ["ᾇ"]={ "ἇ","ͅ" },
+ ["ᾈ"]={ "Ἀ","ͅ" },
+ ["ᾉ"]={ "Ἁ","ͅ" },
+ ["ᾊ"]={ "Ἂ","ͅ" },
+ ["ᾋ"]={ "Ἃ","ͅ" },
+ ["ᾌ"]={ "Ἄ","ͅ" },
+ ["ᾍ"]={ "Ἅ","ͅ" },
+ ["ᾎ"]={ "Ἆ","ͅ" },
+ ["ᾏ"]={ "Ἇ","ͅ" },
+ ["ᾐ"]={ "ἠ","ͅ" },
+ ["ᾑ"]={ "ἡ","ͅ" },
+ ["ᾒ"]={ "ἢ","ͅ" },
+ ["ᾓ"]={ "ἣ","ͅ" },
+ ["ᾔ"]={ "ἤ","ͅ" },
+ ["ᾕ"]={ "ἥ","ͅ" },
+ ["ᾖ"]={ "ἦ","ͅ" },
+ ["ᾗ"]={ "ἧ","ͅ" },
+ ["ᾘ"]={ "Ἠ","ͅ" },
+ ["ᾙ"]={ "Ἡ","ͅ" },
+ ["ᾚ"]={ "Ἢ","ͅ" },
+ ["ᾛ"]={ "Ἣ","ͅ" },
+ ["ᾜ"]={ "Ἤ","ͅ" },
+ ["ᾝ"]={ "Ἥ","ͅ" },
+ ["ᾞ"]={ "Ἦ","ͅ" },
+ ["ᾟ"]={ "Ἧ","ͅ" },
+ ["ᾠ"]={ "ὠ","ͅ" },
+ ["ᾡ"]={ "ὡ","ͅ" },
+ ["ᾢ"]={ "ὢ","ͅ" },
+ ["ᾣ"]={ "ὣ","ͅ" },
+ ["ᾤ"]={ "ὤ","ͅ" },
+ ["ᾥ"]={ "ὥ","ͅ" },
+ ["ᾦ"]={ "ὦ","ͅ" },
+ ["ᾧ"]={ "ὧ","ͅ" },
+ ["ᾨ"]={ "Ὠ","ͅ" },
+ ["ᾩ"]={ "Ὡ","ͅ" },
+ ["ᾪ"]={ "Ὢ","ͅ" },
+ ["ᾫ"]={ "Ὣ","ͅ" },
+ ["ᾬ"]={ "Ὤ","ͅ" },
+ ["ᾭ"]={ "Ὥ","ͅ" },
+ ["ᾮ"]={ "Ὦ","ͅ" },
+ ["ᾯ"]={ "Ὧ","ͅ" },
+ ["ᾰ"]={ "α","̆" },
+ ["ᾱ"]={ "α","̄" },
+ ["ᾲ"]={ "ὰ","ͅ" },
+ ["ᾳ"]={ "α","ͅ" },
+ ["ᾴ"]={ "ά","ͅ" },
+ ["ᾶ"]={ "α","͂" },
+ ["ᾷ"]={ "ᾶ","ͅ" },
+ ["Ᾰ"]={ "Α","̆" },
+ ["Ᾱ"]={ "Α","̄" },
+ ["Ὰ"]={ "Α","̀" },
+ ["ᾼ"]={ "Α","ͅ" },
+ ["῁"]={ "¨","͂" },
+ ["ῂ"]={ "ὴ","ͅ" },
+ ["ῃ"]={ "η","ͅ" },
+ ["ῄ"]={ "ή","ͅ" },
+ ["ῆ"]={ "η","͂" },
+ ["ῇ"]={ "ῆ","ͅ" },
+ ["Ὲ"]={ "Ε","̀" },
+ ["Ὴ"]={ "Η","̀" },
+ ["ῌ"]={ "Η","ͅ" },
+ ["῍"]={ "᾿","̀" },
+ ["῎"]={ "᾿","́" },
+ ["῏"]={ "᾿","͂" },
+ ["ῐ"]={ "ι","̆" },
+ ["ῑ"]={ "ι","̄" },
+ ["ῒ"]={ "ϊ","̀" },
+ ["ῖ"]={ "ι","͂" },
+ ["ῗ"]={ "ϊ","͂" },
+ ["Ῐ"]={ "Ι","̆" },
+ ["Ῑ"]={ "Ι","̄" },
+ ["Ὶ"]={ "Ι","̀" },
+ ["῝"]={ "῾","̀" },
+ ["῞"]={ "῾","́" },
+ ["῟"]={ "῾","͂" },
+ ["ῠ"]={ "υ","̆" },
+ ["ῡ"]={ "υ","̄" },
+ ["ῢ"]={ "ϋ","̀" },
+ ["ῤ"]={ "ρ","̓" },
+ ["ῥ"]={ "ρ","̔" },
+ ["ῦ"]={ "υ","͂" },
+ ["ῧ"]={ "ϋ","͂" },
+ ["Ῠ"]={ "Υ","̆" },
+ ["Ῡ"]={ "Υ","̄" },
+ ["Ὺ"]={ "Υ","̀" },
+ ["Ῥ"]={ "Ρ","̔" },
+ ["῭"]={ "¨","̀" },
+ ["ῲ"]={ "ὼ","ͅ" },
+ ["ῳ"]={ "ω","ͅ" },
+ ["ῴ"]={ "ώ","ͅ" },
+ ["ῶ"]={ "ω","͂" },
+ ["ῷ"]={ "ῶ","ͅ" },
+ ["Ὸ"]={ "Ο","̀" },
+ ["Ὼ"]={ "Ω","̀" },
+ ["ῼ"]={ "Ω","ͅ" },
+ ["↚"]={ "←","̸" },
+ ["↛"]={ "→","̸" },
+ ["↮"]={ "↔","̸" },
+ ["⇍"]={ "⇐","̸" },
+ ["⇎"]={ "⇔","̸" },
+ ["⇏"]={ "⇒","̸" },
+ ["∄"]={ "∃","̸" },
+ ["∉"]={ "∈","̸" },
+ ["∌"]={ "∋","̸" },
+ ["∤"]={ "∣","̸" },
+ ["∦"]={ "∥","̸" },
+ ["≁"]={ "∼","̸" },
+ ["≄"]={ "≃","̸" },
+ ["≇"]={ "≅","̸" },
+ ["≉"]={ "≈","̸" },
+ ["≠"]={ "=","̸" },
+ ["≢"]={ "≡","̸" },
+ ["≭"]={ "≍","̸" },
+ ["≮"]={ "<","̸" },
+ ["≯"]={ ">","̸" },
+ ["≰"]={ "≤","̸" },
+ ["≱"]={ "≥","̸" },
+ ["≴"]={ "≲","̸" },
+ ["≵"]={ "≳","̸" },
+ ["≸"]={ "≶","̸" },
+ ["≹"]={ "≷","̸" },
+ ["⊀"]={ "≺","̸" },
+ ["⊁"]={ "≻","̸" },
+ ["⊄"]={ "⊂","̸" },
+ ["⊅"]={ "⊃","̸" },
+ ["⊈"]={ "⊆","̸" },
+ ["⊉"]={ "⊇","̸" },
+ ["⊬"]={ "⊢","̸" },
+ ["⊭"]={ "⊨","̸" },
+ ["⊮"]={ "⊩","̸" },
+ ["⊯"]={ "⊫","̸" },
+ ["⋠"]={ "≼","̸" },
+ ["⋡"]={ "≽","̸" },
+ ["⋢"]={ "⊑","̸" },
+ ["⋣"]={ "⊒","̸" },
+ ["⋪"]={ "⊲","̸" },
+ ["⋫"]={ "⊳","̸" },
+ ["⋬"]={ "⊴","̸" },
+ ["⋭"]={ "⊵","̸" },
+ ["⫝̸"]={ "⫝","̸" },
+ ["が"]={ "か","゙" },
+ ["ぎ"]={ "き","゙" },
+ ["ぐ"]={ "く","゙" },
+ ["げ"]={ "け","゙" },
+ ["ご"]={ "こ","゙" },
+ ["ざ"]={ "さ","゙" },
+ ["じ"]={ "し","゙" },
+ ["ず"]={ "す","゙" },
+ ["ぜ"]={ "せ","゙" },
+ ["ぞ"]={ "そ","゙" },
+ ["だ"]={ "た","゙" },
+ ["ぢ"]={ "ち","゙" },
+ ["づ"]={ "つ","゙" },
+ ["で"]={ "て","゙" },
+ ["ど"]={ "と","゙" },
+ ["ば"]={ "は","゙" },
+ ["ぱ"]={ "は","゚" },
+ ["び"]={ "ひ","゙" },
+ ["ぴ"]={ "ひ","゚" },
+ ["ぶ"]={ "ふ","゙" },
+ ["ぷ"]={ "ふ","゚" },
+ ["べ"]={ "へ","゙" },
+ ["ぺ"]={ "へ","゚" },
+ ["ぼ"]={ "ほ","゙" },
+ ["ぽ"]={ "ほ","゚" },
+ ["ゔ"]={ "う","゙" },
+ ["ゞ"]={ "ゝ","゙" },
+ ["ガ"]={ "カ","゙" },
+ ["ギ"]={ "キ","゙" },
+ ["グ"]={ "ク","゙" },
+ ["ゲ"]={ "ケ","゙" },
+ ["ゴ"]={ "コ","゙" },
+ ["ザ"]={ "サ","゙" },
+ ["ジ"]={ "シ","゙" },
+ ["ズ"]={ "ス","゙" },
+ ["ゼ"]={ "セ","゙" },
+ ["ゾ"]={ "ソ","゙" },
+ ["ダ"]={ "タ","゙" },
+ ["ヂ"]={ "チ","゙" },
+ ["ヅ"]={ "ツ","゙" },
+ ["デ"]={ "テ","゙" },
+ ["ド"]={ "ト","゙" },
+ ["バ"]={ "ハ","゙" },
+ ["パ"]={ "ハ","゚" },
+ ["ビ"]={ "ヒ","゙" },
+ ["ピ"]={ "ヒ","゚" },
+ ["ブ"]={ "フ","゙" },
+ ["プ"]={ "フ","゚" },
+ ["ベ"]={ "ヘ","゙" },
+ ["ペ"]={ "ヘ","゚" },
+ ["ボ"]={ "ホ","゙" },
+ ["ポ"]={ "ホ","゚" },
+ ["ヴ"]={ "ウ","゙" },
+ ["ヷ"]={ "ワ","゙" },
+ ["ヸ"]={ "ヰ","゙" },
+ ["ヹ"]={ "ヱ","゙" },
+ ["ヺ"]={ "ヲ","゙" },
+ ["ヾ"]={ "ヽ","゙" },
+ ["יִ"]={ "י","ִ" },
+ ["ײַ"]={ "ײ","ַ" },
+ ["שׁ"]={ "ש","ׁ" },
+ ["שׂ"]={ "ש","ׂ" },
+ ["שּׁ"]={ "שּ","ׁ" },
+ ["שּׂ"]={ "שּ","ׂ" },
+ ["אַ"]={ "א","ַ" },
+ ["אָ"]={ "א","ָ" },
+ ["אּ"]={ "א","ּ" },
+ ["בּ"]={ "ב","ּ" },
+ ["גּ"]={ "ג","ּ" },
+ ["דּ"]={ "ד","ּ" },
+ ["הּ"]={ "ה","ּ" },
+ ["וּ"]={ "ו","ּ" },
+ ["זּ"]={ "ז","ּ" },
+ ["טּ"]={ "ט","ּ" },
+ ["יּ"]={ "י","ּ" },
+ ["ךּ"]={ "ך","ּ" },
+ ["כּ"]={ "כ","ּ" },
+ ["לּ"]={ "ל","ּ" },
+ ["מּ"]={ "מ","ּ" },
+ ["נּ"]={ "נ","ּ" },
+ ["סּ"]={ "ס","ּ" },
+ ["ףּ"]={ "ף","ּ" },
+ ["פּ"]={ "פ","ּ" },
+ ["צּ"]={ "צ","ּ" },
+ ["קּ"]={ "ק","ּ" },
+ ["רּ"]={ "ר","ּ" },
+ ["שּ"]={ "ש","ּ" },
+ ["תּ"]={ "ת","ּ" },
+ ["וֹ"]={ "ו","ֹ" },
+ ["בֿ"]={ "ב","ֿ" },
+ ["כֿ"]={ "כ","ֿ" },
+ ["פֿ"]={ "פ","ֿ" },
+ ["𑂚"]={ "𑂙","𑂺" },
+ ["𑂜"]={ "𑂛","𑂺" },
+ ["𑂫"]={ "𑂥","𑂺" },
+ ["𑄮"]={ "𑄱","𑄧" },
+ ["𑄯"]={ "𑄲","𑄧" },
+ ["𑍋"]={ "𑍇","𑌾" },
+ ["𑍌"]={ "𑍇","𑍗" },
+ ["𑒻"]={ "𑒹","𑒺" },
+ ["𑒼"]={ "𑒹","𑒰" },
+ ["𑒾"]={ "𑒹","𑒽" },
+ ["𑖺"]={ "𑖸","𑖯" },
+ ["𑖻"]={ "𑖹","𑖯" },
+ ["𝅗𝅥"]={ "𝅗","𝅥" },
+ ["𝅘𝅥"]={ "𝅘","𝅥" },
+ ["𝅘𝅥𝅮"]={ "𝅘𝅥","𝅮" },
+ ["𝅘𝅥𝅯"]={ "𝅘𝅥","𝅯" },
+ ["𝅘𝅥𝅰"]={ "𝅘𝅥","𝅰" },
+ ["𝅘𝅥𝅱"]={ "𝅘𝅥","𝅱" },
+ ["𝅘𝅥𝅲"]={ "𝅘𝅥","𝅲" },
+ ["𝆹𝅥"]={ "𝆹","𝅥" },
+ ["𝆺𝅥"]={ "𝆺","𝅥" },
+ ["𝆹𝅥𝅮"]={ "𝆹𝅥","𝅮" },
+ ["𝆺𝅥𝅮"]={ "𝆺𝅥","𝅮" },
+ ["𝆹𝅥𝅯"]={ "𝆹𝅥","𝅯" },
+ ["𝆺𝅥𝅯"]={ "𝆺𝅥","𝅯" },
+ },
+ },
+ },
+ ["name"]="collapse",
+ ["prepend"]=true,
+ ["type"]="ligature",
+}
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
if not modules then modules={} end modules ['font-gbn']={
version=1.001,
comment="companion to luatex-*.tex",
diff --git a/tex/generic/context/luatex/luatex-fonts.lua b/tex/generic/context/luatex/luatex-fonts.lua
index c21389c71..20690992c 100644
--- a/tex/generic/context/luatex/luatex-fonts.lua
+++ b/tex/generic/context/luatex/luatex-fonts.lua
@@ -277,6 +277,7 @@ if non_generic_context.luatex_fonts.skip_loading ~= true then
loadmodule('font-def.lua')
loadmodule('font-xtx.lua') -- xetex compatible specifiers (plain/latex only)
loadmodule('luatex-fonts-ext.lua') -- some extensions
+ -- loadmodule('luatex-fonts-lig.lua') -- and another one
-- We need to plug into a callback and the following module implements the handlers. Actual
-- plugging in happens later.