summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scripts/context/lua/luatools.lua845
-rw-r--r--scripts/context/lua/mtx-context.lua3
-rw-r--r--scripts/context/lua/mtx-server.lua83
-rw-r--r--scripts/context/lua/mtxrun.lua920
-rw-r--r--tex/context/base/cont-new.tex2
-rw-r--r--tex/context/base/context.tex2
-rw-r--r--tex/context/base/core-buf.lua21
-rw-r--r--tex/context/base/core-lst.tex2
-rw-r--r--tex/context/base/core-mat.tex13
-rw-r--r--tex/context/base/core-ver.mkiv1
-rw-r--r--tex/context/base/font-afm.lua25
-rw-r--r--tex/context/base/font-def.lua13
-rw-r--r--tex/context/base/font-enc.lua8
-rw-r--r--tex/context/base/font-ini.lua5
-rw-r--r--tex/context/base/font-otf.lua13
-rw-r--r--tex/context/base/font-syn.lua6
-rw-r--r--tex/context/base/font-tfm.lua45
-rw-r--r--tex/context/base/l-file.lua22
-rw-r--r--tex/context/base/l-string.lua1
-rw-r--r--tex/context/base/l-url.lua2
-rw-r--r--tex/context/base/l-utils.lua13
-rw-r--r--tex/context/base/l-xml.lua46
-rw-r--r--tex/context/base/luat-crl.lua7
-rw-r--r--tex/context/base/luat-env.lua4
-rw-r--r--tex/context/base/luat-inp.lua504
-rw-r--r--tex/context/base/luat-lib.lua26
-rw-r--r--tex/context/base/luat-tex.lua1
-rw-r--r--tex/context/base/luat-tmp.lua238
-rw-r--r--tex/context/base/lxml-ini.lua60
-rw-r--r--tex/context/base/lxml-ini.tex12
-rw-r--r--tex/context/base/math-ent.lua2097
-rw-r--r--tex/context/base/math-ini.lua7
-rw-r--r--tex/context/base/math-ini.mkiv1
-rw-r--r--tex/context/base/math-ini.tex7
-rw-r--r--tex/context/base/node-ini.lua4
-rw-r--r--tex/context/base/syst-cat.mkiv2
-rw-r--r--tex/context/base/syst-cat.tex18
-rw-r--r--tex/context/base/x-mathml.lua300
-rw-r--r--tex/context/base/x-mmc.mkiv1028
-rw-r--r--tex/context/base/x-mmp.mkiv107
-rw-r--r--tex/context/interface/keys-cz.xml2
-rw-r--r--tex/context/interface/keys-de.xml2
-rw-r--r--tex/context/interface/keys-en.xml2
-rw-r--r--tex/context/interface/keys-fr.xml2
-rw-r--r--tex/context/interface/keys-it.xml2
-rw-r--r--tex/context/interface/keys-nl.xml2
-rw-r--r--tex/context/interface/keys-ro.xml2
-rw-r--r--web2c/contextcnf.lua36
48 files changed, 4612 insertions, 1952 deletions
diff --git a/scripts/context/lua/luatools.lua b/scripts/context/lua/luatools.lua
index b092c5050..89e5e0eb4 100644
--- a/scripts/context/lua/luatools.lua
+++ b/scripts/context/lua/luatools.lua
@@ -15,7 +15,7 @@
-- the future. As long as Luatex is under development the
-- interfaces and names of functions may change.
-banner = "version 1.1.1 - 2006+ - PRAGMA ADE / CONTEXT"
+banner = "version 1.2.0 - 2006+ - PRAGMA ADE / CONTEXT"
texlua = true
-- For the sake of independence we optionally can merge the library
@@ -374,7 +374,6 @@ local patterns_escapes = {
["]"] = "%]",
}
-
function string:pattesc()
return (self:gsub(".",patterns_escapes))
end
@@ -1687,14 +1686,22 @@ end
--~ print("../test/" .. " == " .. file.collapse_path("../test/"))
--~ print("a/a" .. " == " .. file.collapse_path("a/b/c/../../a"))
+--~ function file.collapse_path(str)
+--~ local ok, n = false, 0
+--~ while not ok do
+--~ ok = true
+--~ str, n = str:gsub("[^%./]+/%.%./", function(s)
+--~ ok = false
+--~ return ""
+--~ end)
+--~ end
+--~ return (str:gsub("/%./","/"))
+--~ end
+
function file.collapse_path(str)
- local ok, n = false, 0
- while not ok do
- ok = true
- str, n = str:gsub("[^%./]+/%.%./", function(s)
- ok = false
- return ""
- end)
+ local n = 1
+ while n > 0 do
+ str, n = str:gsub("([^/%.]+/%.%./)","")
end
return (str:gsub("/%./","/"))
end
@@ -1762,7 +1769,7 @@ function url.hashed(str)
path = s[3],
query = s[4],
fragment = s[5],
- original=str
+ original = str
}
end
@@ -2560,14 +2567,32 @@ os.platform = os.platform or os.type or (io.pathseparator == ";" and "windows")
--
-- for k,v in pairs(arg) do print(k,v) end
-if arg and (arg[0] == 'luatex' or arg[0] == 'luatex.exe') and arg[1] == "--luaonly" then
- arg[-1]=arg[0] arg[0]=arg[2] for k=3,#arg do arg[k-2]=arg[k] end arg[#arg]=nil arg[#arg]=nil
-end
-
-- environment
if not environment then environment = { } end
+environment.ownbin = environment.ownbin or arg[-2] or arg[-1] or arg[0] or "luatex"
+
+local ownpath = nil -- we could use a metatable here
+
+function environment.ownpath()
+ if not ownpath then
+ for p in string.gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
+ local b = file.join(p,environment.ownbin)
+ if lfs.isfile(b..".exe") or lfs.isfile(b) then
+ ownpath = p
+ break
+ end
+ end
+ if not ownpath then ownpath = '.' end
+ end
+ return ownpath
+end
+
+if arg and (arg[0] == 'luatex' or arg[0] == 'luatex.exe') and arg[1] == "--luaonly" then
+ arg[-1]=arg[0] arg[0]=arg[2] for k=3,#arg do arg[k-2]=arg[k] end arg[#arg]=nil arg[#arg]=nil
+end
+
environment.arguments = { }
environment.files = { }
environment.sorted_argument_keys = nil
@@ -2679,6 +2704,10 @@ end
-- additional functionality becomes available. We will split this
-- module in components when we're done with prototyping.
+-- TODO: os.getenv -> os.env[]
+-- TODO: instances.[hashes,cnffiles,configurations,522] -> ipairs (alles check, sneller)
+-- TODO: check escaping in find etc, too much, too slow
+
-- This is the first code I wrote for LuaTeX, so it needs some cleanup.
-- To be considered: hash key lowercase, first entry in table filename
@@ -2689,9 +2718,6 @@ end
-- Beware, loading and saving is overloaded in luat-tmp!
--- todo: instances.[hashes,cnffiles,configurations,522] -> ipairs (alles check, sneller)
--- todo: check escaping in find etc, too much, too slow
-
if not versions then versions = { } end versions['luat-inp'] = 1.001
if not environment then environment = { } end
if not file then file = { } end
@@ -2710,6 +2736,8 @@ if not input.hashers then input.hashers = { } end -- load databases
if not input.generators then input.generators = { } end -- generate databases
if not input.filters then input.filters = { } end -- conversion filters
+local format = string.format
+
input.locators.notfound = { nil }
input.hashers.notfound = { nil }
input.generators.notfound = { nil }
@@ -2719,6 +2747,7 @@ input.banner = nil
input.verbose = false
input.debug = false
input.cnfname = 'texmf.cnf'
+input.luaname = 'texmfcnf.lua'
input.lsrname = 'ls-R'
input.luasuffix = '.tma'
input.lucsuffix = '.tmc'
@@ -2808,12 +2837,14 @@ function input.reset()
instance.files = { }
instance.remap = { }
instance.configuration = { }
+ instance.setup = { }
instance.order = { }
instance.found = { }
instance.foundintrees = { }
instance.kpsevars = { }
instance.hashes = { }
instance.cnffiles = { }
+ instance.luafiles = { }
instance.lists = { }
instance.remember = true
instance.diskcache = true
@@ -2833,7 +2864,6 @@ function input.reset()
instance.stoptime = 0
instance.validfile = function(path,name) return true end
instance.data = { } -- only for loading
- instance.sortdata = false
instance.force_suffixes = true
instance.dummy_path_expr = "^!*unset/*$"
instance.fakepaths = { }
@@ -2846,7 +2876,7 @@ function input.reset()
end
else
-- we will access os.env frequently
- for k,v in pairs({'HOME','TEXMF','TEXMFCNF','SELFAUTOPARENT'}) do
+ for k,v in pairs({'HOME','TEXMF','TEXMFCNF'}) do
local e = os.getenv(v)
if e then
-- input.report("setting",v,"to",input.bare_variable(e))
@@ -2874,7 +2904,7 @@ function input.reset_hashes(instance)
instance.found = { }
end
-function input.bare_variable(str)
+function input.bare_variable(str) -- assumes str is a string
-- return string.gsub(string.gsub(string.gsub(str,"%s+$",""),'^"(.+)"$',"%1"),"^'(.+)'$","%1")
return (str:gsub("\s*([\"\']?)(.+)%1\s*", "%2"))
end
@@ -2959,7 +2989,7 @@ do
instance.stoptime = stoptime
instance.loadtime = instance.loadtime + loadtime
if report then
- input.report('load time', string.format("%0.3f",loadtime))
+ input.report('load time', format("%0.3f",loadtime))
end
return loadtime
end
@@ -2970,7 +3000,7 @@ do
end
function input.elapsedtime(instance)
- return string.format("%0.3f",(instance and instance.loadtime) or 0)
+ return format("%0.3f",(instance and instance.loadtime) or 0)
end
function input.report_loadtime(instance)
@@ -2986,15 +3016,19 @@ function input.env(instance,key)
end
function input.osenv(instance,key)
- if instance.environment[key] == nil then
- local e = os.getenv(key)
+ local ie = instance.environment
+ local value = ie[key]
+ if value == nil then
+ -- local e = os.getenv(key)
+ local e = os.env[key]
if e == nil then
- instance.environment[key] = "" -- false
+ -- value = "" -- false
else
- instance.environment[key] = input.bare_variable(e)
+ value = input.bare_variable(e)
end
+ ie[key] = value
end
- return instance.environment[key] or ""
+ return value or ""
end
-- we follow a rather traditional approach:
@@ -3005,66 +3039,103 @@ end
-- for the moment we don't expect a configuration file in a zip
function input.identify_cnf(instance)
+ -- we no longer support treepath and rootpath (was handy for testing);
+ -- also we now follow the stupid route: if not set then just assume *one*
+ -- cnf file under texmf (i.e. distribution)
if #instance.cnffiles == 0 then
- if instance.treepath ~= "" then
- -- this is a special purpose branch, not really used
- if instance.rootpath ~= "" then
- local t = instance.treepath:splitchr(',')
- for k,v in ipairs(t) do
- t[k] = file.join(instance.rootpath,v)
+ if input.env(instance,'TEXMFCNF') == "" then
+ local ownpath = environment.ownpath() or "."
+ if ownpath then
+ -- beware, this is tricky on my own system because at that location I do have
+ -- the raw tree that ends up in the zip; i.e. I cannot test this kind of mess
+ local function locate(filename,list)
+ local ownroot = input.normalize_name(file.join(ownpath,"../.."))
+ if not lfs.isdir(file.join(ownroot,"texmf")) then
+ ownroot = input.normalize_name(file.join(ownpath,".."))
+ if not lfs.isdir(file.join(ownroot,"texmf")) then
+ input.verbose = true
+ input.report("error", "unable to identify cnf file")
+ return
+ end
+ end
+ local texmfcnf = file.join(ownroot,"texmf-local/web2c",filename) -- for minimals and myself
+ if not lfs.isfile(texmfcnf) then
+ texmfcnf = file.join(ownroot,"texmf/web2c",filename)
+ if not lfs.isfile(texmfcnf) then
+ input.verbose = true
+ input.report("error", "unable to locate",filename)
+ return
+ end
+ end
+ table.insert(list,texmfcnf)
+ local ie = instance.environment
+ if not ie['SELFAUTOPARENT'] then ie['SELFAUTOPARENT'] = ownroot end
+ if not ie['TEXMFCNF'] then ie['TEXMFCNF'] = file.dirname(texmfcnf) end
+ end
+ locate(input.luaname,instance.luafiles)
+ locate(input.cnfname,instance.cnffiles)
+ if #instance.luafiles == 0 and instance.cnffiles == 0 then
+ input.verbose = true
+ input.report("error", "unable to locate",filename)
+ os.exit()
end
- instance.treepath = table.concat(t,',')
+ -- here we also assume then TEXMF is set in the distribution, if this trickery is
+ -- used in the minimals, then users who don't use setuptex are on their own with
+ -- regards to extra trees
+ else
+ input.verbose = true
+ input.report("error", "unable to identify own path")
+ os.exit()
end
- local t = instance.treepath:splitchr(',')
- instance.environment['TEXMF'] = input.bare_variable(instance.treepath)
- instance.environment['TEXMFCNF'] = file.join(t[1] or '.','texmf/web2c')
- end
- if instance.rootpath ~= "" then
- -- this assumes a single path, maybe do an expanded split here too
- instance.environment['TEXMFCNF'] = file.join(instance.rootpath,'texmf/web2c')
- instance.environment['SELFAUTOPARENT'] = instance.rootpath
- end
- if input.env(instance,'TEXMFCNF') ~= "" then
+ else
local t = input.split_path(input.env(instance,'TEXMFCNF'))
t = input.aux.expanded_path(instance,t)
input.aux.expand_vars(instance,t)
- for _,v in ipairs(t) do
- table.insert(instance.cnffiles,file.join(v,input.cnfname))
- end
- elseif input.env(instance,'SELFAUTOPARENT') == '.' then
- table.insert(instance.cnffiles,file.join('.',input.cnfname))
- else
- for _,v in ipairs({'texmf-local','texmf'}) do
- table.insert(instance.cnffiles,file.join(input.env(instance,'SELFAUTOPARENT'),v,'web2c',input.cnfname))
+ local function locate(filename,list)
+ for _,v in ipairs(t) do
+ local texmfcnf = input.normalize_name(file.join(v,filename))
+ if lfs.isfile(texmfcnf) then
+ table.insert(list,texmfcnf)
+ end
+ end
end
+ locate(input.luaname,instance.luafiles)
+ locate(input.cnfname,instance.cnffiles)
end
end
end
function input.load_cnf(instance)
+ local function loadoldconfigdata()
+ for _, fname in ipairs(instance.cnffiles) do
+ input.aux.load_cnf(instance,fname)
+ end
+ end
-- instance.cnffiles contain complete names now !
if #instance.cnffiles == 0 then
input.report("no cnf files found (TEXMFCNF may not be set/known)")
else
instance.rootpath = instance.cnffiles[1]
for k,fname in ipairs(instance.cnffiles) do
- instance.cnffiles[k] = fname:gsub("\\",'/') -- needed?
+ instance.cnffiles[k] = input.normalize_name(fname:gsub("\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
+ instance.rootpath = input.normalize_name(instance.rootpath)
+ instance.environment['SELFAUTOPARENT'] = instance.rootpath -- just to be sure
if instance.lsrmode then
- input.loadconfigdata(instance,instance.cnffiles)
+ loadoldconfigdata()
elseif instance.diskcache and not instance.renewcache then
- input.loadconfig(instance,instance.cnffiles)
+ input.loadoldconfig(instance,instance.cnffiles)
if instance.loaderror then
- input.loadconfigdata(instance,instance.cnffiles)
- input.saveconfig(instance)
+ loadoldconfigdata()
+ input.saveoldconfig(instance)
end
else
- input.loadconfigdata(instance,instance.cnffiles)
+ loadoldconfigdata()
if instance.renewcache then
- input.saveconfig(instance)
+ input.saveoldconfig(instance)
end
end
input.aux.collapse_cnf_data(instance)
@@ -3072,40 +3143,34 @@ function input.load_cnf(instance)
input.checkconfigdata(instance)
end
-function input.loadconfigdata(instance)
- for _, fname in ipairs(instance.cnffiles) do
- input.aux.load_cnf(instance,fname)
+function input.load_lua(instance)
+ if #instance.luafiles == 0 then
+ -- yet harmless
+ else
+ instance.rootpath = instance.luafiles[1]
+ for k,fname in ipairs(instance.luafiles) do
+ instance.luafiles[k] = input.normalize_name(fname:gsub("\\",'/'))
+ end
+ for i=1,3 do
+ instance.rootpath = file.dirname(instance.rootpath)
+ end
+ instance.rootpath = input.normalize_name(instance.rootpath)
+ instance.environment['SELFAUTOPARENT'] = instance.rootpath -- just to be sure
+ input.loadnewconfig(instance)
+ input.aux.collapse_cnf_data(instance)
end
+ input.checkconfigdata(instance)
end
-if os.env then
- function input.aux.collapse_cnf_data(instance)
- for _,c in ipairs(instance.order) do
- for k,v in pairs(c) do
- if not instance.variables[k] then
- if instance.environment[k] then
- instance.variables[k] = instance.environment[k]
- else
- instance.kpsevars[k] = true
- instance.variables[k] = input.bare_variable(v)
- end
- end
- end
- end
- end
-else
- function input.aux.collapse_cnf_data(instance)
- for _,c in ipairs(instance.order) do
- for k,v in pairs(c) do
- if not instance.variables[k] then
- local e = os.getenv(k)
- if e then
- instance.environment[k] = input.bare_variable(e)
- instance.variables[k] = instance.environment[k]
- else
- instance.variables[k] = input.bare_variable(v)
- instance.kpsevars[k] = true
- end
+function input.aux.collapse_cnf_data(instance) -- potential optmization: pass start index (setup and configuration are shared)
+ for _,c in ipairs(instance.order) do
+ for k,v in pairs(c) do
+ if not instance.variables[k] then
+ if instance.environment[k] then
+ instance.variables[k] = instance.environment[k]
+ else
+ instance.kpsevars[k] = true
+ instance.variables[k] = input.bare_variable(v)
end
end
end
@@ -3116,11 +3181,11 @@ function input.aux.load_cnf(instance,fname)
fname = input.clean_path(fname)
local lname = fname:gsub("%.%a+$",input.luasuffix)
local f = io.open(lname)
- if f then
+ if f then -- this will go
f:close()
local dname = file.dirname(fname)
if not instance.configuration[dname] then
- input.aux.load_data(instance,dname,'configuration',file.basename(lname))
+ input.aux.load_configuration(instance,dname,lname)
instance.order[#instance.order+1] = instance.configuration[dname]
end
else
@@ -3135,7 +3200,7 @@ function input.aux.load_cnf(instance,fname)
end
local data = instance.configuration[dname]
while true do
- line = f:read()
+ local line, n = f:read(), 0
if line then
while true do -- join lines
line, n = line:gsub("\\%s*$", "")
@@ -3146,7 +3211,7 @@ function input.aux.load_cnf(instance,fname)
end
end
if not line:find("^[%%#]") then
- k, v = (line:gsub("%s*%%.*$","")):match("%s*(.-)%s*=%s*(.-)%s*$")
+ local k, v = (line:gsub("%s*%%.*$","")):match("%s*(.-)%s*=%s*(.-)%s*$")
if k and v and not data[k] then
data[k] = (v:gsub("[%%#].*",'')):gsub("~", "$HOME")
instance.kpsevars[k] = true
@@ -3220,6 +3285,7 @@ end
function input.locatelists(instance)
for _, path in pairs(input.simplified_list(input.expansion(instance,'TEXMF'))) do
+ path = file.collapse_path(path)
input.report("locating list of",path)
input.locatedatabase(instance,input.normalize_name(path))
end
@@ -3256,7 +3322,7 @@ function input.loadfiles(instance)
end
function input.hashers.tex(instance,tag,name)
- input.aux.load_data(instance,tag,'files')
+ input.aux.load_files(instance,tag)
end
-- generators:
@@ -3333,7 +3399,7 @@ do
end
end
action()
- input.report(string.format("%s files found on %s directories with %s uppercase remappings",n,m,r))
+ input.report(format("%s files found on %s directories with %s uppercase remappings",n,m,r))
else
local fullname = file.join(specification,input.lsrname)
local path = '.'
@@ -3386,7 +3452,7 @@ end
-- is more convenient.
function input.splitconfig(instance)
- for i,c in ipairs(instance.order) do
+ for i,c in ipairs(instance) do
for k,v in pairs(c) do
if type(v) == 'string' then
local t = file.split_path(v)
@@ -3420,14 +3486,7 @@ function input.join_path(str)
return str
end
end
---~ function input.splitexpansions(instance)
---~ for k,v in pairs(instance.expansions) do
---~ local t = file.split_path(v)
---~ if #t > 1 then
---~ instance.expansions[k] = t
---~ end
---~ end
---~ end
+
function input.splitexpansions(instance)
for k,v in pairs(instance.expansions) do
local t, h = { }, { }
@@ -3447,7 +3506,7 @@ end
-- end of split/join code
-function input.saveconfig(instance)
+function input.saveoldconfig(instance)
input.splitconfig(instance)
input.aux.save_data(instance, 'configuration', nil)
input.joinconfig(instance)
@@ -3460,44 +3519,83 @@ input.configbanner = [[
-- not copyrighted. [HH & TH]
]]
-function input.aux.save_data(instance, dataname, check)
- for cachename, files in pairs(instance[dataname]) do
- local name = file.join(cachename,dataname)
- local luaname, lucname = name .. input.luasuffix, name .. input.lucsuffix
- local f = io.open(luaname,'w')
- if f then
- input.report("saving " .. dataname .. " in", luaname)
- f:write(input.configbanner)
- f:write("\n")
- f:write("if not texmf then texmf = { } end\n")
- f:write("if not texmf.data then texmf.data = { } end\n")
- f:write("\n")
- f:write("texmf.data.type = '" .. dataname .. "'\n")
- f:write("texmf.data.version = '" .. input.cacheversion .. "'\n")
- f:write("texmf.data.date = '" .. os.date("%Y-%m-%d") .. "'\n")
- f:write("texmf.data.time = '" .. os.date("%H:%M:%S") .. "'\n")
- f:write('texmf.data.content = {\n')
- local function dump(k,v)
- if not check or check(v,k) then -- path, name
- if type(v) == 'string' then
- f:write("\t['" .. k .. "'] = '" .. v .. "',\n")
- elseif #v == 1 then
- f:write("\t['" .. k .. "'] = '" .. v[1] .. "',\n")
- else
- f:write("\t['" .. k .. "'] = {'" .. table.concat(v,"','").. "'},\n")
- end
+function input.serialize(files)
+ -- This version is somewhat optimized for the kind of
+ -- tables that we deal with, so it's much faster than
+ -- the generic serializer. This makes sense because
+ -- luatools and mtxtools are called frequently. Okay,
+ -- we pay a small price for properly tabbed tables.
+ local t = { }
+ local concat = table.concat
+ local sorted = table.sortedkeys
+ local function dump(k,v,m)
+ if type(v) == 'string' then
+ return m .. "['" .. k .. "']='" .. v .. "',"
+ elseif #v == 1 then
+ return m .. "['" .. k .. "']='" .. v[1] .. "',"
+ else
+ return m .. "['" .. k .. "']={'" .. concat(v,"','").. "'},"
+ end
+ end
+ t[#t+1] = "return {"
+ if instance.sortdata then
+ for _, k in pairs(sorted(files)) do
+ local fk = files[k]
+ if type(fk) == 'table' then
+ t[#t+1] = "\t['" .. k .. "']={"
+ for _, kk in pairs(sorted(fk)) do
+ t[#t+1] = dump(kk,fk[kk],"\t\t")
end
+ t[#t+1] = "\t},"
+ else
+ t[#t+1] = dump(k,fk,"\t")
end
- if instance.sortdata then
- for _, k in pairs(table.sortedkeys(files)) do
- dump(k,files[k])
+ end
+ else
+ for k, v in pairs(files) do
+ if type(v) == 'table' then
+ t[#t+1] = "\t['" .. k .. "']={"
+ for kk,vv in pairs(v) do
+ t[#t+1] = dump(kk,vv,"\t\t")
end
+ t[#t+1] = "\t},"
else
- for k, v in pairs(files) do
- dump(k,v)
+ t[#t+1] = dump(k,v,"\t")
+ end
+ end
+ end
+ t[#t+1] = "}"
+ return concat(t,"\n")
+end
+
+if not texmf then texmf = {} end -- no longer needed, at least not here
+
+function input.aux.save_data(instance, dataname, check, makename) -- untested without cache overload
+ for cachename, files in pairs(instance[dataname]) do
+ local name = (makename or file.join)(cachename,dataname)
+ local luaname, lucname = name .. input.luasuffix, name .. input.lucsuffix
+ input.report("preparing " .. dataname .. " for", luaname)
+ for k, v in pairs(files) do
+ if not check or check(v,k) then -- path, name
+ if type(v) == "table" and #v == 1 then
+ files[k] = v[1]
end
+ else
+ files[k] = nil -- false
end
- f:write('}\n')
+ end
+ local data = {
+ type = dataname,
+ root = cachename,
+ version = input.cacheversion,
+ date = os.date("%Y-%m-%d"),
+ time = os.date("%H:%M:%S"),
+ content = files,
+ }
+ local f = io.open(luaname,'w')
+ if f then
+ input.report("saving " .. dataname .. " in", luaname)
+ f:write(input.serialize(data))
f:close()
input.report("compiling " .. dataname .. " to", lucname)
if not utils.lua.compile(luaname,lucname) then
@@ -3510,49 +3608,106 @@ function input.aux.save_data(instance, dataname, check)
end
end
-function input.loadconfig(instance)
- instance.configuration, instance.order, instance.loaderror = { }, { }, false
- if not instance.renewcache then
- for _, cnf in ipairs(instance.cnffiles) do
- local dname = file.dirname(cnf)
- input.aux.load_data(instance,dname,'configuration')
- instance.order[#instance.order+1] = instance.configuration[dname]
- if instance.loaderror then break end
+function input.aux.load_data(instance,pathname,dataname,filename,makename) -- untested without cache overload
+ filename = ((not filename or (filename == "")) and dataname) or filename
+ filename = (makename and makename(dataname,filename)) or file.join(pathname,filename)
+ local blob = loadfile(filename .. input.lucsuffix) or loadfile(filename .. input.luasuffix)
+ if blob then
+ local data = blob()
+ if data and data.content and data.type == dataname and data.version == input.cacheversion then
+ input.report("loading",dataname,"for",pathname,"from",filename)
+ instance[dataname][pathname] = data.content
+ else
+ input.report("skipping",dataname,"for",pathname,"from",filename)
+ instance[dataname][pathname] = { }
+ instance.loaderror = true
end
+ else
+ input.report("skipping",dataname,"for",pathname,"from",filename)
end
- input.joinconfig(instance)
end
-if not texmf then texmf = {} end
-if not texmf.data then texmf.data = {} end
+-- some day i'll use the nested approach, but not yet (actually we even drop
+-- engine/progname support since we have only luatex now)
+--
+-- first texmfcnf.lua files are located, next the cached texmf.cnf files
+--
+-- return {
+-- TEXMFBOGUS = 'effe checken of dit werkt',
+-- }
-function input.aux.load_data(instance,pathname,dataname,filename)
- if not filename or (filename == "") then
- filename = dataname .. input.lucsuffix
- end
- local blob = loadfile(file.join(pathname,filename))
- if not blob then
- filename = dataname .. input.luasuffix
- blob = loadfile(file.join(pathname,filename))
- end
+function input.aux.load_texmfcnf(instance,dataname,pathname)
+ local filename = file.join(pathname,input.luaname)
+ local blob = loadfile(filename)
if blob then
- blob()
- if (texmf.data.type == dataname) and (texmf.data.version == input.cacheversion) and texmf.data.content then
- input.report("loading",dataname,"for",pathname,"from",filename)
- instance[dataname][pathname] = texmf.data.content
+ local data = blob()
+ if data then
+ input.report("loading","configuration file",filename)
+ if true then
+ -- flatten to variable.progname
+ local t = { }
+ for k, v in pairs(data) do -- v = progname
+ if type(v) == "string" then
+ t[k] = v
+ else
+ for kk, vv in pairs(v) do -- vv = variable
+ if type(vv) == "string" then
+ t[vv.."."..v] = kk
+ end
+ end
+ end
+ end
+ instance[dataname][pathname] = t
+ else
+ instance[dataname][pathname] = data
+ end
else
- input.report("skipping",dataname,"for",pathname,"from",filename)
+ input.report("skipping","configuration file",filename)
instance[dataname][pathname] = { }
instance.loaderror = true
end
+ else
+ input.report("skipping","configuration file",filename)
+ end
+end
+
+function input.aux.load_configuration(instance,dname,lname)
+ input.aux.load_data(instance,dname,'configuration',lname and file.basename(lname))
+end
+function input.aux.load_files(instance,tag)
+ input.aux.load_data(instance,tag,'files')
+end
+
+function input.resetconfig(instance)
+ instance.configuration, instance.setup, instance.order, instance.loaderror = { }, { }, { }, false
+end
+
+function input.loadnewconfig(instance)
+ for _, cnf in ipairs(instance.luafiles) do
+ local dname = file.dirname(cnf)
+ input.aux.load_texmfcnf(instance,'setup',dname)
+ instance.order[#instance.order+1] = instance.setup[dname]
+ if instance.loaderror then break end
+ end
+end
+
+function input.loadoldconfig(instance)
+ if not instance.renewcache then
+ for _, cnf in ipairs(instance.cnffiles) do
+ local dname = file.dirname(cnf)
+ input.aux.load_configuration(instance,dname)
+ instance.order[#instance.order+1] = instance.configuration[dname]
+ if instance.loaderror then break end
+ end
end
- texmf.data.content = { }
+ input.joinconfig(instance)
end
function input.expand_variables(instance)
instance.expansions = { }
- if instance.engine ~= "" then instance.environment['engine'] = instance.engine end
- if instance.progname ~= "" then instance.environment['progname'] = instance.engine end
+--~ instance.environment['SELFAUTOPARENT'] = instance.environment['SELFAUTOPARENT'] or instance.rootpath
+ if instance.engine ~= "" then instance.environment['engine'] = instance.engine end
+ if instance.progname ~= "" then instance.environment['progname'] = instance.progname end
for k,v in pairs(instance.environment) do
local a, b = k:match("^(%a+)%_(.*)%s*$")
if a and b then
@@ -3643,53 +3798,6 @@ function input.is_expansion(instance,name)
return input.aux.is_entry(instance,instance.expansions,name)
end
-function input.aux.list(instance,list)
- local pat = string.upper(instance.pattern or "","")
- for _,key in pairs(table.sortedkeys(list)) do
- if (instance.pattern=="") or string.find(key:upper(),pat) then
- if instance.kpseonly then
- if instance.kpsevars[key] then
- print(key .. "=" .. input.aux.tabstr(list[key]))
- end
- elseif instance.kpsevars[key] then
- print('K ' .. key .. "=" .. input.aux.tabstr(list[key]))
- else
- print('E ' .. key .. "=" .. input.aux.tabstr(list[key]))
- end
- end
- end
-end
-
-function input.list_variables(instance)
- input.aux.list(instance,instance.variables)
-end
-function input.list_expansions(instance)
- input.aux.list(instance,instance.expansions)
-end
-
-function input.list_configurations(instance)
- for _,key in pairs(table.sortedkeys(instance.kpsevars)) do
- if not instance.pattern or (instance.pattern=="") or key:find(instance.pattern) then
- print(key.."\n")
- for i,c in ipairs(instance.order) do
- local str = c[key]
- if str then
- print("\t" .. i .. "\t\t" .. input.aux.tabstr(str))
- end
- end
- print()
- end
- end
-end
-
-function input.aux.tabstr(str)
- if type(str) == 'table' then
- return table.concat(str," | ")
- else
- return str
- end
-end
-
function input.simplified_list(str)
if type(str) == 'table' then
return str -- troubles ; ipv , in texmf
@@ -3713,23 +3821,6 @@ function input.unexpanded_path(instance,str)
return file.join_path(input.unexpanded_path_list(instance,str))
end
---~ function input.expanded_path_list(instance,str)
---~ if not str then
---~ return { }
---~ elseif instance.savelists then
---~ -- engine+progname hash
---~ str = str:gsub("%$","")
---~ if not instance.lists[str] then -- cached
---~ local lst = input.split_path(input.expansion(instance,str))
---~ instance.lists[str] = input.aux.expanded_path(instance,lst)
---~ end
---~ return instance.lists[str]
---~ else
---~ local lst = input.split_path(input.expansion(instance,str))
---~ return input.aux.expanded_path(instance,lst)
---~ end
---~ end
-
do
local done = { }
@@ -4142,6 +4233,8 @@ do
return original
end
+ input.normalize_name = file.collapse_path
+
end
function input.aux.register_in_trees(instance,name)
@@ -4507,7 +4600,10 @@ end
function input.load(instance)
input.starttiming(instance)
+ input.resetconfig(instance)
input.identify_cnf(instance)
+ input.load_lua(instance)
+ input.expand_variables(instance)
input.load_cnf(instance)
input.expand_variables(instance)
input.load_hash(instance)
@@ -4894,28 +4990,45 @@ caches.more = caches.more or "context"
caches.direct = false -- true is faster but may need huge amounts of memory
caches.trace = false
caches.tree = false
-caches.temp = caches.temp or os.getenv("TEXMFCACHE") or os.getenv("HOME") or os.getenv("HOMEPATH") or os.getenv("VARTEXMF") or os.getenv("TEXMFVAR") or os.getenv("TMP") or os.getenv("TEMP") or os.getenv("TMPDIR") or nil
-caches.paths = caches.paths or { caches.temp }
+caches.paths = caches.paths or nil
caches.force = false
input.usecache = not toboolean(os.getenv("TEXMFSHARECACHE") or "false",true) -- true
-if caches.temp and caches.temp ~= "" and lfs.attributes(caches.temp,"mode") ~= "directory" then
- if caches.force or io.ask(string.format("Should I create the cache path %s?",caches.temp), "no", { "yes", "no" }) == "yes" then
- dir.mkdirs(caches.temp)
+function caches.temp(instance)
+ local function checkpath(cachepath)
+ if not cachepath or cachepath == "" then
+ return nil
+ elseif lfs.attributes(cachepath,"mode") == "directory" then -- lfs.isdir(cachepath) then
+ return cachepath
+ elseif caches.force or io.ask(string.format("Should I create the cache path %s?",cachepath), "no", { "yes", "no" }) == "yes" then
+ dir.mkdirs(cachepath)
+ return (lfs.attributes(cachepath,"mode") == "directory") and cachepath
+ else
+ return nil
+ end
end
-end
-if not caches.temp or caches.temp == "" then
- print("\nfatal error: there is no valid cache path defined\n")
- os.exit()
-elseif lfs.attributes(caches.temp,"mode") ~= "directory" then
- print(string.format("\nfatal error: cache path %s is not a directory\n",caches.temp))
- os.exit()
+ local cachepath = input.expanded_path_list(instance,"TEXMFCACHE")
+ cachepath = cachepath and #cachepath > 0 and checkpath(cachepath[1])
+ if not cachepath then
+ cachepath = os.getenv("TEXMFCACHE") or os.getenv("HOME") or os.getenv("HOMEPATH") or os.getenv("TMP") or os.getenv("TEMP") or os.getenv("TMPDIR") or nil
+ cachepath = checkpath(cachepath)
+ end
+ if not cachepath then
+ print("\nfatal error: there is no valid cache path defined\n")
+ os.exit()
+ elseif lfs.attributes(cachepath,"mode") ~= "directory" then
+ print(string.format("\nfatal error: cache path %s is not a directory\n",cachepath))
+ os.exit()
+ end
+ function caches.temp(instance)
+ return cachepath
+ end
+ return cachepath
end
function caches.configpath(instance)
return table.concat(instance.cnffiles,";")
---~ return input.expand_var(instance,"TEXMFCNF")
end
function caches.hashed(tree)
@@ -4933,19 +5046,8 @@ end
function caches.setpath(instance,...)
if not caches.path then
- if lfs and instance then
- for _,v in pairs(caches.paths) do
- for _,vv in pairs(input.expanded_path_list(instance,v)) do
- if lfs.isdir(vv) then
- caches.path = vv
- break
- end
- end
- if caches.path then break end
- end
- end
if not caches.path then
- caches.path = caches.temp
+ caches.path = caches.temp(instance)
end
caches.path = input.clean_path(caches.path) -- to be sure
if lfs then
@@ -4969,6 +5071,12 @@ function caches.setpath(instance,...)
return caches.path
end
+function caches.definepath(instance,category,subcategory)
+ return function()
+ return caches.setpath(instance,category,subcategory)
+ end
+end
+
function caches.setluanames(path,name)
return path .. "/" .. name .. ".tma", path .. "/" .. name .. ".tmc"
end
@@ -5034,19 +5142,35 @@ do -- local report
end
end
+ local allocated = { }
+
+ -- tracing
+
function containers.define(category, subcategory, version, enabled)
- if category and subcategory then
- return {
- category = category,
- subcategory = subcategory,
- storage = { },
- enabled = enabled,
- version = version or 1.000,
- trace = false,
- path = caches.setpath(texmf.instance,category,subcategory),
- }
- else
- return nil
+ return function()
+ if category and subcategory then
+ local c = allocated[category]
+ if not c then
+ c = { }
+ allocated[category] = c
+ end
+ local s = c[subcategory]
+ if not s then
+ s = {
+ category = category,
+ subcategory = subcategory,
+ storage = { },
+ enabled = enabled,
+ version = version or 1.000,
+ trace = false,
+ path = caches.setpath(texmf.instance,category,subcategory),
+ }
+ c[subcategory] = s
+ end
+ return s
+ else
+ return nil
+ end
end
end
@@ -5103,129 +5227,35 @@ end
-- since we want to use the cache instead of the tree, we will now
-- reimplement the saver.
+local save_data = input.aux.save_data
+
+input.cachepath = nil
+
function input.aux.save_data(instance, dataname, check)
- for cachename, files in pairs(instance[dataname]) do
- local name
+ input.cachepath = input.cachepath or caches.definepath(instance,"trees")
+ save_data(instance, dataname, check, function(cachename,dataname)
if input.usecache then
- name = file.join(caches.setpath(instance,"trees"),caches.hashed(cachename))
- else
- name = file.join(cachename,dataname)
- end
- local luaname, lucname = name .. input.luasuffix, name .. input.lucsuffix
- input.report("preparing " .. dataname .. " in", luaname)
- for k, v in pairs(files) do
- if not check or check(v,k) then -- path, name
- if type(v) == "table" and #v == 1 then
- files[k] = v[1]
- end
- else
- files[k] = nil -- false
- end
- end
- local data = {
- type = dataname,
- root = cachename,
- version = input.cacheversion,
- date = os.date("%Y-%m-%d"),
- time = os.date("%H:%M:%S"),
- content = files,
- }
- local f = io.open(luaname,'w')
- if f then
- input.report("saving " .. dataname .. " in", luaname)
- -- f:write(table.serialize(data,'return'))
- f:write(input.serialize(data))
- f:close()
- input.report("compiling " .. dataname .. " to", lucname)
- if not utils.lua.compile(luaname,lucname) then
- input.report("compiling failed for " .. dataname .. ", deleting file " .. lucname)
- os.remove(lucname)
- end
+ return file.join(input.cachepath(),caches.hashed(cachename))
else
- input.report("unable to save " .. dataname .. " in " .. name..input.luasuffix)
+ return file.join(cachename,dataname)
end
- end
+ end)
end
-function input.serialize(files)
- -- This version is somewhat optimized for the kind of
- -- tables that we deal with, so it's much faster than
- -- the generic serializer. This makes sense because
- -- luatools and mtxtools are called frequently. Okay,
- -- we pay a small price for properly tabbed tables.
- local t = { }
- local concat = table.concat
- local sorted = table.sortedkeys
- local function dump(k,v,m)
- if type(v) == 'string' then
- return m .. "['" .. k .. "']='" .. v .. "',"
- elseif #v == 1 then
- return m .. "['" .. k .. "']='" .. v[1] .. "',"
- else
- return m .. "['" .. k .. "']={'" .. concat(v,"','").. "'},"
- end
- end
- t[#t+1] = "return {"
- if instance.sortdata then
- for _, k in pairs(sorted(files)) do
- local fk = files[k]
- if type(fk) == 'table' then
- t[#t+1] = "\t['" .. k .. "']={"
- for _, kk in pairs(sorted(fk)) do
- t[#t+1] = dump(kk,fk[kk],"\t\t")
- end
- t[#t+1] = "\t},"
- else
- t[#t+1] = dump(k,fk,"\t")
- end
- end
- else
- for k, v in pairs(files) do
- if type(v) == 'table' then
- t[#t+1] = "\t['" .. k .. "']={"
- for kk,vv in pairs(v) do
- t[#t+1] = dump(kk,vv,"\t\t")
- end
- t[#t+1] = "\t},"
- else
- t[#t+1] = dump(k,v,"\t")
- end
- end
- end
- t[#t+1] = "}"
- return concat(t,"\n")
-end
+local load_data = input.aux.load_data
function input.aux.load_data(instance,pathname,dataname,filename)
- local luaname, lucname, pname, fname
- if input.usecache then
- pname, fname = caches.setpath(instance,"trees"), caches.hashed(pathname)
- filename = file.join(pname,fname)
- else
- if not filename or (filename == "") then
- filename = dataname
- end
- pname, fname = pathname, filename
- end
- luaname = file.join(pname,fname) .. input.luasuffix
- lucname = file.join(pname,fname) .. input.lucsuffix
- local blob = loadfile(lucname)
- if not blob then
- blob = loadfile(luaname)
- end
- if blob then
- local data = blob()
- if data and data.content and data.type == dataname and data.version == input.cacheversion then
- input.report("loading",dataname,"for",pathname,"from",filename)
- instance[dataname][pathname] = data.content
+ input.cachepath = input.cachepath or caches.definepath(instance,"trees")
+ load_data(instance,pathname,dataname,filename,function(dataname,filename)
+ if input.usecache then
+ return file.join(input.cachepath(),caches.hashed(pathname))
else
- input.report("skipping",dataname,"for",pathname,"from",filename)
- instance[dataname][pathname] = { }
- instance.loaderror = true
+ if not filename or (filename == "") then
+ filename = dataname
+ end
+ return file.join(pathname,filename)
end
- else
- input.report("skipping",dataname,"for",pathname,"from",filename)
- end
+ end)
end
-- we will make a better format, maybe something xml or just text or lua
@@ -5853,7 +5883,6 @@ if texconfig and not texlua then
if not texmf.instance then -- prevent a second loading
-
texmf.instance = input.reset()
texmf.instance.progname = environment.progname or 'context'
texmf.instance.engine = environment.engine or 'luatex'
@@ -6297,7 +6326,10 @@ if environment.arguments["minimize"] then
end
function input.my_prepare_a(instance)
+ input.resetconfig(instance)
input.identify_cnf(instance)
+ input.load_lua(instance)
+ input.expand_variables(instance)
input.load_cnf(instance)
input.expand_variables(instance)
end
@@ -6472,6 +6504,51 @@ function input.my_run_format(instance,name,data,more)
end
end
+-- helpers for verbose lists
+
+input.listers = input.listers or { }
+
+local function tabstr(str)
+ if type(str) == 'table' then
+ return table.concat(str," | ")
+ else
+ return str
+ end
+end
+
+local function list(instance,list)
+ local pat = string.upper(instance.pattern or "","")
+ for _,key in pairs(table.sortedkeys(list)) do
+ if instance.pattern == "" or string.find(key:upper(),pat) then
+ if instance.kpseonly then
+ if instance.kpsevars[key] then
+ print(format("%s=%s",key,tabstr(list[key])))
+ end
+ else
+ print(format('%s %s=%s',(instance.kpsevars[key] and 'K') or 'E',key,tabstr(list[key])))
+ end
+ end
+ end
+end
+
+function input.listers.variables (instance) list(instance,instance.variables ) end
+function input.listers.expansions(instance) list(instance,instance.expansions) end
+
+function input.listers.configurations(instance)
+ for _,key in pairs(table.sortedkeys(instance.kpsevars)) do
+ if not instance.pattern or (instance.pattern=="") or key:find(instance.pattern) then
+ print(key.."\n")
+ for i,c in ipairs(instance.order) do
+ local str = c[key]
+ if str then
+ print(format("\t%s\t\t%s",i,input.aux.tabstr(str)))
+ end
+ end
+ print()
+ end
+ end
+end
+
input.report(banner,"\n")
local ok = true
@@ -6545,13 +6622,13 @@ elseif environment.arguments["selfupdate"] then
input.update_script(instance,own.name,"luatools")
elseif environment.arguments["variables"] or environment.arguments["show-variables"] then
input.my_prepare_a(instance)
- input.list_variables(instance)
+ input.listers.variables(instance)
elseif environment.arguments["expansions"] or environment.arguments["show-expansions"] then
input.my_prepare_a(instance)
- input.list_expansions(instance)
+ input.listers.expansions(instance)
elseif environment.arguments["configurations"] or environment.arguments["show-configurations"] then
input.my_prepare_a(instance)
- input.list_configurations(instance)
+ input.listers.configurations(instance)
elseif environment.arguments["help"] or (environment.files[1]=='help') or (#environment.files==0) then
if not input.verbose then
input.verbose = true
diff --git a/scripts/context/lua/mtx-context.lua b/scripts/context/lua/mtx-context.lua
index ae0ee1b8e..6c444d531 100644
--- a/scripts/context/lua/mtx-context.lua
+++ b/scripts/context/lua/mtx-context.lua
@@ -583,7 +583,8 @@ function scripts.context.run(ctxdata)
--
end
else
- input.error("no format found with name " .. formatname)
+ input.verbose = true
+ input.report("error", "no format found with name " .. formatname)
end
end
end
diff --git a/scripts/context/lua/mtx-server.lua b/scripts/context/lua/mtx-server.lua
new file mode 100644
index 000000000..293bc0c1c
--- /dev/null
+++ b/scripts/context/lua/mtx-server.lua
@@ -0,0 +1,83 @@
+if not modules then modules = { } end modules ['mtx-server'] = {
+ version = 1.001,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+texmf.instance = instance -- we need to get rid of this / maybe current instance in global table
+
+-- The starting point was stripped down webserver.lua by Samuel
+-- Saint-Pettersen (as downloaded on 21-5-2008) which only served
+-- html and was not configureable. In due time I will extend the
+-- next code. Eventually we may move code to l-server.
+
+scripts = scripts or { }
+scripts.webserver = scripts.webserver or {}
+
+local socket = require("socket")
+
+local function message(str)
+ return string.format("<h1>%s</h1>",str)
+end
+
+function scripts.webserver.run(configuration)
+ local server = assert(socket.bind("*", tonumber(configuration.port or 8080)))
+ while true do
+ local client = server:accept()
+ client:settimeout(configuration.timeout or 60)
+ local request, e = client:receive()
+ if e then
+ client:send(message("404 Not Found"))
+ else
+ -- GET /showcase.pdf HTTP/1.1
+ local filename = request:match("GET (.+) HTTP/.*$") -- todo: more clever
+ -- filename = filename:gsub("%%(%d%d)",function(c) return string.char(tonumber(c,16)) end)
+ filename = socket.url.unescape(filename)
+ if filename == nil or filename == "" then
+ filename = configuration.index or "index.html"
+ end
+ -- todo chunked
+ local fullname = file.join(configuration.root,filename)
+ local data = io.loaddata(fullname)
+ if data and data ~= "" then
+ local result
+ client:send("HTTP/1.1 200 OK\r\n")
+ client:send("Connection: close\r\n")
+ if filename:find(".pdf$") then -- todo: special handler
+ client:send(string.format("Content-Length: %s\r\n",#data))
+ client:send("Content-Type: application/pdf\r\n")
+ else
+ client:send("Content-Type: text/html\r\n")
+ end
+ client:send("\r\n")
+ client:send(data)
+ client:send("\r\n")
+ else
+ client:send(message("404 Not Found"))
+ end
+ end
+ client:close()
+ end
+end
+
+
+banner = banner .. " | webserver "
+
+messages.help = [[
+--start start server
+--port port to listen to
+--root server root
+--index index file
+]]
+
+if environment.argument("start") then
+ scripts.webserver.run {
+ port = environment.argument("port") or "8080",
+ root = environment.argument("root") or ".", -- "e:/websites/www.pragma-ade.com",
+ index = environment.argument("index") or "index.html",
+ }
+else
+ input.help(banner,messages.help)
+end
diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua
index 63605b42f..040214178 100644
--- a/scripts/context/lua/mtxrun.lua
+++ b/scripts/context/lua/mtxrun.lua
@@ -388,7 +388,6 @@ local patterns_escapes = {
["]"] = "%]",
}
-
function string:pattesc()
return (self:gsub(".",patterns_escapes))
end
@@ -1701,14 +1700,22 @@ end
--~ print("../test/" .. " == " .. file.collapse_path("../test/"))
--~ print("a/a" .. " == " .. file.collapse_path("a/b/c/../../a"))
+--~ function file.collapse_path(str)
+--~ local ok, n = false, 0
+--~ while not ok do
+--~ ok = true
+--~ str, n = str:gsub("[^%./]+/%.%./", function(s)
+--~ ok = false
+--~ return ""
+--~ end)
+--~ end
+--~ return (str:gsub("/%./","/"))
+--~ end
+
function file.collapse_path(str)
- local ok, n = false, 0
- while not ok do
- ok = true
- str, n = str:gsub("[^%./]+/%.%./", function(s)
- ok = false
- return ""
- end)
+ local n = 1
+ while n > 0 do
+ str, n = str:gsub("([^/%.]+/%.%./)","")
end
return (str:gsub("/%./","/"))
end
@@ -2307,7 +2314,7 @@ do
local remove, nsremap, resolvens = table.remove, xml.xmlns, xml.resolvens
- local stack, top, dt, at, xmlns, errorstr = {}, {}, {}, {}, {}, nil
+ local stack, top, dt, at, xmlns, errorstr, entities = {}, {}, {}, {}, {}, nil, {}
local mt = { __tostring = xml.text }
@@ -2383,14 +2390,6 @@ do
dt[#dt+1] = text
end
end
- --~ local function add_special(what, spacing, text)
- --~ if #spacing > 0 then
- --~ dt[#dt+1] = spacing
- --~ end
- --~ top = stack[#stack] -- hm, left over 1
- --~ setmetatable(top, mt) -- hm, left over 2
- --~ dt[#dt+1] = { special=true, ns="", tg=what, dt={text} }
- --~ end
local function add_special(what, spacing, text)
if #spacing > 0 then
dt[#dt+1] = spacing
@@ -2450,12 +2449,20 @@ do
local somecomment = C((1 - endcomment )^0)
local somecdata = C((1 - endcdata )^0)
+ function entity(k,v) entities[k] = v end
+
local begindoctype = open * P("!DOCTYPE")
local enddoctype = close
- local publicdoctype = P("PUBLIC") * somespace * value * somespace * value * somespace * balanced^0
- local systemdoctype = P("SYSTEM") * somespace * value * somespace * balanced^0
- local simpledoctype = (1-close)^1 * balanced^0
- local somedoctype = C((somespace * P(publicdoctype + systemdoctype + simpledoctype) * optionalspace)^0)
+ local beginset = P("[")
+ local endset = P("]")
+ local doctypename = C((1-somespace)^0)
+ local elementdoctype = optionalspace * P("<!ELEMENT") * (1-close)^0 * close
+ local entitydoctype = optionalspace * P("<!ENTITY") * somespace * (doctypename * somespace * value)/entity * optionalspace * close
+ local publicdoctype = doctypename * somespace * P("PUBLIC") * somespace * value * somespace * value * somespace
+ local systemdoctype = doctypename * somespace * P("SYSTEM") * somespace * value * somespace
+ local definitiondoctype= doctypename * somespace * beginset * P(elementdoctype + entitydoctype)^0 * optionalspace * endset
+ local simpledoctype = (1-close)^1 -- * balanced^0
+ local somedoctype = C((somespace * (publicdoctype + systemdoctype + definitiondoctype + simpledoctype) * optionalspace)^0)
local instruction = (spacing * begininstruction * someinstruction * endinstruction) / function(...) add_special("@pi@",...) end
local comment = (spacing * begincomment * somecomment * endcomment ) / function(...) add_special("@cm@",...) end
@@ -2481,9 +2488,11 @@ do
children = text + V("parent") + emptyelement + comment + cdata + instruction,
}
- function xml.convert(data, no_root, strip_cm_and_dt)
+ -- todo: xml.new + properties like entities and strip and such (store in root)
+
+ function xml.convert(data, no_root, strip_cm_and_dt, given_entities) -- maybe use table met k/v (given_entities may disapear)
strip = strip_cm_and_dt or xml.strip_cm_and_dt
- stack, top, at, xmlns, errorstr, result = {}, {}, {}, {}, nil, nil
+ stack, top, at, xmlns, errorstr, result, entities = {}, {}, {}, {}, nil, nil, given_entities or {}
stack[#stack+1] = top
top.dt = { }
dt = top.dt
@@ -2502,7 +2511,7 @@ do
result = stack[1]
end
if not no_root then
- result = { special = true, ns = "", tg = '@rt@', dt = result.dt, at={} }
+ result = { special = true, ns = "", tg = '@rt@', dt = result.dt, at={}, entities = entities }
setmetatable(result, mt)
local rdt = result.dt
for k=1,#rdt do
@@ -2629,6 +2638,22 @@ do
elseif not nocommands then
local ec = e.command
if ec ~= nil then -- we can have all kind of types
+
+if e.special then -- todo test for true/false
+ local etg, edt = e.tg, e.dt
+ local spc = specialconverter and specialconverter[etg]
+ if spc then
+--~ print("SPECIAL",etg,table.serialize(specialconverter), spc)
+ local result = spc(edt[1])
+ if result then
+ handle(result)
+ return
+ else
+ -- no need to handle any further
+ end
+ end
+end
+
local xc = xml.command
if xc then
xc(e,ec)
@@ -2678,12 +2703,18 @@ do
end
end
end
- if ern and xml.trace_remap then
- if ats then
- ats[#ats+1] = format("xmlns:remapped='%s'",ern)
- else
- ats = { format("xmlns:remapped='%s'",ern) }
- end
+ if ern and xml.trace_remap and ern ~= ens then
+--~ if ats then
+--~ ats[#ats+1] = format("xmlns:remapped='%s'",ern)
+--~ else
+--~ ats = { format("xmlns:remapped='%s'",ern) }
+--~ end
+--~ if ats then
+--~ ats[#ats+1] = format("remappedns='%s'",ens or '-')
+--~ else
+--~ ats = { format("remappedns='%s'",ens or '-') }
+--~ end
+ens = ern
end
if ens ~= "" then
if edt and #edt > 0 then
@@ -3261,10 +3292,10 @@ do
end
end
functions.name = function(root,k,n)
--- way too fuzzy
+ -- way too fuzzy
local found
if not k or not n then
- local ns, tg = root.ns, root.tg
+ local ns, tg = root.rn or root.ns or "", root.tg
if not tg then
for i=1,#root do
local e = root[i]
@@ -3273,10 +3304,10 @@ do
break
end
end
- elseif ns == "" then
- return tg
- else
+ elseif ns ~= "" then
return ns .. ":" .. tg
+ else
+ return tg
end
elseif n == 0 then
local e = root[k]
@@ -3296,6 +3327,7 @@ do
end
end
else
+--~ print(k,n,#root)
for i=k+1,#root,1 do
local e = root[i]
if type(e) == "table" then
@@ -3309,7 +3341,7 @@ do
end
end
if found then
- local ns, tg = found.ns, found.tg
+ local ns, tg = found.rn or found.ns or "", found.tg
if ns ~= "" then
return ns .. ":" .. tg
else
@@ -3709,7 +3741,7 @@ do
end
function xml.filters.tag(root,pattern,n)
local tag = ""
- xml.traverse(root, xml.lpath(pattern), function(r,d,k)
+ traverse(root, lpath(pattern), function(r,d,k)
tag = xml.functions.tag(d,k,n and tonumber(n))
return true
end)
@@ -3717,7 +3749,7 @@ do
end
function xml.filters.name(root,pattern,n)
local tag = ""
- xml.traverse(root, xml.lpath(pattern), function(r,d,k)
+ traverse(root, lpath(pattern), function(r,d,k)
tag = xml.functions.name(d,k,n and tonumber(n))
return true
end)
@@ -3748,8 +3780,13 @@ do
local attribute_filter = xml.filters.attributes
local default_filter = xml.filters.default
+ -- todo: also hash, could be gc'd
+
function xml.filter(root,pattern)
local kind, a, b, c = parser:match(pattern)
+--~ if xml.trace_lpath then
+--~ print(pattern,kind,a,b,c)
+--~ end
if kind == 1 or kind == 3 then
return (filters[b] or default_filter)(root,a,c)
elseif kind == 2 then
@@ -4292,7 +4329,7 @@ do if unicode and unicode.utf8 then
xml.entities = xml.entities or { } -- xml.entities.handler == function
function xml.entities.handler(e)
- return format("[s]",e)
+ return format("[%s]",e)
end
local char = unicode.utf8.char
@@ -4301,6 +4338,8 @@ do if unicode and unicode.utf8 then
return char(tonumber(s,16))
end
+ local entities = xml.entities -- global entities
+
function utfize(root)
local d = root.dt
for k=1,#d do
@@ -4318,8 +4357,6 @@ do if unicode and unicode.utf8 then
xml.utfize = utfize
- local entities = xml.entities
-
local function resolve(e) -- hex encoded always first, just to avoid mkii fallbacks
if e:find("#x") then
return char(tonumber(e:sub(3),16))
@@ -4334,20 +4371,24 @@ do if unicode and unicode.utf8 then
end
end
- function xml.resolve_entities(root)
- local d = root.dt
- for k=1,#d do
- local dk = d[k]
- if type(dk) == "string" then
- if dk:find("&.-;") then
- d[k] = dk:gsub("&(.-);",resolve)
+ local function resolve_entities(root)
+ if not root.special or root.tg == "@rt@" then
+ local d = root.dt
+ for k=1,#d do
+ local dk = d[k]
+ if type(dk) == "string" then
+ if dk:find("&.-;") then
+ d[k] = dk:gsub("&(.-);",resolve)
+ end
+ else
+ resolve_entities(dk)
end
- else
- utfize(dk)
end
end
end
+ xml.resolve_entities = resolve_entities
+
function xml.utfize_text(str)
if str:find("&#") then
return (str:gsub("&#x(.-);",toutf))
@@ -4372,6 +4413,18 @@ do if unicode and unicode.utf8 then
end
end
+ -- experimental, this will be done differently
+
+ function xml.merge_entities(root)
+ local documententities = root.entities
+ local allentities = xml.entities
+ if documententities then
+ for k, v in pairs(documententities) do
+ allentities[k] = v
+ end
+ end
+ end
+
end end
-- xml.set_text_cleanup(xml.show_text_entities)
@@ -4590,14 +4643,32 @@ os.platform = os.platform or os.type or (io.pathseparator == ";" and "windows")
--
-- for k,v in pairs(arg) do print(k,v) end
-if arg and (arg[0] == 'luatex' or arg[0] == 'luatex.exe') and arg[1] == "--luaonly" then
- arg[-1]=arg[0] arg[0]=arg[2] for k=3,#arg do arg[k-2]=arg[k] end arg[#arg]=nil arg[#arg]=nil
-end
-
-- environment
if not environment then environment = { } end
+environment.ownbin = environment.ownbin or arg[-2] or arg[-1] or arg[0] or "luatex"
+
+local ownpath = nil -- we could use a metatable here
+
+function environment.ownpath()
+ if not ownpath then
+ for p in string.gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
+ local b = file.join(p,environment.ownbin)
+ if lfs.isfile(b..".exe") or lfs.isfile(b) then
+ ownpath = p
+ break
+ end
+ end
+ if not ownpath then ownpath = '.' end
+ end
+ return ownpath
+end
+
+if arg and (arg[0] == 'luatex' or arg[0] == 'luatex.exe') and arg[1] == "--luaonly" then
+ arg[-1]=arg[0] arg[0]=arg[2] for k=3,#arg do arg[k-2]=arg[k] end arg[#arg]=nil arg[#arg]=nil
+end
+
environment.arguments = { }
environment.files = { }
environment.sorted_argument_keys = nil
@@ -4709,6 +4780,10 @@ end
-- additional functionality becomes available. We will split this
-- module in components when we're done with prototyping.
+-- TODO: os.getenv -> os.env[]
+-- TODO: instances.[hashes,cnffiles,configurations,522] -> ipairs (alles check, sneller)
+-- TODO: check escaping in find etc, too much, too slow
+
-- This is the first code I wrote for LuaTeX, so it needs some cleanup.
-- To be considered: hash key lowercase, first entry in table filename
@@ -4719,9 +4794,6 @@ end
-- Beware, loading and saving is overloaded in luat-tmp!
--- todo: instances.[hashes,cnffiles,configurations,522] -> ipairs (alles check, sneller)
--- todo: check escaping in find etc, too much, too slow
-
if not versions then versions = { } end versions['luat-inp'] = 1.001
if not environment then environment = { } end
if not file then file = { } end
@@ -4740,6 +4812,8 @@ if not input.hashers then input.hashers = { } end -- load databases
if not input.generators then input.generators = { } end -- generate databases
if not input.filters then input.filters = { } end -- conversion filters
+local format = string.format
+
input.locators.notfound = { nil }
input.hashers.notfound = { nil }
input.generators.notfound = { nil }
@@ -4749,6 +4823,7 @@ input.banner = nil
input.verbose = false
input.debug = false
input.cnfname = 'texmf.cnf'
+input.luaname = 'texmfcnf.lua'
input.lsrname = 'ls-R'
input.luasuffix = '.tma'
input.lucsuffix = '.tmc'
@@ -4838,12 +4913,14 @@ function input.reset()
instance.files = { }
instance.remap = { }
instance.configuration = { }
+ instance.setup = { }
instance.order = { }
instance.found = { }
instance.foundintrees = { }
instance.kpsevars = { }
instance.hashes = { }
instance.cnffiles = { }
+ instance.luafiles = { }
instance.lists = { }
instance.remember = true
instance.diskcache = true
@@ -4863,7 +4940,6 @@ function input.reset()
instance.stoptime = 0
instance.validfile = function(path,name) return true end
instance.data = { } -- only for loading
- instance.sortdata = false
instance.force_suffixes = true
instance.dummy_path_expr = "^!*unset/*$"
instance.fakepaths = { }
@@ -4876,7 +4952,7 @@ function input.reset()
end
else
-- we will access os.env frequently
- for k,v in pairs({'HOME','TEXMF','TEXMFCNF','SELFAUTOPARENT'}) do
+ for k,v in pairs({'HOME','TEXMF','TEXMFCNF'}) do
local e = os.getenv(v)
if e then
-- input.report("setting",v,"to",input.bare_variable(e))
@@ -4904,7 +4980,7 @@ function input.reset_hashes(instance)
instance.found = { }
end
-function input.bare_variable(str)
+function input.bare_variable(str) -- assumes str is a string
-- return string.gsub(string.gsub(string.gsub(str,"%s+$",""),'^"(.+)"$',"%1"),"^'(.+)'$","%1")
return (str:gsub("\s*([\"\']?)(.+)%1\s*", "%2"))
end
@@ -4989,7 +5065,7 @@ do
instance.stoptime = stoptime
instance.loadtime = instance.loadtime + loadtime
if report then
- input.report('load time', string.format("%0.3f",loadtime))
+ input.report('load time', format("%0.3f",loadtime))
end
return loadtime
end
@@ -5000,7 +5076,7 @@ do
end
function input.elapsedtime(instance)
- return string.format("%0.3f",(instance and instance.loadtime) or 0)
+ return format("%0.3f",(instance and instance.loadtime) or 0)
end
function input.report_loadtime(instance)
@@ -5016,15 +5092,19 @@ function input.env(instance,key)
end
function input.osenv(instance,key)
- if instance.environment[key] == nil then
- local e = os.getenv(key)
+ local ie = instance.environment
+ local value = ie[key]
+ if value == nil then
+ -- local e = os.getenv(key)
+ local e = os.env[key]
if e == nil then
- instance.environment[key] = "" -- false
+ -- value = "" -- false
else
- instance.environment[key] = input.bare_variable(e)
+ value = input.bare_variable(e)
end
+ ie[key] = value
end
- return instance.environment[key] or ""
+ return value or ""
end
-- we follow a rather traditional approach:
@@ -5035,66 +5115,103 @@ end
-- for the moment we don't expect a configuration file in a zip
function input.identify_cnf(instance)
+ -- we no longer support treepath and rootpath (was handy for testing);
+ -- also we now follow the stupid route: if not set then just assume *one*
+ -- cnf file under texmf (i.e. distribution)
if #instance.cnffiles == 0 then
- if instance.treepath ~= "" then
- -- this is a special purpose branch, not really used
- if instance.rootpath ~= "" then
- local t = instance.treepath:splitchr(',')
- for k,v in ipairs(t) do
- t[k] = file.join(instance.rootpath,v)
+ if input.env(instance,'TEXMFCNF') == "" then
+ local ownpath = environment.ownpath() or "."
+ if ownpath then
+ -- beware, this is tricky on my own system because at that location I do have
+ -- the raw tree that ends up in the zip; i.e. I cannot test this kind of mess
+ local function locate(filename,list)
+ local ownroot = input.normalize_name(file.join(ownpath,"../.."))
+ if not lfs.isdir(file.join(ownroot,"texmf")) then
+ ownroot = input.normalize_name(file.join(ownpath,".."))
+ if not lfs.isdir(file.join(ownroot,"texmf")) then
+ input.verbose = true
+ input.report("error", "unable to identify cnf file")
+ return
+ end
+ end
+ local texmfcnf = file.join(ownroot,"texmf-local/web2c",filename) -- for minimals and myself
+ if not lfs.isfile(texmfcnf) then
+ texmfcnf = file.join(ownroot,"texmf/web2c",filename)
+ if not lfs.isfile(texmfcnf) then
+ input.verbose = true
+ input.report("error", "unable to locate",filename)
+ return
+ end
+ end
+ table.insert(list,texmfcnf)
+ local ie = instance.environment
+ if not ie['SELFAUTOPARENT'] then ie['SELFAUTOPARENT'] = ownroot end
+ if not ie['TEXMFCNF'] then ie['TEXMFCNF'] = file.dirname(texmfcnf) end
end
- instance.treepath = table.concat(t,',')
+ locate(input.luaname,instance.luafiles)
+ locate(input.cnfname,instance.cnffiles)
+ if #instance.luafiles == 0 and instance.cnffiles == 0 then
+ input.verbose = true
+ input.report("error", "unable to locate",filename)
+ os.exit()
+ end
+ -- here we also assume then TEXMF is set in the distribution, if this trickery is
+ -- used in the minimals, then users who don't use setuptex are on their own with
+ -- regards to extra trees
+ else
+ input.verbose = true
+ input.report("error", "unable to identify own path")
+ os.exit()
end
- local t = instance.treepath:splitchr(',')
- instance.environment['TEXMF'] = input.bare_variable(instance.treepath)
- instance.environment['TEXMFCNF'] = file.join(t[1] or '.','texmf/web2c')
- end
- if instance.rootpath ~= "" then
- -- this assumes a single path, maybe do an expanded split here too
- instance.environment['TEXMFCNF'] = file.join(instance.rootpath,'texmf/web2c')
- instance.environment['SELFAUTOPARENT'] = instance.rootpath
- end
- if input.env(instance,'TEXMFCNF') ~= "" then
+ else
local t = input.split_path(input.env(instance,'TEXMFCNF'))
t = input.aux.expanded_path(instance,t)
input.aux.expand_vars(instance,t)
- for _,v in ipairs(t) do
- table.insert(instance.cnffiles,file.join(v,input.cnfname))
- end
- elseif input.env(instance,'SELFAUTOPARENT') == '.' then
- table.insert(instance.cnffiles,file.join('.',input.cnfname))
- else
- for _,v in ipairs({'texmf-local','texmf'}) do
- table.insert(instance.cnffiles,file.join(input.env(instance,'SELFAUTOPARENT'),v,'web2c',input.cnfname))
+ local function locate(filename,list)
+ for _,v in ipairs(t) do
+ local texmfcnf = input.normalize_name(file.join(v,filename))
+ if lfs.isfile(texmfcnf) then
+ table.insert(list,texmfcnf)
+ end
+ end
end
+ locate(input.luaname,instance.luafiles)
+ locate(input.cnfname,instance.cnffiles)
end
end
end
function input.load_cnf(instance)
+ local function loadoldconfigdata()
+ for _, fname in ipairs(instance.cnffiles) do
+ input.aux.load_cnf(instance,fname)
+ end
+ end
-- instance.cnffiles contain complete names now !
if #instance.cnffiles == 0 then
input.report("no cnf files found (TEXMFCNF may not be set/known)")
else
instance.rootpath = instance.cnffiles[1]
for k,fname in ipairs(instance.cnffiles) do
- instance.cnffiles[k] = fname:gsub("\\",'/') -- needed?
+ instance.cnffiles[k] = input.normalize_name(fname:gsub("\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
+ instance.rootpath = input.normalize_name(instance.rootpath)
+ instance.environment['SELFAUTOPARENT'] = instance.rootpath -- just to be sure
if instance.lsrmode then
- input.loadconfigdata(instance,instance.cnffiles)
+ loadoldconfigdata()
elseif instance.diskcache and not instance.renewcache then
- input.loadconfig(instance,instance.cnffiles)
+ input.loadoldconfig(instance,instance.cnffiles)
if instance.loaderror then
- input.loadconfigdata(instance,instance.cnffiles)
- input.saveconfig(instance)
+ loadoldconfigdata()
+ input.saveoldconfig(instance)
end
else
- input.loadconfigdata(instance,instance.cnffiles)
+ loadoldconfigdata()
if instance.renewcache then
- input.saveconfig(instance)
+ input.saveoldconfig(instance)
end
end
input.aux.collapse_cnf_data(instance)
@@ -5102,40 +5219,34 @@ function input.load_cnf(instance)
input.checkconfigdata(instance)
end
-function input.loadconfigdata(instance)
- for _, fname in ipairs(instance.cnffiles) do
- input.aux.load_cnf(instance,fname)
+function input.load_lua(instance)
+ if #instance.luafiles == 0 then
+ -- yet harmless
+ else
+ instance.rootpath = instance.luafiles[1]
+ for k,fname in ipairs(instance.luafiles) do
+ instance.luafiles[k] = input.normalize_name(fname:gsub("\\",'/'))
+ end
+ for i=1,3 do
+ instance.rootpath = file.dirname(instance.rootpath)
+ end
+ instance.rootpath = input.normalize_name(instance.rootpath)
+ instance.environment['SELFAUTOPARENT'] = instance.rootpath -- just to be sure
+ input.loadnewconfig(instance)
+ input.aux.collapse_cnf_data(instance)
end
+ input.checkconfigdata(instance)
end
-if os.env then
- function input.aux.collapse_cnf_data(instance)
- for _,c in ipairs(instance.order) do
- for k,v in pairs(c) do
- if not instance.variables[k] then
- if instance.environment[k] then
- instance.variables[k] = instance.environment[k]
- else
- instance.kpsevars[k] = true
- instance.variables[k] = input.bare_variable(v)
- end
- end
- end
- end
- end
-else
- function input.aux.collapse_cnf_data(instance)
- for _,c in ipairs(instance.order) do
- for k,v in pairs(c) do
- if not instance.variables[k] then
- local e = os.getenv(k)
- if e then
- instance.environment[k] = input.bare_variable(e)
- instance.variables[k] = instance.environment[k]
- else
- instance.variables[k] = input.bare_variable(v)
- instance.kpsevars[k] = true
- end
+function input.aux.collapse_cnf_data(instance) -- potential optmization: pass start index (setup and configuration are shared)
+ for _,c in ipairs(instance.order) do
+ for k,v in pairs(c) do
+ if not instance.variables[k] then
+ if instance.environment[k] then
+ instance.variables[k] = instance.environment[k]
+ else
+ instance.kpsevars[k] = true
+ instance.variables[k] = input.bare_variable(v)
end
end
end
@@ -5146,11 +5257,11 @@ function input.aux.load_cnf(instance,fname)
fname = input.clean_path(fname)
local lname = fname:gsub("%.%a+$",input.luasuffix)
local f = io.open(lname)
- if f then
+ if f then -- this will go
f:close()
local dname = file.dirname(fname)
if not instance.configuration[dname] then
- input.aux.load_data(instance,dname,'configuration',file.basename(lname))
+ input.aux.load_configuration(instance,dname,lname)
instance.order[#instance.order+1] = instance.configuration[dname]
end
else
@@ -5165,7 +5276,7 @@ function input.aux.load_cnf(instance,fname)
end
local data = instance.configuration[dname]
while true do
- line = f:read()
+ local line, n = f:read(), 0
if line then
while true do -- join lines
line, n = line:gsub("\\%s*$", "")
@@ -5176,7 +5287,7 @@ function input.aux.load_cnf(instance,fname)
end
end
if not line:find("^[%%#]") then
- k, v = (line:gsub("%s*%%.*$","")):match("%s*(.-)%s*=%s*(.-)%s*$")
+ local k, v = (line:gsub("%s*%%.*$","")):match("%s*(.-)%s*=%s*(.-)%s*$")
if k and v and not data[k] then
data[k] = (v:gsub("[%%#].*",'')):gsub("~", "$HOME")
instance.kpsevars[k] = true
@@ -5250,6 +5361,7 @@ end
function input.locatelists(instance)
for _, path in pairs(input.simplified_list(input.expansion(instance,'TEXMF'))) do
+ path = file.collapse_path(path)
input.report("locating list of",path)
input.locatedatabase(instance,input.normalize_name(path))
end
@@ -5286,7 +5398,7 @@ function input.loadfiles(instance)
end
function input.hashers.tex(instance,tag,name)
- input.aux.load_data(instance,tag,'files')
+ input.aux.load_files(instance,tag)
end
-- generators:
@@ -5363,7 +5475,7 @@ do
end
end
action()
- input.report(string.format("%s files found on %s directories with %s uppercase remappings",n,m,r))
+ input.report(format("%s files found on %s directories with %s uppercase remappings",n,m,r))
else
local fullname = file.join(specification,input.lsrname)
local path = '.'
@@ -5416,7 +5528,7 @@ end
-- is more convenient.
function input.splitconfig(instance)
- for i,c in ipairs(instance.order) do
+ for i,c in ipairs(instance) do
for k,v in pairs(c) do
if type(v) == 'string' then
local t = file.split_path(v)
@@ -5450,14 +5562,7 @@ function input.join_path(str)
return str
end
end
---~ function input.splitexpansions(instance)
---~ for k,v in pairs(instance.expansions) do
---~ local t = file.split_path(v)
---~ if #t > 1 then
---~ instance.expansions[k] = t
---~ end
---~ end
---~ end
+
function input.splitexpansions(instance)
for k,v in pairs(instance.expansions) do
local t, h = { }, { }
@@ -5477,7 +5582,7 @@ end
-- end of split/join code
-function input.saveconfig(instance)
+function input.saveoldconfig(instance)
input.splitconfig(instance)
input.aux.save_data(instance, 'configuration', nil)
input.joinconfig(instance)
@@ -5490,44 +5595,83 @@ input.configbanner = [[
-- not copyrighted. [HH & TH]
]]
-function input.aux.save_data(instance, dataname, check)
- for cachename, files in pairs(instance[dataname]) do
- local name = file.join(cachename,dataname)
- local luaname, lucname = name .. input.luasuffix, name .. input.lucsuffix
- local f = io.open(luaname,'w')
- if f then
- input.report("saving " .. dataname .. " in", luaname)
- f:write(input.configbanner)
- f:write("\n")
- f:write("if not texmf then texmf = { } end\n")
- f:write("if not texmf.data then texmf.data = { } end\n")
- f:write("\n")
- f:write("texmf.data.type = '" .. dataname .. "'\n")
- f:write("texmf.data.version = '" .. input.cacheversion .. "'\n")
- f:write("texmf.data.date = '" .. os.date("%Y-%m-%d") .. "'\n")
- f:write("texmf.data.time = '" .. os.date("%H:%M:%S") .. "'\n")
- f:write('texmf.data.content = {\n')
- local function dump(k,v)
- if not check or check(v,k) then -- path, name
- if type(v) == 'string' then
- f:write("\t['" .. k .. "'] = '" .. v .. "',\n")
- elseif #v == 1 then
- f:write("\t['" .. k .. "'] = '" .. v[1] .. "',\n")
- else
- f:write("\t['" .. k .. "'] = {'" .. table.concat(v,"','").. "'},\n")
- end
+function input.serialize(files)
+ -- This version is somewhat optimized for the kind of
+ -- tables that we deal with, so it's much faster than
+ -- the generic serializer. This makes sense because
+ -- luatools and mtxtools are called frequently. Okay,
+ -- we pay a small price for properly tabbed tables.
+ local t = { }
+ local concat = table.concat
+ local sorted = table.sortedkeys
+ local function dump(k,v,m)
+ if type(v) == 'string' then
+ return m .. "['" .. k .. "']='" .. v .. "',"
+ elseif #v == 1 then
+ return m .. "['" .. k .. "']='" .. v[1] .. "',"
+ else
+ return m .. "['" .. k .. "']={'" .. concat(v,"','").. "'},"
+ end
+ end
+ t[#t+1] = "return {"
+ if instance.sortdata then
+ for _, k in pairs(sorted(files)) do
+ local fk = files[k]
+ if type(fk) == 'table' then
+ t[#t+1] = "\t['" .. k .. "']={"
+ for _, kk in pairs(sorted(fk)) do
+ t[#t+1] = dump(kk,fk[kk],"\t\t")
end
+ t[#t+1] = "\t},"
+ else
+ t[#t+1] = dump(k,fk,"\t")
end
- if instance.sortdata then
- for _, k in pairs(table.sortedkeys(files)) do
- dump(k,files[k])
+ end
+ else
+ for k, v in pairs(files) do
+ if type(v) == 'table' then
+ t[#t+1] = "\t['" .. k .. "']={"
+ for kk,vv in pairs(v) do
+ t[#t+1] = dump(kk,vv,"\t\t")
end
+ t[#t+1] = "\t},"
else
- for k, v in pairs(files) do
- dump(k,v)
+ t[#t+1] = dump(k,v,"\t")
+ end
+ end
+ end
+ t[#t+1] = "}"
+ return concat(t,"\n")
+end
+
+if not texmf then texmf = {} end -- no longer needed, at least not here
+
+function input.aux.save_data(instance, dataname, check, makename) -- untested without cache overload
+ for cachename, files in pairs(instance[dataname]) do
+ local name = (makename or file.join)(cachename,dataname)
+ local luaname, lucname = name .. input.luasuffix, name .. input.lucsuffix
+ input.report("preparing " .. dataname .. " for", luaname)
+ for k, v in pairs(files) do
+ if not check or check(v,k) then -- path, name
+ if type(v) == "table" and #v == 1 then
+ files[k] = v[1]
end
+ else
+ files[k] = nil -- false
end
- f:write('}\n')
+ end
+ local data = {
+ type = dataname,
+ root = cachename,
+ version = input.cacheversion,
+ date = os.date("%Y-%m-%d"),
+ time = os.date("%H:%M:%S"),
+ content = files,
+ }
+ local f = io.open(luaname,'w')
+ if f then
+ input.report("saving " .. dataname .. " in", luaname)
+ f:write(input.serialize(data))
f:close()
input.report("compiling " .. dataname .. " to", lucname)
if not utils.lua.compile(luaname,lucname) then
@@ -5540,49 +5684,106 @@ function input.aux.save_data(instance, dataname, check)
end
end
-function input.loadconfig(instance)
- instance.configuration, instance.order, instance.loaderror = { }, { }, false
- if not instance.renewcache then
- for _, cnf in ipairs(instance.cnffiles) do
- local dname = file.dirname(cnf)
- input.aux.load_data(instance,dname,'configuration')
- instance.order[#instance.order+1] = instance.configuration[dname]
- if instance.loaderror then break end
+function input.aux.load_data(instance,pathname,dataname,filename,makename) -- untested without cache overload
+ filename = ((not filename or (filename == "")) and dataname) or filename
+ filename = (makename and makename(dataname,filename)) or file.join(pathname,filename)
+ local blob = loadfile(filename .. input.lucsuffix) or loadfile(filename .. input.luasuffix)
+ if blob then
+ local data = blob()
+ if data and data.content and data.type == dataname and data.version == input.cacheversion then
+ input.report("loading",dataname,"for",pathname,"from",filename)
+ instance[dataname][pathname] = data.content
+ else
+ input.report("skipping",dataname,"for",pathname,"from",filename)
+ instance[dataname][pathname] = { }
+ instance.loaderror = true
end
+ else
+ input.report("skipping",dataname,"for",pathname,"from",filename)
end
- input.joinconfig(instance)
end
-if not texmf then texmf = {} end
-if not texmf.data then texmf.data = {} end
+-- some day i'll use the nested approach, but not yet (actually we even drop
+-- engine/progname support since we have only luatex now)
+--
+-- first texmfcnf.lua files are located, next the cached texmf.cnf files
+--
+-- return {
+-- TEXMFBOGUS = 'effe checken of dit werkt',
+-- }
-function input.aux.load_data(instance,pathname,dataname,filename)
- if not filename or (filename == "") then
- filename = dataname .. input.lucsuffix
- end
- local blob = loadfile(file.join(pathname,filename))
- if not blob then
- filename = dataname .. input.luasuffix
- blob = loadfile(file.join(pathname,filename))
- end
+function input.aux.load_texmfcnf(instance,dataname,pathname)
+ local filename = file.join(pathname,input.luaname)
+ local blob = loadfile(filename)
if blob then
- blob()
- if (texmf.data.type == dataname) and (texmf.data.version == input.cacheversion) and texmf.data.content then
- input.report("loading",dataname,"for",pathname,"from",filename)
- instance[dataname][pathname] = texmf.data.content
+ local data = blob()
+ if data then
+ input.report("loading","configuration file",filename)
+ if true then
+ -- flatten to variable.progname
+ local t = { }
+ for k, v in pairs(data) do -- v = progname
+ if type(v) == "string" then
+ t[k] = v
+ else
+ for kk, vv in pairs(v) do -- vv = variable
+ if type(vv) == "string" then
+ t[vv.."."..v] = kk
+ end
+ end
+ end
+ end
+ instance[dataname][pathname] = t
+ else
+ instance[dataname][pathname] = data
+ end
else
- input.report("skipping",dataname,"for",pathname,"from",filename)
+ input.report("skipping","configuration file",filename)
instance[dataname][pathname] = { }
instance.loaderror = true
end
+ else
+ input.report("skipping","configuration file",filename)
+ end
+end
+
+function input.aux.load_configuration(instance,dname,lname)
+ input.aux.load_data(instance,dname,'configuration',lname and file.basename(lname))
+end
+function input.aux.load_files(instance,tag)
+ input.aux.load_data(instance,tag,'files')
+end
+
+function input.resetconfig(instance)
+ instance.configuration, instance.setup, instance.order, instance.loaderror = { }, { }, { }, false
+end
+
+function input.loadnewconfig(instance)
+ for _, cnf in ipairs(instance.luafiles) do
+ local dname = file.dirname(cnf)
+ input.aux.load_texmfcnf(instance,'setup',dname)
+ instance.order[#instance.order+1] = instance.setup[dname]
+ if instance.loaderror then break end
+ end
+end
+
+function input.loadoldconfig(instance)
+ if not instance.renewcache then
+ for _, cnf in ipairs(instance.cnffiles) do
+ local dname = file.dirname(cnf)
+ input.aux.load_configuration(instance,dname)
+ instance.order[#instance.order+1] = instance.configuration[dname]
+ if instance.loaderror then break end
+ end
end
- texmf.data.content = { }
+ input.joinconfig(instance)
end
function input.expand_variables(instance)
instance.expansions = { }
- if instance.engine ~= "" then instance.environment['engine'] = instance.engine end
- if instance.progname ~= "" then instance.environment['progname'] = instance.engine end
+--~ instance.environment['SELFAUTOPARENT'] = instance.environment['SELFAUTOPARENT'] or instance.rootpath
+ if instance.engine ~= "" then instance.environment['engine'] = instance.engine end
+ if instance.progname ~= "" then instance.environment['progname'] = instance.progname end
for k,v in pairs(instance.environment) do
local a, b = k:match("^(%a+)%_(.*)%s*$")
if a and b then
@@ -5673,53 +5874,6 @@ function input.is_expansion(instance,name)
return input.aux.is_entry(instance,instance.expansions,name)
end
-function input.aux.list(instance,list)
- local pat = string.upper(instance.pattern or "","")
- for _,key in pairs(table.sortedkeys(list)) do
- if (instance.pattern=="") or string.find(key:upper(),pat) then
- if instance.kpseonly then
- if instance.kpsevars[key] then
- print(key .. "=" .. input.aux.tabstr(list[key]))
- end
- elseif instance.kpsevars[key] then
- print('K ' .. key .. "=" .. input.aux.tabstr(list[key]))
- else
- print('E ' .. key .. "=" .. input.aux.tabstr(list[key]))
- end
- end
- end
-end
-
-function input.list_variables(instance)
- input.aux.list(instance,instance.variables)
-end
-function input.list_expansions(instance)
- input.aux.list(instance,instance.expansions)
-end
-
-function input.list_configurations(instance)
- for _,key in pairs(table.sortedkeys(instance.kpsevars)) do
- if not instance.pattern or (instance.pattern=="") or key:find(instance.pattern) then
- print(key.."\n")
- for i,c in ipairs(instance.order) do
- local str = c[key]
- if str then
- print("\t" .. i .. "\t\t" .. input.aux.tabstr(str))
- end
- end
- print()
- end
- end
-end
-
-function input.aux.tabstr(str)
- if type(str) == 'table' then
- return table.concat(str," | ")
- else
- return str
- end
-end
-
function input.simplified_list(str)
if type(str) == 'table' then
return str -- troubles ; ipv , in texmf
@@ -5743,23 +5897,6 @@ function input.unexpanded_path(instance,str)
return file.join_path(input.unexpanded_path_list(instance,str))
end
---~ function input.expanded_path_list(instance,str)
---~ if not str then
---~ return { }
---~ elseif instance.savelists then
---~ -- engine+progname hash
---~ str = str:gsub("%$","")
---~ if not instance.lists[str] then -- cached
---~ local lst = input.split_path(input.expansion(instance,str))
---~ instance.lists[str] = input.aux.expanded_path(instance,lst)
---~ end
---~ return instance.lists[str]
---~ else
---~ local lst = input.split_path(input.expansion(instance,str))
---~ return input.aux.expanded_path(instance,lst)
---~ end
---~ end
-
do
local done = { }
@@ -6172,6 +6309,8 @@ do
return original
end
+ input.normalize_name = file.collapse_path
+
end
function input.aux.register_in_trees(instance,name)
@@ -6537,7 +6676,10 @@ end
function input.load(instance)
input.starttiming(instance)
+ input.resetconfig(instance)
input.identify_cnf(instance)
+ input.load_lua(instance)
+ input.expand_variables(instance)
input.load_cnf(instance)
input.expand_variables(instance)
input.load_hash(instance)
@@ -6924,28 +7066,45 @@ caches.more = caches.more or "context"
caches.direct = false -- true is faster but may need huge amounts of memory
caches.trace = false
caches.tree = false
-caches.temp = caches.temp or os.getenv("TEXMFCACHE") or os.getenv("HOME") or os.getenv("HOMEPATH") or os.getenv("VARTEXMF") or os.getenv("TEXMFVAR") or os.getenv("TMP") or os.getenv("TEMP") or os.getenv("TMPDIR") or nil
-caches.paths = caches.paths or { caches.temp }
+caches.paths = caches.paths or nil
caches.force = false
input.usecache = not toboolean(os.getenv("TEXMFSHARECACHE") or "false",true) -- true
-if caches.temp and caches.temp ~= "" and lfs.attributes(caches.temp,"mode") ~= "directory" then
- if caches.force or io.ask(string.format("Should I create the cache path %s?",caches.temp), "no", { "yes", "no" }) == "yes" then
- dir.mkdirs(caches.temp)
+function caches.temp(instance)
+ local function checkpath(cachepath)
+ if not cachepath or cachepath == "" then
+ return nil
+ elseif lfs.attributes(cachepath,"mode") == "directory" then -- lfs.isdir(cachepath) then
+ return cachepath
+ elseif caches.force or io.ask(string.format("Should I create the cache path %s?",cachepath), "no", { "yes", "no" }) == "yes" then
+ dir.mkdirs(cachepath)
+ return (lfs.attributes(cachepath,"mode") == "directory") and cachepath
+ else
+ return nil
+ end
end
-end
-if not caches.temp or caches.temp == "" then
- print("\nfatal error: there is no valid cache path defined\n")
- os.exit()
-elseif lfs.attributes(caches.temp,"mode") ~= "directory" then
- print(string.format("\nfatal error: cache path %s is not a directory\n",caches.temp))
- os.exit()
+ local cachepath = input.expanded_path_list(instance,"TEXMFCACHE")
+ cachepath = cachepath and #cachepath > 0 and checkpath(cachepath[1])
+ if not cachepath then
+ cachepath = os.getenv("TEXMFCACHE") or os.getenv("HOME") or os.getenv("HOMEPATH") or os.getenv("TMP") or os.getenv("TEMP") or os.getenv("TMPDIR") or nil
+ cachepath = checkpath(cachepath)
+ end
+ if not cachepath then
+ print("\nfatal error: there is no valid cache path defined\n")
+ os.exit()
+ elseif lfs.attributes(cachepath,"mode") ~= "directory" then
+ print(string.format("\nfatal error: cache path %s is not a directory\n",cachepath))
+ os.exit()
+ end
+ function caches.temp(instance)
+ return cachepath
+ end
+ return cachepath
end
function caches.configpath(instance)
return table.concat(instance.cnffiles,";")
---~ return input.expand_var(instance,"TEXMFCNF")
end
function caches.hashed(tree)
@@ -6963,19 +7122,8 @@ end
function caches.setpath(instance,...)
if not caches.path then
- if lfs and instance then
- for _,v in pairs(caches.paths) do
- for _,vv in pairs(input.expanded_path_list(instance,v)) do
- if lfs.isdir(vv) then
- caches.path = vv
- break
- end
- end
- if caches.path then break end
- end
- end
if not caches.path then
- caches.path = caches.temp
+ caches.path = caches.temp(instance)
end
caches.path = input.clean_path(caches.path) -- to be sure
if lfs then
@@ -6999,6 +7147,12 @@ function caches.setpath(instance,...)
return caches.path
end
+function caches.definepath(instance,category,subcategory)
+ return function()
+ return caches.setpath(instance,category,subcategory)
+ end
+end
+
function caches.setluanames(path,name)
return path .. "/" .. name .. ".tma", path .. "/" .. name .. ".tmc"
end
@@ -7064,19 +7218,35 @@ do -- local report
end
end
+ local allocated = { }
+
+ -- tracing
+
function containers.define(category, subcategory, version, enabled)
- if category and subcategory then
- return {
- category = category,
- subcategory = subcategory,
- storage = { },
- enabled = enabled,
- version = version or 1.000,
- trace = false,
- path = caches.setpath(texmf.instance,category,subcategory),
- }
- else
- return nil
+ return function()
+ if category and subcategory then
+ local c = allocated[category]
+ if not c then
+ c = { }
+ allocated[category] = c
+ end
+ local s = c[subcategory]
+ if not s then
+ s = {
+ category = category,
+ subcategory = subcategory,
+ storage = { },
+ enabled = enabled,
+ version = version or 1.000,
+ trace = false,
+ path = caches.setpath(texmf.instance,category,subcategory),
+ }
+ c[subcategory] = s
+ end
+ return s
+ else
+ return nil
+ end
end
end
@@ -7133,129 +7303,35 @@ end
-- since we want to use the cache instead of the tree, we will now
-- reimplement the saver.
+local save_data = input.aux.save_data
+
+input.cachepath = nil
+
function input.aux.save_data(instance, dataname, check)
- for cachename, files in pairs(instance[dataname]) do
- local name
+ input.cachepath = input.cachepath or caches.definepath(instance,"trees")
+ save_data(instance, dataname, check, function(cachename,dataname)
if input.usecache then
- name = file.join(caches.setpath(instance,"trees"),caches.hashed(cachename))
- else
- name = file.join(cachename,dataname)
- end
- local luaname, lucname = name .. input.luasuffix, name .. input.lucsuffix
- input.report("preparing " .. dataname .. " in", luaname)
- for k, v in pairs(files) do
- if not check or check(v,k) then -- path, name
- if type(v) == "table" and #v == 1 then
- files[k] = v[1]
- end
- else
- files[k] = nil -- false
- end
- end
- local data = {
- type = dataname,
- root = cachename,
- version = input.cacheversion,
- date = os.date("%Y-%m-%d"),
- time = os.date("%H:%M:%S"),
- content = files,
- }
- local f = io.open(luaname,'w')
- if f then
- input.report("saving " .. dataname .. " in", luaname)
- -- f:write(table.serialize(data,'return'))
- f:write(input.serialize(data))
- f:close()
- input.report("compiling " .. dataname .. " to", lucname)
- if not utils.lua.compile(luaname,lucname) then
- input.report("compiling failed for " .. dataname .. ", deleting file " .. lucname)
- os.remove(lucname)
- end
+ return file.join(input.cachepath(),caches.hashed(cachename))
else
- input.report("unable to save " .. dataname .. " in " .. name..input.luasuffix)
+ return file.join(cachename,dataname)
end
- end
+ end)
end
-function input.serialize(files)
- -- This version is somewhat optimized for the kind of
- -- tables that we deal with, so it's much faster than
- -- the generic serializer. This makes sense because
- -- luatools and mtxtools are called frequently. Okay,
- -- we pay a small price for properly tabbed tables.
- local t = { }
- local concat = table.concat
- local sorted = table.sortedkeys
- local function dump(k,v,m)
- if type(v) == 'string' then
- return m .. "['" .. k .. "']='" .. v .. "',"
- elseif #v == 1 then
- return m .. "['" .. k .. "']='" .. v[1] .. "',"
- else
- return m .. "['" .. k .. "']={'" .. concat(v,"','").. "'},"
- end
- end
- t[#t+1] = "return {"
- if instance.sortdata then
- for _, k in pairs(sorted(files)) do
- local fk = files[k]
- if type(fk) == 'table' then
- t[#t+1] = "\t['" .. k .. "']={"
- for _, kk in pairs(sorted(fk)) do
- t[#t+1] = dump(kk,fk[kk],"\t\t")
- end
- t[#t+1] = "\t},"
- else
- t[#t+1] = dump(k,fk,"\t")
- end
- end
- else
- for k, v in pairs(files) do
- if type(v) == 'table' then
- t[#t+1] = "\t['" .. k .. "']={"
- for kk,vv in pairs(v) do
- t[#t+1] = dump(kk,vv,"\t\t")
- end
- t[#t+1] = "\t},"
- else
- t[#t+1] = dump(k,v,"\t")
- end
- end
- end
- t[#t+1] = "}"
- return concat(t,"\n")
-end
+local load_data = input.aux.load_data
function input.aux.load_data(instance,pathname,dataname,filename)
- local luaname, lucname, pname, fname
- if input.usecache then
- pname, fname = caches.setpath(instance,"trees"), caches.hashed(pathname)
- filename = file.join(pname,fname)
- else
- if not filename or (filename == "") then
- filename = dataname
- end
- pname, fname = pathname, filename
- end
- luaname = file.join(pname,fname) .. input.luasuffix
- lucname = file.join(pname,fname) .. input.lucsuffix
- local blob = loadfile(lucname)
- if not blob then
- blob = loadfile(luaname)
- end
- if blob then
- local data = blob()
- if data and data.content and data.type == dataname and data.version == input.cacheversion then
- input.report("loading",dataname,"for",pathname,"from",filename)
- instance[dataname][pathname] = data.content
+ input.cachepath = input.cachepath or caches.definepath(instance,"trees")
+ load_data(instance,pathname,dataname,filename,function(dataname,filename)
+ if input.usecache then
+ return file.join(input.cachepath(),caches.hashed(pathname))
else
- input.report("skipping",dataname,"for",pathname,"from",filename)
- instance[dataname][pathname] = { }
- instance.loaderror = true
+ if not filename or (filename == "") then
+ filename = dataname
+ end
+ return file.join(pathname,filename)
end
- else
- input.report("skipping",dataname,"for",pathname,"from",filename)
- end
+ end)
end
-- we will make a better format, maybe something xml or just text or lua
@@ -8027,7 +8103,10 @@ messages.help = [[
]]
function input.runners.my_prepare_a(instance)
+ input.resetconfig(instance)
input.identify_cnf(instance)
+ input.load_lua(instance)
+ input.expand_variables(instance)
input.load_cnf(instance)
input.expand_variables(instance)
end
@@ -8035,6 +8114,7 @@ end
function input.runners.my_prepare_b(instance)
input.runners.my_prepare_a(instance)
input.load_hash(instance)
+ input.automount(instance)
end
function input.runners.prepare(instance)
diff --git a/tex/context/base/cont-new.tex b/tex/context/base/cont-new.tex
index bf5540405..eda6471d2 100644
--- a/tex/context/base/cont-new.tex
+++ b/tex/context/base/cont-new.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2008.05.13 14:42}
+\newcontextversion{2008.05.21 15:21}
%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/context.tex b/tex/context/base/context.tex
index c0f4c7afe..e6959c9b4 100644
--- a/tex/context/base/context.tex
+++ b/tex/context/base/context.tex
@@ -42,7 +42,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2008.05.13 14:42}
+\edef\contextversion{2008.05.21 15:21}
%D For those who want to use this:
diff --git a/tex/context/base/core-buf.lua b/tex/context/base/core-buf.lua
index 4203486f6..7c0164cf5 100644
--- a/tex/context/base/core-buf.lua
+++ b/tex/context/base/core-buf.lua
@@ -217,15 +217,24 @@ function buffers.content(name) -- no print
end
end
-function buffers.collect(names) -- no print
+function buffers.collect(names,separator) -- no print
local t = { }
- for i=1,#names do
- local c = buffers.content(names[i])
- if c ~= "" then
- t[#t+1] = c
+ if type(names) == "table" then
+ for i=1,#names do
+ local c = buffers.content(names[i])
+ if c ~= "" then
+ t[#t+1] = c
+ end
+ end
+ else
+ for name in names:gmatch("[^,]+") do
+ local c = buffers.content(name)
+ if c ~= "" then
+ t[#t+1] = c
+ end
end
end
- return concat(t," ")
+ return concat(t,separator or " ") -- maybe this will change to "\n"
end
function buffers.inspect(name)
diff --git a/tex/context/base/core-lst.tex b/tex/context/base/core-lst.tex
index 5f08146dc..d9fdca375 100644
--- a/tex/context/base/core-lst.tex
+++ b/tex/context/base/core-lst.tex
@@ -66,7 +66,7 @@
\thisisnextinternal\currentlist
\fi
\expanded
- {\writeutilitycommand
+ {\writeutilitycommand % todo: also an immediate option
{\noexpand\listentry
{\currentlist}%
{\nextinternalreference}%
diff --git a/tex/context/base/core-mat.tex b/tex/context/base/core-mat.tex
index 465e8d50b..a74d5f90e 100644
--- a/tex/context/base/core-mat.tex
+++ b/tex/context/base/core-mat.tex
@@ -17,6 +17,18 @@
\unprotect
+% \startlines
+% $\mathopnolimits{\rm d}x$
+% $\mathopnolimits{\kern\zeropoint \rm d}x$
+% $\puremathcomm{nolop}{\rm d}x$
+% $\puremathcomm{nolop}{\kern\zeropoint\rm d}x$
+% \blank
+% $\puremathcomm{nolop}{\mr d}x$
+% $\puremathcomm{nolop}{\kern\zeropoint\mr d}x$
+% $\mathop{\kern\zeropoint\mr d}x$
+% $\mathopnolimits{\kern\zeropoint d}x$
+% \stoplines
+
% \definemessageconstant{math}
% \startmessages all library: math
@@ -2759,6 +2771,7 @@
\def\disablefiller {\let\normalorfiller\firstoftwoarguments}
\def\mathopnolimits#1{\mathop{\mr#1}\nolimits} % was \rm, which follows text fonts (used in mml parser)
+\def\mathopdolimits#1{\mathop{\mr#1}} % was \rm, which follows text fonts (used in mml parser)
%D \macros{overset, underset}
%D
diff --git a/tex/context/base/core-ver.mkiv b/tex/context/base/core-ver.mkiv
index c1dc0c72a..701d19b41 100644
--- a/tex/context/base/core-ver.mkiv
+++ b/tex/context/base/core-ver.mkiv
@@ -36,6 +36,7 @@
{\ctxlua{buffers.visualizers.reset()}%
\def\obs{\obeyedspace}%
\verbatimfont
+ \resetfontfeature
\obeycharacters}
% \ctxluafileload{verb-tex}{}
diff --git a/tex/context/base/font-afm.lua b/tex/context/base/font-afm.lua
index 0bed489d8..fd9315472 100644
--- a/tex/context/base/font-afm.lua
+++ b/tex/context/base/font-afm.lua
@@ -19,7 +19,7 @@ away.</p>
fonts = fonts or { }
fonts.afm = fonts.afm or { }
-fonts.afm.version = 1.25 -- incrementing this number one up will force a re-cache
+fonts.afm.version = 1.26 -- incrementing this number one up will force a re-cache
fonts.afm.syncspace = true -- when true, nicer stretch values
fonts.afm.enhance_data = true -- best leave this set to true
fonts.afm.trace_features = false
@@ -254,7 +254,7 @@ way we can set them faster when defining a font.</p>
function fonts.afm.load(filename)
local name = file.removesuffix(filename)
- local data = containers.read(fonts.afm.cache,name)
+ local data = containers.read(fonts.afm.cache(),name)
local size = lfs.attributes(name,"size") or 0
if data and data.size ~= size then
data = nil
@@ -273,7 +273,7 @@ function fonts.afm.load(filename)
logs.report("load afm","file size: " .. size)
data.size = size
logs.report("load afm","saving: in cache")
- data = containers.write(fonts.afm.cache, name, data)
+ data = containers.write(fonts.afm.cache(), name, data)
end
end
end
@@ -281,7 +281,8 @@ function fonts.afm.load(filename)
end
function fonts.afm.unify(data, filename)
- local unicode, private, unicodes = fonts.enc.load('unicode').hash, 0x0F0000, { }
+--~ local unicode, unicodes, private = fonts.enc.load('unicode').hash, { }, 0x0F0000
+ local unicode, unicodes, private = fonts.enc.load('unicode').hash, { }, fonts.private
for name, blob in pairs(data.characters) do
local code = unicode[name] -- or characters.name_to_unicode[name]
if not code then
@@ -571,9 +572,10 @@ function fonts.afm.afm_to_tfm(specification)
return nil
else
fonts.afm.check_features(specification)
+ specification = fonts.define.resolve(specification) -- new, was forgotten
local features = specification.features.normal
local cache_id = specification.hash
- local tfmdata = containers.read(fonts.tfm.cache, cache_id) -- cache with features applied
+ local tfmdata = containers.read(fonts.tfm.cache(), cache_id) -- cache with features applied
if not tfmdata then
local afmdata = fonts.afm.load(afmname)
if not table.is_empty(afmdata) then
@@ -589,7 +591,7 @@ function fonts.afm.afm_to_tfm(specification)
elseif fonts.trace then
logs.report("load afm", string.format("no (valid) afm file found with name %s",afmname))
end
- tfmdata = containers.write(fonts.tfm.cache,cache_id,tfmdata)
+ tfmdata = containers.write(fonts.tfm.cache(),cache_id,tfmdata)
end
return tfmdata
end
@@ -731,4 +733,13 @@ fonts.afm.features.register('encoding')
fonts.initializers.base.afm.encoding = fonts.initializers.common.encoding
fonts.initializers.node.afm.encoding = fonts.initializers.common.encoding
--- todo: oldstyle smallcaps as features for afm files
+-- todo: oldstyle smallcaps as features for afm files (use with care)
+
+fonts.initializers.base.afm.onum = fonts.initializers.common.oldstyle
+fonts.initializers.base.afm.smcp = fonts.initializers.common.smallcaps
+fonts.initializers.base.afm.fkcp = fonts.initializers.common.fakecaps
+
+fonts.afm.features.register('onum',false)
+fonts.afm.features.register('smcp',false)
+fonts.afm.features.register('fkcp',false)
+
diff --git a/tex/context/base/font-def.lua b/tex/context/base/font-def.lua
index c9a3144f5..af6f5f394 100644
--- a/tex/context/base/font-def.lua
+++ b/tex/context/base/font-def.lua
@@ -277,7 +277,7 @@ function fonts.tfm.read_and_define(name,size) -- no id
fonts.tfm.id[id] = fontdata
fonts.tfm.internalized[hash] = id
if fonts.trace then
- logs.report("define font", string.format("at 1 id %s, hash: %s",id,hash))
+ logs.report("define font", string.format("loading at 1 id %s, hash: %s",id,hash))
end
else
id = fonts.tfm.internalized[hash]
@@ -602,7 +602,7 @@ function fonts.define.read(name,size,id)
specification = fonts.define.resolve(specification)
local hash = fonts.tfm.hash_instance(specification)
if true then
- --~ local fontdata = containers.read(fonts.cache,hash) -- for tracing purposes
+ --~ local fontdata = containers.read(fonts.cache(),hash) -- for tracing purposes
end
local fontdata = fonts.tfm.internalized[hash] -- id
if not fontdata then
@@ -615,23 +615,24 @@ function fonts.define.read(name,size,id)
end
end
if true then
- --~ fontdata = containers.write(fonts.cache,hash,fontdata) -- for tracing purposes
+ --~ fontdata = containers.write(fonts.cache(),hash,fontdata) -- for tracing purposes
end
if not fonts.tfm.internalized[hash] then
fonts.tfm.id[id] = fontdata
fonts.tfm.internalized[hash] = id
if fonts.trace then
- logs.report("define font", string.format("at 2 id %s, hash: %s",id,hash))
+ logs.report("define font", string.format("loading at 2 id %s, hash: %s",id,hash))
end
else
fontdata = fonts.tfm.internalized[hash]
end
end
if not fontdata then
- logs.error("define font", string.format("name: %s, loading aborted",specification.name))
+ logs.error("define font", string.format("unknown font %s, loading aborted",specification.name))
elseif fonts.trace and type(fontdata) == "table" then
- logs.report("use font",string.format("%s font n:%s s:%s b:%s e:%s p:%s f:%s",
+ logs.report("define font",string.format("using %s font with id %s, n:%s s:%s b:%s e:%s p:%s f:%s",
fontdata.type or "unknown",
+ id or "?",
fontdata.name or "?",
fontdata.size or "default",
fontdata.encodingbytes or "?",
diff --git a/tex/context/base/font-enc.lua b/tex/context/base/font-enc.lua
index 73b4ae5d8..fc77aefb9 100644
--- a/tex/context/base/font-enc.lua
+++ b/tex/context/base/font-enc.lua
@@ -27,7 +27,7 @@ fonts.enc.known = {
}
function fonts.enc.is_known(encoding)
- return containers.is_valid(fonts.enc.cache,encoding)
+ return containers.is_valid(fonts.enc.cache(),encoding)
end
--[[ldx--
@@ -51,7 +51,7 @@ will be used.</p>
function fonts.enc.load(filename)
local name = file.removesuffix(filename)
- local data = containers.read(fonts.enc.cache,name)
+ local data = containers.read(fonts.enc.cache(),name)
if data then
return data
end
@@ -93,7 +93,7 @@ function fonts.enc.load(filename)
hash=hash,
unicodes=unicodes
}
- return containers.write(fonts.enc.cache, name, data)
+ return containers.write(fonts.enc.cache(), name, data)
end
--[[ldx--
@@ -116,5 +116,5 @@ function fonts.enc.make_unicode_vector()
for name, code in pairs(characters.synonyms) do
vector[code], hash[name] = name, code
end
- return containers.write(fonts.enc.cache, 'unicode', { name='unicode', tag='unicode', vector=vector, hash=hash })
+ return containers.write(fonts.enc.cache(), 'unicode', { name='unicode', tag='unicode', vector=vector, hash=hash })
end
diff --git a/tex/context/base/font-ini.lua b/tex/context/base/font-ini.lua
index 0cfc7a3f4..a3eefa9db 100644
--- a/tex/context/base/font-ini.lua
+++ b/tex/context/base/font-ini.lua
@@ -15,8 +15,9 @@ if not modules then modules = { } end modules ['font-ini'] = {
fonts = fonts or { }
-fonts.trace = false -- true
-fonts.mode = 'base'
+fonts.trace = false -- true
+fonts.mode = 'base'
+fonts.private = 0xE000
fonts.methods = {
base = { tfm = { }, afm = { }, otf = { }, vtf = { }, fix = { } },
diff --git a/tex/context/base/font-otf.lua b/tex/context/base/font-otf.lua
index 9efa88e50..5c0db392d 100644
--- a/tex/context/base/font-otf.lua
+++ b/tex/context/base/font-otf.lua
@@ -830,7 +830,7 @@ function fonts.otf.load(filename,format,sub,featurefile)
hash = hash:lower()
hash = hash:gsub("[^%w%d]+","-")
end
- local data = containers.read(fonts.otf.cache, hash)
+ local data = containers.read(fonts.otf.cache(), hash)
local size = lfs.attributes(filename,"size") or 0
if data and data.size ~= size then
data = nil
@@ -886,7 +886,7 @@ function fonts.otf.load(filename,format,sub,featurefile)
logs.report("load otf","file size: " .. size)
data.size = size
logs.report("load otf","saving: in cache")
- data = containers.write(fonts.otf.cache, hash, data)
+ data = containers.write(fonts.otf.cache(), hash, data)
else
logs.error("load otf","loading failed (table conversion error)")
end
@@ -1160,7 +1160,7 @@ end
--~ },
function fonts.otf.enhance.before(data,filename)
- local private = 0xE000
+ local private = fonts.private
if data.subfonts and table.is_empty(data.glyphs) then
local cidinfo = data.cidinfo
if cidinfo.registry then
@@ -1697,7 +1697,7 @@ function fonts.otf.otf_to_tfm(specification)
local format = specification.format
local features = specification.features.normal
local cache_id = specification.hash
- local tfmdata = containers.read(fonts.tfm.cache,cache_id)
+ local tfmdata = containers.read(fonts.tfm.cache(),cache_id)
if not tfmdata then
local otfdata = fonts.otf.load(filename,format,sub,features and features.featurefile)
if not table.is_empty(otfdata) then
@@ -1732,7 +1732,7 @@ function fonts.otf.otf_to_tfm(specification)
fonts.otf.set_features(tfmdata)
end
end
- containers.write(fonts.tfm.cache,cache_id,tfmdata)
+ containers.write(fonts.tfm.cache(),cache_id,tfmdata)
end
return tfmdata
end
@@ -3326,7 +3326,8 @@ do
local trace = fonts.otf.trace_kerns
local factor = tfmdata.factor
while next and next.id == glyph and next.subtype<256 and next.font == currentfont do
- if characters[next.char].description.class == 'mark' then
+ local cn = characters[next.char]
+ if not cn or cn.description.class == 'mark' then
prev = next
next = next.next
else
diff --git a/tex/context/base/font-syn.lua b/tex/context/base/font-syn.lua
index 24456e7eb..d99177716 100644
--- a/tex/context/base/font-syn.lua
+++ b/tex/context/base/font-syn.lua
@@ -204,13 +204,13 @@ end
function fonts.names.load(reload)
if not fonts.names.loaded then
if reload then
- if containers.is_usable(fonts.names.cache, "names") then
+ if containers.is_usable(fonts.names.cache(), "names") then
fonts.names.identify()
- containers.write(fonts.names.cache, "names", fonts.names.data)
+ containers.write(fonts.names.cache(), "names", fonts.names.data)
end
fonts.names.saved = true
else
- fonts.names.data = containers.read(fonts.names.cache, "names")
+ fonts.names.data = containers.read(fonts.names.cache(), "names")
if not fonts.names.saved then
if table.is_empty(fonts.names.data) or table.is_empty(fonts.names.data.mapping) then
fonts.names.load(true)
diff --git a/tex/context/base/font-tfm.lua b/tex/context/base/font-tfm.lua
index 175dd6d10..d0a838bcd 100644
--- a/tex/context/base/font-tfm.lua
+++ b/tex/context/base/font-tfm.lua
@@ -180,8 +180,10 @@ in the process; numbers are of course copies. Here 65536 equals 1pt. (Due to
excessive memory usage in CJK fonts, we no longer pass the boundingbox.)</p>
--ldx]]--
+fonts.trace_scaling = false
+
function fonts.tfm.do_scale(tfmtable, scaledpoints)
- local trace = fonts.trace
+ local trace = fonts.trace_scaling
if scaledpoints < 0 then
scaledpoints = (- scaledpoints/1000) * tfmtable.designsize -- already in sp
end
@@ -463,18 +465,18 @@ do
local afmdata = tfmdata.shared.afmdata
local characters = tfmdata.characters
local unicodes = afmdata.luatex.unicodes
- local function remap(pattern,name)
- local p = pattern:match(name)
- if p then
- local oldchr, newchr = unicodes[p], unicodes[name]
- if oldchr and newchr then
- characters[oldchr] = characters[newchr]
+ local done = false
+ for i, blob in pairs(characters) do
+ local name = blob.description.name
+ if name then
+ local p = pattern:match(name)
+ if p then
+ local oldchr, newchr = unicodes[p], unicodes[name]
+ if oldchr and newchr then
+ characters[oldchr] = characters[newchr]
+ end
end
end
- return p
- end
- for _, blob in pairs(characters) do
- remap(pattern,blob.name)
end
end
end
@@ -486,6 +488,27 @@ do
fonts.initializers.common.remap(tfmdata,value,smallcaps)
end
+ function fonts.initializers.common.fakecaps(tfmdata,value)
+ if value then
+ -- todo: scale down
+ local afmdata = tfmdata.shared.afmdata
+ local characters = tfmdata.characters
+ local unicodes = afmdata.luatex.unicodes
+ for i, blob in pairs(characters) do
+ local name = blob.description.name
+ if name then
+ local p = name:lower()
+ if p then
+ local oldchr, newchr = unicodes[p], unicodes[name]
+ if oldchr and newchr then
+ characters[oldchr] = characters[newchr]
+ end
+ end
+ end
+ end
+ end
+ end
+
end
--~ function fonts.initializers.common.install(format,feature) -- 'afm','lineheight'
diff --git a/tex/context/base/l-file.lua b/tex/context/base/l-file.lua
index 91998532b..f49add545 100644
--- a/tex/context/base/l-file.lua
+++ b/tex/context/base/l-file.lua
@@ -134,14 +134,22 @@ end
--~ print("../test/" .. " == " .. file.collapse_path("../test/"))
--~ print("a/a" .. " == " .. file.collapse_path("a/b/c/../../a"))
+--~ function file.collapse_path(str)
+--~ local ok, n = false, 0
+--~ while not ok do
+--~ ok = true
+--~ str, n = str:gsub("[^%./]+/%.%./", function(s)
+--~ ok = false
+--~ return ""
+--~ end)
+--~ end
+--~ return (str:gsub("/%./","/"))
+--~ end
+
function file.collapse_path(str)
- local ok, n = false, 0
- while not ok do
- ok = true
- str, n = str:gsub("[^%./]+/%.%./", function(s)
- ok = false
- return ""
- end)
+ local n = 1
+ while n > 0 do
+ str, n = str:gsub("([^/%.]+/%.%./)","")
end
return (str:gsub("/%./","/"))
end
diff --git a/tex/context/base/l-string.lua b/tex/context/base/l-string.lua
index 0b2fac3a0..6a3bea31c 100644
--- a/tex/context/base/l-string.lua
+++ b/tex/context/base/l-string.lua
@@ -345,7 +345,6 @@ local patterns_escapes = {
["]"] = "%]",
}
-
function string:pattesc()
return (self:gsub(".",patterns_escapes))
end
diff --git a/tex/context/base/l-url.lua b/tex/context/base/l-url.lua
index 906ce0c0c..3bb2b1f11 100644
--- a/tex/context/base/l-url.lua
+++ b/tex/context/base/l-url.lua
@@ -49,7 +49,7 @@ function url.hashed(str)
path = s[3],
query = s[4],
fragment = s[5],
- original=str
+ original = str
}
end
diff --git a/tex/context/base/l-utils.lua b/tex/context/base/l-utils.lua
index d1faa4f34..ec8e39b94 100644
--- a/tex/context/base/l-utils.lua
+++ b/tex/context/base/l-utils.lua
@@ -115,19 +115,18 @@ end
utils.lua.compile_strip = true
-function utils.lua.compile(luafile, lucfile)
+function utils.lua.compile(luafile, lucfile, cleanup)
-- utils.report("compiling",luafile,"into",lucfile)
os.remove(lucfile)
local command = "-o " .. string.quote(lucfile) .. " " .. string.quote(luafile)
if utils.lua.compile_strip then
command = "-s " .. command
end
- if os.spawn("texluac " .. command) == 0 then
- return true
- elseif os.spawn("luac " .. command) == 0 then
- return true
- else
- return false
+ local done = (os.spawn("texluac " .. command) == 0) or (os.spawn("luac " .. command) == 0)
+ if done and cleanup and lfs.isfile(lucfile) and lfs.isfile(luafile) then
+ -- utils.report("removing",luafile)
+ os.remove(luafile)
end
+ return done
end
diff --git a/tex/context/base/l-xml.lua b/tex/context/base/l-xml.lua
index 752ff3f74..b4e151ec3 100644
--- a/tex/context/base/l-xml.lua
+++ b/tex/context/base/l-xml.lua
@@ -480,6 +480,22 @@ do
elseif not nocommands then
local ec = e.command
if ec ~= nil then -- we can have all kind of types
+
+if e.special then -- todo test for true/false
+ local etg, edt = e.tg, e.dt
+ local spc = specialconverter and specialconverter[etg]
+ if spc then
+--~ print("SPECIAL",etg,table.serialize(specialconverter), spc)
+ local result = spc(edt[1])
+ if result then
+ handle(result)
+ return
+ else
+ -- no need to handle any further
+ end
+ end
+end
+
local xc = xml.command
if xc then
xc(e,ec)
@@ -529,12 +545,18 @@ do
end
end
end
- if ern and xml.trace_remap then
- if ats then
- ats[#ats+1] = format("xmlns:remapped='%s'",ern)
- else
- ats = { format("xmlns:remapped='%s'",ern) }
- end
+ if ern and xml.trace_remap and ern ~= ens then
+--~ if ats then
+--~ ats[#ats+1] = format("xmlns:remapped='%s'",ern)
+--~ else
+--~ ats = { format("xmlns:remapped='%s'",ern) }
+--~ end
+--~ if ats then
+--~ ats[#ats+1] = format("remappedns='%s'",ens or '-')
+--~ else
+--~ ats = { format("remappedns='%s'",ens or '-') }
+--~ end
+ens = ern
end
if ens ~= "" then
if edt and #edt > 0 then
@@ -1115,7 +1137,7 @@ do
-- way too fuzzy
local found
if not k or not n then
- local ns, tg = root.ns, root.tg
+ local ns, tg = root.rn or root.ns or "", root.tg
if not tg then
for i=1,#root do
local e = root[i]
@@ -1124,10 +1146,10 @@ do
break
end
end
- elseif ns == "" then
- return tg
- else
+ elseif ns ~= "" then
return ns .. ":" .. tg
+ else
+ return tg
end
elseif n == 0 then
local e = root[k]
@@ -1161,7 +1183,7 @@ do
end
end
if found then
- local ns, tg = found.ns, found.tg
+ local ns, tg = found.rn or found.ns or "", found.tg
if ns ~= "" then
return ns .. ":" .. tg
else
@@ -2149,7 +2171,7 @@ do if unicode and unicode.utf8 then
xml.entities = xml.entities or { } -- xml.entities.handler == function
function xml.entities.handler(e)
- return format("[s]",e)
+ return format("[%s]",e)
end
local char = unicode.utf8.char
diff --git a/tex/context/base/luat-crl.lua b/tex/context/base/luat-crl.lua
index c0690b8af..aaf2e86a1 100644
--- a/tex/context/base/luat-crl.lua
+++ b/tex/context/base/luat-crl.lua
@@ -7,12 +7,11 @@
if not versions then versions = { } end versions['luat-crl'] = 1.001
if not curl then curl = { } end
-curl.cachepath = caches.setpath(texmf.instance,"curl")
-
-curl.cached = { }
+curl.cached = { }
+curl.cachepath = caches.definepath(texmf.instance,"curl")
function curl.fetch(protocol, name)
- local cachename = curl.cachepath .. "/" .. name:gsub("[^%a%d%.]+","-")
+ local cachename = curl.cachepath() .. "/" .. name:gsub("[^%a%d%.]+","-")
-- cachename = cachename:gsub("[\\/]", io.fileseparator)
cachename = cachename:gsub("[\\]", "/")
if not curl.cached[name] then
diff --git a/tex/context/base/luat-env.lua b/tex/context/base/luat-env.lua
index 73df7e3f1..48563e2e7 100644
--- a/tex/context/base/luat-env.lua
+++ b/tex/context/base/luat-env.lua
@@ -35,8 +35,8 @@ if environment.useluc == nil then environment.useluc = true end
if not environment.formatname or environment.formatname == "" then if tex then environment.formatname = tex.formatname end end
if not environment.jobname or environment.jobname == "" then if tex then environment.jobname = tex.jobname end end
-if not environment.progname or environment.progname == "" then environment.progname = "luatex" end
-if not environment.engine or environment.engine == "" then environment.engine = "context" end
+if not environment.progname or environment.progname == "" then environment.progname = "context" end
+if not environment.engine or environment.engine == "" then environment.engine = "luatex" end
if not environment.formatname or environment.formatname == "" then environment.formatname = "cont-en" end
if not environment.formatpath or environment.formatpath == "" then environment.formatpath = '.' end
if not environment.enginepath or environment.enginepath == "" then environment.enginepath = '.' end
diff --git a/tex/context/base/luat-inp.lua b/tex/context/base/luat-inp.lua
index 9ab21000c..63dc1d904 100644
--- a/tex/context/base/luat-inp.lua
+++ b/tex/context/base/luat-inp.lua
@@ -8,6 +8,10 @@
-- additional functionality becomes available. We will split this
-- module in components when we're done with prototyping.
+-- TODO: os.getenv -> os.env[]
+-- TODO: instances.[hashes,cnffiles,configurations,522] -> ipairs (alles check, sneller)
+-- TODO: check escaping in find etc, too much, too slow
+
-- This is the first code I wrote for LuaTeX, so it needs some cleanup.
-- To be considered: hash key lowercase, first entry in table filename
@@ -18,9 +22,6 @@
-- Beware, loading and saving is overloaded in luat-tmp!
--- todo: instances.[hashes,cnffiles,configurations,522] -> ipairs (alles check, sneller)
--- todo: check escaping in find etc, too much, too slow
-
if not versions then versions = { } end versions['luat-inp'] = 1.001
if not environment then environment = { } end
if not file then file = { } end
@@ -39,6 +40,8 @@ if not input.hashers then input.hashers = { } end -- load databases
if not input.generators then input.generators = { } end -- generate databases
if not input.filters then input.filters = { } end -- conversion filters
+local format = string.format
+
input.locators.notfound = { nil }
input.hashers.notfound = { nil }
input.generators.notfound = { nil }
@@ -48,6 +51,7 @@ input.banner = nil
input.verbose = false
input.debug = false
input.cnfname = 'texmf.cnf'
+input.luaname = 'texmfcnf.lua'
input.lsrname = 'ls-R'
input.luasuffix = '.tma'
input.lucsuffix = '.tmc'
@@ -137,12 +141,14 @@ function input.reset()
instance.files = { }
instance.remap = { }
instance.configuration = { }
+ instance.setup = { }
instance.order = { }
instance.found = { }
instance.foundintrees = { }
instance.kpsevars = { }
instance.hashes = { }
instance.cnffiles = { }
+ instance.luafiles = { }
instance.lists = { }
instance.remember = true
instance.diskcache = true
@@ -156,13 +162,11 @@ function input.reset()
instance.allresults = false
instance.pattern = nil -- lists
instance.kpseonly = false -- lists
- instance.cachefile = 'tmftools'
instance.loadtime = 0
instance.starttime = 0
instance.stoptime = 0
instance.validfile = function(path,name) return true end
instance.data = { } -- only for loading
- instance.sortdata = false
instance.force_suffixes = true
instance.dummy_path_expr = "^!*unset/*$"
instance.fakepaths = { }
@@ -175,7 +179,7 @@ function input.reset()
end
else
-- we will access os.env frequently
- for k,v in pairs({'HOME','TEXMF','TEXMFCNF','SELFAUTOPARENT'}) do
+ for k,v in pairs({'HOME','TEXMF','TEXMFCNF'}) do
local e = os.getenv(v)
if e then
-- input.report("setting",v,"to",input.bare_variable(e))
@@ -203,7 +207,7 @@ function input.reset_hashes(instance)
instance.found = { }
end
-function input.bare_variable(str)
+function input.bare_variable(str) -- assumes str is a string
-- return string.gsub(string.gsub(string.gsub(str,"%s+$",""),'^"(.+)"$',"%1"),"^'(.+)'$","%1")
return (str:gsub("\s*([\"\']?)(.+)%1\s*", "%2"))
end
@@ -288,7 +292,7 @@ do
instance.stoptime = stoptime
instance.loadtime = instance.loadtime + loadtime
if report then
- input.report('load time', string.format("%0.3f",loadtime))
+ input.report('load time', format("%0.3f",loadtime))
end
return loadtime
end
@@ -299,7 +303,7 @@ do
end
function input.elapsedtime(instance)
- return string.format("%0.3f",(instance and instance.loadtime) or 0)
+ return format("%0.3f",(instance and instance.loadtime) or 0)
end
function input.report_loadtime(instance)
@@ -315,15 +319,19 @@ function input.env(instance,key)
end
function input.osenv(instance,key)
- if instance.environment[key] == nil then
- local e = os.getenv(key)
+ local ie = instance.environment
+ local value = ie[key]
+ if value == nil then
+ -- local e = os.getenv(key)
+ local e = os.env[key]
if e == nil then
- instance.environment[key] = "" -- false
+ -- value = "" -- false
else
- instance.environment[key] = input.bare_variable(e)
+ value = input.bare_variable(e)
end
+ ie[key] = value
end
- return instance.environment[key] or ""
+ return value or ""
end
-- we follow a rather traditional approach:
@@ -334,66 +342,103 @@ end
-- for the moment we don't expect a configuration file in a zip
function input.identify_cnf(instance)
+ -- we no longer support treepath and rootpath (was handy for testing);
+ -- also we now follow the stupid route: if not set then just assume *one*
+ -- cnf file under texmf (i.e. distribution)
if #instance.cnffiles == 0 then
- if instance.treepath ~= "" then
- -- this is a special purpose branch, not really used
- if instance.rootpath ~= "" then
- local t = instance.treepath:splitchr(',')
- for k,v in ipairs(t) do
- t[k] = file.join(instance.rootpath,v)
+ if input.env(instance,'TEXMFCNF') == "" then
+ local ownpath = environment.ownpath() or "."
+ if ownpath then
+ -- beware, this is tricky on my own system because at that location I do have
+ -- the raw tree that ends up in the zip; i.e. I cannot test this kind of mess
+ local function locate(filename,list)
+ local ownroot = input.normalize_name(file.join(ownpath,"../.."))
+ if not lfs.isdir(file.join(ownroot,"texmf")) then
+ ownroot = input.normalize_name(file.join(ownpath,".."))
+ if not lfs.isdir(file.join(ownroot,"texmf")) then
+ input.verbose = true
+ input.report("error", "unable to identify cnf file")
+ return
+ end
+ end
+ local texmfcnf = file.join(ownroot,"texmf-local/web2c",filename) -- for minimals and myself
+ if not lfs.isfile(texmfcnf) then
+ texmfcnf = file.join(ownroot,"texmf/web2c",filename)
+ if not lfs.isfile(texmfcnf) then
+ input.verbose = true
+ input.report("error", "unable to locate",filename)
+ return
+ end
+ end
+ table.insert(list,texmfcnf)
+ local ie = instance.environment
+ if not ie['SELFAUTOPARENT'] then ie['SELFAUTOPARENT'] = ownroot end
+ if not ie['TEXMFCNF'] then ie['TEXMFCNF'] = file.dirname(texmfcnf) end
+ end
+ locate(input.luaname,instance.luafiles)
+ locate(input.cnfname,instance.cnffiles)
+ if #instance.luafiles == 0 and instance.cnffiles == 0 then
+ input.verbose = true
+ input.report("error", "unable to locate",filename)
+ os.exit()
end
- instance.treepath = table.concat(t,',')
+ -- here we also assume then TEXMF is set in the distribution, if this trickery is
+ -- used in the minimals, then users who don't use setuptex are on their own with
+ -- regards to extra trees
+ else
+ input.verbose = true
+ input.report("error", "unable to identify own path")
+ os.exit()
end
- local t = instance.treepath:splitchr(',')
- instance.environment['TEXMF'] = input.bare_variable(instance.treepath)
- instance.environment['TEXMFCNF'] = file.join(t[1] or '.','texmf/web2c')
- end
- if instance.rootpath ~= "" then
- -- this assumes a single path, maybe do an expanded split here too
- instance.environment['TEXMFCNF'] = file.join(instance.rootpath,'texmf/web2c')
- instance.environment['SELFAUTOPARENT'] = instance.rootpath
- end
- if input.env(instance,'TEXMFCNF') ~= "" then
+ else
local t = input.split_path(input.env(instance,'TEXMFCNF'))
t = input.aux.expanded_path(instance,t)
input.aux.expand_vars(instance,t)
- for _,v in ipairs(t) do
- table.insert(instance.cnffiles,file.join(v,input.cnfname))
- end
- elseif input.env(instance,'SELFAUTOPARENT') == '.' then
- table.insert(instance.cnffiles,file.join('.',input.cnfname))
- else
- for _,v in ipairs({'texmf-local','texmf'}) do
- table.insert(instance.cnffiles,file.join(input.env(instance,'SELFAUTOPARENT'),v,'web2c',input.cnfname))
+ local function locate(filename,list)
+ for _,v in ipairs(t) do
+ local texmfcnf = input.normalize_name(file.join(v,filename))
+ if lfs.isfile(texmfcnf) then
+ table.insert(list,texmfcnf)
+ end
+ end
end
+ locate(input.luaname,instance.luafiles)
+ locate(input.cnfname,instance.cnffiles)
end
end
end
function input.load_cnf(instance)
+ local function loadoldconfigdata()
+ for _, fname in ipairs(instance.cnffiles) do
+ input.aux.load_cnf(instance,fname)
+ end
+ end
-- instance.cnffiles contain complete names now !
if #instance.cnffiles == 0 then
input.report("no cnf files found (TEXMFCNF may not be set/known)")
else
instance.rootpath = instance.cnffiles[1]
for k,fname in ipairs(instance.cnffiles) do
- instance.cnffiles[k] = fname:gsub("\\",'/') -- needed?
+ instance.cnffiles[k] = input.normalize_name(fname:gsub("\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
+ instance.rootpath = input.normalize_name(instance.rootpath)
+ instance.environment['SELFAUTOPARENT'] = instance.rootpath -- just to be sure
if instance.lsrmode then
- input.loadconfigdata(instance,instance.cnffiles)
+ loadoldconfigdata()
elseif instance.diskcache and not instance.renewcache then
- input.loadconfig(instance,instance.cnffiles)
+ input.loadoldconfig(instance,instance.cnffiles)
if instance.loaderror then
- input.loadconfigdata(instance,instance.cnffiles)
- input.saveconfig(instance)
+ loadoldconfigdata()
+ input.saveoldconfig(instance)
end
else
- input.loadconfigdata(instance,instance.cnffiles)
+ loadoldconfigdata()
if instance.renewcache then
- input.saveconfig(instance)
+ input.saveoldconfig(instance)
end
end
input.aux.collapse_cnf_data(instance)
@@ -401,40 +446,34 @@ function input.load_cnf(instance)
input.checkconfigdata(instance)
end
-function input.loadconfigdata(instance)
- for _, fname in ipairs(instance.cnffiles) do
- input.aux.load_cnf(instance,fname)
+function input.load_lua(instance)
+ if #instance.luafiles == 0 then
+ -- yet harmless
+ else
+ instance.rootpath = instance.luafiles[1]
+ for k,fname in ipairs(instance.luafiles) do
+ instance.luafiles[k] = input.normalize_name(fname:gsub("\\",'/'))
+ end
+ for i=1,3 do
+ instance.rootpath = file.dirname(instance.rootpath)
+ end
+ instance.rootpath = input.normalize_name(instance.rootpath)
+ instance.environment['SELFAUTOPARENT'] = instance.rootpath -- just to be sure
+ input.loadnewconfig(instance)
+ input.aux.collapse_cnf_data(instance)
end
+ input.checkconfigdata(instance)
end
-if os.env then
- function input.aux.collapse_cnf_data(instance)
- for _,c in ipairs(instance.order) do
- for k,v in pairs(c) do
- if not instance.variables[k] then
- if instance.environment[k] then
- instance.variables[k] = instance.environment[k]
- else
- instance.kpsevars[k] = true
- instance.variables[k] = input.bare_variable(v)
- end
- end
- end
- end
- end
-else
- function input.aux.collapse_cnf_data(instance)
- for _,c in ipairs(instance.order) do
- for k,v in pairs(c) do
- if not instance.variables[k] then
- local e = os.getenv(k)
- if e then
- instance.environment[k] = input.bare_variable(e)
- instance.variables[k] = instance.environment[k]
- else
- instance.variables[k] = input.bare_variable(v)
- instance.kpsevars[k] = true
- end
+function input.aux.collapse_cnf_data(instance) -- potential optmization: pass start index (setup and configuration are shared)
+ for _,c in ipairs(instance.order) do
+ for k,v in pairs(c) do
+ if not instance.variables[k] then
+ if instance.environment[k] then
+ instance.variables[k] = instance.environment[k]
+ else
+ instance.kpsevars[k] = true
+ instance.variables[k] = input.bare_variable(v)
end
end
end
@@ -445,11 +484,11 @@ function input.aux.load_cnf(instance,fname)
fname = input.clean_path(fname)
local lname = fname:gsub("%.%a+$",input.luasuffix)
local f = io.open(lname)
- if f then
+ if f then -- this will go
f:close()
local dname = file.dirname(fname)
if not instance.configuration[dname] then
- input.aux.load_data(instance,dname,'configuration',file.basename(lname))
+ input.aux.load_configuration(instance,dname,lname)
instance.order[#instance.order+1] = instance.configuration[dname]
end
else
@@ -464,7 +503,7 @@ function input.aux.load_cnf(instance,fname)
end
local data = instance.configuration[dname]
while true do
- line = f:read()
+ local line, n = f:read(), 0
if line then
while true do -- join lines
line, n = line:gsub("\\%s*$", "")
@@ -475,7 +514,7 @@ function input.aux.load_cnf(instance,fname)
end
end
if not line:find("^[%%#]") then
- k, v = (line:gsub("%s*%%.*$","")):match("%s*(.-)%s*=%s*(.-)%s*$")
+ local k, v = (line:gsub("%s*%%.*$","")):match("%s*(.-)%s*=%s*(.-)%s*$")
if k and v and not data[k] then
data[k] = (v:gsub("[%%#].*",'')):gsub("~", "$HOME")
instance.kpsevars[k] = true
@@ -549,6 +588,7 @@ end
function input.locatelists(instance)
for _, path in pairs(input.simplified_list(input.expansion(instance,'TEXMF'))) do
+ path = file.collapse_path(path)
input.report("locating list of",path)
input.locatedatabase(instance,input.normalize_name(path))
end
@@ -585,7 +625,7 @@ function input.loadfiles(instance)
end
function input.hashers.tex(instance,tag,name)
- input.aux.load_data(instance,tag,'files')
+ input.aux.load_files(instance,tag)
end
-- generators:
@@ -662,7 +702,7 @@ do
end
end
action()
- input.report(string.format("%s files found on %s directories with %s uppercase remappings",n,m,r))
+ input.report(format("%s files found on %s directories with %s uppercase remappings",n,m,r))
else
local fullname = file.join(specification,input.lsrname)
local path = '.'
@@ -715,7 +755,7 @@ end
-- is more convenient.
function input.splitconfig(instance)
- for i,c in ipairs(instance.order) do
+ for i,c in ipairs(instance) do
for k,v in pairs(c) do
if type(v) == 'string' then
local t = file.split_path(v)
@@ -749,14 +789,7 @@ function input.join_path(str)
return str
end
end
---~ function input.splitexpansions(instance)
---~ for k,v in pairs(instance.expansions) do
---~ local t = file.split_path(v)
---~ if #t > 1 then
---~ instance.expansions[k] = t
---~ end
---~ end
---~ end
+
function input.splitexpansions(instance)
for k,v in pairs(instance.expansions) do
local t, h = { }, { }
@@ -776,7 +809,7 @@ end
-- end of split/join code
-function input.saveconfig(instance)
+function input.saveoldconfig(instance)
input.splitconfig(instance)
input.aux.save_data(instance, 'configuration', nil)
input.joinconfig(instance)
@@ -789,44 +822,83 @@ input.configbanner = [[
-- not copyrighted. [HH & TH]
]]
-function input.aux.save_data(instance, dataname, check)
- for cachename, files in pairs(instance[dataname]) do
- local name = file.join(cachename,dataname)
- local luaname, lucname = name .. input.luasuffix, name .. input.lucsuffix
- local f = io.open(luaname,'w')
- if f then
- input.report("saving " .. dataname .. " in", luaname)
- f:write(input.configbanner)
- f:write("\n")
- f:write("if not texmf then texmf = { } end\n")
- f:write("if not texmf.data then texmf.data = { } end\n")
- f:write("\n")
- f:write("texmf.data.type = '" .. dataname .. "'\n")
- f:write("texmf.data.version = '" .. input.cacheversion .. "'\n")
- f:write("texmf.data.date = '" .. os.date("%Y-%m-%d") .. "'\n")
- f:write("texmf.data.time = '" .. os.date("%H:%M:%S") .. "'\n")
- f:write('texmf.data.content = {\n')
- local function dump(k,v)
- if not check or check(v,k) then -- path, name
- if type(v) == 'string' then
- f:write("\t['" .. k .. "'] = '" .. v .. "',\n")
- elseif #v == 1 then
- f:write("\t['" .. k .. "'] = '" .. v[1] .. "',\n")
- else
- f:write("\t['" .. k .. "'] = {'" .. table.concat(v,"','").. "'},\n")
- end
+function input.serialize(files)
+ -- This version is somewhat optimized for the kind of
+ -- tables that we deal with, so it's much faster than
+ -- the generic serializer. This makes sense because
+ -- luatools and mtxtools are called frequently. Okay,
+ -- we pay a small price for properly tabbed tables.
+ local t = { }
+ local concat = table.concat
+ local sorted = table.sortedkeys
+ local function dump(k,v,m)
+ if type(v) == 'string' then
+ return m .. "['" .. k .. "']='" .. v .. "',"
+ elseif #v == 1 then
+ return m .. "['" .. k .. "']='" .. v[1] .. "',"
+ else
+ return m .. "['" .. k .. "']={'" .. concat(v,"','").. "'},"
+ end
+ end
+ t[#t+1] = "return {"
+ if instance.sortdata then
+ for _, k in pairs(sorted(files)) do
+ local fk = files[k]
+ if type(fk) == 'table' then
+ t[#t+1] = "\t['" .. k .. "']={"
+ for _, kk in pairs(sorted(fk)) do
+ t[#t+1] = dump(kk,fk[kk],"\t\t")
end
+ t[#t+1] = "\t},"
+ else
+ t[#t+1] = dump(k,fk,"\t")
end
- if instance.sortdata then
- for _, k in pairs(table.sortedkeys(files)) do
- dump(k,files[k])
+ end
+ else
+ for k, v in pairs(files) do
+ if type(v) == 'table' then
+ t[#t+1] = "\t['" .. k .. "']={"
+ for kk,vv in pairs(v) do
+ t[#t+1] = dump(kk,vv,"\t\t")
end
+ t[#t+1] = "\t},"
else
- for k, v in pairs(files) do
- dump(k,v)
+ t[#t+1] = dump(k,v,"\t")
+ end
+ end
+ end
+ t[#t+1] = "}"
+ return concat(t,"\n")
+end
+
+if not texmf then texmf = {} end -- no longer needed, at least not here
+
+function input.aux.save_data(instance, dataname, check, makename) -- untested without cache overload
+ for cachename, files in pairs(instance[dataname]) do
+ local name = (makename or file.join)(cachename,dataname)
+ local luaname, lucname = name .. input.luasuffix, name .. input.lucsuffix
+ input.report("preparing " .. dataname .. " for", luaname)
+ for k, v in pairs(files) do
+ if not check or check(v,k) then -- path, name
+ if type(v) == "table" and #v == 1 then
+ files[k] = v[1]
end
+ else
+ files[k] = nil -- false
end
- f:write('}\n')
+ end
+ local data = {
+ type = dataname,
+ root = cachename,
+ version = input.cacheversion,
+ date = os.date("%Y-%m-%d"),
+ time = os.date("%H:%M:%S"),
+ content = files,
+ }
+ local f = io.open(luaname,'w')
+ if f then
+ input.report("saving " .. dataname .. " in", luaname)
+ f:write(input.serialize(data))
f:close()
input.report("compiling " .. dataname .. " to", lucname)
if not utils.lua.compile(luaname,lucname) then
@@ -839,49 +911,106 @@ function input.aux.save_data(instance, dataname, check)
end
end
-function input.loadconfig(instance)
- instance.configuration, instance.order, instance.loaderror = { }, { }, false
- if not instance.renewcache then
- for _, cnf in ipairs(instance.cnffiles) do
- local dname = file.dirname(cnf)
- input.aux.load_data(instance,dname,'configuration')
- instance.order[#instance.order+1] = instance.configuration[dname]
- if instance.loaderror then break end
+function input.aux.load_data(instance,pathname,dataname,filename,makename) -- untested without cache overload
+ filename = ((not filename or (filename == "")) and dataname) or filename
+ filename = (makename and makename(dataname,filename)) or file.join(pathname,filename)
+ local blob = loadfile(filename .. input.lucsuffix) or loadfile(filename .. input.luasuffix)
+ if blob then
+ local data = blob()
+ if data and data.content and data.type == dataname and data.version == input.cacheversion then
+ input.report("loading",dataname,"for",pathname,"from",filename)
+ instance[dataname][pathname] = data.content
+ else
+ input.report("skipping",dataname,"for",pathname,"from",filename)
+ instance[dataname][pathname] = { }
+ instance.loaderror = true
end
+ else
+ input.report("skipping",dataname,"for",pathname,"from",filename)
end
- input.joinconfig(instance)
end
-if not texmf then texmf = {} end
-if not texmf.data then texmf.data = {} end
+-- some day i'll use the nested approach, but not yet (actually we even drop
+-- engine/progname support since we have only luatex now)
+--
+-- first texmfcnf.lua files are located, next the cached texmf.cnf files
+--
+-- return {
+-- TEXMFBOGUS = 'effe checken of dit werkt',
+-- }
-function input.aux.load_data(instance,pathname,dataname,filename)
- if not filename or (filename == "") then
- filename = dataname .. input.lucsuffix
- end
- local blob = loadfile(file.join(pathname,filename))
- if not blob then
- filename = dataname .. input.luasuffix
- blob = loadfile(file.join(pathname,filename))
- end
+function input.aux.load_texmfcnf(instance,dataname,pathname)
+ local filename = file.join(pathname,input.luaname)
+ local blob = loadfile(filename)
if blob then
- blob()
- if (texmf.data.type == dataname) and (texmf.data.version == input.cacheversion) and texmf.data.content then
- input.report("loading",dataname,"for",pathname,"from",filename)
- instance[dataname][pathname] = texmf.data.content
+ local data = blob()
+ if data then
+ input.report("loading","configuration file",filename)
+ if true then
+ -- flatten to variable.progname
+ local t = { }
+ for k, v in pairs(data) do -- v = progname
+ if type(v) == "string" then
+ t[k] = v
+ else
+ for kk, vv in pairs(v) do -- vv = variable
+ if type(vv) == "string" then
+ t[vv.."."..v] = kk
+ end
+ end
+ end
+ end
+ instance[dataname][pathname] = t
+ else
+ instance[dataname][pathname] = data
+ end
else
- input.report("skipping",dataname,"for",pathname,"from",filename)
+ input.report("skipping","configuration file",filename)
instance[dataname][pathname] = { }
instance.loaderror = true
end
+ else
+ input.report("skipping","configuration file",filename)
+ end
+end
+
+function input.aux.load_configuration(instance,dname,lname)
+ input.aux.load_data(instance,dname,'configuration',lname and file.basename(lname))
+end
+function input.aux.load_files(instance,tag)
+ input.aux.load_data(instance,tag,'files')
+end
+
+function input.resetconfig(instance)
+ instance.configuration, instance.setup, instance.order, instance.loaderror = { }, { }, { }, false
+end
+
+function input.loadnewconfig(instance)
+ for _, cnf in ipairs(instance.luafiles) do
+ local dname = file.dirname(cnf)
+ input.aux.load_texmfcnf(instance,'setup',dname)
+ instance.order[#instance.order+1] = instance.setup[dname]
+ if instance.loaderror then break end
end
- texmf.data.content = { }
+end
+
+function input.loadoldconfig(instance)
+ if not instance.renewcache then
+ for _, cnf in ipairs(instance.cnffiles) do
+ local dname = file.dirname(cnf)
+ input.aux.load_configuration(instance,dname)
+ instance.order[#instance.order+1] = instance.configuration[dname]
+ if instance.loaderror then break end
+ end
+ end
+ input.joinconfig(instance)
end
function input.expand_variables(instance)
instance.expansions = { }
- if instance.engine ~= "" then instance.environment['engine'] = instance.engine end
- if instance.progname ~= "" then instance.environment['progname'] = instance.engine end
+--~ instance.environment['SELFAUTOPARENT'] = instance.environment['SELFAUTOPARENT'] or instance.rootpath
+ if instance.engine ~= "" then instance.environment['engine'] = instance.engine end
+ if instance.progname ~= "" then instance.environment['progname'] = instance.progname end
for k,v in pairs(instance.environment) do
local a, b = k:match("^(%a+)%_(.*)%s*$")
if a and b then
@@ -972,53 +1101,6 @@ function input.is_expansion(instance,name)
return input.aux.is_entry(instance,instance.expansions,name)
end
-function input.aux.list(instance,list)
- local pat = string.upper(instance.pattern or "","")
- for _,key in pairs(table.sortedkeys(list)) do
- if (instance.pattern=="") or string.find(key:upper(),pat) then
- if instance.kpseonly then
- if instance.kpsevars[key] then
- print(key .. "=" .. input.aux.tabstr(list[key]))
- end
- elseif instance.kpsevars[key] then
- print('K ' .. key .. "=" .. input.aux.tabstr(list[key]))
- else
- print('E ' .. key .. "=" .. input.aux.tabstr(list[key]))
- end
- end
- end
-end
-
-function input.list_variables(instance)
- input.aux.list(instance,instance.variables)
-end
-function input.list_expansions(instance)
- input.aux.list(instance,instance.expansions)
-end
-
-function input.list_configurations(instance)
- for _,key in pairs(table.sortedkeys(instance.kpsevars)) do
- if not instance.pattern or (instance.pattern=="") or key:find(instance.pattern) then
- print(key.."\n")
- for i,c in ipairs(instance.order) do
- local str = c[key]
- if str then
- print("\t" .. i .. "\t\t" .. input.aux.tabstr(str))
- end
- end
- print()
- end
- end
-end
-
-function input.aux.tabstr(str)
- if type(str) == 'table' then
- return table.concat(str," | ")
- else
- return str
- end
-end
-
function input.simplified_list(str)
if type(str) == 'table' then
return str -- troubles ; ipv , in texmf
@@ -1042,23 +1124,6 @@ function input.unexpanded_path(instance,str)
return file.join_path(input.unexpanded_path_list(instance,str))
end
---~ function input.expanded_path_list(instance,str)
---~ if not str then
---~ return { }
---~ elseif instance.savelists then
---~ -- engine+progname hash
---~ str = str:gsub("%$","")
---~ if not instance.lists[str] then -- cached
---~ local lst = input.split_path(input.expansion(instance,str))
---~ instance.lists[str] = input.aux.expanded_path(instance,lst)
---~ end
---~ return instance.lists[str]
---~ else
---~ local lst = input.split_path(input.expansion(instance,str))
---~ return input.aux.expanded_path(instance,lst)
---~ end
---~ end
-
do
local done = { }
@@ -1471,6 +1536,8 @@ do
return original
end
+ input.normalize_name = file.collapse_path
+
end
function input.aux.register_in_trees(instance,name)
@@ -1836,7 +1903,10 @@ end
function input.load(instance)
input.starttiming(instance)
+ input.resetconfig(instance)
input.identify_cnf(instance)
+ input.load_lua(instance)
+ input.expand_variables(instance)
input.load_cnf(instance)
input.expand_variables(instance)
input.load_hash(instance)
diff --git a/tex/context/base/luat-lib.lua b/tex/context/base/luat-lib.lua
index 0b18f3eeb..c3c66f7d8 100644
--- a/tex/context/base/luat-lib.lua
+++ b/tex/context/base/luat-lib.lua
@@ -33,14 +33,32 @@ os.platform = os.platform or os.type or (io.pathseparator == ";" and "windows")
--
-- for k,v in pairs(arg) do print(k,v) end
-if arg and (arg[0] == 'luatex' or arg[0] == 'luatex.exe') and arg[1] == "--luaonly" then
- arg[-1]=arg[0] arg[0]=arg[2] for k=3,#arg do arg[k-2]=arg[k] end arg[#arg]=nil arg[#arg]=nil
-end
-
-- environment
if not environment then environment = { } end
+environment.ownbin = environment.ownbin or arg[-2] or arg[-1] or arg[0] or "luatex"
+
+local ownpath = nil -- we could use a metatable here
+
+function environment.ownpath()
+ if not ownpath then
+ for p in string.gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
+ local b = file.join(p,environment.ownbin)
+ if lfs.isfile(b..".exe") or lfs.isfile(b) then
+ ownpath = p
+ break
+ end
+ end
+ if not ownpath then ownpath = '.' end
+ end
+ return ownpath
+end
+
+if arg and (arg[0] == 'luatex' or arg[0] == 'luatex.exe') and arg[1] == "--luaonly" then
+ arg[-1]=arg[0] arg[0]=arg[2] for k=3,#arg do arg[k-2]=arg[k] end arg[#arg]=nil arg[#arg]=nil
+end
+
environment.arguments = { }
environment.files = { }
environment.sorted_argument_keys = nil
diff --git a/tex/context/base/luat-tex.lua b/tex/context/base/luat-tex.lua
index c241bcf80..c9d99c48a 100644
--- a/tex/context/base/luat-tex.lua
+++ b/tex/context/base/luat-tex.lua
@@ -293,7 +293,6 @@ if texconfig and not texlua then
if not texmf.instance then -- prevent a second loading
-
texmf.instance = input.reset()
texmf.instance.progname = environment.progname or 'context'
texmf.instance.engine = environment.engine or 'luatex'
diff --git a/tex/context/base/luat-tmp.lua b/tex/context/base/luat-tmp.lua
index b4583133f..f3b062353 100644
--- a/tex/context/base/luat-tmp.lua
+++ b/tex/context/base/luat-tmp.lua
@@ -32,28 +32,45 @@ caches.more = caches.more or "context"
caches.direct = false -- true is faster but may need huge amounts of memory
caches.trace = false
caches.tree = false
-caches.temp = caches.temp or os.getenv("TEXMFCACHE") or os.getenv("HOME") or os.getenv("HOMEPATH") or os.getenv("VARTEXMF") or os.getenv("TEXMFVAR") or os.getenv("TMP") or os.getenv("TEMP") or os.getenv("TMPDIR") or nil
-caches.paths = caches.paths or { caches.temp }
+caches.paths = caches.paths or nil
caches.force = false
input.usecache = not toboolean(os.getenv("TEXMFSHARECACHE") or "false",true) -- true
-if caches.temp and caches.temp ~= "" and lfs.attributes(caches.temp,"mode") ~= "directory" then
- if caches.force or io.ask(string.format("Should I create the cache path %s?",caches.temp), "no", { "yes", "no" }) == "yes" then
- dir.mkdirs(caches.temp)
+function caches.temp(instance)
+ local function checkpath(cachepath)
+ if not cachepath or cachepath == "" then
+ return nil
+ elseif lfs.attributes(cachepath,"mode") == "directory" then -- lfs.isdir(cachepath) then
+ return cachepath
+ elseif caches.force or io.ask(string.format("Should I create the cache path %s?",cachepath), "no", { "yes", "no" }) == "yes" then
+ dir.mkdirs(cachepath)
+ return (lfs.attributes(cachepath,"mode") == "directory") and cachepath
+ else
+ return nil
+ end
end
-end
-if not caches.temp or caches.temp == "" then
- print("\nfatal error: there is no valid cache path defined\n")
- os.exit()
-elseif lfs.attributes(caches.temp,"mode") ~= "directory" then
- print(string.format("\nfatal error: cache path %s is not a directory\n",caches.temp))
- os.exit()
+ local cachepath = input.expanded_path_list(instance,"TEXMFCACHE")
+ cachepath = cachepath and #cachepath > 0 and checkpath(cachepath[1])
+ if not cachepath then
+ cachepath = os.getenv("TEXMFCACHE") or os.getenv("HOME") or os.getenv("HOMEPATH") or os.getenv("TMP") or os.getenv("TEMP") or os.getenv("TMPDIR") or nil
+ cachepath = checkpath(cachepath)
+ end
+ if not cachepath then
+ print("\nfatal error: there is no valid cache path defined\n")
+ os.exit()
+ elseif lfs.attributes(cachepath,"mode") ~= "directory" then
+ print(string.format("\nfatal error: cache path %s is not a directory\n",cachepath))
+ os.exit()
+ end
+ function caches.temp(instance)
+ return cachepath
+ end
+ return cachepath
end
function caches.configpath(instance)
return table.concat(instance.cnffiles,";")
---~ return input.expand_var(instance,"TEXMFCNF")
end
function caches.hashed(tree)
@@ -71,19 +88,8 @@ end
function caches.setpath(instance,...)
if not caches.path then
- if lfs and instance then
- for _,v in pairs(caches.paths) do
- for _,vv in pairs(input.expanded_path_list(instance,v)) do
- if lfs.isdir(vv) then
- caches.path = vv
- break
- end
- end
- if caches.path then break end
- end
- end
if not caches.path then
- caches.path = caches.temp
+ caches.path = caches.temp(instance)
end
caches.path = input.clean_path(caches.path) -- to be sure
if lfs then
@@ -107,6 +113,12 @@ function caches.setpath(instance,...)
return caches.path
end
+function caches.definepath(instance,category,subcategory)
+ return function()
+ return caches.setpath(instance,category,subcategory)
+ end
+end
+
function caches.setluanames(path,name)
return path .. "/" .. name .. ".tma", path .. "/" .. name .. ".tmc"
end
@@ -135,9 +147,9 @@ function caches.savedata(filepath,filename,data,raw) -- raw needed for file cach
if caches.direct then
file.savedata(tmaname, table.serialize(data,'return',true,true))
else
- table.tofile (tmaname, data,'return',true,true) -- maybe not the last true
+ table.tofile(tmaname, data,'return',true,true) -- maybe not the last true
end
- utils.lua.compile(tmaname, tmcname)
+ utils.lua.compile(tmaname, tmcname, input.expand_var(texmf.instance,'PURGECACHE') == 't')
end
-- here we use the cache for format loading (texconfig.[formatname|jobname])
@@ -172,19 +184,35 @@ do -- local report
end
end
+ local allocated = { }
+
+ -- tracing
+
function containers.define(category, subcategory, version, enabled)
- if category and subcategory then
- return {
- category = category,
- subcategory = subcategory,
- storage = { },
- enabled = enabled,
- version = version or 1.000,
- trace = false,
- path = caches.setpath(texmf.instance,category,subcategory),
- }
- else
- return nil
+ return function()
+ if category and subcategory then
+ local c = allocated[category]
+ if not c then
+ c = { }
+ allocated[category] = c
+ end
+ local s = c[subcategory]
+ if not s then
+ s = {
+ category = category,
+ subcategory = subcategory,
+ storage = { },
+ enabled = enabled,
+ version = version or 1.000,
+ trace = false,
+ path = caches.setpath(texmf.instance,category,subcategory),
+ }
+ c[subcategory] = s
+ end
+ return s
+ else
+ return nil
+ end
end
end
@@ -241,129 +269,35 @@ end
-- since we want to use the cache instead of the tree, we will now
-- reimplement the saver.
+local save_data = input.aux.save_data
+
+input.cachepath = nil
+
function input.aux.save_data(instance, dataname, check)
- for cachename, files in pairs(instance[dataname]) do
- local name
+ input.cachepath = input.cachepath or caches.definepath(instance,"trees")
+ save_data(instance, dataname, check, function(cachename,dataname)
if input.usecache then
- name = file.join(caches.setpath(instance,"trees"),caches.hashed(cachename))
+ return file.join(input.cachepath(),caches.hashed(cachename))
else
- name = file.join(cachename,dataname)
+ return file.join(cachename,dataname)
end
- local luaname, lucname = name .. input.luasuffix, name .. input.lucsuffix
- input.report("preparing " .. dataname .. " in", luaname)
- for k, v in pairs(files) do
- if not check or check(v,k) then -- path, name
- if type(v) == "table" and #v == 1 then
- files[k] = v[1]
- end
- else
- files[k] = nil -- false
- end
- end
- local data = {
- type = dataname,
- root = cachename,
- version = input.cacheversion,
- date = os.date("%Y-%m-%d"),
- time = os.date("%H:%M:%S"),
- content = files,
- }
- local f = io.open(luaname,'w')
- if f then
- input.report("saving " .. dataname .. " in", luaname)
- -- f:write(table.serialize(data,'return'))
- f:write(input.serialize(data))
- f:close()
- input.report("compiling " .. dataname .. " to", lucname)
- if not utils.lua.compile(luaname,lucname) then
- input.report("compiling failed for " .. dataname .. ", deleting file " .. lucname)
- os.remove(lucname)
- end
- else
- input.report("unable to save " .. dataname .. " in " .. name..input.luasuffix)
- end
- end
+ end)
end
-function input.serialize(files)
- -- This version is somewhat optimized for the kind of
- -- tables that we deal with, so it's much faster than
- -- the generic serializer. This makes sense because
- -- luatools and mtxtools are called frequently. Okay,
- -- we pay a small price for properly tabbed tables.
- local t = { }
- local concat = table.concat
- local sorted = table.sortedkeys
- local function dump(k,v,m)
- if type(v) == 'string' then
- return m .. "['" .. k .. "']='" .. v .. "',"
- elseif #v == 1 then
- return m .. "['" .. k .. "']='" .. v[1] .. "',"
- else
- return m .. "['" .. k .. "']={'" .. concat(v,"','").. "'},"
- end
- end
- t[#t+1] = "return {"
- if instance.sortdata then
- for _, k in pairs(sorted(files)) do
- local fk = files[k]
- if type(fk) == 'table' then
- t[#t+1] = "\t['" .. k .. "']={"
- for _, kk in pairs(sorted(fk)) do
- t[#t+1] = dump(kk,fk[kk],"\t\t")
- end
- t[#t+1] = "\t},"
- else
- t[#t+1] = dump(k,fk,"\t")
- end
- end
- else
- for k, v in pairs(files) do
- if type(v) == 'table' then
- t[#t+1] = "\t['" .. k .. "']={"
- for kk,vv in pairs(v) do
- t[#t+1] = dump(kk,vv,"\t\t")
- end
- t[#t+1] = "\t},"
- else
- t[#t+1] = dump(k,v,"\t")
- end
- end
- end
- t[#t+1] = "}"
- return concat(t,"\n")
-end
+local load_data = input.aux.load_data
function input.aux.load_data(instance,pathname,dataname,filename)
- local luaname, lucname, pname, fname
- if input.usecache then
- pname, fname = caches.setpath(instance,"trees"), caches.hashed(pathname)
- filename = file.join(pname,fname)
- else
- if not filename or (filename == "") then
- filename = dataname
- end
- pname, fname = pathname, filename
- end
- luaname = file.join(pname,fname) .. input.luasuffix
- lucname = file.join(pname,fname) .. input.lucsuffix
- local blob = loadfile(lucname)
- if not blob then
- blob = loadfile(luaname)
- end
- if blob then
- local data = blob()
- if data and data.content and data.type == dataname and data.version == input.cacheversion then
- input.report("loading",dataname,"for",pathname,"from",filename)
- instance[dataname][pathname] = data.content
+ input.cachepath = input.cachepath or caches.definepath(instance,"trees")
+ load_data(instance,pathname,dataname,filename,function(dataname,filename)
+ if input.usecache then
+ return file.join(input.cachepath(),caches.hashed(pathname))
else
- input.report("skipping",dataname,"for",pathname,"from",filename)
- instance[dataname][pathname] = { }
- instance.loaderror = true
+ if not filename or (filename == "") then
+ filename = dataname
+ end
+ return file.join(pathname,filename)
end
- else
- input.report("skipping",dataname,"for",pathname,"from",filename)
- end
+ end)
end
-- we will make a better format, maybe something xml or just text or lua
diff --git a/tex/context/base/lxml-ini.lua b/tex/context/base/lxml-ini.lua
index 2f2a74b38..f6dba95d4 100644
--- a/tex/context/base/lxml-ini.lua
+++ b/tex/context/base/lxml-ini.lua
@@ -15,6 +15,8 @@ local type, next, tonumber = type, next, tonumber
document = document or { }
document.xml = document.xml or { }
+-- todo: loaded and myself per document so that we can garbage collect buffers
+
lxml = { }
lxml.loaded = { }
lxml.myself = { }
@@ -61,7 +63,7 @@ do
-- quit
else
local tr = type(root)
- if tr == "string" then
+ if tr == "string" then -- can also be result of lpath
capture:match(root)
elseif tr == "table" then
serialize(root,sprint,nil,nil,specialhandler)
@@ -99,7 +101,6 @@ do
end
end
-
-- lines (untested)
local buffer = { }
@@ -161,7 +162,7 @@ do
local root = get_id(id)
if before then texsprint(tex.ctxcatcodes,format("%s[%s]",before,root.tg)) end
serialize(root.dt,toverbatim,nil,nil,nil,true) -- was root
- if after then texsprint(tex.ctxcatcodes,after) end
+ if after then texsprint(tex.ctxcatcodes,after) end
end
function lxml.inlineverbatim(id)
lxml.verbatim(id,"\\startxmlinlineverbatim","\\stopxmlinlineverbatim")
@@ -170,6 +171,33 @@ do
lxml.verbatim(id,"\\startxmldisplayverbatim","\\stopxmldisplayverbatim")
end
+ local pihandlers = { }
+
+ specialhandler['@pi@'] = function(str)
+ for i=1,#pihandlers do
+ pihandlers[i](str)
+ end
+ end
+
+ xml.pihandlers = pihandlers
+
+ local kind = lpeg.P("context-") * lpeg.C((1-lpeg.P("-"))^1) * lpeg.P("-directive")
+ local space = lpeg.S(" \n\r")
+ local spaces = space^0
+ local class = lpeg.C((1-space)^0)
+ local key = class
+ local value = lpeg.C(lpeg.P(1-(space * -1))^0)
+
+ local parser = kind * spaces * class * spaces * key * spaces * value
+
+ pihandlers[#pihandlers+1] = function(str)
+ -- local kind, class, key, value = parser:match(str)
+ texsprint(tex.ctxcatcodes,format("\\xmlcontextdirective{%s}{%s}{%s}{%s}",parser:match(str)))
+ end
+
+ -- print(contextdirective("context-mathml-directive function reduction yes yes "))
+ -- print(contextdirective("context-mathml-directive function "))
+
end
local xmlsprint = xml.sprint
@@ -284,8 +312,9 @@ function lxml.count(id,pattern)
end
function lxml.name(id) -- or remapped name? -> lxml.info, combine
local r = get_id(id)
- if r.ns then
- texsprint(r.ns .. ":" .. r.tg)
+ local ns = t.rn or r.ns or ""
+ if ns ~= "" then
+ texsprint(ns .. ":" .. r.tg)
else
texsprint(r.tg)
end
@@ -313,9 +342,9 @@ function lxml.concatrange(id,what,start,stop,separator,lastseparator) -- test th
if i == #t then
-- nothing
elseif i == #t-1 and lastseparator ~= "" then
- tex.sprint(tex.ctxcatcodes,lastseparator)
+ texsprint(tex.ctxcatcodes,lastseparator)
elseif separator ~= "" then
- tex.sprint(tex.ctxcatcodes,separator)
+ texsprint(tex.ctxcatcodes,separator)
end
end
end
@@ -367,7 +396,7 @@ lxml.trace_setups = false
function lxml.setsetup(id,pattern,setup)
local trace = lxml.trace_setups
- if not setup or setup == "" or setup == "*" or setup == "-" then
+ if not setup or setup == "" or setup == "*" or setup == "-" or setup == "+" then
for rt, dt, dk in xmlelements(get_id(id),pattern) do
local dtdk = dt and dt[dk] or rt
local ns, tg = dtdk.rn or dtdk.ns, dtdk.tg
@@ -594,16 +623,29 @@ do
end
function xml.getbuffer(name) -- we need to make sure that commands are processed
+ if not name or name == "" then
+ name = tex.jobname
+ end
xml.tostring(xml.convert(concat(buffers.data[name] or {},"")))
end
function lxml.loadbuffer(id,name)
+ if not name or name == "" then
+ name = tex.jobname
+ end
input.starttiming(xml)
- loaded[id] = xml.convert(concat(buffers.data[name or id] or {},""))
+ loaded[id] = xml.convert(buffers.collect(name or id,"\n"))
input.stoptiming(xml)
return loaded[id], name or id
end
+function lxml.loaddata(id,str)
+ input.starttiming(xml)
+ loaded[id] = xml.convert(str or "")
+ input.stoptiming(xml)
+ return loaded[id], id
+end
+
-- for the moment here:
lxml.set_verbatim("\\xmlcdatabefore", "\\xmlcdataafter", "\\xmlcdataobeyedline", "\\xmlcdataobeyedspace")
diff --git a/tex/context/base/lxml-ini.tex b/tex/context/base/lxml-ini.tex
index 8d01736a1..c6cd60b89 100644
--- a/tex/context/base/lxml-ini.tex
+++ b/tex/context/base/lxml-ini.tex
@@ -42,6 +42,7 @@
\def\xmllast #1#2{\ctxlua{lxml.last("#1","#2")}}
\def\xmlload #1#2{\ctxlua{lxml.load("#1","#2")}}
\def\xmlloadbuffer #1#2{\ctxlua{lxml.loadbuffer("#1","#2")}}
+\def\xmlloaddata #1#2{\ctxlua{lxml.loaddata("#1",\!!bs#2\!!es)}}
\def\xmlloaddirectives #1{\ctxlua{lxml.directives.load("#1")}}
\def\xmlname #1{\ctxlua{lxml.name("#1")}}
\def\xmlnamespace #1{\ctxlua{lxml.namespace("#1")}}
@@ -120,8 +121,10 @@
{\directsetup{#4}}%
\endgroup}
-\def\xmlprocess {\doxmlprocess\xmlload}
+\def\xmlprocessfile {\doxmlprocess\xmlload}
+\def\xmlprocessdata {\doxmlprocess\xmlloaddata}
\def\xmlprocessbuffer{\doxmlprocess\xmlloadbuffer}
+\let\xmlprocess \xmlprocessfile
\startsetups xml:process
\xmlregisteredsetups
@@ -207,7 +210,14 @@
{\ctxlua{xml.set_text_cleanup(lxml.trace_text_entities)}%
\appendtoks\ctxlua{lxml.show_text_entities()}\to\everygoodbye}
+% processing instructions
+
+\def\xmlcontextdirective#1% kind class key value
+ {\executeifdefined{xml#1directive}\gobblethreearguments}
+
% brrrr, give this at the top of a style that needs to stub mkiv loading
+%
+% this will change
\def\processXMLfileMKIV
{\dosingleempty\doprocessXMLfileMKIV}
diff --git a/tex/context/base/math-ent.lua b/tex/context/base/math-ent.lua
new file mode 100644
index 000000000..7cc45b8a2
--- /dev/null
+++ b/tex/context/base/math-ent.lua
@@ -0,0 +1,2097 @@
+if not modules then modules = { } end modules ['math-ent'] = {
+ version = 1.001,
+ comment = "companion to math-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "derived from the mathml 2.0 specification",
+}
+
+math.entities={
+ ["Aacute"]=0x000C1,
+ ["aacute"]=0x000E1,
+ ["Abreve"]=0x00102,
+ ["abreve"]=0x00103,
+ ["ac"]=0x0223E,
+ ["acd"]=0x0223F,
+ ["acE"]=0x0223E,
+ ["Acirc"]=0x000C2,
+ ["acirc"]=0x000E2,
+ ["acute"]=0x000B4,
+ ["Acy"]=0x00410,
+ ["acy"]=0x00430,
+ ["AElig"]=0x000C6,
+ ["aelig"]=0x000E6,
+ ["af"]=0x02061,
+ ["Afr"]=0x1D504,
+ ["afr"]=0x1D51E,
+ ["Agrave"]=0x000C0,
+ ["agrave"]=0x000E0,
+ ["aleph"]=0x02135,
+ ["alpha"]=0x003B1,
+ ["Amacr"]=0x00100,
+ ["amacr"]=0x00101,
+ ["amalg"]=0x02A3F,
+ ["amp"]=0x00026,
+ ["And"]=0x02A53,
+ ["and"]=0x02227,
+ ["andand"]=0x02A55,
+ ["andd"]=0x02A5C,
+ ["andslope"]=0x02A58,
+ ["andv"]=0x02A5A,
+ ["ang"]=0x02220,
+ ["ange"]=0x029A4,
+ ["angle"]=0x02220,
+ ["angmsd"]=0x02221,
+ ["angmsdaa"]=0x029A8,
+ ["angmsdab"]=0x029A9,
+ ["angmsdac"]=0x029AA,
+ ["angmsdad"]=0x029AB,
+ ["angmsdae"]=0x029AC,
+ ["angmsdaf"]=0x029AD,
+ ["angmsdag"]=0x029AE,
+ ["angmsdah"]=0x029AF,
+ ["angrt"]=0x0221F,
+ ["angrtvb"]=0x022BE,
+ ["angrtvbd"]=0x0299D,
+ ["angsph"]=0x02222,
+ ["angst"]=0x0212B,
+ ["angzarr"]=0x0237C,
+ ["Aogon"]=0x00104,
+ ["aogon"]=0x00105,
+ ["Aopf"]=0x1D538,
+ ["aopf"]=0x1D552,
+ ["ap"]=0x02248,
+ ["apacir"]=0x02A6F,
+ ["apE"]=0x02A70,
+ ["ape"]=0x0224A,
+ ["apid"]=0x0224B,
+ ["apos"]=0x00027,
+ ["ApplyFunction"]=0x02061,
+ ["approx"]=0x02248,
+ ["approxeq"]=0x0224A,
+ ["Aring"]=0x000C5,
+ ["aring"]=0x000E5,
+ ["Ascr"]=0x1D49C,
+ ["ascr"]=0x1D4B6,
+ ["Assign"]=0x02254,
+ ["ast"]=0x0002A,
+ ["asymp"]=0x02248,
+ ["asympeq"]=0x0224D,
+ ["Atilde"]=0x000C3,
+ ["atilde"]=0x000E3,
+ ["Auml"]=0x000C4,
+ ["auml"]=0x000E4,
+ ["awconint"]=0x02233,
+ ["awint"]=0x02A11,
+ ["backcong"]=0x0224C,
+ ["backepsilon"]=0x003F6,
+ ["backprime"]=0x02035,
+ ["backsim"]=0x0223D,
+ ["backsimeq"]=0x022CD,
+ ["Backslash"]=0x02216,
+ ["Barv"]=0x02AE7,
+ ["barvee"]=0x022BD,
+ ["Barwed"]=0x02306,
+ ["barwed"]=0x02305,
+ ["barwedge"]=0x02305,
+ ["bbrk"]=0x023B5,
+ ["bbrktbrk"]=0x023B6,
+ ["bcong"]=0x0224C,
+ ["Bcy"]=0x00411,
+ ["bcy"]=0x00431,
+ ["becaus"]=0x02235,
+ ["Because"]=0x02235,
+ ["because"]=0x02235,
+ ["bemptyv"]=0x029B0,
+ ["bepsi"]=0x003F6,
+ ["bernou"]=0x0212C,
+ ["Bernoullis"]=0x0212C,
+ ["beta"]=0x003B2,
+ ["beth"]=0x02136,
+ ["between"]=0x0226C,
+ ["Bfr"]=0x1D505,
+ ["bfr"]=0x1D51F,
+ ["bigcap"]=0x022C2,
+ ["bigcirc"]=0x025EF,
+ ["bigcup"]=0x022C3,
+ ["bigodot"]=0x02A00,
+ ["bigoplus"]=0x02A01,
+ ["bigotimes"]=0x02A02,
+ ["bigsqcup"]=0x02A06,
+ ["bigstar"]=0x02605,
+ ["bigtriangledown"]=0x025BD,
+ ["bigtriangleup"]=0x025B3,
+ ["biguplus"]=0x02A04,
+ ["bigvee"]=0x022C1,
+ ["bigwedge"]=0x022C0,
+ ["bkarow"]=0x0290D,
+ ["blacklozenge"]=0x029EB,
+ ["blacksquare"]=0x025AA,
+ ["blacktriangle"]=0x025B4,
+ ["blacktriangledown"]=0x025BE,
+ ["blacktriangleleft"]=0x025C2,
+ ["blacktriangleright"]=0x025B8,
+ ["blank"]=0x02423,
+ ["blk12"]=0x02592,
+ ["blk14"]=0x02591,
+ ["blk34"]=0x02593,
+ ["block"]=0x02588,
+ ["bne"]=0x0003D,
+ ["bnequiv"]=0x02261,
+ ["bNot"]=0x02AED,
+ ["bnot"]=0x02310,
+ ["Bopf"]=0x1D539,
+ ["bopf"]=0x1D553,
+ ["bot"]=0x022A5,
+ ["bottom"]=0x022A5,
+ ["bowtie"]=0x022C8,
+ ["boxbox"]=0x029C9,
+ ["boxDL"]=0x02557,
+ ["boxDl"]=0x02556,
+ ["boxdL"]=0x02555,
+ ["boxdl"]=0x02510,
+ ["boxDR"]=0x02554,
+ ["boxDr"]=0x02553,
+ ["boxdR"]=0x02552,
+ ["boxdr"]=0x0250C,
+ ["boxH"]=0x02550,
+ ["boxh"]=0x02500,
+ ["boxHD"]=0x02566,
+ ["boxHd"]=0x02564,
+ ["boxhD"]=0x02565,
+ ["boxhd"]=0x0252C,
+ ["boxHU"]=0x02569,
+ ["boxHu"]=0x02567,
+ ["boxhU"]=0x02568,
+ ["boxhu"]=0x02534,
+ ["boxminus"]=0x0229F,
+ ["boxplus"]=0x0229E,
+ ["boxtimes"]=0x022A0,
+ ["boxUL"]=0x0255D,
+ ["boxUl"]=0x0255C,
+ ["boxuL"]=0x0255B,
+ ["boxul"]=0x02518,
+ ["boxUR"]=0x0255A,
+ ["boxUr"]=0x02559,
+ ["boxuR"]=0x02558,
+ ["boxur"]=0x02514,
+ ["boxV"]=0x02551,
+ ["boxv"]=0x02502,
+ ["boxVH"]=0x0256C,
+ ["boxVh"]=0x0256B,
+ ["boxvH"]=0x0256A,
+ ["boxvh"]=0x0253C,
+ ["boxVL"]=0x02563,
+ ["boxVl"]=0x02562,
+ ["boxvL"]=0x02561,
+ ["boxvl"]=0x02524,
+ ["boxVR"]=0x02560,
+ ["boxVr"]=0x0255F,
+ ["boxvR"]=0x0255E,
+ ["boxvr"]=0x0251C,
+ ["bprime"]=0x02035,
+ ["Breve"]=0x002D8,
+ ["breve"]=0x002D8,
+ ["brvbar"]=0x000A6,
+ ["Bscr"]=0x0212C,
+ ["bscr"]=0x1D4B7,
+ ["bsemi"]=0x0204F,
+ ["bsim"]=0x0223D,
+ ["bsime"]=0x022CD,
+ ["bsol"]=0x0005C,
+ ["bsolb"]=0x029C5,
+ ["bsolhsub"]=0x0005C,
+ ["bull"]=0x02022,
+ ["bullet"]=0x02022,
+ ["bump"]=0x0224E,
+ ["bumpE"]=0x02AAE,
+ ["bumpe"]=0x0224F,
+ ["Bumpeq"]=0x0224E,
+ ["bumpeq"]=0x0224F,
+ ["Cacute"]=0x00106,
+ ["cacute"]=0x00107,
+ ["Cap"]=0x022D2,
+ ["cap"]=0x02229,
+ ["capand"]=0x02A44,
+ ["capbrcup"]=0x02A49,
+ ["capcap"]=0x02A4B,
+ ["capcup"]=0x02A47,
+ ["capdot"]=0x02A40,
+ ["CapitalDifferentialD"]=0x02145,
+ ["caps"]=0x02229,
+ ["caret"]=0x02041,
+ ["caron"]=0x002C7,
+ ["Cayleys"]=0x0212D,
+ ["ccaps"]=0x02A4D,
+ ["Ccaron"]=0x0010C,
+ ["ccaron"]=0x0010D,
+ ["Ccedil"]=0x000C7,
+ ["ccedil"]=0x000E7,
+ ["Ccirc"]=0x00108,
+ ["ccirc"]=0x00109,
+ ["Cconint"]=0x02230,
+ ["ccups"]=0x02A4C,
+ ["ccupssm"]=0x02A50,
+ ["Cdot"]=0x0010A,
+ ["cdot"]=0x0010B,
+ ["cedil"]=0x000B8,
+ ["Cedilla"]=0x000B8,
+ ["cemptyv"]=0x029B2,
+ ["cent"]=0x000A2,
+ ["CenterDot"]=0x000B7,
+ ["centerdot"]=0x000B7,
+ ["Cfr"]=0x0212D,
+ ["cfr"]=0x1D520,
+ ["CHcy"]=0x00427,
+ ["chcy"]=0x00447,
+ ["check"]=0x02713,
+ ["checkmark"]=0x02713,
+ ["chi"]=0x003C7,
+ ["cir"]=0x025CB,
+ ["circ"]=0x002C6,
+ ["circeq"]=0x02257,
+ ["circlearrowleft"]=0x021BA,
+ ["circlearrowright"]=0x021BB,
+ ["circledast"]=0x0229B,
+ ["circledcirc"]=0x0229A,
+ ["circleddash"]=0x0229D,
+ ["CircleDot"]=0x02299,
+ ["circledR"]=0x000AE,
+ ["circledS"]=0x024C8,
+ ["CircleMinus"]=0x02296,
+ ["CirclePlus"]=0x02295,
+ ["CircleTimes"]=0x02297,
+ ["cirE"]=0x029C3,
+ ["cire"]=0x02257,
+ ["cirfnint"]=0x02A10,
+ ["cirmid"]=0x02AEF,
+ ["cirscir"]=0x029C2,
+ ["ClockwiseContourIntegral"]=0x02232,
+ ["CloseCurlyDoubleQuote"]=0x0201D,
+ ["CloseCurlyQuote"]=0x02019,
+ ["clubs"]=0x02663,
+ ["clubsuit"]=0x02663,
+ ["Colon"]=0x02237,
+ ["colon"]=0x0003A,
+ ["Colone"]=0x02A74,
+ ["colone"]=0x02254,
+ ["coloneq"]=0x02254,
+ ["comma"]=0x0002C,
+ ["commat"]=0x00040,
+ ["comp"]=0x02201,
+ ["compfn"]=0x02218,
+ ["complement"]=0x02201,
+ ["complexes"]=0x02102,
+ ["cong"]=0x02245,
+ ["congdot"]=0x02A6D,
+ ["Congruent"]=0x02261,
+ ["Conint"]=0x0222F,
+ ["conint"]=0x0222E,
+ ["ContourIntegral"]=0x0222E,
+ ["Copf"]=0x02102,
+ ["copf"]=0x1D554,
+ ["coprod"]=0x02210,
+ ["Coproduct"]=0x02210,
+ ["copy"]=0x000A9,
+ ["copysr"]=0x02117,
+ ["CounterClockwiseContourIntegral"]=0x02233,
+ ["Cross"]=0x02A2F,
+ ["cross"]=0x02717,
+ ["Cscr"]=0x1D49E,
+ ["cscr"]=0x1D4B8,
+ ["csub"]=0x02ACF,
+ ["csube"]=0x02AD1,
+ ["csup"]=0x02AD0,
+ ["csupe"]=0x02AD2,
+ ["ctdot"]=0x022EF,
+ ["cudarrl"]=0x02938,
+ ["cudarrr"]=0x02935,
+ ["cuepr"]=0x022DE,
+ ["cuesc"]=0x022DF,
+ ["cularr"]=0x021B6,
+ ["cularrp"]=0x0293D,
+ ["Cup"]=0x022D3,
+ ["cup"]=0x0222A,
+ ["cupbrcap"]=0x02A48,
+ ["CupCap"]=0x0224D,
+ ["cupcap"]=0x02A46,
+ ["cupcup"]=0x02A4A,
+ ["cupdot"]=0x0228D,
+ ["cupor"]=0x02A45,
+ ["cups"]=0x0222A,
+ ["curarr"]=0x021B7,
+ ["curarrm"]=0x0293C,
+ ["curlyeqprec"]=0x022DE,
+ ["curlyeqsucc"]=0x022DF,
+ ["curlyvee"]=0x022CE,
+ ["curlywedge"]=0x022CF,
+ ["curren"]=0x000A4,
+ ["curvearrowleft"]=0x021B6,
+ ["curvearrowright"]=0x021B7,
+ ["cuvee"]=0x022CE,
+ ["cuwed"]=0x022CF,
+ ["cwconint"]=0x02232,
+ ["cwint"]=0x02231,
+ ["cylcty"]=0x0232D,
+ ["Dagger"]=0x02021,
+ ["Dagger"]=0x02021,
+ ["dagger"]=0x02020,
+ ["dagger"]=0x02020,
+ ["daleth"]=0x02138,
+ ["Darr"]=0x021A1,
+ ["dArr"]=0x021D3,
+ ["darr"]=0x02193,
+ ["dash"]=0x02010,
+ ["Dashv"]=0x02AE4,
+ ["dashv"]=0x022A3,
+ ["dbkarow"]=0x0290F,
+ ["dblac"]=0x002DD,
+ ["Dcaron"]=0x0010E,
+ ["dcaron"]=0x0010F,
+ ["Dcy"]=0x00414,
+ ["dcy"]=0x00434,
+ ["DD"]=0x02145,
+ ["dd"]=0x02146,
+ ["ddagger"]=0x02021,
+ ["ddarr"]=0x021CA,
+ ["DDotrahd"]=0x02911,
+ ["ddotseq"]=0x02A77,
+ ["deg"]=0x000B0,
+ ["Del"]=0x02207,
+ ["Delta"]=0x00394,
+ ["delta"]=0x003B4,
+ ["demptyv"]=0x029B1,
+ ["dfisht"]=0x0297F,
+ ["Dfr"]=0x1D507,
+ ["dfr"]=0x1D521,
+ ["dHar"]=0x02965,
+ ["dharl"]=0x021C3,
+ ["dharr"]=0x021C2,
+ ["DiacriticalAcute"]=0x000B4,
+ ["DiacriticalDot"]=0x002D9,
+ ["DiacriticalDoubleAcute"]=0x002DD,
+ ["DiacriticalGrave"]=0x00060,
+ ["DiacriticalTilde"]=0x002DC,
+ ["diam"]=0x022C4,
+ ["Diamond"]=0x022C4,
+ ["diamond"]=0x022C4,
+ ["diamondsuit"]=0x02666,
+ ["diams"]=0x02666,
+ ["die"]=0x000A8,
+ ["DifferentialD"]=0x02146,
+ ["digamma"]=0x003DD,
+ ["disin"]=0x022F2,
+ ["div"]=0x000F7,
+ ["divide"]=0x000F7,
+ ["divideontimes"]=0x022C7,
+ ["divonx"]=0x022C7,
+ ["DJcy"]=0x00402,
+ ["djcy"]=0x00452,
+ ["dlcorn"]=0x0231E,
+ ["dlcrop"]=0x0230D,
+ ["dollar"]=0x00024,
+ ["Dopf"]=0x1D53B,
+ ["dopf"]=0x1D555,
+ ["Dot"]=0x000A8,
+ ["dot"]=0x002D9,
+ ["DotDot"]=0x020DC,
+ ["doteq"]=0x02250,
+ ["doteqdot"]=0x02251,
+ ["DotEqual"]=0x02250,
+ ["dotminus"]=0x02238,
+ ["dotplus"]=0x02214,
+ ["dotsquare"]=0x022A1,
+ ["doublebarwedge"]=0x02306,
+ ["DoubleContourIntegral"]=0x0222F,
+ ["DoubleDot"]=0x000A8,
+ ["DoubleDownArrow"]=0x021D3,
+ ["DoubleLeftArrow"]=0x021D0,
+ ["DoubleLeftRightArrow"]=0x021D4,
+ ["DoubleLeftTee"]=0x02AE4,
+ ["DoubleLongLeftArrow"]=0x027F8,
+ ["DoubleLongLeftRightArrow"]=0x027FA,
+ ["DoubleLongRightArrow"]=0x027F9,
+ ["DoubleRightArrow"]=0x021D2,
+ ["DoubleRightTee"]=0x022A8,
+ ["DoubleUpArrow"]=0x021D1,
+ ["DoubleUpDownArrow"]=0x021D5,
+ ["DoubleVerticalBar"]=0x02225,
+ ["DownArrow"]=0x02193,
+ ["Downarrow"]=0x021D3,
+ ["downarrow"]=0x02193,
+ ["DownArrowBar"]=0x02913,
+ ["DownArrowUpArrow"]=0x021F5,
+ ["DownBreve"]=0x00311,
+ ["downdownarrows"]=0x021CA,
+ ["downharpoonleft"]=0x021C3,
+ ["downharpoonright"]=0x021C2,
+ ["DownLeftRightVector"]=0x02950,
+ ["DownLeftTeeVector"]=0x0295E,
+ ["DownLeftVector"]=0x021BD,
+ ["DownLeftVectorBar"]=0x02956,
+ ["DownRightTeeVector"]=0x0295F,
+ ["DownRightVector"]=0x021C1,
+ ["DownRightVectorBar"]=0x02957,
+ ["DownTee"]=0x022A4,
+ ["DownTeeArrow"]=0x021A7,
+ ["drbkarow"]=0x02910,
+ ["drcorn"]=0x0231F,
+ ["drcrop"]=0x0230C,
+ ["Dscr"]=0x1D49F,
+ ["dscr"]=0x1D4B9,
+ ["DScy"]=0x00405,
+ ["dscy"]=0x00455,
+ ["dsol"]=0x029F6,
+ ["Dstrok"]=0x00110,
+ ["dstrok"]=0x00111,
+ ["dtdot"]=0x022F1,
+ ["dtri"]=0x025BF,
+ ["dtrif"]=0x025BE,
+ ["duarr"]=0x021F5,
+ ["duhar"]=0x0296F,
+ ["dwangle"]=0x029A6,
+ ["DZcy"]=0x0040F,
+ ["dzcy"]=0x0045F,
+ ["dzigrarr"]=0x027FF,
+ ["Eacute"]=0x000C9,
+ ["eacute"]=0x000E9,
+ ["easter"]=0x02A6E,
+ ["Ecaron"]=0x0011A,
+ ["ecaron"]=0x0011B,
+ ["ecir"]=0x02256,
+ ["Ecirc"]=0x000CA,
+ ["ecirc"]=0x000EA,
+ ["ecolon"]=0x02255,
+ ["Ecy"]=0x0042D,
+ ["ecy"]=0x0044D,
+ ["eDDot"]=0x02A77,
+ ["Edot"]=0x00116,
+ ["eDot"]=0x02251,
+ ["edot"]=0x00117,
+ ["ee"]=0x02147,
+ ["efDot"]=0x02252,
+ ["Efr"]=0x1D508,
+ ["efr"]=0x1D522,
+ ["eg"]=0x02A9A,
+ ["Egrave"]=0x000C8,
+ ["egrave"]=0x000E8,
+ ["egs"]=0x02A96,
+ ["egsdot"]=0x02A98,
+ ["el"]=0x02A99,
+ ["Element"]=0x02208,
+ ["elinters"]=0x0FFFD,
+ ["ell"]=0x02113,
+ ["els"]=0x02A95,
+ ["elsdot"]=0x02A97,
+ ["Emacr"]=0x00112,
+ ["emacr"]=0x00113,
+ ["empty"]=0x02205,
+ ["emptyset"]=0x02205,
+ ["EmptySmallSquare"]=0x025FB,
+ ["emptyv"]=0x02205,
+ ["EmptyVerySmallSquare"]=0x025AB,
+ ["emsp"]=0x02003,
+ ["emsp13"]=0x02004,
+ ["emsp14"]=0x02005,
+ ["ENG"]=0x0014A,
+ ["eng"]=0x0014B,
+ ["ensp"]=0x02002,
+ ["Eogon"]=0x00118,
+ ["eogon"]=0x00119,
+ ["Eopf"]=0x1D53C,
+ ["eopf"]=0x1D556,
+ ["epar"]=0x022D5,
+ ["eparsl"]=0x029E3,
+ ["eplus"]=0x02A71,
+ ["epsi"]=0x003F5,
+ ["epsiv"]=0x003B5,
+ ["eqcirc"]=0x02256,
+ ["eqcolon"]=0x02255,
+ ["eqsim"]=0x02242,
+ ["eqslantgtr"]=0x02A96,
+ ["eqslantless"]=0x02A95,
+ ["Equal"]=0x02A75,
+ ["equals"]=0x0003D,
+ ["EqualTilde"]=0x02242,
+ ["equest"]=0x0225F,
+ ["Equilibrium"]=0x021CC,
+ ["equiv"]=0x02261,
+ ["equivDD"]=0x02A78,
+ ["eqvparsl"]=0x029E5,
+ ["erarr"]=0x02971,
+ ["erDot"]=0x02253,
+ ["Escr"]=0x02130,
+ ["escr"]=0x0212F,
+ ["esdot"]=0x02250,
+ ["Esim"]=0x02A73,
+ ["esim"]=0x02242,
+ ["eta"]=0x003B7,
+ ["ETH"]=0x000D0,
+ ["eth"]=0x000F0,
+ ["Euml"]=0x000CB,
+ ["euml"]=0x000EB,
+ ["excl"]=0x00021,
+ ["exist"]=0x02203,
+ ["Exists"]=0x02203,
+ ["expectation"]=0x02130,
+ ["ExponentialE"]=0x02147,
+ ["exponentiale"]=0x02147,
+ ["fallingdotseq"]=0x02252,
+ ["Fcy"]=0x00424,
+ ["fcy"]=0x00444,
+ ["female"]=0x02640,
+ ["ffilig"]=0x0FB03,
+ ["fflig"]=0x0FB00,
+ ["ffllig"]=0x0FB04,
+ ["Ffr"]=0x1D509,
+ ["ffr"]=0x1D523,
+ ["filig"]=0x0FB01,
+ ["FilledSmallSquare"]=0x025FC,
+ ["FilledVerySmallSquare"]=0x025AA,
+ ["flat"]=0x0266D,
+ ["fllig"]=0x0FB02,
+ ["fltns"]=0x025B1,
+ ["fnof"]=0x00192,
+ ["Fopf"]=0x1D53D,
+ ["fopf"]=0x1D557,
+ ["ForAll"]=0x02200,
+ ["forall"]=0x02200,
+ ["fork"]=0x022D4,
+ ["forkv"]=0x02AD9,
+ ["Fouriertrf"]=0x02131,
+ ["fpartint"]=0x02A0D,
+ ["frac12"]=0x000BD,
+ ["frac13"]=0x02153,
+ ["frac14"]=0x000BC,
+ ["frac15"]=0x02155,
+ ["frac16"]=0x02159,
+ ["frac18"]=0x0215B,
+ ["frac23"]=0x02154,
+ ["frac25"]=0x02156,
+ ["frac34"]=0x000BE,
+ ["frac35"]=0x02157,
+ ["frac38"]=0x0215C,
+ ["frac45"]=0x02158,
+ ["frac56"]=0x0215A,
+ ["frac58"]=0x0215D,
+ ["frac78"]=0x0215E,
+ ["frown"]=0x02322,
+ ["Fscr"]=0x02131,
+ ["fscr"]=0x1D4BB,
+ ["gacute"]=0x001F5,
+ ["Gamma"]=0x00393,
+ ["gamma"]=0x003B3,
+ ["Gammad"]=0x003DC,
+ ["gammad"]=0x003DD,
+ ["gap"]=0x02A86,
+ ["Gbreve"]=0x0011E,
+ ["gbreve"]=0x0011F,
+ ["Gcedil"]=0x00122,
+ ["Gcirc"]=0x0011C,
+ ["gcirc"]=0x0011D,
+ ["Gcy"]=0x00413,
+ ["gcy"]=0x00433,
+ ["Gdot"]=0x00120,
+ ["gdot"]=0x00121,
+ ["gE"]=0x02267,
+ ["ge"]=0x02265,
+ ["gEl"]=0x02A8C,
+ ["gel"]=0x022DB,
+ ["geq"]=0x02265,
+ ["geqq"]=0x02267,
+ ["geqslant"]=0x02A7E,
+ ["ges"]=0x02A7E,
+ ["gescc"]=0x02AA9,
+ ["gesdot"]=0x02A80,
+ ["gesdoto"]=0x02A82,
+ ["gesdotol"]=0x02A84,
+ ["gesl"]=0x022DB,
+ ["gesles"]=0x02A94,
+ ["Gfr"]=0x1D50A,
+ ["gfr"]=0x1D524,
+ ["Gg"]=0x022D9,
+ ["gg"]=0x0226B,
+ ["ggg"]=0x022D9,
+ ["gimel"]=0x02137,
+ ["GJcy"]=0x00403,
+ ["gjcy"]=0x00453,
+ ["gl"]=0x02277,
+ ["gla"]=0x02AA5,
+ ["glE"]=0x02A92,
+ ["glj"]=0x02AA4,
+ ["gnap"]=0x02A8A,
+ ["gnapprox"]=0x02A8A,
+ ["gnE"]=0x02269,
+ ["gne"]=0x02A88,
+ ["gneq"]=0x02A88,
+ ["gneqq"]=0x02269,
+ ["gnsim"]=0x022E7,
+ ["Gopf"]=0x1D53E,
+ ["gopf"]=0x1D558,
+ ["grave"]=0x00060,
+ ["GreaterEqual"]=0x02265,
+ ["GreaterEqualLess"]=0x022DB,
+ ["GreaterFullEqual"]=0x02267,
+ ["GreaterGreater"]=0x02AA2,
+ ["GreaterLess"]=0x02277,
+ ["GreaterSlantEqual"]=0x02A7E,
+ ["GreaterTilde"]=0x02273,
+ ["Gscr"]=0x1D4A2,
+ ["gscr"]=0x0210A,
+ ["gsim"]=0x02273,
+ ["gsime"]=0x02A8E,
+ ["gsiml"]=0x02A90,
+ ["Gt"]=0x0226B,
+ ["gt"]=0x0003E,
+ ["gtcc"]=0x02AA7,
+ ["gtcir"]=0x02A7A,
+ ["gtdot"]=0x022D7,
+ ["gtlPar"]=0x02995,
+ ["gtquest"]=0x02A7C,
+ ["gtrapprox"]=0x02A86,
+ ["gtrarr"]=0x02978,
+ ["gtrdot"]=0x022D7,
+ ["gtreqless"]=0x022DB,
+ ["gtreqqless"]=0x02A8C,
+ ["gtrless"]=0x02277,
+ ["gtrsim"]=0x02273,
+ ["gvertneqq"]=0x02269,
+ ["gvnE"]=0x02269,
+ ["Hacek"]=0x002C7,
+ ["hairsp"]=0x0200A,
+ ["half"]=0x000BD,
+ ["hamilt"]=0x0210B,
+ ["HARDcy"]=0x0042A,
+ ["hardcy"]=0x0044A,
+ ["hArr"]=0x021D4,
+ ["harr"]=0x02194,
+ ["harrcir"]=0x02948,
+ ["harrw"]=0x021AD,
+ ["Hat"]=0x0005E,
+ ["hbar"]=0x0210F,
+ ["Hcirc"]=0x00124,
+ ["hcirc"]=0x00125,
+ ["hearts"]=0x02665,
+ ["heartsuit"]=0x02665,
+ ["hellip"]=0x02026,
+ ["hercon"]=0x022B9,
+ ["Hfr"]=0x0210C,
+ ["hfr"]=0x1D525,
+ ["HilbertSpace"]=0x0210B,
+ ["hksearow"]=0x02925,
+ ["hkswarow"]=0x02926,
+ ["hoarr"]=0x021FF,
+ ["homtht"]=0x0223B,
+ ["hookleftarrow"]=0x021A9,
+ ["hookrightarrow"]=0x021AA,
+ ["Hopf"]=0x0210D,
+ ["hopf"]=0x1D559,
+ ["horbar"]=0x02015,
+ ["HorizontalLine"]=0x02500,
+ ["Hscr"]=0x0210B,
+ ["hscr"]=0x1D4BD,
+ ["hslash"]=0x0210F,
+ ["Hstrok"]=0x00126,
+ ["hstrok"]=0x00127,
+ ["HumpDownHump"]=0x0224E,
+ ["HumpEqual"]=0x0224F,
+ ["hybull"]=0x02043,
+ ["hyphen"]=0x02010,
+ ["Iacute"]=0x000CD,
+ ["iacute"]=0x000ED,
+ ["ic"]=0x02063,
+ ["Icirc"]=0x000CE,
+ ["icirc"]=0x000EE,
+ ["Icy"]=0x00418,
+ ["icy"]=0x00438,
+ ["Idot"]=0x00130,
+ ["IEcy"]=0x00415,
+ ["iecy"]=0x00435,
+ ["iexcl"]=0x000A1,
+ ["iff"]=0x021D4,
+ ["Ifr"]=0x02111,
+ ["ifr"]=0x1D526,
+ ["Igrave"]=0x000CC,
+ ["igrave"]=0x000EC,
+ ["ii"]=0x02148,
+ ["iiiint"]=0x02A0C,
+ ["iiint"]=0x0222D,
+ ["iinfin"]=0x029DC,
+ ["iiota"]=0x02129,
+ ["IJlig"]=0x00132,
+ ["ijlig"]=0x00133,
+ ["Im"]=0x02111,
+ ["Imacr"]=0x0012A,
+ ["imacr"]=0x0012B,
+ ["image"]=0x02111,
+ ["ImaginaryI"]=0x02148,
+ ["imagline"]=0x02110,
+ ["imagpart"]=0x02111,
+ ["imath"]=0x00131,
+ ["imof"]=0x022B7,
+ ["imped"]=0x001B5,
+ ["Implies"]=0x021D2,
+ ["in"]=0x02208,
+ ["incare"]=0x02105,
+ ["infin"]=0x0221E,
+ ["infintie"]=0x029DD,
+ ["inodot"]=0x00131,
+ ["Int"]=0x0222C,
+ ["int"]=0x0222B,
+ ["intcal"]=0x022BA,
+ ["integers"]=0x02124,
+ ["Integral"]=0x0222B,
+ ["intercal"]=0x022BA,
+ ["Intersection"]=0x022C2,
+ ["intlarhk"]=0x02A17,
+ ["intprod"]=0x02A3C,
+ ["InvisibleComma"]=0x02063,
+ ["InvisibleTimes"]=0x02062,
+ ["IOcy"]=0x00401,
+ ["iocy"]=0x00451,
+ ["Iogon"]=0x0012E,
+ ["iogon"]=0x0012F,
+ ["Iopf"]=0x1D540,
+ ["iopf"]=0x1D55A,
+ ["iota"]=0x003B9,
+ ["iprod"]=0x02A3C,
+ ["iquest"]=0x000BF,
+ ["Iscr"]=0x02110,
+ ["iscr"]=0x1D4BE,
+ ["isin"]=0x02208,
+ ["isindot"]=0x022F5,
+ ["isinE"]=0x022F9,
+ ["isins"]=0x022F4,
+ ["isinsv"]=0x022F3,
+ ["isinv"]=0x02208,
+ ["it"]=0x02062,
+ ["Itilde"]=0x00128,
+ ["itilde"]=0x00129,
+ ["Iukcy"]=0x00406,
+ ["iukcy"]=0x00456,
+ ["Iuml"]=0x000CF,
+ ["iuml"]=0x000EF,
+ ["Jcirc"]=0x00134,
+ ["jcirc"]=0x00135,
+ ["Jcy"]=0x00419,
+ ["jcy"]=0x00439,
+ ["Jfr"]=0x1D50D,
+ ["jfr"]=0x1D527,
+ ["jmath"]=0x0006A,
+ ["Jopf"]=0x1D541,
+ ["jopf"]=0x1D55B,
+ ["Jscr"]=0x1D4A5,
+ ["jscr"]=0x1D4BF,
+ ["Jsercy"]=0x00408,
+ ["jsercy"]=0x00458,
+ ["Jukcy"]=0x00404,
+ ["jukcy"]=0x00454,
+ ["kappa"]=0x003BA,
+ ["kappav"]=0x003F0,
+ ["Kcedil"]=0x00136,
+ ["kcedil"]=0x00137,
+ ["Kcy"]=0x0041A,
+ ["kcy"]=0x0043A,
+ ["Kfr"]=0x1D50E,
+ ["kfr"]=0x1D528,
+ ["kgreen"]=0x00138,
+ ["KHcy"]=0x00425,
+ ["khcy"]=0x00445,
+ ["KJcy"]=0x0040C,
+ ["kjcy"]=0x0045C,
+ ["Kopf"]=0x1D542,
+ ["kopf"]=0x1D55C,
+ ["Kscr"]=0x1D4A6,
+ ["kscr"]=0x1D4C0,
+ ["lAarr"]=0x021DA,
+ ["Lacute"]=0x00139,
+ ["lacute"]=0x0013A,
+ ["laemptyv"]=0x029B4,
+ ["lagran"]=0x02112,
+ ["Lambda"]=0x0039B,
+ ["lambda"]=0x003BB,
+ ["Lang"]=0x0300A,
+ ["lang"]=0x02329,
+ ["langd"]=0x02991,
+ ["langle"]=0x02329,
+ ["lap"]=0x02A85,
+ ["Laplacetrf"]=0x02112,
+ ["laquo"]=0x000AB,
+ ["Larr"]=0x0219E,
+ ["lArr"]=0x021D0,
+ ["larr"]=0x02190,
+ ["larrb"]=0x021E4,
+ ["larrbfs"]=0x0291F,
+ ["larrfs"]=0x0291D,
+ ["larrhk"]=0x021A9,
+ ["larrlp"]=0x021AB,
+ ["larrpl"]=0x02939,
+ ["larrsim"]=0x02973,
+ ["larrtl"]=0x021A2,
+ ["lat"]=0x02AAB,
+ ["lAtail"]=0x0291B,
+ ["latail"]=0x02919,
+ ["late"]=0x02AAD,
+ ["lates"]=0x02AAD,
+ ["lBarr"]=0x0290E,
+ ["lbarr"]=0x0290C,
+ ["lbbrk"]=0x03014,
+ ["lbrace"]=0x0007B,
+ ["lbrack"]=0x0005B,
+ ["lbrke"]=0x0298B,
+ ["lbrksld"]=0x0298F,
+ ["lbrkslu"]=0x0298D,
+ ["Lcaron"]=0x0013D,
+ ["lcaron"]=0x0013E,
+ ["Lcedil"]=0x0013B,
+ ["lcedil"]=0x0013C,
+ ["lceil"]=0x02308,
+ ["lcub"]=0x0007B,
+ ["Lcy"]=0x0041B,
+ ["lcy"]=0x0043B,
+ ["ldca"]=0x02936,
+ ["ldquo"]=0x0201C,
+ ["ldquor"]=0x0201E,
+ ["ldrdhar"]=0x02967,
+ ["ldrushar"]=0x0294B,
+ ["ldsh"]=0x021B2,
+ ["lE"]=0x02266,
+ ["le"]=0x02264,
+ ["LeftAngleBracket"]=0x02329,
+ ["LeftArrow"]=0x02190,
+ ["Leftarrow"]=0x021D0,
+ ["leftarrow"]=0x02190,
+ ["LeftArrowBar"]=0x021E4,
+ ["LeftArrowRightArrow"]=0x021C6,
+ ["leftarrowtail"]=0x021A2,
+ ["LeftCeiling"]=0x02308,
+ ["LeftDoubleBracket"]=0x0301A,
+ ["LeftDownTeeVector"]=0x02961,
+ ["LeftDownVector"]=0x021C3,
+ ["LeftDownVectorBar"]=0x02959,
+ ["LeftFloor"]=0x0230A,
+ ["leftharpoondown"]=0x021BD,
+ ["leftharpoonup"]=0x021BC,
+ ["leftleftarrows"]=0x021C7,
+ ["LeftRightArrow"]=0x02194,
+ ["Leftrightarrow"]=0x021D4,
+ ["leftrightarrow"]=0x02194,
+ ["leftrightarrows"]=0x021C6,
+ ["leftrightharpoons"]=0x021CB,
+ ["leftrightsquigarrow"]=0x021AD,
+ ["LeftRightVector"]=0x0294E,
+ ["LeftTee"]=0x022A3,
+ ["LeftTeeArrow"]=0x021A4,
+ ["LeftTeeVector"]=0x0295A,
+ ["leftthreetimes"]=0x022CB,
+ ["LeftTriangle"]=0x022B2,
+ ["LeftTriangleBar"]=0x029CF,
+ ["LeftTriangleEqual"]=0x022B4,
+ ["LeftUpDownVector"]=0x02951,
+ ["LeftUpTeeVector"]=0x02960,
+ ["LeftUpVector"]=0x021BF,
+ ["LeftUpVectorBar"]=0x02958,
+ ["LeftVector"]=0x021BC,
+ ["LeftVectorBar"]=0x02952,
+ ["lEg"]=0x02A8B,
+ ["leg"]=0x022DA,
+ ["leq"]=0x02264,
+ ["leqq"]=0x02266,
+ ["leqslant"]=0x02A7D,
+ ["les"]=0x02A7D,
+ ["lescc"]=0x02AA8,
+ ["lesdot"]=0x02A7F,
+ ["lesdoto"]=0x02A81,
+ ["lesdotor"]=0x02A83,
+ ["lesg"]=0x022DA,
+ ["lesges"]=0x02A93,
+ ["lessapprox"]=0x02A85,
+ ["lessdot"]=0x022D6,
+ ["lesseqgtr"]=0x022DA,
+ ["lesseqqgtr"]=0x02A8B,
+ ["LessEqualGreater"]=0x022DA,
+ ["LessFullEqual"]=0x02266,
+ ["LessGreater"]=0x02276,
+ ["lessgtr"]=0x02276,
+ ["LessLess"]=0x02AA1,
+ ["lesssim"]=0x02272,
+ ["LessSlantEqual"]=0x02A7D,
+ ["LessTilde"]=0x02272,
+ ["lfisht"]=0x0297C,
+ ["lfloor"]=0x0230A,
+ ["Lfr"]=0x1D50F,
+ ["lfr"]=0x1D529,
+ ["lg"]=0x02276,
+ ["lgE"]=0x02A91,
+ ["lHar"]=0x02962,
+ ["lhard"]=0x021BD,
+ ["lharu"]=0x021BC,
+ ["lharul"]=0x0296A,
+ ["lhblk"]=0x02584,
+ ["LJcy"]=0x00409,
+ ["ljcy"]=0x00459,
+ ["Ll"]=0x022D8,
+ ["ll"]=0x0226A,
+ ["llarr"]=0x021C7,
+ ["llcorner"]=0x0231E,
+ ["Lleftarrow"]=0x021DA,
+ ["llhard"]=0x0296B,
+ ["lltri"]=0x025FA,
+ ["Lmidot"]=0x0013F,
+ ["lmidot"]=0x00140,
+ ["lmoust"]=0x023B0,
+ ["lmoustache"]=0x023B0,
+ ["lnap"]=0x02A89,
+ ["lnapprox"]=0x02A89,
+ ["lnE"]=0x02268,
+ ["lne"]=0x02A87,
+ ["lneq"]=0x02A87,
+ ["lneqq"]=0x02268,
+ ["lnsim"]=0x022E6,
+ ["loang"]=0x03018,
+ ["loarr"]=0x021FD,
+ ["lobrk"]=0x0301A,
+ ["LongLeftArrow"]=0x027F5,
+ ["Longleftarrow"]=0x027F8,
+ ["longleftarrow"]=0x027F5,
+ ["LongLeftRightArrow"]=0x027F7,
+ ["Longleftrightarrow"]=0x027FA,
+ ["longleftrightarrow"]=0x027F7,
+ ["longmapsto"]=0x027FC,
+ ["LongRightArrow"]=0x027F6,
+ ["Longrightarrow"]=0x027F9,
+ ["longrightarrow"]=0x027F6,
+ ["looparrowleft"]=0x021AB,
+ ["looparrowright"]=0x021AC,
+ ["lopar"]=0x02985,
+ ["Lopf"]=0x1D543,
+ ["lopf"]=0x1D55D,
+ ["loplus"]=0x02A2D,
+ ["lotimes"]=0x02A34,
+ ["lowast"]=0x02217,
+ ["lowbar"]=0x0005F,
+ ["LowerLeftArrow"]=0x02199,
+ ["LowerRightArrow"]=0x02198,
+ ["loz"]=0x025CA,
+ ["lozenge"]=0x025CA,
+ ["lozf"]=0x029EB,
+ ["lpar"]=0x00028,
+ ["lparlt"]=0x02993,
+ ["lrarr"]=0x021C6,
+ ["lrcorner"]=0x0231F,
+ ["lrhar"]=0x021CB,
+ ["lrhard"]=0x0296D,
+ ["lrtri"]=0x022BF,
+ ["Lscr"]=0x02112,
+ ["lscr"]=0x1D4C1,
+ ["Lsh"]=0x021B0,
+ ["lsh"]=0x021B0,
+ ["lsim"]=0x02272,
+ ["lsime"]=0x02A8D,
+ ["lsimg"]=0x02A8F,
+ ["lsqb"]=0x0005B,
+ ["lsquo"]=0x02018,
+ ["lsquor"]=0x0201A,
+ ["Lstrok"]=0x00141,
+ ["lstrok"]=0x00142,
+ ["Lt"]=0x0226A,
+ ["lt"]=0x0003C,
+ ["ltcc"]=0x02AA6,
+ ["ltcir"]=0x02A79,
+ ["ltdot"]=0x022D6,
+ ["lthree"]=0x022CB,
+ ["ltimes"]=0x022C9,
+ ["ltlarr"]=0x02976,
+ ["ltquest"]=0x02A7B,
+ ["ltri"]=0x025C3,
+ ["ltrie"]=0x022B4,
+ ["ltrif"]=0x025C2,
+ ["ltrPar"]=0x02996,
+ ["lurdshar"]=0x0294A,
+ ["luruhar"]=0x02966,
+ ["lvertneqq"]=0x02268,
+ ["lvnE"]=0x02268,
+ ["macr"]=0x000AF,
+ ["male"]=0x02642,
+ ["malt"]=0x02720,
+ ["maltese"]=0x02720,
+ ["Map"]=0x02905,
+ ["map"]=0x021A6,
+ ["mapsto"]=0x021A6,
+ ["mapstodown"]=0x021A7,
+ ["mapstoleft"]=0x021A4,
+ ["mapstoup"]=0x021A5,
+ ["marker"]=0x025AE,
+ ["mcomma"]=0x02A29,
+ ["Mcy"]=0x0041C,
+ ["mcy"]=0x0043C,
+ ["mdash"]=0x02014,
+ ["mDDot"]=0x0223A,
+ ["measuredangle"]=0x02221,
+ ["MediumSpace"]=0x0205F,
+ ["Mellintrf"]=0x02133,
+ ["Mfr"]=0x1D510,
+ ["mfr"]=0x1D52A,
+ ["mho"]=0x02127,
+ ["micro"]=0x000B5,
+ ["mid"]=0x02223,
+ ["midast"]=0x0002A,
+ ["midcir"]=0x02AF0,
+ ["middot"]=0x000B7,
+ ["minus"]=0x02212,
+ ["minusb"]=0x0229F,
+ ["minusd"]=0x02238,
+ ["minusdu"]=0x02A2A,
+ ["MinusPlus"]=0x02213,
+ ["mlcp"]=0x02ADB,
+ ["mldr"]=0x02026,
+ ["mnplus"]=0x02213,
+ ["models"]=0x022A7,
+ ["Mopf"]=0x1D544,
+ ["mopf"]=0x1D55E,
+ ["mp"]=0x02213,
+ ["Mscr"]=0x02133,
+ ["mscr"]=0x1D4C2,
+ ["mstpos"]=0x0223E,
+ ["mu"]=0x003BC,
+ ["multimap"]=0x022B8,
+ ["mumap"]=0x022B8,
+ ["nabla"]=0x02207,
+ ["Nacute"]=0x00143,
+ ["nacute"]=0x00144,
+ ["nang"]=0x02220,
+ ["nap"]=0x02249,
+ ["napE"]=0x02A70,
+ ["napid"]=0x0224B,
+ ["napos"]=0x00149,
+ ["napprox"]=0x02249,
+ ["natur"]=0x0266E,
+ ["natural"]=0x0266E,
+ ["naturals"]=0x02115,
+ ["nbsp"]=0x000A0,
+ ["nbump"]=0x0224E,
+ ["nbumpe"]=0x0224F,
+ ["ncap"]=0x02A43,
+ ["Ncaron"]=0x00147,
+ ["ncaron"]=0x00148,
+ ["Ncedil"]=0x00145,
+ ["ncedil"]=0x00146,
+ ["ncong"]=0x02247,
+ ["ncongdot"]=0x02A6D,
+ ["ncup"]=0x02A42,
+ ["Ncy"]=0x0041D,
+ ["ncy"]=0x0043D,
+ ["ndash"]=0x02013,
+ ["ne"]=0x02260,
+ ["nearhk"]=0x02924,
+ ["neArr"]=0x021D7,
+ ["nearr"]=0x02197,
+ ["nearrow"]=0x02197,
+ ["nedot"]=0x02250,
+ ["NegativeMediumSpace"]=0x0200B,
+ ["NegativeThickSpace"]=0x0200B,
+ ["NegativeThinSpace"]=0x0200B,
+ ["NegativeVeryThinSpace"]=0x0200B,
+ ["nequiv"]=0x02262,
+ ["nesear"]=0x02928,
+ ["nesim"]=0x02242,
+ ["NestedGreaterGreater"]=0x0226B,
+ ["NestedLessLess"]=0x0226A,
+ ["NewLine"]=0x0000A,
+ ["nexist"]=0x02204,
+ ["nexists"]=0x02204,
+ ["Nfr"]=0x1D511,
+ ["nfr"]=0x1D52B,
+ ["ngE"]=0x02267,
+ ["nge"]=0x02271,
+ ["ngeq"]=0x02271,
+ ["ngeqq"]=0x02267,
+ ["ngeqslant"]=0x02A7E,
+ ["nges"]=0x02A7E,
+ ["nGg"]=0x022D9,
+ ["ngsim"]=0x02275,
+ ["nGt"]=0x0226B,
+ ["ngt"]=0x0226F,
+ ["ngtr"]=0x0226F,
+ ["nGtv"]=0x0226B,
+ ["nhArr"]=0x021CE,
+ ["nharr"]=0x021AE,
+ ["nhpar"]=0x02AF2,
+ ["ni"]=0x0220B,
+ ["nis"]=0x022FC,
+ ["nisd"]=0x022FA,
+ ["niv"]=0x0220B,
+ ["NJcy"]=0x0040A,
+ ["njcy"]=0x0045A,
+ ["nlArr"]=0x021CD,
+ ["nlarr"]=0x0219A,
+ ["nldr"]=0x02025,
+ ["nlE"]=0x02266,
+ ["nle"]=0x02270,
+ ["nLeftarrow"]=0x021CD,
+ ["nleftarrow"]=0x0219A,
+ ["nLeftrightarrow"]=0x021CE,
+ ["nleftrightarrow"]=0x021AE,
+ ["nleq"]=0x02270,
+ ["nleqq"]=0x02266,
+ ["nleqslant"]=0x02A7D,
+ ["nles"]=0x02A7D,
+ ["nless"]=0x0226E,
+ ["nLl"]=0x022D8,
+ ["nlsim"]=0x02274,
+ ["nLt"]=0x0226A,
+ ["nlt"]=0x0226E,
+ ["nltri"]=0x022EA,
+ ["nltrie"]=0x022EC,
+ ["nLtv"]=0x0226A,
+ ["nmid"]=0x02224,
+ ["NoBreak"]=0x02060,
+ ["NonBreakingSpace"]=0x000A0,
+ ["Nopf"]=0x02115,
+ ["nopf"]=0x1D55F,
+ ["Not"]=0x02AEC,
+ ["not"]=0x000AC,
+ ["NotCongruent"]=0x02262,
+ ["NotCupCap"]=0x0226D,
+ ["NotDoubleVerticalBar"]=0x02226,
+ ["NotElement"]=0x02209,
+ ["NotEqual"]=0x02260,
+ ["NotEqualTilde"]=0x02242,
+ ["NotExists"]=0x02204,
+ ["NotGreater"]=0x0226F,
+ ["NotGreaterEqual"]=0x02271,
+ ["NotGreaterFullEqual"]=0x02266,
+ ["NotGreaterGreater"]=0x0226B,
+ ["NotGreaterLess"]=0x02279,
+ ["NotGreaterSlantEqual"]=0x02A7E,
+ ["NotGreaterTilde"]=0x02275,
+ ["NotHumpDownHump"]=0x0224E,
+ ["NotHumpEqual"]=0x0224F,
+ ["notin"]=0x02209,
+ ["notindot"]=0x022F5,
+ ["notinE"]=0x022F9,
+ ["notinva"]=0x02209,
+ ["notinvb"]=0x022F7,
+ ["notinvc"]=0x022F6,
+ ["NotLeftTriangle"]=0x022EA,
+ ["NotLeftTriangleBar"]=0x029CF,
+ ["NotLeftTriangleEqual"]=0x022EC,
+ ["NotLess"]=0x0226E,
+ ["NotLessEqual"]=0x02270,
+ ["NotLessGreater"]=0x02278,
+ ["NotLessLess"]=0x0226A,
+ ["NotLessSlantEqual"]=0x02A7D,
+ ["NotLessTilde"]=0x02274,
+ ["NotNestedGreaterGreater"]=0x02AA2,
+ ["NotNestedLessLess"]=0x02AA1,
+ ["notni"]=0x0220C,
+ ["notniva"]=0x0220C,
+ ["notnivb"]=0x022FE,
+ ["notnivc"]=0x022FD,
+ ["NotPrecedes"]=0x02280,
+ ["NotPrecedesEqual"]=0x02AAF,
+ ["NotPrecedesSlantEqual"]=0x022E0,
+ ["NotReverseElement"]=0x0220C,
+ ["NotRightTriangle"]=0x022EB,
+ ["NotRightTriangleBar"]=0x029D0,
+ ["NotRightTriangleEqual"]=0x022ED,
+ ["NotSquareSubset"]=0x0228F,
+ ["NotSquareSubsetEqual"]=0x022E2,
+ ["NotSquareSuperset"]=0x02290,
+ ["NotSquareSupersetEqual"]=0x022E3,
+ ["NotSubset"]=0x02282,
+ ["NotSubsetEqual"]=0x02288,
+ ["NotSucceeds"]=0x02281,
+ ["NotSucceedsEqual"]=0x02AB0,
+ ["NotSucceedsSlantEqual"]=0x022E1,
+ ["NotSucceedsTilde"]=0x0227F,
+ ["NotSuperset"]=0x02283,
+ ["NotSupersetEqual"]=0x02289,
+ ["NotTilde"]=0x02241,
+ ["NotTildeEqual"]=0x02244,
+ ["NotTildeFullEqual"]=0x02247,
+ ["NotTildeTilde"]=0x02249,
+ ["NotVerticalBar"]=0x02224,
+ ["npar"]=0x02226,
+ ["nparallel"]=0x02226,
+ ["nparsl"]=0x02AFD,
+ ["npart"]=0x02202,
+ ["npolint"]=0x02A14,
+ ["npr"]=0x02280,
+ ["nprcue"]=0x022E0,
+ ["npre"]=0x02AAF,
+ ["nprec"]=0x02280,
+ ["npreceq"]=0x02AAF,
+ ["nrArr"]=0x021CF,
+ ["nrarr"]=0x0219B,
+ ["nrarrc"]=0x02933,
+ ["nrarrw"]=0x0219D,
+ ["nRightarrow"]=0x021CF,
+ ["nrightarrow"]=0x0219B,
+ ["nrtri"]=0x022EB,
+ ["nrtrie"]=0x022ED,
+ ["nsc"]=0x02281,
+ ["nsccue"]=0x022E1,
+ ["nsce"]=0x02AB0,
+ ["Nscr"]=0x1D4A9,
+ ["nscr"]=0x1D4C3,
+ ["nshortmid"]=0x02224,
+ ["nshortparallel"]=0x02226,
+ ["nsim"]=0x02241,
+ ["nsime"]=0x02244,
+ ["nsimeq"]=0x02244,
+ ["nsmid"]=0x02224,
+ ["nspar"]=0x02226,
+ ["nsqsube"]=0x022E2,
+ ["nsqsupe"]=0x022E3,
+ ["nsub"]=0x02284,
+ ["nsubE"]=0x02AC5,
+ ["nsube"]=0x02288,
+ ["nsubset"]=0x02282,
+ ["nsubseteq"]=0x02288,
+ ["nsubseteqq"]=0x02AC5,
+ ["nsucc"]=0x02281,
+ ["nsucceq"]=0x02AB0,
+ ["nsup"]=0x02285,
+ ["nsupE"]=0x02AC6,
+ ["nsupe"]=0x02289,
+ ["nsupset"]=0x02283,
+ ["nsupseteq"]=0x02289,
+ ["nsupseteqq"]=0x02AC6,
+ ["ntgl"]=0x02279,
+ ["Ntilde"]=0x000D1,
+ ["ntilde"]=0x000F1,
+ ["ntlg"]=0x02278,
+ ["ntriangleleft"]=0x022EA,
+ ["ntrianglelefteq"]=0x022EC,
+ ["ntriangleright"]=0x022EB,
+ ["ntrianglerighteq"]=0x022ED,
+ ["nu"]=0x003BD,
+ ["num"]=0x00023,
+ ["numero"]=0x02116,
+ ["numsp"]=0x02007,
+ ["nvap"]=0x0224D,
+ ["nVDash"]=0x022AF,
+ ["nVdash"]=0x022AE,
+ ["nvDash"]=0x022AD,
+ ["nvdash"]=0x022AC,
+ ["nvge"]=0x02265,
+ ["nvgt"]=0x0003E,
+ ["nvHarr"]=0x02904,
+ ["nvinfin"]=0x029DE,
+ ["nvlArr"]=0x02902,
+ ["nvle"]=0x02264,
+ ["nvlt"]=0x0003C,
+ ["nvltrie"]=0x022B4,
+ ["nvrArr"]=0x02903,
+ ["nvrtrie"]=0x022B5,
+ ["nvsim"]=0x0223C,
+ ["nwarhk"]=0x02923,
+ ["nwArr"]=0x021D6,
+ ["nwarr"]=0x02196,
+ ["nwarrow"]=0x02196,
+ ["nwnear"]=0x02927,
+ ["Oacute"]=0x000D3,
+ ["oacute"]=0x000F3,
+ ["oast"]=0x0229B,
+ ["ocir"]=0x0229A,
+ ["Ocirc"]=0x000D4,
+ ["ocirc"]=0x000F4,
+ ["Ocy"]=0x0041E,
+ ["ocy"]=0x0043E,
+ ["odash"]=0x0229D,
+ ["Odblac"]=0x00150,
+ ["odblac"]=0x00151,
+ ["odiv"]=0x02A38,
+ ["odot"]=0x02299,
+ ["odsold"]=0x029BC,
+ ["OElig"]=0x00152,
+ ["oelig"]=0x00153,
+ ["ofcir"]=0x029BF,
+ ["Ofr"]=0x1D512,
+ ["ofr"]=0x1D52C,
+ ["ogon"]=0x002DB,
+ ["Ograve"]=0x000D2,
+ ["ograve"]=0x000F2,
+ ["ogt"]=0x029C1,
+ ["ohbar"]=0x029B5,
+ ["ohm"]=0x02126,
+ ["oint"]=0x0222E,
+ ["olarr"]=0x021BA,
+ ["olcir"]=0x029BE,
+ ["olcross"]=0x029BB,
+ ["olt"]=0x029C0,
+ ["Omacr"]=0x0014C,
+ ["omacr"]=0x0014D,
+ ["Omega"]=0x003A9,
+ ["omega"]=0x003C9,
+ ["omid"]=0x029B6,
+ ["ominus"]=0x02296,
+ ["Oopf"]=0x1D546,
+ ["oopf"]=0x1D560,
+ ["opar"]=0x029B7,
+ ["OpenCurlyDoubleQuote"]=0x0201C,
+ ["OpenCurlyQuote"]=0x02018,
+ ["operp"]=0x029B9,
+ ["oplus"]=0x02295,
+ ["Or"]=0x02A54,
+ ["or"]=0x02228,
+ ["orarr"]=0x021BB,
+ ["ord"]=0x02A5D,
+ ["order"]=0x02134,
+ ["orderof"]=0x02134,
+ ["ordf"]=0x000AA,
+ ["ordm"]=0x000BA,
+ ["origof"]=0x022B6,
+ ["oror"]=0x02A56,
+ ["orslope"]=0x02A57,
+ ["orv"]=0x02A5B,
+ ["oS"]=0x024C8,
+ ["Oscr"]=0x1D4AA,
+ ["oscr"]=0x02134,
+ ["Oslash"]=0x000D8,
+ ["oslash"]=0x000F8,
+ ["osol"]=0x02298,
+ ["Otilde"]=0x000D5,
+ ["otilde"]=0x000F5,
+ ["Otimes"]=0x02A37,
+ ["otimes"]=0x02297,
+ ["otimesas"]=0x02A36,
+ ["Ouml"]=0x000D6,
+ ["ouml"]=0x000F6,
+ ["ovbar"]=0x0233D,
+ ["OverBar"]=0x000AF,
+ ["OverBrace"]=0x0FE37,
+ ["OverBracket"]=0x023B4,
+ ["OverParenthesis"]=0x0FE35,
+ ["par"]=0x02225,
+ ["para"]=0x000B6,
+ ["parallel"]=0x02225,
+ ["parsim"]=0x02AF3,
+ ["parsl"]=0x02AFD,
+ ["part"]=0x02202,
+ ["PartialD"]=0x02202,
+ ["Pcy"]=0x0041F,
+ ["pcy"]=0x0043F,
+ ["percnt"]=0x00025,
+ ["period"]=0x0002E,
+ ["permil"]=0x02030,
+ ["perp"]=0x022A5,
+ ["pertenk"]=0x02031,
+ ["Pfr"]=0x1D513,
+ ["pfr"]=0x1D52D,
+ ["Phi"]=0x003A6,
+ ["phi"]=0x003D5,
+ ["phiv"]=0x003C6,
+ ["phmmat"]=0x02133,
+ ["phone"]=0x0260E,
+ ["Pi"]=0x003A0,
+ ["pi"]=0x003C0,
+ ["pitchfork"]=0x022D4,
+ ["piv"]=0x003D6,
+ ["planck"]=0x0210F,
+ ["planckh"]=0x0210E,
+ ["plankv"]=0x0210F,
+ ["plus"]=0x0002B,
+ ["plusacir"]=0x02A23,
+ ["plusb"]=0x0229E,
+ ["pluscir"]=0x02A22,
+ ["plusdo"]=0x02214,
+ ["plusdu"]=0x02A25,
+ ["pluse"]=0x02A72,
+ ["PlusMinus"]=0x000B1,
+ ["plusmn"]=0x000B1,
+ ["plussim"]=0x02A26,
+ ["plustwo"]=0x02A27,
+ ["pm"]=0x000B1,
+ ["Poincareplane"]=0x0210C,
+ ["pointint"]=0x02A15,
+ ["Popf"]=0x02119,
+ ["popf"]=0x1D561,
+ ["pound"]=0x000A3,
+ ["Pr"]=0x02ABB,
+ ["pr"]=0x0227A,
+ ["prap"]=0x02AB7,
+ ["prcue"]=0x0227C,
+ ["prE"]=0x02AB3,
+ ["pre"]=0x02AAF,
+ ["prec"]=0x0227A,
+ ["precapprox"]=0x02AB7,
+ ["preccurlyeq"]=0x0227C,
+ ["Precedes"]=0x0227A,
+ ["PrecedesEqual"]=0x02AAF,
+ ["PrecedesSlantEqual"]=0x0227C,
+ ["PrecedesTilde"]=0x0227E,
+ ["preceq"]=0x02AAF,
+ ["precnapprox"]=0x02AB9,
+ ["precneqq"]=0x02AB5,
+ ["precnsim"]=0x022E8,
+ ["precsim"]=0x0227E,
+ ["Prime"]=0x02033,
+ ["prime"]=0x02032,
+ ["primes"]=0x02119,
+ ["prnap"]=0x02AB9,
+ ["prnE"]=0x02AB5,
+ ["prnsim"]=0x022E8,
+ ["prod"]=0x0220F,
+ ["Product"]=0x0220F,
+ ["profalar"]=0x0232E,
+ ["profline"]=0x02312,
+ ["profsurf"]=0x02313,
+ ["prop"]=0x0221D,
+ ["Proportion"]=0x02237,
+ ["Proportional"]=0x0221D,
+ ["propto"]=0x0221D,
+ ["prsim"]=0x0227E,
+ ["prurel"]=0x022B0,
+ ["Pscr"]=0x1D4AB,
+ ["pscr"]=0x1D4C5,
+ ["Psi"]=0x003A8,
+ ["psi"]=0x003C8,
+ ["puncsp"]=0x02008,
+ ["Qfr"]=0x1D514,
+ ["qfr"]=0x1D52E,
+ ["qint"]=0x02A0C,
+ ["Qopf"]=0x0211A,
+ ["qopf"]=0x1D562,
+ ["qprime"]=0x02057,
+ ["Qscr"]=0x1D4AC,
+ ["qscr"]=0x1D4C6,
+ ["quaternions"]=0x0210D,
+ ["quatint"]=0x02A16,
+ ["quest"]=0x0003F,
+ ["questeq"]=0x0225F,
+ ["quot"]=0x00022,
+ ["rAarr"]=0x021DB,
+ ["race"]=0x029DA,
+ ["Racute"]=0x00154,
+ ["racute"]=0x00155,
+ ["radic"]=0x0221A,
+ ["raemptyv"]=0x029B3,
+ ["Rang"]=0x0300B,
+ ["rang"]=0x0232A,
+ ["rangd"]=0x02992,
+ ["range"]=0x029A5,
+ ["rangle"]=0x0232A,
+ ["raquo"]=0x000BB,
+ ["Rarr"]=0x021A0,
+ ["rArr"]=0x021D2,
+ ["rarr"]=0x02192,
+ ["rarrap"]=0x02975,
+ ["rarrb"]=0x021E5,
+ ["rarrbfs"]=0x02920,
+ ["rarrc"]=0x02933,
+ ["rarrfs"]=0x0291E,
+ ["rarrhk"]=0x021AA,
+ ["rarrlp"]=0x021AC,
+ ["rarrpl"]=0x02945,
+ ["rarrsim"]=0x02974,
+ ["Rarrtl"]=0x02916,
+ ["rarrtl"]=0x021A3,
+ ["rarrw"]=0x0219D,
+ ["rAtail"]=0x0291C,
+ ["ratail"]=0x0291A,
+ ["ratio"]=0x02236,
+ ["rationals"]=0x0211A,
+ ["RBarr"]=0x02910,
+ ["rBarr"]=0x0290F,
+ ["rbarr"]=0x0290D,
+ ["rbbrk"]=0x03015,
+ ["rbrace"]=0x0007D,
+ ["rbrack"]=0x0005D,
+ ["rbrke"]=0x0298C,
+ ["rbrksld"]=0x0298E,
+ ["rbrkslu"]=0x02990,
+ ["Rcaron"]=0x00158,
+ ["rcaron"]=0x00159,
+ ["Rcedil"]=0x00156,
+ ["rcedil"]=0x00157,
+ ["rceil"]=0x02309,
+ ["rcub"]=0x0007D,
+ ["Rcy"]=0x00420,
+ ["rcy"]=0x00440,
+ ["rdca"]=0x02937,
+ ["rdldhar"]=0x02969,
+ ["rdquo"]=0x0201D,
+ ["rdquor"]=0x0201D,
+ ["rdsh"]=0x021B3,
+ ["Re"]=0x0211C,
+ ["real"]=0x0211C,
+ ["realine"]=0x0211B,
+ ["realpart"]=0x0211C,
+ ["reals"]=0x0211D,
+ ["rect"]=0x025AD,
+ ["reg"]=0x000AE,
+ ["ReverseElement"]=0x0220B,
+ ["ReverseEquilibrium"]=0x021CB,
+ ["ReverseUpEquilibrium"]=0x0296F,
+ ["rfisht"]=0x0297D,
+ ["rfloor"]=0x0230B,
+ ["Rfr"]=0x0211C,
+ ["rfr"]=0x1D52F,
+ ["rHar"]=0x02964,
+ ["rhard"]=0x021C1,
+ ["rharu"]=0x021C0,
+ ["rharul"]=0x0296C,
+ ["rho"]=0x003C1,
+ ["rhov"]=0x003F1,
+ ["RightAngleBracket"]=0x0232A,
+ ["RightArrow"]=0x02192,
+ ["Rightarrow"]=0x021D2,
+ ["rightarrow"]=0x02192,
+ ["RightArrowBar"]=0x021E5,
+ ["RightArrowLeftArrow"]=0x021C4,
+ ["rightarrowtail"]=0x021A3,
+ ["RightCeiling"]=0x02309,
+ ["RightDoubleBracket"]=0x0301B,
+ ["RightDownTeeVector"]=0x0295D,
+ ["RightDownVector"]=0x021C2,
+ ["RightDownVectorBar"]=0x02955,
+ ["RightFloor"]=0x0230B,
+ ["rightharpoondown"]=0x021C1,
+ ["rightharpoonup"]=0x021C0,
+ ["rightleftarrows"]=0x021C4,
+ ["rightleftharpoons"]=0x021CC,
+ ["rightrightarrows"]=0x021C9,
+ ["rightsquigarrow"]=0x0219D,
+ ["RightTee"]=0x022A2,
+ ["RightTeeArrow"]=0x021A6,
+ ["RightTeeVector"]=0x0295B,
+ ["rightthreetimes"]=0x022CC,
+ ["RightTriangle"]=0x022B3,
+ ["RightTriangleBar"]=0x029D0,
+ ["RightTriangleEqual"]=0x022B5,
+ ["RightUpDownVector"]=0x0294F,
+ ["RightUpTeeVector"]=0x0295C,
+ ["RightUpVector"]=0x021BE,
+ ["RightUpVectorBar"]=0x02954,
+ ["RightVector"]=0x021C0,
+ ["RightVectorBar"]=0x02953,
+ ["ring"]=0x002DA,
+ ["risingdotseq"]=0x02253,
+ ["rlarr"]=0x021C4,
+ ["rlhar"]=0x021CC,
+ ["rmoust"]=0x023B1,
+ ["rmoustache"]=0x023B1,
+ ["rnmid"]=0x02AEE,
+ ["roang"]=0x03019,
+ ["roarr"]=0x021FE,
+ ["robrk"]=0x0301B,
+ ["ropar"]=0x02986,
+ ["Ropf"]=0x0211D,
+ ["ropf"]=0x1D563,
+ ["roplus"]=0x02A2E,
+ ["rotimes"]=0x02A35,
+ ["RoundImplies"]=0x02970,
+ ["rpar"]=0x00029,
+ ["rpargt"]=0x02994,
+ ["rppolint"]=0x02A12,
+ ["rrarr"]=0x021C9,
+ ["Rrightarrow"]=0x021DB,
+ ["Rscr"]=0x0211B,
+ ["rscr"]=0x1D4C7,
+ ["Rsh"]=0x021B1,
+ ["rsh"]=0x021B1,
+ ["rsqb"]=0x0005D,
+ ["rsquo"]=0x02019,
+ ["rsquor"]=0x02019,
+ ["rthree"]=0x022CC,
+ ["rtimes"]=0x022CA,
+ ["rtri"]=0x025B9,
+ ["rtrie"]=0x022B5,
+ ["rtrif"]=0x025B8,
+ ["rtriltri"]=0x029CE,
+ ["RuleDelayed"]=0x029F4,
+ ["ruluhar"]=0x02968,
+ ["rx"]=0x0211E,
+ ["Sacute"]=0x0015A,
+ ["sacute"]=0x0015B,
+ ["Sc"]=0x02ABC,
+ ["sc"]=0x0227B,
+ ["scap"]=0x02AB8,
+ ["Scaron"]=0x00160,
+ ["scaron"]=0x00161,
+ ["sccue"]=0x0227D,
+ ["scE"]=0x02AB4,
+ ["sce"]=0x02AB0,
+ ["Scedil"]=0x0015E,
+ ["scedil"]=0x0015F,
+ ["Scirc"]=0x0015C,
+ ["scirc"]=0x0015D,
+ ["scnap"]=0x02ABA,
+ ["scnE"]=0x02AB6,
+ ["scnsim"]=0x022E9,
+ ["scpolint"]=0x02A13,
+ ["scsim"]=0x0227F,
+ ["Scy"]=0x00421,
+ ["scy"]=0x00441,
+ ["sdot"]=0x022C5,
+ ["sdotb"]=0x022A1,
+ ["sdote"]=0x02A66,
+ ["searhk"]=0x02925,
+ ["seArr"]=0x021D8,
+ ["searr"]=0x02198,
+ ["searrow"]=0x02198,
+ ["sect"]=0x000A7,
+ ["semi"]=0x0003B,
+ ["seswar"]=0x02929,
+ ["setminus"]=0x02216,
+ ["setmn"]=0x02216,
+ ["sext"]=0x02736,
+ ["Sfr"]=0x1D516,
+ ["sfr"]=0x1D530,
+ ["sfrown"]=0x02322,
+ ["sharp"]=0x0266F,
+ ["SHCHcy"]=0x00429,
+ ["shchcy"]=0x00449,
+ ["SHcy"]=0x00428,
+ ["shcy"]=0x00448,
+ ["ShortDownArrow"]=0x02193,
+ ["ShortLeftArrow"]=0x02190,
+ ["shortmid"]=0x02223,
+ ["shortparallel"]=0x02225,
+ ["ShortRightArrow"]=0x02192,
+ ["ShortUpArrow"]=0x02191,
+ ["shy"]=0x000AD,
+ ["Sigma"]=0x003A3,
+ ["sigma"]=0x003C3,
+ ["sigmav"]=0x003C2,
+ ["sim"]=0x0223C,
+ ["simdot"]=0x02A6A,
+ ["sime"]=0x02243,
+ ["simeq"]=0x02243,
+ ["simg"]=0x02A9E,
+ ["simgE"]=0x02AA0,
+ ["siml"]=0x02A9D,
+ ["simlE"]=0x02A9F,
+ ["simne"]=0x02246,
+ ["simplus"]=0x02A24,
+ ["simrarr"]=0x02972,
+ ["slarr"]=0x02190,
+ ["SmallCircle"]=0x02218,
+ ["smallsetminus"]=0x02216,
+ ["smashp"]=0x02A33,
+ ["smeparsl"]=0x029E4,
+ ["smid"]=0x02223,
+ ["smile"]=0x02323,
+ ["smt"]=0x02AAA,
+ ["smte"]=0x02AAC,
+ ["smtes"]=0x02AAC,
+ ["SOFTcy"]=0x0042C,
+ ["softcy"]=0x0044C,
+ ["sol"]=0x0002F,
+ ["solb"]=0x029C4,
+ ["solbar"]=0x0233F,
+ ["Sopf"]=0x1D54A,
+ ["sopf"]=0x1D564,
+ ["spades"]=0x02660,
+ ["spadesuit"]=0x02660,
+ ["spar"]=0x02225,
+ ["sqcap"]=0x02293,
+ ["sqcaps"]=0x02293,
+ ["sqcup"]=0x02294,
+ ["sqcups"]=0x02294,
+ ["Sqrt"]=0x0221A,
+ ["sqsub"]=0x0228F,
+ ["sqsube"]=0x02291,
+ ["sqsubset"]=0x0228F,
+ ["sqsubseteq"]=0x02291,
+ ["sqsup"]=0x02290,
+ ["sqsupe"]=0x02292,
+ ["sqsupset"]=0x02290,
+ ["sqsupseteq"]=0x02292,
+ ["squ"]=0x025A1,
+ ["Square"]=0x025A1,
+ ["square"]=0x025A1,
+ ["SquareIntersection"]=0x02293,
+ ["SquareSubset"]=0x0228F,
+ ["SquareSubsetEqual"]=0x02291,
+ ["SquareSuperset"]=0x02290,
+ ["SquareSupersetEqual"]=0x02292,
+ ["SquareUnion"]=0x02294,
+ ["squarf"]=0x025AA,
+ ["squf"]=0x025AA,
+ ["srarr"]=0x02192,
+ ["Sscr"]=0x1D4AE,
+ ["sscr"]=0x1D4C8,
+ ["ssetmn"]=0x02216,
+ ["ssmile"]=0x02323,
+ ["sstarf"]=0x022C6,
+ ["Star"]=0x022C6,
+ ["star"]=0x02606,
+ ["starf"]=0x02605,
+ ["straightepsilon"]=0x003F5,
+ ["straightphi"]=0x003D5,
+ ["strns"]=0x000AF,
+ ["Sub"]=0x022D0,
+ ["sub"]=0x02282,
+ ["subdot"]=0x02ABD,
+ ["subE"]=0x02AC5,
+ ["sube"]=0x02286,
+ ["subedot"]=0x02AC3,
+ ["submult"]=0x02AC1,
+ ["subnE"]=0x02ACB,
+ ["subne"]=0x0228A,
+ ["subplus"]=0x02ABF,
+ ["subrarr"]=0x02979,
+ ["Subset"]=0x022D0,
+ ["subset"]=0x02282,
+ ["subseteq"]=0x02286,
+ ["subseteqq"]=0x02AC5,
+ ["SubsetEqual"]=0x02286,
+ ["subsetneq"]=0x0228A,
+ ["subsetneqq"]=0x02ACB,
+ ["subsim"]=0x02AC7,
+ ["subsub"]=0x02AD5,
+ ["subsup"]=0x02AD3,
+ ["succ"]=0x0227B,
+ ["succapprox"]=0x02AB8,
+ ["succcurlyeq"]=0x0227D,
+ ["Succeeds"]=0x0227B,
+ ["SucceedsEqual"]=0x02AB0,
+ ["SucceedsSlantEqual"]=0x0227D,
+ ["SucceedsTilde"]=0x0227F,
+ ["succeq"]=0x02AB0,
+ ["succnapprox"]=0x02ABA,
+ ["succneqq"]=0x02AB6,
+ ["succnsim"]=0x022E9,
+ ["succsim"]=0x0227F,
+ ["SuchThat"]=0x0220B,
+ ["Sum"]=0x02211,
+ ["sum"]=0x02211,
+ ["sung"]=0x0266A,
+ ["Sup"]=0x022D1,
+ ["sup"]=0x02283,
+ ["sup1"]=0x000B9,
+ ["sup2"]=0x000B2,
+ ["sup3"]=0x000B3,
+ ["supdot"]=0x02ABE,
+ ["supdsub"]=0x02AD8,
+ ["supE"]=0x02AC6,
+ ["supe"]=0x02287,
+ ["supedot"]=0x02AC4,
+ ["Superset"]=0x02283,
+ ["SupersetEqual"]=0x02287,
+ ["suphsol"]=0x02283,
+ ["suphsub"]=0x02AD7,
+ ["suplarr"]=0x0297B,
+ ["supmult"]=0x02AC2,
+ ["supnE"]=0x02ACC,
+ ["supne"]=0x0228B,
+ ["supplus"]=0x02AC0,
+ ["Supset"]=0x022D1,
+ ["supset"]=0x02283,
+ ["supseteq"]=0x02287,
+ ["supseteqq"]=0x02AC6,
+ ["supsetneq"]=0x0228B,
+ ["supsetneqq"]=0x02ACC,
+ ["supsim"]=0x02AC8,
+ ["supsub"]=0x02AD4,
+ ["supsup"]=0x02AD6,
+ ["swarhk"]=0x02926,
+ ["swArr"]=0x021D9,
+ ["swarr"]=0x02199,
+ ["swarrow"]=0x02199,
+ ["swnwar"]=0x0292A,
+ ["szlig"]=0x000DF,
+ ["Tab"]=0x00009,
+ ["target"]=0x02316,
+ ["tau"]=0x003C4,
+ ["tbrk"]=0x023B4,
+ ["Tcaron"]=0x00164,
+ ["tcaron"]=0x00165,
+ ["Tcedil"]=0x00162,
+ ["tcedil"]=0x00163,
+ ["Tcy"]=0x00422,
+ ["tcy"]=0x00442,
+ ["tdot"]=0x020DB,
+ ["telrec"]=0x02315,
+ ["Tfr"]=0x1D517,
+ ["tfr"]=0x1D531,
+ ["there4"]=0x02234,
+ ["Therefore"]=0x02234,
+ ["therefore"]=0x02234,
+ ["Theta"]=0x00398,
+ ["theta"]=0x003B8,
+ ["thetav"]=0x003D1,
+ ["thickapprox"]=0x02248,
+ ["thicksim"]=0x0223C,
+ ["ThickSpace"]=0x02009,
+ ["thinsp"]=0x02009,
+ ["ThinSpace"]=0x02009,
+ ["thkap"]=0x02248,
+ ["thksim"]=0x0223C,
+ ["THORN"]=0x000DE,
+ ["thorn"]=0x000FE,
+ ["Tilde"]=0x0223C,
+ ["tilde"]=0x002DC,
+ ["TildeEqual"]=0x02243,
+ ["TildeFullEqual"]=0x02245,
+ ["TildeTilde"]=0x02248,
+ ["times"]=0x000D7,
+ ["timesb"]=0x022A0,
+ ["timesbar"]=0x02A31,
+ ["timesd"]=0x02A30,
+ ["tint"]=0x0222D,
+ ["toea"]=0x02928,
+ ["top"]=0x022A4,
+ ["topbot"]=0x02336,
+ ["topcir"]=0x02AF1,
+ ["Topf"]=0x1D54B,
+ ["topf"]=0x1D565,
+ ["topfork"]=0x02ADA,
+ ["tosa"]=0x02929,
+ ["tprime"]=0x02034,
+ ["trade"]=0x02122,
+ ["triangle"]=0x025B5,
+ ["triangledown"]=0x025BF,
+ ["triangleleft"]=0x025C3,
+ ["trianglelefteq"]=0x022B4,
+ ["triangleq"]=0x0225C,
+ ["triangleright"]=0x025B9,
+ ["trianglerighteq"]=0x022B5,
+ ["tridot"]=0x025EC,
+ ["trie"]=0x0225C,
+ ["triminus"]=0x02A3A,
+ ["TripleDot"]=0x020DB,
+ ["triplus"]=0x02A39,
+ ["trisb"]=0x029CD,
+ ["tritime"]=0x02A3B,
+ ["trpezium"]=0x0FFFD,
+ ["Tscr"]=0x1D4AF,
+ ["tscr"]=0x1D4C9,
+ ["TScy"]=0x00426,
+ ["tscy"]=0x00446,
+ ["TSHcy"]=0x0040B,
+ ["tshcy"]=0x0045B,
+ ["Tstrok"]=0x00166,
+ ["tstrok"]=0x00167,
+ ["twixt"]=0x0226C,
+ ["twoheadleftarrow"]=0x0219E,
+ ["twoheadrightarrow"]=0x021A0,
+ ["Uacute"]=0x000DA,
+ ["uacute"]=0x000FA,
+ ["Uarr"]=0x0219F,
+ ["uArr"]=0x021D1,
+ ["uarr"]=0x02191,
+ ["Uarrocir"]=0x02949,
+ ["Ubrcy"]=0x0040E,
+ ["ubrcy"]=0x0045E,
+ ["Ubreve"]=0x0016C,
+ ["ubreve"]=0x0016D,
+ ["Ucirc"]=0x000DB,
+ ["ucirc"]=0x000FB,
+ ["Ucy"]=0x00423,
+ ["ucy"]=0x00443,
+ ["udarr"]=0x021C5,
+ ["Udblac"]=0x00170,
+ ["udblac"]=0x00171,
+ ["udhar"]=0x0296E,
+ ["ufisht"]=0x0297E,
+ ["Ufr"]=0x1D518,
+ ["ufr"]=0x1D532,
+ ["Ugrave"]=0x000D9,
+ ["ugrave"]=0x000F9,
+ ["uHar"]=0x02963,
+ ["uharl"]=0x021BF,
+ ["uharr"]=0x021BE,
+ ["uhblk"]=0x02580,
+ ["ulcorn"]=0x0231C,
+ ["ulcorner"]=0x0231C,
+ ["ulcrop"]=0x0230F,
+ ["ultri"]=0x025F8,
+ ["Umacr"]=0x0016A,
+ ["umacr"]=0x0016B,
+ ["uml"]=0x000A8,
+ ["UnderBar"]=0x00332,
+ ["UnderBrace"]=0x0FE38,
+ ["UnderBracket"]=0x023B5,
+ ["UnderParenthesis"]=0x0FE36,
+ ["Union"]=0x022C3,
+ ["UnionPlus"]=0x0228E,
+ ["Uogon"]=0x00172,
+ ["uogon"]=0x00173,
+ ["Uopf"]=0x1D54C,
+ ["uopf"]=0x1D566,
+ ["UpArrow"]=0x02191,
+ ["Uparrow"]=0x021D1,
+ ["uparrow"]=0x02191,
+ ["UpArrowBar"]=0x02912,
+ ["UpArrowDownArrow"]=0x021C5,
+ ["UpDownArrow"]=0x02195,
+ ["Updownarrow"]=0x021D5,
+ ["updownarrow"]=0x02195,
+ ["UpEquilibrium"]=0x0296E,
+ ["upharpoonleft"]=0x021BF,
+ ["upharpoonright"]=0x021BE,
+ ["uplus"]=0x0228E,
+ ["UpperLeftArrow"]=0x02196,
+ ["UpperRightArrow"]=0x02197,
+ ["Upsi"]=0x003D2,
+ ["upsi"]=0x003C5,
+ ["Upsilon"]=0x003A5,
+ ["upsilon"]=0x003C5,
+ ["UpTee"]=0x022A5,
+ ["UpTeeArrow"]=0x021A5,
+ ["upuparrows"]=0x021C8,
+ ["urcorn"]=0x0231D,
+ ["urcorner"]=0x0231D,
+ ["urcrop"]=0x0230E,
+ ["Uring"]=0x0016E,
+ ["uring"]=0x0016F,
+ ["urtri"]=0x025F9,
+ ["Uscr"]=0x1D4B0,
+ ["uscr"]=0x1D4CA,
+ ["utdot"]=0x022F0,
+ ["Utilde"]=0x00168,
+ ["utilde"]=0x00169,
+ ["utri"]=0x025B5,
+ ["utrif"]=0x025B4,
+ ["uuarr"]=0x021C8,
+ ["Uuml"]=0x000DC,
+ ["uuml"]=0x000FC,
+ ["uwangle"]=0x029A7,
+ ["vangrt"]=0x0299C,
+ ["varepsilon"]=0x003B5,
+ ["varkappa"]=0x003F0,
+ ["varnothing"]=0x02205,
+ ["varphi"]=0x003C6,
+ ["varpi"]=0x003D6,
+ ["varpropto"]=0x0221D,
+ ["vArr"]=0x021D5,
+ ["varr"]=0x02195,
+ ["varrho"]=0x003F1,
+ ["varsigma"]=0x003C2,
+ ["varsubsetneq"]=0x0228A,
+ ["varsubsetneqq"]=0x02ACB,
+ ["varsupsetneq"]=0x0228B,
+ ["varsupsetneqq"]=0x02ACC,
+ ["vartheta"]=0x003D1,
+ ["vartriangleleft"]=0x022B2,
+ ["vartriangleright"]=0x022B3,
+ ["Vbar"]=0x02AEB,
+ ["vBar"]=0x02AE8,
+ ["vBarv"]=0x02AE9,
+ ["Vcy"]=0x00412,
+ ["vcy"]=0x00432,
+ ["VDash"]=0x022AB,
+ ["Vdash"]=0x022A9,
+ ["vDash"]=0x022A8,
+ ["vdash"]=0x022A2,
+ ["Vdashl"]=0x02AE6,
+ ["Vee"]=0x022C1,
+ ["vee"]=0x02228,
+ ["veebar"]=0x022BB,
+ ["veeeq"]=0x0225A,
+ ["vellip"]=0x022EE,
+ ["Verbar"]=0x02016,
+ ["verbar"]=0x0007C,
+ ["Vert"]=0x02016,
+ ["vert"]=0x0007C,
+ ["VerticalBar"]=0x02223,
+ ["VerticalLine"]=0x0007C,
+ ["VerticalSeparator"]=0x02758,
+ ["VerticalTilde"]=0x02240,
+ ["VeryThinSpace"]=0x0200A,
+ ["Vfr"]=0x1D519,
+ ["vfr"]=0x1D533,
+ ["vltri"]=0x022B2,
+ ["vnsub"]=0x02282,
+ ["vnsup"]=0x02283,
+ ["Vopf"]=0x1D54D,
+ ["vopf"]=0x1D567,
+ ["vprop"]=0x0221D,
+ ["vrtri"]=0x022B3,
+ ["Vscr"]=0x1D4B1,
+ ["vscr"]=0x1D4CB,
+ ["vsubnE"]=0x02ACB,
+ ["vsubne"]=0x0228A,
+ ["vsupnE"]=0x02ACC,
+ ["vsupne"]=0x0228B,
+ ["Vvdash"]=0x022AA,
+ ["vzigzag"]=0x0299A,
+ ["Wcirc"]=0x00174,
+ ["wcirc"]=0x00175,
+ ["wedbar"]=0x02A5F,
+ ["Wedge"]=0x022C0,
+ ["wedge"]=0x02227,
+ ["wedgeq"]=0x02259,
+ ["weierp"]=0x02118,
+ ["Wfr"]=0x1D51A,
+ ["wfr"]=0x1D534,
+ ["Wopf"]=0x1D54E,
+ ["wopf"]=0x1D568,
+ ["wp"]=0x02118,
+ ["wr"]=0x02240,
+ ["wreath"]=0x02240,
+ ["Wscr"]=0x1D4B2,
+ ["wscr"]=0x1D4CC,
+ ["xcap"]=0x022C2,
+ ["xcirc"]=0x025EF,
+ ["xcup"]=0x022C3,
+ ["xdtri"]=0x025BD,
+ ["Xfr"]=0x1D51B,
+ ["xfr"]=0x1D535,
+ ["xhArr"]=0x027FA,
+ ["xharr"]=0x027F7,
+ ["Xi"]=0x0039E,
+ ["xi"]=0x003BE,
+ ["xlArr"]=0x027F8,
+ ["xlarr"]=0x027F5,
+ ["xmap"]=0x027FC,
+ ["xnis"]=0x022FB,
+ ["xodot"]=0x02A00,
+ ["Xopf"]=0x1D54F,
+ ["xopf"]=0x1D569,
+ ["xoplus"]=0x02A01,
+ ["xotime"]=0x02A02,
+ ["xrArr"]=0x027F9,
+ ["xrarr"]=0x027F6,
+ ["Xscr"]=0x1D4B3,
+ ["xscr"]=0x1D4CD,
+ ["xsqcup"]=0x02A06,
+ ["xuplus"]=0x02A04,
+ ["xutri"]=0x025B3,
+ ["xvee"]=0x022C1,
+ ["xwedge"]=0x022C0,
+ ["Yacute"]=0x000DD,
+ ["yacute"]=0x000FD,
+ ["YAcy"]=0x0042F,
+ ["yacy"]=0x0044F,
+ ["Ycirc"]=0x00176,
+ ["ycirc"]=0x00177,
+ ["Ycy"]=0x0042B,
+ ["ycy"]=0x0044B,
+ ["yen"]=0x000A5,
+ ["Yfr"]=0x1D51C,
+ ["yfr"]=0x1D536,
+ ["YIcy"]=0x00407,
+ ["yicy"]=0x00457,
+ ["Yopf"]=0x1D550,
+ ["yopf"]=0x1D56A,
+ ["Yscr"]=0x1D4B4,
+ ["yscr"]=0x1D4CE,
+ ["YUcy"]=0x0042E,
+ ["yucy"]=0x0044E,
+ ["Yuml"]=0x00178,
+ ["yuml"]=0x000FF,
+ ["Zacute"]=0x00179,
+ ["zacute"]=0x0017A,
+ ["Zcaron"]=0x0017D,
+ ["zcaron"]=0x0017E,
+ ["Zcy"]=0x00417,
+ ["zcy"]=0x00437,
+ ["Zdot"]=0x0017B,
+ ["zdot"]=0x0017C,
+ ["zeetrf"]=0x02128,
+ ["ZeroWidthSpace"]=0x0200B,
+ ["zeta"]=0x003B6,
+ ["Zfr"]=0x02128,
+ ["zfr"]=0x1D537,
+ ["ZHcy"]=0x00416,
+ ["zhcy"]=0x00436,
+ ["zigrarr"]=0x021DD,
+ ["Zopf"]=0x02124,
+ ["zopf"]=0x1D56B,
+ ["Zscr"]=0x1D4B5,
+ ["zscr"]=0x1D4CF,
+}
diff --git a/tex/context/base/math-ini.lua b/tex/context/base/math-ini.lua
index 1d11745a6..6b2752cff 100644
--- a/tex/context/base/math-ini.lua
+++ b/tex/context/base/math-ini.lua
@@ -6,7 +6,6 @@ if not modules then modules = { } end modules ['math-ini'] = {
license = "see context related readme files"
}
-
--[[ldx--
<p>Math definitions. This code may move.</p>
--ldx]]--
@@ -87,13 +86,13 @@ function mathematics.radical(small_family,small_slot,large_family,large_slot)
return ("\\radical%s=\"%02X%04X%\"02X%04X"):format(target,small_family,small_slot,large_family,large_slot)
end
function mathematics.mathchar(class,family,slot)
- return ("\\omathchar\"%X%02X%04X"):format(class,family,slot)
+ return ("\\omathchar\"%X%02X%04X "):format(class,family,slot)
end
function mathematics.mathaccent(class,family,slot)
- return ("\\omathaccent\"%X%02X%04X"):format(class,family,slot)
+ return ("\\omathaccent\"%X%02X%04X "):format(class,family,slot)
end
function mathematics.delimiter(class,family,slot,largefamily,largeslot)
- return ("\\odelimiter\"%X%02X%04X\"%02X%04X"):format(class,family,slot,largefamily,largeslot)
+ return ("\\odelimiter\"%X%02X%04X\"%02X%04X "):format(class,family,slot,largefamily,largeslot)
end
function mathematics.mathchardef(name,class,family,slot) -- we can avoid this one
return ("\\omathchardef\\%s\"%X%02X%04X"):format(name,class,family,slot)
diff --git a/tex/context/base/math-ini.mkiv b/tex/context/base/math-ini.mkiv
index 0b1b53caa..4d516a45c 100644
--- a/tex/context/base/math-ini.mkiv
+++ b/tex/context/base/math-ini.mkiv
@@ -19,6 +19,7 @@
% test $[[\char948 \ctxlua{tex.sprint(utf.char(948))}]]$
\registerctxluafile{math-ini}{1.001}
+\registerctxluafile{math-ent}{1.001}
% \registerctxluafile{math-def}{1.001}
% \ctxlua{mathematics.traditional()}
diff --git a/tex/context/base/math-ini.tex b/tex/context/base/math-ini.tex
index 4fc87a676..7ffef6bb8 100644
--- a/tex/context/base/math-ini.tex
+++ b/tex/context/base/math-ini.tex
@@ -35,7 +35,7 @@
\def\@@mathlimopcomm#1{\mathop{#1}} %no \limits
\def\@@mathnolopcomm#1{\mathop{#1}\nolimits}
-\def\@@mathboxcomm #1{\leavevmode\hbox{$\m@th#1$}}
+\def\@@mathboxcomm #1{\dontleavehmode\hbox{$\m@th#1$}}
\chardef\mathordcode = 0 \let\mathordcomm \mathord
\chardef\mathopcode = 1 \let\mathopcomm \mathop
@@ -602,7 +602,10 @@
%D needed for sin, cos etc
-\def\mfunction#1{{\mr#1}}
+\def\mfunction #1{{\mr#1}}
+
+% \def\mlimitsfunction #1{\mathlimopcomm{{\mr#1}}
+% \def\mnolimitsfunction#1{\mathnolopcomm{{\mr#1}}
%D Taco posted this solution as response to a mail by Olivier, so
%D let's integrate it here.
diff --git a/tex/context/base/node-ini.lua b/tex/context/base/node-ini.lua
index 76cbe3b76..5923a49e4 100644
--- a/tex/context/base/node-ini.lua
+++ b/tex/context/base/node-ini.lua
@@ -336,7 +336,9 @@ do
local starttiming, stoptiming = input.starttiming, input.stoptiming
function nodes.process_characters(head)
- if status.output_active then -- not ok, we need a generic blocker, pagebody ! / attr tex.attibutes
+ -- not ok yet; we need a generic blocker
+ -- if status.output_active then
+ if false then -- status.output_active then
return head, false -- true
else
-- either next or not, but definitely no already processed list
diff --git a/tex/context/base/syst-cat.mkiv b/tex/context/base/syst-cat.mkiv
index 212d372c1..46ee0f394 100644
--- a/tex/context/base/syst-cat.mkiv
+++ b/tex/context/base/syst-cat.mkiv
@@ -23,6 +23,7 @@
\ifx\nilcatcodes \undefined \newcatcodetable \nilcatcodes \fi
\ifx\texcatcodes \undefined \newcatcodetable \texcatcodes \fi
\ifx\ctxcatcodes \undefined \newcatcodetable \ctxcatcodes \fi
+\ifx\notcatcodes \undefined \newcatcodetable \notcatcodes \fi
\ifx\mthcatcodes \undefined \newcatcodetable \mthcatcodes \fi % brrr
\ifx\vrbcatcodes \undefined \newcatcodetable \vrbcatcodes \fi
\ifx\prtcatcodes \undefined \newcatcodetable \prtcatcodes \fi
@@ -106,6 +107,7 @@
tex.nilcatcodes = \number\nilcatcodes ;
tex.texcatcodes = \number\texcatcodes ;
tex.ctxcatcodes = \number\ctxcatcodes ;
+ tex.notcatcodes = \number\notcatcodes ;
tex.mthcatcodes = \number\mthcatcodes ;
tex.vrbcatcodes = \number\vrbcatcodes ;
tex.prtcatcodes = \number\prtcatcodes ;
diff --git a/tex/context/base/syst-cat.tex b/tex/context/base/syst-cat.tex
index d5424342c..8994f207b 100644
--- a/tex/context/base/syst-cat.tex
+++ b/tex/context/base/syst-cat.tex
@@ -452,14 +452,26 @@
\chardef\activehackcode=`~
-\def\defineactivecharacter #1 #2%
+% \def\defineactivecharacter #1 #2%
+% {\cctcounterc\uccode\activehackcode
+% \uccode\activehackcode\expandafter\doifnumberelse\expandafter{\string#1}\empty`#1%
+% \catcode\uccode\activehackcode13
+% \uppercase{\def\next{~}}%
+% \uccode\activehackcode\cctcounterc
+% \expandafter\expandafter\expandafter\def\expandafter\next\expandafter
+% {\expandafter\dohandleactivecharacter\next{#2}}}
+%
+% \defineactivecharacter "0EFFF {oeps} \utfchar{0xEFFF}
+
+\def\defineactivecharacter #1#2 #3%
{\cctcounterc\uccode\activehackcode
- \uccode\activehackcode\expandafter\doifnumberelse\expandafter{\string#1}\empty`#1%
+ \if#1"\uccode\activehackcode\expandafter\doifnumberelse\expandafter{\string#1#2}\empty #1#2\else
+ \uccode\activehackcode\expandafter\doifnumberelse\expandafter{\string#1#2}\empty`#1#2\fi
\catcode\uccode\activehackcode13
\uppercase{\def\next{~}}%
\uccode\activehackcode\cctcounterc
\expandafter\expandafter\expandafter\def\expandafter\next\expandafter
- {\expandafter\dohandleactivecharacter\next{#2}}}
+ {\expandafter\dohandleactivecharacter\next{#3}}}
\chardef\activecharactermode\plusone % overloading still backward compatible
diff --git a/tex/context/base/x-mathml.lua b/tex/context/base/x-mathml.lua
new file mode 100644
index 000000000..fa5e617e6
--- /dev/null
+++ b/tex/context/base/x-mathml.lua
@@ -0,0 +1,300 @@
+if not modules then modules = { } end modules ['x-mathml'] = {
+ version = 1.001,
+ comment = "companion to x-mathml.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+lxml.mml = lxml.mml or { }
+
+local texsprint = tex.sprint
+local format = string.format
+local xmlsprint = xml.sprint
+local xmlcprint = xml.cprint
+
+-- an alternative is to remap to private codes, where we can have
+-- different properties .. to be done; this will move and become
+-- generic
+
+local n_replacements = {
+-- [" "] = utf.char(0x2002), -- "&textspace;" -> tricky, no &; in mkiv
+ ["."] = "{.}",
+ [","] = "{,}",
+ [" "] = "",
+}
+
+local o_replacements = {
+ ["@l"] = "\\mmlleftdelimiter.",
+ ["@r"] = "\\mmlrightdelimiter.",
+ ["{"] = "\\mmlleftdelimiter\\lbrace",
+ ["}"] = "\\mmlrightdelimiter\\rbrace",
+ ["("] = "\\mmlleftdelimiter(",
+ [")"] = "\\mmlrightdelimiter)",
+ ["["] = "\\mmlleftdelimiter[",
+ ["]"] = "\\mmlrightdelimiter]",
+ ["<"] = "\\mmlleftdelimiter<",
+ [">"] = "\\mmlrightdelimiter>",
+ ["#"] = "\\mmlchar{35}",
+ ["$"] = "\\mmlchar{36}", -- $
+ ["%"] = "\\mmlchar{37}",
+ ["&"] = "\\mmlchar{38}",
+ ["^"] = "\\mmlchar{94}{}", -- strange, sometimes luatex math sees the char instead of \char
+ ["_"] = "\\mmlchar{95}{}", -- so we need the {}
+ ["~"] = "\\mmlchar{126}",
+ [" "] = "",
+}
+
+local i_replacements = {
+ ["sin"] = "\\mathopnolimits{sin}",
+ ["cos"] = "\\mathopnolimits{cos}",
+ ["abs"] = "\\mathopnolimits{abs}",
+ ["arg"] = "\\mathopnolimits{arg}",
+ ["codomain"] = "\\mathopnolimits{codomain}",
+ ["curl"] = "\\mathopnolimits{curl}",
+ ["determinant"] = "\\mathopnolimits{det}",
+ ["divergence"] = "\\mathopnolimits{div}",
+ ["domain"] = "\\mathopnolimits{domain}",
+ ["gcd"] = "\\mathopnolimits{gcd}",
+ ["grad"] = "\\mathopnolimits{grad}",
+ ["identity"] = "\\mathopnolimits{id}",
+ ["image"] = "\\mathopnolimits{image}",
+ ["lcm"] = "\\mathopnolimits{lcm}",
+ ["max"] = "\\mathopnolimits{max}",
+ ["median"] = "\\mathopnolimits{median}",
+ ["min"] = "\\mathopnolimits{min}",
+ ["mode"] = "\\mathopnolimits{mode}",
+ ["mod"] = "\\mathopnolimits{mod}",
+ ["polar"] = "\\mathopnolimits{Polar}",
+ ["exp"] = "\\mathopnolimits{exp}",
+ ["ln"] = "\\mathopnolimits{ln}",
+ ["log"] = "\\mathopnolimits{log}",
+ ["sin"] = "\\mathopnolimits{sin}",
+ ["arcsin"] = "\\mathopnolimits{arcsin}",
+ ["sinh"] = "\\mathopnolimits{sinh}",
+ ["arcsinh"] = "\\mathopnolimits{arcsinh}",
+ ["cos"] = "\\mathopnolimits{cos}",
+ ["arccos"] = "\\mathopnolimits{arccos}",
+ ["cosh"] = "\\mathopnolimits{cosh}",
+ ["arccosh"] = "\\mathopnolimits{arccosh}",
+ ["tan"] = "\\mathopnolimits{tan}",
+ ["arctan"] = "\\mathopnolimits{arctan}",
+ ["tanh"] = "\\mathopnolimits{tanh}",
+ ["arctanh"] = "\\mathopnolimits{arctanh}",
+ ["cot"] = "\\mathopnolimits{cot}",
+ ["arccot"] = "\\mathopnolimits{arccot}",
+ ["coth"] = "\\mathopnolimits{coth}",
+ ["arccoth"] = "\\mathopnolimits{arccoth}",
+ ["csc"] = "\\mathopnolimits{csc}",
+ ["arccsc"] = "\\mathopnolimits{arccsc}",
+ ["csch"] = "\\mathopnolimits{csch}",
+ ["arccsch"] = "\\mathopnolimits{arccsch}",
+ ["sec"] = "\\mathopnolimits{sec}",
+ ["arcsec"] = "\\mathopnolimits{arcsec}",
+ ["sech"] = "\\mathopnolimits{sech}",
+ ["arcsech"] = "\\mathopnolimits{arcsech}",
+ [" "] = "",
+
+ ["false"] = "{\\mr false}",
+ ["notanumber"] = "{\\mr NaN}",
+ ["otherwise"] = "{\\mr otherwise}",
+ ["true"] = "{\\mr true}",
+ ["declare"] = "{\\mr declare}",
+ ["as"] = "{\\mr as}",
+}
+
+function lxml.mml.checked_operator(str)
+ texsprint(tex.ctxcatcodes,(str:gsub(".",o_replacements)))
+end
+
+function lxml.mml.mn(id,pattern)
+ local str = xml.content(lxml.id(id),pattern) or ""
+ texsprint(tex.ctxcatcodes,(str:gsub(".",n_replacements)))
+end
+function lxml.mml.mo(id,pattern)
+ local str = xml.content(lxml.id(id),pattern) or ""
+ tex.sprint(tex.ctxcatcodes,(str:gsub(".",o_replacements)))
+end
+function lxml.mml.mi(id,pattern)
+ local str = xml.content(lxml.id(id),pattern) or ""
+ str = str:gsub("^%s*(.*)%s*$","%1")
+ local rep = i_replacements[str]
+ if rep then
+ tex.sprint(tex.ctxcatcodes,rep)
+ else
+ tex.sprint(tex.ctxcatcodes,(str:gsub(".",i_replacements)))
+ end
+end
+
+function lxml.mml.mfenced(id,pattern) -- multiple separators
+ id = lxml.id(id)
+ local left, right, separators = id.at.open or "(", id.at.close or ")", id.at.separators or ","
+ local l, r = left:find("[%(%{%<%[]"), right:find("[%)%}%>%]]")
+ texsprint(tex.ctxcatcodes,"\\enabledelimiter")
+ if l then
+ texsprint(tex.ctxcatcodes,o_replacements[left])
+ else
+ texsprint(tex.ctxcatcodes,o_replacements["@l"])
+ texsprint(tex.ctxcatcodes,left)
+ end
+ texsprint(tex.ctxcatcodes,"\\disabledelimiter")
+ local n = xml.count(id,pattern)
+ if n == 0 then
+ -- skip
+ elseif n == 1 then
+ lxml.all(id,pattern)
+ else
+ local t = { }
+ for s in utf.gmatch(separators,"([^%s])") do
+ t[#t+1] = s
+ end
+ for i=1,n do
+ lxml.idx(id,pattern,i) -- kind of slow, some day ...
+ if i < n then
+ local m = t[i] or t[#t] or ""
+ if m == "|" then
+ m = "\\enabledelimiter\\middle|\\relax\\disabledelimiter"
+ elseif m == "{" then
+ m = "\\{"
+ elseif m == "}" then
+ m = "\\}"
+ end
+ texsprint(tex.ctxcatcodes,m)
+ end
+ end
+ end
+ texsprint(tex.ctxcatcodes,"\\enabledelimiter")
+ if r then
+ texsprint(tex.ctxcatcodes,o_replacements[right])
+ else
+ texsprint(tex.ctxcatcodes,right)
+ texsprint(tex.ctxcatcodes,o_replacements["@r"])
+ end
+ texsprint(tex.ctxcatcodes,"\\disabledelimiter")
+end
+
+local function flush(e,tag,toggle)
+ -- texsprint(tex.ctxcatcodes,(toggle and "^{") or "_{")
+ if toggle then
+ texsprint(tex.ctxcatcodes,"^{")
+ else
+ texsprint(tex.ctxcatcodes,"_{")
+ end
+ if tag == "none" then
+ texsprint(tex.ctxcatcodes,"{}")
+ else
+ xmlsprint(e.dt)
+ end
+ if not toggle then
+ texsprint(tex.ctxcatcodes,"}")
+ else
+ texsprint(tex.ctxcatcodes,"}{}")
+ end
+ return not toggle
+end
+
+function lxml.mml.mmultiscripts(id)
+ local done, toggle = false, false
+ id = lxml.id(id)
+ -- for i=1,#id.dt do local e = id.dt[i] if type(e) == table then ...
+ for r, d, k in xml.elements(id,"/*") do
+ local e = d[k]
+ local tag = e.tg
+ if tag == "mprescripts" then
+ texsprint(tex.ctxcatcodes,"{}")
+ done = true
+ elseif done then
+ toggle = flush(e,tag,toggle)
+ end
+ end
+ local done, toggle = false, false
+ for r, d, k in xml.elements(id,"/*") do
+ local e = d[k]
+ local tag = e.tg
+ if tag == "mprescripts" then
+ break
+ elseif done then
+ toggle = flush(e,tag,toggle)
+ else
+ xmlsprint(e.dt)
+ done = true
+ end
+ end
+end
+
+local columnalignments = {
+ left = "flushleft",
+ right = "flushright",
+ center = "middle",
+}
+
+local rowalignments = {
+ top = "high",
+ bottom = "low",
+ center = "lohi",
+ baseline = "top",
+ axis = "lohi",
+}
+
+local frametypes = {
+ none = "off",
+ solid = "on",
+ dashed = "on",
+}
+
+function lxml.mml.mtable(root)
+
+ root = lxml.id(root)
+
+ -- todo: align, rowspacing, columnspacing, rowlines, columnlines
+
+ local at = root.at
+ local rowalign = at.rowalign
+ local columnalign = at.columnalign
+ local frame = at.frame
+ local rowaligns = rowalign and rowalign :split(" ") -- we have a faster one
+ local columnaligns = columnalign and columnalign:split(" ") -- we have a faster one
+ local frames = frame and frame :split(" ") -- we have a faster one
+ local framespacing = at.framespacing or ".5ex"
+
+ texsprint(tex.ctxcatcodes, format("\\bTABLE[frame=%s,offset=%s]",frametypes[frame or "none"] or "off",framespacing))
+ for r, d, k in xml.elements(root,"/(mml:mtr|mml:mlabeledtr)") do
+ texsprint(tex.ctxcatcodes,"\\bTR")
+ local dk = d[k]
+ local at = dk.at
+ local col = 0
+ local rfr = at.frame or (frames and frames [#frames])
+ local rra = at.rowalign or (rowaligns and rowaligns [#rowaligns])
+ local rca = at.columnalign or (columnaligns and columnaligns[#columnaligns])
+ for rr, dd, kk in xml.elements(dk,"/mml:mtd") do
+ col = col + 1
+ local dk = dd[kk]
+ local at = dk.at
+ local rowspan, columnspan = at.rowspan or 1, at.columnspan or 1
+ local cra = rowalignments [at.rowalign or (rowaligns and rowaligns [col]) or rra or "center"] or "lohi"
+ local cca = columnalignments[at.columnalign or (columnaligns and columnaligns[col]) or rca or "center"] or "middle"
+ local cfr = frametypes [at.frame or (frames and frames [col]) or rfr or "none" ] or "off"
+ texsprint(tex.ctxcatcodes,format("\\bTD[align={%s,%s},frame=%s,nx=%s,ny=%s]$\\ignorespaces",cra,cca,cfr,columnspan,rowspan))
+ xmlcprint(dk)
+ texsprint(tex.ctxcatcodes,"\\removeunwantedspaces$\\eTD") -- $
+ end
+ if dk.tg == "mlabeledtr" then
+ texsprint(tex.ctxcatcodes,"\\bTD")
+ xmlcprint(xml.first(dk,"/!mml:mtd"))
+ texsprint(tex.ctxcatcodes,"\\eTD")
+ end
+ texsprint(tex.ctxcatcodes,"\\eTR")
+ end
+ texsprint(tex.ctxcatcodes, "\\eTABLE")
+end
+
+function lxml.mml.csymbol(root)
+ root = lxml.id(root)
+ local encoding = root.at.encoding or ""
+ local hash = url.hashed((root.at.definitionUrl or ""):lower())
+ local full = hash.original or ""
+ local base = hash.path or ""
+ local text = string.strip(xml.content(root) or "")
+ texsprint(tex.ctxcatcodes,format("\\mmlapplycsymbol{%s}{%s}{%s}{%s}",full,base,encoding,text))
+end
+
diff --git a/tex/context/base/x-mmc.mkiv b/tex/context/base/x-mmc.mkiv
index 981dab162..042ef3406 100644
--- a/tex/context/base/x-mmc.mkiv
+++ b/tex/context/base/x-mmc.mkiv
@@ -11,263 +11,63 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+% todo: more consistent both pi's and attributes to apply
+
\doifnotmode {atpragma} {\endinput}
% \xmlfilter{#1}{/*/name()} -> \xmltag
-%D Remark: from now on this is a module and no longer an xtag
-%D filter. There is an intermediate cleaner module but it has
-%D some namespace limitations. Here we do it the \MKV\ way.
+\xmlresolveentities
\startluacode
- do
-
- lxml.mml = lxml.mml or { }
-
- local texsprint = tex.sprint
- local format = string.format
- local xmlsprint = xml.sprint
- local xmlcprint = xml.cprint
-
- -- an alternative is to remap to private codes, where we can have
- -- different properties .. to be done
-
- local n_replacements = {
- -- [" "] = utf.char(0x2002), -- "&textspace;" -> tricky, no &; in mkiv
- ["."] = "{.}",
- [","] = "{,}",
- [" "] = "",
- }
- local o_replacements = {
- ["{"] = "\\mmlleftdelimiter\\lbrace",
- ["}"] = "\\mmlrightdelimiter\\rbrace",
- ["("] = "\\mmlleftdelimiter(",
- [")"] = "\\mmlrightdelimiter)",
- ["["] = "\\mmlleftdelimiter[",
- ["]"] = "\\mmlrightdelimiter]",
- ["<"] = "\\mmlleftdelimiter<",
- [">"] = "\\mmlrightdelimiter>",
- ["#"] = "\\mmlchar{35}",
- ["$"] = "\\mmlchar{36}", -- $
- ["%"] = "\\mmlchar{37}",
- ["&"] = "\\mmlchar{38}",
- ["^"] = "\\mmlchar{94}{}", -- strange, sometimes luatex math see the char instead of \char
- ["_"] = "\\mmlchar{95}{}", -- so we need the {}
- ["~"] = "\\mmlchar{126}",
- [" "] = "",
- }
- local i_replacements = {
- ["sin"] = "\\mmlnolim{sin}",
- ["cos"] = "\\mmlnolim{cos}",
- ["abs"] = "\\mmlnolim{abs}",
- ["arg"] = "\\mmlnolim{arg}",
- ["codomain"] = "\\mmlnolim{codomain}",
- ["curl"] = "\\mmlnolim{curl}",
- ["determinant"] = "\\mmlnolim{det}",
- ["divergence"] = "\\mmlnolim{div}",
- ["domain"] = "\\mmlnolim{domain}",
- ["false"] = "\\mmlnolim{false}",
- ["gcd"] = "\\mmlnolim{gcd}",
- ["grad"] = "\\mmlnolim{grad}",
- ["identity"] = "\\mmlnolim{id}",
- ["image"] = "\\mmlnolim{image}",
- ["lcm"] = "\\mmlnolim{lcm}",
- ["max"] = "\\mmlnolim{max}",
- ["median"] = "\\mmlnolim{median}",
- ["min"] = "\\mmlnolim{min}",
- ["mode"] = "\\mmlnolim{mode}",
- ["mod"] = "\\mmlnolim{mod}",
- ["notanumber"] = "\\mmlnolim{NaN}",
- ["otherwise"] = "\\mmlnolim{otherwise}",
- ["true"] = "\\mmlnolim{true}",
- ["declare"] = "\\mmlnolim{declare}",
- ["as"] = "\\mmlnolim{as}",
- ["polar"] = "\\mmlnolim{Polar}",
- ["exp"] = "\\mmlnolim{exp}",
- ["ln"] = "\\mmlnolim{ln}",
- ["log"] = "\\mmlnolim{log}",
- ["sin"] = "\\mmlnolim{sin}",
- ["arcsin"] = "\\mmlnolim{arcsin}",
- ["sinh"] = "\\mmlnolim{sinh}",
- ["arcsinh"] = "\\mmlnolim{arcsinh}",
- ["cos"] = "\\mmlnolim{cos}",
- ["arccos"] = "\\mmlnolim{arccos}",
- ["cosh"] = "\\mmlnolim{cosh}",
- ["arccosh"] = "\\mmlnolim{arccosh}",
- ["tan"] = "\\mmlnolim{tan}",
- ["arctan"] = "\\mmlnolim{arctan}",
- ["tanh"] = "\\mmlnolim{tanh}",
- ["arctanh"] = "\\mmlnolim{arctanh}",
- ["cot"] = "\\mmlnolim{cot}",
- ["arccot"] = "\\mmlnolim{arccot}",
- ["coth"] = "\\mmlnolim{coth}",
- ["arccoth"] = "\\mmlnolim{arccoth}",
- ["csc"] = "\\mmlnolim{csc}",
- ["arccsc"] = "\\mmlnolim{arccsc}",
- ["csch"] = "\\mmlnolim{csch}",
- ["arccsch"] = "\\mmlnolim{arccsch}",
- ["sec"] = "\\mmlnolim{sec}",
- ["arcsec"] = "\\mmlnolim{arcsec}",
- ["sech"] = "\\mmlnolim{sech}",
- ["arcsech"] = "\\mmlnolim{arcsech}",
- [" "] = "",
- }
-
- function lxml.mml.prepare_number(id,pattern)
- local str = xml.content(lxml.id(id),pattern) or ""
- texsprint(tex.ctxcatcodes,(str:gsub(".",n_replacements)))
- end
- function lxml.mml.prepare_operator(id,pattern)
- local str = xml.content(lxml.id(id),pattern) or ""
- tex.sprint(tex.ctxcatcodes,(str:gsub(".",o_replacements)))
- end
- function lxml.mml.prepare_identifier(id,pattern)
- local str = xml.content(lxml.id(id),pattern) or ""
- str = str:gsub("^%s*(.*)%s*$","%1")
- local rep = i_replacements[str]
- if rep then
- tex.sprint(tex.ctxcatcodes,rep)
- else
- tex.sprint(tex.ctxcatcodes,(str:gsub(".",i_replacements)))
- end
- end
-
- function lxml.mml.connect(id,pattern,separators) -- multiple separators
- local n = xml.count(id,pattern)
- if n == 0 then
- -- skip
- elseif n == 1 then
- lxml.all(id,pattern)
- else
- local t = { }
- for s in utf.gmatch(separators,"([^%s])") do
- t[#t+1] = s
- end
- for i=1,n do
- if i > 1 then
- texsprint(tex.ctxcatcodes,"{")
- texsprint(t[i] or t[#t] or "")
- texsprint(tex.ctxcatcodes,"}")
- end
- lxml.idx(id,pattern,i) -- kind of slow, some day ...
- end
- end
- end
-
- local function flush(e,tag,toggle)
- -- texsprint(tex.ctxcatcodes,(toggle and "^{") or "_{")
- if toggle then
- texsprint(tex.ctxcatcodes,"^{")
- else
- texsprint(tex.ctxcatcodes,"_{")
- end
- if tag == "none" then
- texsprint(tex.ctxcatcodes,"{}")
- else
- xmlsprint(e.dt)
- end
- if not toggle then
- texsprint(tex.ctxcatcodes,"}")
- else
- texsprint(tex.ctxcatcodes,"}{}")
- end
- return not toggle
- end
-
- function lxml.mml.mmultiscripts(id)
- local done, toggle = false, false
- id = lxml.id(id)
- -- for i=1,#id.dt do local e = id.dt[i] if type(e) == table then ...
- for r, d, k in xml.elements(id,"/*") do
- local e = d[k]
- local tag = e.tg
- if tag == "mprescripts" then
- texsprint(tex.ctxcatcodes,"{}")
- done = true
- elseif done then
- toggle = flush(e,tag,toggle)
- end
- end
- local done, toggle = false, false
- for r, d, k in xml.elements(id,"/*") do
- local e = d[k]
- local tag = e.tg
- if tag == "mprescripts" then
- break
- elseif done then
- toggle = flush(e,tag,toggle)
- else
- xmlsprint(e.dt)
- done = true
- end
+ function math.register_xml_entities()
+ local entities, char = xml.entities, utf.char
+ for name, unicode in pairs(math.entities) do
+ if not entities[name] then
+ entities[name] = char(unicode)
end
end
+ end
+ math.register_xml_entities()
+
+ -- not yet needed, we have class info in char-def already
+ --
+ -- characters.data[0x2190].activemath = "mathleftarrow"
+ -- characters.data[0x2190].activemath = "mathuparrow"
+ -- characters.data[0x2192].activemath = "mathrightarrow"
+ -- characters.data[0x2193].activemath = "mathdownarrow"
+ --
+ -- function characters.activate(catcodes)
+ -- local char, sprint, format = utf.char, tex.sprint, string.format
+ -- for k,v in pairs(characters.data) do
+ -- local a = v.activemath
+ -- if a then -- how fast is this?
+ -- sprint(format("\\letcatcodecommand %s %s \\%s",catcodes,k,a))
+ -- end
+ -- end
+ -- end
+ --
+ -- better do this the official way, i.e. defineactivecharacter since it
+ -- permits different meanings for different catcode tables (todo)
+ --
+ -- characters.activate(tex.ctxcatcodes)
+ -- characters.activate(tex.notcatcodes)
+\stopluacode
- local columnalignments = {
- left = "flushleft",
- right = "flushright",
- center = "middle",
- }
-
- local rowalignments = {
- top = "high",
- bottom = "low",
- center = "lohi",
- baseline = "top",
- axis = "lohi",
- }
+% \def\mathrightarrow{\normalorfiller\rightarrow\rightarrowfill}
+% \def\mathleftarrow {\normalorfiller\leftarrow \leftarrowfill}
+% \def\mathdownarrow {\mathortext \downarrow \empty}
+% \def\mathuparrow {\mathortext \uparrow \empty}
- local frames = {
- none = "off",
- solid = "on",
- dashed = "on",
- }
+% \def\mathunderbrace{\normalorfiller\empty\upbracefill}
+% \def\mathoverbrace {\normalorfiller\empty\downbracefill}
+% \def\mathunderbar {\normalorfiller\hrule\hrulefill}
+% \def\mathoverbar {\normalorfiller\hrule\hrulefill}
+% \def\mathhat {\normalorfiller\empty\empty} % todo
- function lxml.mml.mtable(root)
-
- root = lxml.id(root)
-
- local at = root.at
- local rowalign = at.rowalign
- local columnalign = at.columnalign
- local rowaligns = rowalign and rowalign :split(",") -- we have a faster one
- local columnaligns = columnalign and columnalign:split(",") -- we have a faster one
-
- -- todo: align, rowspacing, columnspacing, rowlines, columnlines
-
- local frame = frames[at.frame or "none"]
- local framespacing = at.framespacing or ".5ex"
-
- texsprint(tex.ctxcatcodes, format("\\bTABLE[frame=%s,offset=%s]",frame,framespacing))
- for r, d, k in xml.elements(root,"/(mml:mtr|mml:mlabeledtr)") do
- texsprint(tex.ctxcatcodes,"\\bTR")
- local dk = d[k]
- local at = dk.at
- local rra, rca, col = at.rowalign or rowalign, at.columnalign or columnalign, 0
- for rr, dd, kk in xml.elements(dk,"/mml:mtd") do
- col = col + 1
- local dk = dd[kk]
- local at = dk.at
- local rowspan = at.rowspan or 1
- local columnspan = at.columnspan or 1
- local cra = rowalignments [(rowaligns and rowaligns [col]) or at.rowalign or rra or "center"]
- local cca = columnalignments[(columnaligns and columnaligns[col]) or at.columnalign or rca or "center"]
- texsprint(tex.ctxcatcodes,format("\\bTD[align={%s,%s},nx=%s,ny=%s]$\\ignorespaces",cra,cca,columnspan,rowspan))
- xmlcprint(dk)
- texsprint(tex.ctxcatcodes,"\\removeunwantedspaces$\\eTD") -- $
- end
- if dk.tg == "mlabeledtr" then
- texsprint(tex.ctxcatcodes,"\\bTD")
- xmlcprint(xml.first(dk,"/!mml:mtd"))
- texsprint(tex.ctxcatcodes,"\\eTD")
- end
- texsprint(tex.ctxcatcodes,"\\eTR")
- end
- texsprint(tex.ctxcatcodes, "\\eTABLE")
- end
-
- end
-\stopluacode
+%D Remark: from now on this is a module and no longer an xtag
+%D filter. There is an intermediate cleaner module but it has
+%D some namespace limitations. Here we do it the \MKV\ way.
\unprotect
@@ -289,15 +89,13 @@
\startmodule [mathml]
-%D First we load the entities:
-
-\usemodule[newmme] % will be replaced by math-ent or so
+\ctxlua{environment.loadlucfile("x-mathml")}
\unprotect
\def\MMLrm{\mr}
-\def\MMLseparator#1{{#1}} % nils space after separator
+\def\MMLseparator#1{\removeunwantedspaces{#1}\ignorespaces} % nils space after separator
%D First we define some general formula elements.
@@ -350,11 +148,13 @@
%D We start with the parent elements and the option handler.
- \defineXMLdirective [mathml] \setupMMLappearance % todo
+% \defineXMLdirective [mathml] \setupMMLappearance % todo
+
+\def\xmlmathmldirective#1{\dosetvalue{MML#1}}
%D In the styles, options can be set with:
-\def\setupMMLappearance[#1]{\dodoubleargument\getparameters[@@MML#1]}
+\def\setupMMLappearance[#1]{\dodoubleargument\getparameters[MML#1]} % no @@ because passed to lua
%D We will apply inner math to all bits and pieces made up by an
%D \type {apply}.
@@ -364,11 +164,11 @@
%D Auxiliary MathML macros: (to be generalized)
-\def\mmlfirst #1{\mmlfirst{#1}{/*}} % \xmlsnippet{1}
+\def\mmlfirst #1{\xmlindex{#1}{/*}{1}} % \xmlsnippet{1}
\def\mmlsecond #1{\xmlindex{#1}{/*}{2}} % \xmlsnippet{2}
\def\mmlthird #1{\xmlindex{#1}{/*}{3}} % \xmlsnippet{3}
\def\mmlprelast#1{\xmlindex{#1}{/*}{-2}} %
-\def\mmllast #1{\xmlindex{#1}{/*}{-1}} %
+\def\mmllast #1{\xmlin{#1}{/*}{-1}} %
\starttexdefinition doifelsemmlfunction #1
\xmldoifelse {#1} {/mml:fn} {
@@ -491,14 +291,14 @@
\edef\MMLdoR{\noexpand\right\mmlapplyclosetoken}
\fi
\let\MMLctempresetlist\empty
-% \xmldoifelse {#1} {/mml:apply} {
+ \xmldoifelse {#1} {/mml:apply} {
% % <apply> <apply> ... </apply> <ci> .. </ci> </apply>
% \xmldoifelse {#1} {/mml:apply(mml:plus|mml:minus)} {% [a]
% % yet incomplete and rather untested
% % <apply> <apply> <minus/> <tan/> <cos/> </apply> <ci>x</ci> </apply>
-% } {% [b]
+ } {% [b]
% \MMLcreset
-% }
+ }
% \MMLdoL
% \xmlfirst{#1}{/*}
% \ifconditional\somepostponedMMLactions
@@ -527,10 +327,10 @@
\xmlall{#1}{../[position()>1]}
\stopxmlsetups
\startxmlsetups mml:apply:mml:fn
+ \hbox{todo}% obsolete
\stopxmlsetups
\startxmlsetups mml:apply:mml:csymbol
-\stopxmlsetups
-\startxmlsetups mml:apply:mml:ci
+ \hbox{todo}
\stopxmlsetups
% \startsetups mmc:fn:apply
@@ -577,23 +377,13 @@
% }
% \stopsetups
- % \defineXMLsingular
- % [csymbol]
- % [encoding=text,
- % definitionURL=]
- % {\directsetup{mmc:csymbol:apply:singular}}
-
- % \startsetups mmc:csymbol:apply:singular
- % \lowercasestring\XMLpar{csymbol}{definitionURL}{}\to\mmcSymbolURL
- % \directsetup{mmc:csymbol:\mmcSymbolURL}
- % \stopsetups
- % \startsetups mmc:ci:apply
- % \getXMLstackdata\plusone
- % \ifnum\XMLstacklevel>\plusone
- % \left(\MMLcreset\flushXMLstackwith\plustwo{\MMLseparator,}\right)
- % \fi
- % \stopsetups
+\startxmlsetups mml:apply:mml:ci
+ \xmlfirst{#1}{/mml:ci}
+ \ifnum\xmlcount{#1}{/*}>\plusone
+ \left(\MMLcreset\xmlconcatrange{#1}{/*}{2}{}{\MMLseparator,}\right)
+ \fi
+\stopxmlsetups
% reln
@@ -686,45 +476,43 @@
\MMLcreset
\getXMLentity{NegThinSpace}
\MMCfnleft
- \ifnum\XMLstacklevel=\plustwo\MMLccomma\fi
- \flushXMLstackwith\plustwo\MMLccomma
+ \ifnum\XMLstacklevel=\plustwo,\fi
+ \flushXMLstackwith\plustwo,
\MMCfnright
\endgroup
}
}
\stopsetups
-% c*
-
- \defineXMLargument [csymbol] [encoding=text] {\XMLval{mmc:cs}{\XMLop{encoding}}{\firstofoneargument}}
-
%D The next definition provide a kind of plug-in mechanism (see
%D the open math extension module).
- \defineXMLsingular
- [csymbol]
- [encoding=text,
- definitionURL=]
- {\doifsomething{\XMLop{definitionURL}}{\directsetup{mmc:csymbol:apply}}}
+% http://www.publishers.com/somename
- \startsetups mmc:csymbol:apply
- \begingroup
- \rawXMLstacktext\plusone % still on stack, no check, just attr test
- % http://www.publishers.com/SomeName
- \lowercasestring\XMLpar{csymbol}{definitionURL}{}\to\mmcSymbolURL
- \doifsetupselse{mmc:csymbol:} {\mmcSymbolURL} {
- \expanded{\endgroup\noexpand\directsetup{mmc:csymbol:\mmcSymbolURL}}
- } {
- % SomeName (fallback)
- \splitfilename{\XMLpar{csymbol}{definitionURL}{}}
- \doifsetupselse{mmc:csymbol:\splitoffbase} {
- \expanded{\endgroup\noexpand\directsetup{mmc:csymbol:\splitoffbase}}
- } {
- \endgroup
- \XMLval{mmc:cs}{\XMLop{encoding}}{\firstofoneargument}
- }
- }
- \stopsetups
+\starttexdefinition mmlapplycsymbol #1#2#3#4
+ % #1=full url, #2=name, #3=encoding, #4=text
+ \doifelse {#3} {text} {
+ {\mr #4}
+ } {
+ \doifsetupselse {mml:csymbol:#1} {
+ % full url
+ \directsetup{mml:csymbol:#1}
+ } {
+ % somename (fallback)
+ \doifsetupselse {mmc:csymbol:#2} {
+ \directsetup{mml:csymbol:#2}
+ } {
+ \XMLval{mmc:cs}{#3}{}% todo
+ }
+ }
+ }
+\stoptexdefinition
+
+\startxmlsetups mml:csymbol
+ \ctxlua{lxml.mml.csymbol("#1")}
+\stopxmlsetups
+
+% \startxmlsetups mml:csymbol:<url> \stopxmlsetups
%D Alternative b will convert periods into comma's:
%D
@@ -757,7 +545,7 @@
% helpers cn
\startxmlsetups mml:cn:default
- \mfunction{\xmlflush{#1}}
+ \mathopnolimits{\xmlflush{#1}}
\stopxmlsetups
% helpers ci
@@ -802,7 +590,7 @@
\xmlsetup{#1}{mml:cn:polar}
\stopxmlsetups
-% \doif\@@MMLcnalternative\v!b{\redefinemathcharacter [.][ord][mi]["3B]\relax}%
+% \doif\MMLcnalternative\v!b{\redefinemathcharacter [.][ord][mi]["3B]\relax}%
%
% todo: number function from mmp
@@ -817,15 +605,15 @@
\ifx\mmlintegerbase\empty
\xmlflush{#1}
\else
- \doifelse \@@MMLbasesymbol \v!no {
+ \doifelse \MMLbasesymbol \v!no {
\MMLcCNbasedata{\xmlflush{#1}}
} {
\MMLcCNbasedata{\xmlflush{#1}}_{
\hbox {$
- \rm
+ \mr
\scriptscriptstyle
\processaction
- [\@@MMLbasesymbol]
+ [\MMLbasesymbol]
[\v!characters=>\MMLcCNbasestring BODH,
\v!text=>\MMLcCNbasestring{BIN}{OCT}{DEC}{HEX},
\s!unknown=>\mmlintegerbase]
@@ -836,7 +624,7 @@
\stopxmlsetups
\def\MMLcCNbasedata#1%
- {\ifnum\mmlintegerbase>10 \relax{\rm#1}\else#1\fi}
+ {\ifnum\mmlintegerbase>10 \relax{\mr#1}\else#1\fi}
\def\MMLcCNbasestring#1#2#3#4%
{\ifnum\mmlintegerbase= 2 #1\else
@@ -846,17 +634,17 @@
\mmlintegerbase \fi\fi\fi\fi}
\startxmlsetups mml:cn:polar
- \xmlsetup{#1}{mml:cn:polar:\@@MMLpolaralternative}
+ \xmlsetup{#1}{mml:cn:polar:\MMLpolaralternative}
\stopxmlsetups
\startxmlsetups mml:cn:polar:a
\mathopnolimits{Polar}% ? ? ?
- \left(\xmlsnippet{#1}{1}\MMLccomma\xmlsnippet{#1}{1}\right)
+ \left(\xmlsnippet{#1}{1},\xmlsnippet{#1}{1}\right)
\stopxmlsetups
\startxmlsetups mml:cn:polar:b
-% {\rm e}^{\xmlsnippet{#1}{1}\mskip2mu\getXMLentity{imaginaryi}}
- {\rm e}^{\xmlsnippet{#1}{1}+\xmlsnippet{#1}{3}{\rm i}}
+% {\mr e}^{\xmlsnippet{#1}{1}\mskip2mu\getXMLentity{imaginaryi}}
+ {\mr e}^{\xmlsnippet{#1}{1}+\xmlsnippet{#1}{3}{\mr i}}
\stopxmlsetups
\startxmlsetups mml:cn:polar:c
@@ -869,7 +657,7 @@
\stopxmlsetups
\startxmlsetups mml:cn:complex
- \xmlsnippet{#1}{1} + \xmlsnippet{#1}{3}{\rm i}
+ \xmlsnippet{#1}{1} + \xmlsnippet{#1}{3}{\mr i}
\stopxmlsetups
\startxmlsetups mml:cn:complex-cartesian
@@ -877,9 +665,9 @@
\stopxmlsetups
\startxmlsetups mml:cn:float
- \doifelse \@@MMLfloatsymbol \v!no {
+ \doifelse \MMLfloatsymbol \v!no {
% make sure that e shows up ok
- \mfunction{\xmlflush{#1}}
+ \mathopnolimits{\xmlflush{#1}}
} {
% we should ignore \entities !
\edef\mmlfloatstring{\xmlflush{#1}}
@@ -890,7 +678,7 @@
\mmlfloatstring
\else
\first
- \doifelse \@@MMLfloatsymbol {dot} \cdot \times
+ \doifelse \MMLfloatsymbol {dot} \cdot \times
10^{\last}
\fi \fi
}
@@ -901,19 +689,19 @@
\stopxmlsetups
\startxmlsetups mml:cn:e-notation
- \doifelse \@@MMLenotationsymbol \v!no {
+ \doifelse \MMLenotationsymbol \v!no {
\xmlsnippet{#1}{1}
- \unskip\mfunction{e}\ignorespaces
+ \unskip\mathopnolimits{e}\ignorespaces
\xmlsnippet{#1}{3}
} {
\xmlsnippet{#1}{1}
- \doifelse \@@MMLenotationsymbol {dot} \cdot
+ \doifelse \MMLenotationsymbol {dot} \cdot
\times10^{\xmlsnippet{#1}{3}}
}
\stopxmlsetups
\startxmlsetups mml:cn:logical
- \mfunction{\xmlflush{#1}}
+ \mathopnolimits{\xmlflush{#1}}
\stopxmlsetups
\startxmlsetups mml:cn:rational
@@ -935,30 +723,30 @@
\stopxmlsetups
\startxmlsetups mml:interval:closed
- \left[\mmlsecond{#1}\MMLseparator\@@MMLintervalseparator\mmlthird{#1}\right]
+ \left[\mmlfirst{#1}\MMLseparator\MMLintervalseparator\mmlsecond{#1}\right]
\stopxmlsetups
\startxmlsetups mml:interval:open-closed
- \doifelse \@@MMLintervalalternative \v!b {
- \left<\mmlsecond{#1}\MMLseparator\@@MMLintervalseparator\mmlthird{#1}\right]
+ \doifelse \MMLintervalalternative \v!b {
+ \left<\mmlfirst{#1}\MMLseparator\MMLintervalseparator\mmlsecond{#1}\right]
} {
- \left(\mmlsecond{#1}\MMLseparator\@@MMLintervalseparator\mmlthird{#1}\right]
+ \left(\mmlfirst{#1}\MMLseparator\MMLintervalseparator\mmlsecond{#1}\right]
}
\stopxmlsetups
\startxmlsetups mml:interval:closed-open
- \doifelse \@@MMLintervalalternative \v!b {
- \left[\mmlsecond{#1}\MMLseparator\@@MMLintervalseparator\mmlthird{#1}\right>
+ \doifelse \MMLintervalalternative \v!b {
+ \left[\mmlfirst{#1}\MMLseparator\MMLintervalseparator\mmlsecond{#1}\right>
} {
- \left[\mmlsecond{#1}\MMLseparator\@@MMLintervalseparator\mmlthird{#1}\right)
+ \left[\mmlfirst{#1}\MMLseparator\MMLintervalseparator\mmlsecond{#1}\right)
}
\stopxmlsetups
\startxmlsetups mml:interval:open
- \doifelse \@@MMLintervalalternative \v!b {
- \left<\mmlsecond{#1}\MMLseparator\@@MMLintervalseparator\mmlthird{#1}\right>
+ \doifelse \MMLintervalalternative \v!b {
+ \left<\mmlfirst{#1}\MMLseparator\MMLintervalseparator\mmlsecond{#1}\right>
} {
- \left(\mmlsecond{#1}\MMLseparator\@@MMLintervalseparator\mmlthird{#1}\right)
+ \left(\mmlfirst{#1}\MMLseparator\MMLintervalseparator\mmlsecond{#1}\right)
}
\stopxmlsetups
@@ -981,17 +769,22 @@
\xmlsetup{#1}{\xmlfilter{#1}{/mml:apply/*/name(1)}}
\stopxmlsetups
-\startxmlsetups xml:mmc:process
+\startxmlsetups xml:mml:inverse
\xmlsetsetup{\xmldocument}{mml:apply/mml:apply/mml:inverse/../../..}{mml:apply:inverse}
\stopxmlsetups
-\xmlregistersetup{xml:mmc:process}
+\xmlregistersetup{xml:mml:inverse}
% condition
% maybe a fast \xmlnonfirst
-\startxmlsetups mmc:condition
+\startxmlsetups mml:bvar \xmlflush{#1} \stopxmlsetups
+\startxmlsetups mml:lowlimit \xmlflush{#1} \stopxmlsetups
+\startxmlsetups mml:uplimit \xmlflush{#1} \stopxmlsetups
+\startxmlsetups mml:degree \xmlflush{#1} \stopxmlsetups
+
+\startxmlsetups mml:condition
% \xmldoif {#1} {/mml:bvar} {
% \xmlfirst{#1}{/mml:bvar}\mid
% }
@@ -1003,7 +796,7 @@
\setupMMLappearance[declare][\c!state=\v!start]
\startxmlsetups mml:declare
- \doif \@@MMLdeclarestate \v!start {
+ \doif \MMLdeclarestate \v!start {
\mathopnolimits{declare}
\xmlindex{#1}{/*}{1}
\ifnum \xmlcount{#1}{/} > \plusone
@@ -1019,15 +812,15 @@
\setupMMLappearance[lambda][\c!alternative=b]
-\startxmlsetups mmc:lambda
+\startxmlsetups mml:lambda
\begingroup
- \doifelse \@@MMLlambdaalternative \v!a {
+ \doifelse \MMLlambdaalternative \v!a {
\lambda\left(\xmlconcat{#1}{/!mml:lambda}{\MMLseparator,}\left)
} {
\ifnum \xmlcount {#1} {/mml:bvar} > \plusone
\left(\xmlconcat{#1}{/mml:bvar}{\MMLseparator,}\right)
\else
- \xmlfirstnamed{#1}{bvar}
+ \xmlfirst{#1}{/mml:bvar}
\fi
\mapsto
\MMLcreset
@@ -1043,9 +836,9 @@
\MMLcreset
% \let\MMLcCIfunction\firstofoneargument % brrr ? ? ?
\doifelsemmlfunction {
- \left(\xmlconcatrange{#1}{2}{}{\circ}\right)
+ \left(\xmlconcatrange{#1}{/*}{2}{}{\circ}\right)
} {
- \xmlconcatrange{#1}{2}{}{\circ}
+ \xmlconcatrange{#1}{/*}{2}{}{\circ}
}
\endgroup
\stopxmlsetups
@@ -1058,12 +851,12 @@
\startxmlsetups mml:piecewise
\processaction
- [\@@MMLpieceseparator]
- [ \v!yes=>\def\theMMLpieceseparator{,\@col@amp@},
- \v!no=>\let\theMMLpieceseparator\@col@amp@,
- \s!default=>\let\theMMLpieceseparator\@col@amp@,
- \s!unknown=>\def\theMMLpieceseparator{\,\,\hbox{\@@MMLpieceseparator}\,\,}]
- \cases \xmlflush{#1}
+ [\MMLpieceseparator]
+ [ \v!yes=>\def\theMMLpieceseparator{,&},
+ \v!no=>\def\theMMLpieceseparator{&},
+ \s!default=>\def\theMMLpieceseparator{&},
+ \s!unknown=>\def\theMMLpieceseparator{\,\,\hbox{\MMLpieceseparator}\,\,}]
+ \cases{\xmlflush{#1}}
\stopxmlsetups
\startxmlsetups mml:piece
@@ -1071,7 +864,8 @@
\stopxmlsetups
\startxmlsetups mml:otherwise
- \xmlflush{#1}\MMLcPIECEseparator\@col@amp@\mathematics{otherwise}\crcr
+% \xmlflush{#1}\MMLcPIECEseparator&{\mr otherwise}\crcr
+ \xmlflush{#1}&{\mr otherwise}\crcr
\stopxmlsetups
% end of piece
@@ -1090,10 +884,10 @@
\startxmlsetups mml:divide
\advance\mmldividelevel\plusone
- \doifelse \@@MMLdividealternative \v!b {
+ \doifelse \MMLdividealternative \v!b {
\mmlsecond{#1}/\mmlthird{#1}
} {
- \ifnum \mmldividelevel > \@@MMLdividelevel \relax % threshold
+ \ifnum \mmldividelevel > \MMLdividelevel \relax % threshold
\mmlsecond{#1}/\mmlthird{#1}
\else
\MMLcreset
@@ -1105,20 +899,16 @@
% min max
-\startxmlsetups mml:min
- \xmldoifelse {#1} {/mml:bvar} {
- {}_{\xmlfirst{#1}{/mml:bvar}}
- } {
- }
- \left\{\xmlconcat{#1}{/!(mml:bvar\string|mml:min)}{\wedge}{\MMLseparator,}\right\}
-\stopxmlsetups
+\startxmlsetups mml:min \mathopnolimits{min} \xmlsetup{#1}{mml:minmax} \stopxmlsetups
+\startxmlsetups mml:max \mathopnolimits{max} \xmlsetup{#1}{mml:minmax} \stopxmlsetups
-\startxmlsetups mml:max
- \xmldoifelse {#1} {/mml:bvar} {
+\startxmlsetups mml:minmax
+ \xmldoif {#1} {/mml:bvar} {
{}_{\xmlfirst{#1}{/mml:bvar}}
- } {
}
- \left\{\xmlconcat{#1}{/!(mml:bvar\string|mml:max)}{\wedge}{\MMLseparator,}\right\}
+ \left\{
+ \xmlconcat{#1}{/!(mml:bvar\string|mml:max\string|mml:min)}{\MMLseparator,}
+ \right\}
\stopxmlsetups
% minus plus
@@ -1135,7 +925,7 @@
\newcount\mmlpluscounter
\startxmlsetups mml:plus
- \doifelse \@@MMLsignreduction \v!yes {
+ \doifelse \MMLsignreduction \v!yes {
\MMLdoL
\xmlsetup{#1}{mml:plus:reset}
\xmlcommand{#1}{/!mml:plus}{mml:plus:body}
@@ -1176,7 +966,7 @@
\newcount\mmlminuscounter
\startsetups mml:minus
- \doifelse \@@MMLsignreduction \v!yes {
+ \doifelse \MMLsignreduction \v!yes {
} {
}
\ifnum\xmlcount{#1}{/!mml:minus}=\plusone
@@ -1210,7 +1000,7 @@
\startxmlsetups mml:power
\xmldoifelse {#1} {/mml:apply} {
- \doifelse \@@MMLpowerreduction \v!yes {
+ \doifelse \MMLpowerreduction \v!yes {
\xmldoifelse {#1} {/(\MMLcfunctionlist)} {
\gdef\MMLpowerelement{\mmlthird{#1}}% postpone, no xdef
\MMLcreset\mmlsecond{#1}
@@ -1235,26 +1025,26 @@
\startxmlsetups mml:times
\setMMLcreset{\MMLcfunctionlist\string|\MMLcconstructlist}%
- \doifelse\@@MMLtimesauto\v!no {
- \let\@@MMLtimes@@symbol\@@MMLtimessymbol
+ \doifelse\MMLtimesauto\v!no {
+ \let\MMLtimes@@symbol\MMLtimessymbol
} {
\xmldoifelse {#1} {/mml:cn[name(1) == 'mml:cn']} {% name(1) is next one
- \doifinsetelse\@@MMLtimessymbol{\v!yes,\v!no} {
- \let\@@MMLtimes@@symbol\v!yes
+ \doifinsetelse\MMLtimessymbol{\v!yes,\v!no} {
+ \let\MMLtimes@@symbol\v!yes
} {
- \let\@@MMLtimes@@symbol\@@MMLtimessymbol
+ \let\MMLtimes@@symbol\MMLtimessymbol
}
} {
- \let\@@MMLtimes@@symbol\@@MMLtimessymbol
+ \let\MMLtimes@@symbol\MMLtimessymbol
}
}
- \doifelse\@@MMLtimes@@symbol\v!yes {
+ \doifelse\MMLtimes@@symbol\v!yes {
\xmlconcat{#1}{/!mml:times}{\times}
} {
- \doifelse\@@MMLtimes@@symbol{dot} {
+ \doifelse\MMLtimes@@symbol{dot} {
\xmlconcat{#1}{/!mml:times}{\cdot}
} {
- \doifelse\@@MMLtimes@@symbol{times} {
+ \doifelse\MMLtimes@@symbol{times} {
\xmlconcat{#1}{/!mml:times}{\times}
} {
\xmlall{#1}{/!mml:times}
@@ -1268,7 +1058,7 @@
\startxmlsetups mml:root
\xmldoifelse {#1} {/mml:degree} {
\root
- \doifnot\@@MMLrootsymbol\v!no{\MMLcreset\xmltext{#1}{/mml:degree}}
+ \doifnot\MMLrootsymbol\v!no{\MMLcreset\xmltext{#1}{/mml:degree}}
\of
} {
\sqrt
@@ -1286,11 +1076,11 @@
% and or xor implies, not
-\startxmlsetups mml:and \xmlconcat{#1}{/!mml:and} {2}{}{\wedge} \stopxmlsetups
-\startxmlsetups mml:or \xmlconcat{#1}{/!mml:or} {2}{}{\vee} \stopxmlsetups
-\startxmlsetups mml:xor \xmlconcat{#1}{/!mml:xor} {2}{}{\mathopnolimits{xor}} \stopxmlsetups
-\startxmlsetups mml:implies \xmlconcat{#1}{/!mml:implies}{2}{}{\Rightarrow} \stopxmlsetups
-\startxmlsetups mml:not \neg \xmlall {#1}{/!mml:not} \stopxmlsetups
+\startxmlsetups mml:and \xmlconcat{#1}{/!mml:and} {\wedge} \stopxmlsetups
+\startxmlsetups mml:or \xmlconcat{#1}{/!mml:or} {\vee} \stopxmlsetups
+\startxmlsetups mml:xor \xmlconcat{#1}{/!mml:xor} {\mathopnolimits{xor}} \stopxmlsetups
+\startxmlsetups mml:implies \xmlconcat{#1}{/!mml:implies}{\Rightarrow} \stopxmlsetups
+\startxmlsetups mml:not \neg \xmlall {#1}{/!mml:not} \stopxmlsetups
% forall exists
@@ -1393,7 +1183,7 @@
\startxmlsetups mml:relation
\edef\mmlapplyaction{\xmlfilter{#1}{/*/name()}}
- \MMLcreset \xmlsetup{#1}{mml:relation:\xmlattdef{#1}{align}{no}}
+ \MMLcreset \xmlsetup{#1}{mml:relation:\xmlattdef{#1}{align}{\MMLrelationalign}}
\stopxmlsetups
\startxmlsetups mml:relation:default
@@ -1444,7 +1234,7 @@
\setupMMLappearance[int][\c!location=\v!top]
-\def\doMMLlimits#1{\doifelsevalue{@@MML#1\c!location}\v!top\limits\nolimits}
+\def\doMMLlimits#1{\doifelsevalue{MML#1\c!location}\v!top\limits\nolimits}
\startxmlsetups mml:int
\MMLcreset
@@ -1478,16 +1268,13 @@
\xmlfirst{#1}{/mml:ci}
}
\xmldoifelse {#1} {/mml:bvar} {
- \thinspace \mfunction{d} \xmlfirst{#1}{/mml:bvar}
+ \thinspace {\mr d} \xmlfirst{#1}{/mml:bvar}
} {
% nothing
}
\stopxmlsetups
- \setupMMLappearance[diff][\c!location=\v!top,\c!alternative=\v!a]
-
- \defineXMLcommand [diff] {\directsetup{mmc:diff}}
- \defineXMLcommand [partialdiff] {\directsetup{mmc:partialdiff}}
+\setupMMLappearance[diff][\c!location=\v!top,\c!alternative=\v!a]
% \setupMMLappearance[diff][alternative=b]
%
@@ -1505,118 +1292,104 @@
% </apply></math>
% \stopXMLdata
- \startsetups mmc:diff
- \MMLcreset
- \doifelse\@@MMLdiffalternative\v!a {
- \XMLdoifonstackelse{lambda} {
- % a special case (mathadore/openmath)
- \begingroup
- \defineXMLsave[ci]
- \defineXMLsave[cn]
- \defineXMLprocess[lambda]
- \defineXMLprocess[bvar]
- \frac {
- d^{\XMLfirstnamed{bvar}\XMLflush{cn}}{\XMLfirstnamed{lambda}\XMLflush{ci}}
- } {
- d{\XMLfirstnamed{bvar}\XMLflush{ci}}^{\XMLfirstnamed{bvar}\XMLflush{cn}}
- }
- \endgroup
+\startxmlsetups mml:diff
+ \MMLcreset
+ \doifelse \MMLdiffalternative \v!a {
+ \xmldoifelse {#1} {/mml:lambda} {
+ % a special case (mathadore/openmath)
+ \frac {
+ d^{\xmlfirst{#1}{/mml:bvar}\xmlfirst{#1}{/mml:cn}}{\xmlfirst{#1}{/mml:lambda}\xmlfirst{#1}{/mml:ci}}
+ } {
+ d{\xmlfirst{#1}{/mml:bvar}\xmlfirst{#1}{/mml:ci}}^{\xmlfirst{#1}{/mml:bvar}\xmlfirst{#1}{/mml:cn}}
+ }
+ } {
+ \xmldoifelse {#1} {/mml:bvar} {
+ \frac {
+ {\mr d}{
+ \xmldoifelse {#1} {/mml:degree} {
+ ^{\xmlconcat{#1}{/mml:degree}\empty}
} {
- \XMLdoifonstackelse{bvar} {
- \frac {
- \XMLdoifonstackelse{degree} {
- \collectXMLnamedstack{degree}\empty
- } {
- \collectXMLnamedstacknamed{bvar}{degree}+
- }
- \mfunction{\getXMLentity{mathematicald}}
- ^{\the\XMLRtoks}
- \doif\@@MMLdifflocation\v!top {
- \XMLdoifonstackelse{ci} {
- \XMLfirstnamed{ci}
- } {
- \MMLcreset\XMLfirstnamed{apply}
- }
- }
- } {
- \mfunction{\getXMLentity{mathematicald}}
- \begingroup
- \defineXMLsave[degree]
- \XMLfirstnamed{bvar}
- \doifXMLdata{degree} {
- ^{\XMLflush{degree}}
- }
- \endgroup
- }
- \doifnot\@@MMLdifflocation\v!top {
- \left(\MMLcreset\XMLfirstnamed{apply,ci}\right)
- }
- } {
- \flushXMLstackfrom\plustwo^\prime
- }
- }
- } {
- \MMLcreset
- \XMLfirstnamed{apply,ci}
- % there can be problems with nested diff's: ^^{} error
- % so we add an empty group here
- {}^
- {
- \XMLdoifonstackelse{degree} {
- \defXMLfirstnamedtext\ascii{degree}
- \dorecurse\ascii\prime
- } {
- \prime
+ \xmldoif {#1} {/mml:bvar/mml:degree} {
+ ^{\xmlconcat{#1}{/mml:bvar/mml:degree}+}
}
}
}
- \stopsetups
-
- \startsetups mmc:partialdiff
- \XMLdoifonstackelse{list} {
- \getXMLentity{capitaldifferentiald}_{
- \begingroup
- \setfalse\mmllistdelimiters
- \XMLallnamed{list}
- \endgroup
- }
- \XMLfirstnamed{apply,reln,ci,cn}
- } {
- \XMLdoifonstackelse{bvar} {
- \frac {
- \XMLdoifonstackelse{degree} {
- \collectXMLnamedstack{degree}\empty
- } {
- \collectXMLnamedstacknamed{bvar}{degree}+
- }
- \getXMLentity{differentiald}^{\the\XMLRtoks}
- \MMLcreset
- \XMLfirstnamed{apply,reln,ci,cn}
- } {
- \defineXMLnested[bvar]
- {\directsetup{mmc:bvar:diff:start}}
- {\directsetup{mmc:bvar:diff:stop}}
- \XMLfirstnamed{bvar}
- }
+ \doif \MMLdifflocation \v!top {
+ \xmldoifelse {#1} {/mml:ci} {
+ \xmlfirst{#1}{/mml:ci}
} {
- \XMLfirstnamed{apply,reln,ci,cn}
+ \MMLcreset
+ \xmlfirst{#1}{/mml:apply}
}
}
- \stopsetups
-
- \startsetups mmc:bvar:diff:start
- \begingroup
- \stopsetups
+ } {
+ {\mr d}
+ \xmlfirst{#1}{/mml:bvar/!mml:degree}
+ \xmldoif {#1} {/mml:bvar/mml:degree} {
+ ^{\xmlfirst{#1}{/mml:bvar/mml:degree}}
+ }
+ }
+ \doifnot \MMLdifflocation \v!top {
+ \left(\MMLcreset\xmlfirst{#1}{/(mml:apply\string|mml:ci)}\right)
+ }
+ } {
+ \xmlconcatrange{#1}{/*}{2}{}^\prime
+ }
+ }
+ } {
+ \MMLcreset
+ \xmlfirst{#1}{/(mml:apply\string|mml:ci)}
+ % there can be problems with nested diff's: ^^{} error
+ % so we add an empty group here
+ {}^
+ {
+ \xmldoifelse {#1} {/mml:degree} {
+ \edef\mmldegree{\xmlfirst{#1}{/mml:degree/mml:cn}}
+ \ifx\mmldegree\empty
+ % what to do here
+ \else
+ \dorecurse\mmldegree\prime
+ \fi
+ } {
+ \prime
+ }
+ }
+ }
+\stopxmlsetups
- \startsetups mmc:bvar:diff:stop
- \getXMLentity{differentiald}\XMLfirstnamed{apply,reln,ci,cn}
- \XMLdoifonstackelse{degree} {
- ^{\XMLfirstnamed{degree}}
+\startxmlsetups mml:partialdiff
+ \xmldoifelse {#1} {/mml:list} {
+ {\mr D}_{
+ \begingroup
+ \setfalse\mmllistdelimiters
+ \xmlall{#1}{/mml:list}
+ \endgroup
+ }
+ \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
+ } {
+ \xmldoifelse {#1} {/mml:bvar} {
+ \frac {
+ {\mr d}^{
+ \xmldoifelse {#1} {/mml:degree} {
+ \xmlconcat{#1}{/mml:degree}\empty
} {
- % nothing
+ \xmlconcat{#1}{/mml:bvar/mml:degree}+
}
- \endgroup
- \stopsetups
+ }
+ \MMLcreset
+ \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
+ } {
+ \xmlfirst{#1}{/mml:bvar}
+ {\mr d}\xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
+ \xmldoif {#1} {/mml:degree} {
+ ^{\xmlfirst{#1}{/mml:degree}}
+ }
+ }
+ } {
+ \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
+ }
+ }
+\stopxmlsetups
% option: to be discussed with taco/aditya: all math functions \mathentity
%
@@ -1627,25 +1400,25 @@
\startxmlsetups mml:divergence \mathopnolimits{div} \xmlall{#1}{/!mml:divergence} \stopxmlsetups
\startxmlsetups mml:grad \mathopnolimits{grad} \xmlall{#1}{/!mml:grad} \stopxmlsetups
\startxmlsetups mml:curl \mathopnolimits{curl} \xmlall{#1}{/!mml:curl} \stopxmlsetups
-\startxmlsetups mml:laplacian \mathopnolimits{\nabla^2} \xmlall{#1}{/!mml:laplacian} \stopxmlsetups
+\startxmlsetups mml:laplacian \nabla^2 \xmlall{#1}{/!mml:laplacian} \stopxmlsetups
\startxmlsetups mml:ident \mathopnolimits{identity} \xmlall{#1}{/!mml:ident} \stopxmlsetups
\setupMMLappearance[domain] [symbol=]
\setupMMLappearance[codomain][symbol=]
\startxmlsetups mml:domain
- \doifelsenothing \@@MMLdomainsymbol {
+ \doifelsenothing \MMLdomainsymbol {
\mathopnolimits{domain}\MMLcreset\xmlall{#1}{/!mml:domain}
} {
- \@@MMLdomainsymbol_{\xmlall{#1}{/!mml:domain}}
+ \MMLdomainsymbol_{\xmlall{#1}{/!mml:domain}}
}
\stopxmlsetups
\startxmlsetups mml:codomain
- \doifelsenothing \@@MMLcodomainsymbol {
+ \doifelsenothing \MMLcodomainsymbol {
\mathopnolimits{codomain}\MMLcreset\xmlall{#1}{/!mml:codomain}
} {
- \@@MMLcodomainsymbol_{\xmlall{#1}{/!mml:codomain}}
+ \MMLcodomainsymbol_{\xmlall{#1}{/!mml:codomain}}
}
\stopxmlsetups
@@ -1653,12 +1426,13 @@
\startxmlsetups mml:set
\left\{
- \xmldoif {#1} {/mml:condition} {
+ \xmldoifelse {#1} {/mml:condition} {
\xmlfirst{#1}{/mml:bvar}\,\middle\vert\,\xmlfirst{#1}{/mml:condition}
} {
\xmlconcat{#1}{/!mml:set}{\MMLseparator,}
}
\right\}
+ \relax % needed
\stopxmlsetups
\settrue\mmllistdelimiters
@@ -1697,11 +1471,11 @@
\setupMMLappearance[sum] [\c!location=\v!top]
\setupMMLappearance[product][\c!location=\v!top]
-\mapXMLvalue {mml:sumproc} {sum} {\sum}
-\mapXMLvalue {mml:sumproc} {product} {\prod}
+\mapXMLvalue {mml:sumprod} {sum} {\sum}
+\mapXMLvalue {mml:sumprod} {product} {\prod}
-\startxmlsetups mml:sum \xmlsetup{#1}{mml:sumprod} \stopxmlsetups
-\startxmlsetups mml:product \xmlsetup{#1}{mml:sumprod} \stopxmlsetups
+\startxmlsetups mml:sum \edef\mmlsumprodname{sum} \xmlsetup{#1}{mml:sumprod} \stopxmlsetups
+\startxmlsetups mml:product \edef\mmlsumprodname{product} \xmlsetup{#1}{mml:sumprod} \stopxmlsetups
\def\mmlstackedsubscripts#1%
{\vbox
@@ -1745,7 +1519,7 @@
\fi
}
\MMLcreset
- \XMLval{mml:sumproc}{\xmltag{#1}}{}\doMMLlimits{#1}\mmlsumprodupper\mmlsumprodlower
+ \XMLval{mml:sumprod}{\mmlsumprodname}{}\doMMLlimits\mmlsumprodname\mmlsumprodupper\mmlsumprodlower
\MMLcreset
\xmldoifelse {#1} {/mml:lambda/mml:apply} {
\xmlfirst{#1}{/mml:lambda/mml:apply}% a bit of open math conversion mess
@@ -1759,7 +1533,7 @@
\startxmlsetups mml:limit
\MMLcreset \lim
- \doMMLlimits {#1} {limit}_{
+ \doMMLlimits {limit}_{
\MMLcreset
\xmldoifelse {#1} {/mml:condition} {
\xmlfirst{#1}{/mml:condition}
@@ -1774,7 +1548,7 @@
% a bit of open math conversion mess, lambda needed for openmath, ok?
\MMLcreset
\xmlfirst{#1}{/mml:lambda/mml:apply}
- \xmlfirst{#1}{/(mml:apply\string|\mml:lambda}
+ \xmlfirst{#1}{/(mml:apply\string|mml:lambda)}
\endgroup
\stopxmlsetups
@@ -1795,28 +1569,28 @@
\setupMMLappearance[log][\c!location=\v!right]
\startxmlsetups mml:exp
-% {\rm e}^{\xmlfirst{#1}{/mml:apply\string|mml:reln\string|mml:ci\string|mml:cn}}
- {\rm e}^{\xmlfirst{#1}{/!mml:exp}}
+% {\mr e}^{\xmlfirst{#1}{/mml:apply\string|mml:reln\string|mml:ci\string|mml:cn}}
+ {\mr e}^{\xmlfirst{#1}{/!mml:exp}}
\stopxmlsetups
\startxmlsetups mml:log
\xmldoifelse {#1} {/mml:logbase} {
- \doifelse \@@MMLloglocation \v!left {
+ \doifelse \MMLloglocation \v!left {
\mathop {
- {}^{\xmlfirst{#1}{/mml:logbase}}\negthinspace\mfunction{log}
+ {}^{\xmlfirst{#1}{/mml:logbase}}\negthinspace\mathopnolimits{log}
}
} {
- \mfunction{log}_{\xmlfirst{#1}{/mml:logbase}}
+ \mathopnolimits{log}_{\xmlfirst{#1}{/mml:logbase}}
}
} {
- \mfunction{log}
+ \mathopnolimits{log}
}
\MMLcreset
\xmlsetup{#1}{mml:function}
\stopxmlsetups
\startxmlsetups mml:ln
- \mfunction {ln}
+ \mathopnolimits{ln}
\xmlsetup{#1}{mml:function}
\stopxmlsetups
@@ -1835,7 +1609,7 @@
\xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}^{\xmlfirst{#1}{/mml:degree}}
\right\rangle
\xmldoif {#1} {mml:momentabout} {
- _{\xmlfirst{mml:momentabout}}
+ _{\xmlfirst{#1}{mml:momentabout}}
}
\stopxmlsetups
@@ -1843,16 +1617,16 @@
\setupMMLappearance [vector] [\c!direction=\v!horizontal,\c!separator={,}]
-\startxmlsetups mml:vector:start
+\startxmlsetups mml:vector
\begingroup
\ifnum\xmlcount{#1}{/*}>\plusone
- \doifelse\@@MMLvectordirection\v!horizontal {
- \left(\xmlconcat{#1}{/*}{\MMLseparator\@@MMLvectorseparator}\right)
+ \doifelse\MMLvectordirection\v!horizontal {
+ \left(\xmlconcat{#1}{/*}{\MMLseparator\MMLvectorseparator}\right)
} {
- \MMLcreset\left(\matrix{\xmlconcat{#1}{/*}{\MMLseparator\@@MMLvectorseparator}}\right)
+ \MMLcreset\left(\matrix{\xmlconcat{#1}{/*}{\MMLseparator\MMLvectorseparator}}\right)
}
\else
- \overrightarrow{\charhtstrut\mmlsecond{#1}}
+ \overrightarrow{\charhtstrut\mmlfirst{#1}}
\fi
\endgroup
\stopxmlsetups
@@ -1879,7 +1653,7 @@
\stopxmlsetups
\startxmlsetups mml:matrixrow:do
- \xmlconcat{#1}{/*}\crcr
+ \xmlconcat{#1}{/*}{&}\crcr
\stopxmlsetups
\startxmlsetups mml:determinant
@@ -1890,7 +1664,7 @@
\stopxmlsetups
\startxmlsetups mml:transpose
- \mmlsecond{#1}^{\mfunction{T}}
+ \mmlsecond{#1}^{\mathopnolimits{T}}
\stopxmlsetups
\startxmlsetups mml:selector
@@ -1907,6 +1681,8 @@
\xmlfirst{#1}{/(mml:annotation\string|apply)}
\stopxmlsetups
+\usemodule[m][calcmath]
+
\startxmlsetups mml:annotation
\xmldoifelse {#1} {[oneof(@encoding,'TeX','tex','TEX','ConTeXt','context','CONTEXT','ctx')]} {
\begingroup
@@ -1915,7 +1691,7 @@
\endgroup
} {
\xmldoifelse {#1} {[oneof(@encoding,'calcmath','cm')]} {
- % to be supported
+ \calcmath{\xmlflush{#1}}
} {
% unsupported
}
@@ -1928,61 +1704,69 @@
% misc
-\startxmlsetups mml:integers \integers \stopxmlsetups
-\startxmlsetups mml:reals \reals \stopxmlsetups
-\startxmlsetups mml:rationals \rationals \stopxmlsetups
-\startxmlsetups mml:naturalnumbers \naturalnumbers \stopxmlsetups
-\startxmlsetups mml:complexes \complexes \stopxmlsetups
-\startxmlsetups mml:primes \primes \stopxmlsetups
-\startxmlsetups mml:exponentiale \mathop{\rm e} \stopxmlsetups
-\startxmlsetups mml:imaginaryi \mathop{\rm i} \stopxmlsetups
-\startxmlsetups mml:notanumber \mathop{\mfunction{NaN}} \stopxmlsetups
-\startxmlsetups mml:true \mathop{\mfunction{true}} \stopxmlsetups
-\startxmlsetups mml:false \mathop{\mfunction{false}} \stopxmlsetups
-\startxmlsetups mml:emptyset \mathop{\O} \stopxmlsetups
-\startxmlsetups mml:pi \pi \stopxmlsetups
-\startxmlsetups mml:eulergamma \gamma \stopxmlsetups
-\startxmlsetups mml:infinity \infty \stopxmlsetups
+\startxmlsetups mml:integers \integers \stopxmlsetups
+\startxmlsetups mml:reals \reals \stopxmlsetups
+\startxmlsetups mml:rationals \rationals \stopxmlsetups
+\startxmlsetups mml:naturalnumbers \naturalnumbers \stopxmlsetups
+\startxmlsetups mml:complexes \complexes \stopxmlsetups
+\startxmlsetups mml:primes \primes \stopxmlsetups
+\startxmlsetups mml:exponentiale \mathopnolimits{e} \stopxmlsetups
+\startxmlsetups mml:imaginaryi \mathopnolimits{i} \stopxmlsetups
+\startxmlsetups mml:notanumber \mathopnolimits{NaN} \stopxmlsetups
+\startxmlsetups mml:true \mathopnolimits{true} \stopxmlsetups
+\startxmlsetups mml:false \mathopnolimits{false} \stopxmlsetups
+\startxmlsetups mml:emptyset \mathopnolimits{\O} \stopxmlsetups
+\startxmlsetups mml:pi \pi \stopxmlsetups
+\startxmlsetups mml:eulergamma \gamma \stopxmlsetups
+\startxmlsetups mml:infinity \infty \stopxmlsetups
% gonio functions
\setupMMLappearance[function][\c!reduction=\v!yes]
-\startxmlsetups mml:sin \mfunction {sin}\xmlsetup{#1}{mml:function} \stopxmlsetups
-\startxmlsetups mml:sinh \mfunction{sinh}\xmlsetup{#1}{mml:function} \stopxmlsetups
-\startxmlsetups mml:cos \mfunction {cos}\xmlsetup{#1}{mml:function} \stopxmlsetups
-\startxmlsetups mml:cosh \mfunction{cosh}\xmlsetup{#1}{mml:function} \stopxmlsetups
-\startxmlsetups mml:tan \mfunction {tan}\xmlsetup{#1}{mml:function} \stopxmlsetups
-\startxmlsetups mml:tanh \mfunction{tanh}\xmlsetup{#1}{mml:function} \stopxmlsetups
-\startxmlsetups mml:cot \mfunction {cot}\xmlsetup{#1}{mml:function} \stopxmlsetups
-\startxmlsetups mml:coth \mfunction{coth}\xmlsetup{#1}{mml:function} \stopxmlsetups
-\startxmlsetups mml:csc \mfunction {csc}\xmlsetup{#1}{mml:function} \stopxmlsetups
-\startxmlsetups mml:csch \mfunction{csch}\xmlsetup{#1}{mml:function} \stopxmlsetups
-\startxmlsetups mml:sec \mfunction {sec}\xmlsetup{#1}{mml:function} \stopxmlsetups
-\startxmlsetups mml:sech \mfunction{sech}\xmlsetup{#1}{mml:function} \stopxmlsetups
+% todo: \mfunction which adapts itself when registered as command
+
+\startxmlsetups mml:sin \mathopnolimits {sin}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:sinh \mathopnolimits{sinh}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:cos \mathopnolimits {cos}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:cosh \mathopnolimits{cosh}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:tan \mathopnolimits {tan}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:tanh \mathopnolimits{tanh}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:cot \mathopnolimits {cot}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:coth \mathopnolimits{coth}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:csc \mathopnolimits {csc}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:csch \mathopnolimits{csch}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:sec \mathopnolimits {sec}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:sech \mathopnolimits{sech}\xmlsetup{#1}{mml:function} \stopxmlsetups
\startxmlsetups mml:function
\ifconditional\xmlinversefunction^{-1}\fi\setfalse\xmlinversefunction
\xmlsetup{#1}{mml:function:argument}
\stopxmlsetups
- \startxmlsetups mml:function:argument
- % \doifelse \@@MMLfunctionreduction \v!yes {
- % \xmldoifelse {#1} {/mml:apply} {
- % \xmldoifelse {#1} {/(\MMLcfunctionlist\string|mml:divide} \donefalse \donetrue
- % } {
- % \donefalse
- % }
- % } {
- % \donetrue
- % }
- % beware, we still flush from 2 up
- % \ifdone
- \left(\MMLcreset\xmlall{#1}{/[position()>1]}\right)
- % \else
- % \MMLcreset\flushXMLstackfrom\plustwo
- % \fi
- \stopxmlsetups
+\startxmlsetups mml:function:argument
+ \doifelse \MMLfunctionreduction \v!yes {
+ \xmldoifelse {#1} {/mml:apply} {
+ \xmldoifelse {#1} {/mml:apply/(\MMLcfunctionlist\string|mml:divide)}
+ \donefalse
+ \donetrue
+ } {
+ \donefalse
+ }
+ } {
+ \donetrue
+ }
+ % beware, we still flush from 2 up
+ \ifdone
+ \left(
+ \MMLcreset
+ \xmlall{#1}{/[position()>1]}% \xmlconcatrange{#1}{/*}{2}{}\empty
+ \right)
+ \else
+ \MMLcreset
+ \xmlall{#1}{/[position()>1]}
+ \fi
+\stopxmlsetups
% PRESENTATION MATHML
%
@@ -2030,7 +1814,7 @@
\stoptexdefinition
\starttexdefinition applymmlsometext #1#2
- applymmlmathbackground {#1} {
+ \applymmlmathbackground {#1} {
\applymmlmathcolor {#1} {
\setmmlmathstyle {#1}
\ignorespaces#2\removeunwantedspaces
@@ -2060,50 +1844,45 @@
% setups
\startxmlsetups mml:mi % todo: mathvariant mathsize mathcolor mathbackground
- \ctxlua{lxml.mml.prepare_identifier("#1","*")}
+ \ctxlua{lxml.mml.mi("#1","*")}
\stopxmlsetups
\startxmlsetups mml:mn % todo: mathvariant mathsize mathcolor mathbackground
\begingroup
- \mr \ctxlua{lxml.mml.prepare_number("#1","*")}% no \hbox, would be ok for . , but spoils rest
+ \mr \ctxlua{lxml.mml.mn("#1","*")}% no \hbox, would be ok for . , but spoils rest
\endgroup
\stopxmlsetups
\startxmlsetups mml:mo
- \ctxlua{lxml.mml.prepare_operator("#1","*")}
+ \ctxlua{lxml.mml.mo("#1","*")}
\stopxmlsetups
\startxmlsetups mml:mfenced % {} around separator is needed for spacing
- \edef\mmlfencedopen {\xmlatt{#1}{open}}
- \edef\mmlfencedclose {\xmlatt{#1}{close}}
- \edef\mmlfencedseparators{\xmlatt{#1}{separators}}
- \ifx \mmlfencedseparators \empty
- \def\mmlfencedseparators{,}
- \fi
- \ifx \mmlfencedopen \empty
- \left.
- \else
- \left\mmlfencedopen
- \fi
- \ctxlua{lxml.mml.connect("#1","/*","\mmlfencedseparators")}%
- \ifx \mmlfencedclose \empty
- \right.
- \else
- \right\mmlfencedclose
- \fi
+ \def\MMLleft {\left }% weird
+ \def\MMLright{\right}
+ \ctxlua{lxml.mml.mfenced("#1","/*")}
\stopxmlsetups
\startxmlsetups mml:menclose % notation=.....
- \doifelse {\xmlatt{#1}{notation}} {longdiv} {
- \overline{)\xmlflush{#1}}
+ \edef\mmlmenclosenotation{\xmlattdef{#1}{notation}{longdiv}}
+ \doifelse \mmlmenclosenotation {longdiv} {
+ \overline{\left)\xmlflush{#1}\right.}
} {
- \xmlflush{#1}
+ \doifelse \mmlmenclosenotation {actuarial} {
+ \overline{\left.\xmlflush{#1}\right|}
+ } {
+ \doifelse \mmlmenclosenotation {radical} {
+ \sqrt{\xmlflush{#1}}
+ } {
+ \xmlflush{#1}
+ }
+ }
}
\stopxmlsetups
-\mapXMLvalue {mfrac:linethickness} {thin} {.2pt}
-\mapXMLvalue {mfrac:linethickness} {medium} {.4pt}
-\mapXMLvalue {mfrac:linethickness} {thick} {.8pt}
+\mapXMLvalue {mml:mfrac:linethickness} {thin} {.2pt}
+\mapXMLvalue {mml:mfrac:linethickness} {medium} {.4pt}
+\mapXMLvalue {mml:mfrac:linethickness} {thick} {.8pt}
\startxmlsetups mml:mfrac % dodo: handle linethickness in lua + unit
\begingroup
@@ -2114,16 +1893,16 @@
\mathpunct{\kern-.2ex\left.\middle/\right.\kern-.25ex}
\mmlsecond{#1}
} {
- \frac{\xmlfirst{#1}}{\mmlsecond{#1}}
+ \frac{\mmlfirst{#1}}{\mmlsecond{#1}}
}
\else
- \doifXMLvalelse {mfrac:linethickness} \mmlfraclinethickness {
- \scratchdimen\XMLval{mfrac:linethickness}\mmlfraclinethickness{.4pt}
+ \doifXMLvalelse {mml:mfrac:linethickness} \mmlfraclinethickness {
+ \scratchdimen\XMLval{mml:mfrac:linethickness}\mmlfraclinethickness{.4pt}
} {
\setdimensionwithunit\scratchdimen\mmlfraclinethickness{pt}
}
{
- {\xmlfirst{#1}}
+ {\mmlfirst{#1}}
\above\scratchdimen
{\mmlsecond{#1}}
}
@@ -2134,7 +1913,11 @@
\startxmlsetups mml:ms
\hbox {
\tf % else encoding problems
+ \edef\mmllquote{\xmlatt{#1}{lquote}}
+ \edef\mmlrquote{\xmlatt{#1}{rquote}}
+ \ifx\mmllquote\empty\symbol[leftquotation]\else\mmllquote\fi
\applymmlsometext{#1}{\xmlflush{#1}}
+ \ifx\mmlrquote\empty\symbol[rightquotation]\else\mmlrquote\fi
}
\stopxmlsetups
@@ -2166,19 +1949,42 @@
% mrow
+% \startxmlsetups mml:mrow
+% \begingroup
+% \ifcase\xmlcount{#1}{/mml:mo}\relax
+% \xmlflush{#1}
+% \else % no \let
+% \def\MMLleft {\left }
+% \def\MMLright{\right}
+% \enabledelimiter
+% \checkdelimiters{\xmlall{#1}{/mml:mo}}
+% \fakeleftdelimiter
+% \xmlflush{#1}
+% \fakerightdelimiter
+% \disabledelimiter
+% \fi
+% \endgroup
+% \stopxmlsetups
+
+% option: no fenced
+
\startxmlsetups mml:mrow
\begingroup
- \ifcase\xmlcount{#1}{/mml:mo}\relax
- \xmlflush{#1}
- \else % no \let
- \def\MMLleft {\left }
- \def\MMLright{\right}
- \enabledelimiter
- \checkdelimiters{\xmlall{#1}{/mml:mo}}
- \fakeleftdelimiter
+ \ifnum\xmlcount{#1}{/mml:mo}=\plustwo
+ \xmldoifelse {#1} {/mml:mo[position()==1 or position()==\xmlcount{#1}{/*}]} {% we need a {}
+ \def\MMLleft {\left }
+ \def\MMLright{\right}
+ \enabledelimiter
+ \checkdelimiters{\xmlall{#1}{/mml:mo}}
+ \fakeleftdelimiter
+ \xmlflush{#1}
+ \fakerightdelimiter
+ \disabledelimiter
+ } {
+ \xmlflush{#1}
+ }
+ \else
\xmlflush{#1}
- \fakerightdelimiter
- \disabledelimiter
\fi
\endgroup
\stopxmlsetups
@@ -2188,13 +1994,13 @@
\stopxmlsetups
\startxmlsetups mml:mroot
- \root{\mmlfirst{#1}}\of{\mmlsecond{#1}}
+ \root{\mmlsecond{#1}}\of{\mmlfirst{#1}}
\stopxmlsetups
\setupMMLappearance[scripts][\c!alternative=\v!a] % {} rond base
\startxmlsetups mml:msub
- \doifelse\@@MMLscriptsalternative\v!a {
+ \doifelse\MMLscriptsalternative\v!a {
{\mmlfirst{#1}}_{\mmlsecond{#1}}
} {
\mmlfirst{#1} _{\mmlsecond{#1}}
@@ -2202,7 +2008,7 @@
\stopxmlsetups
\startxmlsetups mml:msup
- \doifelse\@@MMLscriptsalternative\v!a {
+ \doifelse\MMLscriptsalternative\v!a {
{\mmlfirst{#1}}^{\mmlsecond{#1}}
} {
\mmlfirst{#1} ^{\mmlsecond{#1}}
@@ -2210,7 +2016,7 @@
\stopxmlsetups
\startxmlsetups mml:msubsup
- \doifelse\@@MMLscriptsalternative\v!a {
+ \doifelse\MMLscriptsalternative\v!a {
{\mmlfirst{#1}}_{\mmlsecond{#1}}^{\mmlthird{#1}}
} {
\mmlfirst{#1} _{\mmlsecond{#1}}^{\mmlthird{#1}}
@@ -2266,7 +2072,7 @@
% tables (mml:mtable, mml:mtr, mml:mlabledtr, mml:mtd)
\startxmlsetups mml:mtable % some more attributes need to be supported
- \ctxlua{lxml.mml.mtable("#1")}
+ \vcenter{\ctxlua{lxml.mml.mtable("#1")}}
\stopxmlsetups
\startxmlsetups mml:mspace % complete
@@ -2290,8 +2096,8 @@
\startxmlsetups mml:mglyph % probably never ok
\begingroup
\edef\mmlglyphfontfamily{\xmlatt {#1}{fontfamily}}
- \edef\mmlglyphalt {\xmlattdef{#1}{fontfamily}{unknown}}
- \edef\mmlglyphindex {\xmlatt {#1}{fontfamily}}
+ \edef\mmlglyphalt {\xmlattdef{#1}{alt}{unknown}}
+ \edef\mmlglyphindex {\xmlatt {#1}{index}}
\ifx \mmlglyphfontfamily \empty
\hbox{\tttf[no fontfamily specified for \mmlglyphalt]}
\else\ifx\mmlglyphindex\empty
@@ -2350,8 +2156,8 @@
% </apply>
% </apply>
-\startxmlsetups mmc:minus
- \doif \@@MMLsignreduction \v!yes {
+\startxmlsetups mml:minus
+ \doif \MMLsignreduction \v!yes {
\setMMLcreset{fn,\MMLcfunctionlist}
}
\ifcase\XMLstacklevel
diff --git a/tex/context/base/x-mmp.mkiv b/tex/context/base/x-mmp.mkiv
index 1b5dd97b3..dff7ade58 100644
--- a/tex/context/base/x-mmp.mkiv
+++ b/tex/context/base/x-mmp.mkiv
@@ -46,60 +46,61 @@
[" "] = "",
}
local i_replacements = {
- ["sin"] = "\\mmlnolim{sin}",
- ["cos"] = "\\mmlnolim{cos}",
- ["abs"] = "\\mmlnolim{abs}",
- ["arg"] = "\\mmlnolim{arg}",
- ["codomain"] = "\\mmlnolim{codomain}",
- ["curl"] = "\\mmlnolim{curl}",
- ["determinant"] = "\\mmlnolim{det}",
- ["divergence"] = "\\mmlnolim{div}",
- ["domain"] = "\\mmlnolim{domain}",
- ["false"] = "\\mmlnolim{false}",
- ["gcd"] = "\\mmlnolim{gcd}",
- ["grad"] = "\\mmlnolim{grad}",
- ["identity"] = "\\mmlnolim{id}",
- ["image"] = "\\mmlnolim{image}",
- ["lcm"] = "\\mmlnolim{lcm}",
- ["max"] = "\\mmlnolim{max}",
- ["median"] = "\\mmlnolim{median}",
- ["min"] = "\\mmlnolim{min}",
- ["mode"] = "\\mmlnolim{mode}",
- ["mod"] = "\\mmlnolim{mod}",
- ["notanumber"] = "\\mmlnolim{NaN}",
- ["otherwise"] = "\\mmlnolim{otherwise}",
- ["true"] = "\\mmlnolim{true}",
- ["declare"] = "\\mmlnolim{declare}",
- ["as"] = "\\mmlnolim{as}",
- ["polar"] = "\\mmlnolim{Polar}",
- ["exp"] = "\\mmlnolim{exp}",
- ["ln"] = "\\mmlnolim{ln}",
- ["log"] = "\\mmlnolim{log}",
- ["sin"] = "\\mmlnolim{sin}",
- ["arcsin"] = "\\mmlnolim{arcsin}",
- ["sinh"] = "\\mmlnolim{sinh}",
- ["arcsinh"] = "\\mmlnolim{arcsinh}",
- ["cos"] = "\\mmlnolim{cos}",
- ["arccos"] = "\\mmlnolim{arccos}",
- ["cosh"] = "\\mmlnolim{cosh}",
- ["arccosh"] = "\\mmlnolim{arccosh}",
- ["tan"] = "\\mmlnolim{tan}",
- ["arctan"] = "\\mmlnolim{arctan}",
- ["tanh"] = "\\mmlnolim{tanh}",
- ["arctanh"] = "\\mmlnolim{arctanh}",
- ["cot"] = "\\mmlnolim{cot}",
- ["arccot"] = "\\mmlnolim{arccot}",
- ["coth"] = "\\mmlnolim{coth}",
- ["arccoth"] = "\\mmlnolim{arccoth}",
- ["csc"] = "\\mmlnolim{csc}",
- ["arccsc"] = "\\mmlnolim{arccsc}",
- ["csch"] = "\\mmlnolim{csch}",
- ["arccsch"] = "\\mmlnolim{arccsch}",
- ["sec"] = "\\mmlnolim{sec}",
- ["arcsec"] = "\\mmlnolim{arcsec}",
- ["sech"] = "\\mmlnolim{sech}",
- ["arcsech"] = "\\mmlnolim{arcsech}",
+ ["sin"] = "\\mathopnolimits{sin}",
+ ["cos"] = "\\mathopnolimits{cos}",
+ ["abs"] = "\\mathopnolimits{abs}",
+ ["arg"] = "\\mathopnolimits{arg}",
+ ["codomain"] = "\\mathopnolimits{codomain}",
+ ["curl"] = "\\mathopnolimits{curl}",
+ ["determinant"] = "\\mathopnolimits{det}",
+ ["divergence"] = "\\mathopnolimits{div}",
+ ["domain"] = "\\mathopnolimits{domain}",
+ ["gcd"] = "\\mathopnolimits{gcd}",
+ ["grad"] = "\\mathopnolimits{grad}",
+ ["identity"] = "\\mathopnolimits{id}",
+ ["image"] = "\\mathopnolimits{image}",
+ ["lcm"] = "\\mathopnolimits{lcm}",
+ ["max"] = "\\mathopnolimits{max}",
+ ["median"] = "\\mathopnolimits{median}",
+ ["min"] = "\\mathopnolimits{min}",
+ ["mode"] = "\\mathopnolimits{mode}",
+ ["mod"] = "\\mathopnolimits{mod}",
+ ["polar"] = "\\mathopnolimits{Polar}",
+ ["exp"] = "\\mathopnolimits{exp}",
+ ["ln"] = "\\mathopnolimits{ln}",
+ ["log"] = "\\mathopnolimits{log}",
+ ["sin"] = "\\mathopnolimits{sin}",
+ ["arcsin"] = "\\mathopnolimits{arcsin}",
+ ["sinh"] = "\\mathopnolimits{sinh}",
+ ["arcsinh"] = "\\mathopnolimits{arcsinh}",
+ ["cos"] = "\\mathopnolimits{cos}",
+ ["arccos"] = "\\mathopnolimits{arccos}",
+ ["cosh"] = "\\mathopnolimits{cosh}",
+ ["arccosh"] = "\\mathopnolimits{arccosh}",
+ ["tan"] = "\\mathopnolimits{tan}",
+ ["arctan"] = "\\mathopnolimits{arctan}",
+ ["tanh"] = "\\mathopnolimits{tanh}",
+ ["arctanh"] = "\\mathopnolimits{arctanh}",
+ ["cot"] = "\\mathopnolimits{cot}",
+ ["arccot"] = "\\mathopnolimits{arccot}",
+ ["coth"] = "\\mathopnolimits{coth}",
+ ["arccoth"] = "\\mathopnolimits{arccoth}",
+ ["csc"] = "\\mathopnolimits{csc}",
+ ["arccsc"] = "\\mathopnolimits{arccsc}",
+ ["csch"] = "\\mathopnolimits{csch}",
+ ["arccsch"] = "\\mathopnolimits{arccsch}",
+ ["sec"] = "\\mathopnolimits{sec}",
+ ["arcsec"] = "\\mathopnolimits{arcsec}",
+ ["sech"] = "\\mathopnolimits{sech}",
+ ["arcsech"] = "\\mathopnolimits{arcsech}",
[" "] = "",
+
+ ["false"] = "{\\mr false}",
+ ["notanumber"] = "{\\mr NaN}",
+ ["otherwise"] = "{\\mr otherwise}",
+ ["true"] = "{\\mr true}",
+ ["declare"] = "{\\mr declare}",
+ ["as"] = "{\\mr as}",
}
function lxml.mml.prepare_number(id,pattern)
diff --git a/tex/context/interface/keys-cz.xml b/tex/context/interface/keys-cz.xml
index 70473fe3b..0cc095221 100644
--- a/tex/context/interface/keys-cz.xml
+++ b/tex/context/interface/keys-cz.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="cz" version="2008.05.13 14:42">
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="cz" version="2008.05.21 15:21">
<cd:variables>
<cd:variable name="lesshyphenation" value="lesshyphenation"/>
diff --git a/tex/context/interface/keys-de.xml b/tex/context/interface/keys-de.xml
index 430b09aab..26c687b0b 100644
--- a/tex/context/interface/keys-de.xml
+++ b/tex/context/interface/keys-de.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="de" version="2008.05.13 14:42">
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="de" version="2008.05.21 15:21">
<cd:variables>
<cd:variable name="lesshyphenation" value="lesshyphenation"/>
diff --git a/tex/context/interface/keys-en.xml b/tex/context/interface/keys-en.xml
index d9b93f10d..b627027a9 100644
--- a/tex/context/interface/keys-en.xml
+++ b/tex/context/interface/keys-en.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="en" version="2008.05.13 14:42">
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="en" version="2008.05.21 15:21">
<cd:variables>
<cd:variable name="lesshyphenation" value="lesshyphenation"/>
diff --git a/tex/context/interface/keys-fr.xml b/tex/context/interface/keys-fr.xml
index 320cd677b..be8429449 100644
--- a/tex/context/interface/keys-fr.xml
+++ b/tex/context/interface/keys-fr.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="fr" version="2008.05.13 14:42">
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="fr" version="2008.05.21 15:21">
<cd:variables>
<cd:variable name="lesshyphenation" value="lesshyphenation"/>
diff --git a/tex/context/interface/keys-it.xml b/tex/context/interface/keys-it.xml
index 4e929bd87..0f0fbbd51 100644
--- a/tex/context/interface/keys-it.xml
+++ b/tex/context/interface/keys-it.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="it" version="2008.05.13 14:42">
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="it" version="2008.05.21 15:21">
<cd:variables>
<cd:variable name="lesshyphenation" value="lesshyphenation"/>
diff --git a/tex/context/interface/keys-nl.xml b/tex/context/interface/keys-nl.xml
index 0986c4f3b..437059374 100644
--- a/tex/context/interface/keys-nl.xml
+++ b/tex/context/interface/keys-nl.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="nl" version="2008.05.13 14:42">
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="nl" version="2008.05.21 15:21">
<cd:variables>
<cd:variable name="lesshyphenation" value="lesshyphenation"/>
diff --git a/tex/context/interface/keys-ro.xml b/tex/context/interface/keys-ro.xml
index 10c9d75d0..8ef0f6158 100644
--- a/tex/context/interface/keys-ro.xml
+++ b/tex/context/interface/keys-ro.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="ro" version="2008.05.13 14:42">
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="ro" version="2008.05.21 15:21">
<cd:variables>
<cd:variable name="lesshyphenation" value="lesshyphenation"/>
diff --git a/web2c/contextcnf.lua b/web2c/contextcnf.lua
new file mode 100644
index 000000000..d2708a925
--- /dev/null
+++ b/web2c/contextcnf.lua
@@ -0,0 +1,36 @@
+-- filename : texmfcnf.lua
+-- comment : companion to luatex/mkiv
+-- authors : Hans Hagen & Taco Hoekwater
+-- copyright: not relevant
+-- license : not relevant
+
+-- This file is read bij luatools, mtxrun and context mkiv. This is still
+-- somewhat experimental and eventually we will support booleans instead
+-- of the 't' strings. The content is similar to that of texmf.cnf. Both
+-- namespaces strings
+--
+-- TEXINPUT.context = "..."
+--
+-- and subtables (
+--
+-- context = { TEXINPUT = ".." }
+--
+-- are supported with the later a being the way to go. You can test settings
+-- with:
+--
+-- luatools --expand-var TEXMFBOGUS
+--
+-- which should return
+--
+-- It works!
+--
+-- We first read the lua configuration file(s) and then do a first variable
+-- expansion pass. Next we read the regular cnf files. These are cached
+-- in the mkiv cache for faster loading. The lua configuration files are
+-- not cached.
+
+return {
+-- PURGECACHE = 't', -- this saves disk space
+-- TEXMFCACHE = 'c:/temp', -- installers can change this
+ TEXMFBOGUS = 'It works!', -- a test string
+}