From 612f23ed1b01240fdc9ca5132dbd3164e96ed570 Mon Sep 17 00:00:00 2001
From: Hans Hagen
Date: Mon, 11 Apr 2011 16:45:00 +0200
Subject: beta 2011.04.11 16:45
---
metapost/context/base/mp-mlib.mp | 18 +-
metapost/context/base/mp-tool.mp | 1 +
scripts/context/lua/mtxrun.lua | 306 +++++++---
scripts/context/stubs/mswin/mtxrun.lua | 306 +++++++---
scripts/context/stubs/unix/mtxrun | 306 +++++++---
tex/context/base/anch-pos.lua | 20 +-
tex/context/base/attr-col.lua | 19 +-
tex/context/base/attr-eff.lua | 36 +-
tex/context/base/attr-ini.mkiv | 1 +
tex/context/base/attr-lay.lua | 7 +-
tex/context/base/attr-neg.lua | 32 +-
tex/context/base/back-exp.lua | 798 +++++++++++++++++--------
tex/context/base/back-exp.mkiv | 27 +-
tex/context/base/back-ini.lua | 40 +-
tex/context/base/back-pdf.lua | 2 +
tex/context/base/buff-ver.lua | 33 +-
tex/context/base/buff-ver.mkiv | 16 +-
tex/context/base/char-ini.lua | 64 +-
tex/context/base/cldf-ini.lua | 58 +-
tex/context/base/cldf-ini.mkiv | 3 +
tex/context/base/cldf-int.lua | 55 +-
tex/context/base/cldf-int.mkiv | 12 +-
tex/context/base/cont-new.mkii | 2 +-
tex/context/base/cont-new.mkiv | 2 +-
tex/context/base/context.mkii | 2 +-
tex/context/base/context.mkiv | 2 +-
tex/context/base/core-con.lua | 173 +++++-
tex/context/base/core-con.mkiv | 241 ++++----
tex/context/base/core-env.lua | 114 ++--
tex/context/base/core-two.lua | 11 +-
tex/context/base/core-uti.lua | 32 +-
tex/context/base/data-env.lua | 26 +-
tex/context/base/data-res.lua | 30 +-
tex/context/base/data-tmp.lua | 6 +-
tex/context/base/font-col.lua | 4 +-
tex/context/base/font-col.mkiv | 4 +-
tex/context/base/font-con.lua | 27 +-
tex/context/base/font-ctx.lua | 40 +-
tex/context/base/font-def.lua | 23 +-
tex/context/base/font-enc.lua | 6 +-
tex/context/base/font-gds.lua | 73 ++-
tex/context/base/font-ini.mkiv | 2 +-
tex/context/base/font-log.lua | 2 +-
tex/context/base/font-mis.lua | 2 +-
tex/context/base/font-ota.lua | 9 +-
tex/context/base/font-otc.lua | 304 +++++-----
tex/context/base/font-otd.lua | 18 +-
tex/context/base/font-otf.lua | 122 ++--
tex/context/base/font-otn.lua | 56 +-
tex/context/base/font-ott.lua | 43 +-
tex/context/base/font-vf.lua | 29 +-
tex/context/base/grph-fil.lua | 9 +-
tex/context/base/grph-inc.lua | 29 +-
tex/context/base/l-dimen.lua | 434 --------------
tex/context/base/l-file.lua | 2 -
tex/context/base/l-md5.lua | 6 +-
tex/context/base/l-table.lua | 52 +-
tex/context/base/lang-def.lua | 32 +-
tex/context/base/lang-def.mkiv | 35 --
tex/context/base/lang-ini.lua | 13 +-
tex/context/base/lang-lab.lua | 1 -
tex/context/base/lang-url.lua | 6 +-
tex/context/base/lang-url.mkiv | 2 +-
tex/context/base/luat-bas.mkiv | 2 -
tex/context/base/luat-lib.mkiv | 3 +-
tex/context/base/luat-mac.lua | 12 +-
tex/context/base/lxml-aux.lua | 41 +-
tex/context/base/lxml-lpt.lua | 13 +-
tex/context/base/math-tag.lua | 10 +-
tex/context/base/math-vfu.lua | 31 +-
tex/context/base/mlib-pps.lua | 74 +--
tex/context/base/mult-ini.lua | 51 +-
tex/context/base/node-aux.lua | 25 +-
tex/context/base/node-fnt.lua | 72 ++-
tex/context/base/node-ref.lua | 2 +-
tex/context/base/node-spl.lua | 2 +-
tex/context/base/pack-obj.lua | 9 +-
tex/context/base/regi-ini.lua | 9 +-
tex/context/base/s-inf-03.mkiv | 352 +++++++++++
tex/context/base/scrn-ini.lua | 9 +
tex/context/base/sort-ini.lua | 11 +-
tex/context/base/sort-lan.lua | 2 +-
tex/context/base/spac-ali.mkiv | 4 +-
tex/context/base/spac-grd.mkiv | 9 +-
tex/context/base/spac-ver.mkiv | 3 -
tex/context/base/status-files.pdf | Bin 23594 -> 23588 bytes
tex/context/base/status-lua.pdf | Bin 0 -> 154910 bytes
tex/context/base/strc-blk.lua | 20 +-
tex/context/base/strc-doc.lua | 16 +-
tex/context/base/strc-ini.lua | 9 +-
tex/context/base/strc-lst.lua | 19 +-
tex/context/base/strc-lst.mkiv | 8 +-
tex/context/base/strc-mar.lua | 21 +-
tex/context/base/strc-num.lua | 28 +-
tex/context/base/strc-pag.lua | 4 +-
tex/context/base/strc-ref.lua | 35 +-
tex/context/base/strc-ref.mkiv | 60 +-
tex/context/base/strc-reg.lua | 16 +-
tex/context/base/strc-ren.mkiv | 8 +-
tex/context/base/strc-syn.lua | 16 +-
tex/context/base/strc-syn.mkiv | 11 +
tex/context/base/strc-tag.lua | 29 +-
tex/context/base/strc-tag.mkiv | 4 +
tex/context/base/supp-box.lua | 4 +-
tex/context/base/supp-fil.lua | 4 +-
tex/context/base/trac-log.lua | 8 +-
tex/context/base/util-deb.lua | 2 +-
tex/context/base/util-dim.lua | 436 ++++++++++++++
tex/context/base/util-prs.lua | 16 +-
tex/context/base/util-seq.lua | 4 +-
tex/context/base/util-sto.lua | 85 ++-
tex/context/base/util-tab.lua | 19 +-
tex/context/base/x-set-11.mkiv | 27 +-
tex/context/base/x-set-12.mkiv | 166 ++---
tex/generic/context/luatex-basics-gen.lua | 6 +
tex/generic/context/luatex-fonts-demo-vf-1.lua | 4 +-
tex/generic/context/luatex-fonts-merged.lua | 299 +++++----
tex/generic/context/luatex-test.tex | 4 +
118 files changed, 3965 insertions(+), 2355 deletions(-)
delete mode 100644 tex/context/base/l-dimen.lua
create mode 100644 tex/context/base/s-inf-03.mkiv
create mode 100644 tex/context/base/status-lua.pdf
create mode 100644 tex/context/base/util-dim.lua
diff --git a/metapost/context/base/mp-mlib.mp b/metapost/context/base/mp-mlib.mp
index e812df61e..11f096c18 100644
--- a/metapost/context/base/mp-mlib.mp
+++ b/metapost/context/base/mp-mlib.mp
@@ -31,6 +31,20 @@ newinternal lightentransparent ; lightentransparent := 10 ;
newinternal differencetransparent ; differencetransparent := 11 ;
newinternal exclusiontransparent ; exclusiontransparent := 12 ;
+vardef transparency_alternative_to_number(expr name) =
+ if string name :
+ if expandafter known scantokens(name & "transparent") :
+ scantokens(name & "transparent")
+ else :
+ 0
+ fi
+ elseif name < 13 :
+ name
+ else :
+ 0
+ fi
+enddef ;
+
def spotcolor(expr n, v) =
1
withprescript "sp_name=" & n
@@ -47,12 +61,12 @@ enddef ;
def transparent(expr alternative, transparency)(text c) =
c
- withprescript "tr_alternative=" & decimal alternative
+ withprescript "tr_alternative=" & decimal transparency_alternative_to_number(alternative)
withprescript "tr_transparency=" & decimal transparency
enddef ;
def withtransparency(expr alternative, transparency) =
- withprescript "tr_alternative=" & decimal alternative
+ withprescript "tr_alternative=" & decimal transparency_alternative_to_number(alternative)
withprescript "tr_transparency=" & decimal transparency
enddef ;
diff --git a/metapost/context/base/mp-tool.mp b/metapost/context/base/mp-tool.mp
index 1a748baf9..7f047fefc 100644
--- a/metapost/context/base/mp-tool.mp
+++ b/metapost/context/base/mp-tool.mp
@@ -251,6 +251,7 @@ def newtransform text v = forsuffixes i=v : save i ; transform i ; endfor ; endd
def newpath text v = forsuffixes i=v : save i ; path i ; endfor ; enddef ;
def newpicture text v = forsuffixes i=v : save i ; picture i ; endfor ; enddef ;
def newstring text v = forsuffixes i=v : save i ; string i ; endfor ; enddef ;
+def newpair text v = forsuffixes i=v : save i ; pair i ; endfor ; enddef ;
%D Sometimes we don't want parts of the graphics add to the
%D bounding box. One way of doing this is to save the bounding
diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua
index 6a3df03d0..e0fc8d823 100644
--- a/scripts/context/lua/mtxrun.lua
+++ b/scripts/context/lua/mtxrun.lua
@@ -971,10 +971,6 @@ function table.fromhash(t)
return hsh
end
-table.serialize_functions = true
-table.serialize_compact = true
-table.serialize_inline = true
-
local noquotes, hexify, handle, reduce, compact, inline, functions
local reserved = table.tohash { -- intercept a language inconvenience: no reserved words as key
@@ -1257,15 +1253,36 @@ end
-- replacing handle by a direct t[#t+1] = ... (plus test) is not much
-- faster (0.03 on 1.00 for zapfino.tma)
-local function serialize(root,name,_handle,_reduce,_noquotes,_hexify)
- noquotes = _noquotes
- hexify = _hexify
- handle = _handle or print
- reduce = _reduce or false
- compact = table.serialize_compact
- inline = compact and table.serialize_inline
- functions = table.serialize_functions
+local function serialize(root,name,_handle,_reduce,_noquotes,_hexify) -- I might drop the _'s some day.
local tname = type(name)
+ if tname == "table" then
+ noquotes = name.noquotes
+ hexify = name.hexify
+ handle = name.handle or print
+ reduce = name.reduce or false
+ functions = name.functions
+ compact = name.compact
+ inline = name.inline and compact
+ name = name.name
+ tname = type(name)
+ if functions == nil then
+ functions = true
+ end
+ if compact == nil then
+ compact = true
+ end
+ if inline == nil then
+ inline = compact
+ end
+ else
+ noquotes = _noquotes
+ hexify = _hexify
+ handle = _handle or print
+ reduce = _reduce or false
+ compact = true
+ inline = true
+ functions = true
+ end
if tname == "string" then
if name == "return" then
handle("return {")
@@ -1324,12 +1341,11 @@ end
--
-- so this is on the todo list
-table.tofile_maxtab = 2*1024
+local maxtab = 2*1024
function table.tofile(filename,root,name,reduce,noquotes,hexify)
local f = io.open(filename,'w')
if f then
- local maxtab = table.tofile_maxtab
if maxtab > 1 then
local t, n = { }, 0
local function flush(s)
@@ -1532,8 +1548,12 @@ function table.sequenced(t,sep,simple) -- hash only
return concat(s, sep or " | ")
end
-function table.print(...)
- table.tohandle(print,...)
+function table.print(t,...)
+ if type(t) ~= "table" then
+ print(tostring(t))
+ else
+ table.tohandle(print,t,...)
+ end
end
-- -- -- obsolete but we keep them for a while and might comment them later -- -- --
@@ -2535,8 +2555,6 @@ function file.collapsepath(str,anchor)
end
end
-file.collapse_path = file.collapsepath
-
function file.robustname(str,strict)
str = gsub(str,"[^%a%d%/%-%.\\]+","-")
@@ -2651,14 +2669,12 @@ if not md5.hex then function md5.hex(str) return convert(str,"%02x") end end
if not md5.dec then function md5.dec(str) return convert(str,"%03i") end end
-file.needs_updating_threshold = 1
-
-function file.needs_updating(oldname,newname) -- size modification access change
+function file.needs_updating(oldname,newname,threshold) -- size modification access change
local oldtime = lfs.attributes(oldname, modification)
local newtime = lfs.attributes(newname, modification)
if newtime >= oldtime then
return false
- elseif oldtime - newtime < file.needs_updating_threshold then
+ elseif oldtime - newtime < (threshold or 1) then
return false
else
return true
@@ -3666,7 +3682,7 @@ local tables = utilities.tables
local format, gmatch = string.format, string.gmatch
local concat, insert, remove = table.concat, table.insert, table.remove
-local setmetatable, tonumber, tostring = setmetatable, tonumber, tostring
+local setmetatable, getmetatable, tonumber, tostring = setmetatable, getmetatable, tonumber, tostring
function tables.definetable(target) -- defines undefined tables
local composed, t, n = nil, { }, 0
@@ -3731,12 +3747,6 @@ function tables.insertaftervalue(t,value,extra)
insert(t,#t+1,extra)
end
-local _empty_table_ = { __index = function(t,k) return "" end }
-
-function table.setemptymetatable(t)
- setmetatable(t,_empty_table_)
-end
-
-- experimental
local function toxml(t,d,result)
@@ -3753,9 +3763,14 @@ local function toxml(t,d,result)
end
end
-function table.toxml(t,name)
- local result = { "" }
- toxml( { [name or "root"] = t }, "", result)
+function table.toxml(t,name,nobanner)
+ local noroot = name == false
+ local result = (nobanner or noroot) and { } or { "" }
+ if noroot then
+ toxml( t, "", result)
+ else
+ toxml( { [name or "root"] = t }, "", result)
+ end
return concat(result,"\n")
end
@@ -3816,20 +3831,6 @@ function storage.checked(t)
return t
end
-function setmetatablekey(t,key,value)
- local m = getmetatable(t)
- if not m then
- m = { }
- setmetatable(t,m)
- end
- m[key] = value
-end
-
-function getmetatablekey(t,key,value)
- local m = getmetatable(t)
- return m and m[key]
-end
-
function storage.setinitializer(data,initialize)
local m = getmetatable(data) or { }
@@ -3852,6 +3853,77 @@ function storage.sparse(t)
return t
end
+-- table namespace ?
+
+local function f_empty () return "" end -- t,k
+local function f_self (t,k) t[k] = k return k end
+local function f_ignore() end -- t,k,v
+
+local t_empty = { __index = empty }
+local t_self = { __index = self }
+local t_ignore = { __newindex = ignore }
+
+function table.setmetatableindex(t,f)
+ local m = getmetatable(t)
+ if m then
+ if f == "empty" then
+ m.__index = f_empty
+ elseif f == "key" then
+ m.__index = f_self
+ else
+ m.__index = f
+ end
+ else
+ if f == "empty" then
+ setmetatable(t, t_empty)
+ elseif f == "key" then
+ setmetatable(t, t_self)
+ else
+ setmetatable(t,{ __index = f })
+ end
+ end
+end
+
+function table.setmetatablenewindex(t,f)
+ local m = getmetatable(t)
+ if m then
+ if f == "ignore" then
+ m.__newindex = f_ignore
+ else
+ m.__newindex = f
+ end
+ else
+ if f == "ignore" then
+ setmetatable(t, t_ignore)
+ else
+ setmetatable(t,{ __newindex = f })
+ end
+ end
+end
+
+function table.setmetatablecall(t,f)
+ local m = getmetatable(t)
+ if m then
+ m.__call = f
+ else
+ setmetatable(t,{ __call = f })
+ end
+end
+
+function table.setmetatablekey(t,key,value)
+ local m = getmetatable(t)
+ if not m then
+ m = { }
+ setmetatable(t,m)
+ end
+ m[key] = value
+end
+
+function table.getmetatablekey(t,key,value)
+ local m = getmetatable(t)
+ return m and m[key]
+end
+
end -- of closure
@@ -4047,18 +4119,20 @@ if not modules then modules = { } end modules ['util-prs'] = {
license = "see context related readme files"
}
+local P, R, V, C, Ct, Carg = lpeg.P, lpeg.R, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Carg
+local lpegmatch = lpeg.match
+local concat, format, gmatch = table.concat, string.format, string.gmatch
+local tostring, type, next = tostring, type, next
+
utilities = utilities or {}
utilities.parsers = utilities.parsers or { }
local parsers = utilities.parsers
parsers.patterns = parsers.patterns or { }
--- we could use a Cf Cg construct
+local setmetatableindex = table.setmetatableindex
+local sortedhash = table.sortedhash
-local P, R, V, C, Ct, Carg = lpeg.P, lpeg.R, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Carg
-local lpegmatch = lpeg.match
-local concat, format, gmatch = table.concat, string.format, string.gmatch
-local tostring, type, next, setmetatable = tostring, type, next, setmetatable
-local sortedhash = table.sortedhash
+-- we could use a Cf Cg construct
local escape, left, right = P("\\"), P('{'), P('}')
@@ -4257,7 +4331,7 @@ function parsers.getparameters(self,class,parentclass,settings)
sp = { }
self[parentclass] = sp
end
- setmetatable(sc, { __index = sp })
+ setmetatableindex(sc,sp)
end
end
parsers.settings_to_hash(settings,sc)
@@ -4474,7 +4548,7 @@ end
local is_node = node and node.is_node
-function inspect(i)
+function inspect(i) -- global function
local ti = type(i)
if ti == "table" then
table.print(i,"table")
@@ -5044,6 +5118,8 @@ local escapedpattern = string.escapedpattern
local texcount = tex and tex.count
local next, type = next, type
+local setmetatableindex = table.setmetatableindex
+
--[[ldx--
This is a prelude to a more extensive logging module. We no longer
provide based logging a sparsing is relatively easy anyway.
@@ -5064,11 +5140,11 @@ wiki : http://contextgarden.net
local function ignore() end
-setmetatable(logs, { __index = function(t,k) t[k] = ignore ; return ignore end })
+setmetatableindex(logs, function(t,k) t[k] = ignore ; return ignore end)
-local report, subreport, status, settarget, setformatter
+local report, subreport, status, settarget, setformats, settranslations
-local direct, subdirect, writer
+local direct, subdirect, writer, pushtarget, poptarget
if tex and tex.jobname or tex.formatname then
@@ -7308,6 +7384,8 @@ local type, next, tonumber, tostring, setmetatable, loadstring = type, next, ton
local format, upper, lower, gmatch, gsub, find, rep = string.format, string.upper, string.lower, string.gmatch, string.gsub, string.find, string.rep
local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
+local setmetatableindex = table.setmetatableindex
+
-- beware, this is not xpath ... e.g. position is different (currently) and
-- we have reverse-sibling as reversed preceding sibling
@@ -7380,8 +7458,8 @@ local function fallback (t, name)
return fn
end
-setmetatable(finalizers.xml, { __index = fallback })
-setmetatable(finalizers.tex, { __index = fallback })
+setmetatableindex(finalizers.xml, fallback)
+setmetatableindex(finalizers.tex, fallback)
xml.defaultprotocol = "xml"
@@ -8078,14 +8156,13 @@ xml.nodesettostring = nodesettostring
local lpath -- we have a harmless kind of circular reference
+local lshowoptions = { name = false, functions = false }
+
local function lshow(parsed)
if type(parsed) == "string" then
parsed = lpath(parsed)
end
- local s = table.serialize_functions -- ugly
- table.serialize_functions = false -- ugly
- report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,table.serialize(parsed,false))
- table.serialize_functions = s -- ugly
+ report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,table.serialize(parsed,lshowoptions))
end
xml.lshow = lshow
@@ -8679,8 +8756,8 @@ local xmlconvert, xmlcopy, xmlname = xml.convert, xml.copy, xml.name
local xmlinheritedconvert = xml.inheritedconvert
local xmlapplylpath = xml.applylpath
-local type = type
-local insert, remove = table.insert, table.remove
+local type, setmetatable, getmetatable = type, setmetatable, getmetatable
+local insert, remove, fastcopy = table.insert, table.remove, table.fastcopy
local gmatch, gsub = string.gmatch, string.gsub
local function report(what,pattern,c,e)
@@ -8889,6 +8966,41 @@ function xml.replace(root,pattern,whatever)
end
end
+local function wrap(e,wrapper)
+ local t = {
+ rn = e.rn,
+ tg = e.tg,
+ ns = e.ns,
+ at = e.at,
+ dt = e.dt,
+ __p__ = e,
+ }
+ setmetatable(t,getmetatable(e))
+ e.rn = wrapper.rn or e.rn or ""
+ e.tg = wrapper.tg or e.tg or ""
+ e.ns = wrapper.ns or e.ns or ""
+ e.at = fastcopy(wrapper.at)
+ e.dt = { t }
+end
+
+function xml.wrap(root,pattern,whatever)
+ if whatever then
+ local wrapper = xmltoelement(whatever,root)
+ local collected = xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e = collected[c]
+ if trace_manipulations then
+ report('wrapping',pattern,c,e)
+ end
+ wrap(e,wrapper)
+ end
+ end
+ else
+ wrap(root,xmltoelement(pattern))
+ end
+end
+
local function inject_element(root,pattern,whatever,prepend)
local element = root and xmltoelement(whatever,root)
local collected = element and xmlapplylpath(root,pattern)
@@ -8959,7 +9071,7 @@ local function include(xmldata,pattern,attribute,recursive,loaddata)
local ekat = ek.at
local epdt = ek.__p__.dt
if not attribute or attribute == "" then
- name = (type(ekdt) == "table" and ekdt[1]) or ekdt -- ckeck, probably always tab or str
+ name = (type(ekdt) == "table" and ekdt[1]) or ekdt -- check, probably always tab or str
end
if not name then
for a in gmatch(attribute or "href","([^|]+)") do
@@ -10039,17 +10151,23 @@ if not modules then modules = { } end modules ['data-env'] = {
license = "see context related readme files",
}
-local allocate = utilities.storage.allocate
local lower, gsub = string.lower, string.gsub
-local fileextname = file.extname
-
local resolvers = resolvers
-local formats = allocate() resolvers.formats = formats
-local suffixes = allocate() resolvers.suffixes = suffixes
-local dangerous = allocate() resolvers.dangerous = dangerous
-local suffixmap = allocate() resolvers.suffixmap = suffixmap
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
+local fileextname = file.extname
+
+local formats = allocate()
+local suffixes = allocate()
+local dangerous = allocate()
+local suffixmap = allocate()
+
+resolvers.formats = formats
+resolvers.suffixes = suffixes
+resolvers.dangerous = dangerous
+resolvers.suffixmap = suffixmap
local relations = allocate { -- todo: handlers also here
core = {
@@ -10261,9 +10379,9 @@ local function simplified(t,k)
return rawget(t,lower(gsub(k," ","")))
end
-setmetatablekey(formats, "__index", simplified)
-setmetatablekey(suffixes, "__index", simplified)
-setmetatablekey(suffixmap, "__index", simplified)
+setmetatableindex(formats, simplified)
+setmetatableindex(suffixes, simplified)
+setmetatableindex(suffixmap, simplified)
-- A few accessors, mostly for command line tool.
@@ -10611,6 +10729,8 @@ function caches.is_writable(filepath,filename)
return file.is_writable(tmaname)
end
+local saveoptions = { name = "return", reduce = true }
+
function caches.savedata(filepath,filename,data,raw)
local tmaname, tmcname = caches.setluanames(filepath,filename)
local reduce, simplify = true, true
@@ -10619,9 +10739,9 @@ function caches.savedata(filepath,filename,data,raw)
end
data.cache_uuid = os.uuid()
if caches.direct then
- file.savedata(tmaname, table.serialize(data,'return',false,true,false)) -- no hex
+ file.savedata(tmaname,table.serialize(data,saveoptions))
else
- table.tofile(tmaname, data,'return',false,true,false) -- maybe not the last true
+ table.tofile(tmaname,data,saveoptions)
end
utilities.lua.compile(tmaname,tmcname)
end
@@ -10865,15 +10985,20 @@ if not modules then modules = { } end modules ['data-res'] = {
local format, gsub, find, lower, upper, match, gmatch = string.format, string.gsub, string.find, string.lower, string.upper, string.match, string.gmatch
local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys
-local next, type, rawget, setmetatable, getmetatable = next, type, rawget, setmetatable, getmetatable
+local next, type, rawget = next, type, rawget
local os = os
local P, S, R, C, Cc, Cs, Ct, Carg = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Carg
local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
-local filedirname, filebasename, fileextname, filejoin = file.dirname, file.basename, file.extname, file.join
-local collapsepath, joinpath = file.collapsepath, file.joinpath
-local allocate = utilities.storage.allocate
+local filedirname = file.dirname
+local filebasename = file.basename
+local fileextname = file.extname
+local filejoin = file.join
+local collapsepath = file.collapsepath
+local joinpath = file.joinpath
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end)
local trace_detail = false trackers.register("resolvers.details", function(v) trace_detail = v end)
@@ -11010,7 +11135,8 @@ function resolvers.newinstance() -- todo: all vars will become lowercase and alp
force_suffixes = true,
}
- setmetatable(variables, { __index = function(t,k)
+ setmetatableindex(variables,function(t,k)
+ local v
for i=1,#order do
v = order[i][k]
if v ~= nil then
@@ -11023,10 +11149,10 @@ function resolvers.newinstance() -- todo: all vars will become lowercase and alp
end
t[k] = v
return v
- end } )
+ end)
- setmetatable(environment, { __index = function(t,k)
- v = osgetenv(k)
+ setmetatableindex(environment, function(t,k)
+ local v = osgetenv(k)
if v == nil then
v = variables[k]
end
@@ -11036,9 +11162,9 @@ function resolvers.newinstance() -- todo: all vars will become lowercase and alp
v = resolvers.repath(v) -- for taco who has a : separated osfontdir
t[k] = v
return v
- end } )
+ end)
- setmetatable(expansions, { __index = function(t,k)
+ setmetatableindex(expansions, function(t,k)
local v = environment[k]
if type(v) == "string" then
v = lpegmatch(variableresolver,v)
@@ -11046,7 +11172,7 @@ function resolvers.newinstance() -- todo: all vars will become lowercase and alp
end
t[k] = v
return v
- end } )
+ end)
return newinstance
@@ -11552,7 +11678,7 @@ function resolvers.registerfilehash(name,content,someerror)
end
end
-function isreadable(name)
+local function isreadable(name)
local readable = lfs.isfile(name) -- not file.is_readable(name) asit can be a dir
if trace_detail then
if readable then
diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua
index 6a3df03d0..e0fc8d823 100644
--- a/scripts/context/stubs/mswin/mtxrun.lua
+++ b/scripts/context/stubs/mswin/mtxrun.lua
@@ -971,10 +971,6 @@ function table.fromhash(t)
return hsh
end
-table.serialize_functions = true
-table.serialize_compact = true
-table.serialize_inline = true
-
local noquotes, hexify, handle, reduce, compact, inline, functions
local reserved = table.tohash { -- intercept a language inconvenience: no reserved words as key
@@ -1257,15 +1253,36 @@ end
-- replacing handle by a direct t[#t+1] = ... (plus test) is not much
-- faster (0.03 on 1.00 for zapfino.tma)
-local function serialize(root,name,_handle,_reduce,_noquotes,_hexify)
- noquotes = _noquotes
- hexify = _hexify
- handle = _handle or print
- reduce = _reduce or false
- compact = table.serialize_compact
- inline = compact and table.serialize_inline
- functions = table.serialize_functions
+local function serialize(root,name,_handle,_reduce,_noquotes,_hexify) -- I might drop the _'s some day.
local tname = type(name)
+ if tname == "table" then
+ noquotes = name.noquotes
+ hexify = name.hexify
+ handle = name.handle or print
+ reduce = name.reduce or false
+ functions = name.functions
+ compact = name.compact
+ inline = name.inline and compact
+ name = name.name
+ tname = type(name)
+ if functions == nil then
+ functions = true
+ end
+ if compact == nil then
+ compact = true
+ end
+ if inline == nil then
+ inline = compact
+ end
+ else
+ noquotes = _noquotes
+ hexify = _hexify
+ handle = _handle or print
+ reduce = _reduce or false
+ compact = true
+ inline = true
+ functions = true
+ end
if tname == "string" then
if name == "return" then
handle("return {")
@@ -1324,12 +1341,11 @@ end
--
-- so this is on the todo list
-table.tofile_maxtab = 2*1024
+local maxtab = 2*1024
function table.tofile(filename,root,name,reduce,noquotes,hexify)
local f = io.open(filename,'w')
if f then
- local maxtab = table.tofile_maxtab
if maxtab > 1 then
local t, n = { }, 0
local function flush(s)
@@ -1532,8 +1548,12 @@ function table.sequenced(t,sep,simple) -- hash only
return concat(s, sep or " | ")
end
-function table.print(...)
- table.tohandle(print,...)
+function table.print(t,...)
+ if type(t) ~= "table" then
+ print(tostring(t))
+ else
+ table.tohandle(print,t,...)
+ end
end
-- -- -- obsolete but we keep them for a while and might comment them later -- -- --
@@ -2535,8 +2555,6 @@ function file.collapsepath(str,anchor)
end
end
-file.collapse_path = file.collapsepath
-
function file.robustname(str,strict)
str = gsub(str,"[^%a%d%/%-%.\\]+","-")
@@ -2651,14 +2669,12 @@ if not md5.hex then function md5.hex(str) return convert(str,"%02x") end end
if not md5.dec then function md5.dec(str) return convert(str,"%03i") end end
-file.needs_updating_threshold = 1
-
-function file.needs_updating(oldname,newname) -- size modification access change
+function file.needs_updating(oldname,newname,threshold) -- size modification access change
local oldtime = lfs.attributes(oldname, modification)
local newtime = lfs.attributes(newname, modification)
if newtime >= oldtime then
return false
- elseif oldtime - newtime < file.needs_updating_threshold then
+ elseif oldtime - newtime < (threshold or 1) then
return false
else
return true
@@ -3666,7 +3682,7 @@ local tables = utilities.tables
local format, gmatch = string.format, string.gmatch
local concat, insert, remove = table.concat, table.insert, table.remove
-local setmetatable, tonumber, tostring = setmetatable, tonumber, tostring
+local setmetatable, getmetatable, tonumber, tostring = setmetatable, getmetatable, tonumber, tostring
function tables.definetable(target) -- defines undefined tables
local composed, t, n = nil, { }, 0
@@ -3731,12 +3747,6 @@ function tables.insertaftervalue(t,value,extra)
insert(t,#t+1,extra)
end
-local _empty_table_ = { __index = function(t,k) return "" end }
-
-function table.setemptymetatable(t)
- setmetatable(t,_empty_table_)
-end
-
-- experimental
local function toxml(t,d,result)
@@ -3753,9 +3763,14 @@ local function toxml(t,d,result)
end
end
-function table.toxml(t,name)
- local result = { "" }
- toxml( { [name or "root"] = t }, "", result)
+function table.toxml(t,name,nobanner)
+ local noroot = name == false
+ local result = (nobanner or noroot) and { } or { "" }
+ if noroot then
+ toxml( t, "", result)
+ else
+ toxml( { [name or "root"] = t }, "", result)
+ end
return concat(result,"\n")
end
@@ -3816,20 +3831,6 @@ function storage.checked(t)
return t
end
-function setmetatablekey(t,key,value)
- local m = getmetatable(t)
- if not m then
- m = { }
- setmetatable(t,m)
- end
- m[key] = value
-end
-
-function getmetatablekey(t,key,value)
- local m = getmetatable(t)
- return m and m[key]
-end
-
function storage.setinitializer(data,initialize)
local m = getmetatable(data) or { }
@@ -3852,6 +3853,77 @@ function storage.sparse(t)
return t
end
+-- table namespace ?
+
+local function f_empty () return "" end -- t,k
+local function f_self (t,k) t[k] = k return k end
+local function f_ignore() end -- t,k,v
+
+local t_empty = { __index = empty }
+local t_self = { __index = self }
+local t_ignore = { __newindex = ignore }
+
+function table.setmetatableindex(t,f)
+ local m = getmetatable(t)
+ if m then
+ if f == "empty" then
+ m.__index = f_empty
+ elseif f == "key" then
+ m.__index = f_self
+ else
+ m.__index = f
+ end
+ else
+ if f == "empty" then
+ setmetatable(t, t_empty)
+ elseif f == "key" then
+ setmetatable(t, t_self)
+ else
+ setmetatable(t,{ __index = f })
+ end
+ end
+end
+
+function table.setmetatablenewindex(t,f)
+ local m = getmetatable(t)
+ if m then
+ if f == "ignore" then
+ m.__newindex = f_ignore
+ else
+ m.__newindex = f
+ end
+ else
+ if f == "ignore" then
+ setmetatable(t, t_ignore)
+ else
+ setmetatable(t,{ __newindex = f })
+ end
+ end
+end
+
+function table.setmetatablecall(t,f)
+ local m = getmetatable(t)
+ if m then
+ m.__call = f
+ else
+ setmetatable(t,{ __call = f })
+ end
+end
+
+function table.setmetatablekey(t,key,value)
+ local m = getmetatable(t)
+ if not m then
+ m = { }
+ setmetatable(t,m)
+ end
+ m[key] = value
+end
+
+function table.getmetatablekey(t,key,value)
+ local m = getmetatable(t)
+ return m and m[key]
+end
+
end -- of closure
@@ -4047,18 +4119,20 @@ if not modules then modules = { } end modules ['util-prs'] = {
license = "see context related readme files"
}
+local P, R, V, C, Ct, Carg = lpeg.P, lpeg.R, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Carg
+local lpegmatch = lpeg.match
+local concat, format, gmatch = table.concat, string.format, string.gmatch
+local tostring, type, next = tostring, type, next
+
utilities = utilities or {}
utilities.parsers = utilities.parsers or { }
local parsers = utilities.parsers
parsers.patterns = parsers.patterns or { }
--- we could use a Cf Cg construct
+local setmetatableindex = table.setmetatableindex
+local sortedhash = table.sortedhash
-local P, R, V, C, Ct, Carg = lpeg.P, lpeg.R, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Carg
-local lpegmatch = lpeg.match
-local concat, format, gmatch = table.concat, string.format, string.gmatch
-local tostring, type, next, setmetatable = tostring, type, next, setmetatable
-local sortedhash = table.sortedhash
+-- we could use a Cf Cg construct
local escape, left, right = P("\\"), P('{'), P('}')
@@ -4257,7 +4331,7 @@ function parsers.getparameters(self,class,parentclass,settings)
sp = { }
self[parentclass] = sp
end
- setmetatable(sc, { __index = sp })
+ setmetatableindex(sc,sp)
end
end
parsers.settings_to_hash(settings,sc)
@@ -4474,7 +4548,7 @@ end
local is_node = node and node.is_node
-function inspect(i)
+function inspect(i) -- global function
local ti = type(i)
if ti == "table" then
table.print(i,"table")
@@ -5044,6 +5118,8 @@ local escapedpattern = string.escapedpattern
local texcount = tex and tex.count
local next, type = next, type
+local setmetatableindex = table.setmetatableindex
+
--[[ldx--
This is a prelude to a more extensive logging module. We no longer
provide based logging a sparsing is relatively easy anyway.
@@ -5064,11 +5140,11 @@ wiki : http://contextgarden.net
local function ignore() end
-setmetatable(logs, { __index = function(t,k) t[k] = ignore ; return ignore end })
+setmetatableindex(logs, function(t,k) t[k] = ignore ; return ignore end)
-local report, subreport, status, settarget, setformatter
+local report, subreport, status, settarget, setformats, settranslations
-local direct, subdirect, writer
+local direct, subdirect, writer, pushtarget, poptarget
if tex and tex.jobname or tex.formatname then
@@ -7308,6 +7384,8 @@ local type, next, tonumber, tostring, setmetatable, loadstring = type, next, ton
local format, upper, lower, gmatch, gsub, find, rep = string.format, string.upper, string.lower, string.gmatch, string.gsub, string.find, string.rep
local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
+local setmetatableindex = table.setmetatableindex
+
-- beware, this is not xpath ... e.g. position is different (currently) and
-- we have reverse-sibling as reversed preceding sibling
@@ -7380,8 +7458,8 @@ local function fallback (t, name)
return fn
end
-setmetatable(finalizers.xml, { __index = fallback })
-setmetatable(finalizers.tex, { __index = fallback })
+setmetatableindex(finalizers.xml, fallback)
+setmetatableindex(finalizers.tex, fallback)
xml.defaultprotocol = "xml"
@@ -8078,14 +8156,13 @@ xml.nodesettostring = nodesettostring
local lpath -- we have a harmless kind of circular reference
+local lshowoptions = { name = false, functions = false }
+
local function lshow(parsed)
if type(parsed) == "string" then
parsed = lpath(parsed)
end
- local s = table.serialize_functions -- ugly
- table.serialize_functions = false -- ugly
- report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,table.serialize(parsed,false))
- table.serialize_functions = s -- ugly
+ report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,table.serialize(parsed,lshowoptions))
end
xml.lshow = lshow
@@ -8679,8 +8756,8 @@ local xmlconvert, xmlcopy, xmlname = xml.convert, xml.copy, xml.name
local xmlinheritedconvert = xml.inheritedconvert
local xmlapplylpath = xml.applylpath
-local type = type
-local insert, remove = table.insert, table.remove
+local type, setmetatable, getmetatable = type, setmetatable, getmetatable
+local insert, remove, fastcopy = table.insert, table.remove, table.fastcopy
local gmatch, gsub = string.gmatch, string.gsub
local function report(what,pattern,c,e)
@@ -8889,6 +8966,41 @@ function xml.replace(root,pattern,whatever)
end
end
+local function wrap(e,wrapper)
+ local t = {
+ rn = e.rn,
+ tg = e.tg,
+ ns = e.ns,
+ at = e.at,
+ dt = e.dt,
+ __p__ = e,
+ }
+ setmetatable(t,getmetatable(e))
+ e.rn = wrapper.rn or e.rn or ""
+ e.tg = wrapper.tg or e.tg or ""
+ e.ns = wrapper.ns or e.ns or ""
+ e.at = fastcopy(wrapper.at)
+ e.dt = { t }
+end
+
+function xml.wrap(root,pattern,whatever)
+ if whatever then
+ local wrapper = xmltoelement(whatever,root)
+ local collected = xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e = collected[c]
+ if trace_manipulations then
+ report('wrapping',pattern,c,e)
+ end
+ wrap(e,wrapper)
+ end
+ end
+ else
+ wrap(root,xmltoelement(pattern))
+ end
+end
+
local function inject_element(root,pattern,whatever,prepend)
local element = root and xmltoelement(whatever,root)
local collected = element and xmlapplylpath(root,pattern)
@@ -8959,7 +9071,7 @@ local function include(xmldata,pattern,attribute,recursive,loaddata)
local ekat = ek.at
local epdt = ek.__p__.dt
if not attribute or attribute == "" then
- name = (type(ekdt) == "table" and ekdt[1]) or ekdt -- ckeck, probably always tab or str
+ name = (type(ekdt) == "table" and ekdt[1]) or ekdt -- check, probably always tab or str
end
if not name then
for a in gmatch(attribute or "href","([^|]+)") do
@@ -10039,17 +10151,23 @@ if not modules then modules = { } end modules ['data-env'] = {
license = "see context related readme files",
}
-local allocate = utilities.storage.allocate
local lower, gsub = string.lower, string.gsub
-local fileextname = file.extname
-
local resolvers = resolvers
-local formats = allocate() resolvers.formats = formats
-local suffixes = allocate() resolvers.suffixes = suffixes
-local dangerous = allocate() resolvers.dangerous = dangerous
-local suffixmap = allocate() resolvers.suffixmap = suffixmap
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
+local fileextname = file.extname
+
+local formats = allocate()
+local suffixes = allocate()
+local dangerous = allocate()
+local suffixmap = allocate()
+
+resolvers.formats = formats
+resolvers.suffixes = suffixes
+resolvers.dangerous = dangerous
+resolvers.suffixmap = suffixmap
local relations = allocate { -- todo: handlers also here
core = {
@@ -10261,9 +10379,9 @@ local function simplified(t,k)
return rawget(t,lower(gsub(k," ","")))
end
-setmetatablekey(formats, "__index", simplified)
-setmetatablekey(suffixes, "__index", simplified)
-setmetatablekey(suffixmap, "__index", simplified)
+setmetatableindex(formats, simplified)
+setmetatableindex(suffixes, simplified)
+setmetatableindex(suffixmap, simplified)
-- A few accessors, mostly for command line tool.
@@ -10611,6 +10729,8 @@ function caches.is_writable(filepath,filename)
return file.is_writable(tmaname)
end
+local saveoptions = { name = "return", reduce = true }
+
function caches.savedata(filepath,filename,data,raw)
local tmaname, tmcname = caches.setluanames(filepath,filename)
local reduce, simplify = true, true
@@ -10619,9 +10739,9 @@ function caches.savedata(filepath,filename,data,raw)
end
data.cache_uuid = os.uuid()
if caches.direct then
- file.savedata(tmaname, table.serialize(data,'return',false,true,false)) -- no hex
+ file.savedata(tmaname,table.serialize(data,saveoptions))
else
- table.tofile(tmaname, data,'return',false,true,false) -- maybe not the last true
+ table.tofile(tmaname,data,saveoptions)
end
utilities.lua.compile(tmaname,tmcname)
end
@@ -10865,15 +10985,20 @@ if not modules then modules = { } end modules ['data-res'] = {
local format, gsub, find, lower, upper, match, gmatch = string.format, string.gsub, string.find, string.lower, string.upper, string.match, string.gmatch
local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys
-local next, type, rawget, setmetatable, getmetatable = next, type, rawget, setmetatable, getmetatable
+local next, type, rawget = next, type, rawget
local os = os
local P, S, R, C, Cc, Cs, Ct, Carg = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Carg
local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
-local filedirname, filebasename, fileextname, filejoin = file.dirname, file.basename, file.extname, file.join
-local collapsepath, joinpath = file.collapsepath, file.joinpath
-local allocate = utilities.storage.allocate
+local filedirname = file.dirname
+local filebasename = file.basename
+local fileextname = file.extname
+local filejoin = file.join
+local collapsepath = file.collapsepath
+local joinpath = file.joinpath
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end)
local trace_detail = false trackers.register("resolvers.details", function(v) trace_detail = v end)
@@ -11010,7 +11135,8 @@ function resolvers.newinstance() -- todo: all vars will become lowercase and alp
force_suffixes = true,
}
- setmetatable(variables, { __index = function(t,k)
+ setmetatableindex(variables,function(t,k)
+ local v
for i=1,#order do
v = order[i][k]
if v ~= nil then
@@ -11023,10 +11149,10 @@ function resolvers.newinstance() -- todo: all vars will become lowercase and alp
end
t[k] = v
return v
- end } )
+ end)
- setmetatable(environment, { __index = function(t,k)
- v = osgetenv(k)
+ setmetatableindex(environment, function(t,k)
+ local v = osgetenv(k)
if v == nil then
v = variables[k]
end
@@ -11036,9 +11162,9 @@ function resolvers.newinstance() -- todo: all vars will become lowercase and alp
v = resolvers.repath(v) -- for taco who has a : separated osfontdir
t[k] = v
return v
- end } )
+ end)
- setmetatable(expansions, { __index = function(t,k)
+ setmetatableindex(expansions, function(t,k)
local v = environment[k]
if type(v) == "string" then
v = lpegmatch(variableresolver,v)
@@ -11046,7 +11172,7 @@ function resolvers.newinstance() -- todo: all vars will become lowercase and alp
end
t[k] = v
return v
- end } )
+ end)
return newinstance
@@ -11552,7 +11678,7 @@ function resolvers.registerfilehash(name,content,someerror)
end
end
-function isreadable(name)
+local function isreadable(name)
local readable = lfs.isfile(name) -- not file.is_readable(name) asit can be a dir
if trace_detail then
if readable then
diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun
index 6a3df03d0..e0fc8d823 100755
--- a/scripts/context/stubs/unix/mtxrun
+++ b/scripts/context/stubs/unix/mtxrun
@@ -971,10 +971,6 @@ function table.fromhash(t)
return hsh
end
-table.serialize_functions = true
-table.serialize_compact = true
-table.serialize_inline = true
-
local noquotes, hexify, handle, reduce, compact, inline, functions
local reserved = table.tohash { -- intercept a language inconvenience: no reserved words as key
@@ -1257,15 +1253,36 @@ end
-- replacing handle by a direct t[#t+1] = ... (plus test) is not much
-- faster (0.03 on 1.00 for zapfino.tma)
-local function serialize(root,name,_handle,_reduce,_noquotes,_hexify)
- noquotes = _noquotes
- hexify = _hexify
- handle = _handle or print
- reduce = _reduce or false
- compact = table.serialize_compact
- inline = compact and table.serialize_inline
- functions = table.serialize_functions
+local function serialize(root,name,_handle,_reduce,_noquotes,_hexify) -- I might drop the _'s some day.
local tname = type(name)
+ if tname == "table" then
+ noquotes = name.noquotes
+ hexify = name.hexify
+ handle = name.handle or print
+ reduce = name.reduce or false
+ functions = name.functions
+ compact = name.compact
+ inline = name.inline and compact
+ name = name.name
+ tname = type(name)
+ if functions == nil then
+ functions = true
+ end
+ if compact == nil then
+ compact = true
+ end
+ if inline == nil then
+ inline = compact
+ end
+ else
+ noquotes = _noquotes
+ hexify = _hexify
+ handle = _handle or print
+ reduce = _reduce or false
+ compact = true
+ inline = true
+ functions = true
+ end
if tname == "string" then
if name == "return" then
handle("return {")
@@ -1324,12 +1341,11 @@ end
--
-- so this is on the todo list
-table.tofile_maxtab = 2*1024
+local maxtab = 2*1024
function table.tofile(filename,root,name,reduce,noquotes,hexify)
local f = io.open(filename,'w')
if f then
- local maxtab = table.tofile_maxtab
if maxtab > 1 then
local t, n = { }, 0
local function flush(s)
@@ -1532,8 +1548,12 @@ function table.sequenced(t,sep,simple) -- hash only
return concat(s, sep or " | ")
end
-function table.print(...)
- table.tohandle(print,...)
+function table.print(t,...)
+ if type(t) ~= "table" then
+ print(tostring(t))
+ else
+ table.tohandle(print,t,...)
+ end
end
-- -- -- obsolete but we keep them for a while and might comment them later -- -- --
@@ -2535,8 +2555,6 @@ function file.collapsepath(str,anchor)
end
end
-file.collapse_path = file.collapsepath
-
function file.robustname(str,strict)
str = gsub(str,"[^%a%d%/%-%.\\]+","-")
@@ -2651,14 +2669,12 @@ if not md5.hex then function md5.hex(str) return convert(str,"%02x") end end
if not md5.dec then function md5.dec(str) return convert(str,"%03i") end end
-file.needs_updating_threshold = 1
-
-function file.needs_updating(oldname,newname) -- size modification access change
+function file.needs_updating(oldname,newname,threshold) -- size modification access change
local oldtime = lfs.attributes(oldname, modification)
local newtime = lfs.attributes(newname, modification)
if newtime >= oldtime then
return false
- elseif oldtime - newtime < file.needs_updating_threshold then
+ elseif oldtime - newtime < (threshold or 1) then
return false
else
return true
@@ -3666,7 +3682,7 @@ local tables = utilities.tables
local format, gmatch = string.format, string.gmatch
local concat, insert, remove = table.concat, table.insert, table.remove
-local setmetatable, tonumber, tostring = setmetatable, tonumber, tostring
+local setmetatable, getmetatable, tonumber, tostring = setmetatable, getmetatable, tonumber, tostring
function tables.definetable(target) -- defines undefined tables
local composed, t, n = nil, { }, 0
@@ -3731,12 +3747,6 @@ function tables.insertaftervalue(t,value,extra)
insert(t,#t+1,extra)
end
-local _empty_table_ = { __index = function(t,k) return "" end }
-
-function table.setemptymetatable(t)
- setmetatable(t,_empty_table_)
-end
-
-- experimental
local function toxml(t,d,result)
@@ -3753,9 +3763,14 @@ local function toxml(t,d,result)
end
end
-function table.toxml(t,name)
- local result = { "" }
- toxml( { [name or "root"] = t }, "", result)
+function table.toxml(t,name,nobanner)
+ local noroot = name == false
+ local result = (nobanner or noroot) and { } or { "" }
+ if noroot then
+ toxml( t, "", result)
+ else
+ toxml( { [name or "root"] = t }, "", result)
+ end
return concat(result,"\n")
end
@@ -3816,20 +3831,6 @@ function storage.checked(t)
return t
end
-function setmetatablekey(t,key,value)
- local m = getmetatable(t)
- if not m then
- m = { }
- setmetatable(t,m)
- end
- m[key] = value
-end
-
-function getmetatablekey(t,key,value)
- local m = getmetatable(t)
- return m and m[key]
-end
-
function storage.setinitializer(data,initialize)
local m = getmetatable(data) or { }
@@ -3852,6 +3853,77 @@ function storage.sparse(t)
return t
end
+-- table namespace ?
+
+local function f_empty () return "" end -- t,k
+local function f_self (t,k) t[k] = k return k end
+local function f_ignore() end -- t,k,v
+
+local t_empty = { __index = empty }
+local t_self = { __index = self }
+local t_ignore = { __newindex = ignore }
+
+function table.setmetatableindex(t,f)
+ local m = getmetatable(t)
+ if m then
+ if f == "empty" then
+ m.__index = f_empty
+ elseif f == "key" then
+ m.__index = f_self
+ else
+ m.__index = f
+ end
+ else
+ if f == "empty" then
+ setmetatable(t, t_empty)
+ elseif f == "key" then
+ setmetatable(t, t_self)
+ else
+ setmetatable(t,{ __index = f })
+ end
+ end
+end
+
+function table.setmetatablenewindex(t,f)
+ local m = getmetatable(t)
+ if m then
+ if f == "ignore" then
+ m.__newindex = f_ignore
+ else
+ m.__newindex = f
+ end
+ else
+ if f == "ignore" then
+ setmetatable(t, t_ignore)
+ else
+ setmetatable(t,{ __newindex = f })
+ end
+ end
+end
+
+function table.setmetatablecall(t,f)
+ local m = getmetatable(t)
+ if m then
+ m.__call = f
+ else
+ setmetatable(t,{ __call = f })
+ end
+end
+
+function table.setmetatablekey(t,key,value)
+ local m = getmetatable(t)
+ if not m then
+ m = { }
+ setmetatable(t,m)
+ end
+ m[key] = value
+end
+
+function table.getmetatablekey(t,key,value)
+ local m = getmetatable(t)
+ return m and m[key]
+end
+
end -- of closure
@@ -4047,18 +4119,20 @@ if not modules then modules = { } end modules ['util-prs'] = {
license = "see context related readme files"
}
+local P, R, V, C, Ct, Carg = lpeg.P, lpeg.R, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Carg
+local lpegmatch = lpeg.match
+local concat, format, gmatch = table.concat, string.format, string.gmatch
+local tostring, type, next = tostring, type, next
+
utilities = utilities or {}
utilities.parsers = utilities.parsers or { }
local parsers = utilities.parsers
parsers.patterns = parsers.patterns or { }
--- we could use a Cf Cg construct
+local setmetatableindex = table.setmetatableindex
+local sortedhash = table.sortedhash
-local P, R, V, C, Ct, Carg = lpeg.P, lpeg.R, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Carg
-local lpegmatch = lpeg.match
-local concat, format, gmatch = table.concat, string.format, string.gmatch
-local tostring, type, next, setmetatable = tostring, type, next, setmetatable
-local sortedhash = table.sortedhash
+-- we could use a Cf Cg construct
local escape, left, right = P("\\"), P('{'), P('}')
@@ -4257,7 +4331,7 @@ function parsers.getparameters(self,class,parentclass,settings)
sp = { }
self[parentclass] = sp
end
- setmetatable(sc, { __index = sp })
+ setmetatableindex(sc,sp)
end
end
parsers.settings_to_hash(settings,sc)
@@ -4474,7 +4548,7 @@ end
local is_node = node and node.is_node
-function inspect(i)
+function inspect(i) -- global function
local ti = type(i)
if ti == "table" then
table.print(i,"table")
@@ -5044,6 +5118,8 @@ local escapedpattern = string.escapedpattern
local texcount = tex and tex.count
local next, type = next, type
+local setmetatableindex = table.setmetatableindex
+
--[[ldx--
This is a prelude to a more extensive logging module. We no longer
provide based logging a sparsing is relatively easy anyway.
@@ -5064,11 +5140,11 @@ wiki : http://contextgarden.net
local function ignore() end
-setmetatable(logs, { __index = function(t,k) t[k] = ignore ; return ignore end })
+setmetatableindex(logs, function(t,k) t[k] = ignore ; return ignore end)
-local report, subreport, status, settarget, setformatter
+local report, subreport, status, settarget, setformats, settranslations
-local direct, subdirect, writer
+local direct, subdirect, writer, pushtarget, poptarget
if tex and tex.jobname or tex.formatname then
@@ -7308,6 +7384,8 @@ local type, next, tonumber, tostring, setmetatable, loadstring = type, next, ton
local format, upper, lower, gmatch, gsub, find, rep = string.format, string.upper, string.lower, string.gmatch, string.gsub, string.find, string.rep
local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
+local setmetatableindex = table.setmetatableindex
+
-- beware, this is not xpath ... e.g. position is different (currently) and
-- we have reverse-sibling as reversed preceding sibling
@@ -7380,8 +7458,8 @@ local function fallback (t, name)
return fn
end
-setmetatable(finalizers.xml, { __index = fallback })
-setmetatable(finalizers.tex, { __index = fallback })
+setmetatableindex(finalizers.xml, fallback)
+setmetatableindex(finalizers.tex, fallback)
xml.defaultprotocol = "xml"
@@ -8078,14 +8156,13 @@ xml.nodesettostring = nodesettostring
local lpath -- we have a harmless kind of circular reference
+local lshowoptions = { name = false, functions = false }
+
local function lshow(parsed)
if type(parsed) == "string" then
parsed = lpath(parsed)
end
- local s = table.serialize_functions -- ugly
- table.serialize_functions = false -- ugly
- report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,table.serialize(parsed,false))
- table.serialize_functions = s -- ugly
+ report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,table.serialize(parsed,lshowoptions))
end
xml.lshow = lshow
@@ -8679,8 +8756,8 @@ local xmlconvert, xmlcopy, xmlname = xml.convert, xml.copy, xml.name
local xmlinheritedconvert = xml.inheritedconvert
local xmlapplylpath = xml.applylpath
-local type = type
-local insert, remove = table.insert, table.remove
+local type, setmetatable, getmetatable = type, setmetatable, getmetatable
+local insert, remove, fastcopy = table.insert, table.remove, table.fastcopy
local gmatch, gsub = string.gmatch, string.gsub
local function report(what,pattern,c,e)
@@ -8889,6 +8966,41 @@ function xml.replace(root,pattern,whatever)
end
end
+local function wrap(e,wrapper)
+ local t = {
+ rn = e.rn,
+ tg = e.tg,
+ ns = e.ns,
+ at = e.at,
+ dt = e.dt,
+ __p__ = e,
+ }
+ setmetatable(t,getmetatable(e))
+ e.rn = wrapper.rn or e.rn or ""
+ e.tg = wrapper.tg or e.tg or ""
+ e.ns = wrapper.ns or e.ns or ""
+ e.at = fastcopy(wrapper.at)
+ e.dt = { t }
+end
+
+function xml.wrap(root,pattern,whatever)
+ if whatever then
+ local wrapper = xmltoelement(whatever,root)
+ local collected = xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e = collected[c]
+ if trace_manipulations then
+ report('wrapping',pattern,c,e)
+ end
+ wrap(e,wrapper)
+ end
+ end
+ else
+ wrap(root,xmltoelement(pattern))
+ end
+end
+
local function inject_element(root,pattern,whatever,prepend)
local element = root and xmltoelement(whatever,root)
local collected = element and xmlapplylpath(root,pattern)
@@ -8959,7 +9071,7 @@ local function include(xmldata,pattern,attribute,recursive,loaddata)
local ekat = ek.at
local epdt = ek.__p__.dt
if not attribute or attribute == "" then
- name = (type(ekdt) == "table" and ekdt[1]) or ekdt -- ckeck, probably always tab or str
+ name = (type(ekdt) == "table" and ekdt[1]) or ekdt -- check, probably always tab or str
end
if not name then
for a in gmatch(attribute or "href","([^|]+)") do
@@ -10039,17 +10151,23 @@ if not modules then modules = { } end modules ['data-env'] = {
license = "see context related readme files",
}
-local allocate = utilities.storage.allocate
local lower, gsub = string.lower, string.gsub
-local fileextname = file.extname
-
local resolvers = resolvers
-local formats = allocate() resolvers.formats = formats
-local suffixes = allocate() resolvers.suffixes = suffixes
-local dangerous = allocate() resolvers.dangerous = dangerous
-local suffixmap = allocate() resolvers.suffixmap = suffixmap
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
+local fileextname = file.extname
+
+local formats = allocate()
+local suffixes = allocate()
+local dangerous = allocate()
+local suffixmap = allocate()
+
+resolvers.formats = formats
+resolvers.suffixes = suffixes
+resolvers.dangerous = dangerous
+resolvers.suffixmap = suffixmap
local relations = allocate { -- todo: handlers also here
core = {
@@ -10261,9 +10379,9 @@ local function simplified(t,k)
return rawget(t,lower(gsub(k," ","")))
end
-setmetatablekey(formats, "__index", simplified)
-setmetatablekey(suffixes, "__index", simplified)
-setmetatablekey(suffixmap, "__index", simplified)
+setmetatableindex(formats, simplified)
+setmetatableindex(suffixes, simplified)
+setmetatableindex(suffixmap, simplified)
-- A few accessors, mostly for command line tool.
@@ -10611,6 +10729,8 @@ function caches.is_writable(filepath,filename)
return file.is_writable(tmaname)
end
+local saveoptions = { name = "return", reduce = true }
+
function caches.savedata(filepath,filename,data,raw)
local tmaname, tmcname = caches.setluanames(filepath,filename)
local reduce, simplify = true, true
@@ -10619,9 +10739,9 @@ function caches.savedata(filepath,filename,data,raw)
end
data.cache_uuid = os.uuid()
if caches.direct then
- file.savedata(tmaname, table.serialize(data,'return',false,true,false)) -- no hex
+ file.savedata(tmaname,table.serialize(data,saveoptions))
else
- table.tofile(tmaname, data,'return',false,true,false) -- maybe not the last true
+ table.tofile(tmaname,data,saveoptions)
end
utilities.lua.compile(tmaname,tmcname)
end
@@ -10865,15 +10985,20 @@ if not modules then modules = { } end modules ['data-res'] = {
local format, gsub, find, lower, upper, match, gmatch = string.format, string.gsub, string.find, string.lower, string.upper, string.match, string.gmatch
local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys
-local next, type, rawget, setmetatable, getmetatable = next, type, rawget, setmetatable, getmetatable
+local next, type, rawget = next, type, rawget
local os = os
local P, S, R, C, Cc, Cs, Ct, Carg = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Carg
local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
-local filedirname, filebasename, fileextname, filejoin = file.dirname, file.basename, file.extname, file.join
-local collapsepath, joinpath = file.collapsepath, file.joinpath
-local allocate = utilities.storage.allocate
+local filedirname = file.dirname
+local filebasename = file.basename
+local fileextname = file.extname
+local filejoin = file.join
+local collapsepath = file.collapsepath
+local joinpath = file.joinpath
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end)
local trace_detail = false trackers.register("resolvers.details", function(v) trace_detail = v end)
@@ -11010,7 +11135,8 @@ function resolvers.newinstance() -- todo: all vars will become lowercase and alp
force_suffixes = true,
}
- setmetatable(variables, { __index = function(t,k)
+ setmetatableindex(variables,function(t,k)
+ local v
for i=1,#order do
v = order[i][k]
if v ~= nil then
@@ -11023,10 +11149,10 @@ function resolvers.newinstance() -- todo: all vars will become lowercase and alp
end
t[k] = v
return v
- end } )
+ end)
- setmetatable(environment, { __index = function(t,k)
- v = osgetenv(k)
+ setmetatableindex(environment, function(t,k)
+ local v = osgetenv(k)
if v == nil then
v = variables[k]
end
@@ -11036,9 +11162,9 @@ function resolvers.newinstance() -- todo: all vars will become lowercase and alp
v = resolvers.repath(v) -- for taco who has a : separated osfontdir
t[k] = v
return v
- end } )
+ end)
- setmetatable(expansions, { __index = function(t,k)
+ setmetatableindex(expansions, function(t,k)
local v = environment[k]
if type(v) == "string" then
v = lpegmatch(variableresolver,v)
@@ -11046,7 +11172,7 @@ function resolvers.newinstance() -- todo: all vars will become lowercase and alp
end
t[k] = v
return v
- end } )
+ end)
return newinstance
@@ -11552,7 +11678,7 @@ function resolvers.registerfilehash(name,content,someerror)
end
end
-function isreadable(name)
+local function isreadable(name)
local readable = lfs.isfile(name) -- not file.is_readable(name) asit can be a dir
if trace_detail then
if readable then
diff --git a/tex/context/base/anch-pos.lua b/tex/context/base/anch-pos.lua
index 132ad32c7..789e1aefe 100644
--- a/tex/context/base/anch-pos.lua
+++ b/tex/context/base/anch-pos.lua
@@ -22,7 +22,8 @@ local allocate, mark = utilities.storage.allocate, utilities.storage.mark
local texsp = tex.sp
----- texsp = string.todimen -- because we cache this is much faster but no rounding
-local collected, tobesaved = allocate(), allocate()
+local collected = allocate()
+local tobesaved = allocate()
local jobpositions = {
collected = collected,
@@ -36,14 +37,15 @@ _ptbs_, _pcol_ = tobesaved, collected -- global
local dx, dy, nx, ny = "0pt", "0pt", 0, 0
local function initializer()
- tobesaved = mark(jobpositions.tobesaved)
- collected = mark(jobpositions.collected)
- _ptbs_, _pcol_ = tobesaved, collected -- global
- local p = collected["page:0"] -- page:1
- if p then
- -- dx, nx = p[2] or "0pt", 0
- -- dy, ny = p[3] or "0pt", 0
- end
+ tobesaved = jobpositions.tobesaved
+ collected = jobpositions.collected
+ _ptbs_ = tobesaved -- global
+ _pcol_ = collected -- global
+ -- local p = collected["page:0"] -- page:1
+ -- if p then
+ -- dx, nx = p[2] or "0pt", 0
+ -- dy, ny = p[3] or "0pt", 0
+ -- end
end
job.register('job.positions.collected', tobesaved, initializer)
diff --git a/tex/context/base/attr-col.lua b/tex/context/base/attr-col.lua
index acabe62ac..871ac3e03 100644
--- a/tex/context/base/attr-col.lua
+++ b/tex/context/base/attr-col.lua
@@ -13,14 +13,15 @@ local type = type
local format = string.format
local concat = table.concat
-local allocate = utilities.storage.allocate
+local attributes, nodes = attributes, nodes
+
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
local report_attributes = logs.reporter("attributes","colors")
local report_colors = logs.reporter("colors","support")
local report_transparencies = logs.reporter("transparencies","support")
-local attributes, nodes = attributes, nodes
-
-- todo: document this but first reimplement this as it reflects the early
-- days of luatex / mkiv and we have better ways now
@@ -290,8 +291,8 @@ local function reviver(data,n)
end
end
-setmetatable(colors, { __index = extender })
-setmetatable(colors.data, { __index = reviver })
+setmetatableindex(colors, extender)
+setmetatableindex(colors.data, reviver)
function colors.filter(n)
return concat(data[n],":",5)
@@ -420,8 +421,8 @@ local function reviver(data,n)
end
end
-setmetatable(transparencies, { __index = extender })
-setmetatable(transparencies.data, { __index = reviver }) -- register if used
+setmetatableindex(transparencies, extender)
+setmetatableindex(transparencies.data, reviver) -- register if used
-- check if there is an identity
@@ -485,8 +486,8 @@ local function reviver(data,n)
end
end
-setmetatable(colorintents, { __index = extender })
-setmetatable(colorintents.data, { __index = reviver })
+setmetatableindex(colorintents, extender)
+setmetatableindex(colorintents.data, reviver)
function colorintents.register(stamp)
return registered[stamp] or registered.overprint
diff --git a/tex/context/base/attr-eff.lua b/tex/context/base/attr-eff.lua
index 6ed64f201..023d1c51b 100644
--- a/tex/context/base/attr-eff.lua
+++ b/tex/context/base/attr-eff.lua
@@ -8,31 +8,33 @@ if not modules then modules = { } end modules ['attr-eff'] = {
local format = string.format
-local allocate = utilities.storage.allocate
-
local attributes, nodes = attributes, nodes
-local states = attributes.states
-local tasks = nodes.tasks
-local nodeinjections = backends.nodeinjections
-local settexattribute = tex.setattribute
+local states = attributes.states
+local tasks = nodes.tasks
+local nodeinjections = backends.nodeinjections
+local settexattribute = tex.setattribute
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
-attributes.effects = attributes.effects or { }
-local effects = attributes.effects
+attributes.effects = attributes.effects or { }
+local effects = attributes.effects
-local a_effect = attributes.private('effect')
+local a_effect = attributes.private('effect')
-effects.data = allocate()
-effects.values = effects.values or { }
-effects.registered = effects.registered or { }
-effects.attribute = a_effect
+effects.data = allocate()
+effects.values = effects.values or { }
+effects.registered = effects.registered or { }
+effects.attribute = a_effect
storage.register("attributes/effects/registered", effects.registered, "attributes.effects.registered")
storage.register("attributes/effects/values", effects.values, "attributes.effects.values")
-local template = "%s:%s:%s"
+local template = "%s:%s:%s"
-local data, registered, values = effects.data, effects.registered, effects.values
+local data = effects.data
+local registered = effects.registered
+local values = effects.values
-- valid effects: normal inner outer both hidden (stretch,rulethickness,effect)
@@ -53,8 +55,8 @@ local function reviver(data,n)
return d
end
-setmetatable(effects, { __index = extender })
-setmetatable(effects.data, { __index = reviver })
+setmetatableindex(effects, extender)
+setmetatableindex(effects.data, reviver)
effects.handler = nodes.installattributehandler {
name = "effect",
diff --git a/tex/context/base/attr-ini.mkiv b/tex/context/base/attr-ini.mkiv
index 0d7328a12..ba6ca369f 100644
--- a/tex/context/base/attr-ini.mkiv
+++ b/tex/context/base/attr-ini.mkiv
@@ -88,6 +88,7 @@
\definesystemattribute [layoutcomponent] [public]
\definesystemattribute [reference] [public]
\definesystemattribute [destination] [public]
+\definesystemattribute [internal] [public]
\definesystemattribute [ruled] [public]
\definesystemattribute [shifted] [public]
diff --git a/tex/context/base/attr-lay.lua b/tex/context/base/attr-lay.lua
index 1b652e469..ce76bb899 100644
--- a/tex/context/base/attr-lay.lua
+++ b/tex/context/base/attr-lay.lua
@@ -14,7 +14,8 @@ local type = type
local format = string.format
local insert, remove = table.insert, table.remove
-local allocate = utilities.storage.allocate
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
local report_viewerlayers = logs.reporter("viewerlayers")
@@ -90,8 +91,8 @@ local function reviver(data,n)
end
end
-setmetatable(viewerlayers, { __index = extender })
-setmetatable(viewerlayers.data, { __index = reviver })
+setmetatableindex(viewerlayers, extender)
+setmetatableindex(viewerlayers.data, reviver)
local function initializer(...)
return states.initialize(...)
diff --git a/tex/context/base/attr-neg.lua b/tex/context/base/attr-neg.lua
index c8f294c71..766295a16 100644
--- a/tex/context/base/attr-neg.lua
+++ b/tex/context/base/attr-neg.lua
@@ -11,30 +11,34 @@ if not modules then modules = { } end modules ['attr-neg'] = {
local format = string.format
+
local attributes, nodes = attributes, nodes
-local states = attributes.states
-local tasks = nodes.tasks
-local nodeinjections = backends.nodeinjections
-local settexattribute = tex.setattribute
-local variables = interfaces.variables
+local states = attributes.states
+local tasks = nodes.tasks
+local nodeinjections = backends.nodeinjections
+local settexattribute = tex.setattribute
+local variables = interfaces.variables
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
--- negative / positive
-attributes.negatives = attributes.negatives or { }
-local negatives = attributes.negatives
+attributes.negatives = attributes.negatives or { }
+local negatives = attributes.negatives
-local a_negative = attributes.private("negative")
+local a_negative = attributes.private("negative")
-negatives.data = negatives.data or { }
-negatives.attribute = a_negative
+negatives.data = allocate()
+negatives.attribute = a_negative
-negatives.registered = {
+negatives.registered = allocate {
[variables.positive] = 1,
[variables.negative] = 2,
}
-local data, registered = negatives.data, negatives.registered
+local data = negatives.data
+local registered = negatives.registered
local function extender(negatives,key)
if key == "none" then
@@ -56,8 +60,8 @@ local function reviver(data,n)
end
end
-setmetatable(negatives, { __index = extender })
-setmetatable(negatives.data, { __index = reviver })
+setmetatableindex(negatives, extender)
+setmetatableindex(negatives.data, reviver)
negatives.handler = nodes.installattributehandler {
name = "negative",
diff --git a/tex/context/base/back-exp.lua b/tex/context/base/back-exp.lua
index b9cfcefd4..8450b36f1 100644
--- a/tex/context/base/back-exp.lua
+++ b/tex/context/base/back-exp.lua
@@ -15,6 +15,9 @@ if not modules then modules = { } end modules ['back-exp'] = {
-- We can consider replacing attributes by the hash entry ... slower in resolving but it's still
-- quite okay.
+-- todo: less attributes e.g. internal only first node
+-- todo: build xml tree in mem (handy for cleaning)
+
local nodecodes = nodes.nodecodes
local traverse_nodes = node.traverse
local hlist_code = nodecodes.hlist
@@ -39,9 +42,9 @@ end
nodes.locate = locate
local next, type = next, type
-local format, match, concat, rep = string.format, string.match, table.concat, string.rep
+local format, match, concat, rep, sub, gsub = string.format, string.match, table.concat, string.rep, string.sub, string.gsub
local lpegmatch = lpeg.match
-local utfchar = utf.char
+local utfchar, utfsub = utf.char, utf.sub
local insert, remove = table.insert, table.remove
local trace_export = false trackers.register ("structures.export", function(v) trace_export = v end)
@@ -50,82 +53,91 @@ local trace_tree = false trackers.register ("structures.export.showtree",
local less_state = false directives.register("structures.export.lessstate", function(v) less_state = v end)
local page_breaks = false directives.register("structures.export.pagebreaks", function(v) page_breaks = v end)
-local report_export = logs.reporter("backend","export")
-
-local nodes = nodes
-local attributes = attributes
-local variables = interfaces.variables
-
-local tasks = nodes.tasks
-local fontchar = fonts.hashes.characters
-local languagenames = languages.numbers
-
-local nodecodes = nodes.nodecodes
-local skipcodes = nodes.skipcodes
-local whatsitcodes = nodes.whatsitcodes
-local listcodes = nodes.listcodes
-
-local hlist_code = nodecodes.hlist
-local vlist_code = nodecodes.vlist
-local glyph_code = nodecodes.glyph
-local glue_code = nodecodes.glue
-local kern_code = nodecodes.kern
-local disc_code = nodecodes.disc
-local insert_code = nodecodes.insert
-local whatsit_code = nodecodes.whatsit
-local refximage_code = whatsitcodes.pdfrefximage
-
-local userskip_code = skipcodes.userskip
-local rightskip_code = skipcodes.rightskip
-local parfillskip_code= skipcodes.parfillskip
-
-local line_code = listcodes.line
-
-local a_tagged = attributes.private('tagged')
-local a_image = attributes.private('image')
-
-local a_taggedalign = attributes.private("taggedalign")
-local a_taggedcolumns = attributes.private("taggedcolumns")
-local a_taggedrows = attributes.private("taggedrows")
-local a_taggedpar = attributes.private("taggedpar")
-local a_taggedpacked = attributes.private("taggedpacked")
-local a_taggedsymbol = attributes.private("taggedsymbol")
-local a_taggedinsert = attributes.private("taggedinsert")
-
-local a_reference = attributes.private('reference')
-
-local has_attribute = node.has_attribute
-local traverse_nodes = node.traverse
-local slide_nodelist = node.slide
-local texattribute = tex.attribute
-local unsetvalue = attributes.unsetvalue
-local locate_node = nodes.locate
-
-local references = structures.references
-local structurestags = structures.tags
-local taglist = structurestags.taglist
-local properties = structurestags.properties
-local userdata = structurestags.userdata -- might be combines with taglist
-
-local version = "0.10"
-local result = nil
+local report_export = logs.reporter("backend","export")
+
+local nodes = nodes
+local attributes = attributes
+local variables = interfaces.variables
+
+local setmetatableindex = table.setmetatableindex
+local tasks = nodes.tasks
+local fontchar = fonts.hashes.characters
+local languagenames = languages.numbers
+
+local nodecodes = nodes.nodecodes
+local skipcodes = nodes.skipcodes
+local whatsitcodes = nodes.whatsitcodes
+local listcodes = nodes.listcodes
+
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+local glyph_code = nodecodes.glyph
+local glue_code = nodecodes.glue
+local kern_code = nodecodes.kern
+local disc_code = nodecodes.disc
+local insert_code = nodecodes.insert
+local whatsit_code = nodecodes.whatsit
+local refximage_code = whatsitcodes.pdfrefximage
+
+local userskip_code = skipcodes.userskip
+local rightskip_code = skipcodes.rightskip
+local parfillskip_code = skipcodes.parfillskip
+
+local line_code = listcodes.line
+
+local a_tagged = attributes.private('tagged')
+local a_image = attributes.private('image')
+
+local a_taggedalign = attributes.private("taggedalign")
+local a_taggedcolumns = attributes.private("taggedcolumns")
+local a_taggedrows = attributes.private("taggedrows")
+local a_taggedpar = attributes.private("taggedpar")
+local a_taggedpacked = attributes.private("taggedpacked")
+local a_taggedsymbol = attributes.private("taggedsymbol")
+local a_taggedinsert = attributes.private("taggedinsert")
+local a_taggedtag = attributes.private("taggedtag")
+
+local a_reference = attributes.private('reference')
+
+local has_attribute = node.has_attribute
+local traverse_nodes = node.traverse
+local slide_nodelist = node.slide
+local texattribute = tex.attribute
+local unsetvalue = attributes.unsetvalue
+local locate_node = nodes.locate
+
+local references = structures.references
+local structurestags = structures.tags
+local taglist = structurestags.taglist
+local properties = structurestags.properties
+local userdata = structurestags.userdata -- might be combines with taglist
+local tagdata = structurestags.data
+
+local starttiming = statistics.starttiming
+local stoptiming = statistics.stoptiming
+
+-- todo: more locals (and optimize)
+
+local version = "0.20"
+local result = nil -- todo: nofresult
local entry = nil
local attributehash = { }
-local handle = nil
-local hyphen = utfchar(0xAD)
+local hyphen = utfchar(0xAD) -- todo: also emdash etc
local colonsplitter = lpeg.splitat(":")
local dashsplitter = lpeg.splitat("-")
local threshold = 65536
local indexing = false
local linedone = false
local inlinedepth = 0
-local collapse = true
local tree = { data = { }, depth = 0 } -- root
local treestack = { }
local treehash = { }
local extras = { }
local nofbreaks = 0
-local listhash = { }
+local used = { }
+local exporting = false
+
+setmetatableindex(used, function(t,k) if k then local v = { } t[k] = v return v end end)
local last = nil
local lastpar = nil
@@ -136,7 +148,7 @@ local joiner_3 = " "
local joiner_4 = " "
local joiner_5 = " "
local joiner_6 = " "
-local joiner_7 = " "
+local joiner_7 = "\n"
local joiner_8 = " "
local joiner_9 = " "
local joiner_0 = " "
@@ -150,9 +162,22 @@ local joiner_0 = " "
-- local tagsplitter = C(precolon) * colon * C(predash) * dash * C(rest) +
-- C(predash) * dash * Cc(nil) * C(rest)
+local listdata = { }
+
+local function hashlistdata()
+ local c = structures.lists.collected
+ for i=1,#c do
+ local ci = c[i]
+ local tag = ci.references.tag
+ if tag then
+ listdata[ci.metadata.kind .. ":" .. ci.metadata.name .. "-" .. tag] = ci
+ end
+ end
+end
+
local spaces = { } -- watch how we also moved the -1 in depth-1 to the creator
-setmetatable(spaces, { __index = function(t,k) t[k] = rep(" ",k-1) return t[k] end } )
+setmetatableindex(spaces, function(t,k) t[k] = rep(" ",k-1) return t[k] end)
properties.vspace = { export = "break", nature = "display" }
properties.pbreak = { export = "pagebreak", nature = "display" }
@@ -184,13 +209,23 @@ local function makebreaknode(node)
}
end
-function extras.document(element,detail,n,fulltag,hash)
- handle:write(" language='",languagenames[tex.count.mainlanguagenumber],"'")
+local fields = { "title", "subtitle", "author", "keywords" }
+
+function extras.document(handle,element,detail,n,fulltag,hash)
+ handle:write(format(" language=%q",languagenames[tex.count.mainlanguagenumber]))
if not less_state then
- handle:write(" file='",tex.jobname,"'")
- handle:write(" date='",os.date(),"'")
- handle:write(" context='",environment.version,"'")
- handle:write(" version='",version,"'")
+ handle:write(format(" file=%q",tex.jobname))
+ handle:write(format(" date=%q",os.date()))
+ handle:write(format(" context=%q",environment.version))
+ handle:write(format(" version=%q",version))
+ local identity = interactions.general.getidentity()
+ for i=1,#fields do
+ local key = fields[i]
+ local value = identity[key]
+ if value and value ~= "" then
+ handle:write(format(" %s=%q",key,value))
+ end
+ end
end
end
@@ -206,10 +241,34 @@ function structurestags.setitemgroup(packed,symbol,di)
texattribute[a_taggedsymbol] = s
end
+-- todo: per class
+
+local synonymnames, synonymnumbers = { }, { } -- can be one hash
+
+function structurestags.setsynonym(class,tag)
+ local s = synonymnumbers[tag]
+ if not s then
+ s = #synonymnames + 1
+ synonymnames[s], synonymnumbers[tag] = tag, s
+ end
+ texattribute[a_taggedtag] = s
+end
+
+local sortingnames, sortingnumbers = { }, { } -- can be one hash
+
+function structurestags.setsorting(class,tag)
+ local s = sortingnumbers[tag]
+ if not s then
+ s = #sortingnames + 1
+ sortingnames[s], sortingnumbers[tag] = tag, s
+ end
+ texattribute[a_taggedtag] = s
+end
+
local insertids = { }
function structurestags.setdescriptionid(tag,n)
- local nd = structures.notes.get(tag,n)
+ local nd = structures.notes.get(tag,n) -- todo: use listdata instead
if nd then
local r = nd.references
texattribute[a_taggedinsert] = r.internal or unsetvalue
@@ -218,7 +277,7 @@ function structurestags.setdescriptionid(tag,n)
end
end
-function extras.descriptiontag(element,detail,n,fulltag,di)
+function extras.descriptiontag(handle,element,detail,n,fulltag,di)
local hash = attributehash[fulltag]
if hash then
local v = hash.insert
@@ -229,7 +288,7 @@ function extras.descriptiontag(element,detail,n,fulltag,di)
end
end
-function extras.descriptionsymbol(element,detail,n,fulltag,di)
+function extras.descriptionsymbol(handle,element,detail,n,fulltag,di)
local hash = attributehash[fulltag]
if hash then
local v = hash.insert
@@ -240,7 +299,29 @@ function extras.descriptionsymbol(element,detail,n,fulltag,di)
end
end
-function extras.image(element,detail,n,fulltag,di)
+function extras.synonym(handle,element,detail,n,fulltag,di)
+ local hash = attributehash[fulltag]
+ if hash then
+ local v = hash.tag
+ v = v and synonymnames[v]
+ if v then
+ handle:write(" tag='",v,"'")
+ end
+ end
+end
+
+function extras.sorting(handle,element,detail,n,fulltag,di)
+ local hash = attributehash[fulltag]
+ if hash then
+ local v = hash.tag
+ v = v and sortingnames[v]
+ if v then
+ handle:write(" tag='",v,"'")
+ end
+ end
+end
+
+function extras.image(handle,element,detail,n,fulltag,di)
local hash = attributehash[fulltag]
if hash then
local v = hash.imageindex
@@ -270,14 +351,14 @@ end
local evaluators = { }
local specials = { }
-evaluators.inner = function(var)
+evaluators.inner = function(handle,var)
local inner = var.inner
if var.inner then
handle:write(" location='",inner,"'")
end
end
-evaluators.outer = function(var)
+evaluators.outer = function(handle,var)
local file, url = references.checkedfileorurl(var.outer,var.outer)
if url then
handle:write(" url='",file,"'")
@@ -286,7 +367,7 @@ evaluators.outer = function(var)
end
end
-evaluators["outer with inner"] = function(var)
+evaluators["outer with inner"] = function(handle,var)
local file = references.checkedfile(var.f)
if file then
handle:write(" file='",file,"'")
@@ -297,10 +378,10 @@ evaluators["outer with inner"] = function(var)
end
end
-evaluators.special = function(var)
+evaluators.special = function(handle,var)
local handler = specials[var.special]
if handler then
- handler(var)
+ handler(handle,var)
end
end
@@ -308,21 +389,21 @@ evaluators["special outer with operation"] = evaluators.special
evaluators["special operation"] = evaluators.special
evaluators["special operation with arguments"] = evaluators.special
-function specials.url(var)
+function specials.url(handle,var)
local url = references.checkedurl(var.operation)
if url then
handle:write(" url='",url,"'")
end
end
-function specials.file(var)
+function specials.file(handle,var)
local file = references.checkedfile(var.operation)
if file then
handle:write(" file='",file,"'")
end
end
-function specials.fileorurl(var)
+function specials.fileorurl(handle,var)
local file, url = references.checkedfileorurl(var.operation,var.operation)
if url then
handle:write(" url='",file,"'")
@@ -331,7 +412,14 @@ function specials.fileorurl(var)
end
end
-local function addreference(references) -- todo: specials -> exporters and then concat
+function specials.internal(handle,var)
+ local internal = references.checkedurl(var.operation)
+ if internal then
+ handle:write(" location='aut:",internal,"'")
+ end
+end
+
+local function adddestination(handle,references) -- todo: specials -> exporters and then concat
if references then
local reference = references.reference
if reference and reference ~= "" then
@@ -339,44 +427,97 @@ local function addreference(references) -- todo: specials -> exporters and then
if prefix and prefix ~= "" then
handle:write(" prefix='",prefix,"'")
end
- handle:write(" reference='",reference,"'")
+ handle:write(" destination='",reference,"'")
for i=1,#references do
local r = references[i]
local e = evaluators[r.kind]
if e then
- e(r)
+ e(handle,r)
end
end
end
end
end
--- end of references related code --
+local function addreference(handle,references)
+ if references then
+ local reference = references.reference
+ if reference and reference ~= "" then
+ local prefix = references.prefix
+ if prefix and prefix ~= "" then
+ handle:write(" prefix='",prefix,"'")
+ end
+ handle:write(" reference='",reference,"'")
+ end
+ local internal = references.internal
+ if internal and internal ~= "" then
+ handle:write(" location='aut:",internal,"'")
+ end
+ end
+end
-function extras.link(element,detail,n,fulltag,di)
- -- why so often
+function extras.link(handle,element,detail,n,fulltag,di)
+ -- for instance in lists a link has nested elements and no own text
local hash = attributehash[fulltag]
if hash then
local references = hash.reference
if references then
- addreference(structures.references.get(references))
+ adddestination(handle,structures.references.get(references))
+ end
+ return true
+ else
+ local data = di.data
+ if data then
+ for i=1,#data do
+ local di = data[i]
+ if di and extras.link(handle,element,detail,n,di.fulltag,di) then
+ return true
+ end
+ end
end
end
end
-function extras.section(element,detail,n,fulltag,di)
- local hash = listhash[element]
- hash = hash and hash[n]
- addreference(hash and hash.references)
+function extras.section(handle,element,detail,n,fulltag,di)
+ local data = listdata[fulltag]
+ if data then
+ addreference(handle,data.references)
+ return true
+ else
+ local data = di.data
+ if data then
+ for i=1,#data do
+ local di = data[i]
+ if di then
+ local ft = di.fulltag
+ if ft and extras.section(handle,element,detail,n,ft,di) then
+ return true
+ end
+ end
+ end
+ end
+ end
end
-function extras.float(element,detail,n,fulltag,di)
- local hash = listhash[element]
- hash = hash and hash[n]
- addreference(hash and hash.references)
+function extras.float(handle,element,detail,n,fulltag,di)
+ local data = listdata[fulltag]
+ if data then
+ addreference(handle,data.references)
+ return true
+ else
+ local data = di.data
+ if data then
+ for i=1,#data do
+ local di = data[i]
+ if di and extras.section(handle,element,detail,n,di.fulltag,di) then
+ return true
+ end
+ end
+ end
+ end
end
-function extras.itemgroup(element,detail,n,fulltag,di)
+function extras.itemgroup(handle,element,detail,n,fulltag,di)
local data = di.data
for i=1,#data do
local di = data[i]
@@ -388,8 +529,6 @@ function extras.itemgroup(element,detail,n,fulltag,di)
local tg = ddi.tg
if tg == "itemtag" or tg == "itemcontent" then
local hash = attributehash[ddi.fulltag]
---~ table.print(attributehash)
---~ print(ddi.fulltag,hash)
if hash then
local v = hash.packed
if v and v == 1 then
@@ -408,47 +547,51 @@ function extras.itemgroup(element,detail,n,fulltag,di)
end
end
-function extras.tablecell(element,detail,n,fulltag,di)
+function extras.tablecell(handle,element,detail,n,fulltag,di)
local hash = attributehash[fulltag]
- local v = hash.align
- if not v or v == 0 then
- -- normal
- elseif v == 1 then
- handle:write(" align='flushright'")
- elseif v == 2 then
- handle:write(" align='middle'")
- elseif v == 3 then
- handle:write(" align='flushleft'")
- end
- local v = hash.columns
- if v and v > 1 then
- handle:write(" columns='",v,"'")
- end
- local v = hash.rows
- if v and v > 1 then
- handle:write(" rows='",v,"'")
+ if hash then
+ local v = hash.align
+ if not v or v == 0 then
+ -- normal
+ elseif v == 1 then
+ handle:write(" align='flushright'")
+ elseif v == 2 then
+ handle:write(" align='middle'")
+ elseif v == 3 then
+ handle:write(" align='flushleft'")
+ end
+ local v = hash.columns
+ if v and v > 1 then
+ handle:write(" columns='",v,"'")
+ end
+ local v = hash.rows
+ if v and v > 1 then
+ handle:write(" rows='",v,"'")
+ end
end
end
-function extras.tabulatecell(element,detail,n,fulltag,di)
+function extras.tabulatecell(handle,element,detail,n,fulltag,di)
local hash = attributehash[fulltag]
- local v = hash.align
- if not v or v == 0 then
- -- normal
- elseif v == 1 then
- handle:write(" align='flushright'")
- elseif v == 2 then
- handle:write(" align='middle'")
- elseif v == 3 then
- handle:write(" align='flushleft'")
+ if hash then
+ local v = hash.align
+ if not v or v == 0 then
+ -- normal
+ elseif v == 1 then
+ handle:write(" align='flushright'")
+ elseif v == 2 then
+ handle:write(" align='middle'")
+ elseif v == 3 then
+ handle:write(" align='flushleft'")
+ end
end
end
-local function emptytag(element,nature,depth)
+local function emptytag(handle,element,nature,depth)
handle:write("\n",spaces[depth],"<",element,"/>\n")
end
-local function begintag(element,nature,depth,di,empty)
+local function begintag(handle,element,nature,depth,di,empty)
local detail, n, fulltag = di.detail, di.n, di.fulltag
if nature == "inline" then
linedone = false
@@ -480,7 +623,7 @@ local function begintag(element,nature,depth,di,empty)
end
local extra = extras[element]
if extra then
- extra(element,detail,n,fulltag,di)
+ extra(handle,element,detail,n,fulltag,di)
end
local u = userdata[fulltag]
if u then
@@ -496,9 +639,10 @@ local function begintag(element,nature,depth,di,empty)
linedone = true
end
end
+ used[element][detail or ""] = nature
end
-local function endtag(element,nature,depth,empty)
+local function endtag(handle,element,nature,depth,empty)
if nature == "display" then
if inlinedepth == 0 then
if empty then
@@ -556,7 +700,7 @@ local function push(fulltag,depth,entry)
data = { },
attribute = attribute,
parnumber = parnumber,
- node = entry[5],
+ -- node = entry[5], -- will go
}
local treedata = tree.data
treedata[#treedata+1] = t
@@ -574,37 +718,29 @@ local function pop()
tree = remove(treestack)
end
-local function flush(current,content)
- if content then
- if collapse then
- tree.data[#tree.data+1] = content
- else
- handle:write(content)
- end
- end
-end
-
local function flushresult(entry)
local current, content = entry[1], entry[2]
if not content then
- -- skip
+ -- skip, normally this cannot happen
else
local newdepth, olddepth, content = #current, #treestack, concat(content)
if trace_export then
- report_export("%3i => %3i : handling: ",olddepth,newdepth,current[newdepth])
+ report_export("%s => %s : handling: %s",olddepth,newdepth,current[newdepth])
end
if olddepth <= 0 then
for i=1,newdepth do
if trace_export then
- report_export("[1] push :",current[i])
+ report_export("[1] push : %s",current[i])
end
push(current[i],i,entry)
end
- flush(current,content)
+ if content then
+ tree.data[#tree.data+1] = content
+ end
elseif newdepth < olddepth then
for i=newdepth,olddepth-1 do
if trace_export then
- report_export("[2a] pop :",current[i])
+ report_export("[2a] pop : %s",current[i])
end
pop()
end
@@ -613,7 +749,7 @@ local function flushresult(entry)
for i=newdepth,1,-1 do
if current[i] ~= treestack[i].fulltag then -- needs checking
if trace_export then
- report_export("[2b] pop :",current[i])
+ report_export("[2b] pop : %s",current[i])
end
pop()
else
@@ -623,16 +759,18 @@ local function flushresult(entry)
olddepth = #treestack
for i=olddepth+1,newdepth do
if trace_export then
- report_export("[2] push :",current[i])
+ report_export("[2] push : %s",current[i])
end
push(current[i],i,entry)
end
- flush(current,content)
+ if content then
+ tree.data[#tree.data+1] = content
+ end
elseif newdepth > olddepth then
for i=olddepth,1,-1 do
if current[i] ~= treestack[i].fulltag then
if trace_export then
- report_export("[3] pop :",current[i])
+ report_export("[3] pop : %s",current[i])
end
pop()
else
@@ -642,19 +780,23 @@ local function flushresult(entry)
olddepth = #treestack
for i=olddepth+1,newdepth do
if trace_export then
- report_export("[3] push :",current[i])
+ report_export("[3] push : %s",current[i])
end
push(current[i],i,entry)
end
- flush(current,content)
+ if content then
+ tree.data[#tree.data+1] = content
+ end
elseif current[newdepth] == treestack[olddepth] then --move up ?
-- continuation
- flush(current,content)
+ if content then
+ tree.data[#tree.data+1] = content
+ end
else
for i=olddepth,1,-1 do
if current[i] ~= treestack[i].fulltag then
if trace_export then
- report_export("[4] pop :",current[i])
+ report_export("[4] pop : %s",current[i])
end
pop()
else
@@ -664,11 +806,13 @@ local function flushresult(entry)
olddepth = #treestack
for i=olddepth+1,newdepth do
if trace_export then
- report_export("[4] push :",current[i])
+ report_export("[4] push : %s",current[i])
end
push(current[i],i,entry)
end
- flush(current,content)
+ if content then
+ tree.data[#tree.data+1] = content
+ end
end
end
end
@@ -692,47 +836,39 @@ local function checkinserts(data)
end
end
-local function checkreferences(data)
- local c = structures.lists.collected
- for i=1,#c do -- todo: make hash from name -> n
- local ci = c[i]
- local name = ci.metadata.kind
- local hash = listhash[name]
- if not hash then
- hash = { }
- listhash[name] = hash
- end
- local tag = ci.references.tag
- if tag then
- hash[tag] = ci
- end
- end
-end
-
-local function flushtree(data)
- for i=1,#data do
+local function flushtree(handle,data,nature)
+ local nofdata = #data
+ for i=1,nofdata do
local di = data[i]
if not di then
-- collapsed
elseif type(di) == "string" then
+if i == nofdata and sub(di,-1) == joiner_7 then
+ if nature == "inline" or nature == "mixed" then
+ handle:write(sub(di,1,-2))
+ else
+ handle:write(sub(di,1,-2)," ")
+ end
+else
handle:write(di)
+end
linedone = false
elseif not di.collapsed then
local element = di.element
if element == "break" or element == "pagebreak" then
- emptytag(element,nature,di.depth)
+ emptytag(handle,element,nature,di.depth)
else
local nature, depth = di.nature, di.depth
local did = di.data
local nid = #did
if nid == 0 or (nid == 1 and did[1] == "") then
- begintag(element,nature,depth,di,true)
+ begintag(handle,element,nature,depth,di,true)
-- no content
- endtag(element,nature,depth,true)
+ endtag(handle,element,nature,depth,true)
else
- begintag(element,nature,depth,di)
- flushtree(did)
- endtag(element,nature,depth)
+ begintag(handle,element,nature,depth,di)
+ flushtree(handle,did,nature)
+ endtag(handle,element,nature,depth)
end
end
end
@@ -750,9 +886,11 @@ local function collapsetree()
local lpn = v[i-1].parnumber
if lpn and lpn == 0 then lpn = nil end
if type(d[1]) ~= "string" then lpn = nil end -- no need anyway so no further testing needed
+local justdone = false
for j=1,#vd do
local vdj = vd[j]
if type(vdj) == "string" then
+--~ print(vdj)
-- experiment, should be improved
-- can be simplified ... lpn instead of done
if done then
@@ -779,6 +917,8 @@ local function collapsetree()
end
end
else
+--~ nd = nd + 1
+--~ d[nd] = joiner_3
-- lpn = nil
end
if vdj ~= "" then
@@ -815,7 +955,7 @@ local function prunetree(tree)
end
end
-function finishexport()
+local function finishexport()
if entry then
local result = entry[2]
if result and result[#result] == " " then
@@ -828,27 +968,25 @@ function finishexport()
end
end
-local function stopexport()
- if handle then
- report_export("finalizing")
- finishexport()
- if collapse then
- collapsetree()
- if trace_tree then
- prunetree(tree)
- report_export(table.serialize(tree,"root"))
- end
- end
- checkinserts(tree.data)
- checkreferences(tree.data)
- flushtree(tree.data)
- handle = false
- end
-end
+local displaymapping = {
+ inline = "inline",
+ display = "block",
+ mixed = "inline",
+}
+
+local e_template = [[
+%s {
+ display: %s
+}]]
+
+local d_template = [[
+%s[detail=%s] {
+ display: %s
+}]]
-- encoding='utf-8'
-local preamble = [[
+local xmlpreamble = [[
@@ -857,23 +995,112 @@ local preamble = [[
]]
-local done = false
+local csspreamble = [[
-local function startexport(v)
- if not done then
- local filename = tex.jobname
- if type(v) == "string" and v ~= variables.yes and v ~= "" then
- filename = v
+
+]]
+
+local cssfile, xhtmlfile = nil, nil
+
+directives.register("backend.export.css", function(v) cssfile = v end)
+directives.register("backend.export.xhtml",function(v) xhtmlfile = v end)
+
+local function stopexport(v)
+ starttiming(treehash)
+ report_export("finalizing")
+ finishexport()
+ collapsetree()
+ if trace_tree then
+ prunetree(tree)
+ report_export(table.serialize(tree,"root"))
+ end
+ checkinserts(tree.data)
+ hashlistdata()
+ if type(v) ~= "string" or v == variables.yes or v == "" then
+ v = tex.jobname
+ end
+ local xmlfile = file.addsuffix(v,"export")
+ local handle = io.open(xmlfile,"wb")
+ if handle then
+ report_export("saving xml data in '%s",xmlfile)
+ handle:write(format(xmlpreamble,tex.jobname,os.date(),environment.version,version))
+ if cssfile then
+ if type(v) ~= "string" or cssfile == variables.yes or cssfile == "" or cssfile == xmlfile then
+ cssfile = file.replacesuffix(xmlfile,"css")
+ else
+ cssfile = file.addsuffix(cssfile,"css")
+ end
+ report_export("adding css reference '%s",cssfile)
+ handle:write(format(csspreamble,cssfile))
end
- local filename = file.addsuffix(filename,"export") -- todo: v
- handle = io.open(filename,"wb")
- if handle then
- nodes.tasks.appendaction("shipouts", "normalizers", "nodes.handlers.export")
- report_export("saving xml in '%s",filename)
- handle:write(format(preamble,tex.jobname,os.date(),environment.version,version))
- luatex.registerstopactions(stopexport)
+ flushtree(handle,tree.data)
+ handle:close()
+ -- css template file
+ local cssfile = file.replacesuffix(xmlfile,"template")
+ report_export("saving css template in '%s",cssfile)
+ local templates = { format("/* template for file %s */",xmlfile) }
+ for element, details in table.sortedhash(used) do
+ templates[#templates+1] = format("/* category: %s */",element)
+ for detail, nature in table.sortedhash(details) do
+ local d = displaymapping[nature or "display"] or "block"
+ if detail == "" then
+ templates[#templates+1] = format(e_template,element,d)
+ else
+ templates[#templates+1] = format(d_template,element,detail,d)
+ end
+ end
+ end
+ io.savedata(cssfile,concat(templates,"\n\n"))
+ -- xhtml references
+ if xhtmlfile then
+ if type(v) ~= "string" or xhtmlfile == variables.yes or xhtmlfile == "" or xhtmlfile == xmlfile then
+ xhtmlfile = file.replacesuffix(xmlfile,"xhtml")
+ else
+ xhtmlfile = file.addsuffix(xhtmlfile,"xhtml")
+ end
+ report_export("saving xhtml variant in '%s",xhtmlfile)
+ local xmltree = xml.load(xmlfile)
+ if xmltree then
+ local xmlwrap = xml.wrap
+ for e in xml.collected(xmltree,"/document") do
+ e.at["xmlns:xhtml"] = "http://www.w3.org/1999/xhtml"
+ break
+ end
+ local wrapper = { tg = "a", ns = "xhtml", at = { href = "unknown" } }
+ for e in xml.collected(xmltree,"link") do
+ local location = e.at.location
+ if location then
+ wrapper.at.href = "#" .. gsub(location,":","_")
+ xmlwrap(e,wrapper)
+ end
+ end
+ local wrapper = { tg = "a", ns = "xhtml", at = { name = "unknown" } }
+ for e in xml.collected(xmltree,"!link[@location]") do
+ local location = e.at.location
+ if location then
+ wrapper.at.name = gsub(location,":","_")
+ xmlwrap(e,wrapper)
+ end
+ end
+ xml.save(xmltree,xhtmlfile)
+ end
+ end
+ else
+ report_export("unable to saving xml in '%s",xmlfile)
+ end
+ stoptiming(treehash)
+end
+
+local function startexport(v)
+ if v and not exporting then
+ nodes.tasks.appendaction("shipouts", "normalizers", "nodes.handlers.export")
+ report_export("enabling export to xml")
+ luatex.registerstopactions(function() stopexport(v) end)
+ if trace_spaces then
+ joiner_1 = "" joiner_2 = "" joiner_3 = "" joiner_4 = "" joiner_5 = ""
+ joiner_6 = "" joiner_7 = "" joiner_8 = "" joiner_9 = "" joiner_0 = ""
end
- done = true
+ exporting = true
end
end
@@ -883,23 +1110,32 @@ local function injectbreak()
flushresult(entry)
flushresult(makebreak(entry))
result = { }
- entry = { entry[1], result, last, lastpar }
+ entry = { entry[1], result, last, lastpar } -- entry[1] ?
+end
+
+local function injectspace(a,joiner)
+ flushresult(entry)
+ result = { joiner }
+ local tl = taglist[a]
+ entry = { tl , result, a, lastpar, n }
end
local function collectresults(head,list,p)
- local preceding = p or false -- nasty hack
+ local preceding = p or false
for n in traverse_nodes(head) do
local id = n.id -- 14: image, 8: literal (mp)
if id == glyph_code then
local at = has_attribute(n,a_tagged)
if not at then
- report_export("skipping character: 0x%05X %s (no attribute)",n.char,utfchar(n.char))
+ -- we need to tag the pagebody stuff as being valid skippable
+ --
+ -- report_export("skipping character: 0x%05X %s (no attribute)",n.char,utfchar(n.char))
else
- -- we could add tonunicodes for ligatures
+ -- we could add tonunicodes for ligatures (todo)
local components = n.components
- if components then
- collectresults(components,nil)
- preceding = false
+ if components then -- we loose data
+ collectresults(components,nil,preceding)
+--~ preceding = true
else
if last ~= at then
local tl = taglist[at]
@@ -913,16 +1149,20 @@ local function collectresults(head,list,p)
result = { }
end
lastpar = has_attribute(n,a_taggedpar)
- entry = { tl , result, at, lastpar, n }
- attributehash[tl[#tl]] = { -- this includes detail !
- align = has_attribute(n,a_taggedalign ),
- columns = has_attribute(n,a_taggedcolumns),
- rows = has_attribute(n,a_taggedrows ),
- packed = has_attribute(n,a_taggedpacked ),
- symbol = has_attribute(n,a_taggedsymbol ),
- insert = has_attribute(n,a_taggedinsert ),
- reference = has_attribute(n,a_reference ),
+ entry = { tl, result, at, lastpar, n }
+ local ah = { -- this includes detail !
+ align = has_attribute(n,a_taggedalign ),
+ columns = has_attribute(n,a_taggedcolumns),
+ rows = has_attribute(n,a_taggedrows ),
+ packed = has_attribute(n,a_taggedpacked ),
+ symbol = has_attribute(n,a_taggedsymbol ),
+ insert = has_attribute(n,a_taggedinsert ),
+ reference = has_attribute(n,a_reference ),
+ tag = has_attribute(n,a_taggedtag ), -- used for synonyms
}
+ if next(ah) then
+ attributehash[tl[#tl]] = ah
+ end
last = at
elseif last then
local at = has_attribute(n,a_taggedpar)
@@ -980,44 +1220,74 @@ local function collectresults(head,list,p)
last = nil
lastpar = nil
else
- -- maybe check for lines: n.subtype = line_code
+--~ if result and #result > 0 then -- and n.subtype == line_code then
+--~ local r = result[#result]
+--~ if type(r) == "string" and r ~= " " then
+--~ local s = utfsub(r,-1)
+--~ if s == hyphen then
+--~ result[#result] = utfsub(r,1,-2)
+--~ elseif s ~= joiner_7 then
+--~ result[#result] = r .. joiner_7
+--~ --~ preceding = true
+--~ end
+--~ end
+--~ preceding = false
+--~ end
+ -- we need to determine an end-of-line
preceding = collectresults(n.list,n,preceding)
preceding = false
end
- elseif id == disc_code then
+ elseif id == disc_code then -- probably too late
collectresults(n.replace,nil)
preceding = false
elseif id == glue_code then
+ -- we need to distinguish between hskips and vskips
local subtype = n.subtype
- if subtype == userskip_code then
+ if subtype == userskip_code then -- todo space_code
if n.spec.width > threshold then
- preceding = true
- if result then
- if last and #result > 0 and result[#result] ~= " " then
- if has_attribute(n,a_tagged) == last then
- result[#result+1] = joiner_6
- preceding = false
- end
+--~ preceding = true
+ if result and last and #result > 0 and result[#result] ~= " " then
+ local a = has_attribute(n,a_tagged)
+ if a == last then
+ result[#result+1] = joiner_6
+ preceding = false
+ elseif a then
+ -- e.g LOGOLOGO
+ preceding = false
+ last = a
+ injectspace(last,joiner_6)
end
end
end
---~ elseif subtype == rightskip_code or subtype == parfillskip_code then
---~ if result and last and #result > 0 and result[#result] ~= " " then
---~ result[#result+1] = joiner_7
---~ end
+ elseif subtype == rightskip_code or subtype == parfillskip_code then
+if result and #result > 0 then -- and n.subtype == line_code then
+ local r = result[#result]
+ if type(r) == "string" and r ~= " " then
+ local s = utfsub(r,-1)
+ if s == hyphen then
+ result[#result] = utfsub(r,1,-2)
+ elseif s ~= joiner_7 then
+ result[#result] = r .. joiner_7
+--~ preceding = true
+ end
+ end
+ preceding = false
+end
end
elseif id == kern_code then
if n.kern > threshold then
- preceding = true
- if result then
- if last and #result > 0 and result[#result] ~= " " then
- if has_attribute(n,a_tagged) == last then
- result[#result+1] = joiner_8
- preceding = false
- end
+--~ preceding = true
+ if result and last and #result > 0 and result[#result] ~= " " then
+ local a = has_attribute(n,a_tagged)
+ if a == last then
+ result[#result+1] = joiner_8
+ preceding = false
+ elseif a then
+ -- e.g LOGOLOGO
+ preceding = false
+ last = a
+ injectspace(last,joiner_8)
end
- elseif not preceding then
- preceding = true
end
end
end
@@ -1026,10 +1296,6 @@ local function collectresults(head,list,p)
end
function nodes.handlers.export(head)
- if trace_spaces then
- joiner_1 = "" joiner_2 = "" joiner_3 = "" joiner_4 = "" joiner_5 = ""
- joiner_6 = "" joiner_7 = "" joiner_8 = "" joiner_9 = "" joiner_0 = ""
- end
if result then
-- maybe we need a better test for what is in result so far
if page_breaks then
@@ -1037,7 +1303,15 @@ function nodes.handlers.export(head)
end
result[#result+1] = joiner_0
end
+ starttiming(treehash)
collectresults(head)
-- no flush here, pending page stuff
+ stoptiming(treehash)
return head, true
end
+
+statistics.register("xml exporting time", function()
+ if exporting then
+ return format("%s seconds", statistics.elapsedtime(treehash))
+ end
+end)
diff --git a/tex/context/base/back-exp.mkiv b/tex/context/base/back-exp.mkiv
index 98da9b06f..2da163a7e 100644
--- a/tex/context/base/back-exp.mkiv
+++ b/tex/context/base/back-exp.mkiv
@@ -33,6 +33,7 @@
\definesystemattribute[taggedpacked] [public]
\definesystemattribute[taggedsymbol] [public]
\definesystemattribute[taggedinsert] [public]
+\definesystemattribute[taggedtag] [public]
\def\setelementexporttag
{\dotripleargument\dosetelementexporttag}
@@ -74,6 +75,14 @@
\def\dotagtabulatealign{\attribute\taggedalignattribute\ifcase\tabulatealign\attributeunsetvalue\or\plusthree\or\plusone\or\plustwo\or\attributeunsetvalue\fi}%
\to \everyenableelements
+\appendtoks
+ \def\dotagsynonym{\ctxlua{structures.tags.setsynonym("\currentsynonym","\currentsynonymtag")}}%
+\to \everyenableelements
+
+\appendtoks
+ \def\dotagsorting{\ctxlua{structures.tags.setsorting("\currentsorting","\currentsortingtag")}}%
+\to \everyenableelements
+
\appendtoks
\def\dotagsetparcounter{\global\advance\tagparcounter\plusone\attribute\taggedparattribute\tagparcounter}%
\to \everyenableelements
@@ -90,14 +99,24 @@
\def\dotagsetnotesymbol{\ctxlua{structures.tags.setdescriptionid("\currentnote",\currentnotenumber)}}%
\to \everyenableelements
-% The action: \setubackend[export=yes] % or filename
+\appendtoks
+ \unexpanded\def\doverbatimspace{\char32\relax}% will be done permanently
+\to \everyenableelements
+
+% The action: \setupbackend[export=yes] % or filename
-\def\c!export{export}
+\def\c!export {export} % maybe: options={css,xhtml}
+\def\c!css {css}
+\def\c!xhtml {xhtml}
\appendtoks
\doifsomething{\backendparameter\c!export}
- {\setupstructure[\c!state=\v!start]%
- \enabledirectives[backend.export=\backendparameter\c!export]}%
+ {\setupstructure
+ [\c!state=\v!start]%
+ \enabledirectives
+ [backend.export=\backendparameter\c!export,%
+ backend.export.xhtml=\backendparameter\c!xhtml,%
+ backend.export.css=\backendparameter\c!css]}%
\to \everysetupbackend
\protect \endinput
diff --git a/tex/context/base/back-ini.lua b/tex/context/base/back-ini.lua
index 5cabc16ac..39de73741 100644
--- a/tex/context/base/back-ini.lua
+++ b/tex/context/base/back-ini.lua
@@ -6,7 +6,6 @@ if not modules then modules = { } end modules ['back-ini'] = {
license = "see context related readme files"
}
-local setmetatable = setmetatable
backends = backends or { }
local backends = backends
@@ -15,21 +14,26 @@ local trace_backend = false trackers.register("backend.initializers", function(
local report_backend = logs.reporter("backend","initializing")
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
+
local function nothing() return nil end
backends.nothing = nothing
-local mt = {
- __index = function(t,k)
- t[k] = nothing
- return nothing
- end
-}
+local nodeinjections = { }
+local codeinjections = { }
+local registrations = { }
+local tables = allocate()
+
+local function donothing(t,k)
+ t[k] = nothing
+ return nothing
+end
-local nodeinjections = { } setmetatable(nodeinjections, mt)
-local codeinjections = { } setmetatable(codeinjections, mt)
-local registrations = { } setmetatable(registrations, mt)
-local tables = { }
+setmetatableindex(nodeinjections, donothing)
+setmetatableindex(codeinjections, donothing)
+setmetatableindex(registrations, donothing)
local defaults = {
nodeinjections = nodeinjections,
@@ -40,10 +44,10 @@ local defaults = {
backends.defaults = defaults
-backends.nodeinjections = { } setmetatable(backends.nodeinjections, { __index = nodeinjections })
-backends.codeinjections = { } setmetatable(backends.codeinjections, { __index = codeinjections })
-backends.registrations = { } setmetatable(backends.registrations, { __index = registrations })
-backends.tables = { } setmetatable(backends.tables, { __index = tables })
+backends.nodeinjections = { } setmetatableindex(backends.nodeinjections, nodeinjections)
+backends.codeinjections = { } setmetatableindex(backends.codeinjections, codeinjections)
+backends.registrations = { } setmetatableindex(backends.registrations, registrations)
+backends.tables = { } setmetatableindex(backends.tables, tables)
backends.current = "unknown"
@@ -57,8 +61,8 @@ function backends.install(what)
backends.current = what
for category, default in next, defaults do
local target, plugin = backends[category], backend[category]
- setmetatable(plugin, { __index = default })
- setmetatable(target, { __index = plugin })
+ setmetatableindex(plugin, default)
+ setmetatableindex(target, plugin)
end
elseif trace_backend then
report_backend("no backend named %s",what)
@@ -77,7 +81,7 @@ end)
local comment = { "comment", "" }
-tables.vfspecials = {
+tables.vfspecials = allocate {
red = comment,
green = comment,
blue = comment,
diff --git a/tex/context/base/back-pdf.lua b/tex/context/base/back-pdf.lua
index 5f4ea465c..f6f82c7f5 100644
--- a/tex/context/base/back-pdf.lua
+++ b/tex/context/base/back-pdf.lua
@@ -427,6 +427,8 @@ function registrations.transparency(n,a,t)
end
end
+-- overloaded in lpdf-xmp:
+
function codeinjections.adddocumentinfo(key,value)
lpdf.addtoinfo(key,lpdf.tosixteen(value))
end
diff --git a/tex/context/base/buff-ver.lua b/tex/context/base/buff-ver.lua
index a1f98ab0a..bd274a36a 100644
--- a/tex/context/base/buff-ver.lua
+++ b/tex/context/base/buff-ver.lua
@@ -18,25 +18,25 @@ local concat = table.concat
local C, P, R, V, Carg, Cc, Cs = lpeg.C, lpeg.P, lpeg.R, lpeg.V, lpeg.Carg, lpeg.Cc, lpeg.Cs
local patterns, lpegmatch, is_lpeg = lpeg.patterns, lpeg.match, lpeg.is_lpeg
-local tabtospace = utilities.strings.tabtospace
-local variables = interfaces.variables
-local settings_to_array = utilities.parsers.settings_to_array
+local trace_visualize = false trackers.register("buffers.visualize", function(v) trace_visualize = v end)
+local report_visualizers = logs.reporter("buffers","visualizers")
-local trace_visualize = false trackers.register("buffers.visualize", function(v) trace_visualize = v end)
+local allocate = utilities.storage.allocate
-local report_visualizers = logs.reporter("buffers","visualizers")
+visualizers = visualizers or { }
+local specifications = allocate()
+visualizers.specifications = specifications
-visualizers = visualizers or { }
+local tabtospace = utilities.strings.tabtospace
+local variables = interfaces.variables
+local settings_to_array = utilities.parsers.settings_to_array
+local verbatim = context.verbatim
+local variables = interfaces.variables
+local findfile = resolvers.findfile
+local addsuffix = file.addsuffix
-local specifications = { } visualizers.specifications = specifications
-
-local verbatim = context.verbatim
-local variables = interfaces.variables
-local findfile = resolvers.findfile
-local addsuffix = file.addsuffix
-
-local v_auto = variables.auto
-local v_yes = variables.yes
+local v_auto = variables.auto
+local v_yes = variables.yes
-- beware, these all get an argument (like newline)
@@ -315,7 +315,8 @@ function visualizers.register(name,specification)
return specification
end
-local escapepatterns = { } visualizers.escapepatterns = escapepatterns
+local escapepatterns = allocate()
+visualizers.escapepatterns = escapepatterns
local function texmethod(s)
context.bgroup()
diff --git a/tex/context/base/buff-ver.mkiv b/tex/context/base/buff-ver.mkiv
index ab1d0cb23..114cb2128 100644
--- a/tex/context/base/buff-ver.mkiv
+++ b/tex/context/base/buff-ver.mkiv
@@ -466,8 +466,9 @@
\def\dodotypeblockverbatim#1#2%
{\secondstageinitializetyping
- \beginofverbatimlines
\dostarttagged\t!verbatimblock\currenttyping
+ \beginofverbatimlines
+ \dostarttagged\t!verbatimlines\empty
\ctxcommand{typebuffer {
name = "_typing_",
strip = "\typingparameter\c!strip",
@@ -479,6 +480,7 @@
}}%
\dostoptagged
\endofverbatimlines
+ \dostoptagged
\csname#2\endcsname}
\def\dostoptyping#1% hm, currenttyping
@@ -578,8 +580,9 @@
\dosetuptypelinenumbering
\firststageinitializetyping
\secondstageinitializetyping
- \beginofverbatimlines
\dostarttagged\t!verbatimblock\currenttyping
+ \beginofverbatimlines
+ \dostarttagged\t!verbatimlines\empty
\ctxcommand{typefile {
name = "#2",
strip = "\typingparameter\c!strip",
@@ -591,6 +594,7 @@
}}%
\dostoptagged
\endofverbatimlines
+ \dostoptagged
\stoppacked
\typingparameter\c!after}
@@ -741,7 +745,7 @@
\firststageinitializetyping
\secondstageinitializetyping
\beginofverbatimlines
- \dostarttagged\t!verbatim{#1}%
+ \dostarttagged\t!verbatimblock{#1}%
\ctxcommand{typebuffer {
name = "#2",
strip = "\typingparameter\c!strip",
@@ -813,11 +817,13 @@
\fi}
\def\doverbatimemptyline
- {\ifconditional\verbatimnumberinglines
+ {\dostoptagged
+ \ifconditional\verbatimnumberinglines
\par\strut\par % this will be an option where we use a signal instead of a strut
\else
\blank[\typingparameter\c!blank]%
- \fi}
+ \fi
+ \dostarttagged\t!verbatimlines\empty}
% hooks:
diff --git a/tex/context/base/char-ini.lua b/tex/context/base/char-ini.lua
index a10b75398..159ff47e7 100644
--- a/tex/context/base/char-ini.lua
+++ b/tex/context/base/char-ini.lua
@@ -13,20 +13,24 @@ local utf = unicode.utf8
local utfchar, utfbyte, utfvalues = utf.char, utf.byte, string.utfvalues
local concat, unpack = table.concat, table.unpack
-local next, tonumber, type, rawget, rawset, setmetatable = next, tonumber, type, rawget, rawset, setmetatable
+local next, tonumber, type, rawget, rawset = next, tonumber, type, rawget, rawset
local texsprint, texprint = tex.sprint, tex.print
local format, lower, gsub, match, gmatch = string.format, string.lower, string.gsub, string.match, string.match, string.gmatch
-local texsetlccode, texsetuccode, texsetsfcode, texsetcatcode = tex.setlccode, tex.setuccode, tex.setsfcode, tex.setcatcode
local P, R, lpegmatch = lpeg.P, lpeg.R, lpeg.match
-local allocate, mark = utilities.storage.allocate, utilities.storage.mark
+local allocate = utilities.storage.allocate
+local mark = utilities.storage.mark
+local texsetlccode = tex.setlccode
+local texsetuccode = tex.setuccode
+local texsetsfcode = tex.setsfcode
+local texsetcatcode = tex.setcatcode
+local ctxcatcodes = tex.ctxcatcodes
+local texcatcodes = tex.texcatcodes
+local setmetatableindex = table.setmetatableindex
-local ctxcatcodes = tex.ctxcatcodes
-local texcatcodes = tex.texcatcodes
+local trace_defining = false trackers.register("characters.defining", function(v) characters_defining = v end)
-local trace_defining = false trackers.register("characters.defining", function(v) characters_defining = v end)
-
-local report_defining = logs.reporter("characters")
+local report_defining = logs.reporter("characters")
--[[ldx--
This module implements some methods and creates additional datastructured
@@ -95,7 +99,7 @@ local private = {
local ranges = allocate()
characters.ranges = ranges
-setmetatablekey(data, "__index", function(t,k)
+setmetatableindex(data, function(t,k)
local tk = type(k)
if tk == "string" then
k = lpegmatch(pattern,k) or utfbyte(k)
@@ -124,9 +128,7 @@ setmetatablekey(data, "__index", function(t,k)
end
end
return private -- handy for when we loop over characters in fonts and check for a property
-end )
-
---~ setmetatable(data,{ __index = function(t,k) return "" end }) -- quite old, obsolete
+end)
local blocks = allocate {
["aegeannumbers"] = { first = 0x10100, last = 0x1013F, description = "Aegean Numbers" },
@@ -304,9 +306,9 @@ local blocks = allocate {
characters.blocks = blocks
-setmetatable(blocks, { __index = function(t,k)
+setmetatableindex(blocks, function(t,k)
return k and rawget(t,lower(gsub(k,"[^a-zA-Z]","")))
-end } )
+end)
function characters.getrange(name) -- used in font fallback definitions (name or range)
local range = blocks[name]
@@ -400,10 +402,10 @@ local mt = { -- yes or no ?
end
}
-setmetatable(characters.is_character, mt)
-setmetatable(characters.is_letter, mt)
-setmetatable(characters.is_command, mt)
-setmetatable(characters.is_spacing, mt)
+setmetatableindex(characters.is_character, mt)
+setmetatableindex(characters.is_letter, mt)
+setmetatableindex(characters.is_command, mt)
+setmetatableindex(characters.is_spacing, mt)
-- linebreak: todo: hash
--
@@ -702,32 +704,32 @@ utf.string = utf.string or utfstring
characters.categories = allocate() local categories = characters.categories -- lazy table
-setmetatable(categories, { __index = function(t,u) if u then local c = data[u] c = c and c.category or u t[u] = c return c end end } )
+setmetatableindex(categories, function(t,u) if u then local c = data[u] c = c and c.category or u t[u] = c return c end end)
characters.lccodes = allocate() local lccodes = characters.lccodes -- lazy table
characters.uccodes = allocate() local uccodes = characters.uccodes -- lazy table
characters.shcodes = allocate() local shcodes = characters.shcodes -- lazy table
characters.fscodes = allocate() local fscodes = characters.fscodes -- lazy table
-setmetatable(lccodes, { __index = function(t,u) if u then local c = data[u] c = c and c.lccode or (type(u) == "string" and utfbyte(u)) or u t[u] = c return c end end } )
-setmetatable(uccodes, { __index = function(t,u) if u then local c = data[u] c = c and c.uccode or (type(u) == "string" and utfbyte(u)) or u t[u] = c return c end end } )
-setmetatable(shcodes, { __index = function(t,u) if u then local c = data[u] c = c and c.shcode or (type(u) == "string" and utfbyte(u)) or u t[u] = c return c end end } )
-setmetatable(fscodes, { __index = function(t,u) if u then local c = data[u] c = c and c.fscode or (type(u) == "string" and utfbyte(u)) or u t[u] = c return c end end } )
+setmetatableindex(lccodes, function(t,u) if u then local c = data[u] c = c and c.lccode or (type(u) == "string" and utfbyte(u)) or u t[u] = c return c end end)
+setmetatableindex(uccodes, function(t,u) if u then local c = data[u] c = c and c.uccode or (type(u) == "string" and utfbyte(u)) or u t[u] = c return c end end)
+setmetatableindex(shcodes, function(t,u) if u then local c = data[u] c = c and c.shcode or (type(u) == "string" and utfbyte(u)) or u t[u] = c return c end end)
+setmetatableindex(fscodes, function(t,u) if u then local c = data[u] c = c and c.fscode or (type(u) == "string" and utfbyte(u)) or u t[u] = c return c end end)
characters.lcchars = allocate() local lcchars = characters.lcchars -- lazy table
characters.ucchars = allocate() local ucchars = characters.ucchars -- lazy table
characters.shchars = allocate() local shchars = characters.shchars -- lazy table
characters.fschars = allocate() local fschars = characters.fschars -- lazy table
-setmetatable(lcchars, { __index = function(t,u) if u then local c = data[u] c = c and c.lccode c = c and utfstring(c) or (type(u) == "number" and utfchar(u)) or u t[u] = c return c end end } )
-setmetatable(ucchars, { __index = function(t,u) if u then local c = data[u] c = c and c.uccode c = c and utfstring(c) or (type(u) == "number" and utfchar(u)) or u t[u] = c return c end end } )
-setmetatable(shchars, { __index = function(t,u) if u then local c = data[u] c = c and c.shcode c = c and utfstring(c) or (type(u) == "number" and utfchar(u)) or u t[u] = c return c end end } )
-setmetatable(fschars, { __index = function(t,u) if u then local c = data[u] c = c and c.fscode c = c and utfstring(c) or (type(u) == "number" and utfchar(u)) or u t[u] = c return c end end } )
+setmetatableindex(lcchars, function(t,u) if u then local c = data[u] c = c and c.lccode c = c and utfstring(c) or (type(u) == "number" and utfchar(u)) or u t[u] = c return c end end)
+setmetatableindex(ucchars, function(t,u) if u then local c = data[u] c = c and c.uccode c = c and utfstring(c) or (type(u) == "number" and utfchar(u)) or u t[u] = c return c end end)
+setmetatableindex(shchars, function(t,u) if u then local c = data[u] c = c and c.shcode c = c and utfstring(c) or (type(u) == "number" and utfchar(u)) or u t[u] = c return c end end)
+setmetatableindex(fschars, function(t,u) if u then local c = data[u] c = c and c.fscode c = c and utfstring(c) or (type(u) == "number" and utfchar(u)) or u t[u] = c return c end end)
characters.specialchars = allocate() local specialchars = characters.specialchars -- lazy table
characters.descriptions = allocate() local descriptions = characters.descriptions -- lazy table
-setmetatable(specialchars, { __index = function(t,u)
+setmetatableindex(specialchars, function(t,u)
if u then
local c = data[u]
local s = c and c.specials
@@ -752,9 +754,9 @@ setmetatable(specialchars, { __index = function(t,u)
return u
end
end
-end } )
+end)
-setmetatable(descriptions, { __index = function(t,k)
+setmetatableindex(descriptions, function(t,k)
-- 0.05 - 0.10 sec
for u, c in next, data do
local d = c.description
@@ -769,7 +771,7 @@ setmetatable(descriptions, { __index = function(t,k)
t[k] = k
end
return d
-end } )
+end)
function characters.unicodechar(asked)
local n = tonumber(asked)
diff --git a/tex/context/base/cldf-ini.lua b/tex/context/base/cldf-ini.lua
index da8e70962..8edc05023 100644
--- a/tex/context/base/cldf-ini.lua
+++ b/tex/context/base/cldf-ini.lua
@@ -21,6 +21,8 @@ if not modules then modules = { } end modules ['cldf-ini'] = {
-- __flushlines is an experiment and rather ugly so it will go away
+local tex = tex
+
context = context or { }
local context = context
@@ -29,31 +31,29 @@ local next, type, tostring, setmetatable = next, type, tostring, setmetatable
local insert, remove, concat = table.insert, table.remove, table.concat
local lpegmatch = lpeg.match
-local tex = tex
-
-local texsprint = tex.sprint
-local textprint = tex.tprint
-local texprint = tex.print
-local texiowrite = texio.write
-local texcount = tex.count
+local texsprint = tex.sprint
+local textprint = tex.tprint
+local texprint = tex.print
+local texiowrite = texio.write
+local texcount = tex.count
-local isnode = node.is_node -- after 0.65 just node.type
-local writenode = node.write
-local copynodelist = node.copy_list
+local isnode = node.is_node -- after 0.65 just node.type
+local writenode = node.write
+local copynodelist = node.copy_list
-local ctxcatcodes = tex.ctxcatcodes
-local prtcatcodes = tex.prtcatcodes
-local texcatcodes = tex.texcatcodes
-local txtcatcodes = tex.txtcatcodes
-local vrbcatcodes = tex.vrbcatcodes
-local xmlcatcodes = tex.xmlcatcodes
+local ctxcatcodes = tex.ctxcatcodes
+local prtcatcodes = tex.prtcatcodes
+local texcatcodes = tex.texcatcodes
+local txtcatcodes = tex.txtcatcodes
+local vrbcatcodes = tex.vrbcatcodes
+local xmlcatcodes = tex.xmlcatcodes
-local flush = texsprint
+local flush = texsprint
-local report_context = logs.reporter("cld","tex")
-local report_cld = logs.reporter("cld","stack")
+local report_context = logs.reporter("cld","tex")
+local report_cld = logs.reporter("cld","stack")
-local processlines = true -- experiments.register("context.processlines", function(v) processlines = v end)
+local processlines = true -- experiments.register("context.processlines", function(v) processlines = v end)
-- for tracing it's easier to have two stacks
@@ -116,11 +116,11 @@ end
context._stack_f_ = _stack_f_
context._store_f_ = _store_f_
-context._flush_f_ = _flush_f_ cldff = _flush_f_
+context._flush_f_ = _flush_f_ _cldf_ = _flush_f_
context._stack_n_ = _stack_n_
context._store_n_ = _store_n_
-context._flush_n_ = _flush_n_ cldfn = _flush_n_
+context._flush_n_ = _flush_n_ _cldn_ = _flush_n_
-- Should we keep the catcodes with the function?
@@ -285,7 +285,7 @@ local function writer(parent,command,first,...)
elseif tn == 1 then -- some 20% faster than the next loop
local tj = ti[1]
if type(tj) == "function" then
- flush(currentcatcodes,"[\\cldff{",_store_f_(tj),"}]")
+ flush(currentcatcodes,"[\\cldf{",_store_f_(tj),"}]")
else
flush(currentcatcodes,"[",tj,"]")
end
@@ -293,13 +293,13 @@ local function writer(parent,command,first,...)
for j=1,tn do
local tj = ti[j]
if type(tj) == "function" then
- ti[j] = "\\cldff{" .. _store_f_(tj) .. "}"
+ ti[j] = "\\cldf{" .. _store_f_(tj) .. "}"
end
end
flush(currentcatcodes,"[",concat(ti,","),"]")
end
elseif typ == "function" then
- flush(currentcatcodes,"{\\cldff{",_store_f_(ti),"}}") -- todo: ctx|prt|texcatcodes
+ flush(currentcatcodes,"{\\cldf{",_store_f_(ti),"}}") -- todo: ctx|prt|texcatcodes
elseif typ == "boolean" then
if ti then
-- flush(currentcatcodes,"^^M")
@@ -310,7 +310,7 @@ local function writer(parent,command,first,...)
elseif typ == "thread" then
report_context("coroutines not supported as we cannot yield across boundaries")
elseif isnode(ti) then -- slow
- flush(currentcatcodes,"{\\cldfn{",_store_n_(ti),"}}")
+ flush(currentcatcodes,"{\\cldn{",_store_n_(ti),"}}")
else
report_context("error: '%s' gets a weird argument '%s'",command,tostring(ti))
end
@@ -354,7 +354,7 @@ local function caller(parent,f,a,...)
end
elseif typ == "function" then
-- ignored: a ...
- flush(currentcatcodes,"{\\cldff{",_store_f_(f),"}}") -- todo: ctx|prt|texcatcodes
+ flush(currentcatcodes,"{\\cldf{",_store_f_(f),"}}") -- todo: ctx|prt|texcatcodes
elseif typ == "boolean" then
if f then
if a ~= nil then
@@ -377,7 +377,7 @@ local function caller(parent,f,a,...)
report_context("coroutines not supported as we cannot yield across boundaries")
elseif isnode(f) then -- slow
-- writenode(f)
- flush(currentcatcodes,"\\cldfn{",_store_n_(f),"}")
+ flush(currentcatcodes,"\\cldn{",_store_n_(f),"}")
else
report_context("error: 'context' gets a weird argument '%s'",tostring(f))
end
@@ -625,7 +625,7 @@ local function caller(parent,f,a,...)
end
elseif typ == "function" then
-- ignored: a ...
- flush(currentcatcodes,mpdrawing,"{\\cldff{",store_(f),"}}")
+ flush(currentcatcodes,mpdrawing,"{\\cldf{",store_(f),"}}")
elseif typ == "boolean" then
-- ignored: a ...
if f then
diff --git a/tex/context/base/cldf-ini.mkiv b/tex/context/base/cldf-ini.mkiv
index 35cf5a2ac..5f7e31ae7 100644
--- a/tex/context/base/cldf-ini.mkiv
+++ b/tex/context/base/cldf-ini.mkiv
@@ -15,6 +15,9 @@
\registerctxluafile{cldf-ini}{1.001}
+\def\cldf#1{\directlua\zerocount{_cldf_(#1)}} % global (functions)
+\def\cldn#1{\directlua\zerocount{_cldn_(#1)}} % global (nodes)
+
\normalprotected\def\cldprocessfile#1{\directlua\zerocount{context.runfile("#1")}}
\def\cldcontext #1{\directlua\zerocount{context(#1)}}
\def\cldcommand #1{\directlua\zerocount{context.#1}}
diff --git a/tex/context/base/cldf-int.lua b/tex/context/base/cldf-int.lua
index 4e2e7b0e6..2291fd849 100644
--- a/tex/context/base/cldf-int.lua
+++ b/tex/context/base/cldf-int.lua
@@ -7,6 +7,8 @@ if not modules then modules = { } end modules ['mult-clm'] = {
}
-- another experiment
+-- needs upgrading
+-- needs checking
-- todo: multilingual
local texsprint, ctxcatcodes, vrbcatcodes = tex.sprint, tex.ctxcatcodes, tex.vrbcatcodes
@@ -15,9 +17,10 @@ local unpack = unpack or table.unpack
local trace_define = false trackers.register("context.define", function(v) trace_define = v end)
-mkiv = mkiv or { }
+interfaces = interfaces or { }
-mkiv.h, mkiv.a = utilities.parsers.settings_to_hash, utilities.parsers.settings_to_array
+_clmh_ = utilities.parsers.settings_to_array
+_clma_ = utilities.parsers.settings_to_array
local starters, stoppers, macros, stack = { }, { }, { }, { }
@@ -30,17 +33,17 @@ local checkers = {
"\\dosixtupleempty",
}
-function mkiv.m(name,...)
+function _clmm_(name,...)
macros[name](...)
end
-function mkiv.b(name,...)
+function _clmb_(name,...)
local sn = stack[name]
insert(sn,{...})
starters[name](...)
end
-function mkiv.e(name)
+function _clme_(name)
local sn = stack[name]
local sv = remove(sn)
if sv then
@@ -50,9 +53,9 @@ function mkiv.e(name)
end
end
-mkiv.n = tonumber
+_clmn_ = tonumber
-function mkiv.define(name,specification) -- name is optional
+function interfaces.definecommand(name,specification) -- name is optional
if type(name) == "table" then
specification = name
name = specification.name
@@ -63,15 +66,15 @@ function mkiv.define(name,specification) -- name is optional
local environment = specification.environment
if na == 0 then
if environment then
- texsprint(ctxcatcodes,"\\mkdefstart{",name,"}{\\ctxlua{mkiv.b('",name,"')}}")
- texsprint(ctxcatcodes,"\\mkdefstop{", name,"}{\\ctxlua{mkiv.b('",name,"')}}")
+ texsprint(ctxcatcodes,"\\clmb{",name,"}{\\ctxlua{_clmb_('",name,"')}}")
+ texsprint(ctxcatcodes,"\\clme{",name,"}{\\ctxlua{_clme_('",name,"')}}")
else
- texsprint(ctxcatcodes,"\\mkivdef{", name,"}{\\ctxlua{mkiv.m('",name,"')}}")
+ texsprint(ctxcatcodes,"\\clmm{",name,"}{\\ctxlua{_clmm_('",name,"')}}")
end
else
stack[name] = { }
local opt, done = 0, false
- local mkivdo = "\\mkivdo" .. name
+ local mkivdo = "\\mkivdo" .. name -- maybe clddo
texsprint(ctxcatcodes,"\\def",mkivdo)
for i=1,na do
local a = arguments[i]
@@ -87,29 +90,29 @@ function mkiv.define(name,specification) -- name is optional
end
end
if environment then
- texsprint(ctxcatcodes,"{\\ctxlua{mkiv.b('",name,"'")
+ texsprint(ctxcatcodes,"{\\ctxlua{_clmb_('",name,"'")
else
- texsprint(ctxcatcodes,"{\\ctxlua{mkiv.m('",name,"'")
+ texsprint(ctxcatcodes,"{\\ctxlua{_clmm_('",name,"'")
end
for i=1,na do
local a = arguments[i]
local variant = a[2]
if variant == "list" then
- texsprint(ctxcatcodes,",mkiv.a([[#",i,"]])")
+ texsprint(ctxcatcodes,",_clma_([[#",i,"]])")
elseif variant == "hash" then
- texsprint(ctxcatcodes,",mkiv.h([[#",i,"]])")
+ texsprint(ctxcatcodes,",_clmh_([[#",i,"]])")
elseif variant == "number" then
- texsprint(ctxcatcodes,",mkiv.n([[#",i,"]])")
+ texsprint(ctxcatcodes,",_clmn_([[#",i,"]])")
else
texsprint(ctxcatcodes,",[[#",i,"]]")
end
end
texsprint(ctxcatcodes,")}}")
if environment then
- texsprint(ctxcatcodes,"\\mkivdefstop{" ,name,"}{\\ctxlua{mkiv.e('",name,"')}}")
- texsprint(ctxcatcodes,"\\mkivdefstart{",name,"}{",checkers[opt],mkivdo,"}")
+ texsprint(ctxcatcodes,"\\clme{",name,"}{\\ctxlua{_clme_('",name,"')}}")
+ texsprint(ctxcatcodes,"\\clmb{",name,"}{",checkers[opt],mkivdo,"}")
else
- texsprint(ctxcatcodes,"\\mkivdef{", name,"}{",checkers[opt],mkivdo,"}")
+ texsprint(ctxcatcodes,"\\clmm{",name,"}{",checkers[opt],mkivdo,"}")
end
end
if environment then
@@ -121,7 +124,7 @@ function mkiv.define(name,specification) -- name is optional
end
end
-function mkiv.tolist(t)
+function interfaces.tolist(t)
local r = { }
for i=1,#t do
r[i] = t[i]
@@ -139,15 +142,15 @@ end
--~ \startluacode
--~ function test(opt_1, opt_2, arg_1)
--~ context.startnarrower()
---~ context("options 1: %s",mkiv.tolist(opt_1))
+--~ context("options 1: %s",interfaces.tolist(opt_1))
--~ context.par()
---~ context("options 2: %s",mkiv.tolist(opt_2))
+--~ context("options 2: %s",interfaces.tolist(opt_2))
--~ context.par()
--~ context("argument 1: %s",arg_1)
--~ context.stopnarrower()
--~ end
---~ mkiv.define {
+--~ interfaces.definecommand {
--~ name = "test",
--~ arguments = {
--~ { "option", "list" },
@@ -163,17 +166,17 @@ end
--~ \startluacode
--~ local function startmore(opt_1)
--~ context.startnarrower()
---~ context("start more, options: %s",mkiv.tolist(opt_1))
+--~ context("start more, options: %s",interfaces.tolist(opt_1))
--~ context.startnarrower()
--~ end
--~ local function stopmore(opt_1)
--~ context.stopnarrower()
---~ context("stop more, options: %s",mkiv.tolist(opt_1))
+--~ context("stop more, options: %s",interfaces.tolist(opt_1))
--~ context.stopnarrower()
--~ end
---~ mkiv.define ( "more", {
+--~ interfaces.definecommand ( "more", {
--~ environment = true,
--~ arguments = {
--~ { "option", "list" },
diff --git a/tex/context/base/cldf-int.mkiv b/tex/context/base/cldf-int.mkiv
index b510dfe80..cedac8fc0 100644
--- a/tex/context/base/cldf-int.mkiv
+++ b/tex/context/base/cldf-int.mkiv
@@ -17,14 +17,8 @@
\unprotect
-\unexpanded\def\mkivdefstart #1{\unexpanded\expandafter\def\csname\e!start#1\endcsname}
-\unexpanded\def\mkivdefstop #1{\unexpanded\expandafter\def\csname\e!stop #1\endcsname}
-\unexpanded\def\mkivdef #1{\unexpanded\expandafter\def\csname #1\endcsname}
-
- \def\cldff #1{\directlua\zerocount{cldff(#1)}} % global (functions)
- \def\cldfn #1{\directlua\zerocount{cldfn(#1)}} % global (nodes)
-
- %\def\mkivflush #1{\directlua\zerocount{context._flush_f_(#1)}} % obsolete
- \let\mkivflush \cldff
+\unexpanded\def\clmb#1{\unexpanded\expandafter\def\csname\e!start#1\endcsname}
+\unexpanded\def\clme#1{\unexpanded\expandafter\def\csname\e!stop #1\endcsname}
+\unexpanded\def\clmm#1{\unexpanded\expandafter\def\csname #1\endcsname}
\protect \endinput
diff --git a/tex/context/base/cont-new.mkii b/tex/context/base/cont-new.mkii
index 67a42198f..6d4d27f53 100644
--- a/tex/context/base/cont-new.mkii
+++ b/tex/context/base/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2011.04.03 22:32}
+\newcontextversion{2011.04.11 16:45}
%D This file is loaded at runtime, thereby providing an
%D excellent place for hacks, patches, extensions and new
diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv
index acc44ba36..cbf10277a 100644
--- a/tex/context/base/cont-new.mkiv
+++ b/tex/context/base/cont-new.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2011.04.03 22:32}
+\newcontextversion{2011.04.11 16:45}
%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.mkii b/tex/context/base/context.mkii
index dcadc7c69..3223fea70 100644
--- a/tex/context/base/context.mkii
+++ b/tex/context/base/context.mkii
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2011.04.03 22:32}
+\edef\contextversion{2011.04.11 16:45}
%D For those who want to use this:
diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv
index c303419b9..64e2b5e28 100644
--- a/tex/context/base/context.mkiv
+++ b/tex/context/base/context.mkiv
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2011.04.03 22:32}
+\edef\contextversion{2011.04.11 16:45}
%D For those who want to use this:
diff --git a/tex/context/base/core-con.lua b/tex/context/base/core-con.lua
index 3ad9f6c98..3b2d396b0 100644
--- a/tex/context/base/core-con.lua
+++ b/tex/context/base/core-con.lua
@@ -17,14 +17,16 @@ slower but look nicer this way.
local utf = unicode.utf8
local floor, date, time, concat = math.floor, os.date, os.time, table.concat
-local lower, format, rep = string.lower, string.format, string.rep
+local lower, format, rep, match = string.lower, string.format, string.rep, string.match
local utfchar, utfbyte = utf.char, utf.byte
local tonumber, tostring = tonumber, tostring
local settings_to_array = utilities.parsers.settings_to_array
local allocate = utilities.storage.allocate
-local context = context
+local context = context
+
+local variables = interfaces.variables
converters = converters or { }
local converters = converters
@@ -697,3 +699,170 @@ end
-- function converters.Alphabetic(n,code)
-- do_alphabetic(n,counters[code] or counters['**'],uppercased)
-- end
+
+-- --
+
+local ordinals = {
+ english = function(n)
+ local two = n % 100
+ if two == 11 or two == 12 or to == 13 then
+ return "th"
+ else
+ local one = n % 10
+ if one == 1 then
+ return "st"
+ elseif one == 2 then
+ return "nd"
+ elseif one == 3 then
+ return "rd"
+ else
+ return "th"
+ end
+ end
+ end,
+ dutch = function(n)
+ return "e"
+ end,
+ french = function(n)
+ if n == 1 then
+ return "er"
+ end
+ end,
+}
+
+ordinals.en = ordinals.english
+ordinals.nl = ordinals.dutch
+ordinals.fr = ordinals.french
+
+function converters.ordinal(n,language)
+ local t = language and ordinals[language]
+ return t and t(n)
+end
+
+function commands.ordinal(n,language)
+ local t = language and ordinals[language]
+ local o = t and t(n)
+ if o then
+ context.highordinalstr(o)
+ end
+end
+
+-- --
+
+local v_day = variables.day
+local v_year = variables.year
+local v_month = variables.month
+local v_weekday = variables.weekday
+local v_referral = variables.referral
+
+local convert = converters.convert
+
+local days = {
+ variables.sunday,
+ variables.monday,
+ variables.tuesday,
+ variables.wednesday,
+ variables.thursday,
+ variables.friday,
+ variables.saturday,
+}
+
+local months = {
+ variables.january,
+ variables.february,
+ variables.march,
+ variables.april,
+ variables.may,
+ variables.june,
+ variables.july,
+ variables.august,
+ variables.september,
+ variables.october,
+ variables.november,
+ variables.december,
+}
+
+function commands.dayname(n)
+ context.labeltext(days[n] or "unknown")
+end
+
+function commands.weekdayname(day,month,year)
+ context.labeltext(days[weekday(day,month,year)] or "unknown")
+end
+
+function commands.monthname(n)
+ context.labeltext(months[n] or "unknown")
+end
+
+function commands.monthmnem(n)
+ local m = months[n]
+ context.labeltext(m and (m ..":mnem") or "unknown")
+end
+
+-- a prelude to a function that we can use at the lua end
+
+-- historic : day+ month:mnem
+-- maybe better: day:ord month:mmem
+
+function commands.currentdate(str,currentlanguage) -- j and jj obsolete
+ local list = utilities.parsers.settings_to_array(str)
+ local year, month, day = tex.year, tex.month, tex.day
+ local auto = true
+ for i=1,#list do
+ local entry = list[i]
+ local tag, plus = match(entry,"^([^%+:]+)(.*)$")
+ local ordinal, mnemonic, whatordinal = false, false, nil
+ if not tag then
+ tag = entry
+ elseif plus == "+" or plus == "ord" then
+ ordinal = true
+ elseif plus == "mnem" then
+ mnemonic = true
+ end
+ if not auto and (tag == v_year or tag == v_month or tag == v_day or tag == v_weekday) then
+ context.space()
+ end
+ auto = false
+ if tag == v_year or tag == "y" then
+ context.convertnumber(v_year,year)
+ elseif tag == "yy" then
+ context("%02i",year % 100)
+ elseif tag == "Y" then
+ context(year)
+ elseif tag == v_month or tag == "m" then
+ if mnemonic then
+ commands.monthmnem(month)
+ else
+ commands.monthname(month)
+ end
+ elseif tag == "mm" then
+ context("%02i",month)
+ elseif tag == "M" then
+ context(month)
+ elseif tag == v_day or tag == "d" then
+ context.convertnumber(v_day,day)
+ whatordinal = day
+ elseif tag == "dd" then
+ context("%02i",day)
+ whatordinal = day
+ elseif tag == "D" then
+ context(day)
+ whatordinal = day
+ elseif tag == v_weekday or tag == "w" then
+ commands.dayname(weekday(day,month,year))
+ elseif tag == "W" then
+ context(weekday(day,month,year))
+ elseif tag == v_referral then
+ context("%04i%02i%02i",year,month,day)
+ elseif tag == v_space or tag == "\\ " then
+ context.space()
+ auto = true
+ elseif tag ~= "" then
+ context(tag)
+ auto = true
+ end
+ if ordinal and whatordinal then
+ commands.ordinal(whatordinal,currentlanguage)
+ end
+ end
+end
diff --git a/tex/context/base/core-con.mkiv b/tex/context/base/core-con.mkiv
index e2ae88f60..75f2b6acd 100644
--- a/tex/context/base/core-con.mkiv
+++ b/tex/context/base/core-con.mkiv
@@ -17,7 +17,7 @@
\unprotect
-\ifx\currentlanguage\undefined \let\currentlanguage\empty \fi
+\ifx\currentlanguage\undefined \let\currentlanguage\empty \fi
\ifx\labeltext \undefined \let\labeltext\firstofoneargument \fi
%D This module deals with all kind of conversions from numbers
@@ -202,17 +202,8 @@
%D
%D Anyhow, the conversion looks like:
-\def\domonthtag#1%
- {\ifcase#1%
- \or \v!january \or \v!february \or \v!march \or \v!april
- \or \v!may \or \v!june \or \v!july \or \v!august
- \or \v!september \or \v!october \or \v!november \or \v!december
- \else
- \v!unknown
- \fi}
-
-\def\doconvertmonthlong #1{\labeltext{\domonthtag{#1}}}
-\def\doconvertmonthshort#1{\labeltext{\domonthtag{#1}:\s!mnem}}
+\def\doconvertmonthlong #1{\ctxcommand{month(#1)}}
+\def\doconvertmonthshort#1{\ctxcommand{monthmnem(#1)}}
\let\doconvertmonth\doconvertmonthlong
@@ -245,25 +236,18 @@
%D 2000 into leap years, right? Well, converting to string
%D looks familiar:
-\def\doconvertday#1%
- {\labeltext
- {\ifcase#1
- \or \v!sunday \or \v!monday \or \v!tuesday \or \v!wednesday
- \or \v!thursday \or \v!friday \or \v!saturday \fi}}
+\def\doconvertday#1{\ctxcommand{day(#1)}}
%D \macros
%D {getdayoftheweek, dayoftheweek}
-%D
-%D The conversion algoritm is an old one and a translation from
-%D a procedure written in MODULA~2 back in the 80's. I finaly
-%D found the 4--100-400 rules in some enclopedia. Look at this
-%D messy low level routine that takes the day, month and year
-%D as arguments:
\newcount\normalweekday
-\def\getdayoftheweek#1#2#3{\normalweekday\ctxcommand{weekday(\number#1,\number#2,\number#3)}}
-\def\dayoftheweek #1#2#3{\doconvertday{\ctxcommand{weekday(\number#1,\number#2,\number#3)}}}
+% \def\getdayoftheweek#1#2#3{\normalweekday\ctxcommand{weekday(\number#1,\number#2,\number#3)}}
+% \def\dayoftheweek #1#2#3{\doconvertday{\ctxcommand{weekday(\number#1,\number#2,\number#3)}}}
+
+\def\getdayoftheweek#1#2#3{\normalweekday\ctxcommand{weekday(\number#1,\number#2,\number#3)}\relax} % number
+\def\dayoftheweek #1#2#3{\ctxcommand{weekdayname(\number#1,\number#2,\number#3)}} % name
%D Using this macro in
%D
@@ -412,79 +396,131 @@
%D \getbuffer
%D \stoplines
-\def\referraldatepattern{j,mm,dd} % jj,mm,dd changed at januari 1-1-2000
-
-\newsignal\datesignal
-
-\def\dobetweendates
- {\ifdim\lastskip=\datesignal\relax\else
- \unskip\space
- \hskip\datesignal\relax
- \fi}
-
-\def\dodobetweendates
- {\let\betweendates\dobetweendates}%
+% \newtoks \everycurrentdate
+%
+% \newsignal\datesignal
+%
+% \def\dobetweendates
+% {\ifdim\lastskip=\datesignal\relax\else
+% \unskip\space
+% \hskip\datesignal\relax
+% \fi}
+%
+% \def\referraldatepattern{j,mm,dd} % jj,mm,dd changed at januari 1-1-2000
+%
+% \def\dodobetweendates
+% {\let\betweendates\dobetweendates}%
+%
+% \def\dodocurrentdate#1%
+% {\processallactionsinset[#1]
+% [ \v!year=>\betweendates
+% \convertnumber\v!year\normalyear,
+% yy=>\lasttwodigits\normalyear,
+% y=>\convertnumber\v!year\normalyear,
+% Y=>\number\normalyear,
+% \v!month=>\betweendates
+% \month\normalmonth,
+% mm=>\twodigits\normalmonth,
+% m=>\month\normalmonth,
+% M=>\number\normalmonth,
+% \v!day=>\betweendates
+% \convertnumber\v!day\normalday,
+% \v!day+=>\betweendates
+% \convertnumber\v!day\normalday
+% \ordinal\normalday,
+% dd=>\twodigits\normalday,
+% dd+=>\convertnumber\v!day{\twodigits\normalday}%
+% \ordinal\normalday,
+% d=>\convertnumber\v!day\normalday,
+% d+=>\convertnumber\v!day\normalday
+% \ordinal\normalday,
+% d=>\number\normalday,
+% \v!weekday=>\betweendates
+% \convertnumber\v!day{\dayoftheweek\normalday\normalmonth\normalyear},
+% w=>\convertnumber\v!day{\dayoftheweek\normalday\normalmonth\normalyear},
+% W=>\dayoftheweek\normalday\normalmonth\normalyear,
+% \v!referral=>\docomplexcurrentdate\referraldatepattern,
+% \v!space=>\unskip\ \hskip\datesignal,
+% \ =>\unskip\ \hskip\datesignal,
+% \s!default=>,
+% \s!unknown=>\unskip\commalistelement
+% \hskip\datesignal
+% \let\betweendates\dodobetweendates]}
+%
+% \def\docurrentdate[#1]%
+% {\begingroup
+% \the\everycurrentdate
+% \let\betweendates\dodobetweendates
+% \doifsomething{#1}{\edef\currentdatespecification{#1}}%
+% \normalexpanded{\dodocurrentdate{\currentdatespecification}}%
+% \ifdim\lastskip=\datesignal\relax
+% \unskip
+% \fi
+% \endgroup}
+
+%D \starttabulate[|l|l|]
+%D \HL
+%D \NC year \NC (\currentdate[year]) \NC\NR
+%D \NC yy \NC (\currentdate[yy]) \NC\NR
+%D \NC y \NC (\currentdate[y]) \NC\NR
+%D \NC Y \NC (\currentdate[Y]) \NC\NR
+%D \HL
+%D \NC month \NC (\currentdate[month]) \NC\NR
+%D \NC mm \NC (\currentdate[mm]) \NC\NR
+%D \NC m \NC (\currentdate[m]) \NC\NR
+%D \NC M \NC (\currentdate[M]) \NC\NR
+%D \HL
+%D \NC day \NC (\currentdate[day]) \NC\NR
+%D \NC dd \NC (\currentdate[dd]) \NC\NR
+%D \NC d \NC (\currentdate[d]) \NC\NR
+%D \NC D \NC (\currentdate[D]) \NC\NR
+%D \HL
+%D \NC weekday \NC (\currentdate[weekday]) \NC\NR
+%D \NC w \NC (\currentdate[w]) \NC\NR
+%D \NC W \NC (\currentdate[W]) \NC\NR
+%D \HL
+%D \NC referral \NC (\currentdate[referral]) \NC\NR
+%D \HL
+%D \NC day+ \NC (\currentdate[day+]) \NC\NR
+%D \NC dd+ \NC (\currentdate[dd+]) \NC\NR
+%D \NC d+ \NC (\currentdate[d+]) \NC\NR
+%D \NC D+ \NC (\currentdate[D+]) \NC\NR
+%D \HL
+%D \stoptabulate
+%D
+%D \startbuffer
+%D (\currentdate[D,.,M,.,Y])
+%D (\currentdate[day,month,year])
+%D (\currentdate[day,+,month,+,year])
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
\newtoks \everycurrentdate
-\def\docomplexcurrentdate#1%
- {\normalexpanded{\noexpand\processallactionsinset[#1]}
- [ \v!day=>\betweendates\the\normalday,
- \v!day+=>\betweendates\convertnumber{\v!day+}\normalday,
- \v!month=>\betweendates\month\normalmonth,
- \v!year=>\betweendates\the\normalyear,
- \v!space=>\unskip\ \hskip\datesignal,
- \ =>\unskip\ \hskip\datesignal,
- d=>\convertnumber\v!day\normalday,
- d+=>\convertnumber{\v!day+}\normalday,
- m=>\convertnumber\v!month\normalmonth,
- j=>\convertnumber\v!year\normalyear,
- y=>\convertnumber\v!year\normalyear,
- w=>\betweendates\dayoftheweek\normalday\normalmonth\normalyear,
- dd=>\ifnum\normalday >9 \else0\fi\the\normalday,
- dd+=>\convertnumber{\v!day+}{\ifnum\normalday >9 \else0\fi\the\normalday},
- mm=>\ifnum\normalmonth>9 \else0\fi\the\normalmonth,
- jj=>\expandafter\gobbletwoarguments\the\normalyear,
- yy=>\expandafter\gobbletwoarguments\the\normalyear,
- \v!weekday=>\betweendates\dayoftheweek\normalday\normalmonth\normalyear,
- \v!referral=>\docomplexcurrentdate\referraldatepattern,
- \s!default=>,
- \s!unknown=>\unskip\commalistelement\hskip\datesignal\let\betweendates\dodobetweendates]}
-
-\def\complexcurrentdate[#1]%
- {\bgroup
- \the\everycurrentdate
- \let\betweendates\dodobetweendates
- \docomplexcurrentdate{#1}%
- \ifdim\lastskip=\datesignal\relax
- \unskip
- \fi
- \egroup}
+\unexpanded\def\currentdate
+ {\dosingleempty\docurrentdate}
-\def\simplecurrentdate
- {\complexcurrentdate[\currentdatespecification]}
+\def\docurrentdate[#1]%
+ {\begingroup
+ \the\everycurrentdate
+ \doifsomething{#1}{\edef\currentdatespecification{#1}}%
+ \ctxcommand{currentdate(\!!bs\currentdatespecification\!!es,"\labellanguage")}%
+ \endgroup}
-\definecomplexorsimple\currentdate
+\unexpanded\def\date
+ {\dodoubleempty\dodate}
\def\dodate[#1][#2]%
- {\bgroup
+ {\begingroup
\iffirstargument
\getparameters[\??da][d=\normalday,m=\normalmonth,y=\normalyear,#1]%
\normalday \@@dad\relax
\normalmonth\@@dam\relax
\normalyear \@@day\relax
- \ifsecondargument
- \currentdate[#2]%
- \else
- \currentdate
- \fi
- \else
- \currentdate
\fi
- \egroup}
-
-\def\date
- {\dodoubleempty\dodate}
+ \docurrentdate{#2}%
+ \endgroup}
%D \macros
%D {currenttime}
@@ -493,7 +529,7 @@
%D a pattern similar to the previous date macro using the
%D keys \type {h}, \type {m} and a separator.
-\def\calculatecurrenttime
+\unexpanded\def\calculatecurrenttime
{\edef\currenthour {\ctxcommand{hour ()}}%
\edef\currentminute{\ctxcommand{minute()}}%
\edef\currentsecond{\ctxcommand{second()}}}
@@ -505,8 +541,7 @@
\def\complexcurrenttime[#1]%
{\calculatecurrenttime
- \processallactionsinset[#1]
- [h=>\currenthour,m=>\currentminute,\s!unknown=>\commalistelement]}
+ \processallactionsinset[#1][h=>\currenthour,m=>\currentminute,\s!unknown=>\commalistelement]}
\def\simplecurrenttime
{\expanded{\complexcurrenttime[\currenttimespecification]}}
@@ -592,19 +627,16 @@
%D need to handle the second argument.
\def\convertnumber#1#2%
- {\csname\??cv % we want a fully expandable (no if interference)
- \ifcsname\??cv\currentlanguage#1\endcsname
- \currentlanguage#1%
- \@EA\firstoftwoarguments % dirty, gobble {#1}
- \else\ifcsname\??cv#1\endcsname
- #1%
- \@EAEAEA\firstoftwoarguments % dirty, gobble {#1}
- \else
- ->\s!default
- \fi\fi
+ {\csname
+ \??cv=>% we want a fully expandable (no if interference)
+ \ifcsname\??cv\currentlanguage#1\endcsname1\else
+ \ifcsname\??cv #1\endcsname2\else
+ 3\fi\fi
\endcsname{#1}{\number#2}}
-\letvalue{\??cv->\s!default}\docheckedconversion
+\setvalue{\??cv=>1}#1{\csname\??cv\currentlanguage#1\endcsname}
+\setvalue{\??cv=>2}#1{\csname\??cv #1\endcsname}
+\letvalue{\??cv=>3}\checkedconversion
\def\doifconversiondefinedelse#1%
{\ifcsname\??cv\currentlanguage#1\endcsname
@@ -639,14 +671,9 @@
%D difficult to implement. Fortunately dates never exceed the
%D number~31.
-\ifx\high \undefined \let\high \firstofoneargument \fi
-\ifx\notsmallcapped\undefined \let\notsmallcapped\firstofoneargument \fi
-
-\def\highordinalstr#1{\high{\notsmallcapped{#1}}}
-\def\ordinalstr #1{\notsmallcapped{#1}}
-
-\def\ordinaldaynumber#1% \strippedcsname\ordinaldaynumber
- {\expanded{\executeifdefined{\currentlanguage ordinaldaynumber}\noexpand\firstofoneargument{\number#1}}}
+\def\highordinalstr #1{\high{\notsmallcapped{#1}}}
+\def\ordinalstr #1{\notsmallcapped{#1}}
+\def\ordinaldaynumber #1{\ctxcommand{ordinal(#1,"\currentlanguage"}}
%D As longs as symbols are linked to levels or numbers, we can
%D also use the conversion mechanism, but in for instance the
diff --git a/tex/context/base/core-env.lua b/tex/context/base/core-env.lua
index 5545b5d32..bc260bc36 100644
--- a/tex/context/base/core-env.lua
+++ b/tex/context/base/core-env.lua
@@ -11,80 +11,68 @@ if not modules then modules = { } end modules ['core-env'] = {
--
-- if tex.modes['xxxx'] then .... else .... end
-local csname_id, texcount, create = token.csname_id, tex.count, token.create
-
local P, C, S, Cc, lpegmatch, patterns = lpeg.P, lpeg.C, lpeg.S, lpeg.Cc, lpeg.match, lpeg.patterns
-local undefined = csname_id("*undefined*crap*")
-local iftrue = create("iftrue")[2] -- inefficient hack
+local csname_id = token.csname_id
+local texcount = tex.count
+local create = token.create
+
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
+
+local undefined = csname_id("*undefined*crap*")
+local iftrue = create("iftrue")[2] -- inefficient hack
+
+tex.modes = allocate { }
+tex.systemmodes = allocate { }
+tex.constants = allocate { }
+tex.conditionals = allocate { }
+tex.ifs = allocate { }
-tex.modes = { } local modes = { }
-tex.systemmodes = { } local systemmodes = { }
-tex.constants = { }
-tex.conditionals = { }
-tex.ifs = { }
+local modes = { }
+local systemmodes = { }
-setmetatable(tex.modes, {
- __index = function(t,k)
- local m = modes[k]
- if m then
- return m()
+setmetatableindex(tex.modes, function(t,k)
+ local m = modes[k]
+ if m then
+ return m()
+ else
+ local n = "mode" .. k
+ if csname_id(n) == undefined then
+ return false
else
- local n = "mode" .. k
- if csname_id(n) == undefined then
- return false
- else
- modes[k] = function() return texcount[n] >= 1 end
- return texcount[n] >= 1
- end
+ modes[k] = function() return texcount[n] >= 1 end
+ return texcount[n] >= 1
end
end
-})
+end)
-setmetatable(tex.systemmodes, {
- __index = function(t,k)
- local m = systemmodes[k]
- if m then
- return m()
+setmetatableindex(tex.systemmodes, function(t,k)
+ local m = systemmodes[k]
+ if m then
+ return m()
+ else
+ local n = "mode*" .. k
+ if csname_id(n) == undefined then
+ return false
else
- local n = "mode*" .. k
- if csname_id(n) == undefined then
- return false
- else
- systemmodes[k] = function() return texcount[n] >= 1 end
- return texcount[n] >= 1
- end
+ systemmodes[k] = function() return texcount[n] >= 1 end
+ return texcount[n] >= 1
end
end
-})
-
-setmetatable(tex.constants, {
- __index = function(t,k)
- return csname_id(k) ~= undefined and texcount[k] or 0
- end,
---~ __newindex = function(t,k)
---~ if csname_id(k) ~= undefined then
---~ texcount[k] = k
---~ end
---~ end
-})
-
-setmetatable(tex.conditionals, {
- __index = function(t,k) -- 0 == true
- return csname_id(k) ~= undefined and texcount[k] == 0
- end,
---~ __newindex = function(t,k) -- not ok
---~ if csname_id(k) ~= undefined then
---~ texcount[k] = k and 0 or 1 -- 0 == true
---~ end
---~ end
-})
-
-setmetatable(tex.ifs, {
- __index = function(t,k)
- return csname_id(k) ~= undefined and create(k)[2] == iftrue -- inefficient, this create, we need a helper
- end
-})
+end)
+
+setmetatableindex(tex.constants, function(t,k)
+ return csname_id(k) ~= undefined and texcount[k] or 0
+end)
+
+setmetatableindex(tex.conditionals, function(t,k) -- 0 == true
+ return csname_id(k) ~= undefined and texcount[k] == 0
+end)
+
+setmetatableindex(tex.ifs, function(t,k)
+ return csname_id(k) ~= undefined and create(k)[2] == iftrue -- inefficient, this create, we need a helper
+end)
---- arg = P("{") * C(patterns.nested) * P("}") + Cc("")
diff --git a/tex/context/base/core-two.lua b/tex/context/base/core-two.lua
index c1a55b9f9..51f6dd890 100644
--- a/tex/context/base/core-two.lua
+++ b/tex/context/base/core-two.lua
@@ -8,15 +8,16 @@ if not modules then modules = { } end modules ['core-two'] = {
local remove, concat = table.remove, table.concat
local texprint = tex.print
-local allocate, mark = utilities.storage.allocate, utilities.storage.mark
-
-local collected, tobesaved = allocate(), allocate()
+local allocate = utilities.storage.allocate
--[[ldx--
We save multi-pass information in the main utility table. This is a
bit of a mess because we support old and new methods.
--ldx]]--
+local collected = allocate()
+local tobesaved = allocate()
+
local jobpasses = {
collected = collected,
tobesaved = tobesaved,
@@ -25,8 +26,8 @@ local jobpasses = {
job.passes = jobpasses
local function initializer()
- collected = mark(jobpasses.collected)
- tobesaved = mark(jobpasses.tobesaved)
+ collected = jobpasses.collected
+ tobesaved = jobpasses.tobesaved
end
job.register('job.passes.collected', tobesaved, initializer, nil)
diff --git a/tex/context/base/core-uti.lua b/tex/context/base/core-uti.lua
index cae744176..02411f13d 100644
--- a/tex/context/base/core-uti.lua
+++ b/tex/context/base/core-uti.lua
@@ -19,17 +19,20 @@ saves much runtime but at the cost of more memory usage.
local format, match = string.format, string.match
local next, type, tostring = next, type, tostring
-local definetable, accesstable = utilities.tables.definetable, utilities.tables.accesstable
-local serialize = table.serialize
-local packers = utilities.packers
-local allocate, mark = utilities.storage.allocate, utilities.storage.mark
+
+local definetable = utilities.tables.definetable
+local accesstable = utilities.tables.accesstable
+local serialize = table.serialize
+local packers = utilities.packers
+local allocate = utilities.storage.allocate
+local mark = utilities.storage.mark
local report_jobcontrol = logs.reporter("jobcontrol")
-job = job or { }
-local job = job
+job = job or { }
+local job = job
-job.version = 1.14
+job.version = 1.14
-- some day we will implement loading of other jobs and then we need
-- job.jobs
@@ -57,8 +60,8 @@ function job.initialize(loadname,savename)
end)
end
-function job.register(...) -- collected, tobesaved, initializer, finalizer
- savelist[#savelist+1] = { ... }
+function job.register(collected, tobesaved, initializer, finalizer)
+ savelist[#savelist+1] = { collected, tobesaved, initializer, finalizer }
end
-- as an example we implement variables
@@ -81,9 +84,9 @@ job.register('job.variables.checksums', checksums)
local rmethod, rvalue
local function initializer()
- tobesaved = mark(jobvariables.tobesaved)
- collected = mark(jobvariables.collected)
- checksums = mark(jobvariables.checksums)
+ tobesaved = jobvariables.tobesaved
+ collected = jobvariables.collected
+ checksums = jobvariables.checksums
rvalue = collected.randomseed
if not rvalue then
rvalue = math.random()
@@ -168,9 +171,10 @@ function job.load(filename)
for l=1,#savelist do
local list = savelist[l]
local target, initializer = list[1], list[3]
- packers.unpack(accesstable(target),job.packed,true)
+ local result = mark(accesstable(target))
+ packers.unpack(result,job.packed,true)
if type(initializer) == "function" then
- initializer(accesstable(target))
+ initializer(result)
end
end
job.packed = nil
diff --git a/tex/context/base/data-env.lua b/tex/context/base/data-env.lua
index a053c1aca..108858ccc 100644
--- a/tex/context/base/data-env.lua
+++ b/tex/context/base/data-env.lua
@@ -6,17 +6,23 @@ if not modules then modules = { } end modules ['data-env'] = {
license = "see context related readme files",
}
-local allocate = utilities.storage.allocate
local lower, gsub = string.lower, string.gsub
-local fileextname = file.extname
-
local resolvers = resolvers
-local formats = allocate() resolvers.formats = formats
-local suffixes = allocate() resolvers.suffixes = suffixes
-local dangerous = allocate() resolvers.dangerous = dangerous
-local suffixmap = allocate() resolvers.suffixmap = suffixmap
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
+local fileextname = file.extname
+
+local formats = allocate()
+local suffixes = allocate()
+local dangerous = allocate()
+local suffixmap = allocate()
+
+resolvers.formats = formats
+resolvers.suffixes = suffixes
+resolvers.dangerous = dangerous
+resolvers.suffixmap = suffixmap
local relations = allocate { -- todo: handlers also here
core = {
@@ -228,9 +234,9 @@ local function simplified(t,k)
return rawget(t,lower(gsub(k," ","")))
end
-setmetatablekey(formats, "__index", simplified)
-setmetatablekey(suffixes, "__index", simplified)
-setmetatablekey(suffixmap, "__index", simplified)
+setmetatableindex(formats, simplified)
+setmetatableindex(suffixes, simplified)
+setmetatableindex(suffixmap, simplified)
-- A few accessors, mostly for command line tool.
diff --git a/tex/context/base/data-res.lua b/tex/context/base/data-res.lua
index 82066a90e..842eed169 100644
--- a/tex/context/base/data-res.lua
+++ b/tex/context/base/data-res.lua
@@ -16,15 +16,20 @@ if not modules then modules = { } end modules ['data-res'] = {
local format, gsub, find, lower, upper, match, gmatch = string.format, string.gsub, string.find, string.lower, string.upper, string.match, string.gmatch
local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys
-local next, type, rawget, setmetatable, getmetatable = next, type, rawget, setmetatable, getmetatable
+local next, type, rawget = next, type, rawget
local os = os
local P, S, R, C, Cc, Cs, Ct, Carg = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Carg
local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
-local filedirname, filebasename, fileextname, filejoin = file.dirname, file.basename, file.extname, file.join
-local collapsepath, joinpath = file.collapsepath, file.joinpath
-local allocate = utilities.storage.allocate
+local filedirname = file.dirname
+local filebasename = file.basename
+local fileextname = file.extname
+local filejoin = file.join
+local collapsepath = file.collapsepath
+local joinpath = file.joinpath
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end)
local trace_detail = false trackers.register("resolvers.details", function(v) trace_detail = v end)
@@ -169,7 +174,8 @@ function resolvers.newinstance() -- todo: all vars will become lowercase and alp
force_suffixes = true,
}
- setmetatable(variables, { __index = function(t,k)
+ setmetatableindex(variables,function(t,k)
+ local v
for i=1,#order do
v = order[i][k]
if v ~= nil then
@@ -182,10 +188,10 @@ function resolvers.newinstance() -- todo: all vars will become lowercase and alp
end
t[k] = v
return v
- end } )
+ end)
- setmetatable(environment, { __index = function(t,k)
- v = osgetenv(k)
+ setmetatableindex(environment, function(t,k)
+ local v = osgetenv(k)
if v == nil then
v = variables[k]
end
@@ -195,9 +201,9 @@ function resolvers.newinstance() -- todo: all vars will become lowercase and alp
v = resolvers.repath(v) -- for taco who has a : separated osfontdir
t[k] = v
return v
- end } )
+ end)
- setmetatable(expansions, { __index = function(t,k)
+ setmetatableindex(expansions, function(t,k)
local v = environment[k]
if type(v) == "string" then
v = lpegmatch(variableresolver,v)
@@ -205,7 +211,7 @@ function resolvers.newinstance() -- todo: all vars will become lowercase and alp
end
t[k] = v
return v
- end } )
+ end)
return newinstance
@@ -711,7 +717,7 @@ function resolvers.registerfilehash(name,content,someerror)
end
end
-function isreadable(name)
+local function isreadable(name)
local readable = lfs.isfile(name) -- not file.is_readable(name) asit can be a dir
if trace_detail then
if readable then
diff --git a/tex/context/base/data-tmp.lua b/tex/context/base/data-tmp.lua
index 240493195..10cbe4486 100644
--- a/tex/context/base/data-tmp.lua
+++ b/tex/context/base/data-tmp.lua
@@ -290,6 +290,8 @@ function caches.is_writable(filepath,filename)
return file.is_writable(tmaname)
end
+local saveoptions = { name = "return", reduce = true }
+
function caches.savedata(filepath,filename,data,raw)
local tmaname, tmcname = caches.setluanames(filepath,filename)
local reduce, simplify = true, true
@@ -298,9 +300,9 @@ function caches.savedata(filepath,filename,data,raw)
end
data.cache_uuid = os.uuid()
if caches.direct then
- file.savedata(tmaname, table.serialize(data,'return',false,true,false)) -- no hex
+ file.savedata(tmaname,table.serialize(data,saveoptions))
else
- table.tofile(tmaname, data,'return',false,true,false) -- maybe not the last true
+ table.tofile(tmaname,data,saveoptions)
end
utilities.lua.compile(tmaname,tmcname)
end
diff --git a/tex/context/base/font-col.lua b/tex/context/base/font-col.lua
index 945d35d43..e0d2fed11 100644
--- a/tex/context/base/font-col.lua
+++ b/tex/context/base/font-col.lua
@@ -87,7 +87,7 @@ function collections.define(name,font,ranges,details)
end
end
-function collections.stage_1(name)
+function collections.stage_one(name)
local last = font.current()
if trace_collecting then
report_fonts("def: registering font %s with name %s",last,name)
@@ -95,7 +95,7 @@ function collections.stage_1(name)
list[#list+1] = last
end
-function collections.stage_2(name)
+function collections.stage_two(name)
statistics.starttiming(fonts)
local d = definitions[name]
local t = { }
diff --git a/tex/context/base/font-col.mkiv b/tex/context/base/font-col.mkiv
index 20af3e91b..f4f9a9dc7 100644
--- a/tex/context/base/font-col.mkiv
+++ b/tex/context/base/font-col.mkiv
@@ -94,10 +94,10 @@
{\doclonefonta{#1 \savedfontspec}}
\def\doclonefontstageone#1%
- {\ctxlua{fonts.collections.stage_1("#1")}}
+ {\ctxlua{fonts.collections.stage_one("#1")}}
\def\doclonefontstagetwo#1%
- {\ctxlua{fonts.collections.stage_2("#1")}}
+ {\ctxlua{fonts.collections.stage_two("#1")}}
% check : only replace when present in replacement font (default: no)
% force : force replacent even when basefont has glyph (default: yes)
diff --git a/tex/context/base/font-con.lua b/tex/context/base/font-con.lua
index 7e823c6e2..0da0e8e46 100644
--- a/tex/context/base/font-con.lua
+++ b/tex/context/base/font-con.lua
@@ -9,13 +9,11 @@ if not modules then modules = { } end modules ['font-con'] = {
local utf = unicode.utf8
-local next, tostring, setmetatable, rawget = next, tostring, setmetatable, rawget
+local next, tostring, rawget = next, tostring, rawget
local format, match, lower, gsub = string.format, string.match, string.lower, string.gsub
local utfbyte = utf.byte
local sort, insert, concat, sortedkeys, serialize, fastcopy = table.sort, table.insert, table.concat, table.sortedkeys, table.serialize, table.fastcopy
-local allocate = utilities.storage.allocate
-
local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end)
local trace_scaling = false trackers.register("fonts.scaling" , function(v) trace_scaling = v end)
@@ -37,6 +35,9 @@ local specifiers = fonts.specifiers
local contextsetups = specifiers.contextsetups
local contextnumbers = specifiers.contextnumbers
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
+
-- will be directives
constructors.dontembed = allocate()
@@ -670,7 +671,7 @@ function constructors.finalize(tfmdata)
--
if not tfmdata.descriptions then
local descriptions = { } -- yes or no
- setmetatable(descriptions, { __index = function(t,k) local v = { } t[k] = v return v end })
+ setmetatableindex(descriptions, function(t,k) local v = { } t[k] = v return v end)
tfmdata.descriptions = descriptions
end
--
@@ -868,16 +869,14 @@ end
local formats = allocate()
fonts.formats = formats
-setmetatable(formats, {
- __index = function(t,k)
- local l = lower(k)
- if rawget(t,k) then
- t[k] = l
- return l
- end
- return rawget(t,file.extname(l))
+setmetatableindex(formats, function(t,k)
+ local l = lower(k)
+ if rawget(t,k) then
+ t[k] = l
+ return l
end
-} )
+ return rawget(t,file.extname(l))
+end)
local locations = { }
@@ -977,7 +976,7 @@ function constructors.newfeatures(what)
local features = handlers[what].features
if not features then
local tables = handlers[what].tables -- can be preloaded
- features = {
+ features = allocate {
defaults = { },
descriptions = tables and tables.features or { },
initializers = { base = { }, node = { } },
diff --git a/tex/context/base/font-ctx.lua b/tex/context/base/font-ctx.lua
index fe32a2420..486300bc1 100644
--- a/tex/context/base/font-ctx.lua
+++ b/tex/context/base/font-ctx.lua
@@ -29,6 +29,8 @@ local report_defining = logs.reporter("fonts","defining")
local report_status = logs.reporter("fonts","status")
local report_mapfiles = logs.reporter("fonts","mapfiles")
+local setmetatableindex = table.setmetatableindex
+
local fonts = fonts
local handlers = fonts.handlers
local otf = handlers.otf -- brrr
@@ -94,9 +96,7 @@ function definers.resetnullfont()
definers.resetnullfont = function() end
end
-setmetatablekey(fontdata, "__index", function(t,k)
- return nulldata
-end)
+setmetatableindex(fontdata, function(t,k) return nulldata end)
local chardata = allocate() -- chardata
local parameters = allocate()
@@ -109,26 +109,26 @@ hashes.parameters = parameters
hashes.quads = quaddata
hashes.xheights = xheightdata
-setmetatablekey(chardata, "__index", function(t,k)
+setmetatableindex(chardata, function(t,k)
local characters = fontdata[k].characters
t[k] = characters
return characters
end)
-setmetatablekey(parameters, "__index", function(t,k)
+setmetatableindex(parameters, function(t,k)
local parameters = fontdata[k].parameters
t[k] = parameters
return parameters
end)
-setmetatablekey(quaddata, "__index", function(t,k)
+setmetatableindex(quaddata, function(t,k)
local parameters = parameters[k]
local quad = parameters and parameters.quad or 0
t[k] = quad
return quad
end)
-setmetatablekey(xheightdata, "__index", function(t,k)
+setmetatableindex(xheightdata, function(t,k)
local parameters = parameters[k]
local xheight = parameters and parameters.xheight or 0
t[k] = xheight
@@ -865,7 +865,7 @@ mappings.reset() -- resets the default file
-- => commands
-function nametoslot(name)
+local function nametoslot(name)
local t = type(name)
if t == "string" then
local tfmdata = fonts.hashes.identifiers[currentfont()]
@@ -1202,20 +1202,18 @@ local xheights = hashes.xheights
local currentfont = font.current
local texdimen = tex.dimen
-setmetatable(number.dimenfactors, {
- __index = function(t,k)
- if k == "ex" then
- return xheigths[currentfont()]
- elseif k == "em" then
- return quads[currentfont()]
- elseif k == "%" then
- return dimen.hsize/100
- else
- -- error("wrong dimension: " .. (s or "?")) -- better a message
- return false
- end
+setmetatableindex(number.dimenfactors, function(t,k)
+ if k == "ex" then
+ return xheigths[currentfont()]
+ elseif k == "em" then
+ return quads[currentfont()]
+ elseif k == "%" then
+ return dimen.hsize/100
+ else
+ -- error("wrong dimension: " .. (s or "?")) -- better a message
+ return false
end
-} )
+end)
--[[ldx--
Before a font is passed to we scale it. Here we also need
diff --git a/tex/context/base/font-def.lua b/tex/context/base/font-def.lua
index c4904aa39..182e543b0 100644
--- a/tex/context/base/font-def.lua
+++ b/tex/context/base/font-def.lua
@@ -409,18 +409,17 @@ function definers.read(specification,size,id) -- id can be optional, name can al
if not tfmdata then -- or id?
report_defining( "unknown font %s, loading aborted",specification.name)
elseif trace_defining and type(tfmdata) == "table" then
- constructors.finalize(tfmdata)
- -- local properties = tfmdata.properties or { }
- -- local parameters = tfmdata.parameters or { }
+ local properties = tfmdata.properties or { }
+ local parameters = tfmdata.parameters or { }
report_defining("using %s font with id %s, name:%s size:%s bytes:%s encoding:%s fullname:%s filename:%s",
- properties.type or "unknown",
- id or "?",
- properties.name or "?",
- parameters.size or "default",
- properties.encodingbytes or "?",
- properties.encodingname or "unicode",
- properties.fullname or "?",
- file.basename(properties.filename or "?"))
+ properties.type or "unknown",
+ id or "?",
+ properties.name or "?",
+ parameters.size or "default",
+ properties.encodingbytes or "?",
+ properties.encodingname or "unicode",
+ properties.fullname or "?",
+ file.basename(properties.filename or "?"))
end
statistics.stoptiming(fonts)
return tfmdata
@@ -430,4 +429,4 @@ end
We overload the reader.
--ldx]]--
-callbacks.register('define_font' , definers.read, "definition of fonts (tfmdata preparation)")
+callbacks.register('define_font', definers.read, "definition of fonts (tfmdata preparation)")
diff --git a/tex/context/base/font-enc.lua b/tex/context/base/font-enc.lua
index a06866225..a6f9250e7 100644
--- a/tex/context/base/font-enc.lua
+++ b/tex/context/base/font-enc.lua
@@ -10,6 +10,8 @@ if not modules then modules = { } end modules ['font-enc'] = {
local match, gmatch, gsub = string.match, string.gmatch, string.gsub
+local setmetatableindex = table.setmetatableindex
+
--[[ldx--
Because encodings are going to disappear, we don't bother defining
them in tables. But we may do so some day, for consistency.
@@ -136,10 +138,10 @@ if not encodings.agl then
encodings.agl = { }
- setmetatable(encodings.agl, { __index = function(t,k)
+ setmetatableindex(encodings.agl, function(t,k)
report_encoding("loading (extended) adobe glyph list")
dofile(resolvers.findfile("font-agl.lua"))
return rawget(encodings.agl,k)
- end })
+ end)
end
diff --git a/tex/context/base/font-gds.lua b/tex/context/base/font-gds.lua
index 556f093d4..a5c60d252 100644
--- a/tex/context/base/font-gds.lua
+++ b/tex/context/base/font-gds.lua
@@ -9,7 +9,7 @@ if not modules then modules = { } end modules ['font-gds'] = {
-- depends on ctx
local type, next = type, next
-local gmatch = string.gmatch
+local gmatch, format = string.gmatch, string.format
local fonts, nodes, attributes, node = fonts, nodes, attributes, node
@@ -18,6 +18,9 @@ local report_fonts = logs.reporter("fonts","goodies")
local allocate = utilities.storage.allocate
+local otf = fonts.handlers.otf
+local addotffeature = otf.enhancers.addfeature
+
local otffeatures = fonts.constructors.newfeatures("otf")
local registerotffeature = otffeatures.register
@@ -305,6 +308,25 @@ function colorschemes.enable()
function colorschemes.enable() end
end
+local function setextrafeatures(tfmdata)
+ local goodies = tfmdata.goodies
+ if goodies then
+ for i=1,#goodies do
+ local g = goodies[i]
+ local f = g.features
+ if f then
+ for feature, specification in next, f do
+ addotffeature(tfmdata.shared.rawdata,feature,specification)
+ registerotffeature {
+ name = feature,
+ description = format("extra: %s",feature)
+ }
+ end
+ end
+ end
+ end
+end
+
-- installation (collected to keep the overview) -- also for type 1
registerotffeature {
@@ -317,23 +339,14 @@ registerotffeature {
}
}
-registerafmfeature {
- name = "goodies",
- description = "goodies on top of built in features",
- initializers = {
- position = 1,
- base = setgoodies,
- node = setgoodies,
- }
-}
-
-registertfmfeature {
- name = "goodies",
- description = "goodies on top of built in features",
+registerotffeature {
+ name = "extrafeatures",
+ description = "extra features",
+ default = true,
initializers = {
- position = 1,
- base = setgoodies,
- node = setgoodies,
+ position = 2,
+ base = setextrafeatures,
+ node = setextrafeatures,
}
}
@@ -341,7 +354,7 @@ registerotffeature {
name = "featureset",
description = "goodie feature set",
initializers = {
- position = 2,
+ position = 3,
base = setfeatureset,
node = setfeatureset,
}
@@ -365,6 +378,30 @@ registerotffeature {
}
}
+-- afm
+
+registerafmfeature {
+ name = "goodies",
+ description = "goodies on top of built in features",
+ initializers = {
+ position = 1,
+ base = setgoodies,
+ node = setgoodies,
+ }
+}
+
+-- tfm
+
+registertfmfeature {
+ name = "goodies",
+ description = "goodies on top of built in features",
+ initializers = {
+ position = 1,
+ base = setgoodies,
+ node = setgoodies,
+ }
+}
+
-- experiment, we have to load the definitions immediately as they precede
-- the definition so they need to be initialized in the typescript
diff --git a/tex/context/base/font-ini.mkiv b/tex/context/base/font-ini.mkiv
index e8c2ee8af..b179aae35 100644
--- a/tex/context/base/font-ini.mkiv
+++ b/tex/context/base/font-ini.mkiv
@@ -4394,7 +4394,7 @@
\def\dolookupfontbyspec #1{\ctxcommand{fontlookupinitialize("#1")}}
\def\dolookupnoffound {\ctxcommand{fontlookupnoffound()}}
-\def\dolookupgetkeyofindex#1#2{\ctxcommand{fontlookupgetkeyofindex("#1",#2))}}
+\def\dolookupgetkeyofindex#1#2{\ctxcommand{fontlookupgetkeyofindex("#1",#2)}}
\def\dolookupgetkey #1{\ctxcommand{fontlookupgetkey("#1")}}
\def\cleanfontname #1{\ctxcommand{cleanfontname("#1")}}
diff --git a/tex/context/base/font-log.lua b/tex/context/base/font-log.lua
index d89482737..8bc12a215 100644
--- a/tex/context/base/font-log.lua
+++ b/tex/context/base/font-log.lua
@@ -51,7 +51,7 @@ end
function loggers.register(tfmdata,source,specification) -- save file name in spec here ! ! ! ! ! !
if tfmdata and specification and specification.specification then
local name = lower(specification.name)
- if trace_defining and not fonts.used[name] then
+ if trace_defining and not usedfonts[name] then
report_defining("registering %s as %s (used: %s)",file.basename(specification.name),source,file.basename(specification.filename))
end
specification.source = source
diff --git a/tex/context/base/font-mis.lua b/tex/context/base/font-mis.lua
index 368eb4b9e..3de1cd30d 100644
--- a/tex/context/base/font-mis.lua
+++ b/tex/context/base/font-mis.lua
@@ -22,7 +22,7 @@ local handlers = fonts.handlers
handlers.otf = handlers.otf or { }
local otf = handlers.otf
-otf.version = otf.version or 2.721
+otf.version = otf.version or 2.722
otf.cache = otf.cache or containers.define("fonts", "otf", otf.version, true)
function otf.loadcached(filename,format,sub)
diff --git a/tex/context/base/font-ota.lua b/tex/context/base/font-ota.lua
index a820236fd..cb41194ee 100644
--- a/tex/context/base/font-ota.lua
+++ b/tex/context/base/font-ota.lua
@@ -14,14 +14,15 @@ if not trackers then trackers = { register = function() end } end
local trace_analyzing = false trackers.register("otf.analyzing", function(v) trace_analyzing = v end)
-local fonts, nodes = fonts, nodes
-local node = node
+local fonts, nodes, node = fonts, nodes, node
+
+local allocate = utilities.storage.allocate
local otf = fonts.handlers.otf
local analyzers = fonts.analyzers
-local initializers = { }
-local methods = { }
+local initializers = allocate()
+local methods = allocate()
analyzers.initializers = initializers
analyzers.methods = methods
diff --git a/tex/context/base/font-otc.lua b/tex/context/base/font-otc.lua
index 5fdcf203b..1b4983ce0 100644
--- a/tex/context/base/font-otc.lua
+++ b/tex/context/base/font-otc.lua
@@ -19,6 +19,7 @@ local fonts = fonts
local otf = fonts.handlers.otf
local otffeatures = fonts.constructors.newfeatures("otf")
local registerotffeature = otffeatures.register
+local setmetatableindex = table.setmetatableindex
-- In the userdata interface we can not longer tweak the loaded font as
-- conveniently as before. For instance, instead of pushing extra data in
@@ -26,118 +27,49 @@ local registerotffeature = otffeatures.register
-- the mkiv representation. And as the fontloader interface is modelled
-- after fontforge we cannot change that one too much either.
-local extra_lists = {
- tlig = {
- {
- endash = "hyphen hyphen",
- emdash = "hyphen hyphen hyphen",
- -- quotedblleft = "quoteleft quoteleft",
- -- quotedblright = "quoteright quoteright",
- -- quotedblleft = "grave grave",
- -- quotedblright = "quotesingle quotesingle",
- -- quotedblbase = "comma comma",
- },
- },
- trep = {
- {
- -- [0x0022] = 0x201D,
- [0x0027] = 0x2019,
- -- [0x0060] = 0x2018,
- },
- },
- anum = {
- { -- arabic
- [0x0030] = 0x0660,
- [0x0031] = 0x0661,
- [0x0032] = 0x0662,
- [0x0033] = 0x0663,
- [0x0034] = 0x0664,
- [0x0035] = 0x0665,
- [0x0036] = 0x0666,
- [0x0037] = 0x0667,
- [0x0038] = 0x0668,
- [0x0039] = 0x0669,
- },
- { -- persian
- [0x0030] = 0x06F0,
- [0x0031] = 0x06F1,
- [0x0032] = 0x06F2,
- [0x0033] = 0x06F3,
- [0x0034] = 0x06F4,
- [0x0035] = 0x06F5,
- [0x0036] = 0x06F6,
- [0x0037] = 0x06F7,
- [0x0038] = 0x06F8,
- [0x0039] = 0x06F9,
- },
- },
+local types = {
+ substitution = "gsub_single",
+ ligature = "gsub_ligature",
+ alternate = "gsub_alternate",
}
-local extra_features = { -- maybe just 1..n so that we prescribe order
- tlig = {
- {
- features = { ["*"] = { ["*"] = true } },
- name = "ctx_tlig_1",
- subtables = { "ctx_tlig_1_s" },
- type = "gsub_ligature",
- flags = { },
- },
- },
- trep = {
- {
- features = { ["*"] = { ["*"] = true } },
- name = "ctx_trep_1",
- subtables = { "ctx_trep_1_s" },
- type = "gsub_single",
- flags = { },
- },
- },
- anum = {
- {
- features = { arab = { URD = true, dflt = true } },
- name = "ctx_anum_1",
- subtables = { "ctx_anum_1_s" },
- type = "gsub_single",
- flags = { },
- },
- {
- features = { arab = { URD = true } },
- name = "ctx_anum_2",
- subtables = { "ctx_anum_2_s" },
- type = "gsub_single",
- flags = { },
- },
- },
-}
+setmetatableindex(types, function(t,k) t[k] = k return k end) -- "key"
-otf.extrafeatures = extra_features
-otf.extralists = extra_lists
+local everywhere = { ["*"] = { ["*"] = true } } -- or: { ["*"] = { "*" } }
+local noflags = { }
-local function enhancedata(data,filename,raw)
+local function addfeature(data,feature,specifications)
local descriptions = data.descriptions
local resources = data.resources
local lookups = resources.lookups
local gsubfeatures = resources.features.gsub
- local sequences = resources.sequences
- local fontfeatures = resources.features
- local unicodes = resources.unicodes
- local lookuptypes = resources.lookuptypes
- local splitter = lpeg.splitter(" ",unicodes)
- for feature, specifications in next, extra_features do
- if gsub and gsub[feature] then
- -- already present
- else
- local done = 0
- for s=1,#specifications do
- local specification = specifications[s]
- local askedfeatures = specification.features
- local subtables = specification.subtables
- local featurename = specification.name
- local featuretype = specification.type
- local featureflags = specification.flags
- local full = subtables[1]
- local list = extra_lists[feature][s]
- local added = false
+ if gsubfeatures and gsubfeatures[feature] then
+ -- already present
+ else
+ local sequences = resources.sequences
+ local fontfeatures = resources.features
+ local unicodes = resources.unicodes
+ local lookuptypes = resources.lookuptypes
+ local splitter = lpeg.splitter(" ",unicodes)
+ local done = 0
+ if not specifications[1] then
+ -- so we accept a one entry specification
+ specifications = { specifications }
+ end
+ -- subtables are tables themselves but we also accept flattened singular subtables
+ for s=1,#specifications do
+ local specification = specifications[s]
+ local askedfeatures = specification.features or everywhere
+ local subtables = specification.subtables or { specification.data } or { }
+ local featuretype = types[specification.type or "substitution"]
+ local featureflags = specification.flags or noflags
+ local added = false
+ local featurename = format("ctx_%s_%s",feature,s)
+ local st = { }
+ for t=1,#subtables do
+ local list = subtables[t]
+ local full = format("%s_%s",featurename,t)
+ st[t] = full
if featuretype == "gsub_ligature" then
lookuptypes[full] = "ligature"
for code, ligature in next, list do
@@ -173,58 +105,160 @@ local function enhancedata(data,filename,raw)
end
end
end
- if added then
- sequences[#sequences+1] = {
- chain = 0,
- features = { [feature] = askedfeatures },
- flags = featureflags,
- name = featurename,
- subtables = subtables,
- type = featuretype,
- }
- -- register in metadata (merge as there can be a few)
- if not gsubfeatures then
- gsubfeatures = { }
- fontfeatures.gsub = gsubfeatures
+ end
+ if added then
+ -- script = { lang1, lang2, lang3 } or script = { lang1 = true, ... }
+ for k, v in next, askedfeatures do
+ if v[1] then
+ askedfeatures[k] = table.tohash(v)
end
- local k = gsubfeatures[feature]
- if not k then
- k = { }
- gsubfeatures[feature] = k
+ end
+ sequences[#sequences+1] = {
+ chain = 0,
+ features = { [feature] = askedfeatures },
+ flags = featureflags,
+ name = featurename,
+ subtables = st,
+ type = featuretype,
+ }
+ -- register in metadata (merge as there can be a few)
+ if not gsubfeatures then
+ gsubfeatures = { }
+ fontfeatures.gsub = gsubfeatures
+ end
+ local k = gsubfeatures[feature]
+ if not k then
+ k = { }
+ gsubfeatures[feature] = k
+ end
+ for script, languages in next, askedfeatures do
+ local kk = k[script]
+ if not kk then
+ kk = { }
+ k[script] = kk
end
- for script, languages in next, askedfeatures do
- local kk = k[script]
- if not kk then
- kk = { }
- k[script] = kk
- end
- for language, value in next, languages do
- kk[language] = value
- end
+ for language, value in next, languages do
+ kk[language] = value
end
end
end
- if done > 0 and trace_loading then
- report_otf("enhance: registering %s feature (%s glyphs affected)",feature,done)
- end
end
+ if done > 0 and trace_loading then
+ report_otf("enhance: registering %s feature (%s glyphs affected)",feature,done)
+ end
+ end
+end
+
+otf.enhancers.addfeature = addfeature
+
+local extrafeatures = { }
+
+function otf.addfeature(name,specification)
+ extrafeatures[name] = specification
+end
+
+local function enhance(data,filename,raw)
+ for feature, specification in next, extrafeatures do
+ addfeature(data,feature,specification)
end
end
-otf.enhancers.register("check extra features",enhancedata)
+otf.enhancers.register("check extra features",enhance)
+
+-- tlig --
+
+local tlig = {
+ endash = "hyphen hyphen",
+ emdash = "hyphen hyphen hyphen",
+ -- quotedblleft = "quoteleft quoteleft",
+ -- quotedblright = "quoteright quoteright",
+ -- quotedblleft = "grave grave",
+ -- quotedblright = "quotesingle quotesingle",
+ -- quotedblbase = "comma comma",
+}
+
+local tlig_specification = {
+ type = "ligature",
+ features = everywhere, -- { ["*"] = { ["*"] = true } },
+ data = tlig,
+ flags = noflags, -- { },
+}
+
+otf.addfeature("tlig",tlig_specification)
registerotffeature {
name = 'tlig',
description = 'tex ligatures',
}
+-- trep
+
+local trep = {
+ -- [0x0022] = 0x201D,
+ [0x0027] = 0x2019,
+ -- [0x0060] = 0x2018,
+}
+
+local trep_specification = {
+ type = "substitution",
+ features = everywhere, -- { ["*"] = { ["*"] = true } },
+ data = trep,
+ flags = noflags, -- { },
+}
+
+otf.addfeature("trep",trep_specification)
+
registerotffeature {
name = 'trep',
description = 'tex replacements',
}
+-- anum
+
+local anum_arabic = {
+ [0x0030] = 0x0660,
+ [0x0031] = 0x0661,
+ [0x0032] = 0x0662,
+ [0x0033] = 0x0663,
+ [0x0034] = 0x0664,
+ [0x0035] = 0x0665,
+ [0x0036] = 0x0666,
+ [0x0037] = 0x0667,
+ [0x0038] = 0x0668,
+ [0x0039] = 0x0669,
+}
+
+local anum_persian = {
+ [0x0030] = 0x06F0,
+ [0x0031] = 0x06F1,
+ [0x0032] = 0x06F2,
+ [0x0033] = 0x06F3,
+ [0x0034] = 0x06F4,
+ [0x0035] = 0x06F5,
+ [0x0036] = 0x06F6,
+ [0x0037] = 0x06F7,
+ [0x0038] = 0x06F8,
+ [0x0039] = 0x06F9,
+}
+
+local anum_specification = {
+ {
+ type = "substitution",
+ features = { arab = { URD = true, dflt = true } },
+ data = anum_arabic,
+ flags = noflags, -- { },
+ },
+ {
+ type = "substitution",
+ features = { arab = { URD = true } },
+ data = anum_persian,
+ flags = noflags, -- { },
+ },
+}
+
+otf.addfeature("anum",anum_specification)
+
registerotffeature {
name = 'anum',
description = 'arabic digits',
}
-
diff --git a/tex/context/base/font-otd.lua b/tex/context/base/font-otd.lua
index 59c050e10..84811f0e1 100644
--- a/tex/context/base/font-otd.lua
+++ b/tex/context/base/font-otd.lua
@@ -25,6 +25,8 @@ local contextsetups = specifiers.contextsetups
local contextnumbers = specifiers.contextnumbers
local contextmerged = specifiers.contextmerged
+local setmetatableindex = table.setmetatableindex
+
local otffeatures = fonts.constructors.newfeatures("otf")
local registerotffeature = otffeatures.register
@@ -34,13 +36,11 @@ fonts.hashes.dynamics = fontdynamics
local a_to_script = { }
local a_to_language = { }
-setmetatable(fontdynamics, { __index =
- function(t,font)
- local d = fontdata[font].shared.dynamics or false
- t[font] = d
- return d
- end
-})
+setmetatableindex(fontdynamics, function(t,font)
+ local d = fontdata[font].shared.dynamics or false
+ t[font] = d
+ return d
+end)
function otf.setdynamics(font,attribute)
local features = contextsetups[contextnumbers[attribute]] -- can be moved to caller
@@ -206,11 +206,11 @@ function otf.dataset(tfmdata,sequences,font,attr)
if ra == nil then -- attr can be false
ra = { }
rl[attr] = ra
- setmetatable(ra, { __index = function(t,k)
+ setmetatableindex(ra, function(t,k)
local v = initialize(sequences[k],script,language,s_enabled,a_enabled,attr,dynamic)
t[k] = v
return v
- end})
+ end)
end
return ra
diff --git a/tex/context/base/font-otf.lua b/tex/context/base/font-otf.lua
index 65b868045..e66e3c01b 100644
--- a/tex/context/base/font-otf.lua
+++ b/tex/context/base/font-otf.lua
@@ -47,7 +47,7 @@ local otf = fonts.handlers.otf
otf.glists = { "gsub", "gpos" }
-otf.version = 2.721 -- beware: also sync font-mis.lua
+otf.version = 2.722 -- beware: also sync font-mis.lua
otf.cache = containers.define("fonts", "otf", otf.version, true)
local fontdata = fonts.hashes.identifiers
@@ -1172,13 +1172,55 @@ end
-- to be checked italic_correction
+local function check_variants(unicode,the_variants,splitter,unicodes)
+ local variants = the_variants.variants
+ if variants then -- use splitter
+ local glyphs = lpegmatch(splitter,variants)
+ local done = { [unicode] = true }
+ local n = 0
+ for i=1,#glyphs do
+ local g = glyphs[i]
+ if done[g] then
+ report_otf("skipping cyclic reference U+%05X in math variant U+%05X",g,unicode)
+ elseif n == 0 then
+ n = 1
+ variants = { g }
+ else
+ n = n + 1
+ variants[n] = g
+ end
+ end
+ if n == 0 then
+ variants = nil
+ end
+ end
+ local parts = the_variants.parts
+ if parts then
+ local p = #parts
+ if p > 0 then
+ for i=1,p do
+ local pi = parts[i]
+ pi.glyph = unicodes[pi.component] or 0
+ pi.component = nil
+ end
+ else
+ parts = nil
+ end
+ end
+ local italic_correction = the_variants.italic_correction
+ if italic_correction and italic_correction == 0 then
+ italic_correction = nil
+ end
+ return variants, parts, italic_correction
+end
+
actions["analyze math"] = function(data,filename,raw)
if raw.math then
data.metadata.math = raw.math
local unicodes = data.resources.unicodes
local splitter = data.helpers.tounicodetable
for unicode, description in next, data.descriptions do
- local glyph = description.glyph
+ local glyph = description.glyph
local mathkerns = glyph.mathkern -- singular
local horiz_variants = glyph.horiz_variants
local vert_variants = glyph.vert_variants
@@ -1203,56 +1245,10 @@ actions["analyze math"] = function(data,filename,raw)
math.kerns = mathkerns
end
if horiz_variants then
- local variants = horiz_variants.variants
- if variants then -- use splitter
- local glyphs = lpegmatch(splitter,variants)
- for i=1,#glyphs do
- if glyphs[i] == u then
- remove(glyphs,i)
- break
- end
- end
- math.horiz_variants = glyphs
- end
- local parts = horiz_variants.parts
- if parts and #parts > 0 then
- for i=1,#parts do
- local pi = parts[i]
- pi.glyph = unicodes[pi.component] or 0
- pi.component = nil
- end
- math.horiz_parts = parts
- end
- local italic_correction = horiz_variants.italic_correction
- if italic_correction and italic_correction ~= 0 then
- math.horiz_italic_correction = italic_correction
- end
+ math.horiz_variants, math.horiz_parts, math.horiz_italic_correction = check_variants(unicode,horiz_variants,splitter,unicodes)
end
if vert_variants then
- local variants = vert_variants.variants
- if variants then
- local glyphs = lpegmatch(splitter,variants)
- for i=1,#glyphs do
- if glyphs[i] == u then
- remove(glyphs,i)
- break
- end
- end
- math.vert_variants = glyphs
- end
- local p = vert_variants.parts
- if parts and #parts > 0 then
- for i=1,#parts do
- local pi = parts[i]
- pi.glyph = unicodes[pi.component] or 0
- pi.component = nil
- end
- math.vert_parts = parts
- end
- local italic_correction = vert_variants.italic_correction
- if italic_correction and italic_correction ~= 0 then
- math.vert_italic_correction = italic_correction
- end
+ math.vert_variants, math.vert_parts, math.vert_italic_correction = check_variants(unicode,vert_variants,splitter,unicodes)
end
local italic_correction = description.italic
if italic_correction and italic_correction ~= 0 then
@@ -1610,25 +1606,39 @@ local function copytotfm(data,cache_id)
local m = d.math
if m then
-- watch out: luatex uses horiz_variants for the parts
- local variants, parts = m.horiz_variants, m.horiz_parts
+ local variants = m.horiz_variants
+ local parts = m.horiz_parts
+ -- local done = { [unicode] = true }
if variants then
local c = character
for i=1,#variants do
local un = variants[i]
- c.next = un
- c = characters[un]
+ -- if done[un] then
+ -- -- report_otf("skipping cyclic reference U+%05X in math variant U+%05X",un,unicode)
+ -- else
+ c.next = un
+ c = characters[un]
+ -- done[un] = true
+ -- end
end -- c is now last in chain
c.horiz_variants = parts
elseif parts then
character.horiz_variants = parts
end
- local variants, parts = m.vert_variants, m.vert_parts
+ local variants = m.vert_variants
+ local parts = m.vert_parts
+ -- local done = { [unicode] = true }
if variants then
local c = character
for i=1,#variants do
local un = variants[i]
- c.next = un
- c = characters[un]
+ -- if done[un] then
+ -- -- report_otf("skipping cyclic reference U+%05X in math variant U+%05X",un,unicode)
+ -- else
+ c.next = un
+ c = characters[un]
+ -- done[un] = true
+ -- end
end -- c is now last in chain
c.vert_variants = parts
elseif parts then
diff --git a/tex/context/base/font-otn.lua b/tex/context/base/font-otn.lua
index a5de4ea46..17c1a92e9 100644
--- a/tex/context/base/font-otn.lua
+++ b/tex/context/base/font-otn.lua
@@ -166,6 +166,8 @@ local find_node_tail = node.tail or node.slide
local set_attribute = node.set_attribute
local has_attribute = node.has_attribute
+local setmetatableindex = table.setmetatableindex
+
local zwnj = 0x200C
local zwj = 0x200D
local wildcard = "*"
@@ -462,7 +464,7 @@ function handlers.gsub_multiple(start,kind,lookupname,multiple)
return multiple_glyphs(start,multiple)
end
-function handlers.gsub_ligature(start,kind,lookupname,ligature,sequence) --or maybe pass lookup ref
+function handlers.gsub_ligature(start,kind,lookupname,ligature,sequence)
local s, stop, discfound = start.next, nil, false
local startchar = start.char
if marks[startchar] then
@@ -483,14 +485,18 @@ function handlers.gsub_ligature(start,kind,lookupname,ligature,sequence) --or ma
end
if stop then
local lig = ligature.ligature
- if trace_ligatures then
- local stopchar = stop.char
- start = markstoligature(kind,lookupname,start,stop,lig)
- logprocess("%s: replacing %s upto %s by ligature %s",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char))
+ if lig then
+ if trace_ligatures then
+ local stopchar = stop.char
+ start = markstoligature(kind,lookupname,start,stop,lig)
+ logprocess("%s: replacing %s upto %s by ligature %s",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char))
+ else
+ start = markstoligature(kind,lookupname,start,stop,lig)
+ end
+ return start, true
else
- start = markstoligature(kind,lookupname,start,stop,lig)
+ -- ok, goto next lookup
end
- return start, true
end
else
local skipmark = sequence.flags[1]
@@ -523,14 +529,18 @@ function handlers.gsub_ligature(start,kind,lookupname,ligature,sequence) --or ma
end
if stop then
local lig = ligature.ligature
- if trace_ligatures then
- local stopchar = stop.char
- start = toligature(kind,lookupname,start,stop,lig,skipmark,discfound)
- logprocess("%s: replacing %s upto %s by ligature %s",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char))
+ if lig then
+ if trace_ligatures then
+ local stopchar = stop.char
+ start = toligature(kind,lookupname,start,stop,lig,skipmark,discfound)
+ logprocess("%s: replacing %s upto %s by ligature %s",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char))
+ else
+ start = toligature(kind,lookupname,start,stop,lig,skipmark,discfound)
+ end
+ return start, true
else
- start = toligature(kind,lookupname,start,stop,lig,skipmark,discfound)
+ -- ok, goto next lookup
end
- return start, true
end
end
return start, false
@@ -1843,16 +1853,14 @@ local resolved = { } -- we only resolve a font,script,language pair once
local lookuphashes = { }
-setmetatable(lookuphashes, { __index =
- function(t,font)
- local lookuphash = fontdata[font].resources.lookuphash
- if not lookuphash or not next(lookuphash) then
- lookuphash = false
- end
- t[font] = lookuphash
- return lookuphash
+setmetatableindex(lookuphashes, function(t,font)
+ local lookuphash = fontdata[font].resources.lookuphash
+ if not lookuphash or not next(lookuphash) then
+ lookuphash = false
end
-})
+ t[font] = lookuphash
+ return lookuphash
+end)
-- fonts.hashes.lookups = lookuphashes
@@ -1899,11 +1907,11 @@ function otf.dataset(ftfmdata,sequences,font) -- generic variant, overloaded in
if not rl then
rl = { }
rs[language] = rl
- setmetatable(rl, { __index = function(t,k)
+ setmetatableindex(rl, function(t,k)
local v = enabled and initialize(sequences[k],script,language,enabled)
t[k] = v
return v
- end})
+ end)
end
return rl
end
diff --git a/tex/context/base/font-ott.lua b/tex/context/base/font-ott.lua
index 1dbf626ca..800fd3c65 100644
--- a/tex/context/base/font-ott.lua
+++ b/tex/context/base/font-ott.lua
@@ -6,20 +6,21 @@ if not modules then modules = { } end modules ['font-otf'] = {
license = "see context related readme files"
}
-local type, next, tonumber, tostring, rawget, setmetatable = type, next, tonumber, tostring, rawget, setmetatable
+local type, next, tonumber, tostring, rawget = type, next, tonumber, tostring, rawget
local gsub, lower, format, match = string.gsub, string.lower, string.format, string.match
local is_boolean = string.is_boolean
-local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
+local setmetatablenewindex = table.setmetatablenewindex
+local allocate = utilities.storage.allocate
-local fonts = fonts
-local otf = fonts.handlers.otf
+local fonts = fonts
+local otf = fonts.handlers.otf
+local tables = { }
+otf.tables = tables
-local tables = { }
-otf.tables = tables
-
-local otffeatures = fonts.constructors.newfeatures("otf")
-local registerotffeature = otffeatures.register
+local otffeatures = fonts.constructors.newfeatures("otf")
+local registerotffeature = otffeatures.register
local scripts = allocate {
['arab'] = 'arabic',
@@ -672,10 +673,10 @@ local function resolve(t,k)
return "dflt"
end
-setmetatable(verbosescripts, { __index = resolve })
-setmetatable(verboselanguages, { __index = resolve })
-setmetatable(verbosefeatures, { __index = resolve })
-setmetatable(verbosebaselines, { __index = resolve })
+setmetatableindex(verbosescripts, resolve)
+setmetatableindex(verboselanguages, resolve)
+setmetatableindex(verbosefeatures, resolve)
+setmetatableindex(verbosebaselines, resolve)
local function resolve(t,k)
if k then
@@ -688,13 +689,13 @@ local function resolve(t,k)
return "dflt"
end
-local function assign(t,k,v)
- -- forget about it
-end
+setmetatableindex(scripts, resolve)
+setmetatableindex(scripts, resolve)
+setmetatableindex(languages, resolve)
-setmetatable(scripts, { __index = resolve, __newindex = assign })
-setmetatable(languages, { __index = resolve, __newindex = assign })
-setmetatable(baselines, { __index = resolve, __newindex = assign })
+setmetatablenewindex(languages, "ignore")
+setmetatablenewindex(baselines, "ignore")
+setmetatablenewindex(baselines, "ignore")
local function resolve(t,k)
if k then
@@ -719,6 +720,8 @@ local function resolve(t,k)
return "dflt"
end
+setmetatableindex(features, resolve)
+
local function assign(t,k,v)
if k then
v = lower(v)
@@ -727,7 +730,7 @@ local function assign(t,k,v)
end
end
-setmetatable(features, { __index = resolve, __newindex = assign })
+setmetatablenewindex(features, assign)
local checkers = {
rand = function(v)
diff --git a/tex/context/base/font-vf.lua b/tex/context/base/font-vf.lua
index 8eab88b40..287d073d6 100644
--- a/tex/context/base/font-vf.lua
+++ b/tex/context/base/font-vf.lua
@@ -12,14 +12,15 @@ changes. This will change.
--ldx]]--
local next = next
-local fastcopy = table.fastcopy
-local allocate = utilities.storage.allocate
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
+local fastcopy = table.fastcopy
-local fonts = fonts
-local constructors = fonts.constructors
-local vf = { }
-fonts.handlers.vf = vf
+local fonts = fonts
+local constructors = fonts.constructors
+local vf = { }
+fonts.handlers.vf = vf
-- general code
@@ -60,9 +61,13 @@ local methods = definers.methods
local variants = allocate()
local combinations = { }
local combiner = { }
-local whatever = allocate() -- can be used to store data
-local predefined = allocate() -- can be used to store data
-local helpers = allocate() -- can be used to store data
+local whatever = allocate()
+local helpers = allocate()
+local predefined = allocate {
+ dummy = { "comment" },
+ push = { "push" },
+ pop = { "pop" },
+}
methods.variants = variants -- todo .. wrong namespace
vf.combinations = combinations
@@ -71,11 +76,7 @@ vf.whatever = whatever
vf.helpers = helpers
vf.predefined = predefined
-setmetatable(whatever, { __index = function(t,k) local v = { } t[k] = v return v end })
-
-predefined.dummy = { "comment" }
-predefined.push = { "push" }
-predefined.pop = { "pop" }
+setmetatableindex(whatever, function(t,k) local v = { } t[k] = v return v end)
local function checkparameters(g,f)
if f and g and not g.parameters and #g.fonts > 0 then
diff --git a/tex/context/base/grph-fil.lua b/tex/context/base/grph-fil.lua
index e036cf9a1..0856f5b08 100644
--- a/tex/context/base/grph-fil.lua
+++ b/tex/context/base/grph-fil.lua
@@ -12,9 +12,10 @@ local trace_run = false trackers.register("graphic.runfile",function(v) trace_r
local report_run = logs.reporter("graphics","run")
-local allocate, mark = utilities.storage.allocate, utilities.storage.mark
+local allocate = utilities.storage.allocate
-local collected, tobesaved = allocate(), allocate()
+local collected = allocate()
+local tobesaved = allocate()
local jobfiles = {
collected = collected,
@@ -24,8 +25,8 @@ local jobfiles = {
job.files = jobfiles
local function initializer()
- tobesaved = mark(jobfiles.tobesaved)
- collected = mark(jobfiles.collected)
+ tobesaved = jobfiles.tobesaved
+ collected = jobfiles.collected
end
job.register('job.files.collected', tobesaved, initializer)
diff --git a/tex/context/base/grph-inc.lua b/tex/context/base/grph-inc.lua
index bb29e6142..48cc2e4b0 100644
--- a/tex/context/base/grph-inc.lua
+++ b/tex/context/base/grph-inc.lua
@@ -44,20 +44,23 @@ local texbox = tex.box
local contains = table.contains
local concat, insert, remove = table.concat, table.insert, table.remove
local todimen = string.todimen
-local settings_to_array, settings_to_hash = utilities.parsers.settings_to_array, utilities.parsers.settings_to_hash
-local allocate = utilities.storage.allocate
-local variables = interfaces.variables
-local codeinjections = backends.codeinjections
-local nodeinjections = backends.nodeinjections
+local settings_to_array = utilities.parsers.settings_to_array
+local settings_to_hash = utilities.parsers.settings_to_hash
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
-local trace_figures = false trackers.register("graphics.locating", function(v) trace_figures = v end)
-local trace_bases = false trackers.register("graphics.bases", function(v) trace_bases = v end)
-local trace_programs = false trackers.register("graphics.programs", function(v) trace_programs = v end)
-local trace_conversion = false trackers.register("graphics.conversion", function(v) trace_conversion = v end)
-local trace_inclusion = false trackers.register("graphics.inclusion", function(v) trace_inclusion = v end)
+local variables = interfaces.variables
+local codeinjections = backends.codeinjections
+local nodeinjections = backends.nodeinjections
-local report_inclusion = logs.reporter("graphics","inclusion")
+local trace_figures = false trackers.register("graphics.locating", function(v) trace_figures = v end)
+local trace_bases = false trackers.register("graphics.bases", function(v) trace_bases = v end)
+local trace_programs = false trackers.register("graphics.programs", function(v) trace_programs = v end)
+local trace_conversion = false trackers.register("graphics.conversion", function(v) trace_conversion = v end)
+local trace_inclusion = false trackers.register("graphics.inclusion", function(v) trace_inclusion = v end)
+
+local report_inclusion = logs.reporter("graphics","inclusion")
local context, img = context, img
@@ -290,8 +293,8 @@ local function new() -- we could use metatables status -> used -> request but it
fullname = false,
format = false,
}
- -- setmetatable(status, { __index = used })
- -- setmetatable(used, { __index = request })
+ -- setmetatableindex(status, used)
+ -- setmetatableindex(used, request)
return {
request = request,
used = used,
diff --git a/tex/context/base/l-dimen.lua b/tex/context/base/l-dimen.lua
deleted file mode 100644
index f8a999cc9..000000000
--- a/tex/context/base/l-dimen.lua
+++ /dev/null
@@ -1,434 +0,0 @@
-if not modules then modules = { } end modules ['l-dimen'] = {
- version = 1.001,
- comment = "support for dimensions",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
---[[ldx--
-Internally work with scaled point, which are
-represented by integers. However, in practice, at east at the
- end we work with more generic units like points (pt). Going
-from scaled points (numbers) to one of those units can be
-done by using the conversion factors collected in the following
-table.
---ldx]]--
-
-local format, match, gsub, type, setmetatable = string.format, string.match, string.gsub, type, setmetatable
-local P, S, R, Cc, lpegmatch = lpeg.P, lpeg.S, lpeg.R, lpeg.Cc, lpeg.match
-
-number = number or { }
-local number = number
-
-number.tonumberf = function(n) return match(format("%.20f",n),"(.-0?)0*$") end -- one zero too much but alas
-number.tonumberg = function(n) return format("%.20g",n) end
-
-local dimenfactors = {
- ["pt"] = 1/65536,
- ["in"] = ( 100/ 7227)/65536,
- ["cm"] = ( 254/ 7227)/65536,
- ["mm"] = ( 2540/ 7227)/65536,
- ["sp"] = 1, -- 65536 sp in 1pt
- ["bp"] = ( 7200/ 7227)/65536,
- ["pc"] = ( 1/ 12)/65536,
- ["dd"] = ( 1157/ 1238)/65536,
- ["cc"] = ( 1157/14856)/65536,
- ["nd"] = (20320/21681)/65536,
- ["nc"] = ( 5080/65043)/65536
-}
-
---~ print(table.serialize(dimenfactors))
---~
---~ %.99g:
---~
---~ t={
---~ ["bp"]=1.5201782378580324e-005,
---~ ["cc"]=1.1883696112892098e-006,
---~ ["cm"]=5.3628510057769479e-007,
---~ ["dd"]=1.4260435335470516e-005,
---~ ["em"]=0.000152587890625,
---~ ["ex"]=6.103515625e-005,
---~ ["in"]=2.1113586636917117e-007,
---~ ["mm"]=5.3628510057769473e-008,
---~ ["nc"]=1.1917446679504327e-006,
---~ ["nd"]=1.4300936015405194e-005,
---~ ["pc"]=1.2715657552083333e-006,
---~ ["pt"]=1.52587890625e-005,
---~ ["sp"]=1,
---~ }
---~
---~ patched %s and tonumber
---~
---~ t={
---~ ["bp"]=0.00001520178238,
---~ ["cc"]=0.00000118836961,
---~ ["cm"]=0.0000005362851,
---~ ["dd"]=0.00001426043534,
---~ ["em"]=0.00015258789063,
---~ ["ex"]=0.00006103515625,
---~ ["in"]=0.00000021113587,
---~ ["mm"]=0.00000005362851,
---~ ["nc"]=0.00000119174467,
---~ ["nd"]=0.00001430093602,
---~ ["pc"]=0.00000127156576,
---~ ["pt"]=0.00001525878906,
---~ ["sp"]=1,
---~ }
-
---[[ldx--
-A conversion function that takes a number, unit (string) and optional
-format (string) is implemented using this table.
---ldx]]--
-
-local function numbertodimen(n,unit,fmt)
- if type(n) == 'string' then
- return n
- else
- unit = unit or 'pt'
- return format(fmt or "%s%s",n*dimenfactors[unit],unit)
- -- if fmt then
- -- return format(fmt,n*dimenfactors[unit],unit)
- -- else
- -- return match(format("%.20f",n*dimenfactors[unit]),"(.-0?)0*$") .. unit
- -- end
- end
-end
-
---[[ldx--
-We collect a bunch of converters in the number namespace.
---ldx]]--
-
-number.maxdimen = 1073741823
-number.todimen = numbertodimen
-number.dimenfactors = dimenfactors
-
-function number.topoints (n) return numbertodimen(n,"pt") end
-function number.toinches (n) return numbertodimen(n,"in") end
-function number.tocentimeters (n) return numbertodimen(n,"cm") end
-function number.tomillimeters (n) return numbertodimen(n,"mm") end
-function number.toscaledpoints(n) return numbertodimen(n,"sp") end
-function number.toscaledpoints(n) return n .. "sp" end
-function number.tobasepoints (n) return numbertodimen(n,"bp") end
-function number.topicas (n) return numbertodimen(n "pc") end
-function number.todidots (n) return numbertodimen(n,"dd") end
-function number.tociceros (n) return numbertodimen(n,"cc") end
-function number.tonewdidots (n) return numbertodimen(n,"nd") end
-function number.tonewciceros (n) return numbertodimen(n,"nc") end
-
---[[ldx--
-More interesting it to implement a (sort of) dimen datatype, one
-that permits calculations too. First we define a function that
-converts a string to scaledpoints. We use . We capture
-a number and optionally a unit. When no unit is given a constant
-capture takes place.
---ldx]]--
-
-local amount = (S("+-")^0 * R("09")^0 * P(".")^0 * R("09")^0) + Cc("0")
-local unit = R("az")^1
-
-local dimenpair = amount/tonumber * (unit^1/dimenfactors + Cc(1)) -- tonumber is new
-
-lpeg.patterns.dimenpair = dimenpair
-
---[[ldx--
-We use a metatable to intercept errors. When no key is found in
-the table with factors, the metatable will be consulted for an
-alternative index function.
---ldx]]--
-
-local mt = { } setmetatable(dimenfactors,mt)
-
-mt.__index = function(t,s)
- -- error("wrong dimension: " .. (s or "?")) -- better a message
- return false
-end
-
-
---[[ldx--
-We redefine the following function later on, so we comment it
-here (which saves us bytecodes.
---ldx]]--
-
--- function string.todimen(str)
--- if type(str) == "number" then
--- return str
--- else
--- local value, unit = lpegmatch(dimenpair,str)
--- return value/unit
--- end
--- end
---
--- local stringtodimen = string.todimen
-
-local stringtodimen -- assigned later (commenting saves bytecode)
-
-local amount = S("+-")^0 * R("09")^0 * S(".,")^0 * R("09")^0
-local unit = P("pt") + P("cm") + P("mm") + P("sp") + P("bp") + P("in") +
- P("pc") + P("dd") + P("cc") + P("nd") + P("nc")
-
-local validdimen = amount * unit
-
-lpeg.patterns.validdimen = validdimen
-
---[[ldx--
-This converter accepts calls like:
-
-
-string.todimen("10")
-string.todimen(".10")
-string.todimen("10.0")
-string.todimen("10.0pt")
-string.todimen("10pt")
-string.todimen("10.0pt")
-
-
-With this in place, we can now implement a proper datatype for dimensions, one
-that permits us to do this:
-
-
-s = dimen "10pt" + dimen "20pt" + dimen "200pt"
- - dimen "100sp" / 10 + "20pt" + "0pt"
-
-
-We create a local metatable for this new type:
---ldx]]--
-
-local dimensions = { }
-
---[[ldx--
-The main (and globally) visible representation of a dimen is defined next: it is
-a one-element table. The unit that is returned from the match is normally a number
-(one of the previously defined factors) but we also accept functions. Later we will
-see why. This function is redefined later.
---ldx]]--
-
--- function dimen(a)
--- if a then
--- local ta= type(a)
--- if ta == "string" then
--- local value, unit = lpegmatch(pattern,a)
--- if type(unit) == "function" then
--- k = value/unit()
--- else
--- k = value/unit
--- end
--- a = k
--- elseif ta == "table" then
--- a = a[1]
--- end
--- return setmetatable({ a }, dimensions)
--- else
--- return setmetatable({ 0 }, dimensions)
--- end
--- end
-
---[[ldx--
-This function return a small hash with a metatable attached. It is
-through this metatable that we can do the calculations. We could have
-shared some of the code but for reasons of speed we don't.
---ldx]]--
-
-function dimensions.__add(a, b)
- local ta, tb = type(a), type(b)
- if ta == "string" then a = stringtodimen(a) elseif ta == "table" then a = a[1] end
- if tb == "string" then b = stringtodimen(b) elseif tb == "table" then b = b[1] end
- return setmetatable({ a + b }, dimensions)
-end
-
-function dimensions.__sub(a, b)
- local ta, tb = type(a), type(b)
- if ta == "string" then a = stringtodimen(a) elseif ta == "table" then a = a[1] end
- if tb == "string" then b = stringtodimen(b) elseif tb == "table" then b = b[1] end
- return setmetatable({ a - b }, dimensions)
-end
-
-function dimensions.__mul(a, b)
- local ta, tb = type(a), type(b)
- if ta == "string" then a = stringtodimen(a) elseif ta == "table" then a = a[1] end
- if tb == "string" then b = stringtodimen(b) elseif tb == "table" then b = b[1] end
- return setmetatable({ a * b }, dimensions)
-end
-
-function dimensions.__div(a, b)
- local ta, tb = type(a), type(b)
- if ta == "string" then a = stringtodimen(a) elseif ta == "table" then a = a[1] end
- if tb == "string" then b = stringtodimen(b) elseif tb == "table" then b = b[1] end
- return setmetatable({ a / b }, dimensions)
-end
-
-function dimensions.__unm(a)
- local ta = type(a)
- if ta == "string" then a = stringtodimen(a) elseif ta == "table" then a = a[1] end
- return setmetatable({ - a }, dimensions)
-end
-
---[[ldx--
-It makes no sense to implement the power and modulo function but
-the next two do make sense because they permits is code like:
-
-
-local a, b = dimen "10pt", dimen "11pt"
-...
-if a > b then
- ...
-end
-
---ldx]]--
-
--- makes no sense: dimensions.__pow and dimensions.__mod
-
-function dimensions.__lt(a, b)
- return a[1] < b[1]
-end
-
-function dimensions.__eq(a, b)
- return a[1] == b[1]
-end
-
---[[ldx--
-We also need to provide a function for conversion to string (so that
-we can print dimensions). We print them as points, just like .
---ldx]]--
-
-function dimensions.__tostring(a)
- return a[1]/65536 .. "pt" -- instead of todimen(a[1])
-end
-
---[[ldx--
-Since it does not take much code, we also provide a way to access
-a few accessors
-
-
-print(dimen().pt)
-print(dimen().sp)
-
---ldx]]--
-
-function dimensions.__index(tab,key)
- local d = dimenfactors[key]
- if not d then
- error("illegal property of dimen: " .. key)
- d = 1
- end
- return 1/d
-end
-
---[[ldx--
-In the converter from string to dimension we support functions as
-factors. This is because in we have a few more units:
-ex and em. These are not constant factors but
-depend on the current font. They are not defined by default, but need
-an explicit function call. This is because at the moment that this code
-is loaded, the relevant tables that hold the functions needed may not
-yet be available.
---ldx]]--
-
- dimenfactors["ex"] = 4 * 1/65536 -- 4pt
- dimenfactors["em"] = 10 * 1/65536 -- 10pt
--- dimenfactors["%"] = 4 * 1/65536 -- 400pt/100
-
---[[ldx--
-The previous code is rather efficient (also thanks to ) but we
-can speed it up by caching converted dimensions. On my machine (2008) the following
-loop takes about 25.5 seconds.
-
-
-for i=1,1000000 do
- local s = dimen "10pt" + dimen "20pt" + dimen "200pt"
- - dimen "100sp" / 10 + "20pt" + "0pt"
-end
-
-
-When we cache converted strings this becomes 16.3 seconds. In order not
-to waste too much memory on it, we tag the values of the cache as being
-week which mean that the garbage collector will collect them in a next
-sweep. This means that in most cases the speed up is mostly affecting the
-current couple of calculations and as such the speed penalty is small.
-
-We redefine two previous defined functions that can benefit from
-this:
---ldx]]--
-
-local known = { } setmetatable(known, { __mode = "v" })
-
-function dimen(a)
- if a then
- local ta= type(a)
- if ta == "string" then
- local k = known[a]
- if k then
- a = k
- else
- local value, unit = lpegmatch(dimenpair,a)
- if type(unit) == "function" then
- k = value/unit()
- else
- k = value/unit
- end
- known[a] = k
- a = k
- end
- elseif ta == "table" then
- a = a[1]
- end
- return setmetatable({ a }, dimensions)
- else
- return setmetatable({ 0 }, dimensions)
- end
-end
-
-function string.todimen(str) -- maybe use tex.sp when available
- if type(str) == "number" then
- return str
- else
- local k = known[str]
- if not k then
- local value, unit = lpegmatch(dimenpair,str)
- if value and unit then
- k = value/unit -- to be considered: round
- else
- k = 0
- end
- -- print(str,value,unit)
- known[str] = k
- end
- return k
- end
-end
-
---~ local known = { }
-
---~ function string.todimen(str) -- maybe use tex.sp
---~ local k = known[str]
---~ if not k then
---~ k = tex.sp(str)
---~ known[str] = k
---~ end
---~ return k
---~ end
-
-stringtodimen = string.todimen -- local variable defined earlier
-
-function number.toscaled(d)
- return format("%0.5f",d/2^16)
-end
-
---[[ldx--
-In a similar fashion we can define a glue datatype. In that case we
-probably use a hash instead of a one-element table.
---ldx]]--
-
---[[ldx--
-Goodie:s
---ldx]]--
-
-function number.percent(n) -- will be cleaned up once luatex 0.30 is out
- local hsize = tex.hsize
- if type(hsize) == "string" then
- hsize = stringtodimen(hsize)
- end
- return (n/100) * hsize
-end
-
-number["%"] = number.percent
diff --git a/tex/context/base/l-file.lua b/tex/context/base/l-file.lua
index fe69c9181..c3199f022 100644
--- a/tex/context/base/l-file.lua
+++ b/tex/context/base/l-file.lua
@@ -253,8 +253,6 @@ function file.collapsepath(str,anchor)
end
end
-file.collapse_path = file.collapsepath
-
--~ local function test(str)
--~ print(string.format("%-20s %-15s %-15s",str,file.collapsepath(str),file.collapsepath(str,true)))
--~ end
diff --git a/tex/context/base/l-md5.lua b/tex/context/base/l-md5.lua
index f9197c56e..1d471c966 100644
--- a/tex/context/base/l-md5.lua
+++ b/tex/context/base/l-md5.lua
@@ -31,14 +31,12 @@ if not md5.dec then function md5.dec(str) return convert(str,"%03i") end end
--~ function md5.dec(str) return (gsub(md5.sum(str),".",remap)) end
--~ end
-file.needs_updating_threshold = 1
-
-function file.needs_updating(oldname,newname) -- size modification access change
+function file.needs_updating(oldname,newname,threshold) -- size modification access change
local oldtime = lfs.attributes(oldname, modification)
local newtime = lfs.attributes(newname, modification)
if newtime >= oldtime then
return false
- elseif oldtime - newtime < file.needs_updating_threshold then
+ elseif oldtime - newtime < (threshold or 1) then
return false
else
return true
diff --git a/tex/context/base/l-table.lua b/tex/context/base/l-table.lua
index 727d80df7..9de3c5502 100644
--- a/tex/context/base/l-table.lua
+++ b/tex/context/base/l-table.lua
@@ -306,10 +306,6 @@ function table.fromhash(t)
return hsh
end
-table.serialize_functions = true
-table.serialize_compact = true
-table.serialize_inline = true
-
local noquotes, hexify, handle, reduce, compact, inline, functions
local reserved = table.tohash { -- intercept a language inconvenience: no reserved words as key
@@ -595,15 +591,36 @@ end
-- replacing handle by a direct t[#t+1] = ... (plus test) is not much
-- faster (0.03 on 1.00 for zapfino.tma)
-local function serialize(root,name,_handle,_reduce,_noquotes,_hexify)
- noquotes = _noquotes
- hexify = _hexify
- handle = _handle or print
- reduce = _reduce or false
- compact = table.serialize_compact
- inline = compact and table.serialize_inline
- functions = table.serialize_functions
+local function serialize(root,name,_handle,_reduce,_noquotes,_hexify) -- I might drop the _'s some day.
local tname = type(name)
+ if tname == "table" then
+ noquotes = name.noquotes
+ hexify = name.hexify
+ handle = name.handle or print
+ reduce = name.reduce or false
+ functions = name.functions
+ compact = name.compact
+ inline = name.inline and compact
+ name = name.name
+ tname = type(name)
+ if functions == nil then
+ functions = true
+ end
+ if compact == nil then
+ compact = true
+ end
+ if inline == nil then
+ inline = compact
+ end
+ else
+ noquotes = _noquotes
+ hexify = _hexify
+ handle = _handle or print
+ reduce = _reduce or false
+ compact = true
+ inline = true
+ functions = true
+ end
if tname == "string" then
if name == "return" then
handle("return {")
@@ -670,12 +687,11 @@ end
--
-- so this is on the todo list
-table.tofile_maxtab = 2*1024
+local maxtab = 2*1024
function table.tofile(filename,root,name,reduce,noquotes,hexify)
local f = io.open(filename,'w')
if f then
- local maxtab = table.tofile_maxtab
if maxtab > 1 then
local t, n = { }, 0
local function flush(s)
@@ -893,8 +909,12 @@ function table.sequenced(t,sep,simple) -- hash only
return concat(s, sep or " | ")
end
-function table.print(...)
- table.tohandle(print,...)
+function table.print(t,...)
+ if type(t) ~= "table" then
+ print(tostring(t))
+ else
+ table.tohandle(print,t,...)
+ end
end
-- -- -- obsolete but we keep them for a while and might comment them later -- -- --
diff --git a/tex/context/base/lang-def.lua b/tex/context/base/lang-def.lua
index 4fdcdf8a7..78c8eecbd 100644
--- a/tex/context/base/lang-def.lua
+++ b/tex/context/base/lang-def.lua
@@ -8,11 +8,12 @@ if not modules then modules = { } end modules ['lang-ini'] = {
local lower = string.lower
-languages = languages or { }
-local languages = languages
+languages = languages or { }
+local languages = languages
+local data = languages.data
-languages.data = languages.data or utilities.storage.allocate { }
-local data = languages.data
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
-- The specifications are based on an analysis done by Arthur. The
-- names of tags were changed by Hans. The data is not yet used but
@@ -62,7 +63,7 @@ local data = languages.data
--
-- todo: add default features
-local specifications = {
+local specifications = allocate {
{
["description"] = "Basque",
["script"] = "latn",
@@ -360,16 +361,13 @@ local specifications = {
data.specifications = specifications
-storage.mark(specifications)
-
local variants = { } data.variants = variants
local opentypes = { } data.opentypes = opentypes
local contexts = { } data.contexts = contexts
local records = { } data.records = records
-
for k=1,#specifications do
- local v = languagedata[k]
+ local v = specifications[k]
if v.variant then
variants[v.variant] = v
end
@@ -388,31 +386,31 @@ for k=1,#specifications do
end
end
-setmetatable(variants, { __index = function(t,k)
+setmetatableindex(variants, function(t,k)
str = lower(str)
local v = (l_variant[str] or l_opentype[str] or l_context[str] or l_variant.en).language
t[k] = v
return v
-end } )
+end)
-setmetatable(opentypes, { __index = function(t,k)
+setmetatableindex(opentypes, function(t,k)
str = lower(str)
local v = (l_variant[str] or l_opentype[str] or l_context[str] or l_variant.en).opentype
t[k] = v
return v
-end
+end)
-setmetatable(contexts, { __index = function(t,k)
+setmetatableindex(contexts, function(t,k)
str = lower(str)
local v = (l_variant[str] or l_opentype[str] or l_context[str] or l_variant[languages.default]).context
v = (type(v) == "table" and v[1]) or v
t[k] = v
return v
-end
+end)
-setmetatable(records, { __index = function(t,k) -- how useful is this one?
+setmetatableindex(records, function(t,k) -- how useful is this one?
str = lower(str)
local v = variants[str] or opentypes[str] or contexts[str] or variants.en
t[k] = v
return v
-end
+end)
diff --git a/tex/context/base/lang-def.mkiv b/tex/context/base/lang-def.mkiv
index 871e4f528..401065adb 100644
--- a/tex/context/base/lang-def.mkiv
+++ b/tex/context/base/lang-def.mkiv
@@ -190,34 +190,6 @@
\installlanguage [swedish] [\s!sv]
\installlanguage [afrikaans] [\s!af]
-%D Next we implement couple of ordinal mumber converters:
-
-\def\enordinaldaynumber#1%
- {#1\ifnum\lasttwodigits{#1}=11
- \highordinalstr{th}%
- \else\ifnum\lasttwodigits{#1}=12
- \highordinalstr{th}%
- \else\ifnum\lasttwodigits{#1}=13
- \highordinalstr{th}%
- \else\ifcase\lastdigit{#1}%
- \highordinalstr{th}%
- \or % 1
- \highordinalstr{st}%
- \or % 2
- \highordinalstr{nd}%
- \or % 3
- \highordinalstr{rd}%
- \else
- \highordinalstr{th}%
- \fi\fi\fi\fi}
-
-% \def\enordinaldaynumber#1%
-% {#1\ordinalstr{\ifnum\lasttwodigits{#1}=11 th\else\ifcase\lastdigit{#1}
-% th\or st\or nd\or rd\else th\fi\fi}}
-
-\def\nlordinaldaynumber#1%
- {#1\highordinalstr{e}}
-
% Slavic Languages: Belarussian, Russian, Ukrainian, Bulgarian,
% Macedonian, Serbian, Croatian, Slovenian, Czech, Kushubian,
% Lusatian/Sorbian/Wendish, Polish, Slovak, Albanian, Illyrian,
@@ -699,13 +671,6 @@
\installlanguage [portuguese] [\s!pt]
\installlanguage [romanian] [\s!ro]
-%D Ordinal converters:
-
-\def\frordinaldaynumber#1% date is masculine
- {\number#1\ifcase#1\or
- \highordinalstr{er}%
- \fi}
-
\defineconversion [\s!fr] [\v!day+] [\frordinaldaynumber]
% Vietnamese Language
diff --git a/tex/context/base/lang-ini.lua b/tex/context/base/lang-ini.lua
index 0a2d76508..305b429e1 100644
--- a/tex/context/base/lang-ini.lua
+++ b/tex/context/base/lang-ini.lua
@@ -23,16 +23,19 @@ local format, gsub = string.format, string.gsub
local concat = table.concat
local lpegmatch = lpeg.match
local texwrite = tex.write
+
local settings_to_array = utilities.parsers.settings_to_array
local trace_patterns = false trackers.register("languages.patterns", function(v) trace_patterns = v end)
local report_initialization = logs.reporter("languages","initialization")
-local prehyphenchar, posthyphenchar = lang.prehyphenchar, lang.posthyphenchar -- global per language
-local lefthyphenmin, righthyphenmin = lang.lefthyphenmin, lang.righthyphenmin
+local prehyphenchar = lang.prehyphenchar -- global per language
+local posthyphenchar = lang.posthyphenchar -- global per language
+local lefthyphenmin = lang.lefthyphenmin
+local righthyphenmin = lang.righthyphenmin
-lang.exceptions = lang.hyphenation
+lang.exceptions = lang.hyphenation
languages = languages or {}
local languages = languages
@@ -48,9 +51,13 @@ local associated = languages.associated
languages.numbers = languages.numbers or { }
local numbers = languages.numbers
+languages.data = languages.data or { }
+local data = languages.data
+
storage.register("languages/numbers", numbers, "languages.numbers")
storage.register("languages/registered",registered,"languages.registered")
storage.register("languages/associated",associated,"languages.associated")
+storage.register("languages/data", data, "languages.data")
local nofloaded = 0
diff --git a/tex/context/base/lang-lab.lua b/tex/context/base/lang-lab.lua
index 58fff29cd..1947616a9 100644
--- a/tex/context/base/lang-lab.lua
+++ b/tex/context/base/lang-lab.lua
@@ -65,7 +65,6 @@ local texsprint = tex.sprint
local prtcatcodes = tex.prtcatcodes
languages.labels = languages.labels or { }
-languages.data = languages.data or { }
local trace_labels = false trackers.register("languages.labels", function(v) trace_labels = v end)
diff --git a/tex/context/base/lang-url.lua b/tex/context/base/lang-url.lua
index ecde7f3ae..e401e4148 100644
--- a/tex/context/base/lang-url.lua
+++ b/tex/context/base/lang-url.lua
@@ -68,7 +68,7 @@ hyphenatedurl.discretionary = nil
local chars = hyphenatedurl.characters
-function hyphenatedurl.action(str, left, right, disc)
+local function action(hyphenatedurl, str, left, right, disc)
local n = 0
local b = math.max( left or hyphenatedurl.lefthyphenmin, 2)
local e = math.min(#str-(right or hyphenatedurl.righthyphenmin)+2,#str)
@@ -90,6 +90,10 @@ function hyphenatedurl.action(str, left, right, disc)
end
end
+-- hyphenatedurl.action = function(_,...) action(...) end -- sort of obsolete
+
+table.setmetatablecall(hyphenatedurl,action)
+
-- todo, no interface in mkiv yet
function hyphenatedurl.setcharacters(str,value) -- 1, 2 == before, after
diff --git a/tex/context/base/lang-url.mkiv b/tex/context/base/lang-url.mkiv
index a3cf466de..cba013324 100644
--- a/tex/context/base/lang-url.mkiv
+++ b/tex/context/base/lang-url.mkiv
@@ -81,7 +81,7 @@
\let\b\dohyphenatedurlbefore
\let\a\dohyphenatedurlafter
\let\d\dohyphenatedurldisc
- \normalexpanded{\noexpand\ctxcommand{hyphenatedurl.action(
+ \normalexpanded{\noexpand\ctxcommand{hyphenatedurl(
\!!bs\noexpand\detokenize{#1}\!!es,
\number\hyphenatedurllefthyphenmin,
\number\hyphenatedurlrighthyphenmin,
diff --git a/tex/context/base/luat-bas.mkiv b/tex/context/base/luat-bas.mkiv
index d9c857211..d5075b4cb 100644
--- a/tex/context/base/luat-bas.mkiv
+++ b/tex/context/base/luat-bas.mkiv
@@ -27,10 +27,8 @@
\registerctxluafile{l-dir} {1.001}
\registerctxluafile{l-unicode}{1.001}
%registerctxluafile{l-utils} {1.001}
-\registerctxluafile{l-dimen} {1.001}
\registerctxluafile{l-url} {1.001}
\registerctxluafile{l-set} {1.001}
-\registerctxluafile{l-dimen} {1.001}
% \registerctxluafile{socket.lua}{}
% \registerctxluafile{ltn12.lua} {}
diff --git a/tex/context/base/luat-lib.mkiv b/tex/context/base/luat-lib.mkiv
index 29de9a0ea..83b96639b 100644
--- a/tex/context/base/luat-lib.mkiv
+++ b/tex/context/base/luat-lib.mkiv
@@ -16,13 +16,14 @@
\registerctxluafile{util-str}{1.001}
\registerctxluafile{util-tab}{1.001}
\registerctxluafile{util-pck}{1.001}
+\registerctxluafile{util-sto}{1.001} % could also be done in trac-deb.mkiv
\registerctxluafile{util-seq}{1.001}
%registerctxluafile{util-mrg}{1.001} % not needed in context itself, only mtxrun
\registerctxluafile{util-lua}{1.001}
\registerctxluafile{util-prs}{1.001}
\registerctxluafile{util-fmt}{1.001}
\registerctxluafile{util-deb}{1.001} % could also be done in trac-deb.mkiv
-\registerctxluafile{util-sto}{1.001} % could also be done in trac-deb.mkiv
+\registerctxluafile{util-dim}{1.001}
\registerctxluafile{trac-inf}{1.001}
\registerctxluafile{trac-set}{1.001}
diff --git a/tex/context/base/luat-mac.lua b/tex/context/base/luat-mac.lua
index 775e8a3b5..0dc6593c6 100644
--- a/tex/context/base/luat-mac.lua
+++ b/tex/context/base/luat-mac.lua
@@ -258,4 +258,14 @@ end
--~ % \hbox attr \referenceattribute \lastreferenceattribute {\localframed[#namespace:#current]{#text}}}
--~ \hbox attr \referenceattribute \lastreferenceattribute {\directlocalframed[#namespace:#current]{#text}}}
--~ ]]))
-
+--~
+--~ print(macros.preprocessed([[
+--~ \def\definefoo[#name]%
+--~ {\setvalue{start#name}{\dostartfoo{#name}}}
+--~ \def\dostartfoo#name%
+--~ {\def\noexpand\next#content\expandafter\noexpand\csname stop#name\endcsname{#name : #content}%
+--~ \next}
+--~ \def\dostartfoo#name%
+--~ {\normalexpanded{\def\noexpand\next#content\expandafter\noexpand\csname stop#name\endcsname}{#name : #content}%
+--~ \next}
+--~ ]]))
diff --git a/tex/context/base/lxml-aux.lua b/tex/context/base/lxml-aux.lua
index a8223c4b4..4798fe06a 100644
--- a/tex/context/base/lxml-aux.lua
+++ b/tex/context/base/lxml-aux.lua
@@ -19,8 +19,8 @@ local xmlconvert, xmlcopy, xmlname = xml.convert, xml.copy, xml.name
local xmlinheritedconvert = xml.inheritedconvert
local xmlapplylpath = xml.applylpath
-local type = type
-local insert, remove = table.insert, table.remove
+local type, setmetatable, getmetatable = type, setmetatable, getmetatable
+local insert, remove, fastcopy = table.insert, table.remove, table.fastcopy
local gmatch, gsub = string.gmatch, string.gsub
local function report(what,pattern,c,e)
@@ -234,6 +234,41 @@ function xml.replace(root,pattern,whatever)
end
end
+local function wrap(e,wrapper)
+ local t = {
+ rn = e.rn,
+ tg = e.tg,
+ ns = e.ns,
+ at = e.at,
+ dt = e.dt,
+ __p__ = e,
+ }
+ setmetatable(t,getmetatable(e))
+ e.rn = wrapper.rn or e.rn or ""
+ e.tg = wrapper.tg or e.tg or ""
+ e.ns = wrapper.ns or e.ns or ""
+ e.at = fastcopy(wrapper.at)
+ e.dt = { t }
+end
+
+function xml.wrap(root,pattern,whatever)
+ if whatever then
+ local wrapper = xmltoelement(whatever,root)
+ local collected = xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e = collected[c]
+ if trace_manipulations then
+ report('wrapping',pattern,c,e)
+ end
+ wrap(e,wrapper)
+ end
+ end
+ else
+ wrap(root,xmltoelement(pattern))
+ end
+end
+
local function inject_element(root,pattern,whatever,prepend)
local element = root and xmltoelement(whatever,root)
local collected = element and xmlapplylpath(root,pattern)
@@ -304,7 +339,7 @@ local function include(xmldata,pattern,attribute,recursive,loaddata)
local ekat = ek.at
local epdt = ek.__p__.dt
if not attribute or attribute == "" then
- name = (type(ekdt) == "table" and ekdt[1]) or ekdt -- ckeck, probably always tab or str
+ name = (type(ekdt) == "table" and ekdt[1]) or ekdt -- check, probably always tab or str
end
if not name then
for a in gmatch(attribute or "href","([^|]+)") do
diff --git a/tex/context/base/lxml-lpt.lua b/tex/context/base/lxml-lpt.lua
index f25d13eed..3384f80ee 100644
--- a/tex/context/base/lxml-lpt.lua
+++ b/tex/context/base/lxml-lpt.lua
@@ -14,6 +14,8 @@ local type, next, tonumber, tostring, setmetatable, loadstring = type, next, ton
local format, upper, lower, gmatch, gsub, find, rep = string.format, string.upper, string.lower, string.gmatch, string.gsub, string.find, string.rep
local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
+local setmetatableindex = table.setmetatableindex
+
-- beware, this is not xpath ... e.g. position is different (currently) and
-- we have reverse-sibling as reversed preceding sibling
@@ -86,8 +88,8 @@ local function fallback (t, name)
return fn
end
-setmetatable(finalizers.xml, { __index = fallback })
-setmetatable(finalizers.tex, { __index = fallback })
+setmetatableindex(finalizers.xml, fallback)
+setmetatableindex(finalizers.tex, fallback)
xml.defaultprotocol = "xml"
@@ -821,14 +823,13 @@ xml.nodesettostring = nodesettostring
local lpath -- we have a harmless kind of circular reference
+local lshowoptions = { name = false, functions = false }
+
local function lshow(parsed)
if type(parsed) == "string" then
parsed = lpath(parsed)
end
- local s = table.serialize_functions -- ugly
- table.serialize_functions = false -- ugly
- report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,table.serialize(parsed,false))
- table.serialize_functions = s -- ugly
+ report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,table.serialize(parsed,lshowoptions))
end
xml.lshow = lshow
diff --git a/tex/context/base/math-tag.lua b/tex/context/base/math-tag.lua
index 278e3b9cb..e5ad30be0 100644
--- a/tex/context/base/math-tag.lua
+++ b/tex/context/base/math-tag.lua
@@ -8,9 +8,9 @@ if not modules then modules = { } end modules ['math-tag'] = {
local attributes, nodes = attributes, nodes
-local has_attribute = nodes.has_attribute
-local set_attribute = nodes.set_attribute
-local set_attributes = nodes.set_attributes
+local get_attribute = nodes.getattribute
+local set_attribute = nodes.setattribute
+local set_attributes = nodes.setattributes
local traverse_nodes = node.traverse
local nodecodes = nodes.nodecodes
@@ -101,7 +101,7 @@ process = function(start) -- we cannot use the processor as we have no finalizer
processsubsup(start)
elseif id == math_box_code or id == hlist_code or id == vlist_code then
-- keep an eye on math_box_code and see what ends up in there
- local attr = has_attribute(start,a_tagged)
+ local attr = get_attribute(start,a_tagged)
local text = start_tagged("mtext")
set_attribute(start,a_tagged,text)
local list = start.list
@@ -124,7 +124,7 @@ process = function(start) -- we cannot use the processor as we have no finalizer
if id == hlist_code or id == vlist_code then
runner(n.list)
elseif id == glyph_code then
- local aa = has_attribute(n,a_tagged) -- only glyph needed
+ local aa = get_attribute(n,a_tagged) -- only glyph needed
if aa then
local ac = cache[aa]
if not ac then
diff --git a/tex/context/base/math-vfu.lua b/tex/context/base/math-vfu.lua
index 190a89c71..afb4c1be2 100644
--- a/tex/context/base/math-vfu.lua
+++ b/tex/context/base/math-vfu.lua
@@ -13,23 +13,24 @@ if not modules then modules = { } end modules ['math-vfu'] = {
local type, next = type, next
local max = math.max
+local fonts, nodes, mathematics = fonts, nodes, mathematics
+
local trace_virtual = false trackers.register("math.virtual", function(v) trace_virtual = v end)
local trace_timings = false trackers.register("math.timings", function(v) trace_timings = v end)
-local report_virtual = logs.reporter("fonts","virtual math")
-
-local fonts, nodes, mathematics = fonts, nodes, mathematics
+local report_virtual = logs.reporter("fonts","virtual math")
-local allocate = utilities.storage.allocate
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
-local mathencodings = allocate()
-fonts.encodings.math = mathencodings -- better is then: fonts.encodings.vectors
-local vfmath = allocate()
-fonts.handlers.vf.math = vfmath
+local mathencodings = allocate()
+fonts.encodings.math = mathencodings -- better is then: fonts.encodings.vectors
+local vfmath = allocate()
+fonts.handlers.vf.math = vfmath
-vfmath.optional = false
+vfmath.optional = false
-local shared = { }
+local shared = { }
--~ local push, pop, back = { "push" }, { "pop" }, { "slot", 1, 0x2215 }
@@ -346,7 +347,7 @@ local unique = 0 -- testcase: \startTEXpage \math{!\text{-}\text{-}\text{-}} \st
local reported = { }
local reverse = { } -- index -> unicode
-setmetatable ( reverse, { __index = function(t,name)
+setmetatableindex(reverse, function(t,name)
if trace_virtual then
report_virtual("initializing math vector '%s'",name)
end
@@ -356,7 +357,7 @@ setmetatable ( reverse, { __index = function(t,name)
end
reverse[name] = r
return r
-end } )
+end)
function vfmath.define(specification,set,goodies)
local name = specification.name -- symbolic name
@@ -460,14 +461,14 @@ function vfmath.define(specification,set,goodies)
end
--
local description = { name = "" }
- setmetatable(descriptions, { __index = function() return description end })
+ setmetatableindex(descriptions,function() return description end)
--
if parent.properties then
- setmetatable(properties, { __index = parent.properties })
+ setmetatableindex(properties,parent.properties)
end
--
if parent.goodies then
- setmetatable(goodies, { __index = parent.goodies })
+ setmetatableindex(goodies,parent.goodies)
end
--
properties.virtualized = true
diff --git a/tex/context/base/mlib-pps.lua b/tex/context/base/mlib-pps.lua
index e1f85e804..bbdd0bbd5 100644
--- a/tex/context/base/mlib-pps.lua
+++ b/tex/context/base/mlib-pps.lua
@@ -15,43 +15,47 @@ if not modules then modules = { } end modules ['mlib-pps'] = {
local format, gmatch, concat, round, match = string.format, string.gmatch, table.concat, math.round, string.match
local tonumber, type = tonumber, type
-local lpegmatch = lpeg.match
-local texbox = tex.box
-local copy_list, free_list = node.copy_list, node.flush_list
-
local Cs, Cf, C, Cg, Ct, P, S, V, Carg = lpeg.Cs, lpeg.Cf, lpeg.C, lpeg.Cg, lpeg.Ct, lpeg.P, lpeg.S, lpeg.V, lpeg.Carg
+local lpegmatch = lpeg.match
-local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming
+local mplib, metapost, lpdf, context = mplib, metapost, lpdf, context
-local context = context
+local texbox = tex.box
+local copy_list = node.copy_list
+local free_list = node.flush_list
+local setmetatableindex = table.setmetatableindex
+local sortedhash = table.sortedhash
-local trace_textexts = false trackers.register("metapost.textexts", function(v) trace_textexts = v end)
+local starttiming = statistics.starttiming
+local stoptiming = statistics.stoptiming
-local report_metapost = logs.reporter("metapost")
-local report_textexts = logs.reporter("metapost","textexts")
+local trace_textexts = false trackers.register("metapost.textexts", function(v) trace_textexts = v end)
-local colors = attributes.colors
+local report_metapost = logs.reporter("metapost")
+local report_textexts = logs.reporter("metapost","textexts")
-local rgbtocmyk = colors.rgbtocmyk or function() return 0,0,0,1 end
-local cmyktorgb = colors.cmyktorgb or function() return 0,0,0 end
-local rgbtogray = colors.rgbtogray or function() return 0 end
-local cmyktogray = colors.cmyktogray or function() return 0 end
+local colors = attributes.colors
-local mplib, metapost, lpdf = mplib, metapost, lpdf
+local rgbtocmyk = colors.rgbtocmyk or function() return 0,0,0,1 end
+local cmyktorgb = colors.cmyktorgb or function() return 0,0,0 end
+local rgbtogray = colors.rgbtogray or function() return 0 end
+local cmyktogray = colors.cmyktogray or function() return 0 end
-metapost.makempy = metapost.makempy or { nofconverted = 0 }
-local makempy = metapost.makempy
+metapost.makempy = metapost.makempy or { nofconverted = 0 }
+local makempy = metapost.makempy
-local nooutercolor = "0 g 0 G"
-local nooutertransparency = "/Tr0 gs" -- only when set
-local outercolormode = 0
-local outercolor = nooutercolor
-local outertransparency = nooutertransparency
-local innercolor = nooutercolor
-local innertransparency = nooutertransparency
+local nooutercolor = "0 g 0 G"
+local nooutertransparency = "/Tr0 gs" -- only when set
+local outercolormode = 0
+local outercolor = nooutercolor
+local outertransparency = nooutertransparency
+local innercolor = nooutercolor
+local innertransparency = nooutertransparency
-local pdfcolor, pdftransparency = lpdf.color, lpdf.transparency
-local registercolor, registerspotcolor = colors.register, colors.registerspotcolor
+local pdfcolor = lpdf.color
+local pdftransparency = lpdf.transparency
+local registercolor = colors.register
+local registerspotcolor = colors.registerspotcolor
local transparencies = attributes.transparencies
local registertransparency = transparencies.register
@@ -352,11 +356,11 @@ function models.gray(cr)
return checked_color_pair(format("%.3f g %.3f G",s,s))
end
-setmetatable(models, { __index = function(t,k)
+setmetatableindex(models, function(t,k)
local v = models.gray
t[k] = v
return v
-end })
+end)
local function colorconverter(cs)
return models[colors.model](cs)
@@ -839,15 +843,15 @@ local value = Cs ( (
)
local function tr_process(object,prescript,before,after)
+ -- before can be shortcut to t
+ local tr_alternative = prescript.tr_alternative
+ if tr_alternative then
+ tr_alternative = tonumber(tr_alternative)
+ local tr_transparency = tonumber(prescript.tr_transparency)
+ before[#before+1], after[#after+1] = format("/Tr%s gs",registertransparency(nil,tr_alternative,tr_transparency,true)), "/Tr0 gs" -- outertransparency
+ end
local cs = object.color
if cs and #cs > 0 then
- -- before can be shortcut to t
- local tr_alternative = prescript.tr_alternative
- if tr_alternative then
- tr_alternative = tonumber(tr_alternative)
- local tr_transparency = tonumber(prescript.tr_transparency)
- before[#before+1], after[#after+1] = format("/Tr%s gs",registertransparency(nil,tr_alternative,tr_transparency,true)), "/Tr0 gs" -- outertransparency
- end
local sp_name = prescript.sp_name
if sp_name then
local sp_fractions = prescript.sp_fractions or 1
diff --git a/tex/context/base/mult-ini.lua b/tex/context/base/mult-ini.lua
index fbb986017..4156e813d 100644
--- a/tex/context/base/mult-ini.lua
+++ b/tex/context/base/mult-ini.lua
@@ -10,16 +10,19 @@ local format, gmatch, gsub = string.format, string.gmatch, string.gsub
local lpegmatch = lpeg.match
local serialize = table.serialize
-local texsprint = tex.sprint
+local allocate = utilities.storage.allocate
+local mark = utilities.storage.mark
+local texsprint = tex.sprint
+local setmetatableindex = table.setmetatableindex
-local report_interface = logs.reporter("interface","initialization")
+local report_interface = logs.reporter("interface","initialization")
-interfaces = interfaces or { }
-interfaces.constants = interfaces.constants or { }
-interfaces.variables = interfaces.variables or { }
-interfaces.elements = interfaces.elements or { }
-interfaces.formats = interfaces.formats or { }
-interfaces.translations = interfaces.translations or { }
+interfaces = interfaces or { }
+interfaces.constants = mark(interfaces.constants or { })
+interfaces.variables = mark(interfaces.variables or { })
+interfaces.elements = mark(interfaces.elements or { })
+interfaces.formats = mark(interfaces.formats or { })
+interfaces.translations = mark(interfaces.translations or { })
storage.register("interfaces/constants", interfaces.constants, "interfaces.constants")
storage.register("interfaces/variables", interfaces.variables, "interfaces.variables")
@@ -37,16 +40,19 @@ storage.shared.currentresponse = storage.shared.currentresponse or "en"
local currentinterface = storage.shared.currentinterface
local currentresponse = storage.shared.currentresponse
-local complete = { } interfaces.complete = complete
+local complete = allocate()
+interfaces.complete = complete
-setmetatable(complete, { __index = function(t,k) -- one access needed to get loaded
+local function resolve(t,k) -- one access needed to get loaded
report_interface("loading interface definitions from 'mult-def.lua'")
complete = dofile(resolvers.findfile("mult-def.lua"))
report_interface("loading interface messages from 'mult-mes.lua'")
complete.messages = dofile(resolvers.findfile("mult-mes.lua"))
interfaces.complete = complete
return rawget(complete,k)
-end } )
+end
+
+setmetatableindex(complete, resolve)
local constants = interfaces.constants
local variables = interfaces.variables
@@ -55,15 +61,24 @@ local formats = interfaces.formats
local translations = interfaces.translations
local reporters = { } -- just an optimization
-local valueiskey = { __index = function(t,k) t[k] = k return k end } -- will be helper
+local function valueiskey(t,k) -- will be helper
+ t[k] = k
+ return k
+end
-setmetatable(variables, valueiskey)
-setmetatable(constants, valueiskey)
-setmetatable(elements, valueiskey)
-setmetatable(formats, valueiskey)
-setmetatable(translations, valueiskey)
+setmetatableindex(variables, valueiskey)
+setmetatableindex(constants, valueiskey)
+setmetatableindex(elements, valueiskey)
+setmetatableindex(formats, valueiskey)
+setmetatableindex(translations, valueiskey)
+
+local function resolve(t,k)
+ local v = logs.reporter(k)
+ t[k] = v
+ return v
+end
-setmetatable(reporters, { __index = function(t,k) local v = logs.reporter(k) ; t[k] = v ; return v end })
+setmetatableindex(reporters, resolve)
for category, _ in next, translations do
-- We pre-create reporters for already defined messages
diff --git a/tex/context/base/node-aux.lua b/tex/context/base/node-aux.lua
index 65a47939b..0b44f7724 100644
--- a/tex/context/base/node-aux.lua
+++ b/tex/context/base/node-aux.lua
@@ -39,7 +39,7 @@ local isnode = node.is_node
local texbox = tex.box
-function nodes.repack_hlist(list,...)
+function nodes.repackhlist(list,...)
--~ nodes.showsimplelist(list)
local temp, b = hpack_nodes(list,...)
list = temp.list
@@ -80,22 +80,15 @@ local function unset_attributes(head,attr)
end
end
-nodes.set_attribute = set_attribute
-nodes.unset_attribute = unset_attribute
-nodes.has_attribute = has_attribute
-nodes.first_glyph = first_glyph
+nodes.firstglyph = first_glyph
+nodes.setattribute = set_attribute
+nodes.getattribute = has_attribute
+nodes.unsetattribute = unset_attribute
+nodes.setattributes = set_attributes
+nodes.setunsetattributes = set_unset_attributes
+nodes.unsetattributes = unset_attributes
-nodes.set_attributes = set_attributes
-nodes.set_unset_attributes = set_unset_attributes
-nodes.unset_attributes = unset_attributes
-
-nodes.setattribute = set_attribute
-nodes.unsetattribute = unset_attribute
-nodes.hasattribute = has_attribute
-
-nodes.setattributes = set_attributes
-nodes.setunsetattributes = set_unset_attributes
-nodes.unsetattributes = unset_attributes
+nodes.has_attribute = has_attribute
-- function nodes.is_skipable(a,id) -- skipable nodes at the margins during character protrusion
-- return (
diff --git a/tex/context/base/node-fnt.lua b/tex/context/base/node-fnt.lua
index 77aa79396..7ceb96f80 100644
--- a/tex/context/base/node-fnt.lua
+++ b/tex/context/base/node-fnt.lua
@@ -11,26 +11,28 @@ if not context then os.exit() end -- generic function in node-dum
local next, type = next, type
local concat = table.concat
-local trace_characters = false trackers.register("nodes.characters", function(v) trace_characters = v end)
-local trace_fontrun = false trackers.register("nodes.fontrun", function(v) trace_fontrun = v end)
+local nodes, node, fonts = nodes, node, fonts
-local report_fonts = logs.reporter("fonts","processing")
+local trace_characters = false trackers.register("nodes.characters", function(v) trace_characters = v end)
+local trace_fontrun = false trackers.register("nodes.fontrun", function(v) trace_fontrun = v end)
-local nodes, node, fonts = nodes, node, fonts
+local report_fonts = logs.reporter("fonts","processing")
+
+local fonthashes = fonts.hashes
+local fontdata = fonthashes.identifiers
-local fonthashes = fonts.hashes
-local fontdata = fonthashes.identifiers
+local otf = fonts.handlers.otf
-local otf = fonts.handlers.otf
+local traverse_id = node.traverse_id
+local has_attribute = node.has_attribute
+local starttiming = statistics.starttiming
+local stoptiming = statistics.stoptiming
+local nodecodes = nodes.nodecodes
+local handlers = nodes.handlers
-local traverse_id = node.traverse_id
-local has_attribute = node.has_attribute
-local starttiming = statistics.starttiming
-local stoptiming = statistics.stoptiming
-local nodecodes = nodes.nodecodes
-local handlers = nodes.handlers
+local glyph_code = nodecodes.glyph
-local glyph_code = nodecodes.glyph
+local setmetatableindex = table.setmetatableindex
-- some tests with using an array of dynamics[id] and processes[id] demonstrated
-- that there was nothing to gain (unless we also optimize other parts)
@@ -47,30 +49,26 @@ local run = 0
local setfontdynamics = { }
local fontprocesses = { }
-setmetatable(setfontdynamics, { __index =
- function(t,font)
- local tfmdata = fontdata[font]
- local shared = tfmdata.shared
- local v = shared and shared.dynamics and otf.setdynamics or false
- t[font] = v
- return v
- end
-})
-
-setmetatable(fontprocesses, { __index =
- function(t,font)
- local tfmdata = fontdata[font]
- local shared = tfmdata.shared -- we need to check shared, only when same features
- local processes = shared and shared.processes
- if processes and #processes > 0 then
- t[font] = processes
- return processes
- else
- t[font] = false
- return false
- end
+setmetatableindex(setfontdynamics, function(t,font)
+ local tfmdata = fontdata[font]
+ local shared = tfmdata.shared
+ local v = shared and shared.dynamics and otf.setdynamics or false
+ t[font] = v
+ return v
+end)
+
+setmetatableindex(fontprocesses, function(t,font)
+ local tfmdata = fontdata[font]
+ local shared = tfmdata.shared -- we need to check shared, only when same features
+ local processes = shared and shared.processes
+ if processes and #processes > 0 then
+ t[font] = processes
+ return processes
+ else
+ t[font] = false
+ return false
end
-})
+end)
fonts.hashes.setdynamics = setfontdynamics
fonts.hashes.processes = fontprocesses
diff --git a/tex/context/base/node-ref.lua b/tex/context/base/node-ref.lua
index fbf528629..19d602ed6 100644
--- a/tex/context/base/node-ref.lua
+++ b/tex/context/base/node-ref.lua
@@ -436,7 +436,7 @@ function nodes.references.handler(head)
end
end
--- destinations (we can clean up once set!)
+-- destinations (we can clean up once set, unless tagging!)
local stack = { }
local done = { }
diff --git a/tex/context/base/node-spl.lua b/tex/context/base/node-spl.lua
index ddb4a26a8..0fe3f759d 100644
--- a/tex/context/base/node-spl.lua
+++ b/tex/context/base/node-spl.lua
@@ -53,7 +53,7 @@ local protect_glyphs = nodes.handlers.protectglyphs or node.protect_glyphs
local hpack_nodes = node.hpack
local insert_node_before = node.insert_before
local insert_node_after = node.insert_after
-local repack_hlist = nodes.repack_hlist
+local repack_hlist = nodes.repackhlist
local setnodecolor = nodes.tracers.colors.set
diff --git a/tex/context/base/pack-obj.lua b/tex/context/base/pack-obj.lua
index 088ad6add..2dabfa784 100644
--- a/tex/context/base/pack-obj.lua
+++ b/tex/context/base/pack-obj.lua
@@ -12,9 +12,10 @@ reusable components.
--ldx]]--
local texsprint, texcount = tex.sprint, tex.count
-local allocate, mark = utilities.storage.allocate, utilities.storage.mark
+local allocate = utilities.storage.allocate
-local collected, tobesaved = allocate(), allocate()
+local collected = allocate()
+local tobesaved = allocate()
local jobobjects = {
collected = collected,
@@ -24,8 +25,8 @@ local jobobjects = {
job.objects = jobobjects
local function initializer()
- collected = mark(jobobjects.collected)
- tobesaved = mark(jobobjects.tobesaved)
+ collected = jobobjects.collected
+ tobesaved = jobobjects.tobesaved
end
job.register('job.objects.collected', tobesaved, initializer, nil)
diff --git a/tex/context/base/regi-ini.lua b/tex/context/base/regi-ini.lua
index fbbfda75a..a440b6577 100644
--- a/tex/context/base/regi-ini.lua
+++ b/tex/context/base/regi-ini.lua
@@ -14,11 +14,12 @@ runtime.
local utfchar = utf.char
local char, gsub, format = string.char, string.gsub, string.format
-local next, setmetatable = next, setmetatable
+local next = next
local insert, remove = table.insert, table.remove
-local sequencers = utilities.sequencers
-local textlineactions = resolvers.openers.helpers.textlineactions
+local sequencers = utilities.sequencers
+local textlineactions = resolvers.openers.helpers.textlineactions
+local setmetatableindex = table.setmetatableindex
--[[ldx--
We will hook regime handling code into the input methods.
@@ -108,7 +109,7 @@ local function loadregime(mapping,regime)
return vector
end
-setmetatable(mapping, { __index = loadregime })
+setmetatableindex(mapping, loadregime)
local function translate(line,regime)
if line and #line > 0 then
diff --git a/tex/context/base/s-inf-03.mkiv b/tex/context/base/s-inf-03.mkiv
new file mode 100644
index 000000000..bfcf5650b
--- /dev/null
+++ b/tex/context/base/s-inf-03.mkiv
@@ -0,0 +1,352 @@
+% \nopdfcompression
+
+% \enablemode[ipad]
+
+\doifmodeelse {ipad} {
+
+ \setuppapersize
+ [S6,landscape]
+ [S6,landscape]
+
+ \definefont
+ [TitlePageFont]
+ [MonoBold at 20pt]
+
+} {
+
+ \definefont
+ [TitlePageFont]
+ [MonoBold at 26pt]
+
+}
+
+\setuplayout
+ [header=0cm,
+ footer=1cm,
+ backspace=.5cm,
+ topspace=.5cm,
+ width=middle,
+ height=middle]
+
+\setuphead
+ [title]
+ [style=\ttc,
+ interaction=reference]
+
+\definehead
+ [xtitle]
+ [title]
+
+\setuphead
+ [xtitle]
+ [color=darkgreen]
+
+\setupbodyfont
+ [tt]
+
+\setupfootertexts
+ [\llap{\goto{\hbox to 5cm{\hss previous}}[previouspage]}%
+ \quad\pagenumber\quad
+ \rlap{\goto{\hbox to 5cm{next\hss}}[nextpage]}]
+
+\setupinteraction
+ [state=start,
+ style=,
+ color=,
+ title={ConTeXt MkIV},
+ subtitle={Lua modules and functions},
+ author={Hans Hagen - automatically generated},
+ contrastcolor=]
+
+\setupinteractionscreen
+ [option=bookmark]
+
+\placebookmarks
+ [title,xtitle]
+ [force=yes]
+
+\definecolor[darkyellow][r=.5,g=.5,b=0]
+\definecolor[darkgray] [s=.15]
+
+\nonknuthmode
+
+\starttext
+
+\startbuffer
+\startluacode
+local basiclua = libraries.basiclua
+local basictex = libraries.basictex
+local extratex = libraries.extratex
+local extralua = libraries.extralua
+local obsolete = libraries.obsolete
+
+local find = string.find
+local color, goto = context.color, context.goto
+
+for k, v in table.sortedpairs(_G) do
+ if obsolete[k] or find(k,"_") or k == "arg" or k == "utf" then
+ --
+ elseif basiclua[k] then
+ goto(function() color( { "darkred" }, k) end, { k } )
+ elseif extralua[k] then
+ goto(function() color( { "darkgreen" }, k) end, { k } )
+ elseif basictex[k] then
+ goto(function() color( { "darkblue" }, k) end, { k } )
+ elseif extratex[k] then
+ goto(function() color( { "darkyellow" }, k) end, { k } )
+ elseif type(v) == "table" then
+ goto(function() color( { "white" }, k) end, { k } )
+ end
+ context(" ")
+end
+\stopluacode
+\stopbuffer
+
+\setupbackgrounds
+ [page]
+ [background=color,
+ backgroundcolor=darkgray,
+ backgroundoffset=2mm]
+
+\setuplayout
+ [page]
+
+\startstandardmakeup
+ \vfill
+ \startnarrower[5mm]
+ \raggedcenter
+ \TitlePageFont \setupinterlinespace
+ \getbuffer
+ \par
+ \stopnarrower
+ \vfill
+ \vfill
+ \hskip10mm\scale[width=\dimexpr\paperwidth-20mm\relax]{\ttbf\white\ConTeXt\ MkIV}
+ \par
+ % \hskip10mm\scale[width=\dimexpr\paperwidth-20mm\relax]{\white \strut Lua infrastructure \emdash\ \currentdate}
+ \vfill
+\stopstandardmakeup
+
+\setuplayout
+
+\setupbackgrounds
+ [page]
+ [background=]
+
+\startluacode
+local builtin = libraries.builtin
+local globals = libraries.globals
+local basiclua = libraries.basiclua
+local basictex = libraries.basictex
+local extratex = libraries.extratex
+local extralua = libraries.extralua
+local obsolete = libraries.obsolete
+
+local sortedkeys = table.sortedkeys
+local mark = storage.mark
+local marked = storage.marked
+local gsub = string.gsub
+local sub = string.sub
+local byte = string.byte
+local upper = string.upper
+
+local skipglobal = table.tohash {
+ "_G", "context", "modules", "global", "arg", "utf", 1,
+ "_ptbs_", "_pcol_", "_plib_", "_clib_", "_tlib_",
+ "_M", "kpse",
+}
+
+local skipkeys = table.tohash {
+ "_pcol_", "_plib_", "_clib_", "_tlib_", "_bpnf_", "_ptbs_",
+ "_cldf_", "_cldn_",
+ "_clmb_", "_clme_", "_clmm_", "_clmn_", "_clma_", "_clmh_",
+ "_G", "_M", "_VERSION", "_COPYRIGHT", "_DESCRIPTION", "_NAME", "_PACKAGE", "__unload",
+}
+
+local sameglobal = {
+ ["global"] = "_G",
+ -- ["commands"] = "cs", -- already gone
+}
+
+-- -- -- -- -- -- -- -- -- -- -- -- --
+-- this should be done internally
+-- -- -- -- -- -- -- -- -- -- -- -- --
+
+for k,v in next, modules do
+ mark(v)
+end
+
+mark(document.arguments)
+mark(environment.arguments)
+mark(environment.engineflags)
+mark(characters.data)
+
+-- -- -- -- -- -- -- -- -- -- -- -- --
+-- -- -- -- -- -- -- -- -- -- -- -- --
+
+local variant = 1 -- all parents
+local variant = 2 -- parent name too
+local variant = 3 -- no parents
+
+local function childtables(key,tab,handler,depth)
+ depth = depth or 1
+ local keys = sortedkeys(tab) -- no sorted_pairs
+ for i=1,#keys do
+ local k = keys[i]
+-- if k ~= "_G" and k ~= "_M" and type(k) == "string" then
+ if not skipkeys[k] and type(k) == "string" then
+ local v = tab[k]
+ local t = type(v)
+ local s = k
+ if variant ~= 3 then
+ s = key and (key .. "." .. s) or s
+ end
+ if t == "table" then
+ if marked(v) then
+ t = "data"
+ handler(s,t,depth)
+ else
+ handler(s,t,depth)
+ if variant == 3 then
+ childtables(false,v,handler,depth+1)
+ elseif variant == 2 then
+ childtables(k,v,handler,depth+1)
+ else
+ childtables(s,v,handler,depth+1)
+ end
+ end
+ else
+ handler(s,t,depth)
+ end
+ end
+ end
+end
+
+local NC, NR = context.NC, context.NR
+local overstrike, rlap, bf = context.overstrike, context.rlap, context.bf
+local color, goto = context.color, context.goto
+
+local function cleanup(s)
+ return "\\char" ..byte(s) .. " "
+end
+
+local function handler(k,t,depth)
+ k = gsub(k,"([~#$%%^&{}\\\|])",cleanup)
+-- NC() rlap("\\quad\\tx " .. upper(sub(t,1,1)) .. " ".. k) NC() NC() NR()
+ NC() rlap("\\quad\\tx\\kern" .. (depth or 0).. "em" .. upper(sub(t,1,1)) .. " ".. k) NC() NC() NR()
+end
+
+local function show(title,subtitle,alias,builtin,t,lib,libcolor,glo,glocolor,mark,obsolete)
+ -- todo: table as argument
+ local keys = sortedkeys(t) -- no sorted_pairs
+ if #keys > 0 then
+ local fulltitle = title
+ if subtitle and subtitle ~= "" then
+ fulltitle = fulltitle .. " (" .. subtitle .. ")"
+ end
+ if alias and alias ~= "" then
+ fulltitle = fulltitle .. " (alias: " .. alias .. ")"
+ end
+ if builtin then
+ context.startxtitle { reference = title, title = fulltitle, backreference = "global" }
+ else
+ context.starttitle { reference = title, title = fulltitle, backreference = "global" }
+ end
+ context.startcolumns { n = 2 }
+ context.starttabulate { "|||" }
+ local t_obsolete = t.obsolete
+ if type(t_obsolete) ~= "table" then
+ t_obsolete = nil
+ end
+ for i=1,#keys do
+ local k = keys[i]
+ local v = t[k]
+ if k ~= "obsolete" and not skipkeys[k] and (not obsolete or not obsolete[k]) then
+ local inlib = lib and lib[k]
+ local inglo = glo and glo[k]
+ if k then
+ local t = type(v)
+ local kstr, tstr = k, t
+ local obs = t_obsolete and t_obsolete[k]
+ if obs then
+ tstr = function() overstrike(t) end
+ kstr = function() overstrike(k) end
+ end
+ local marked = marked(v)
+ if marked then
+ tstr = "data table"
+ end
+ if t == "table" then
+ local m = getmetatable(v)
+ if m and m.__call then
+ tstr = "function"
+ end
+ end
+ if not mark then
+ --
+ elseif inlib and tostring(inlib) ~= tostring(v) then
+ tstr = "overloaded ".. tstr
+ elseif inglo and tostring(inglo) ~= tostring(v) then
+ tstr = "overloaded ".. tstr
+ end
+ NC() bf()
+ if inlib then
+ if not mark and t == "table" then
+ goto(function() color( { libcolor }, kstr) end, { k } )
+ else
+ color( { libcolor }, kstr)
+ end
+ elseif inglo then
+ if not mark and t == "table" then
+ goto(function() color( { glocolor }, kstr) end, { k } )
+ else
+ color( { glocolor }, kstr)
+ end
+ else
+ if not mark and t == "table" then
+ goto(k, { kstr } )
+ else
+ context(kstr)
+ end
+ end
+ NC()
+ if inlib then
+ color( { libcolor }, tstr)
+ elseif inglo then
+ color( { glocolor }, tstr)
+ else
+ context(tstr)
+ end
+ NC() NR()
+ if mark and t == "table" and title ~= "libraries" and title ~= "package" and not marked then
+ childtables(false,v,handler) -- (k,v,handler)
+ end
+ end
+ end
+ end
+ context.stoptabulate()
+ context.stopcolumns()
+ if builtin then
+ context.stopxtitle()
+ else
+ context.stoptitle()
+ end
+ end
+end
+
+show("global","",sameglobal.global,false,_G,builtin,"darkgreen",globals,"darkblue",false,obsolete)
+
+for k, v in table.sortedpairs(_G) do
+ if not skipglobal[k] and not obsolete[k] and type(v) == "table" and not marked(v) then
+ if basiclua[k] then show(k,"basic lua",sameglobal[k],basiclua[k],v,builtin[k],"darkred", false,false,true)
+ elseif extralua[k] then show(k,"extra lua",sameglobal[k],extralua[k],v,builtin[k],"darkred", false,false,true)
+ elseif basictex[k] then show(k,"basic tex",sameglobal[k],basictex[k],v,builtin[k],"darkred", false,false,true)
+ elseif extratex[k] then show(k,"extra tex",sameglobal[k],extratex[k],v,builtin[k],"darkred", false,false,true)
+ else show(k,"context", sameglobal[k],false, v,builtin[k],"darkyellow",false,false,true)
+ end
+ end
+end
+
+\stopluacode
+
+\stoptext
diff --git a/tex/context/base/scrn-ini.lua b/tex/context/base/scrn-ini.lua
index 76696eed0..2836362df 100644
--- a/tex/context/base/scrn-ini.lua
+++ b/tex/context/base/scrn-ini.lua
@@ -12,10 +12,19 @@ local general = interactions.general
local codeinjections = backends.codeinjections
+local identitydata = { }
+
local function setupidentity(specification)
+ for k, v in next, specification do
+ identitydata[k] = v
+ end
codeinjections.setupidentity(specification)
end
+function general.getidentity()
+ return identitydata
+end
+
general.setupidentity = setupidentity
commands.setupidentity = setupidentity
diff --git a/tex/context/base/sort-ini.lua b/tex/context/base/sort-ini.lua
index 3ff6f1d96..4462ddb9c 100644
--- a/tex/context/base/sort-ini.lua
+++ b/tex/context/base/sort-ini.lua
@@ -50,12 +50,13 @@ local utfbyte, utfchar = utf.byte, utf.char
local utfcharacters = string.utfcharacters
local next, type, tonumber, rawget, rawset = next, type, tonumber, rawget, rawset
-local allocate = utilities.storage.allocate
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
-local trace_tests = false trackers.register("sorters.tests", function(v) trace_tests = v end)
-local trace_methods = false trackers.register("sorters.methods", function(v) trace_methods = v end)
+local trace_tests = false trackers.register("sorters.tests", function(v) trace_tests = v end)
+local trace_methods = false trackers.register("sorters.methods", function(v) trace_methods = v end)
-local report_sorters = logs.reporter("languages","sorters")
+local report_sorters = logs.reporter("languages","sorters")
local comparers = { }
local splitters = { }
@@ -278,7 +279,7 @@ local function update() -- prepare parent chains, needed when new languages are
for language, data in next, definitions do
local parent = data.parent or "default"
if language ~= "default" then
- setmetatable(data,{ __index = definitions[parent] or definitions.default })
+ setmetatableindex(data,definitions[parent] or definitions.default)
end
data.language = language
data.parent = parent
diff --git a/tex/context/base/sort-lan.lua b/tex/context/base/sort-lan.lua
index 7bfa0d86b..e7556c1de 100644
--- a/tex/context/base/sort-lan.lua
+++ b/tex/context/base/sort-lan.lua
@@ -862,7 +862,7 @@ definitions["et"] = {
local fschars = characters.fschars
-function firstofsplit(first)
+local function firstofsplit(first)
local fs = fschars[first] or first
-- print(string.format("%04x %04x",utfbyte(first),utfbyte(fs)))
return fs, fs -- entry, tag
diff --git a/tex/context/base/spac-ali.mkiv b/tex/context/base/spac-ali.mkiv
index 297302808..cccfe181a 100644
--- a/tex/context/base/spac-ali.mkiv
+++ b/tex/context/base/spac-ali.mkiv
@@ -473,8 +473,8 @@
\def\setraggedparagraphmode
{\doifrightpageelse
- {\ifdoublesided\signalinnerrealign\firstoftwoarguments \fi}
- {\ifdoublesided\signalouterrealign\secondoftwoarguments\fi}}
+ {\ifdoublesided\signalinnerrealign\expandafter\firstoftwoarguments \fi}
+ {\ifdoublesided\signalouterrealign\expandafter\secondoftwoarguments\fi}}
\def\installalign#1#2{\setvalue{@@align@@#1}{#2}} % can be used for overloads
diff --git a/tex/context/base/spac-grd.mkiv b/tex/context/base/spac-grd.mkiv
index 91fcf3207..8701f4d7e 100644
--- a/tex/context/base/spac-grd.mkiv
+++ b/tex/context/base/spac-grd.mkiv
@@ -267,12 +267,19 @@
\def\donegtopbaselinecorrection{\blank[\thenegtopbaselinecorrection]}
\def\donegbotbaselinecorrection{\blank[\thenegbotbaselinecorrection]}
+% nointerlineskip
+%
+% startpacked
+% \startlinecorrection \framed{test} \stoplinecorrection
+% \startlinecorrection \framed{test} \stoplinecorrection
+% \stoppacked
+
\def\forcedtopbaselinecorrection
{\ifvmode
\bgroup
\setbaselinecorrections
\vspacing[white]
- \nointerlineskip
+% \nointerlineskip %
\dotopbaselinecorrection
\egroup
\fi}
diff --git a/tex/context/base/spac-ver.mkiv b/tex/context/base/spac-ver.mkiv
index 220e1c15c..de16fa286 100644
--- a/tex/context/base/spac-ver.mkiv
+++ b/tex/context/base/spac-ver.mkiv
@@ -457,9 +457,6 @@
% laatste skip over de lege tekst heen gehaald. Dit komt goed
% van pas bij het plaatsen van (mogelijk lege) lijsten.
-\newsignal \noparskipsignal % \def\noparskipsignal {0.00001pt}
-\def\lastdoneparskip {0pt}
-
\newconditional\noblankinpacked
\newcount\packeddepth
diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf
index 277169501..d15ff4264 100644
Binary files a/tex/context/base/status-files.pdf and b/tex/context/base/status-files.pdf differ
diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf
new file mode 100644
index 000000000..5e11911be
Binary files /dev/null and b/tex/context/base/status-lua.pdf differ
diff --git a/tex/context/base/strc-blk.lua b/tex/context/base/strc-blk.lua
index 0c94af5bb..cbdc8c6ea 100644
--- a/tex/context/base/strc-blk.lua
+++ b/tex/context/base/strc-blk.lua
@@ -18,19 +18,21 @@ local structures, context = structures, context
structures.blocks = structures.blocks or { }
-local blocks = structures.blocks
-local sections = structures.sections
-local lists = structures.lists
+local blocks = structures.blocks
+local sections = structures.sections
+local lists = structures.lists
-local collected, tobesaved, states = allocate(), allocate(), allocate()
+local collected = allocate()
+local tobesaved = allocate()
+local states = allocate()
-blocks.collected = collected
-blocks.tobesaved = tobesaved
-blocks.states = states
+blocks.collected = collected
+blocks.tobesaved = tobesaved
+blocks.states = states
local function initializer()
- collected = mark(blocks.collected)
- tobesaved = mark(blocks.tobesaved)
+ collected = blocks.collected
+ tobesaved = blocks.tobesaved
end
job.register('structures.blocks.collected', tobesaved, initializer)
diff --git a/tex/context/base/strc-doc.lua b/tex/context/base/strc-doc.lua
index 40b01fcbe..d50d49b92 100644
--- a/tex/context/base/strc-doc.lua
+++ b/tex/context/base/strc-doc.lua
@@ -41,6 +41,8 @@ local processors = structures.processors
local sprintprocessor = processors.sprint
local ignoreprocessor = processors.ignore
+local a_internal = attributes.private('internal')
+
-- -- -- document -- -- --
local data
@@ -73,14 +75,15 @@ documents.initialize()
-- -- -- sections -- -- --
-local collected, tobesaved = allocate(), allocate()
+local collected = allocate()
+local tobesaved = allocate()
sections.collected = collected
sections.tobesaved = tobesaved
--~ local function initializer()
---~ collected = mark(sections.collected)
---~ tobesaved = mark(sections.tobesaved)
+--~ collected = sections.collected
+--~ tobesaved = sections.tobesaved
--~ end
--~ job.register('structures.sections.collected', tobesaved, initializer)
@@ -316,9 +319,12 @@ function sections.somelevel(given)
report_structure("name '%s', numbers '%s', own numbers '%s'",givenname,concat(numberdata.numbers, " "),concat(numberdata.ownnumbers, " "))
end
- given.references.tag = tags.last and tags.last("section") -- (metadata.kind) sort of forward usage (section -> structure)
+ local metadata = given.metadata
+ local references = given.references
+
+ references.tag = references.tag or tags.getid(metadata.kind,metadata.name)
- given.references.section = sections.save(given)
+ references.section = sections.save(given)
-- given.numberdata = nil
end
diff --git a/tex/context/base/strc-ini.lua b/tex/context/base/strc-ini.lua
index d213c925e..a9013c641 100644
--- a/tex/context/base/strc-ini.lua
+++ b/tex/context/base/strc-ini.lua
@@ -25,7 +25,7 @@ local count, texwrite, texprint, texsprint = tex.count, tex.write, tex.print, te
local type, next, tonumber, tostring = type, next, tonumber, tostring
local lpegmatch = lpeg.match
local settings_to_array, settings_to_hash = utilities.parsers.settings_to_array, utilities.parsers.settings_to_hash
-local allocate, mark = utilities.storage.allocate, utilities.storage.mark
+local allocate = utilities.storage.allocate
local ctxcatcodes, xmlcatcodes, notcatcodes = tex.ctxcatcodes, tex.xmlcatcodes, tex.notcatcodes -- tricky as we're in notcatcodes
@@ -81,14 +81,15 @@ structures.synonyms = structures.synonyms or { }
local specials = structures.specials
-local collected, tobesaved = allocate(), allocate()
+local collected = allocate()
+local tobesaved = allocate()
specials.collected = collected
specials.tobesaved = tobesaved
local function initializer()
- collected = mark(specials.collected)
- tobesaved = mark(specials.tobesaved)
+ collected = specials.collected
+ tobesaved = specials.tobesaved
end
if job then
diff --git a/tex/context/base/strc-lst.lua b/tex/context/base/strc-lst.lua
index f09444f26..6a7a7d8c7 100644
--- a/tex/context/base/strc-lst.lua
+++ b/tex/context/base/strc-lst.lua
@@ -17,7 +17,7 @@ local texsprint, texprint, texwrite, texcount = tex.sprint, tex.print, tex.write
local concat, insert, remove = table.concat, table.insert, table.remove
local lpegmatch = lpeg.match
local simple_hash_to_string, settings_to_hash = utilities.parsers.simple_hash_to_string, utilities.parsers.settings_to_hash
-local allocate, mark, checked = utilities.storage.allocate, utilities.storage.mark, utilities.storage.checked
+local allocate, checked = utilities.storage.allocate, utilities.storage.checked
local trace_lists = false trackers.register("structures.lists", function(v) trace_lists = v end)
@@ -75,7 +75,7 @@ end
local function initializer()
-- create a cross reference between internal references
-- and list entries
- local collected = mark(lists.collected)
+ local collected = lists.collected
local internals = checked(references.internals)
local ordered = lists.ordered
for i=1,#collected do
@@ -110,14 +110,12 @@ end
job.register('structures.lists.collected', tobesaved, initializer)
function lists.push(t)
+ local m = t.metadata
local r = t.references
local i = (r and r.internal) or 0 -- brrr
local p = pushed[i]
if not p then
p = #cached + 1
- if r.tag == nil then
- r.tag = tags.last and tags.last(t.metadata.kind) -- maybe kind but then also check elsewhere
- end
cached[p] = helpers.simplify(t)
pushed[i] = p
end
@@ -134,14 +132,21 @@ function lists.enhance(n)
-- todo: symbolic names for counters
local l = cached[n]
if l then
+ local metadata = l.metadata
+ local references = l.references
--
l.directives = nil -- might change
-- save in the right order (happens at shipout)
lists.tobesaved[#lists.tobesaved+1] = l
-- default enhancer (cross referencing)
- l.references.realpage = texcount.realpageno
+ references.realpage = texcount.realpageno
+ -- tags
+ local kind = metadata.kind
+ local name = metadata.name
+ if references then
+ references.tag = tags.getid(kind,name)
+ end
-- specific enhancer (kind of obsolete)
- local kind = l.metadata.kind
local enhancer = kind and lists.enhancers[kind]
if enhancer then
enhancer(l)
diff --git a/tex/context/base/strc-lst.mkiv b/tex/context/base/strc-lst.mkiv
index b14297e26..c764b889b 100644
--- a/tex/context/base/strc-lst.mkiv
+++ b/tex/context/base/strc-lst.mkiv
@@ -141,7 +141,7 @@
{\ctxlua{structures.lists.realpage("\currentlist",\currentlistindex)}}
\def\structurelistfirst
- {\dostarttagged\t!listdata{first} % ot always ok
+ {\dostarttagged\t!listdata{first}% not always ok
\ctxlua{structures.lists.userdata("\currentlist",\currentlistindex,"first")}%
\dostoptagged}
@@ -499,7 +499,7 @@
\unexpanded\def\listsymbol[#1]#2%
{\begingroup
\edef\currentlist{#1}%
- \edef\currentlistnumber{#2}%
+ \def\currentlistnumber{#2}% no edef else tag problems
\currentlistsymbol
\endgroup}
@@ -633,7 +633,7 @@
\def\dodolistelement#1#2#3#4#5#6%
{\edef\currentlist{#1}%
- \edef\currentlistnumber{#3}%
+ \def\currentlistnumber{#3}% no edef else tag problem
\docurrentlistalternative
\letinteractionparameter\c!width\zeropoint
\dontcomplain
@@ -999,7 +999,7 @@
\ctxlua{structures.lists.title("\currentlist",\currentlistindex)}%
\dostoptagged}
-\def\structurelistgenericnumber
+\def\structurelistgenericnumber % tricky, we need to delay tagging as we have nested lua calls
{\dostarttagged\t!listtag\empty
\ctxlua{structures.lists.prefixednumber("\currentlist",\currentlistindex, {
prefix = "\listparameter\c!prefix",
diff --git a/tex/context/base/strc-mar.lua b/tex/context/base/strc-mar.lua
index 983ffe97e..5bb40fa94 100644
--- a/tex/context/base/strc-mar.lua
+++ b/tex/context/base/strc-mar.lua
@@ -9,15 +9,18 @@ if not modules then modules = { } end modules ['strc-mar'] = {
-- todo: cleanup stack (structures.marks.reset(v_all) also does the job)
local insert, concat = table.insert, table.concat
-local tostring, next, setmetatable, rawget = tostring, next, setmetatable, rawget
+local tostring, next, rawget = tostring, next, rawget
local lpegmatch = lpeg.match
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
+
local nodecodes = nodes.nodecodes
local glyph_code = nodecodes.glyph
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
-local hasattribute = nodes.hasattribute
+local getattribute = nodes.getattribute
local traversenodes = node.traverse
local texsetattribute = tex.setattribute
local texbox = tex.box
@@ -58,7 +61,7 @@ local lists = structures.lists
local settings_to_array = utilities.parsers.settings_to_array
-marks.data = marks.data or { }
+marks.data = marks.data or allocate()
storage.register("structures/marks/data", marks.data, "structures.marks.data")
@@ -85,7 +88,7 @@ local function resolve(t,k)
end
end
-setmetatable(data, { __index = resolve} )
+setmetatableindex(data, resolve)
function marks.exists(name)
return rawget(data,name) ~= nil
@@ -97,7 +100,7 @@ local function sweep(head,first,last)
for n in traversenodes(head) do
local id = n.id
if id == glyph_code then
- local a = hasattribute(n,a_marks)
+ local a = getattribute(n,a_marks)
if not a then
-- next
elseif first == 0 then
@@ -106,7 +109,7 @@ local function sweep(head,first,last)
last = a
end
elseif id == hlist_code or id == vlist_code then
- local a = hasattribute(n,a_marks)
+ local a = getattribute(n,a_marks)
if not a then
-- next
elseif first == 0 then
@@ -125,7 +128,7 @@ end
local classes = { }
-setmetatable(classes, { __index = function(t,k) local s = settings_to_array(k) t[k] = s return s end } )
+setmetatableindex(classes, function(t,k) local s = settings_to_array(k) t[k] = s return s end)
function marks.synchronize(class,n)
local box = texbox[n]
@@ -187,11 +190,11 @@ function marks.define(name,settings)
settings.parent = dp.parent
end
end
- setmetatable(settings, { __index = resolve } )
+ setmetatableindex(settings, resolve)
end
for k, v in next, data do
- setmetatable(v, { __index = resolve } ) -- runtime loaded table
+ setmetatableindex(v,resolve) -- runtime loaded table
end
local function parentname(name)
diff --git a/tex/context/base/strc-num.lua b/tex/context/base/strc-num.lua
index b8a62d152..95cf6d941 100644
--- a/tex/context/base/strc-num.lua
+++ b/tex/context/base/strc-num.lua
@@ -12,25 +12,25 @@ local format = string.format
local next, type = next, type
local min, max = math.min, math.max
local texsprint, texcount = tex.sprint, tex.count
-local allocate, mark = utilities.storage.allocate, utilities.storage.mark
-local trace_counters = false trackers.register("structures.counters", function(v) trace_counters = v end)
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
-local report_counters = logs.reporter("structure","counters")
+local trace_counters = false trackers.register("structures.counters", function(v) trace_counters = v end)
+local report_counters = logs.reporter("structure","counters")
-local structures = structures
+local structures = structures
+local helpers = structures.helpers
+local sections = structures.sections
+local counters = structures.counters
+local documents = structures.documents
-local helpers = structures.helpers
-local sections = structures.sections
-local counters = structures.counters
-local documents = structures.documents
-
-local variables = interfaces.variables
+local variables = interfaces.variables
-- state: start stop none reset
-counters.specials = counters.specials or { }
-local counterspecials = counters.specials
+counters.specials = counters.specials or { }
+local counterspecials = counters.specials
local counterranges, tbs = { }, 0
@@ -113,7 +113,7 @@ local function enhance()
local data = cd.data
for i=1,#data do
local ci = data[i]
- setmetatable(ci, { __index = function(t,s) return constructor(t,s,name,i) end })
+ setmetatableindex(ci, function(t,s) return constructor(t,s,name,i) end)
end
end
enhance = nil
@@ -145,7 +145,7 @@ local function allocate(name,i) -- can be metatable
offset = false,
stop = 0, -- via metatable: last, first, stop only for tracing
}
- setmetatable(ci, { __index = function(t,s) return constructor(t,s,name,i) end })
+ setmetatableindex(ci, function(t,s) return constructor(t,s,name,i) end)
cd[i] = ci
tobesaved[name][i] = { }
else
diff --git a/tex/context/base/strc-pag.lua b/tex/context/base/strc-pag.lua
index b899b924b..bce8a2c3a 100644
--- a/tex/context/base/strc-pag.lua
+++ b/tex/context/base/strc-pag.lua
@@ -37,8 +37,8 @@ pages.collected = collected
pages.tobesaved = tobesaved
local function initializer()
- collected = mark(pages.collected)
- tobesaved = mark(pages.tobesaved)
+ collected = pages.collected
+ tobesaved = pages.tobesaved
end
job.register('structures.pages.collected', tobesaved, initializer)
diff --git a/tex/context/base/strc-ref.lua b/tex/context/base/strc-ref.lua
index 3379bbbdb..ee32353f0 100644
--- a/tex/context/base/strc-ref.lua
+++ b/tex/context/base/strc-ref.lua
@@ -9,10 +9,11 @@ if not modules then modules = { } end modules ['strc-ref'] = {
local format, find, gmatch, match, concat = string.format, string.find, string.gmatch, string.match, table.concat
local lpegmatch, lpegP, lpegCs = lpeg.match, lpeg.P, lpeg.Cs
local texcount, texsetcount = tex.count, tex.setcount
-local allocate, mark = utilities.storage.allocate, utilities.storage.mark
-local setmetatable, rawget = setmetatable, rawget
+local rawget = rawget
-local allocate = utilities.storage.allocate
+local allocate = utilities.storage.allocate
+local mark = utilities.storage.mark
+local setmetatableindex = table.setmetatableindex
local trace_referencing = false trackers.register("structures.referencing", function(v) trace_referencing = v end)
@@ -44,8 +45,8 @@ references.defined = references.defined or allocate()
local defined = references.defined
local derived = allocate()
-local specials = { } -- allocate()
-local runners = { } -- allocate()
+local specials = allocate()
+local runners = allocate()
local internals = allocate()
local exporters = allocate()
local imported = allocate()
@@ -86,15 +87,14 @@ function references.registerfinalizer(func) -- we could use a token register ins
end
local function initializer() -- can we use a tobesaved as metatable for collected?
- tobesaved = mark(references.tobesaved)
- collected = mark(references.collected)
+ tobesaved = references.tobesaved
+ collected = references.collected
for i=1,#initializers do
initializers[i](tobesaved,collected)
end
end
local function finalizer()
- -- tobesaved = mark(references.tobesaved)
for i=1,#finalizers do
finalizers[i](tobesaved)
end
@@ -105,10 +105,9 @@ job.register('structures.references.collected', tobesaved, initializer, finalize
local maxreferred = 1
local function initializer() -- can we use a tobesaved as metatable for collected?
- tobereferred = mark(references.tobereferred)
- referred = mark(references.referred)
-
- function get(t,n) -- catch sparse, a bit slow but who cares
+ tobereferred = references.tobereferred
+ referred = references.referred
+ local function get(t,n) -- catch sparse, a bit slow but who cares
for i=n,1,-1 do -- we could make a tree ... too much work
local p = rawget(t,i)
if p then
@@ -116,7 +115,7 @@ local function initializer() -- can we use a tobesaved as metatable for collecte
end
end
end
- setmetatable(referred, { __index = get })
+ setmetatableindex(referred, get)
end
local function finalizer() -- make sparse
@@ -133,6 +132,8 @@ local function finalizer() -- make sparse
end
end
+job.register('structures.references.referred', tobereferred, initializer, finalizer)
+
function references.referredpage(n)
return referred[n] or referred[n] or texcount.realpageno
end
@@ -146,8 +147,6 @@ function references.registerpage(n)
end
end
-job.register('structures.references.referred', tobereferred, initializer, finalizer)
-
-- todo: delay split till later as in destinations we split anyway
local orders, lastorder = { }, 0
@@ -305,7 +304,7 @@ local function register_from_lists(collected,derived)
if kind and realpage then
local d = derived[prefix] if not d then d = { } derived[prefix] = d end
local t = { kind, i }
- for s in gmatch(reference,"[^, ]+") do
+ for s in gmatch(reference,"%s*([^,]+)") do
if trace_referencing then
report_references("list entry %s provides %s reference '%s' on realpage %s",i,kind,s,realpage)
end
@@ -1109,7 +1108,7 @@ set.n = n
bug = bug or var.error
set[i] = var
end
- references.currentset = set
+ references.currentset = mark(set) -- mark, else in api doc
--~ table.print(set,tostring(bug))
return set, bug
end
@@ -1440,7 +1439,7 @@ end
local plist
-function realpageofpage(p)
+local function realpageofpage(p)
if not plist then
local pages = structures.pages.collected
plist = { }
diff --git a/tex/context/base/strc-ref.mkiv b/tex/context/base/strc-ref.mkiv
index 60a02c171..bec96e05c 100644
--- a/tex/context/base/strc-ref.mkiv
+++ b/tex/context/base/strc-ref.mkiv
@@ -1157,12 +1157,12 @@
\attribute\referenceattribute\attributeunsetvalue
\global\lastsavedreferenceattribute\attributeunsetvalue
\iflocation
- \dostarttagged\t!link\empty % not here
\ctxlua{structures.references.inject("\referenceprefix","#2",\number\ht\strutbox,\number\dp\strutbox,\extrareferencearguments)}%
\setlocationattributes\??ia
\setstrut % can be option
\global\lastsavedreferenceattribute\lastreferenceattribute
\attribute\referenceattribute\lastreferenceattribute
+ \dostarttagged\t!link\empty % not here
#1%
\dostoptagged
\else
@@ -1176,14 +1176,16 @@
\global\lastsavedreferenceattribute\attributeunsetvalue
\attribute\referenceattribute\attributeunsetvalue
\iflocation
- \dostarttagged\t!link\empty
\ctxlua{structures.references.inject("\referenceprefix","#2",\number\dimexpr\interactionparameter\c!height\relax,\number\dimexpr\interactionparameter\c!depth\relax,\extrareferencearguments)}%
- \dostoptagged
\setlocationattributes\??ia
\attribute\referenceattribute\lastreferenceattribute
\global\lastsavedreferenceattribute\lastreferenceattribute
+ \dostarttagged\t!link\empty
+ #1%
+ \dostoptagged
+ \else
+ #1%
\fi
- #1%
\endgroup}
\def\dogoto#1#2[#3]% #2 gobbles spaces after #1 so that \goto{xx} [yy] works ok
@@ -1195,16 +1197,18 @@
\iflocation
\ctxlua{structures.references.doifelse("\referenceprefix","#3",\extrareferencearguments)}%
{\expandtexincurrentreference
- \dostarttagged\t!link\empty
\ctxlua{structures.references.injectcurrentset(\number\ht\strutbox,\number\dp\strutbox)}%
- \dostoptagged
\setlocationattributes\??ia
\setstrut % can be option
\global\lastsavedreferenceattribute\lastreferenceattribute
- \attribute\referenceattribute\lastreferenceattribute}%
- {}%
+ \attribute\referenceattribute\lastreferenceattribute
+ \dostarttagged\t!link\empty
+ #1%
+ \dostoptagged}%
+ {#1}%
+ \else
+ #1%
\fi
- #1%
%\egroup\unhbox\referencebox}
\endgroup}
@@ -1216,15 +1220,17 @@
\iflocation
\ctxlua{structures.references.doifelse("\referenceprefix","#3",\extrareferencearguments)}%
{\expandtexincurrentreference
- \dostarttagged\t!link\empty
\ctxlua{structures.references.injectcurrentset(\number\dimexpr\interactionparameter\c!height\relax,\number\dimexpr\interactionparameter\c!depth\relax)}%
- \dostoptagged
\setlocationattributes\??ia
\global\lastsavedreferenceattribute\lastreferenceattribute
- \attribute\referenceattribute\lastreferenceattribute}%
- {}%
+ \attribute\referenceattribute\lastreferenceattribute
+ \dostarttagged\t!link\empty
+ #1%
+ \dostoptagged}%
+ {#1}%
+ \else
+ #1%
\fi
- #1%
\endgroup}
\unexpanded\def\directgotobox#1[#2]% no test for valid references
@@ -1233,12 +1239,12 @@
\global\lastsavedreferenceattribute\attributeunsetvalue
\attribute\referenceattribute\attributeunsetvalue
\iflocation
- \dostarttagged\t!link\empty
\ctxlua{structures.references.inject("\referenceprefix","#2",nil,nil,\extrareferencearguments)}%
- \dostoptagged
\setlocationattributes\??ia
\global\lastsavedreferenceattribute\lastreferenceattribute
+ \dostarttagged\t!link\empty
\hbox attr \referenceattribute \lastreferenceattribute {#1}%
+ \dostoptagged
\else
#1%
\fi
@@ -1250,12 +1256,12 @@
\global\lastsavedreferenceattribute\attributeunsetvalue
\attribute\referenceattribute\attributeunsetvalue
\iflocation
- \dostarttagged\t!link\empty
\ctxlua{structures.references.inject("\referenceprefix","#3",nil,nil,\extrareferencearguments)}%
- \dostoptagged
\setlocationcolorspec{#1}% no consequence for strut
\global\lastsavedreferenceattribute\lastreferenceattribute
+ \dostarttagged\t!link\empty
\hbox attr \referenceattribute \lastreferenceattribute {#2}%
+ \dostoptagged
\else
#2%
\fi
@@ -1267,11 +1273,11 @@
\global\lastsavedreferenceattribute\attributeunsetvalue
\attribute\referenceattribute\attributeunsetvalue
\iflocation
- \dostarttagged\t!link\empty
\ctxlua{structures.references.inject("\referenceprefix","#2",nil,nil,\extrareferencearguments)}%
- \dostoptagged
\global\lastsavedreferenceattribute\lastreferenceattribute
+ \dostarttagged\t!link\empty
\hbox attr \referenceattribute \lastreferenceattribute {#1}%
+ \dostoptagged
\else
#1%
\fi
@@ -1285,13 +1291,13 @@
\iflocation
\ctxlua{structures.references.doifelse("\referenceprefix","#2",\extrareferencearguments)}%
{\expandtexincurrentreference
- \dostarttagged\t!link\empty
\ctxlua{structures.references.injectcurrentset(nil,nil)}%
- \dostoptagged
\setlocationattributes\??ia
\global\lastsavedreferenceattribute\lastreferenceattribute
- \hbox attr \referenceattribute \lastreferenceattribute {#1}}%
- {}%
+ \dostarttagged\t!link\empty
+ \hbox attr \referenceattribute \lastreferenceattribute {#1}%
+ \dostoptagged}%
+ {#1}%
\else
#1%
\fi
@@ -1300,14 +1306,14 @@
\unexpanded\def\gotowdhtbox#1#2[#3]% fast variant for overlays
{\dontleavehmode
\begingroup
+ \setbox\scratchbox\emptyhbox\wd\scratchbox#1\ht\scratchbox#2%
\global\lastsavedreferenceattribute\attributeunsetvalue
\attribute\referenceattribute\attributeunsetvalue
\ctxlua{structures.references.doifelse("\referenceprefix","#3",\extrareferencearguments)}%
{\ctxlua{structures.references.injectcurrentset(nil,nil)}%
- \setbox\scratchbox\emptyhbox\wd\scratchbox#1\ht\scratchbox#2%
\global\lastsavedreferenceattribute\lastreferenceattribute
- \hbox attr \referenceattribute \lastreferenceattribute {\box\scratchbox}}%
- {}%
+ \hbox attr \referenceattribute \lastreferenceattribute {\box\scratchbox}}
+ {\box\scratchbox}%
\endgroup}
%D An reference to another document can be specified as a file
diff --git a/tex/context/base/strc-reg.lua b/tex/context/base/strc-reg.lua
index b2deb0605..c19ae12d6 100644
--- a/tex/context/base/strc-reg.lua
+++ b/tex/context/base/strc-reg.lua
@@ -12,7 +12,7 @@ local format, gmatch = string.format, string.gmatch
local equal, concat, remove = table.are_equal, table.concat, table.remove
local utfchar = utf.char
local lpegmatch = lpeg.match
-local allocate, mark = utilities.storage.allocate, utilities.storage.mark
+local allocate = utilities.storage.allocate
local trace_registers = false trackers.register("structures.registers", function(v) trace_registers = v end)
@@ -177,11 +177,11 @@ local function filtercollected(names,criterium,number,collected,prevmode)
return result
end
-local tobesaved, collected = allocate(), allocate()
-
-registers.collected = collected
-registers.tobesaved = tobesaved
+local tobesaved = allocate()
+local collected = allocate()
+registers.collected = collected
+registers.tobesaved = tobesaved
registers.filtercollected = filtercollected
-- we follow a different strategy than by lists, where we have a global
@@ -189,8 +189,8 @@ registers.filtercollected = filtercollected
-- older we delay that decision
local function initializer()
- tobesaved = mark(registers.tobesaved)
- collected = mark(registers.collected)
+ tobesaved = registers.tobesaved
+ collected = registers.collected
local internals = references.internals
for name, list in next, collected do
local entries = list.entries
@@ -650,7 +650,7 @@ local function collapsedpage(pages)
return false
end
-function collapsepages(pages)
+local function collapsepages(pages)
while collapsedpage(pages) do end
return #pages
end
diff --git a/tex/context/base/strc-ren.mkiv b/tex/context/base/strc-ren.mkiv
index 84f8b34dd..73eb0ccd2 100644
--- a/tex/context/base/strc-ren.mkiv
+++ b/tex/context/base/strc-ren.mkiv
@@ -120,12 +120,14 @@
{\iflocation
attr \destinationattribute \currentstructureattribute
attr \referenceattribute \currentstructurereferenceattribute
- \fi}
+ % attr \internalattribute \nextinternalreference
+ \fi}
\def\setinlinestructureheadreferenceattributes
{\ifconditional\structureheadisdisplay \else \iflocation
- \attribute\destinationattribute\currentstructureattribute
- \attribute\referenceattribute \currentstructurereferenceattribute
+ \attribute\destinationattribute\currentstructureattribute
+ \attribute\referenceattribute \currentstructurereferenceattribute
+ % \attribute\internalattribute \nextinternalreference
\fi \fi}
\def\docheckstructureheadreference
diff --git a/tex/context/base/strc-syn.lua b/tex/context/base/strc-syn.lua
index 599f15311..f3ba97ffc 100644
--- a/tex/context/base/strc-syn.lua
+++ b/tex/context/base/strc-syn.lua
@@ -8,21 +8,23 @@ if not modules then modules = { } end modules ['str-syn'] = {
local next, type = next, type
local texwrite, format = tex.write, string.format
-local allocate, mark = utilities.storage.allocate, utilities.storage.mark
+local allocate = utilities.storage.allocate
-- interface to tex end
-local structures = structures
-local synonyms = structures.synonyms
+local structures = structures
+local synonyms = structures.synonyms
+local tags = structures.tags
-local collected, tobesaved = allocate(), allocate()
+local collected = allocate()
+local tobesaved = allocate()
synonyms.collected = collected
synonyms.tobesaved = tobesaved
local function initializer()
- collected = mark(synonyms.collected)
- tobesaved = mark(synonyms.tobesaved)
+ collected = synonyms.collected
+ tobesaved = synonyms.tobesaved
end
local function finalizer()
@@ -33,6 +35,8 @@ end
job.register('structures.synonyms.collected', tobesaved, initializer, finalizer)
+-- todo: allocate becomes metatable
+
local function allocate(class)
local d = tobesaved[class]
if not d then
diff --git a/tex/context/base/strc-syn.mkiv b/tex/context/base/strc-syn.mkiv
index 1cb1bb1f6..f063ef087 100644
--- a/tex/context/base/strc-syn.mkiv
+++ b/tex/context/base/strc-syn.mkiv
@@ -20,6 +20,9 @@
\unprotect
+\let\dotagsynonym\relax
+\let\dotagsorting\relax
+
% general help, can be shared
% simplifiedcommands -> flag in lua
@@ -171,8 +174,12 @@
\unexpanded\def\doinsertsynonym#1#2% name tag
{\begingroup
\def\currentsynonym{#1}%
+ \def\currentsynonymtag{#2}%
+ \dotagsynonym
+ \dostarttagged\t!synonym\currentsynonym
\dosetsynonymattributes\c!synonymstyle\c!synonymcolor
\synonymparameter\c!synonymcommand{\ctxlua{structures.synonyms.synonym("#1","#2")}}%
+ \dostoptagged
\normalexpanded{\endgroup\synonymparameter\c!next}}
\unexpanded\def\placelistofsynonyms
@@ -328,8 +335,12 @@
{\begingroup
% no kap currently, of .. we need to map cap onto WORD
\edef\currentsorting{#1}%
+ \def\currentsortingtag{#2}%
+ \dotagsorting
+ \dostarttagged\t!sorting\currentsorting
\dosetsortingattributes\c!style\c!color
\ctxlua{structures.synonyms.synonym("#1","#2")}%
+ \dostoptagged
\normalexpanded{\endgroup\sortingparameter\c!next}}
\def\registersort
diff --git a/tex/context/base/strc-tag.lua b/tex/context/base/strc-tag.lua
index 1c30541c3..f1381dad5 100644
--- a/tex/context/base/strc-tag.lua
+++ b/tex/context/base/strc-tag.lua
@@ -33,10 +33,12 @@ local stack = { }
local chain = { }
local ids = { }
local enabled = false
+local tagdata = { } -- used in export
local tags = structures.tags
tags.taglist = taglist -- can best be hidden
tags.labels = labels
+tags.data = tagdata
local properties = allocate {
@@ -62,9 +64,13 @@ local properties = allocate {
descriptionsymbol = { pdf = "Span", nature = "inline" }, -- note reference
verbatimblock = { pdf = "Code", nature = "display" },
- verbatimline = { pdf = "Code", nature = "display" },
+ verbatimlines = { pdf = "Code", nature = "display" },
+ verbatimline = { pdf = "Code", nature = "mixed" },
verbatim = { pdf = "Code", nature = "inline" },
+ synonym = { pdf = "Span", nature = "inline" },
+ sort = { pdf = "Span", nature = "inline" },
+
register = { pdf = "Div", nature = "display" },
registersection = { pdf = "Div", nature = "display" },
registertag = { pdf = "Span", nature = "mixed" },
@@ -175,7 +181,7 @@ function tags.start(tag,specification)
stack[#stack+1] = t -- insert(stack,t)
taglist[t] = { unpack(chain) } -- we can add key values for alt and actualtext if needed
if user and user ~= "" then
- -- maybe we should merge this into taglistor or whatever ... anyway there is room to optimize
+ -- maybe we should merge this into taglist or whatever ... anyway there is room to optimize
-- taglist.userdata = settings_to_hash(user)
userdata[completetag] = settings_to_hash(user)
end
@@ -197,10 +203,29 @@ function tags.stop()
return t
end
+function tags.getid(tag,detail)
+ if detail and detail ~= "" then
+ return ids[tag .. ":" .. detail] or "?"
+ else
+ return ids[tag] or "?"
+ end
+end
+
function tags.last(tag)
return lasttags[tag] -- or false
end
+function tags.lastinchain()
+ return chain[#chain]
+end
+
+function tags.registerdata(data)
+ local fulltag = chain[#chain]
+ if fulltag then
+ tagdata[fulltag] = data
+ end
+end
+
function structures.atlocation(str)
local location = gsub(concat(taglist[texattribute[a_tagged]],"-"),"%-%d+","")
return find(location,topattern(str)) ~= nil
diff --git a/tex/context/base/strc-tag.mkiv b/tex/context/base/strc-tag.mkiv
index addff193b..8bc8d9f69 100644
--- a/tex/context/base/strc-tag.mkiv
+++ b/tex/context/base/strc-tag.mkiv
@@ -43,9 +43,13 @@
\def\t!descriptionsymbol {descriptionsymbol} % Span
\def\t!verbatimblock {verbatimblock} % Code
+\def\t!verbatimlines {verbatimlines} % Code
\def\t!verbatimline {verbatimline} % Code
\def\t!verbatim {verbatim} % Code
+\def\t!sorting {sorting} % Span
+\def\t!synonym {synonym} % Span
+
\def\t!register {register} % Div
\def\t!registersection {registersection} % Div
\def\t!registertag {registertag} % Span
diff --git a/tex/context/base/supp-box.lua b/tex/context/base/supp-box.lua
index 4d496d8de..48baecf6f 100644
--- a/tex/context/base/supp-box.lua
+++ b/tex/context/base/supp-box.lua
@@ -24,7 +24,7 @@ local copynodelist = node.copy_list
local copynode = node.copy
local texbox = tex.box
-function hyphenatedlist(list)
+local function hyphenatedlist(list)
while list do
local id, next, prev = list.id, list.next, list.prev
if id == disc_code then
@@ -50,7 +50,7 @@ function commands.showhyphenatedinlist(list)
report_hyphenation("show: %s",nodes.listtoutf(list))
end
-function checkedlist(list)
+local function checkedlist(list)
if type(list) == "number" then
return texbox[list].list
else
diff --git a/tex/context/base/supp-fil.lua b/tex/context/base/supp-fil.lua
index 91fa446b9..a2c0b5d7d 100644
--- a/tex/context/base/supp-fil.lua
+++ b/tex/context/base/supp-fil.lua
@@ -111,11 +111,11 @@ local function readfilename(specification,backtrack,treetoo)
if not fnd then
if isfile(name) then
if trace_files then
- report_files("found local: %s",fname)
+ report_files("found local: %s",name)
end
fnd = name
end
- if backtrack then
+ if not fnd and backtrack then
local fname = name
for i=1,backtrack,1 do
fname = "../" .. fname
diff --git a/tex/context/base/trac-log.lua b/tex/context/base/trac-log.lua
index fdc57eba1..13bb18b06 100644
--- a/tex/context/base/trac-log.lua
+++ b/tex/context/base/trac-log.lua
@@ -18,6 +18,8 @@ local escapedpattern = string.escapedpattern
local texcount = tex and tex.count
local next, type = next, type
+local setmetatableindex = table.setmetatableindex
+
--[[ldx--
This is a prelude to a more extensive logging module. We no longer
provide based logging a sparsing is relatively easy anyway.
@@ -38,11 +40,11 @@ wiki : http://contextgarden.net
local function ignore() end
-setmetatable(logs, { __index = function(t,k) t[k] = ignore ; return ignore end })
+setmetatableindex(logs, function(t,k) t[k] = ignore ; return ignore end)
-local report, subreport, status, settarget, setformatter
+local report, subreport, status, settarget, setformats, settranslations
-local direct, subdirect, writer
+local direct, subdirect, writer, pushtarget, poptarget
if tex and tex.jobname or tex.formatname then
diff --git a/tex/context/base/util-deb.lua b/tex/context/base/util-deb.lua
index d61ac0f02..5eabbc8c4 100644
--- a/tex/context/base/util-deb.lua
+++ b/tex/context/base/util-deb.lua
@@ -145,7 +145,7 @@ end
local is_node = node and node.is_node
-function inspect(i)
+function inspect(i) -- global function
local ti = type(i)
if ti == "table" then
table.print(i,"table")
diff --git a/tex/context/base/util-dim.lua b/tex/context/base/util-dim.lua
new file mode 100644
index 000000000..4e2cc1662
--- /dev/null
+++ b/tex/context/base/util-dim.lua
@@ -0,0 +1,436 @@
+if not modules then modules = { } end modules ['util-dim'] = {
+ version = 1.001,
+ comment = "support for dimensions",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+--[[ldx--
+Internally work with scaled point, which are
+represented by integers. However, in practice, at east at the
+ end we work with more generic units like points (pt). Going
+from scaled points (numbers) to one of those units can be
+done by using the conversion factors collected in the following
+table.
+--ldx]]--
+
+local format, match, gsub, type, setmetatable = string.format, string.match, string.gsub, type, setmetatable
+local P, S, R, Cc, lpegmatch = lpeg.P, lpeg.S, lpeg.R, lpeg.Cc, lpeg.match
+
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
+
+--this might become another namespace
+
+number = number or { }
+local number = number
+
+number.tonumberf = function(n) return match(format("%.20f",n),"(.-0?)0*$") end -- one zero too much but alas
+number.tonumberg = function(n) return format("%.20g",n) end
+
+local dimenfactors = allocate {
+ ["pt"] = 1/65536,
+ ["in"] = ( 100/ 7227)/65536,
+ ["cm"] = ( 254/ 7227)/65536,
+ ["mm"] = ( 2540/ 7227)/65536,
+ ["sp"] = 1, -- 65536 sp in 1pt
+ ["bp"] = ( 7200/ 7227)/65536,
+ ["pc"] = ( 1/ 12)/65536,
+ ["dd"] = ( 1157/ 1238)/65536,
+ ["cc"] = ( 1157/14856)/65536,
+ ["nd"] = (20320/21681)/65536,
+ ["nc"] = ( 5080/65043)/65536
+}
+
+--~ print(table.serialize(dimenfactors))
+--~
+--~ %.99g:
+--~
+--~ t={
+--~ ["bp"]=1.5201782378580324e-005,
+--~ ["cc"]=1.1883696112892098e-006,
+--~ ["cm"]=5.3628510057769479e-007,
+--~ ["dd"]=1.4260435335470516e-005,
+--~ ["em"]=0.000152587890625,
+--~ ["ex"]=6.103515625e-005,
+--~ ["in"]=2.1113586636917117e-007,
+--~ ["mm"]=5.3628510057769473e-008,
+--~ ["nc"]=1.1917446679504327e-006,
+--~ ["nd"]=1.4300936015405194e-005,
+--~ ["pc"]=1.2715657552083333e-006,
+--~ ["pt"]=1.52587890625e-005,
+--~ ["sp"]=1,
+--~ }
+--~
+--~ patched %s and tonumber
+--~
+--~ t={
+--~ ["bp"]=0.00001520178238,
+--~ ["cc"]=0.00000118836961,
+--~ ["cm"]=0.0000005362851,
+--~ ["dd"]=0.00001426043534,
+--~ ["em"]=0.00015258789063,
+--~ ["ex"]=0.00006103515625,
+--~ ["in"]=0.00000021113587,
+--~ ["mm"]=0.00000005362851,
+--~ ["nc"]=0.00000119174467,
+--~ ["nd"]=0.00001430093602,
+--~ ["pc"]=0.00000127156576,
+--~ ["pt"]=0.00001525878906,
+--~ ["sp"]=1,
+--~ }
+
+--[[ldx--
+A conversion function that takes a number, unit (string) and optional
+format (string) is implemented using this table.
+--ldx]]--
+
+local function numbertodimen(n,unit,fmt)
+ if type(n) == 'string' then
+ return n
+ else
+ unit = unit or 'pt'
+ return format(fmt or "%s%s",n*dimenfactors[unit],unit)
+ -- if fmt then
+ -- return format(fmt,n*dimenfactors[unit],unit)
+ -- else
+ -- return match(format("%.20f",n*dimenfactors[unit]),"(.-0?)0*$") .. unit
+ -- end
+ end
+end
+
+--[[ldx--
+We collect a bunch of converters in the number namespace.
+--ldx]]--
+
+number.maxdimen = 1073741823
+number.todimen = numbertodimen
+number.dimenfactors = dimenfactors
+
+function number.topoints (n) return numbertodimen(n,"pt") end
+function number.toinches (n) return numbertodimen(n,"in") end
+function number.tocentimeters (n) return numbertodimen(n,"cm") end
+function number.tomillimeters (n) return numbertodimen(n,"mm") end
+function number.toscaledpoints(n) return numbertodimen(n,"sp") end
+function number.toscaledpoints(n) return n .. "sp" end
+function number.tobasepoints (n) return numbertodimen(n,"bp") end
+function number.topicas (n) return numbertodimen(n "pc") end
+function number.todidots (n) return numbertodimen(n,"dd") end
+function number.tociceros (n) return numbertodimen(n,"cc") end
+function number.tonewdidots (n) return numbertodimen(n,"nd") end
+function number.tonewciceros (n) return numbertodimen(n,"nc") end
+
+--[[ldx--
+More interesting it to implement a (sort of) dimen datatype, one
+that permits calculations too. First we define a function that
+converts a string to scaledpoints. We use . We capture
+a number and optionally a unit. When no unit is given a constant
+capture takes place.
+--ldx]]--
+
+local amount = (S("+-")^0 * R("09")^0 * P(".")^0 * R("09")^0) + Cc("0")
+local unit = R("az")^1
+
+local dimenpair = amount/tonumber * (unit^1/dimenfactors + Cc(1)) -- tonumber is new
+
+lpeg.patterns.dimenpair = dimenpair
+
+--[[ldx--
+We use a metatable to intercept errors. When no key is found in
+the table with factors, the metatable will be consulted for an
+alternative index function.
+--ldx]]--
+
+setmetatableindex(dimenfactors, function(t,s)
+ -- error("wrong dimension: " .. (s or "?")) -- better a message
+ return false
+end)
+
+--[[ldx--
+We redefine the following function later on, so we comment it
+here (which saves us bytecodes.
+--ldx]]--
+
+-- function string.todimen(str)
+-- if type(str) == "number" then
+-- return str
+-- else
+-- local value, unit = lpegmatch(dimenpair,str)
+-- return value/unit
+-- end
+-- end
+--
+-- local stringtodimen = string.todimen
+
+local stringtodimen -- assigned later (commenting saves bytecode)
+
+local amount = S("+-")^0 * R("09")^0 * S(".,")^0 * R("09")^0
+local unit = P("pt") + P("cm") + P("mm") + P("sp") + P("bp") + P("in") +
+ P("pc") + P("dd") + P("cc") + P("nd") + P("nc")
+
+local validdimen = amount * unit
+
+lpeg.patterns.validdimen = validdimen
+
+--[[ldx--
+This converter accepts calls like:
+
+
+string.todimen("10")
+string.todimen(".10")
+string.todimen("10.0")
+string.todimen("10.0pt")
+string.todimen("10pt")
+string.todimen("10.0pt")
+
+
+With this in place, we can now implement a proper datatype for dimensions, one
+that permits us to do this:
+
+
+s = dimen "10pt" + dimen "20pt" + dimen "200pt"
+ - dimen "100sp" / 10 + "20pt" + "0pt"
+
+
+We create a local metatable for this new type:
+--ldx]]--
+
+local dimensions = { }
+
+--[[ldx--
+The main (and globally) visible representation of a dimen is defined next: it is
+a one-element table. The unit that is returned from the match is normally a number
+(one of the previously defined factors) but we also accept functions. Later we will
+see why. This function is redefined later.
+--ldx]]--
+
+-- function dimen(a)
+-- if a then
+-- local ta= type(a)
+-- if ta == "string" then
+-- local value, unit = lpegmatch(pattern,a)
+-- if type(unit) == "function" then
+-- k = value/unit()
+-- else
+-- k = value/unit
+-- end
+-- a = k
+-- elseif ta == "table" then
+-- a = a[1]
+-- end
+-- return setmetatable({ a }, dimensions)
+-- else
+-- return setmetatable({ 0 }, dimensions)
+-- end
+-- end
+
+--[[ldx--
+This function return a small hash with a metatable attached. It is
+through this metatable that we can do the calculations. We could have
+shared some of the code but for reasons of speed we don't.
+--ldx]]--
+
+function dimensions.__add(a, b)
+ local ta, tb = type(a), type(b)
+ if ta == "string" then a = stringtodimen(a) elseif ta == "table" then a = a[1] end
+ if tb == "string" then b = stringtodimen(b) elseif tb == "table" then b = b[1] end
+ return setmetatable({ a + b }, dimensions)
+end
+
+function dimensions.__sub(a, b)
+ local ta, tb = type(a), type(b)
+ if ta == "string" then a = stringtodimen(a) elseif ta == "table" then a = a[1] end
+ if tb == "string" then b = stringtodimen(b) elseif tb == "table" then b = b[1] end
+ return setmetatable({ a - b }, dimensions)
+end
+
+function dimensions.__mul(a, b)
+ local ta, tb = type(a), type(b)
+ if ta == "string" then a = stringtodimen(a) elseif ta == "table" then a = a[1] end
+ if tb == "string" then b = stringtodimen(b) elseif tb == "table" then b = b[1] end
+ return setmetatable({ a * b }, dimensions)
+end
+
+function dimensions.__div(a, b)
+ local ta, tb = type(a), type(b)
+ if ta == "string" then a = stringtodimen(a) elseif ta == "table" then a = a[1] end
+ if tb == "string" then b = stringtodimen(b) elseif tb == "table" then b = b[1] end
+ return setmetatable({ a / b }, dimensions)
+end
+
+function dimensions.__unm(a)
+ local ta = type(a)
+ if ta == "string" then a = stringtodimen(a) elseif ta == "table" then a = a[1] end
+ return setmetatable({ - a }, dimensions)
+end
+
+--[[ldx--
+It makes no sense to implement the power and modulo function but
+the next two do make sense because they permits is code like:
+
+
+local a, b = dimen "10pt", dimen "11pt"
+...
+if a > b then
+ ...
+end
+
+--ldx]]--
+
+-- makes no sense: dimensions.__pow and dimensions.__mod
+
+function dimensions.__lt(a, b)
+ return a[1] < b[1]
+end
+
+function dimensions.__eq(a, b)
+ return a[1] == b[1]
+end
+
+--[[ldx--
+We also need to provide a function for conversion to string (so that
+we can print dimensions). We print them as points, just like .
+--ldx]]--
+
+function dimensions.__tostring(a)
+ return a[1]/65536 .. "pt" -- instead of todimen(a[1])
+end
+
+--[[ldx--
+Since it does not take much code, we also provide a way to access
+a few accessors
+
+
+print(dimen().pt)
+print(dimen().sp)
+
+--ldx]]--
+
+function dimensions.__index(tab,key)
+ local d = dimenfactors[key]
+ if not d then
+ error("illegal property of dimen: " .. key)
+ d = 1
+ end
+ return 1/d
+end
+
+--[[ldx--
+In the converter from string to dimension we support functions as
+factors. This is because in we have a few more units:
+ex and em. These are not constant factors but
+depend on the current font. They are not defined by default, but need
+an explicit function call. This is because at the moment that this code
+is loaded, the relevant tables that hold the functions needed may not
+yet be available.
+--ldx]]--
+
+ dimenfactors["ex"] = 4 * 1/65536 -- 4pt
+ dimenfactors["em"] = 10 * 1/65536 -- 10pt
+-- dimenfactors["%"] = 4 * 1/65536 -- 400pt/100
+
+--[[ldx--
+The previous code is rather efficient (also thanks to ) but we
+can speed it up by caching converted dimensions. On my machine (2008) the following
+loop takes about 25.5 seconds.
+
+
+for i=1,1000000 do
+ local s = dimen "10pt" + dimen "20pt" + dimen "200pt"
+ - dimen "100sp" / 10 + "20pt" + "0pt"
+end
+
+
+When we cache converted strings this becomes 16.3 seconds. In order not
+to waste too much memory on it, we tag the values of the cache as being
+week which mean that the garbage collector will collect them in a next
+sweep. This means that in most cases the speed up is mostly affecting the
+current couple of calculations and as such the speed penalty is small.
+
+We redefine two previous defined functions that can benefit from
+this:
+--ldx]]--
+
+local known = { } setmetatable(known, { __mode = "v" })
+
+function dimen(a)
+ if a then
+ local ta= type(a)
+ if ta == "string" then
+ local k = known[a]
+ if k then
+ a = k
+ else
+ local value, unit = lpegmatch(dimenpair,a)
+ if type(unit) == "function" then
+ k = value/unit()
+ else
+ k = value/unit
+ end
+ known[a] = k
+ a = k
+ end
+ elseif ta == "table" then
+ a = a[1]
+ end
+ return setmetatable({ a }, dimensions)
+ else
+ return setmetatable({ 0 }, dimensions)
+ end
+end
+
+function string.todimen(str) -- maybe use tex.sp when available
+ if type(str) == "number" then
+ return str
+ else
+ local k = known[str]
+ if not k then
+ local value, unit = lpegmatch(dimenpair,str)
+ if value and unit then
+ k = value/unit -- to be considered: round
+ else
+ k = 0
+ end
+ -- print(str,value,unit)
+ known[str] = k
+ end
+ return k
+ end
+end
+
+--~ local known = { }
+
+--~ function string.todimen(str) -- maybe use tex.sp
+--~ local k = known[str]
+--~ if not k then
+--~ k = tex.sp(str)
+--~ known[str] = k
+--~ end
+--~ return k
+--~ end
+
+stringtodimen = string.todimen -- local variable defined earlier
+
+function number.toscaled(d)
+ return format("%0.5f",d/2^16)
+end
+
+--[[ldx--
+In a similar fashion we can define a glue datatype. In that case we
+probably use a hash instead of a one-element table.
+--ldx]]--
+
+--[[ldx--
+Goodie:s
+--ldx]]--
+
+function number.percent(n) -- will be cleaned up once luatex 0.30 is out
+ local hsize = tex.hsize
+ if type(hsize) == "string" then
+ hsize = stringtodimen(hsize)
+ end
+ return (n/100) * hsize
+end
+
+number["%"] = number.percent
diff --git a/tex/context/base/util-prs.lua b/tex/context/base/util-prs.lua
index 617dc0c78..591453760 100644
--- a/tex/context/base/util-prs.lua
+++ b/tex/context/base/util-prs.lua
@@ -6,18 +6,20 @@ if not modules then modules = { } end modules ['util-prs'] = {
license = "see context related readme files"
}
+local P, R, V, C, Ct, Carg = lpeg.P, lpeg.R, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Carg
+local lpegmatch = lpeg.match
+local concat, format, gmatch = table.concat, string.format, string.gmatch
+local tostring, type, next = tostring, type, next
+
utilities = utilities or {}
utilities.parsers = utilities.parsers or { }
local parsers = utilities.parsers
parsers.patterns = parsers.patterns or { }
--- we could use a Cf Cg construct
+local setmetatableindex = table.setmetatableindex
+local sortedhash = table.sortedhash
-local P, R, V, C, Ct, Carg = lpeg.P, lpeg.R, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Carg
-local lpegmatch = lpeg.match
-local concat, format, gmatch = table.concat, string.format, string.gmatch
-local tostring, type, next, setmetatable = tostring, type, next, setmetatable
-local sortedhash = table.sortedhash
+-- we could use a Cf Cg construct
local escape, left, right = P("\\"), P('{'), P('}')
@@ -216,7 +218,7 @@ function parsers.getparameters(self,class,parentclass,settings)
sp = { }
self[parentclass] = sp
end
- setmetatable(sc, { __index = sp })
+ setmetatableindex(sc,sp)
end
end
parsers.settings_to_hash(settings,sc)
diff --git a/tex/context/base/util-seq.lua b/tex/context/base/util-seq.lua
index f36d1d640..22733b022 100644
--- a/tex/context/base/util-seq.lua
+++ b/tex/context/base/util-seq.lua
@@ -22,10 +22,12 @@ local type, loadstring = type, loadstring
utilities = utilities or { }
local tables = utilities.tables
+local allocate = utilities.storage.allocate
local sequencers = { }
utilities.sequencers = sequencers
-local functions = { }
+
+local functions = allocate()
sequencers.functions = functions
local removevalue, insertaftervalue, insertbeforevalue = tables.removevalue, tables.insertaftervalue, tables.insertbeforevalue
diff --git a/tex/context/base/util-sto.lua b/tex/context/base/util-sto.lua
index 19b8093c9..f4521c91f 100644
--- a/tex/context/base/util-sto.lua
+++ b/tex/context/base/util-sto.lua
@@ -50,20 +50,6 @@ function storage.checked(t)
return t
end
-function setmetatablekey(t,key,value)
- local m = getmetatable(t)
- if not m then
- m = { }
- setmetatable(t,m)
- end
- m[key] = value
-end
-
-function getmetatablekey(t,key,value)
- local m = getmetatable(t)
- return m and m[key]
-end
-
--~ function utilities.storage.delay(parent,name,filename)
--~ local m = getmetatable(parent)
--~ m.__list[name] = filename
@@ -109,3 +95,74 @@ function storage.sparse(t)
setmetatable(t,keyisvalue)
return t
end
+
+-- table namespace ?
+
+local function f_empty () return "" end -- t,k
+local function f_self (t,k) t[k] = k return k end
+local function f_ignore() end -- t,k,v
+
+local t_empty = { __index = empty }
+local t_self = { __index = self }
+local t_ignore = { __newindex = ignore }
+
+function table.setmetatableindex(t,f)
+ local m = getmetatable(t)
+ if m then
+ if f == "empty" then
+ m.__index = f_empty
+ elseif f == "key" then
+ m.__index = f_self
+ else
+ m.__index = f
+ end
+ else
+ if f == "empty" then
+ setmetatable(t, t_empty)
+ elseif f == "key" then
+ setmetatable(t, t_self)
+ else
+ setmetatable(t,{ __index = f })
+ end
+ end
+end
+
+function table.setmetatablenewindex(t,f)
+ local m = getmetatable(t)
+ if m then
+ if f == "ignore" then
+ m.__newindex = f_ignore
+ else
+ m.__newindex = f
+ end
+ else
+ if f == "ignore" then
+ setmetatable(t, t_ignore)
+ else
+ setmetatable(t,{ __newindex = f })
+ end
+ end
+end
+
+function table.setmetatablecall(t,f)
+ local m = getmetatable(t)
+ if m then
+ m.__call = f
+ else
+ setmetatable(t,{ __call = f })
+ end
+end
+
+function table.setmetatablekey(t,key,value)
+ local m = getmetatable(t)
+ if not m then
+ m = { }
+ setmetatable(t,m)
+ end
+ m[key] = value
+end
+
+function table.getmetatablekey(t,key,value)
+ local m = getmetatable(t)
+ return m and m[key]
+end
diff --git a/tex/context/base/util-tab.lua b/tex/context/base/util-tab.lua
index f8422c626..818266d3c 100644
--- a/tex/context/base/util-tab.lua
+++ b/tex/context/base/util-tab.lua
@@ -12,7 +12,7 @@ local tables = utilities.tables
local format, gmatch = string.format, string.gmatch
local concat, insert, remove = table.concat, table.insert, table.remove
-local setmetatable, tonumber, tostring = setmetatable, tonumber, tostring
+local setmetatable, getmetatable, tonumber, tostring = setmetatable, getmetatable, tonumber, tostring
function tables.definetable(target) -- defines undefined tables
local composed, t, n = nil, { }, 0
@@ -77,12 +77,6 @@ function tables.insertaftervalue(t,value,extra)
insert(t,#t+1,extra)
end
-local _empty_table_ = { __index = function(t,k) return "" end }
-
-function table.setemptymetatable(t)
- setmetatable(t,_empty_table_)
-end
-
-- experimental
local function toxml(t,d,result)
@@ -99,8 +93,13 @@ local function toxml(t,d,result)
end
end
-function table.toxml(t,name)
- local result = { "" }
- toxml( { [name or "root"] = t }, "", result)
+function table.toxml(t,name,nobanner)
+ local noroot = name == false
+ local result = (nobanner or noroot) and { } or { "" }
+ if noroot then
+ toxml( t, "", result)
+ else
+ toxml( { [name or "root"] = t }, "", result)
+ end
return concat(result,"\n")
end
diff --git a/tex/context/base/x-set-11.mkiv b/tex/context/base/x-set-11.mkiv
index 4db75ef06..ceba34f3d 100644
--- a/tex/context/base/x-set-11.mkiv
+++ b/tex/context/base/x-set-11.mkiv
@@ -29,7 +29,7 @@
% \setup{setupinterlinespace:1}
% \setup{setupinterlinespace:2}
%
-% cd:include -> @file
+% cd:include -> filename
% cd:choice
%
% register, interaction
@@ -304,13 +304,13 @@
% general
-\unexpanded\def\setupnumfont {}
-\unexpanded\def\setuptxtfont {}
-\unexpanded\def\setupintfont {\WORD}
-\unexpanded\def\setupvarfont {\sl}
-\unexpanded\def\setupoptfont {\sl}
-\unexpanded\def\setupalwcolor {}
-\unexpanded\def\setupoptcolor {darkgray}
+\unexpanded\def\setupnumfont {}
+\unexpanded\def\setuptxtfont {}
+\unexpanded\def\setupintfont {\WORD}
+\unexpanded\def\setupvarfont {\sl}
+\unexpanded\def\setupoptfont {\sl}
+\unexpanded\def\setupalwcolor{}
+\unexpanded\def\setupoptcolor{darkgray}
\def\c!setup!definereserved#1#2%
{\setvalue{c!setup!:r:#1}{#2}}
@@ -394,6 +394,7 @@
\stopxmlsetups
\startxmlsetups xml:setups:basics
+ \xmlinclude{#1}{include}{filename}%
\xmlsetsetup {#1} {
sequence|string|variable|assignments|keywords|content|displaymath|index|math|
nothing|file|position|reference|csname|destination|triplet|word|
@@ -415,7 +416,7 @@
{\doonlyonce{setups:#1}
{\doglobal\prependtocommalist{setups:#1}\loadedsetups % last overloads first
\xmlloadonly{setups:#1}{#1}{setups}%
- \xmlfilter{setups:#1}{/interface/command/command(xml:setups:register)}}}} % qualified path saves > 50% runtime
+ \xmlfilter{setups:#1}{interface/command/command(xml:setups:register)}}}} % qualified path saves > 50% runtime
\newif\ifshortsetup
@@ -444,10 +445,10 @@
\showsetupindeed{#1}}
% \def\showsetupindeed#1%
-% {\xmlfilterlist{\loadedsetups}{/interface/command[@name='#1']/command(xml:setups:typeset)}}
+% {\xmlfilterlist{\loadedsetups}{interface/command[@name='#1']/command(xml:setups:typeset)}}
\def\showsetupindeed#1%
- {\xmlfilterlist{\loadedsetups}{/interface/command['#1' == (@type=='environment' and 'start' or '') .. @name]/command(xml:setups:typeset)}}
+ {\xmlfilterlist{\loadedsetups}{interface/command['#1' == (@type=='environment' and 'start' or '') .. @name]/command(xml:setups:typeset)}}
\unexpanded\def\placesetup {\placelistofsorts[texcommand][\c!criterium=\v!used]}
\unexpanded\def\placeallsetups{\placelistofsorts[texcommand][\c!criterium=\v!all ]}
@@ -475,6 +476,7 @@
\doglobal\newcounter\currentSETUPargument
\xdef\maximumSETUPargument{\xmlcount{#1}{/arguments/*}}
\bgroup
+ \enablemode[setups-pass-one]%
\doif {\xmlatt{#1}{generated}} {yes} {
\ttsl
}
@@ -496,6 +498,7 @@
}
\doif {\xmlatt{#1}{type}} {environment} {
\bgroup
+ \enablemode[setups-pass-one]%
\hskip.5em\unknown\hskip.5em
\doif {\xmlatt{#1}{generated}} {yes} {
\ttsl
@@ -526,7 +529,7 @@
\startxmlsetups xml:setups:resolve
\ignorespaces
- \xmlfilterlist{\loadedsetups}{/interface/define[@name='\xmlatt{#1}{name}']/first()}
+ \xmlfilterlist{\loadedsetups}{interface/define[@name='\xmlatt{#1}{name}']/first()}
\stopxmlsetups
%D This is the first pass; here we generate the top line.
diff --git a/tex/context/base/x-set-12.mkiv b/tex/context/base/x-set-12.mkiv
index d79901433..d95aff4a3 100644
--- a/tex/context/base/x-set-12.mkiv
+++ b/tex/context/base/x-set-12.mkiv
@@ -87,34 +87,32 @@
[\hbox to \paperwidth{\reuseMPgraphic{cover+back}\hss}]
\startreusableMPgraphic{cover+back}
- numeric h, w ; path p, q, r ; color f, d ; pair s ;
- h := OverlayHeight ; w := 2*OverlayWidth ;
- r := unitsquare xyscaled (w,h) ;
- fill r withcolor \MPcolor{lightgray} ;
- set_grid(w,h,w/8,w/16) ;
- forever :
- s := center r randomized (w,h) ;
- if new_on_grid(xpart s, ypart s) :
- s := (dx,dy) ;
- p := fullsquare xyscaled(w/4,w/8) ;
- q := (-4w,ypart ulcorner p) --
- .5[ulcorner p, urcorner p] --
- (4w,ypart urcorner p) ;
- q := q shifted (0,-w/24) ;
- p := p randomized (w/40,w/40) ;
- q := q randomized (0,w/100) ;
- q := q cutafter (p cutafter point 3 of p) ;
- q := q cutbefore (p cutbefore point 3 of p) ;
- d := .5[\MPcolor{LocalColor},\MPcolor{lightgray}] randomized (.5,.9) ;
- f := \MPcolor{lightgray} randomized (.5,.9) ;
- pickup pencircle scaled (w/100) ;
- fill p shifted s withcolor f ;
- draw p shifted s withcolor d ;
- draw q shifted s withcolor d ;
- fi ;
- exitif grid_full ;
- endfor ;
- setbounds currentpicture to r ;
+ numeric h, w ; path p, q, r ; color f, d ; pair s ;
+ h := OverlayHeight ; w := 2*OverlayWidth ;
+ r := unitsquare xyscaled (w,h) ;
+ fill r withcolor \MPcolor{lightgray} ;
+ set_grid(w,h,w/8,w/16) ;
+ forever :
+ s := center r randomized (w,h) ;
+ if new_on_grid(xpart s, ypart s) :
+ s := (dx,dy) ;
+ p := fullsquare xyscaled(w/4,w/8) ;
+ q := (-4w,ypart ulcorner p) -- .5[ulcorner p, urcorner p] -- (4w,ypart urcorner p) ;
+ q := q shifted (0,-w/24) ;
+ p := p randomized (w/40,w/40) ;
+ q := q randomized (0,w/100) ;
+ q := q cutafter (p cutafter point 3 of p) ;
+ q := q cutbefore (p cutbefore point 3 of p) ;
+ d := .5[\MPcolor{LocalColor},\MPcolor{lightgray}] randomized (.5,.9) ;
+ f := \MPcolor{lightgray} randomized (.5,.9) ;
+ pickup pencircle scaled (w/100) ;
+ fill p shifted s withcolor f ;
+ draw p shifted s withcolor d ;
+ draw q shifted s withcolor d ;
+ fi ;
+ exitif grid_full ;
+ endfor ;
+ setbounds currentpicture to r ;
\stopreusableMPgraphic
\definelayout
@@ -143,7 +141,9 @@
\setupframedtexts
[setuptext]
- [\c!frame=\v!on,
+ [\c!before=\blank,
+ \c!after=\blank,
+ \c!frame=\v!on,
\c!rulethickness=1pt,
\c!framecolor=TitleColor]
@@ -161,47 +161,47 @@
[titlepage]
\startsetups text:commands
- \startinterface dutch \strut commando's \par \stopinterface
- \startinterface english \strut commands \par \stopinterface
- \startinterface german \strut befehle \par \stopinterface
- \startinterface french \strut commandes \par \stopinterface
- \startinterface czech \strut p\v{r}ikazy \par \stopinterface
- \startinterface italian \strut comandi \par \stopinterface
- \startinterface romanian \strut comenzile \par \stopinterface
+ \startinterface dutch \strut commando's \par \stopinterface
+ \startinterface english \strut commands \par \stopinterface
+ \startinterface german \strut befehle \par \stopinterface
+ \startinterface french \strut commandes \par \stopinterface
+ \startinterface czech \strut p\v{r}ikazy \par \stopinterface
+ \startinterface italian \strut comandi \par \stopinterface
+ \startinterface romanian \strut comenzile \par \stopinterface
\stopsetups
\startsetups text:uppercase
- \startinterface dutch NL\stopinterface
- \startinterface english EN\stopinterface
- \startinterface german DE\stopinterface
- \startinterface french FR\stopinterface
- \startinterface czech CS\stopinterface
- \startinterface italian IT\stopinterface
- \startinterface romanian RO\stopinterface
+ \startinterface dutch NL\stopinterface
+ \startinterface english EN\stopinterface
+ \startinterface german DE\stopinterface
+ \startinterface french FR\stopinterface
+ \startinterface czech CS\stopinterface
+ \startinterface italian IT\stopinterface
+ \startinterface romanian RO\stopinterface
\stopsetups
\startsetups text:lowercase
- \startinterface dutch \strut nl / nederlands \par \stopinterface
- \startinterface english \strut en / english \par \stopinterface
- \startinterface german \strut de / deutsch \par \stopinterface
- \startinterface french \strut fr / fran\c{c}ais \par \stopinterface
- \startinterface czech \strut cs / \v{c}esk\'y \par \stopinterface
- \startinterface italian \strut it / italiano \par \stopinterface
- \startinterface romanian \strut ro / rom\^{a}n\u{a} \par \stopinterface
+ \startinterface dutch \strut nl / nederlands \par \stopinterface
+ \startinterface english \strut en / english \par \stopinterface
+ \startinterface german \strut de / deutsch \par \stopinterface
+ \startinterface french \strut fr / fran\c{c}ais \par \stopinterface
+ \startinterface czech \strut cs / \v{c}esk\'y \par \stopinterface
+ \startinterface italian \strut it / italiano \par \stopinterface
+ \startinterface romanian \strut ro / rom\^{a}n\u{a} \par \stopinterface
\stopsetups
\startmakeup[\v!standard]
- \dontcomplain
- \setupalign[\v!left]
- \startcolor[TitleColor]
- \definedfont[RegularBold at 100pt]\setstrut
- \strut Con\TeX t \par
- \definedfont[RegularBold at 50pt]\setstrut
- \setups[text:commands]
- \vfill
- \definedfont[RegularBold at 150pt]\setstrut
- \setups[text:uppercase]
- \stopcolor
+ \dontcomplain
+ \setupalign[\v!left]
+ \startcolor[TitleColor]
+ \definedfont[RegularBold at 100pt]\setstrut
+ \strut Con\TeX t \par
+ \definedfont[RegularBold at 50pt]\setstrut
+ \setups[text:commands]
+ \vfill
+ \definedfont[RegularBold at 150pt]\setstrut
+ \setups[text:uppercase]
+ \stopcolor
\stopmakeup
\setuplayout % needed ?
@@ -211,18 +211,18 @@
[\c!background=]
\startmakeup[\v!standard]
- \dontcomplain
- \startcolor[TitleColor]
- \definedfont[RegularBold at 100pt]\setstrut
- \setupalign[\v!left]
- \strut Con\TeX t \par
- \definedfont[RegularBold at 50pt]\setstrut
- \setups[text:commands]
- \vfill
- \definedfont[RegularBold at 24pt]\setupinterlinespace
- \setups[text:lowercase]
- \par \strut \currentdate \par
- \stopcolor
+ \dontcomplain
+ \startcolor[TitleColor]
+ \definedfont[RegularBold at 100pt]\setstrut
+ \setupalign[\v!left]
+ \strut Con\TeX t \par
+ \definedfont[RegularBold at 50pt]\setstrut
+ \setups[text:commands]
+ \vfill
+ \definedfont[RegularBold at 24pt]\setupinterlinespace
+ \setups[text:lowercase]
+ \par \strut \currentdate \par
+ \stopcolor
\stopmakeup
\protect
@@ -241,16 +241,16 @@
[\c!background=back]
\startmakeup[\v!standard][\c!page=]
- \dontcomplain
- \startcolor[TitleColor]
- \definedfont[RegularBold at 24pt]\setupinterlinespace
- \setupalign[\v!left]
- \vfill
- PRAGMA ADE \par
- Ridderstraat 27 \par
- 8061GH Hasselt NL \par
- www.pragma-ade.com \par
- \stopcolor
+ \dontcomplain
+ \startcolor[TitleColor]
+ \definedfont[RegularBold at 24pt]\setupinterlinespace
+ \setupalign[\v!left]
+ \vfill
+ PRAGMA ADE \par
+ Ridderstraat 27 \par
+ 8061GH Hasselt NL \par
+ www.pragma-ade.com \par
+ \stopcolor
\stopmakeup
\protect
diff --git a/tex/generic/context/luatex-basics-gen.lua b/tex/generic/context/luatex-basics-gen.lua
index df5e7e6c4..ad12daa4e 100644
--- a/tex/generic/context/luatex-basics-gen.lua
+++ b/tex/generic/context/luatex-basics-gen.lua
@@ -218,3 +218,9 @@ function caches.savedata(path,name,data)
table.tofile(fullname,data,'return',false,true,false)
end
end
+
+--
+
+local table.setmetatableindex(t,f)
+ setmetatable(t,{ __index = f })
+end
diff --git a/tex/generic/context/luatex-fonts-demo-vf-1.lua b/tex/generic/context/luatex-fonts-demo-vf-1.lua
index b9f2a2c76..3878ae648 100644
--- a/tex/generic/context/luatex-fonts-demo-vf-1.lua
+++ b/tex/generic/context/luatex-fonts-demo-vf-1.lua
@@ -5,8 +5,8 @@ return function(specification)
local f2, id2 = fonts.constructors.readanddefine('lmsans10-regular', specification.size)
local f3, id3 = fonts.constructors.readanddefine('lmtypewriter10-regular',specification.size)
if f1 and f2 and f3 then
- f1.name = specification.name
- f1.virtualized = true
+ f1.properties.name = specification.name
+ f1.properties.virtualized = true
f1.fonts = {
{ id = id1 },
{ id = id2 },
diff --git a/tex/generic/context/luatex-fonts-merged.lua b/tex/generic/context/luatex-fonts-merged.lua
index b1c147c96..3c6391e92 100644
--- a/tex/generic/context/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
-- merged file : luatex-fonts-merged.lua
-- parent file : luatex-fonts.lua
--- merge date : 04/03/11 22:32:45
+-- merge date : 04/11/11 16:45:23
do -- begin closure to overcome local limits and interference
@@ -1079,10 +1079,6 @@ function table.fromhash(t)
return hsh
end
-table.serialize_functions = true
-table.serialize_compact = true
-table.serialize_inline = true
-
local noquotes, hexify, handle, reduce, compact, inline, functions
local reserved = table.tohash { -- intercept a language inconvenience: no reserved words as key
@@ -1368,15 +1364,36 @@ end
-- replacing handle by a direct t[#t+1] = ... (plus test) is not much
-- faster (0.03 on 1.00 for zapfino.tma)
-local function serialize(root,name,_handle,_reduce,_noquotes,_hexify)
- noquotes = _noquotes
- hexify = _hexify
- handle = _handle or print
- reduce = _reduce or false
- compact = table.serialize_compact
- inline = compact and table.serialize_inline
- functions = table.serialize_functions
+local function serialize(root,name,_handle,_reduce,_noquotes,_hexify) -- I might drop the _'s some day.
local tname = type(name)
+ if tname == "table" then
+ noquotes = name.noquotes
+ hexify = name.hexify
+ handle = name.handle or print
+ reduce = name.reduce or false
+ functions = name.functions
+ compact = name.compact
+ inline = name.inline and compact
+ name = name.name
+ tname = type(name)
+ if functions == nil then
+ functions = true
+ end
+ if compact == nil then
+ compact = true
+ end
+ if inline == nil then
+ inline = compact
+ end
+ else
+ noquotes = _noquotes
+ hexify = _hexify
+ handle = _handle or print
+ reduce = _reduce or false
+ compact = true
+ inline = true
+ functions = true
+ end
if tname == "string" then
if name == "return" then
handle("return {")
@@ -1443,12 +1460,11 @@ end
--
-- so this is on the todo list
-table.tofile_maxtab = 2*1024
+local maxtab = 2*1024
function table.tofile(filename,root,name,reduce,noquotes,hexify)
local f = io.open(filename,'w')
if f then
- local maxtab = table.tofile_maxtab
if maxtab > 1 then
local t, n = { }, 0
local function flush(s)
@@ -1666,8 +1682,12 @@ function table.sequenced(t,sep,simple) -- hash only
return concat(s, sep or " | ")
end
-function table.print(...)
- table.tohandle(print,...)
+function table.print(t,...)
+ if type(t) ~= "table" then
+ print(tostring(t))
+ else
+ table.tohandle(print,t,...)
+ end
end
-- -- -- obsolete but we keep them for a while and might comment them later -- -- --
@@ -1947,8 +1967,6 @@ function file.collapsepath(str,anchor)
end
end
-file.collapse_path = file.collapsepath
-
--~ local function test(str)
--~ print(string.format("%-20s %-15s %-15s",str,file.collapsepath(str),file.collapsepath(str,true)))
--~ end
@@ -2585,6 +2603,12 @@ function caches.savedata(path,name,data)
end
end
+--
+
+local table.setmetatableindex(t,f)
+ setmetatable(t,{ __index = f })
+end
+
end -- closure
do -- begin closure to overcome local limits and interference
@@ -2883,13 +2907,11 @@ if not modules then modules = { } end modules ['font-con'] = {
local utf = unicode.utf8
-local next, tostring, setmetatable, rawget = next, tostring, setmetatable, rawget
+local next, tostring, rawget = next, tostring, rawget
local format, match, lower, gsub = string.format, string.match, string.lower, string.gsub
local utfbyte = utf.byte
local sort, insert, concat, sortedkeys, serialize, fastcopy = table.sort, table.insert, table.concat, table.sortedkeys, table.serialize, table.fastcopy
-local allocate = utilities.storage.allocate
-
local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end)
local trace_scaling = false trackers.register("fonts.scaling" , function(v) trace_scaling = v end)
@@ -2911,6 +2933,9 @@ local specifiers = fonts.specifiers
local contextsetups = specifiers.contextsetups
local contextnumbers = specifiers.contextnumbers
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
+
-- will be directives
constructors.dontembed = allocate()
@@ -3544,7 +3569,7 @@ function constructors.finalize(tfmdata)
--
if not tfmdata.descriptions then
local descriptions = { } -- yes or no
- setmetatable(descriptions, { __index = function(t,k) local v = { } t[k] = v return v end })
+ setmetatableindex(descriptions, function(t,k) local v = { } t[k] = v return v end)
tfmdata.descriptions = descriptions
end
--
@@ -3742,16 +3767,14 @@ end
local formats = allocate()
fonts.formats = formats
-setmetatable(formats, {
- __index = function(t,k)
- local l = lower(k)
- if rawget(t,k) then
- t[k] = l
- return l
- end
- return rawget(t,file.extname(l))
+setmetatableindex(formats, function(t,k)
+ local l = lower(k)
+ if rawget(t,k) then
+ t[k] = l
+ return l
end
-} )
+ return rawget(t,file.extname(l))
+end)
local locations = { }
@@ -3851,7 +3874,7 @@ function constructors.newfeatures(what)
local features = handlers[what].features
if not features then
local tables = handlers[what].tables -- can be preloaded
- features = {
+ features = allocate {
defaults = { },
descriptions = tables and tables.features or { },
initializers = { base = { }, node = { } },
@@ -4777,7 +4800,7 @@ local otf = fonts.handlers.otf
otf.glists = { "gsub", "gpos" }
-otf.version = 2.721 -- beware: also sync font-mis.lua
+otf.version = 2.722 -- beware: also sync font-mis.lua
otf.cache = containers.define("fonts", "otf", otf.version, true)
local fontdata = fonts.hashes.identifiers
@@ -5902,13 +5925,55 @@ end
-- to be checked italic_correction
+local function check_variants(unicode,the_variants,splitter,unicodes)
+ local variants = the_variants.variants
+ if variants then -- use splitter
+ local glyphs = lpegmatch(splitter,variants)
+ local done = { [unicode] = true }
+ local n = 0
+ for i=1,#glyphs do
+ local g = glyphs[i]
+ if done[g] then
+ report_otf("skipping cyclic reference U+%05X in math variant U+%05X",g,unicode)
+ elseif n == 0 then
+ n = 1
+ variants = { g }
+ else
+ n = n + 1
+ variants[n] = g
+ end
+ end
+ if n == 0 then
+ variants = nil
+ end
+ end
+ local parts = the_variants.parts
+ if parts then
+ local p = #parts
+ if p > 0 then
+ for i=1,p do
+ local pi = parts[i]
+ pi.glyph = unicodes[pi.component] or 0
+ pi.component = nil
+ end
+ else
+ parts = nil
+ end
+ end
+ local italic_correction = the_variants.italic_correction
+ if italic_correction and italic_correction == 0 then
+ italic_correction = nil
+ end
+ return variants, parts, italic_correction
+end
+
actions["analyze math"] = function(data,filename,raw)
if raw.math then
data.metadata.math = raw.math
local unicodes = data.resources.unicodes
local splitter = data.helpers.tounicodetable
for unicode, description in next, data.descriptions do
- local glyph = description.glyph
+ local glyph = description.glyph
local mathkerns = glyph.mathkern -- singular
local horiz_variants = glyph.horiz_variants
local vert_variants = glyph.vert_variants
@@ -5933,56 +5998,10 @@ actions["analyze math"] = function(data,filename,raw)
math.kerns = mathkerns
end
if horiz_variants then
- local variants = horiz_variants.variants
- if variants then -- use splitter
- local glyphs = lpegmatch(splitter,variants)
- for i=1,#glyphs do
- if glyphs[i] == u then
- remove(glyphs,i)
- break
- end
- end
- math.horiz_variants = glyphs
- end
- local parts = horiz_variants.parts
- if parts and #parts > 0 then
- for i=1,#parts do
- local pi = parts[i]
- pi.glyph = unicodes[pi.component] or 0
- pi.component = nil
- end
- math.horiz_parts = parts
- end
- local italic_correction = horiz_variants.italic_correction
- if italic_correction and italic_correction ~= 0 then
- math.horiz_italic_correction = italic_correction
- end
+ math.horiz_variants, math.horiz_parts, math.horiz_italic_correction = check_variants(unicode,horiz_variants,splitter,unicodes)
end
if vert_variants then
- local variants = vert_variants.variants
- if variants then
- local glyphs = lpegmatch(splitter,variants)
- for i=1,#glyphs do
- if glyphs[i] == u then
- remove(glyphs,i)
- break
- end
- end
- math.vert_variants = glyphs
- end
- local p = vert_variants.parts
- if parts and #parts > 0 then
- for i=1,#parts do
- local pi = parts[i]
- pi.glyph = unicodes[pi.component] or 0
- pi.component = nil
- end
- math.vert_parts = parts
- end
- local italic_correction = vert_variants.italic_correction
- if italic_correction and italic_correction ~= 0 then
- math.vert_italic_correction = italic_correction
- end
+ math.vert_variants, math.vert_parts, math.vert_italic_correction = check_variants(unicode,vert_variants,splitter,unicodes)
end
local italic_correction = description.italic
if italic_correction and italic_correction ~= 0 then
@@ -6340,25 +6359,39 @@ local function copytotfm(data,cache_id)
local m = d.math
if m then
-- watch out: luatex uses horiz_variants for the parts
- local variants, parts = m.horiz_variants, m.horiz_parts
+ local variants = m.horiz_variants
+ local parts = m.horiz_parts
+ -- local done = { [unicode] = true }
if variants then
local c = character
for i=1,#variants do
local un = variants[i]
- c.next = un
- c = characters[un]
+ -- if done[un] then
+ -- -- report_otf("skipping cyclic reference U+%05X in math variant U+%05X",un,unicode)
+ -- else
+ c.next = un
+ c = characters[un]
+ -- done[un] = true
+ -- end
end -- c is now last in chain
c.horiz_variants = parts
elseif parts then
character.horiz_variants = parts
end
- local variants, parts = m.vert_variants, m.vert_parts
+ local variants = m.vert_variants
+ local parts = m.vert_parts
+ -- local done = { [unicode] = true }
if variants then
local c = character
for i=1,#variants do
local un = variants[i]
- c.next = un
- c = characters[un]
+ -- if done[un] then
+ -- -- report_otf("skipping cyclic reference U+%05X in math variant U+%05X",un,unicode)
+ -- else
+ c.next = un
+ c = characters[un]
+ -- done[un] = true
+ -- end
end -- c is now last in chain
c.vert_variants = parts
elseif parts then
@@ -7852,6 +7885,8 @@ local find_node_tail = node.tail or node.slide
local set_attribute = node.set_attribute
local has_attribute = node.has_attribute
+local setmetatableindex = table.setmetatableindex
+
local zwnj = 0x200C
local zwj = 0x200D
local wildcard = "*"
@@ -8148,7 +8183,7 @@ function handlers.gsub_multiple(start,kind,lookupname,multiple)
return multiple_glyphs(start,multiple)
end
-function handlers.gsub_ligature(start,kind,lookupname,ligature,sequence) --or maybe pass lookup ref
+function handlers.gsub_ligature(start,kind,lookupname,ligature,sequence)
local s, stop, discfound = start.next, nil, false
local startchar = start.char
if marks[startchar] then
@@ -8169,14 +8204,18 @@ function handlers.gsub_ligature(start,kind,lookupname,ligature,sequence) --or ma
end
if stop then
local lig = ligature.ligature
- if trace_ligatures then
- local stopchar = stop.char
- start = markstoligature(kind,lookupname,start,stop,lig)
- logprocess("%s: replacing %s upto %s by ligature %s",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char))
+ if lig then
+ if trace_ligatures then
+ local stopchar = stop.char
+ start = markstoligature(kind,lookupname,start,stop,lig)
+ logprocess("%s: replacing %s upto %s by ligature %s",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char))
+ else
+ start = markstoligature(kind,lookupname,start,stop,lig)
+ end
+ return start, true
else
- start = markstoligature(kind,lookupname,start,stop,lig)
+ -- ok, goto next lookup
end
- return start, true
end
else
local skipmark = sequence.flags[1]
@@ -8209,14 +8248,18 @@ function handlers.gsub_ligature(start,kind,lookupname,ligature,sequence) --or ma
end
if stop then
local lig = ligature.ligature
- if trace_ligatures then
- local stopchar = stop.char
- start = toligature(kind,lookupname,start,stop,lig,skipmark,discfound)
- logprocess("%s: replacing %s upto %s by ligature %s",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char))
+ if lig then
+ if trace_ligatures then
+ local stopchar = stop.char
+ start = toligature(kind,lookupname,start,stop,lig,skipmark,discfound)
+ logprocess("%s: replacing %s upto %s by ligature %s",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char))
+ else
+ start = toligature(kind,lookupname,start,stop,lig,skipmark,discfound)
+ end
+ return start, true
else
- start = toligature(kind,lookupname,start,stop,lig,skipmark,discfound)
+ -- ok, goto next lookup
end
- return start, true
end
end
return start, false
@@ -9529,16 +9572,14 @@ local resolved = { } -- we only resolve a font,script,language pair once
local lookuphashes = { }
-setmetatable(lookuphashes, { __index =
- function(t,font)
- local lookuphash = fontdata[font].resources.lookuphash
- if not lookuphash or not next(lookuphash) then
- lookuphash = false
- end
- t[font] = lookuphash
- return lookuphash
+setmetatableindex(lookuphashes, function(t,font)
+ local lookuphash = fontdata[font].resources.lookuphash
+ if not lookuphash or not next(lookuphash) then
+ lookuphash = false
end
-})
+ t[font] = lookuphash
+ return lookuphash
+end)
-- fonts.hashes.lookups = lookuphashes
@@ -9585,11 +9626,11 @@ function otf.dataset(ftfmdata,sequences,font) -- generic variant, overloaded in
if not rl then
rl = { }
rs[language] = rl
- setmetatable(rl, { __index = function(t,k)
+ setmetatableindex(rl, function(t,k)
local v = enabled and initialize(sequences[k],script,language,enabled)
t[k] = v
return v
- end})
+ end)
end
return rl
end
@@ -10197,14 +10238,15 @@ if not trackers then trackers = { register = function() end } end
local trace_analyzing = false trackers.register("otf.analyzing", function(v) trace_analyzing = v end)
-local fonts, nodes = fonts, nodes
-local node = node
+local fonts, nodes, node = fonts, nodes, node
+
+local allocate = utilities.storage.allocate
local otf = fonts.handlers.otf
local analyzers = fonts.analyzers
-local initializers = { }
-local methods = { }
+local initializers = allocate()
+local methods = allocate()
analyzers.initializers = initializers
analyzers.methods = methods
@@ -10987,18 +11029,17 @@ function definers.read(specification,size,id) -- id can be optional, name can al
if not tfmdata then -- or id?
report_defining( "unknown font %s, loading aborted",specification.name)
elseif trace_defining and type(tfmdata) == "table" then
- constructors.finalize(tfmdata)
- -- local properties = tfmdata.properties or { }
- -- local parameters = tfmdata.parameters or { }
+ local properties = tfmdata.properties or { }
+ local parameters = tfmdata.parameters or { }
report_defining("using %s font with id %s, name:%s size:%s bytes:%s encoding:%s fullname:%s filename:%s",
- properties.type or "unknown",
- id or "?",
- properties.name or "?",
- parameters.size or "default",
- properties.encodingbytes or "?",
- properties.encodingname or "unicode",
- properties.fullname or "?",
- file.basename(properties.filename or "?"))
+ properties.type or "unknown",
+ id or "?",
+ properties.name or "?",
+ parameters.size or "default",
+ properties.encodingbytes or "?",
+ properties.encodingname or "unicode",
+ properties.fullname or "?",
+ file.basename(properties.filename or "?"))
end
statistics.stoptiming(fonts)
return tfmdata
@@ -11008,7 +11049,7 @@ end
We overload the reader.
--ldx]]--
-callbacks.register('define_font' , definers.read, "definition of fonts (tfmdata preparation)")
+callbacks.register('define_font', definers.read, "definition of fonts (tfmdata preparation)")
end -- closure
diff --git a/tex/generic/context/luatex-test.tex b/tex/generic/context/luatex-test.tex
index 9f57cfea9..1c3aeb1b6 100644
--- a/tex/generic/context/luatex-test.tex
+++ b/tex/generic/context/luatex-test.tex
@@ -52,4 +52,8 @@
\mine \input tufte \par
+
+% \font\mine=file:luatex-fonts-demo-vf-2.lua at 12pt \mine [abab] \par
+% \font\mine=file:luatex-fonts-demo-vf-3.lua at 12pt \mine [abab] \par
+
\end
--
cgit v1.2.3