From dbbbbfac3d158709a07af8c26e68284d1b0ea202 Mon Sep 17 00:00:00 2001
From: Marius 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. We save multi-pass information in the main utility table. This is a
bit of a mess because we support old and new methods.
Before a font is passed to
We overload the
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
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
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 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:
- -With this in place, we can now implement a proper datatype for dimensions, one -that permits us to do this:
- -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:
- -We also need to provide a function for conversion to string (so that
-we can print dimensions). We print them as points, just like
Since it does not take much code, we also provide a way to access -a few accessors
- -In the converter from string to dimension we support functions as
-factors. This is because in
The previous code is rather efficient (also thanks to
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 = "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
Internally
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
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 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:
+ +With this in place, we can now implement a proper datatype for dimensions, one +that permits us to do this:
+ +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:
+ +We also need to provide a function for conversion to string (so that
+we can print dimensions). We print them as points, just like
Since it does not take much code, we also provide a way to access +a few accessors
+ +In the converter from string to dimension we support functions as
+factors. This is because in
The previous code is rather efficient (also thanks to
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 @@ endWe overload the