summaryrefslogtreecommitdiff
path: root/tex
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2013-03-05 16:40:00 +0100
committerHans Hagen <pragma@wxs.nl>2013-03-05 16:40:00 +0100
commit7be0d39244155e874321d77ef81078c5bd2817a9 (patch)
tree0c09404e97c825961c5ee25a31ecab080eff54e6 /tex
parent4eeccc18e84e817ecf7045bcb0a8d35875006f42 (diff)
downloadcontext-7be0d39244155e874321d77ef81078c5bd2817a9.tar.gz
beta 2013.03.05 16:40
Diffstat (limited to 'tex')
-rw-r--r--tex/context/base/attr-mkr.lua12
-rw-r--r--tex/context/base/back-exp.lua39
-rw-r--r--tex/context/base/cont-new.mkii2
-rw-r--r--tex/context/base/cont-new.mkiv2
-rw-r--r--tex/context/base/context-version.pdfbin4123 -> 4135 bytes
-rw-r--r--tex/context/base/context-version.pngbin40213 -> 40313 bytes
-rw-r--r--tex/context/base/context.mkii2
-rw-r--r--tex/context/base/context.mkiv2
-rw-r--r--tex/context/base/font-ctx.lua30
-rw-r--r--tex/context/base/font-gds.lua3
-rw-r--r--tex/context/base/font-odv.lua1305
-rw-r--r--tex/context/base/font-ota.lua106
-rw-r--r--tex/context/base/font-otd.lua4
-rw-r--r--tex/context/base/font-otn.lua336
-rw-r--r--tex/context/base/font-sol.lua16
-rw-r--r--tex/context/base/l-boolean.lua16
-rw-r--r--tex/context/base/lang-wrd.lua10
-rw-r--r--tex/context/base/lpdf-tag.lua14
-rw-r--r--tex/context/base/math-noa.lua295
-rw-r--r--tex/context/base/math-tag.lua72
-rw-r--r--tex/context/base/node-acc.lua14
-rw-r--r--tex/context/base/node-aux.lua31
-rw-r--r--tex/context/base/node-bck.lua32
-rw-r--r--tex/context/base/node-fin.lua61
-rw-r--r--tex/context/base/node-fnt.lua170
-rw-r--r--tex/context/base/node-inj.lua71
-rw-r--r--tex/context/base/node-mig.lua8
-rw-r--r--tex/context/base/node-ref.lua19
-rw-r--r--tex/context/base/node-rul.lua22
-rw-r--r--tex/context/base/node-tra.lua33
-rw-r--r--tex/context/base/page-lin.lua11
-rw-r--r--tex/context/base/scrn-hlp.lua3
-rw-r--r--tex/context/base/scrp-cjk.lua19
-rw-r--r--tex/context/base/scrp-eth.lua5
-rw-r--r--tex/context/base/scrp-ini.lua16
-rw-r--r--tex/context/base/spac-adj.lua17
-rw-r--r--tex/context/base/spac-ali.lua8
-rw-r--r--tex/context/base/spac-chr.lua12
-rw-r--r--tex/context/base/spac-ver.lua41
-rw-r--r--tex/context/base/status-files.pdfbin24788 -> 24803 bytes
-rw-r--r--tex/context/base/status-lua.pdfbin208938 -> 209215 bytes
-rw-r--r--tex/context/base/strc-mar.lua5
-rw-r--r--tex/context/base/trac-jus.lua8
-rw-r--r--tex/context/base/trac-vis.lua70
-rw-r--r--tex/context/base/typo-bld.lua3
-rw-r--r--tex/context/base/typo-brk.lua7
-rw-r--r--tex/context/base/typo-cap.lua11
-rw-r--r--tex/context/base/typo-cln.lua5
-rw-r--r--tex/context/base/typo-dig.lua7
-rw-r--r--tex/context/base/typo-dir.lua13
-rw-r--r--tex/context/base/typo-itc.lua3
-rw-r--r--tex/context/base/typo-krn.lua8
-rw-r--r--tex/context/base/typo-mar.lua15
-rw-r--r--tex/context/base/typo-pag.lua13
-rw-r--r--tex/context/base/typo-par.lua11
-rw-r--r--tex/context/base/typo-rep.lua3
-rw-r--r--tex/context/base/typo-spa.lua6
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua18
58 files changed, 984 insertions, 2081 deletions
diff --git a/tex/context/base/attr-mkr.lua b/tex/context/base/attr-mkr.lua
index c809d53a9..976598fa0 100644
--- a/tex/context/base/attr-mkr.lua
+++ b/tex/context/base/attr-mkr.lua
@@ -6,23 +6,21 @@ if not modules then modules = { } end modules ['attr-mkr'] = {
license = "see context related readme files"
}
-local has_attribute = node.has_attribute
-
local markers = nodes.markers or { }
nodes.markers = markers
-local cache = { }
-local numbers = attributes.numbers
-local unknown = attributes.private("marker:unknown")
+local cache = { }
+local numbers = attributes.numbers
+local a_unknown = attributes.private("marker:unknown")
table.setmetatableindex(cache,function(t,k)
local k = "marker:" .. k
- local v = numbers[k] or unknown
+ local v = numbers[k] or a_unknown
t[k] = v
return v
end)
function markers.get(n,name)
local a = cache[name]
- return a and has_attribute(n,a) or nil
+ return a and n[a] or nil
end
diff --git a/tex/context/base/back-exp.lua b/tex/context/base/back-exp.lua
index 37af87505..5d8b4cc8c 100644
--- a/tex/context/base/back-exp.lua
+++ b/tex/context/base/back-exp.lua
@@ -88,15 +88,12 @@ local a_reference = attributes.private('reference')
local a_textblock = attributes.private("textblock")
-local has_attribute = node.has_attribute
-local set_attribute = node.set_attribute
local traverse_id = node.traverse_id
local traverse_nodes = node.traverse
local slide_nodelist = node.slide
local texattribute = tex.attribute
local texdimen = tex.dimen
local texcount = tex.count
-local unsetvalue = attributes.unsetvalue
local locate_node = nodes.locate
local references = structures.references
@@ -1844,7 +1841,7 @@ local function collectresults(head,list) -- is last used (we also have currentat
for n in traverse_nodes(head) do
local id = n.id -- 14: image, 8: literal (mp)
if id == glyph_code then
- local at = has_attribute(n,a_tagged)
+ local at = n[a_tagged]
if not at then
-- we need to tag the pagebody stuff as being valid skippable
--
@@ -1863,7 +1860,7 @@ local function collectresults(head,list) -- is last used (we also have currentat
-- end
pushcontent()
currentnesting = tl
- currentparagraph = has_attribute(n,a_taggedpar)
+ currentparagraph = n[a_taggedpar]
currentattribute = at
last = at
pushentry(currentnesting)
@@ -1872,13 +1869,13 @@ local function collectresults(head,list) -- is last used (we also have currentat
end
-- We need to intercept this here; maybe I will also move this
-- to a regular setter at the tex end.
- local r = has_attribute(n,a_reference)
+ local r = n[a_reference]
if r then
referencehash[tl[#tl]] = r -- fulltag
end
--
elseif last then
- local ap = has_attribute(n,a_taggedpar)
+ local ap = n[a_taggedpar]
if ap ~= currentparagraph then
pushcontent(format("new paragraph (%s -> %s)",tostring(currentparagraph),tostring(ap)))
pushentry(currentnesting)
@@ -1893,7 +1890,7 @@ local function collectresults(head,list) -- is last used (we also have currentat
report_export("%s<!-- processing glyph %s (tag %s) -->",spaces[currentdepth],tracedchar(c),at)
end
end
- local s = has_attribute(n,a_exportstatus)
+ local s = n[a_exportstatus]
if s then
c = s
end
@@ -1902,7 +1899,7 @@ local function collectresults(head,list) -- is last used (we also have currentat
report_export("%s<!-- skipping last glyph -->",spaces[currentdepth])
end
elseif c == 0x20 then
- local a = has_attribute(n,a_characters)
+ local a = n[a_characters]
nofcurrentcontent = nofcurrentcontent + 1
if a then
if trace_export then
@@ -1947,11 +1944,11 @@ local function collectresults(head,list) -- is last used (we also have currentat
collectresults(n.replace,nil)
elseif id == glue_code then
-- we need to distinguish between hskips and vskips
- local ca = has_attribute(n,a_characters)
+ local ca = n[a_characters]
if ca == 0 then
-- skip this one ... already converted special character (node-acc)
elseif ca then
- local a = has_attribute(n,a_tagged)
+ local a = n[a_tagged]
if a then
local c = specialspaces[ca]
if last ~= a then
@@ -1961,13 +1958,13 @@ local function collectresults(head,list) -- is last used (we also have currentat
end
pushcontent()
currentnesting = tl
- currentparagraph = has_attribute(n,a_taggedpar)
+ currentparagraph = n[a_taggedpar]
currentattribute = a
last = a
pushentry(currentnesting)
-- no reference check (see above)
elseif last then
- local ap = has_attribute(n,a_taggedpar)
+ local ap = n[a_taggedpar]
if ap ~= currentparagraph then
pushcontent(format("new paragraph (%s -> %s)",tostring(currentparagraph),tostring(ap)))
pushentry(currentnesting)
@@ -1992,7 +1989,7 @@ local function collectresults(head,list) -- is last used (we also have currentat
if subtype == userskip_code then
if n.spec.width > threshold then
if last and not somespace[currentcontent[nofcurrentcontent]] then
- local a = has_attribute(n,a_tagged)
+ local a = n[a_tagged]
if a == last then
if trace_export then
report_export("%s<!-- injecting spacing 5a -->",spaces[currentdepth])
@@ -2019,7 +2016,7 @@ local function collectresults(head,list) -- is last used (we also have currentat
end
elseif subtype == spaceskip_code or subtype == xspaceskip_code then
if not somespace[currentcontent[nofcurrentcontent]] then
- local a = has_attribute(n,a_tagged)
+ local a = n[a_tagged]
if a == last then
if trace_export then
report_export("%s<!-- injecting spacing 7 (stay in element) -->",spaces[currentdepth])
@@ -2048,7 +2045,7 @@ local function collectresults(head,list) -- is last used (we also have currentat
nofcurrentcontent = nofcurrentcontent - 1
end
elseif not somespace[r] then
- local a = has_attribute(n,a_tagged)
+ local a = n[a_tagged]
if a == last then
if trace_export then
report_export("%s<!-- injecting spacing 1 (end of line, stay in element) -->",spaces[currentdepth])
@@ -2076,9 +2073,9 @@ local function collectresults(head,list) -- is last used (we also have currentat
end
end
elseif id == hlist_code or id == vlist_code then
- local ai = has_attribute(n,a_image)
+ local ai = n[a_image]
if ai then
- local at = has_attribute(n,a_tagged)
+ local at = n[a_tagged]
if nofcurrentcontent > 0 then
pushcontent()
pushentry(currentnesting) -- ??
@@ -2102,7 +2099,7 @@ local function collectresults(head,list) -- is last used (we also have currentat
end
if kern > limit then
if last and not somespace[currentcontent[nofcurrentcontent]] then
- local a = has_attribute(n,a_tagged)
+ local a = n[a_tagged]
if a == last then
if not somespace[currentcontent[nofcurrentcontent]] then
if trace_export then
@@ -2155,9 +2152,9 @@ function builders.paragraphs.tag(head)
for n in traverse_id(hlist_code,head) do
local subtype = n.subtype
if subtype == line_code then
- set_attribute(n,a_textblock,noftextblocks)
+ n[a_textblock] = noftextblocks
elseif subtype == glue_code or subtype == kern_code then
- set_attribute(n,a_textblock,0)
+ n[a_textblock] = 0
end
end
return false
diff --git a/tex/context/base/cont-new.mkii b/tex/context/base/cont-new.mkii
index 595673889..d48699773 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{2013.03.04 18:28}
+\newcontextversion{2013.03.05 16:40}
%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 d57ae6a48..5f1458551 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{2013.03.04 18:28}
+\newcontextversion{2013.03.05 16:40}
%D This file is loaded at runtime, thereby providing an excellent place for
%D hacks, patches, extensions and new features.
diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf
index b1f6dc675..b4229a6ae 100644
--- a/tex/context/base/context-version.pdf
+++ b/tex/context/base/context-version.pdf
Binary files differ
diff --git a/tex/context/base/context-version.png b/tex/context/base/context-version.png
index d0dbca3ea..429cde9e0 100644
--- a/tex/context/base/context-version.png
+++ b/tex/context/base/context-version.png
Binary files differ
diff --git a/tex/context/base/context.mkii b/tex/context/base/context.mkii
index d99c0fea8..6295767a5 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{2013.03.04 18:28}
+\edef\contextversion{2013.03.05 16:40}
%D For those who want to use this:
diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv
index 1be6780bf..991356070 100644
--- a/tex/context/base/context.mkiv
+++ b/tex/context/base/context.mkiv
@@ -25,7 +25,7 @@
%D up and the dependencies are more consistent.
\edef\contextformat {\jobname}
-\edef\contextversion{2013.03.04 18:28}
+\edef\contextversion{2013.03.05 16:40}
%D For those who want to use this:
diff --git a/tex/context/base/font-ctx.lua b/tex/context/base/font-ctx.lua
index 1e10e2e68..611da4c97 100644
--- a/tex/context/base/font-ctx.lua
+++ b/tex/context/base/font-ctx.lua
@@ -1635,9 +1635,8 @@ local registerotffeature = otffeatures.register
local analyzers = fonts.analyzers
local methods = analyzers.methods
-local get_attribute = node.has_attribute
-local set_attribute = node.set_attribute
-local unset_attribute = node.unset_attribute
+local unsetvalue = attributes.unsetvalue
+
local traverse_by_id = node.traverse_id
local a_color = attributes.private('color')
@@ -1647,23 +1646,34 @@ local m_color = attributes.list[a_color] or { }
local glyph_code = nodes.nodecodes.glyph
+local states = analyzers.states
+
local names = {
- "font:1", "font:2", "font:3", "font:3", -- arabic
- "font:4", "font:5", "font:6", "font:7", "font:8", "font:9", -- devanagary
+ [states.init] = "font:1",
+ [states.medi] = "font:2",
+ [states.fina] = "font:3",
+ [states.isol] = "font:4",
+ [states.mark] = "font:5",
+ [states.rest] = "font:6",
+ [states.rphf] = "font:1",
+ [states.half] = "font:2",
+ [states.pref] = "font:3",
+ [states.blwf] = "font:4",
+ [states.pstf] = "font:5",
}
local function markstates(head)
if head then
- local model = get_attribute(head,a_colormodel) or 1
+ local model = head[a_colormodel] or 1
for glyph in traverse_by_id(glyph_code,head) do
- local a = get_attribute(glyph,a_state)
+ local a = glyph[a_state]
if a then
local name = names[a]
if name then
local color = m_color[name]
if color then
- set_attribute(glyph,a_colormodel,model)
- set_attribute(glyph,a_color,color)
+ glyph[a_colormodel] = model
+ glyph[a_color] = color
end
end
end
@@ -1707,7 +1717,7 @@ registerotffeature { -- adapts
function methods.nocolor(head,font,attr)
for n in traverse_by_id(glyph_code,head) do
if not font or n.font == font then
- unset_attribute(n,a_color)
+ n[a_color] = unsetvalue
end
end
return head, true
diff --git a/tex/context/base/font-gds.lua b/tex/context/base/font-gds.lua
index ea24b203a..68a2317ab 100644
--- a/tex/context/base/font-gds.lua
+++ b/tex/context/base/font-gds.lua
@@ -300,7 +300,6 @@ end
local fontdata = fonts.hashes.identifiers
local setnodecolor = nodes.tracers.colors.set
-local has_attribute = node.has_attribute
local traverse_id = node.traverse_id
local a_colorscheme = attributes.private('colorscheme')
local glyph = node.id("glyph")
@@ -309,7 +308,7 @@ function colorschemes.coloring(head)
local lastfont, lastscheme
local done = false
for n in traverse_id(glyph,head) do
- local a = has_attribute(n,a_colorscheme)
+ local a = n[a_colorscheme]
if a then
local f = n.font
if f ~= lastfont then
diff --git a/tex/context/base/font-odv.lua b/tex/context/base/font-odv.lua
index c4def223e..7904bdb59 100644
--- a/tex/context/base/font-odv.lua
+++ b/tex/context/base/font-odv.lua
@@ -6,20 +6,6 @@ if not modules then modules = { } end modules ['font-odv'] = {
license = "see context related readme files"
}
-if true then
- -- Not yet as there is some change in headnode handling as needed
- -- for this mechanism and I won't adapt this code because soon there's
- -- another adaption coming (already in my private tree) but that need
- -- a newer luatex.
- return
-end
-
--- Kai: we're leaking nodes (happens when assigning start nodes behind start, also
--- in the original code) so this needs to be sorted out. As I touched nearly all code,
--- reshuffled, etc. etc. (imagine how much can get messed up in nearly a week work) it
--- could be that I introduced bugs. There is more to gain (esp in the functions applied
--- to a range) but I'll do that when everything works as expected.
-
-- A few remarks:
--
-- This code is a partial rewrite of the code that deals with devanagari. The data and logic
@@ -29,6 +15,12 @@ end
-- deva: http://www.microsoft.com/typography/OpenType%20Dev/devanagari/introO.mspx
-- dev2: http://www.microsoft.com/typography/OpenType%20Dev/devanagari/intro.mspx
--
+-- As I touched nearly all code, reshuffled it, optimized a lot, etc. etc. (imagine how
+-- much can get messed up in over a week work) it could be that I introduced bugs. There
+-- is more to gain (esp in the functions applied to a range) but I'll do that when
+-- everything works as expected. Kai's original code is kept in font-odk.lua as a reference
+-- so blame me (HH) for bugs.
+--
-- Interesting is that Kai managed to write this on top of the existing otf handler. Only a
-- few extensions were needed, like a few more analyzing states and dealing with changed
-- head nodes in the core scanner as that only happens here. There's a lot going on here
@@ -38,16 +30,17 @@ end
-- The rewrite mostly deals with efficiency, both in terms of speed and code. We also made
-- sure that it suits generic use as well as use in ConTeXt. I removed some buglets but can
-- as well have messed up the logic by doing this. For this we keep the original around
--- as that serves as reference. I kept the comments but added a few more. Due to the lots
--- of reshuffling glyphs quite some leaks occur(red) but once I'm satisfied with the rewrite
--- I'll weed them. I also integrated initialization etc into the regular mechanisms.
+-- as that serves as reference. Due to the lots of reshuffling glyphs quite some leaks
+-- occur(red) but once I'm satisfied with the rewrite I'll weed them. I also integrated
+-- initialization etc into the regular mechanisms.
--
-- In the meantime, we're down from 25.5-3.5=22 seconds to 17.7-3.5=14.2 seconds for a 100
--- page sample with both variants so it's worth the effort. Due to the method chosen it will
--- never be real fast. If I ever become a power user I'll have a go at some further speed
--- up. I will rename some functions (and features) once we don't need to check the original
--- code. We now use a special subset sequence for use inside the analyzer (after all we could
--- can store this in the dataset and save redundant analysis).
+-- page sample (mid 2012) with both variants so it's worth the effort. Some more speedup is
+-- to be expected. Due to the method chosen it will never be real fast. If I ever become a
+-- power user I'll have a go at some further speed up. I will rename some functions (and
+-- features) once we don't need to check the original code. We now use a special subset
+-- sequence for use inside the analyzer (after all we could can store this in the dataset
+-- and save redundant analysis).
--
-- I might go for an array approach with respect to attributes (and reshuffling). Easier.
--
@@ -108,15 +101,14 @@ local registerotffeature = otffeatures.register
local processcharacters = nodes.handlers.characters
-local set_attribute = node.set_attribute
-local unset_attribute = node.unset_attribute
-local has_attribute = node.has_attribute
local insert_node_after = node.insert_after
local copy_node = node.copy
local free_node = node.free
local remove_node = node.remove
local flush_list = node.flush_list
+local unsetvalue = attributes.unsetvalue
+
local fontdata = fonts.hashes.identifiers
local a_state = attributes.private('state')
@@ -124,6 +116,14 @@ local a_syllabe = attributes.private('syllabe')
local dotted_circle = 0x25CC
+local states = fonts.analyzers.states -- not features
+
+local s_rphf = states.rphf
+local s_half = states.half
+local s_pref = states.pref
+local s_blwf = states.blwf
+local s_pstf = states.pstf
+
-- In due time there will be entries here for scripts like Bengali, Gujarati,
-- Gurmukhi, Kannada, Malayalam, Oriya, Tamil, Telugu. Feel free to provide the
-- code points.
@@ -176,35 +176,15 @@ local stress_tone_mark = {
[0x0951] = true, [0x0952] = true, [0x0953] = true, [0x0954] = true,
}
-local nukta = {
- [0x093C] = true,
-}
-
-local halant = {
- [0x094D] = true,
-}
-
-local ra = {
- [0x0930] = true,
-}
-
-local anudatta = {
- [0x0952] = true,
-}
-
-local nbsp = { -- might become a constant instead of table
- [0x00A0] = true,
-}
-
-local zwnj = { -- might become a constant instead of table
- [0x200C] = true,
-}
-
-local zwj = { -- might become a constant instead of table
- [0x200D] = true,
-}
+local c_nukta = 0x093C -- used to be tables
+local c_halant = 0x094D -- used to be tables
+local c_ra = 0x0930 -- used to be tables
+local c_anudatta = 0x0952 -- used to be tables
+local c_nbsp = 0x00A0 -- used to be tables
+local c_zwnj = 0x200C -- used to be tables
+local c_zwj = 0x200D -- used to be tables
-local zw_char = {
+local zw_char = { -- could also be inlined
[0x200C] = true,
[0x200D] = true,
}
@@ -292,7 +272,10 @@ local deva_defaults = {
local false_flags = { false, false, false, false }
-local both_joiners_true = { [0x200C] = true, [0x200D] = true }
+local both_joiners_true = {
+ [0x200C] = true,
+ [0x200D] = true,
+}
local sequence_reorder_matras = {
chain = 0,
@@ -483,38 +466,38 @@ local function deva_reorder(head,start,stop,font,attr)
local lastcons = nil
local basefound = false
- if ra[start.char] and halant[n.char] and reph then
+ if start.char == c_ra and n.char == c_halant and reph then
-- if syllable starts with Ra + H and script has 'Reph' then exclude Reph
-- from candidates for base consonants
if n == stop then
return head, stop
end
- if zwj[n.next.char] then
+ if n.next.char == c_zwj then
current = start
else
current = n.next
- set_attribute(start,a_state,5) -- rphf
+ start[a_state] = s_rphf
end
end
- if nbsp[current.char] then
+ if current.char == c_nbsp then
-- Stand Alone cluster
if current == stop then
stop = stop.prev
- head = remove_node(head, current)
+ head = remove_node(head,current)
free_node(current)
return head, stop
else
base, firstcons, lastcons = current, current, current
current = current.next
if current ~= stop then
- if nukta[current.char] then
+ if current.char == c_nukta then
current = current.next
end
- if zwj[current.char] then
+ if current.char == c_zwj then
if current ~= stop then
local next = current.next
- if next ~= stop and halant[next.char] then
+ if next ~= stop and next.char == c_halant then
current = next
next = current.next
local tmp = next.next
@@ -523,9 +506,9 @@ local function deva_reorder(head,start,stop,font,attr)
local nextcurrent = copy_node(current)
tempcurrent.next = nextcurrent
nextcurrent.prev = tempcurrent
- set_attribute(tempcurrent,a_state,8) --blwf
+ tempcurrent[a_state] = s_blwf
tempcurrent = processcharacters(tempcurrent)
- unset_attribute(tempcurrent,a_state)
+ tempcurrent[a_state] = unsetvalue
if next.char == tempcurrent.char then
flush_list(tempcurrent)
local n = copy_node(current)
@@ -552,7 +535,7 @@ local function deva_reorder(head,start,stop,font,attr)
while not basefound do
-- find base consonant
if consonant[current.char] then
- set_attribute(current,a_state,6) -- half
+ current[a_state] = s_half
if not firstcons then
firstcons = current
end
@@ -561,7 +544,7 @@ local function deva_reorder(head,start,stop,font,attr)
base = current
elseif blwfcache[current.char] then
-- consonant has below-base (or post-base) form
- set_attribute(current,a_state,8) -- blwf
+ current[a_state] = s_blwf
else
base = current
end
@@ -574,14 +557,14 @@ local function deva_reorder(head,start,stop,font,attr)
-- if base consonant is not last one then move halant from base consonant to last one
local np = base
local n = base.next
- if nukta[n.char] then
+ if n.char == c_nukta then
np = n
n = n.next
end
- if halant[n.char] then
+ if n.char == c_halant then
if lastcons ~= stop then
local ln = lastcons.next
- if nukta[ln.char] then
+ if ln.char == c_nukta then
lastcons = ln
end
end
@@ -603,7 +586,7 @@ local function deva_reorder(head,start,stop,font,attr)
end
n = start.next
- if ra[start.char] and halant[n.char] and not (n ~= stop and zw_char[n.next.char]) then
+ if start.char == c_ra and n.char == c_halant and not (n ~= stop and zw_char[n.next.char]) then
-- if syllable starts with Ra + H then move this combination so that it follows either:
-- the post-base 'matra' (if any) or the base consonant
local matra = base
@@ -640,16 +623,16 @@ local function deva_reorder(head,start,stop,font,attr)
local current = start
while current ~= stop do
local next = current.next
- if next ~= stop and halant[next.char] and zwnj[next.next.char] then
- unset_attribute(current,a_state)
+ if next ~= stop and next.char == c_halant and next.next.char == c_zwnj then
+ current[a_state] = unsetvalue
end
current = next
end
- if base ~= stop and has_attribute(base,a_state) then
+ if base ~= stop and base[a_state] then
local next = base.next
- if halant[next.char] and not (next ~= stop and zwj[next.next.char]) then
- unset_attribute(base,a_state)
+ if next.char == c_halant and not (next ~= stop and next.next.char == c_zwj) then
+ base[a_state] = unsetvalue
end
end
@@ -660,7 +643,7 @@ local function deva_reorder(head,start,stop,font,attr)
local current, allreordered, moved = start, false, { [base] = true }
local a, b, p, bn = base, base, base, base.next
- if base ~= stop and nukta[bn.char] then
+ if base ~= stop and bn.char == c_nukta then
a, b, p = bn, bn, bn
end
while not allreordered do
@@ -669,12 +652,12 @@ local function deva_reorder(head,start,stop,font,attr)
local n = current.next
local l = nil -- used ?
if c ~= stop then
- if nukta[n.char] then
+ if n.char == c_nukta then
c = n
n = n.next
end
if c ~= stop then
- if halant[n.char] then
+ if n.char == c_halant then
c = n
n = n.next
end
@@ -734,7 +717,7 @@ local function deva_reorder(head,start,stop,font,attr)
while current ~= stop do
local c = current
local n = current.next
- if ra[current.char] and halant[n.char] then
+ if current.char == c_ra and n.char == c_halant then
c = n
n = n.next
local b, bn = base, base
@@ -745,7 +728,7 @@ local function deva_reorder(head,start,stop,font,attr)
end
bn = next
end
- if has_attribute(current,a_state) == 5 then
+ if current[a_state] == s_rphf then
-- position Reph (Ra + H) after post-base 'matra' (if any) since these
-- become marks on the 'matra', not on the base glyph
if b ~= current then
@@ -797,10 +780,10 @@ local function deva_reorder(head,start,stop,font,attr)
end
else
local char = current.char
- if consonant[char] or nbsp[char] then -- maybe combined hash
+ if consonant[char] or char == c_nbsp then -- maybe combined hash
cns = current
local next = cns.next
- if halant[next.char] then
+ if next.char == c_halant then
cns = next
end
end
@@ -809,7 +792,7 @@ local function deva_reorder(head,start,stop,font,attr)
end
end
- if nbsp[base.char] then
+ if base.char == c_nbsp then
head = remove_node(head,base)
free_node(base)
end
@@ -826,19 +809,19 @@ end
-- so we break out ... this is only done for the first 'word' (if we feed words we can as
-- well test for non glyph.
-function handlers.devanagari_reorder_matras(start,kind,lookupname,replacement) -- no leak
+function handlers.devanagari_reorder_matras(head,start,kind,lookupname,replacement) -- no leak
local current = start -- we could cache attributes here
local startfont = start.font
- local startattr = has_attribute(start,a_syllabe)
+ local startattr = start[a_syllabe]
-- can be fast loop
- while current and current.id == glyph_code and current.subtype<256 and current.font == font and has_attribute(current,a_syllabe) == startattr do
+ while current and current.id == glyph_code and current.subtype<256 and current.font == font and current[a_syllabe] == startattr do
local next = current.next
- if halant[current.char] and not has_attribute(current,a_state) then
- if next and next.id == glyph_code and next.subtype<256 and next.font == font and has_attribute(next,a_syllabe) == startattr and zw_char[next.char] then
+ if current.char == c_halant and not current[a_state] then
+ if next and next.id == glyph_code and next.subtype<256 and next.font == font and next[a_syllabe] == startattr and zw_char[next.char] then
current = next
end
local startnext = start.next
- remove_node(start,start)
+ head = remove_node(head,start)
local next = current.next
if next then
next.prev = start
@@ -851,7 +834,7 @@ function handlers.devanagari_reorder_matras(start,kind,lookupname,replacement) -
end
current = next
end
- return start, true
+ return head, start, true
end
-- todo: way more caching of attributes and font
@@ -878,22 +861,22 @@ end
-- hm, this only looks at the start of a nodelist ... is this supposed to be line based?
-function handlers.devanagari_reorder_reph(start,kind,lookupname,replacement)
+function handlers.devanagari_reorder_reph(head,start,kind,lookupname,replacement)
-- since in Devanagari reph has reordering position 'before postscript' dev2 only follows step 2, 4, and 6,
-- the other steps are still ToDo (required for scripts other than dev2)
local current = start.next
local startnext = nil
local startprev = nil
local startfont = start.font
- local startattr = has_attribute(start,a_syllabe)
- while current and current.id == glyph_code and current.subtype<256 and current.font == startfont and has_attribute(current,a_syllabe) == startattr do --step 2
- if halant[current.char] and not has_attribute(current,a_state) then
+ local startattr = start[a_syllabe]
+ while current and current.id == glyph_code and current.subtype<256 and current.font == startfont and current[a_syllabe] == startattr do --step 2
+ if current.char == c_halant and not current[a_state] then
local next = current.next
- if next and next.id == glyph_code and next.subtype<256 and next.font == startfont and has_attribute(next,a_syllabe) == startattr and zw_char[next.char] then
+ if next and next.id == glyph_code and next.subtype<256 and next.font == startfont and next[a_syllabe] == startattr and zw_char[next.char] then
current = next
end
startnext = start.next
- remove_node(start,start)
+ head = remove_node(head,start)
local next = current.next
if next then
next.prev = start
@@ -902,24 +885,24 @@ function handlers.devanagari_reorder_reph(start,kind,lookupname,replacement)
current.next = start
start.prev = current
start = startnext
- startattr = has_attribute(start,a_syllabe)
+ startattr = start[a_syllabe]
break
end
current = current.next
end
if not startnext then
current = start.next
- while current and current.id == glyph_code and current.subtype<256 and current.font == startfont and has_attribute(current,a_syllabe) == startattr do --step 4
- if has_attribute(current,a_state) == 9 then --post-base
+ while current and current.id == glyph_code and current.subtype<256 and current.font == startfont and current[a_syllabe] == startattr do --step 4
+ if current[a_state] == s_pstf then --post-base
startnext = start.next
- remove_node(start,start)
+ head = remove_node(head,start)
local prev = current.prev
start.prev = prev
prev.next = start
start.next = current
current.prev = start
start = startnext
- startattr = has_attribute(start,a_syllabe)
+ startattr = start[a_syllabe]
break
end
current = current.next
@@ -931,7 +914,7 @@ function handlers.devanagari_reorder_reph(start,kind,lookupname,replacement)
if not startnext then
current = start.next
local c = nil
- while current and current.id == glyph_code and current.subtype<256 and current.font == startfont and has_attribute(current,a_syllabe) == startattr do --step 5
+ while current and current.id == glyph_code and current.subtype<256 and current.font == startfont and current[a_syllabe] == startattr do --step 5
if not c then
local char = current.char
-- todo: combine in one
@@ -944,27 +927,28 @@ function handlers.devanagari_reorder_reph(start,kind,lookupname,replacement)
-- here we can loose the old start node: maybe best split cases
if c then
startnext = start.next
- remove_node(start,start)
+ head = remove_node(head,start)
local prev = c.prev
start.prev = prev
prev.next = start
start.next = c
c.prev = start
+ -- end
start = startnext
- startattr = has_attribute(start,a_syllabe)
+ startattr = start[a_syllabe]
end
end
-- leaks
if not startnext then
current = start
local next = current.next
- while next and next.id == glyph_code and next.subtype<256 and next.font == startfont and has_attribute(next,a_syllabe) == startattr do --step 6
+ while next and next.id == glyph_code and next.subtype<256 and next.font == startfont and next[a_syllabe] == startattr do --step 6
current = next
next = current.next
end
if start ~= current then
startnext = start.next
- remove_node(start,start)
+ head = remove_node(head,start)
local next = current.next
if next then
next.prev = start
@@ -976,7 +960,7 @@ function handlers.devanagari_reorder_reph(start,kind,lookupname,replacement)
end
end
--
- return start, true
+ return head, start, true
end
-- we can cache some checking (v)
@@ -990,19 +974,19 @@ end
-- UNTESTED: NOT CALLED IN EXAMPLE
-function handlers.devanagari_reorder_pre_base_reordering_consonants(start,kind,lookupname,replacement)
+function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start,kind,lookupname,replacement)
local current = start
local startnext = nil
local startprev = nil
local startfont = start.font
- local startattr = has_attribute(start,a_syllabe)
+ local startattr = start[a_syllabe]
-- can be fast for loop + caching state
- while current and current.id == glyph_code and current.subtype<256 and current.font == startfont and has_attribute(current,a_syllabe) == startattr do
+ while current and current.id == glyph_code and current.subtype<256 and current.font == startfont and current[a_syllabe] == startattr do
local next = current.next
- if halant[current.char] and not has_attribute(current,a_state) then
- if next and next.id == glyph_code and next.subtype<256 and next.font == font and has_attribute(next,a_syllabe) == startattr then
+ if current.char == c_halant and not current[a_state] then
+ if next and next.id == glyph_code and next.subtype<256 and next.font == font and next[a_syllabe] == startattr then
local char = next.char
- if zw_char[char] then
+ if char == c_zwnj or char == c_zwj then
current = next
end
end
@@ -1022,9 +1006,9 @@ function handlers.devanagari_reorder_pre_base_reordering_consonants(start,kind,l
end
if not startnext then
current = start.next
- startattr = has_attribute(start,a_syllabe)
- while current and current.id == glyph_code and current.subtype<256 and current.font == startfont and has_attribute(current,a_syllabe) == startattr do
- if not consonant[current.char] and has_attribute(current,a_state) then --main
+ startattr = start[a_syllabe]
+ while current and current.id == glyph_code and current.subtype<256 and current.font == startfont and current[a_syllabe] == startattr do
+ if not consonant[current.char] and current[a_state] then --main
startnext = start.next
removenode(start,start)
local prev = current.prev
@@ -1038,15 +1022,15 @@ function handlers.devanagari_reorder_pre_base_reordering_consonants(start,kind,l
current = current.next
end
end
- return start, true
+ return head, start, true
end
-function handlers.devanagari_remove_joiners(start,kind,lookupname,replacement)
+function handlers.devanagari_remove_joiners(head,start,kind,lookupname,replacement)
local stop = start.next
local startfont = start.font
while stop and stop.id == glyph_code and stop.subtype<256 and stop.font == startfont do
local char = stop.char
- if zw_char[char] then
+ if char == c_zwnj or char == c_zwj then
stop = stop.next
else
break
@@ -1061,7 +1045,7 @@ function handlers.devanagari_remove_joiners(start,kind,lookupname,replacement)
prev.next = stop
end
flush_list(start)
- return stop, true
+ return head, stop, true
end
local valid = {
@@ -1174,7 +1158,7 @@ local function dev2_reorder(head,start,stop,font,attr) -- maybe do a pass over (
current = next
current = current.next
elseif current == start then
- set_attribute(current,a_state,5)
+ current[a_state] = s_rphf
current = next
else
current = next
@@ -1201,8 +1185,8 @@ local function dev2_reorder(head,start,stop,font,attr) -- maybe do a pass over (
local next = current.next
local n = locl[next] or next.char
if found[n] then
- set_attribute(current,a_state,7)
- set_attribute(next,a_state,7)
+ current[a_state] = s_pref
+ next[a_state] = s_pref
current = next
end
end
@@ -1220,10 +1204,10 @@ local function dev2_reorder(head,start,stop,font,attr) -- maybe do a pass over (
local next = current.next
local n = locl[next] or next.char
if found[n] then
- if next ~= stop and zwnj[next.next.char] then --ZWNJ prevent creation of half
+ if next ~= stop and next.next.char == c_zwnj then --ZWNJ prevent creation of half
current = current.next
else
- set_attribute(current,a_state,6)
+ current[a_state] = s_half
if not halfpos then
halfpos = current
end
@@ -1245,8 +1229,8 @@ local function dev2_reorder(head,start,stop,font,attr) -- maybe do a pass over (
local next = current.next
local n = locl[next] or next.char
if found[n] then
- set_attribute(current,a_state,8)
- set_attribute(next,a_state,8)
+ current[a_state] = s_blwf
+ next[a_state] = s_blwf
current = next
subpos = current
end
@@ -1265,8 +1249,8 @@ local function dev2_reorder(head,start,stop,font,attr) -- maybe do a pass over (
local next = current.next
local n = locl[next] or next.char
if found[n] then
- set_attribute(current,a_state,9)
- set_attribute(next,a_state,9)
+ current[a_state] = s_pstf
+ next[a_state] = s_pstf
current = next
postpos = current
end
@@ -1284,12 +1268,12 @@ local function dev2_reorder(head,start,stop,font,attr) -- maybe do a pass over (
local current, base, firstcons = start, nil, nil
- if has_attribute(start,a_state) == 5 then
+ if start[a_state] == s_rphf then
-- if syllable starts with Ra + H and script has 'Reph' then exclude Reph from candidates for base consonants
current = start.next.next
end
- if current ~= stop.next and nbsp[current.char] then
+ if current ~= stop.next and current.char == c_nbsp then
-- Stand Alone cluster
if current == stop then
stop = stop.prev
@@ -1301,26 +1285,26 @@ local function dev2_reorder(head,start,stop,font,attr) -- maybe do a pass over (
current = current.next
if current ~= stop then
local char = current.char
- if nukta[char] then
+ if char == c_nukta then
current = current.next
char = current.char
end
- if zwj[char] then
+ if char == c_zwj then
local next = current.next
- if current ~= stop and next ~= stop and halant[next.char] then
+ if current ~= stop and next ~= stop and next.char == c_halant then
current = next
next = current.next
local tmp = next.next
local changestop = next == stop
next.next = nil
- set_attribute(current,a_state,7) --pref
+ current[a_state] = s_pref
current = processcharacters(current)
- set_attribute(current,a_state,8) --blwf
+ current[a_state] = s_blwf
current = processcharacters(current)
- set_attribute(current,a_state,9) --pstf
+ current[a_state] = s_pstf
current = processcharacters(current)
- unset_attribute(current,a_state)
- if halant[current.char] then
+ current[a_state] = unsetvalue
+ if current.char == c_halant then
current.next.next = tmp
local nc = copy_node(current)
current.char = dotted_circle
@@ -1340,13 +1324,13 @@ local function dev2_reorder(head,start,stop,font,attr) -- maybe do a pass over (
while current ~= last do -- find base consonant
local next = current.next
if consonant[current.char] then
- if not (current ~= stop and next ~= stop and halant[next.char] and zwj[next.next.char]) then
+ if not (current ~= stop and next ~= stop and next.char == c_halant and next.next.char == c_zwj) then
if not firstcons then
firstcons = current
end
-- check whether consonant has below-base or post-base form or is pre-base reordering Ra
- local a = has_attribute(current,a_state)
- if not (a == 7 or a == 8 or a == 9) then
+ local a = current[a_state]
+ if not (a == s_pref or a == s_blwf or a == pstf) then
base = current
end
end
@@ -1359,13 +1343,13 @@ local function dev2_reorder(head,start,stop,font,attr) -- maybe do a pass over (
end
if not base then
- if has_attribute(start,a_state) == 5 then
- unset_attribute(start,a_state)
+ if start[a_state] == s_rphf then
+ start[a_state] = unsetvalue
end
return head, stop
else
- if has_attribute(base,a_state) then
- unset_attribute(base,a_state)
+ if base[a_state] then
+ base[a_state] = unsetvalue
end
basepos = base
end
@@ -1464,7 +1448,7 @@ local function dev2_reorder(head,start,stop,font,attr) -- maybe do a pass over (
local current, c = start, nil
while current ~= stop do
local char = current.char
- if halant[char] or stress_tone_mark[char] then
+ if char == c_halant or stress_tone_mark[char] then
if not c then
c = current
end
@@ -1472,7 +1456,7 @@ local function dev2_reorder(head,start,stop,font,attr) -- maybe do a pass over (
c = nil
end
local next = current.next
- if c and nukta[next.char] then
+ if c and next.char == c_nukta then
if head == c then
head = next
end
@@ -1497,7 +1481,7 @@ local function dev2_reorder(head,start,stop,font,attr) -- maybe do a pass over (
current = current.next
end
- if nbsp[base.char] then
+ if base.char == c_nbsp then
head = remove_node(head, base)
free_node(base)
end
@@ -1514,8 +1498,9 @@ imerge(separator,independent_vowel)
imerge(separator,dependent_vowel)
imerge(separator,vowel_modifier)
imerge(separator,stress_tone_mark)
-imerge(separator,nukta)
-imerge(separator,halant)
+
+separator[0x093C] = true -- nukta
+separator[0x094D] = true -- halant
local function analyze_next_chars_one(c,font,variant) -- skip one dependent vowel
-- why two variants ... the comment suggests that it's the same ruleset
@@ -1525,7 +1510,7 @@ local function analyze_next_chars_one(c,font,variant) -- skip one dependent vowe
end
if variant == 1 then
local v = n.id == glyph_code and n.subtype<256 and n.font == font
- if v and nukta[n.char] then
+ if v and n.char == c_nukta then
n = n.next
if n then
v = n.id == glyph_code and n.subtype<256 and n.font == font
@@ -1538,9 +1523,9 @@ local function analyze_next_chars_one(c,font,variant) -- skip one dependent vowe
if nnn and nnn.id == glyph_code and nnn.subtype<256 and nnn.font == font then
local nnc = nn.char
local nnnc = nnn.char
- if zwj[nnc] and consonant[nnnc] then
+ if nnc == c_zwj and consonant[nnnc] then
c = nnn
- elseif zw_char[nnc] and halant[nnnc] then
+ elseif (nnc == c_zwnj or nnc == c_zwj) and nnnc == c_halant then
local nnnn = nnn.next
if nnnn and nnnn.id == glyph_code and consonant[nnnn.char] and nnnn.subtype<256 and nnnn.font == font then
c = nnnn
@@ -1550,7 +1535,7 @@ local function analyze_next_chars_one(c,font,variant) -- skip one dependent vowe
end
end
elseif variant == 2 then
- if n.id == glyph_code and nukta[n.char] and n.subtype<256 and n.font == font then
+ if n.id == glyph_code and n.char == c_nukta and n.subtype<256 and n.font == font then
c = n
end
n = c.next
@@ -1563,7 +1548,7 @@ local function analyze_next_chars_one(c,font,variant) -- skip one dependent vowe
nn = nn.next
nv = nn.id == glyph_code and nn.subtype<256 and nn.font == font
end
- if nn and nv and halant[n.char] and consonant[nn.char] then
+ if nn and nv and n.char == c_halant and consonant[nn.char] then
c = nn
end
end
@@ -1591,7 +1576,7 @@ local function analyze_next_chars_one(c,font,variant) -- skip one dependent vowe
end
char = n.char
end
- if nukta[char] then
+ if char == c_nukta then
c = c.next
n = c.next
if not n then
@@ -1603,7 +1588,7 @@ local function analyze_next_chars_one(c,font,variant) -- skip one dependent vowe
end
char = n.char
end
- if halant[char] then
+ if char == c_halant then
c = c.next
n = c.next
if not n then
@@ -1651,7 +1636,7 @@ local function analyze_next_chars_two(c,font)
if not n then
return c
end
- if n.id == glyph_code and nukta[n.char] and n.subtype<256 and n.font == font then
+ if n.id == glyph_code and n.char == c_nukta and n.subtype<256 and n.font == font then
c = n
end
n = c
@@ -1659,16 +1644,16 @@ local function analyze_next_chars_two(c,font)
local nn = n.next
if nn and nn.id == glyph_code and nn.subtype<256 and nn.font == font then
local char = nn.char
- if halant[char] then
+ if char == c_halant then
n = nn
local nnn = nn.next
if nnn and nnn.id == glyph_code and zw_char[nnn.char] and nnn.subtype<256 and nnn.font == font then
n = nnn
end
- elseif zw_char[char] then
+ elseif char == c_zwnj or char == c_zwj then
-- n = nn -- not here (?)
local nnn = nn.next
- if nnn and nnn.id == glyph_code and halant[nnn.char] and nnn.subtype<256 and nnn.font == font then
+ if nnn and nnn.id == glyph_code and nnn.char == c_halant and nnn.subtype<256 and nnn.font == font then
n = nnn
end
else
@@ -1678,7 +1663,7 @@ local function analyze_next_chars_two(c,font)
if nn and nn.id == glyph_code and consonant[nn.char] and nn.subtype<256 and nn.font == font then
n = nn
local nnn = nn.next
- if nnn and nnn.id == glyph_code and nukta[nnn.char] and nnn.subtype<256 and nnn.font == font then
+ if nnn and nnn.id == glyph_code and nnn.char == c_nukta and nnn.subtype<256 and nnn.font == font then
n = nnn
end
c = n
@@ -1703,7 +1688,7 @@ local function analyze_next_chars_two(c,font)
return c
end
local char = n.char
- if anudatta[char] then
+ if char == c_anudatta then
c = n
n = c.next
if not n then
@@ -1715,7 +1700,7 @@ local function analyze_next_chars_two(c,font)
end
char = n.char
end
- if halant[char] then
+ if char == c_halant then
c = c.next
n = c.next
if not n then
@@ -1726,7 +1711,7 @@ local function analyze_next_chars_two(c,font)
return c
end
char = n.char
- if zw_char[char] then
+ if char == c_zwnj or char == c_zwj then
c = c.next
n = c.next
if not n then
@@ -1753,7 +1738,7 @@ local function analyze_next_chars_two(c,font)
end
char = n.char
end
- if nukta[char] then
+ if char == c_nukta then
c = c.next
n = c.next
if not n then
@@ -1765,7 +1750,7 @@ local function analyze_next_chars_two(c,font)
end
char = n.char
end
- if halant[char] then
+ if char == c_halant then
c = c.next
n = c.next
if not n then
@@ -1832,13 +1817,13 @@ function methods.deva(head,font,attr)
local syllableend = nil
local c = current
local n = c.next
- if n and ra[c.char] and n.id == glyph_code and halant[n.char] and n.subtype<256 and n.font == font then
+ if n and c.char == c_ra and n.id == glyph_code and n.char == c_halant and n.subtype<256 and n.font == font then
local n = n.next
if n and n.id == glyph_code and n.subtype<256 and n.font == font then
c = n
end
end
- local standalone = nbsp[c.char]
+ local standalone = c.char == c_nbsp
if standalone then
local prev = current.prev
if not prev then
@@ -1859,7 +1844,7 @@ function methods.deva(head,font,attr)
current = current.next
end
else
- -- we can delay the n.subtype and n.font and test for say halant[c] first
+ -- we can delay the n.subtype and n.font and test for say halant first
-- as an table access is faster than two function calls (subtype and font are
-- pseudo fields) but the code becomes messy (unless we make it a function)
local char = current.char
@@ -1877,7 +1862,7 @@ function methods.deva(head,font,attr)
break
end
local c = n.char
- if nukta[c] then
+ if c == c_nukta then
n = n.next
if not n then
break
@@ -1888,7 +1873,7 @@ function methods.deva(head,font,attr)
end
c = n.char
end
- if halant[c] then
+ if c == c_halant then
n = n.next
if not n then
break
@@ -1898,7 +1883,7 @@ function methods.deva(head,font,attr)
break
end
c = n.char
- if zw_char[c] then
+ if c == c_zwnj or c == c_zwj then
n = n.next
if not n then
break
@@ -1916,7 +1901,7 @@ function methods.deva(head,font,attr)
end
end
local n = current.next
- if n and n.id == glyph_code and nukta[n.char] and n.subtype<256 and n.font == font then
+ if n and n.id == glyph_code and n.char == c_nukta and n.subtype<256 and n.font == font then
-- nukta (not specified in Microsft Devanagari OpenType specification)
current = n
n = current.next
@@ -1926,7 +1911,7 @@ function methods.deva(head,font,attr)
if current then
local v = current.id == glyph_code and current.subtype<256 and current.font == font
if v then
- if halant[current.char] then
+ if current.char == c_halant then
-- syllable containing consonant without vowels: {C + [Nukta] + H} + C + H
local n = current.next
if n and n.id == glyph_code and zw_char[n.char] and n.subtype<256 and n.font == font then
@@ -2009,7 +1994,7 @@ end
-- there is a good change that when we run into one with subtype < 256 that the rest is also done
-- so maybe we can omit this check (it's pretty hard to get glyphs in the stream out of the blue)
--- handler(start,kind,lookupname,lookupmatch,sequence,lookuphash,1)
+-- handler(head,start,kind,lookupname,lookupmatch,sequence,lookuphash,1)
function methods.dev2(head,font,attr)
local current = head
@@ -2023,7 +2008,7 @@ function methods.dev2(head,font,attr)
syllablestart = current
local c = current
local n = current.next
- if n and ra[c.char] and n.id == glyph_code and halant[n.char] and n.subtype<256 and n.font == font then
+ if n and c.char == c_ra and n.id == glyph_code and n.char == c_halant and n.subtype<256 and n.font == font then
local n = n.next
if n and n.id == glyph_code and n.subtype<256 and n.font == font then
c = n
@@ -2035,7 +2020,7 @@ function methods.dev2(head,font,attr)
current = analyze_next_chars_one(c,font,1)
syllableend = current
else
- local standalone = nbsp[char]
+ local standalone = char == c_nbsp
if standalone then
local p = current.prev
if not p then
@@ -2066,14 +2051,14 @@ function methods.dev2(head,font,attr)
local c = syllablestart
local n = syllableend.next
while c ~= n do
- set_attribute(c,a_syllabe,syllabe)
+ c[a_syllabe] = syllabe
c = c.next
end
end
if syllableend and syllablestart ~= syllableend then
head, current = dev2_reorder(head,syllablestart,syllableend,font,attr)
end
- if not syllableend and current.id == glyph_code and current.subtype<256 and current.font == font and not has_attribute(current,a_state) then
+ if not syllableend and current.id == glyph_code and current.subtype<256 and current.font == font and not current[a_state] then
local mark = mark_four[current.char]
if mark then
head, current = inject_syntax_error(head,current,mark)
@@ -2085,961 +2070,3 @@ function methods.dev2(head,font,attr)
return head, done
end
-
--- Temporary checker:
-
-if false then -- when true we can see how much nodes bleed
-
- local function check(what,action,head,kind,lookupname,replacement)
- local n_before = nodes.count(head)
- local s_before = nodes.listtoutf(head)
- local head, done = action(head,kind,lookupname,replacement)
- local n_after = nodes.count(head)
- local s_after = nodes.listtoutf(head)
- if n_before ~= n_after then
- print("leak",what)
- print(n_before,s_before)
- print(n_after,s_after)
- end
- return head, done
- end
-
- local devanagari_reorder_matras = handlers.devanagari_reorder_matras
- local devanagari_reorder_reph = handlers.devanagari_reorder_reph
- local devanagari_reorder_pre_base_reordering_consonants = handlers.devanagari_reorder_pre_base_reordering_consonants
- local devanagari_remove_joiners = handlers.devanagari_remove_joiners
-
- function handlers.devanagari_reorder_matras(start,kind,lookupname,replacement)
- if trace then
- return check("matras",devanagari_reorder_matras,start,kind,lookupname,replacement)
- else
- return devanagari_reorder_matras(start,kind,lookupname,replacement)
- end
- end
-
- function handlers.devanagari_reorder_reph(start,kind,lookupname,replacement)
- if trace then
- return check("reph",devanagari_reorder_reph,start,kind,lookupname,replacement)
- else
- return devanagari_reorder_reph(start,kind,lookupname,replacement)
- end
- end
-
- function handlers.devanagari_reorder_pre_base_reordering_consonants(start,kind,lookupname,replacement)
- if trace then
- return check("consonants",devanagari_reorder_pre_base_reordering_consonants,start,kind,lookupname,replacement)
- else
- return devanagari_reorder_pre_base_reordering_consonants(start,kind,lookupname,replacement)
- end
- end
-
- function handlers.devanagari_remove_joiners(start,kind,lookupname,replacement)
- if trace then
- return check("joiners",devanagari_remove_joiners,start,kind,lookupname,replacement)
- else
- return devanagari_remove_joiners(start,kind,lookupname,replacement)
- end
- end
-
-end
-
--- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
--- We keep the original around for a while so that we can check it --
--- when the above code does it wrong (data tables are not included). --
--- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-
--- local state = attributes.private('state')
--- local sylnr = attributes.private('syllabe')
---
--- local function install_dev(tfmdata)
--- local features = tfmdata.resources.features
--- local sequences = tfmdata.resources.sequences
---
--- local insertpos = 1
--- for s=1,#sequences do -- classify chars
--- for k in pairs(basic_shaping_forms) do
--- if sequences[s].features and ( sequences[s].features[k] or sequences[s].features.locl ) then insertpos = s + 1 end
--- end
--- end
---
--- features.gsub["dev2_reorder_matras"] = { ["dev2"] = { ["dflt"] = true } }
--- features.gsub["dev2_reorder_reph"] = { ["dev2"] = { ["dflt"] = true } }
--- features.gsub["dev2_reorder_pre_base_reordering_consonants"] = { ["dev2"] = { ["dflt"] = true } }
--- features.gsub["remove_joiners"] = { ["deva"] = { ["dflt"] = true }, ["dev2"] = { ["dflt"] = true } }
---
--- local sequence_dev2_reorder_matras = {
--- chain = 0,
--- features = { dev2_reorder_matras = { dev2 = { dflt = true } } },
--- flags = { false, false, false, false },
--- name = "dev2_reorder_matras",
--- subtables = { "dev2_reorder_matras" },
--- type = "dev2_reorder_matras",
--- }
--- local sequence_dev2_reorder_reph = {
--- chain = 0,
--- features = { dev2_reorder_reph = { dev2 = { dflt = true } } },
--- flags = { false, false, false, false },
--- name = "dev2_reorder_reph",
--- subtables = { "dev2_reorder_reph" },
--- type = "dev2_reorder_reph",
--- }
--- local sequence_dev2_reorder_pre_base_reordering_consonants = {
--- chain = 0,
--- features = { dev2_reorder_pre_base_reordering_consonants = { dev2 = { dflt = true } } },
--- flags = { false, false, false, false },
--- name = "dev2_reorder_pre_base_reordering_consonants",
--- subtables = { "dev2_reorder_pre_base_reordering_consonants" },
--- type = "dev2_reorder_pre_base_reordering_consonants",
--- }
--- local sequence_remove_joiners = {
--- chain = 0,
--- features = { remove_joiners = { deva = { dflt = true }, dev2 = { dflt = true } } },
--- flags = { false, false, false, false },
--- name = "remove_joiners",
--- subtables = { "remove_joiners" },
--- type = "remove_joiners",
--- }
--- table.insert(sequences, insertpos, sequence_dev2_reorder_pre_base_reordering_consonants)
--- table.insert(sequences, insertpos, sequence_dev2_reorder_reph)
--- table.insert(sequences, insertpos, sequence_dev2_reorder_matras)
--- table.insert(sequences, insertpos, sequence_remove_joiners)
--- end
---
--- local function deva_reorder(head,start,stop,font,attr)
--- local tfmdata = fontdata[font]
--- local lookuphash = tfmdata.resources.lookuphash
--- local sequences = tfmdata.resources.sequences
---
--- if not lookuphash["remove_joiners"] then install_dev(tfmdata) end --install Devanagari-features
---
--- local sharedfeatures = tfmdata.shared.features
--- sharedfeatures["remove_joiners"] = true
--- local datasets = otf.dataset(tfmdata,font,attr)
---
--- lookuphash["remove_joiners"] = { [0x200C] = true, [0x200D] = true }
---
--- local current, n, base, firstcons, lastcons, basefound = start, start.next, nil, nil, nil, false
--- local reph, vattu = false, false
--- for s=1,#sequences do
--- local dataset = datasets[s]
--- featurevalue = dataset and dataset[1]
--- if featurevalue and dataset[4] == "rphf" then reph = true end
--- if featurevalue and dataset[4] == "blwf" then vattu = true end
--- end
--- if ra[start.char] and halant[n.char] and reph then -- if syllable starts with Ra + H and script has 'Reph' then exclude Reph from candidates for base consonants
--- if n == stop then return head, stop end
--- if zwj[n.next.char] then
--- current = start
--- else
--- current = n.next
--- set_attribute(start,state,5) -- rphf
--- end
--- end
---
--- if nbsp[current.char] then --Stand Alone cluster
--- if current == stop then
--- stop = stop.prev
--- head = node.remove(head, current)
--- node.free(current)
--- return head, stop
--- else
--- base, firstcons, lastcons = current, current, current
--- current = current.next
--- if current ~= stop then
--- if nukta[current.char] then current = current.next end
--- if zwj[current.char] then
--- if current ~= stop and current.next ~= stop and halant[current.next.char] then
--- current = current.next
--- local tmp = current.next.next
--- local changestop = current.next == stop
--- local tempcurrent = node.copy(current.next)
--- tempcurrent.next = node.copy(current)
--- tempcurrent.next.prev = tempcurrent
--- set_attribute(tempcurrent,state,8) --blwf
--- tempcurrent = nodes.handlers.characters(tempcurrent)
--- unset_attribute(tempcurrent,state)
--- if current.next.char == tempcurrent.char then
--- node.flush_list(tempcurrent)
--- local n = node.copy(current)
--- current.char = dotted_circle
--- head = node.insert_after(head, current, n)
--- else
--- current.char = tempcurrent.char -- (assumes that result of blwf consists of one node)
--- local freenode = current.next
--- current.next = tmp
--- tmp.prev = current
--- node.free(freenode)
--- node.flush_list(tempcurrent)
--- if changestop then stop = current end
--- end
--- end
--- end
--- end
--- end
--- end
---
--- while not basefound do -- find base consonant
--- if consonant[current.char] then
--- set_attribute(current, state, 6) -- half
--- if not firstcons then firstcons = current end
--- lastcons = current
--- if not base then
--- base = current
--- else --check whether consonant has below-base (or post-base) form
--- local baseform = true
--- for s=1,#sequences do
--- local sequence = sequences[s]
--- local dataset = datasets[s]
--- featurevalue = dataset and dataset[1]
--- if featurevalue and dataset[4] == "blwf" then
--- local subtables = sequence.subtables
--- for i=1,#subtables do
--- local lookupname = subtables[i]
--- local lookupcache = lookuphash[lookupname]
--- if lookupcache then
--- local lookupmatch = lookupcache[current.char]
--- if lookupmatch then
--- set_attribute(current, state, 8) -- blwf
--- baseform = false
--- end
--- end
--- end
--- end
--- end
--- if baseform then base = current end
--- end
--- end
--- basefound = current == stop
--- current = current.next
--- end
--- if base ~= lastcons then -- if base consonant is not last one then move halant from base consonant to last one
--- n = base.next
--- if nukta[n.char] then n = n.next end
--- if halant[n.char] then
--- if lastcons ~= stop then
--- local ln = lastcons.next
--- if nukta[ln.char] then lastcons = ln end
--- end
--- local np, nn, ln = n.prev, n.next, lastcons.next
--- np.next = n.next
--- nn.prev = n.prev
--- lastcons.next = n
--- if ln then ln.prev = n end
--- n.next = ln
--- n.prev = lastcons
--- if lastcons == stop then stop = n end
--- end
--- end
---
--- n = start.next
--- if ra[start.char] and halant[n.char] and not ( n ~= stop and ( zwj[n.next.char] or zwnj[n.next.char] ) ) then -- if syllable starts with Ra + H then move this combination so that it follows either: the post-base 'matra' (if any) or the base consonant
--- local matra = base
--- if base ~= stop and dependent_vowel[base.next.char] then matra = base.next end
--- local sp, nn, mn = start.prev, n.next, matra.next
--- if sp then sp.next = nn end
--- nn.prev = sp
--- matra.next = start
--- start.prev = matra
--- n.next = mn
--- if mn then mn.prev = n end
--- if head == start then head = nn end
--- start = nn
--- if matra == stop then stop = n end
--- end
---
--- local current = start
--- while current ~= stop do
--- if halant[current.next.char] and current.next ~= stop and zwnj[current.next.next.char] then unset_attribute(current, state) end
--- current = current.next
--- end
---
--- if has_attribute(base, state) and base ~= stop and halant[base.next.char] and not ( base.next ~= stop and zwj[base.next.next.char] ) then unset_attribute(base, state) end
---
--- local current, allreordered, moved = start, false, { [base] = true }
--- local a, b, p, bn = base, base, base, base.next
--- if base ~= stop and nukta[bn.char] then a, b, p = bn, bn, bn end
--- while not allreordered do
--- local c, n, l = current, current.next, nil --current is always consonant
--- if c ~= stop and nukta[n.char] then c = n n = n.next end
--- if c ~= stop and halant[n.char] then c = n n = n.next end
--- while c ~= stop and dependent_vowel[n.char] do c = n n = n.next end
--- if c ~= stop and vowel_modifier[n.char] then c = n n = n.next end
--- if c ~= stop and stress_tone_mark[n.char] then c = n n = n.next end
--- local bp, cn = firstcons.prev, current.next
--- while cn ~= c.next do -- move pre-base matras...
--- if pre_mark[cn.char] then
--- if bp then bp.next = cn end
--- cn.prev.next = cn.next
--- if cn.next then cn.next.prev = cn.prev end
--- if cn == stop then stop = cn.prev end
--- cn.prev = bp
--- cn.next = firstcons
--- firstcons.prev = cn
--- if firstcons == start then
--- if head == start then head = cn end
--- start = cn
--- end
--- break
--- end
--- cn = cn.next
--- end
--- allreordered = c == stop
--- current = c.next
--- end
---
--- if reph or vattu then
--- local current, cns = start, nil
--- while current ~= stop do
--- local c, n = current, current.next
--- if ra[current.char] and halant[n.char] then
--- c, n = n, n.next
--- local b, bn = base, base
--- while bn ~= stop do
--- if dependent_vowel[bn.next.char] then b = bn.next end
--- bn = bn.next
--- end
--- if has_attribute(current,state,attribute) == 5 then -- position Reph (Ra + H) after post-base 'matra' (if any) since these become marks on the 'matra', not on the base glyph
--- if b ~= current then
--- if current == start then
--- if head == start then head = n end
--- start = n
--- end
--- if b == stop then stop = c end
--- if current.prev then current.prev.next = n end
--- if n then n.prev = current.prev end
--- c.next = b.next
--- if b.next then b.next.prev = c end
--- b.next = current
--- current.prev = b
--- end
--- elseif cns and cns.next ~= current then -- position below-base Ra (vattu) following the consonants on which it is placed (either the base consonant or one of the pre-base consonants)
--- local cp, cnsn = current.prev, cns.next
--- if cp then cp.next = n end
--- if n then n.prev = cp end
--- cns.next = current
--- current.prev = cns
--- c.next = cnsn
--- if cnsn then cnsn.prev = c end
--- if c == stop then stop = cp break end
--- current = n.prev
--- end
--- elseif consonant[current.char] or nbsp[current.char] then
--- cns = current
--- if halant[cns.next.char] then cns = cns.next end
--- end
--- current = current.next
--- end
--- end
---
--- if nbsp[base.char] then
--- head = node.remove(head, base)
--- node.free(base)
--- end
---
--- return head, stop
--- end
---
--- function dev2_reorder_matras(start,kind,lookupname,replacement)
--- local current = start
--- while current and current.id == glyph and current.subtype<256 and current.font == start.font and has_attribute(current, sylnr) == has_attribute(start, sylnr) do
--- if halant[current.char] and not has_attribute(current, state) then
--- if current.next and current.next.id == glyph and current.next.subtype<256 and current.next.font == start.font and has_attribute(current.next, sylnr) == has_attribute(start, sylnr) and ( zwj[current.next.char] or zwnj[current.next.char] ) then current = current.next end
--- local sn = start.next
--- start.next.prev = start.prev
--- if start.prev then start.prev.next = start.next end
--- if current.next then current.next.prev = start end
--- start.next = current.next
--- current.next = start
--- start.prev = current
--- start = sn
--- break
--- end
--- current = current.next
--- end
--- return start, true
--- end
---
--- function dev2_reorder_reph(start,kind,lookupname,replacement)
--- local current, sn = start.next, nil
--- while current and current.id == glyph and current.subtype<256 and current.font == start.font and has_attribute(current, sylnr) == has_attribute(start, sylnr) do --step 2
--- if halant[current.char] and not has_attribute(current, state) then
--- if current.next and current.next.id == glyph and current.next.subtype<256 and current.next.font == start.font and has_attribute(current.next, sylnr) == has_attribute(start, sylnr) and ( zwj[current.next.char] or zwnj[current.next.char] ) then current = current.next end
--- sn = start.next
--- start.next.prev = start.prev
--- if start.prev then start.prev.next = start.next end
--- if current.next then current.next.prev = start end
--- start.next = current.next
--- current.next = start
--- start.prev = current
--- start = sn
--- break
--- end
--- current = current.next
--- end
--- if not sn then
--- current = start.next
--- while current and current.id == glyph and current.subtype<256 and current.font == start.font and has_attribute(current, sylnr) == has_attribute(start, sylnr) do --step 4
--- if has_attribute(current, state) == 9 then --post-base
--- sn = start.next
--- start.next.prev = start.prev
--- if start.prev then start.prev.next = start.next end
--- start.prev = current.prev
--- current.prev.next = start
--- start.next = current
--- current.prev = start
--- start = sn
--- break
--- end
--- current = current.next
--- end
--- end
--- if not sn then
--- current = start.next
--- local c = nil
--- while current and current.id == glyph and current.subtype<256 and current.font == start.font and has_attribute(current, sylnr) == has_attribute(start, sylnr) do --step 5
--- if not c and ( above_mark[current.char] or below_mark[current.char] or post_mark[current.char] ) and ReorderClass[current.char] ~= "after subscript" then c = current end
--- current = current.next
--- end
--- if c then
--- sn = start.next
--- start.next.prev = start.prev
--- if start.prev then start.prev.next = start.next end
--- start.prev = c.prev
--- c.prev.next = start
--- start.next = c
--- c.prev = start
--- start = sn
--- end
--- end
--- if not sn then
--- current = start
--- while current.next and current.next.id == glyph and current.next.subtype<256 and current.next.font == start.font and has_attribute(current.next, sylnr) == has_attribute(start, sylnr) do --step 6
--- current = current.next
--- end
--- if start ~= current then
--- sn = start.next
--- start.next.prev = start.prev
--- if start.prev then start.prev.next = start.next end
--- if current.next then current.next.prev = start end
--- start.next = current.next
--- current.next = start
--- start.prev = current
--- start = sn
--- end
--- end
--- return start, true
--- end
---
--- function dev2_reorder_pre_base_reordering_consonants(start,kind,lookupname,replacement)
--- local current, sn = start, nil
--- while current and current.id == glyph and current.subtype<256 and current.font == start.font and has_attribute(current, sylnr) == has_attribute(start, sylnr) do
--- if halant[current.char] and not has_attribute(current, state) then
--- if current.next and current.next.id == glyph and current.next.subtype<256 and current.next.font == start.font and has_attribute(current.next, sylnr) == has_attribute(start, sylnr) and ( zwj[current.next.char] or zwnj[current.next.char] ) then current = current.next end
--- sn = start.next
--- start.next.prev = start.prev
--- if start.prev then start.prev.next = start.next end
--- if current.next then current.next.prev = start end
--- start.next = current.next
--- current.next = start
--- start.prev = current
--- start = sn
--- break
--- end
--- current = current.next
--- end
--- if not sn then
--- current = start.next
--- while current and current.id == glyph and current.subtype<256 and current.font == start.font and has_attribute(current, sylnr) == has_attribute(start, sylnr) do
--- if not consonant[current.char] and has_attribute(current, state) then --main
--- sn = start.next
--- start.next.prev = start.prev
--- if start.prev then start.prev.next = start.next end
--- start.prev = current.prev
--- current.prev.next = start
--- start.next = current
--- current.prev = start
--- start = sn
--- break
--- end
--- current = current.next
--- end
--- end
--- return start, true
--- end
---
--- function remove_joiners(start,kind,lookupname,replacement)
--- local stop = start.next
--- while stop and stop.id == glyph and stop.subtype<256 and stop.font == start.font and (zwj[stop.char] or zwnj[stop.char]) do stop = stop.next end
--- if stop then stop.prev.next = nil stop.prev = start.prev end
--- if start.prev then start.prev.next = stop end
--- node.flush_list(start)
--- return stop, true
--- end
---
--- local function dev2_reorder(head,start,stop,font,attr)
--- local tfmdata = fontdata[font]
--- local lookuphash = tfmdata.resources.lookuphash
--- local sequences = tfmdata.resources.sequences
---
--- if not lookuphash["remove_joiners"] then install_dev(tfmdata) end --install Devanagari-features
---
--- local sharedfeatures = tfmdata.shared.features
--- sharedfeatures["dev2_reorder_matras"] = true
--- sharedfeatures["dev2_reorder_reph"] = true
--- sharedfeatures["dev2_reorder_pre_base_reordering_consonants"] = true
--- sharedfeatures["remove_joiners"] = true
--- local datasets = otf.dataset(tfmdata,font,attr)
---
--- local reph, pre_base_reordering_consonants = false, nil
--- local halfpos, basepos, subpos, postpos = nil, nil, nil, nil
--- local locl = { }
---
--- for s=1,#sequences do -- classify chars
--- local sequence = sequences[s]
--- local dataset = datasets[s]
--- featurevalue = dataset and dataset[1]
--- if featurevalue and dataset[4] then
--- local subtables = sequence.subtables
--- for i=1,#subtables do
--- local lookupname = subtables[i]
--- local lookupcache = lookuphash[lookupname]
--- if lookupcache then
--- if dataset[4] == "rphf" then
--- if dataset[3] ~= 0 then --rphf is result of of chain
--- else
--- reph = lookupcache[0x0930] and lookupcache[0x0930][0x094D] and lookupcache[0x0930][0x094D]["ligature"]
--- end
--- end
--- if dataset[4] == "pref" and not pre_base_reordering_consonants then
--- for k, v in pairs(lookupcache[0x094D]) do
--- pre_base_reordering_consonants[k] = v and v["ligature"] --ToDo: reph might also be result of chain
--- end
--- end
--- local current = start
--- while current ~= stop.next do
--- if dataset[4] == "locl" then locl[current] = lookupcache[current.char] end --ToDo: locl might also be result of chain
--- if current ~= stop then
--- local c, n = locl[current] or current.char, locl[current.next] or current.next.char
--- if dataset[4] == "rphf" and lookupcache[c] and lookupcache[c][n] then --above-base: rphf Consonant + Halant
--- if current.next ~= stop and ( zwj[current.next.next.char] or zwnj[current.next.next.char] ) then --ZWJ and ZWNJ prevent creation of reph
--- current = current.next
--- elseif current == start then
--- set_attribute(current,state,5)
--- end
--- current = current.next
--- end
--- if dataset[4] == "half" and lookupcache[c] and lookupcache[c][n] then --half forms: half Consonant + Halant
--- if current.next ~= stop and zwnj[current.next.next.char] then --ZWNJ prevent creation of half
--- current = current.next
--- else
--- set_attribute(current,state,6)
--- if not halfpos then halfpos = current end
--- end
--- current = current.next
--- end
--- if dataset[4] == "pref" and lookupcache[c] and lookupcache[c][n] then --pre-base: pref Halant + Consonant
--- set_attribute(current,state,7)
--- set_attribute(current.next,state,7)
--- current = current.next
--- end
--- if dataset[4] == "blwf" and lookupcache[c] and lookupcache[c][n] then --below-base: blwf Halant + Consonant
--- set_attribute(current,state,8)
--- set_attribute(current.next,state,8)
--- current = current.next
--- subpos = current
--- end
--- if dataset[4] == "pstf" and lookupcache[c] and lookupcache[c][n] then --post-base: pstf Halant + Consonant
--- set_attribute(current,state,9)
--- set_attribute(current.next,state,9)
--- current = current.next
--- postpos = current
--- end
--- end
--- current = current.next
--- end
--- end
--- end
--- end
--- end
---
--- lookuphash["dev2_reorder_matras"] = pre_mark
--- lookuphash["dev2_reorder_reph"] = { [reph] = true }
--- lookuphash["dev2_reorder_pre_base_reordering_consonants"] = pre_base_reordering_consonants or { }
--- lookuphash["remove_joiners"] = { [0x200C] = true, [0x200D] = true }
---
--- local current, base, firstcons = start, nil, nil
--- if has_attribute(start,state) == 5 then current = start.next.next end -- if syllable starts with Ra + H and script has 'Reph' then exclude Reph from candidates for base consonants
---
--- if current ~= stop.next and nbsp[current.char] then --Stand Alone cluster
--- if current == stop then
--- stop = stop.prev
--- head = node.remove(head, current)
--- node.free(current)
--- return head, stop
--- else
--- base = current
--- current = current.next
--- if current ~= stop then
--- if nukta[current.char] then current = current.next end
--- if zwj[current.char] then
--- if current ~= stop and current.next ~= stop and halant[current.next.char] then
--- current = current.next
--- local tmp = current.next.next
--- local changestop = current.next == stop
--- current.next.next = nil
--- set_attribute(current,state,7) --pref
--- current = nodes.handlers.characters(current)
--- set_attribute(current,state,8) --blwf
--- current = nodes.handlers.characters(current)
--- set_attribute(current,state,9) --pstf
--- current = nodes.handlers.characters(current)
--- unset_attribute(current,state)
--- if halant[current.char] then
--- current.next.next = tmp
--- local nc = node.copy(current)
--- current.char = dotted_circle
--- head = node.insert_after(head, current, nc)
--- else
--- current.next = tmp -- (assumes that result of pref, blwf, or pstf consists of one node)
--- if changestop then stop = current end
--- end
--- end
--- end
--- end
--- end
--- else --not Stand Alone cluster
--- while current ~= stop.next do -- find base consonant
--- if consonant[current.char] and not ( current ~= stop and halant[current.next.char] and current.next ~= stop and zwj[current.next.next.char] ) then
--- if not firstcons then firstcons = current end
--- if not ( has_attribute(current, state) == 7 or has_attribute(current, state) == 8 or has_attribute(current, state) == 9 ) then base = current end --check whether consonant has below-base or post-base form or is pre-base reordering Ra
--- end
--- current = current.next
--- end
--- if not base then
--- base = firstcons
--- end
--- end
---
--- if not base then
--- if has_attribute(start, state) == 5 then unset_attribute(start, state) end
--- return head, stop
--- else
--- if has_attribute(base, state) then unset_attribute(base, state) end
--- basepos = base
--- end
--- if not halfpos then halfpos = base end
--- if not subpos then subpos = base end
--- if not postpos then postpos = subpos or base end
---
--- --Matra characters are classified and reordered by which consonant in a conjunct they have affinity for
--- local moved = { }
--- current = start
--- while current ~= stop.next do
--- local char, target, cn = locl[current] or current.char, nil, current.next
--- if not moved[current] and dependent_vowel[char] then
--- if pre_mark[char] then -- Before first half form in the syllable
--- moved[current] = true
--- if current.prev then current.prev.next = current.next end
--- if current.next then current.next.prev = current.prev end
--- if current == stop then stop = current.prev end
--- if halfpos == start then
--- if head == start then head = current end
--- start = current
--- end
--- if halfpos.prev then halfpos.prev.next = current end
--- current.prev = halfpos.prev
--- halfpos.prev = current
--- current.next = halfpos
--- halfpos = current
--- elseif above_mark[char] then -- After main consonant
--- target = basepos
--- if subpos == basepos then subpos = current end
--- if postpos == basepos then postpos = current end
--- basepos = current
--- elseif below_mark[char] then -- After subjoined consonants
--- target = subpos
--- if postpos == subpos then postpos = current end
--- subpos = current
--- elseif post_mark[char] then -- After post-form consonant
--- target = postpos
--- postpos = current
--- end
--- if ( above_mark[char] or below_mark[char] or post_mark[char] ) and current.prev ~= target then
--- if current.prev then current.prev.next = current.next end
--- if current.next then current.next.prev = current.prev end
--- if current == stop then stop = current.prev end
--- if target.next then target.next.prev = current end
--- current.next = target.next
--- target.next = current
--- current.prev = target
--- end
--- end
--- current = cn
--- end
---
--- --Reorder marks to canonical order: Adjacent nukta and halant or nukta and vedic sign are always repositioned if necessary, so that the nukta is first.
--- local current, c = start, nil
--- while current ~= stop do
--- if halant[current.char] or stress_tone_mark[current.char] then
--- if not c then c = current end
--- else
--- c = nil
--- end
--- if c and nukta[current.next.char] then
--- if head == c then head = current.next end
--- if stop == current.next then stop = current end
--- if c.prev then c.prev.next = current.next end
--- current.next.prev = c.prev
--- current.next = current.next.next
--- if current.next.next then current.next.next.prev = current end
--- c.prev = current.next
--- current.next.next = c
--- end
--- if stop == current then break end
--- current = current.next
--- end
---
--- if nbsp[base.char] then
--- head = node.remove(head, base)
--- node.free(base)
--- end
---
--- return head, stop
--- end
---
--- function fonts.analyzers.methods.deva(head,font,attr)
--- local orighead = head
--- local current, start, done = head, true, false
--- while current do
--- if current.id == glyph and current.subtype<256 and current.font == font then
--- done = true
--- local syllablestart, syllableend = current, nil
---
--- local c = current --Checking Stand Alone cluster (this behavior is copied from dev2)
--- if ra[c.char] and c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and halant[c.next.char] and c.next.next and c.next.next.id == glyph and c.next.next.subtype<256 and c.next.next.font == font then c = c.next.next end
--- if nbsp[c.char] and ( not current.prev or current.prev.id ~= glyph or current.prev.subtype>=256 or current.prev.font ~= font or
--- ( not consonant[current.prev.char] and not independent_vowel[current.prev.char] and not dependent_vowel[current.prev.char] and
--- not vowel_modifier[current.prev.char] and not stress_tone_mark[current.prev.char] and not nukta[current.prev.char] and not halant[current.prev.char] )
--- ) then --Stand Alone cluster (at the start of the word only): #[Ra+H]+NBSP+[N]+[<[<ZWJ|ZWNJ>]+H+C>]+[{M}+[N]+[H]]+[SM]+[(VD)]
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and nukta[c.next.char] then c = c.next end
--- local n = c.next
--- if n and n.id == glyph and n.subtype<256 and n.font == font then
--- local ni = n.next
--- if ( zwj[n.char] or zwnj[n.char] ) and ni and ni.id == glyph and ni.subtype<256 and ni.font == font then n = ni ni = ni.next end
--- if halant[n.char] and ni and ni.id == glyph and ni.subtype<256 and ni.font == font and consonant[ni.char] then c = ni end
--- end
--- while c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and dependent_vowel[c.next.char] do c = c.next end
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and nukta[c.next.char] then c = c.next end
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and halant[c.next.char] then c = c.next end
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and vowel_modifier[c.next.char] then c = c.next end
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and stress_tone_mark[c.next.char] then c = c.next end
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and stress_tone_mark[c.next.char] then c = c.next end
--- current = c.next
--- syllableend = c
--- if syllablestart ~= syllableend then
--- head, current = deva_reorder(head, syllablestart,syllableend,font,attr)
--- current = current.next
--- end
--- elseif consonant[current.char] then -- syllable containing consonant
--- prevc = true
--- while prevc do
--- prevc = false
--- local n = current.next
--- if n and n.id == glyph and n.subtype<256 and n.font == font and nukta[n.char] then n = n.next end
--- if n and n.id == glyph and n.subtype<256 and n.font == font and halant[n.char] then
--- local n = n.next
--- if n and n.id == glyph and n.subtype<256 and n.font == font and ( zwj[n.char] or zwnj[n.char] ) then n = n.next end
--- if n and n.id == glyph and n.subtype<256 and n.font == font and consonant[n.char] then
--- prevc = true
--- current = n
--- end
--- end
--- end
--- if current.next and current.next.id == glyph and current.next.subtype<256 and current.next.font == font and nukta[current.next.char] then current = current.next end -- nukta (not specified in Microsft Devanagari OpenType specification)
--- syllableend = current
--- current = current.next
--- if current and current.id == glyph and current.subtype<256 and current.font == font and halant[current.char] then -- syllable containing consonant without vowels: {C + [Nukta] + H} + C + H
--- if current.next and current.next.id == glyph and current.next.subtype<256 and current.next.font == font and ( zwj[current.next.char] or zwnj[current.next.char] ) then current = current.next end
--- syllableend = current
--- current = current.next
--- else -- syllable containing consonant with vowels: {C + [Nukta] + H} + C + [M] + [VM] + [SM]
--- if current and current.id == glyph and current.subtype<256 and current.font == font and dependent_vowel[current.char] then
--- syllableend = current
--- current = current.next
--- end
--- if current and current.id == glyph and current.subtype<256 and current.font == font and vowel_modifier[current.char] then
--- syllableend = current
--- current = current.next
--- end
--- if current and current.id == glyph and current.subtype<256 and current.font == font and stress_tone_mark[current.char] then
--- syllableend = current
--- current = current.next
--- end
--- end
--- if syllablestart ~= syllableend then
--- head, current = deva_reorder(head,syllablestart,syllableend,font,attr)
--- current = current.next
--- end
--- elseif current.id == glyph and current.subtype<256 and current.font == font and independent_vowel[current.char] then -- syllable without consonants: VO + [VM] + [SM]
--- syllableend = current
--- current = current.next
--- if current and current.id == glyph and current.subtype<256 and current.font == font and vowel_modifier[current.char] then
--- syllableend = current
--- current = current.next
--- end
--- if current and current.id == glyph and current.subtype<256 and current.font == font and stress_tone_mark[current.char] then
--- syllableend = current
--- current = current.next
--- end
--- else -- Syntax error
--- if pre_mark[current.char] or above_mark[current.char] or below_mark[current.char] or post_mark[current.char] then
--- local n = node.copy(current)
--- if pre_mark[current.char] then
--- n.char = dotted_circle
--- else
--- current.char = dotted_circle
--- end
--- head, current = node.insert_after(head, current, n)
--- end
--- current = current.next
--- end
--- else
--- current = current.next
--- end
--- start = false
--- end
---
--- return head, done
--- end
---
--- function fonts.analyzers.methods.dev2(head,font,attr)
--- local current, start, done, syl_nr = head, true, false, 0
--- while current do
--- local syllablestart, syllableend = nil, nil
--- if current.id == glyph and current.subtype<256 and current.font == font then
--- syllablestart = current
--- done = true
--- local c, n = current, current.next
--- if ra[current.char] and n and n.id == glyph and n.subtype<256 and n.font == font and halant[n.char] and n.next and n.next.id == glyph and n.next.subtype<256 and n.next.font == font then c = n.next end
--- if independent_vowel[c.char] then --Vowel-based syllable: [Ra+H]+V+[N]+[<[<ZWJ|ZWNJ>]+H+C|ZWJ+C>]+[{M}+[N]+[H]]+[SM]+[(VD)]
--- n = c.next
--- local ni, nii = nil, nil
--- if n and n.id == glyph and n.subtype<256 and n.font == font and nukta[n.char] then n = n.next end
--- if n and n.id == glyph and n.subtype<256 and n.font == font then local ni = n.next end
--- if ni and ni.id == glyph and ni.subtype<256 and ni.font == font and ni.next and ni.next.id == glyph and ni.next.subtype<256 and ni.next.font == font then
--- nii = ni.next
--- if zwj[ni.char] and consonant[nii.char] then
--- c = nii
--- elseif (zwj[ni.char] or zwnj[ni.char]) and halant[nii.char] and nii.next and nii.next.id == glyph and nii.next.subtype<256 and nii.next.font == font and consonant[nii.next.char] then
--- c = nii.next
--- end
--- end
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and dependent_vowel[c.next.char] then c = c.next end
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and nukta[c.next.char] then c = c.next end
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and halant[c.next.char] then c = c.next end
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and vowel_modifier[c.next.char] then c = c.next end
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and stress_tone_mark[c.next.char] then c = c.next end
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and stress_tone_mark[c.next.char] then c = c.next end
--- current = c
--- syllableend = c
--- elseif nbsp[c.char] and ( not current.prev or current.prev.id ~= glyph or current.prev.subtype>=256 or current.prev.font ~= font or
--- ( not consonant[current.prev.char] and not independent_vowel[current.prev.char] and not dependent_vowel[current.prev.char] and
--- not vowel_modifier[current.prev.char] and not stress_tone_mark[current.prev.char] and not nukta[current.prev.char] and not halant[current.prev.char] )
--- ) then --Stand Alone cluster (at the start of the word only): #[Ra+H]+NBSP+[N]+[<[<ZWJ|ZWNJ>]+H+C>]+[{M}+[N]+[H]]+[SM]+[(VD)]
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and nukta[c.next.char] then c = c.next end
--- n = c.next
--- if n and n.id == glyph and n.subtype<256 and n.font == font then
--- local ni = n.next
--- if ( zwj[n.char] or zwnj[n.char] ) and ni and ni.id == glyph and ni.subtype<256 and ni.font == font then n = ni ni = ni.next end
--- if halant[n.char] and ni and ni.id == glyph and ni.subtype<256 and ni.font == font and consonant[ni.char] then c = ni end
--- end
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and dependent_vowel[c.next.char] then c = c.next end
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and nukta[c.next.char] then c = c.next end
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and halant[c.next.char] then c = c.next end
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and vowel_modifier[c.next.char] then c = c.next end
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and stress_tone_mark[c.next.char] then c = c.next end
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and stress_tone_mark[c.next.char] then c = c.next end
--- current = c
--- syllableend = c
--- elseif consonant[current.char] then --Consonant syllable: {C+[N]+<H+[<ZWNJ|ZWJ>]|<ZWNJ|ZWJ>+H>} + C+[N]+[A] + [< H+[<ZWNJ|ZWJ>] | {M}+[N]+[H]>]+[SM]+[(VD)]
--- c = current
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and nukta[c.next.char] then c = c.next end
--- n = c
--- while n.next and n.next.id == glyph and n.next.subtype<256 and n.next.font == font and ( halant[n.next.char] or zwnj[n.next.char] or zwj[n.next.char] ) do
--- if halant[n.next.char] then
--- n = n.next
--- if n.next and n.next.id == glyph and n.next.subtype<256 and n.next.font == font and ( zwnj[n.next.char] or zwj[n.next.char] ) then n = n.next end
--- else
--- if n.next.next and n.next.next.id == glyph and n.next.next.subtype<256 and n.next.next.font == font and halant[n.next.next.char] then n = n.next.next end
--- end
--- if n.next and n.next.id == glyph and n.next.subtype<256 and n.next.font == font and consonant[n.next.char] then
--- n = n.next
--- if n.next and n.next.id == glyph and n.next.subtype<256 and n.next.font == font and nukta[n.next.char] then n = n.next end
--- c = n
--- else
--- break
--- end
--- end
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and anudatta[c.next.char] then c = c.next end
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and halant[c.next.char] then
--- c = c.next
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and ( zwnj[c.next.char] or zwj[c.next.char] ) then c = c.next end
--- else
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and dependent_vowel[c.next.char] then c = c.next end
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and nukta[c.next.char] then c = c.next end
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and halant[c.next.char] then c = c.next end
--- end
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and vowel_modifier[c.next.char] then c = c.next end
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and stress_tone_mark[c.next.char] then c = c.next end
--- if c.next and c.next.id == glyph and c.next.subtype<256 and c.next.font == font and stress_tone_mark[c.next.char] then c = c.next end
--- current = c
--- syllableend = c
--- end
--- end
---
--- if syllableend then
--- syl_nr = syl_nr + 1
--- c = syllablestart
--- while c ~= syllableend.next do
--- set_attribute(c,sylnr,syl_nr)
--- c = c.next
--- end
--- end
--- if syllableend and syllablestart ~= syllableend then
--- head, current = dev2_reorder(head,syllablestart,syllableend,font,attr)
--- end
---
--- if not syllableend and not has_attribute(current, state) and current.id == glyph and current.subtype<256 and current.font == font then -- Syntax error
--- if pre_mark[current.char] or above_mark[current.char] or below_mark[current.char] or post_mark[current.char] then
--- local n = node.copy(current)
--- if pre_mark[current.char] then
--- n.char = dotted_circle
--- else
--- current.char = dotted_circle
--- end
--- head, current = node.insert_after(head, current, n)
--- end
--- end
---
--- start = false
--- current = current.next
--- end
---
--- return head, done
--- end
---
--- function otf.handlers.dev2_reorder_matras(start,kind,lookupname,replacement)
--- return dev2_reorder_matras(start,kind,lookupname,replacement)
--- end
---
--- function otf.handlers.dev2_reorder_reph(start,kind,lookupname,replacement)
--- return dev2_reorder_reph(start,kind,lookupname,replacement)
--- end
---
--- function otf.handlers.dev2_reorder_pre_base_reordering_consonants(start,kind,lookupname,replacement)
--- return dev2_reorder_pre_base_reordering_consonants(start,kind,lookupname,replacement)
--- end
---
--- function otf.handlers.remove_joiners(start,kind,lookupname,replacement)
--- return remove_joiners(start,kind,lookupname,replacement)
--- end
diff --git a/tex/context/base/font-ota.lua b/tex/context/base/font-ota.lua
index 11615ea8b..61081cb9b 100644
--- a/tex/context/base/font-ota.lua
+++ b/tex/context/base/font-ota.lua
@@ -28,16 +28,17 @@ analyzers.initializers = initializers
analyzers.methods = methods
analyzers.useunicodemarks = false
+local a_state = attributes.private('state')
+
local nodecodes = nodes.nodecodes
local glyph_code = nodecodes.glyph
+local math_code = nodecodes.math
-local set_attribute = node.set_attribute
-local has_attribute = node.has_attribute
local traverse_id = node.traverse_id
local traverse_node_list = node.traverse
+local endofmath = nodes.endofmath
local fontdata = fonts.hashes.identifiers
-local state = attributes.private('state')
local categories = characters and characters.categories or { } -- sorry, only in context
local otffeatures = fonts.constructors.newfeatures("otf")
@@ -48,19 +49,40 @@ local registerotffeature = otffeatures.register
process features right.</p>
--ldx]]--
-analyzers.constants = {
- init = 1,
- medi = 2,
- fina = 3,
- isol = 4,
- -- devanagari
- rphf = 5,
- half = 6,
- pref = 7,
- blwf = 8,
- pstf = 9,
+-- never use these numbers directly
+
+local s_init = 1 local s_rphf = 7
+local s_medi = 2 local s_half = 8
+local s_fina = 3 local s_pref = 9
+local s_isol = 4 local s_blwf = 10
+local s_mark = 5 local s_pstf = 11
+local s_rest = 6
+
+local states = {
+ init = s_init,
+ medi = s_medi,
+ fina = s_fina,
+ isol = s_isol,
+ mark = s_mark,
+ rest = s_rest,
+ rphf = s_rphf,
+ half = s_half,
+ pref = s_pref,
+ blwf = s_blwf,
+ pstf = s_pstf,
+}
+
+local features = {
+ init = s_init,
+ medi = s_medi,
+ fina = s_fina,
+ isol = s_isol,
+ -- mark = s_mark,
}
+analyzers.states = states
+analyzers.features = features
+
-- todo: analyzers per script/lang, cross font, so we need an font id hash -> script
-- e.g. latin -> hyphenate, arab -> 1/2/3 analyze -- its own namespace
@@ -78,40 +100,42 @@ function analyzers.setstate(head,font)
if d then
if d.class == "mark" or (useunicodemarks and categories[char] == "mn") then
done = true
- set_attribute(current,state,5) -- mark
+ current[a_state] = s_mark
elseif n == 0 then
first, last, n = current, current, 1
- set_attribute(current,state,1) -- init
+ current[a_state] = s_init
else
last, n = current, n+1
- set_attribute(current,state,2) -- medi
+ current[a_state] = s_medi
end
else -- finish
if first and first == last then
- set_attribute(last,state,4) -- isol
+ last[a_state] = s_isol
elseif last then
- set_attribute(last,state,3) -- fina
+ last[a_state] = s_fina
end
first, last, n = nil, nil, 0
end
elseif id == disc_code then
-- always in the middle
- set_attribute(current,state,2) -- midi
+ current[a_state] = s_midi
last = current
else -- finish
if first and first == last then
- set_attribute(last,state,4) -- isol
+ last[a_state] = s_isol
elseif last then
- set_attribute(last,state,3) -- fina
+ last[a_state] = s_fina
end
first, last, n = nil, nil, 0
+-- elseif id == math_code then
+-- current = endofmath(current)
end
current = current.next
end
if first and first == last then
- set_attribute(last,state,4) -- isol
+ last[a_state] = s_isol
elseif last then
- set_attribute(last,state,3) -- fina
+ last[a_state] = s_fina
end
return head, done
end
@@ -273,19 +297,19 @@ local function finish(first,last)
if first == last then
local fc = first.char
if isol_fina_medi_init[fc] or isol_fina[fc] then
- set_attribute(first,state,4) -- isol
+ first[a_state] = s_isol
else
warning(first,"isol")
- set_attribute(first,state,0) -- error
+ first[a_state] = s_error
end
else
local lc = last.char
if isol_fina_medi_init[lc] or isol_fina[lc] then -- why isol here ?
-- if laststate == 1 or laststate == 2 or laststate == 4 then
- set_attribute(last,state,3) -- fina
+ last[a_state] = s_fina
else
warning(last,"fina")
- set_attribute(last,state,0) -- error
+ last[a_state] = s_error
end
end
first, last = nil, nil
@@ -293,10 +317,10 @@ local function finish(first,last)
-- first and last are either both set so we never com here
local fc = first.char
if isol_fina_medi_init[fc] or isol_fina[fc] then
- set_attribute(first,state,4) -- isol
+ first[a_state] = s_isol
else
warning(first,"isol")
- set_attribute(first,state,0) -- error
+ first[a_state] = s_error
end
first = nil
end
@@ -309,43 +333,45 @@ function methods.arab(head,font,attr) -- maybe make a special version with no tr
local marks = tfmdata.resources.marks
local first, last, current, done = nil, nil, head, false
while current do
- if current.id == glyph_code and current.font == font and current.subtype<256 and not has_attribute(current,state) then
+ if current.id == glyph_code and current.font == font and current.subtype<256 and not current[a_state] then
done = true
local char = current.char
if marks[char] or (useunicodemarks and categories[char] == "mn") then
- set_attribute(current,state,5) -- mark
+ current[a_state] = s_mark
elseif isol[char] then -- can be zwj or zwnj too
first, last = finish(first,last)
- set_attribute(current,state,4) -- isol
+ current[a_state] = s_isol
first, last = nil, nil
elseif not first then
if isol_fina_medi_init[char] then
- set_attribute(current,state,1) -- init
+ current[a_state] = s_init
first, last = first or current, current
elseif isol_fina[char] then
- set_attribute(current,state,4) -- isol
+ current[a_state] = s_isol
first, last = nil, nil
else -- no arab
first, last = finish(first,last)
end
elseif isol_fina_medi_init[char] then
first, last = first or current, current
- set_attribute(current,state,2) -- medi
+ current[a_state] = s_medi
elseif isol_fina[char] then
- if not has_attribute(last,state,1) then
+ if not last[a_state] == s_init then
-- tricky, we need to check what last may be !
- set_attribute(last,state,2) -- medi
+ last[a_state] = s_medi
end
- set_attribute(current,state,3) -- fina
+ current[a_state] = s_fina
first, last = nil, nil
elseif char >= 0x0600 and char <= 0x06FF then
- set_attribute(current,state,6) -- rest
+ current[a_state] = s_rest
first, last = finish(first,last)
else --no
first, last = finish(first,last)
end
else
first, last = finish(first,last)
+-- elseif id == math_code then
+-- current = endofmath(current).next
end
current = current.next
end
diff --git a/tex/context/base/font-otd.lua b/tex/context/base/font-otd.lua
index 89f84804c..cedc66a72 100644
--- a/tex/context/base/font-otd.lua
+++ b/tex/context/base/font-otd.lua
@@ -116,7 +116,7 @@ end
-- we reimplement the dataset resolver
-local constants = fonts.analyzers.constants
+local autofeatures = fonts.analyzers.features -- was: constants
local resolved = { } -- we only resolve a font,script,language,attribute pair once
local wildcard = "*"
@@ -147,7 +147,7 @@ local function initialize(sequence,script,language,s_enabled,a_enabled,font,attr
what = wildcard
end
if valid then
- local attribute = constants[kind] or false
+ local attribute = autofeatures[kind] or false
if a_e and dynamic < 0 then
valid = false
end
diff --git a/tex/context/base/font-otn.lua b/tex/context/base/font-otn.lua
index 5cf1423ea..cfdbdbaca 100644
--- a/tex/context/base/font-otn.lua
+++ b/tex/context/base/font-otn.lua
@@ -173,10 +173,10 @@ local insert_node_after = node.insert_after
local delete_node = nodes.delete
local copy_node = node.copy
local find_node_tail = node.tail or node.slide
-local set_attribute = node.set_attribute
-local has_attribute = node.has_attribute
local flush_node_list = node.flush_list
+local endofmath = nodes.endofmath
+
local setmetatableindex = table.setmetatableindex
local zwnj = 0x200C
@@ -192,6 +192,7 @@ local glyph_code = nodecodes.glyph
local glue_code = nodecodes.glue
local disc_code = nodecodes.disc
local whatsit_code = nodecodes.whatsit
+local math_code = nodecodes.math
local dir_code = whatcodes.dir
local localpar_code = whatcodes.localpar
@@ -206,15 +207,15 @@ local privateattribute = attributes.private
-- more complex than an average font) but I need proper examples of all cases, not
-- of only some.
-local state = privateattribute('state')
-local markbase = privateattribute('markbase')
-local markmark = privateattribute('markmark')
-local markdone = privateattribute('markdone') -- assigned at the injection end
-local cursbase = privateattribute('cursbase')
-local curscurs = privateattribute('curscurs')
-local cursdone = privateattribute('cursdone')
-local kernpair = privateattribute('kernpair')
-local ligacomp = privateattribute('ligacomp') -- assigned here (ideally it should be combined)
+local a_state = privateattribute('state')
+local a_markbase = privateattribute('markbase')
+local a_markmark = privateattribute('markmark')
+local a_markdone = privateattribute('markdone') -- assigned at the injection end
+local a_cursbase = privateattribute('cursbase')
+local a_curscurs = privateattribute('curscurs')
+local a_cursdone = privateattribute('cursdone')
+local a_kernpair = privateattribute('kernpair')
+local a_ligacomp = privateattribute('ligacomp') -- assigned here (ideally it should be combined)
local injections = nodes.injections
local setmark = injections.setmark
@@ -236,8 +237,7 @@ local onetimemessage = fonts.loggers.onetimemessage
otf.defaultnodealternate = "none" -- first last
--- we share some vars here, after all, we have no nested lookups and
--- less code
+-- we share some vars here, after all, we have no nested lookups and less code
local tfmdata = false
local characters = false
@@ -337,35 +337,18 @@ end
-- start is a mark and we need to keep that one
--- local function markstoligature(kind,lookupname,start,stop,char)
--- -- [start]..[stop]
--- local keep = start
--- local prev = start.prev
--- local next = stop.next
--- local base = copy_glyph(start)
--- local current, start = insert_node_after(start,start,base)
--- -- [current][start]..[stop]
--- current.next = next
--- if next then
--- next.prev = current
--- end
--- start.prev = nil
--- stop.next = nil
--- current.char = char
--- current.subtype = ligature_code
--- current.components = start
--- return keep
--- end
-
-local function markstoligature(kind,lookupname,start,stop,char)
+local function markstoligature(kind,lookupname,head,start,stop,char)
if start == stop and start.char == char then
- return start
+ return head, start
else
local prev = start.prev
local next = stop.next
start.prev = nil
stop.next = nil
local base = copy_glyph(start)
+ if head == start then
+ head = base
+ end
base.char = char
base.subtype = ligature_code
base.components = start
@@ -377,7 +360,7 @@ local function markstoligature(kind,lookupname,start,stop,char)
end
base.next = next
base.prev = prev
- return base
+ return head, base
end
end
@@ -406,16 +389,19 @@ local function getcomponentindex(start)
end
end
-local function toligature(kind,lookupname,start,stop,char,markflag,discfound) -- brr head
+local function toligature(kind,lookupname,head,start,stop,char,markflag,discfound) -- brr head
if start == stop and start.char == char then
start.char = char
- return start
+ return head, start
end
local prev = start.prev
local next = stop.next
start.prev = nil
stop.next = nil
local base = copy_glyph(start)
+ if start == head then
+ head = base
+ end
base.char = char
base.subtype = ligature_code
base.components = start -- start can have components
@@ -440,9 +426,9 @@ local function toligature(kind,lookupname,start,stop,char,markflag,discfound) --
baseindex = baseindex + componentindex
componentindex = getcomponentindex(start)
elseif not deletemarks then -- quite fishy
- set_attribute(start,ligacomp,baseindex + (has_attribute(start,ligacomp) or componentindex))
+ start[a_ligacomp] = baseindex + (start[a_ligacomp] or componentindex)
if trace_marks then
- logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(char),has_attribute(start,ligacomp))
+ logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(char),start[a_ligacomp])
end
head, current = insert_node_after(head,current,copy_node(start)) -- unlikely that mark has components
end
@@ -452,9 +438,9 @@ local function toligature(kind,lookupname,start,stop,char,markflag,discfound) --
while start and start.id == glyph_code do -- hm, is id test needed ?
local char = start.char
if marks[char] then
- set_attribute(start,ligacomp,baseindex + (has_attribute(start,ligacomp) or componentindex))
+ start[a_ligacomp] = baseindex + (start[a_ligacomp] or componentindex)
if trace_marks then
- logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(char),has_attribute(start,ligacomp))
+ logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(char),start[a_ligacomp])
end
else
break
@@ -462,15 +448,15 @@ local function toligature(kind,lookupname,start,stop,char,markflag,discfound) --
start = start.next
end
end
- return base
+ return head, base
end
-function handlers.gsub_single(start,kind,lookupname,replacement)
+function handlers.gsub_single(head,start,kind,lookupname,replacement)
if trace_singles then
logprocess("%s: replacing %s by single %s",pref(kind,lookupname),gref(start.char),gref(replacement))
end
start.char = replacement
- return start, true
+ return head, start, true
end
local function get_alternative_glyph(start,alternatives,value)
@@ -510,7 +496,7 @@ local function get_alternative_glyph(start,alternatives,value)
return choice
end
-local function multiple_glyphs(start,multiple) -- marks ?
+local function multiple_glyphs(head,start,multiple) -- marks ?
local nofmultiples = #multiple
if nofmultiples > 0 then
start.char = multiple[1]
@@ -528,16 +514,16 @@ local function multiple_glyphs(start,multiple) -- marks ?
start = n
end
end
- return start, true
+ return head, start, true
else
if trace_multiples then
logprocess("no multiple for %s",gref(start.char))
end
- return start, false
+ return head, start, false
end
end
-function handlers.gsub_alternate(start,kind,lookupname,alternative,sequence)
+function handlers.gsub_alternate(head,start,kind,lookupname,alternative,sequence)
local value = featurevalue == true and tfmdata.shared.features[kind] or featurevalue
local choice = get_alternative_glyph(start,alternative,value)
if choice then
@@ -550,17 +536,17 @@ function handlers.gsub_alternate(start,kind,lookupname,alternative,sequence)
logwarning("%s: no variant %s for %s",pref(kind,lookupname),tostring(value),gref(start.char))
end
end
- return start, true
+ return head, start, true
end
-function handlers.gsub_multiple(start,kind,lookupname,multiple)
+function handlers.gsub_multiple(head,start,kind,lookupname,multiple)
if trace_multiples then
logprocess("%s: replacing %s by multiple %s",pref(kind,lookupname),gref(start.char),gref(multiple))
end
- return multiple_glyphs(start,multiple)
+ return multiple_glyphs(head,start,multiple)
end
-function handlers.gsub_ligature(start,kind,lookupname,ligature,sequence)
+function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence)
local s, stop, discfound = start.next, nil, false
local startchar = start.char
if marks[startchar] then
@@ -584,12 +570,12 @@ function handlers.gsub_ligature(start,kind,lookupname,ligature,sequence)
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))
+ head, start = markstoligature(kind,lookupname,start,stop,lig)
+ logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char))
else
- start = markstoligature(kind,lookupname,start,stop,lig)
+ head, start = markstoligature(kind,lookupname,start,stop,lig)
end
- return start, true
+ return head, start, true
else
-- ok, goto next lookup
end
@@ -628,18 +614,18 @@ function handlers.gsub_ligature(start,kind,lookupname,ligature,sequence)
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))
+ head, start = toligature(kind,lookupname,head, start,stop,lig,skipmark,discfound)
+ logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char))
else
- start = toligature(kind,lookupname,start,stop,lig,skipmark,discfound)
+ head, start = toligature(kind,lookupname,head, start,stop,lig,skipmark,discfound)
end
- return start, true
+ return head, start, true
else
-- ok, goto next lookup
end
end
end
- return start, false
+ return head, start, false
end
--[[ldx--
@@ -647,7 +633,7 @@ end
we need to explicitly test for basechar, baselig and basemark entries.</p>
--ldx]]--
-function handlers.gpos_mark2base(start,kind,lookupname,markanchors,sequence)
+function handlers.gpos_mark2base(head,start,kind,lookupname,markanchors,sequence)
local markchar = start.char
if marks[markchar] then
local base = start.prev -- [glyph] [start=mark]
@@ -665,7 +651,7 @@ function handlers.gpos_mark2base(start,kind,lookupname,markanchors,sequence)
if trace_bugs then
logwarning("%s: no base for mark %s",pref(kind,lookupname),gref(markchar))
end
- return start, false
+ return head, start, false
end
end
end
@@ -686,7 +672,7 @@ function handlers.gpos_mark2base(start,kind,lookupname,markanchors,sequence)
logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%s,%s)",
pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy)
end
- return start, true
+ return head, start, true
end
end
end
@@ -704,10 +690,10 @@ function handlers.gpos_mark2base(start,kind,lookupname,markanchors,sequence)
elseif trace_bugs then
logwarning("%s: mark %s is no mark",pref(kind,lookupname),gref(markchar))
end
- return start, false
+ return head, start, false
end
-function handlers.gpos_mark2ligature(start,kind,lookupname,markanchors,sequence)
+function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequence)
-- check chainpos variant
local markchar = start.char
if marks[markchar] then
@@ -726,11 +712,11 @@ function handlers.gpos_mark2ligature(start,kind,lookupname,markanchors,sequence)
if trace_bugs then
logwarning("%s: no base for mark %s",pref(kind,lookupname),gref(markchar))
end
- return start, false
+ return head, start, false
end
end
end
- local index = has_attribute(start,ligacomp)
+ local index = start[a_ligacomp]
local baseanchors = descriptions[basechar]
if baseanchors then
baseanchors = baseanchors.anchors
@@ -749,7 +735,7 @@ function handlers.gpos_mark2ligature(start,kind,lookupname,markanchors,sequence)
logprocess("%s, anchor %s, index %s, bound %s: anchoring mark %s to baselig %s at index %s => (%s,%s)",
pref(kind,lookupname),anchor,index,bound,gref(markchar),gref(basechar),index,dx,dy)
end
- return start, true
+ return head, start, true
end
end
end
@@ -769,17 +755,17 @@ function handlers.gpos_mark2ligature(start,kind,lookupname,markanchors,sequence)
elseif trace_bugs then
logwarning("%s: mark %s is no mark",pref(kind,lookupname),gref(markchar))
end
- return start, false
+ return head, start, false
end
-function handlers.gpos_mark2mark(start,kind,lookupname,markanchors,sequence)
+function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence)
local markchar = start.char
if marks[markchar] then
local base = start.prev -- [glyph] [basemark] [start=mark]
- local slc = has_attribute(start,ligacomp)
+ local slc = start[a_ligacomp]
if slc then -- a rather messy loop ... needs checking with husayni
while base do
- local blc = has_attribute(base,ligacomp)
+ local blc = base[a_ligacomp]
if blc and blc ~= slc then
base = base.prev
else
@@ -805,7 +791,7 @@ function handlers.gpos_mark2mark(start,kind,lookupname,markanchors,sequence)
logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%s,%s)",
pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy)
end
- return start,true
+ return head, start, true
end
end
end
@@ -824,11 +810,11 @@ function handlers.gpos_mark2mark(start,kind,lookupname,markanchors,sequence)
elseif trace_bugs then
logwarning("%s: mark %s is no mark",pref(kind,lookupname),gref(markchar))
end
- return start,false
+ return head, start, false
end
-function handlers.gpos_cursive(start,kind,lookupname,exitanchors,sequence) -- to be checked
- local alreadydone = cursonce and has_attribute(start,cursbase)
+function handlers.gpos_cursive(head,start,kind,lookupname,exitanchors,sequence) -- to be checked
+ local alreadydone = cursonce and start[a_cursbase]
if not alreadydone then
local done = false
local startchar = start.char
@@ -874,30 +860,30 @@ function handlers.gpos_cursive(start,kind,lookupname,exitanchors,sequence) -- to
end
end
end
- return start, done
+ return head, start, done
else
if trace_cursive and trace_details then
logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(start.char),alreadydone)
end
- return start, false
+ return head, start, false
end
end
-function handlers.gpos_single(start,kind,lookupname,kerns,sequence)
+function handlers.gpos_single(head,start,kind,lookupname,kerns,sequence)
local startchar = start.char
local dx, dy, w, h = setpair(start,tfmdata.parameters.factor,rlmode,sequence.flags[4],kerns,characters[startchar])
if trace_kerns then
logprocess("%s: shifting single %s by (%s,%s) and correction (%s,%s)",pref(kind,lookupname),gref(startchar),dx,dy,w,h)
end
- return start, false
+ return head, start, false
end
-function handlers.gpos_pair(start,kind,lookupname,kerns,sequence)
+function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence)
-- todo: kerns in disc nodes: pre, post, replace -> loop over disc too
-- todo: kerns in components of ligatures
local snext = start.next
if not snext then
- return start, false
+ return head, start, false
else
local prev, done = start, false
local factor = tfmdata.parameters.factor
@@ -953,7 +939,7 @@ function handlers.gpos_pair(start,kind,lookupname,kerns,sequence)
break
end
end
- return start, done
+ return head, start, done
end
end
@@ -986,21 +972,21 @@ local logwarning = report_chain
-- We could share functions but that would lead to extra function calls with many
-- arguments, redundant tests and confusing messages.
-function chainprocs.chainsub(start,stop,kind,chainname,currentcontext,lookuphash,lookuplist,chainlookupname)
+function chainprocs.chainsub(head,start,stop,kind,chainname,currentcontext,lookuphash,lookuplist,chainlookupname)
logwarning("%s: a direct call to chainsub cannot happen",cref(kind,chainname,chainlookupname))
- return start, false
+ return head, start, false
end
-function chainmores.chainsub(start,stop,kind,chainname,currentcontext,lookuphash,lookuplist,chainlookupname,n)
+function chainmores.chainsub(head,start,stop,kind,chainname,currentcontext,lookuphash,lookuplist,chainlookupname,n)
logprocess("%s: a direct call to chainsub cannot happen",cref(kind,chainname,chainlookupname))
- return start, false
+ return head, start, false
end
-- The reversesub is a special case, which is why we need to store the replacements
-- in a bit weird way. There is no lookup and the replacement comes from the lookup
-- itself. It is meant mostly for dealing with Urdu.
-function chainprocs.reversesub(start,stop,kind,chainname,currentcontext,lookuphash,replacements)
+function chainprocs.reversesub(head,start,stop,kind,chainname,currentcontext,lookuphash,replacements)
local char = start.char
local replacement = replacements[char]
if replacement then
@@ -1008,9 +994,9 @@ function chainprocs.reversesub(start,stop,kind,chainname,currentcontext,lookupha
logprocess("%s: single reverse replacement of %s by %s",cref(kind,chainname),gref(char),gref(replacement))
end
start.char = replacement
- return start, true
+ return head, start, true
else
- return start, false
+ return head, start, false
end
end
@@ -1038,10 +1024,10 @@ local function delete_till_stop(start,stop,ignoremarks) -- keeps start
repeat -- start x x m x x stop => start m
local next = start.next
if not marks[next.char] then
-local components = next.components
-if components then -- probably not needed
- flush_node_list(components)
-end
+ local components = next.components
+ if components then -- probably not needed
+ flush_node_list(components)
+ end
delete_node(start,next)
end
n = n + 1
@@ -1049,10 +1035,10 @@ end
else -- start x x x stop => start
repeat
local next = start.next
-local components = next.components
-if components then -- probably not needed
- flush_node_list(components)
-end
+ local components = next.components
+ if components then -- probably not needed
+ flush_node_list(components)
+ end
delete_node(start,next)
n = n + 1
until next == stop
@@ -1065,7 +1051,7 @@ end
match.</p>
--ldx]]--
-function chainprocs.gsub_single(start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex)
+function chainprocs.gsub_single(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex)
-- todo: marks ?
local current = start
local subtables = currentlookup.subtables
@@ -1094,14 +1080,14 @@ function chainprocs.gsub_single(start,stop,kind,chainname,currentcontext,lookuph
current.char = replacement
end
end
- return start, true
+ return head, start, true
elseif current == stop then
break
else
current = current.next
end
end
- return start, false
+ return head, start, false
end
chainmores.gsub_single = chainprocs.gsub_single
@@ -1111,7 +1097,7 @@ chainmores.gsub_single = chainprocs.gsub_single
the match.</p>
--ldx]]--
-function chainprocs.gsub_multiple(start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname)
+function chainprocs.gsub_multiple(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname)
delete_till_stop(start,stop) -- we could pass ignoremarks as #3 ..
local startchar = start.char
local subtables = currentlookup.subtables
@@ -1123,7 +1109,7 @@ function chainprocs.gsub_multiple(start,stop,kind,chainname,currentcontext,looku
end
else
replacements = replacements[startchar]
- if not replacements then
+ if not replacements or replacement == "" then
if trace_bugs then
logwarning("%s: no multiple for %s",cref(kind,chainname,chainlookupname,lookupname),gref(startchar))
end
@@ -1131,17 +1117,12 @@ function chainprocs.gsub_multiple(start,stop,kind,chainname,currentcontext,looku
if trace_multiples then
logprocess("%s: replacing %s by multiple characters %s",cref(kind,chainname,chainlookupname,lookupname),gref(startchar),gref(replacements))
end
- return multiple_glyphs(start,replacements)
+ return multiple_glyphs(head,start,replacements)
end
end
- return start, false
+ return head, start, false
end
--- function chainmores.gsub_multiple(start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,n)
--- logprocess("%s: gsub_multiple not yet supported",cref(kind,chainname,chainlookupname))
--- return start, false
--- end
-
chainmores.gsub_multiple = chainprocs.gsub_multiple
--[[ldx--
@@ -1156,7 +1137,7 @@ chainmores.gsub_multiple = chainprocs.gsub_multiple
-- marks come last anyway
-- are there cases where we need to delete the mark
-function chainprocs.gsub_alternate(start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname)
+function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname)
local current = start
local subtables = currentlookup.subtables
local value = featurevalue == true and tfmdata.shared.features[kind] or featurevalue
@@ -1187,21 +1168,16 @@ function chainprocs.gsub_alternate(start,stop,kind,chainname,currentcontext,look
logwarning("%s: no alternative for %s",cref(kind,chainname,chainlookupname,lookupname),gref(currentchar))
end
end
- return start, true
+ return head, start, true
elseif current == stop then
break
else
current = current.next
end
end
- return start, false
+ return head, start, false
end
--- function chainmores.gsub_alternate(start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,n)
--- logprocess("%s: gsub_alternate not yet supported",cref(kind,chainname,chainlookupname))
--- return start, false
--- end
-
chainmores.gsub_alternate = chainprocs.gsub_alternate
--[[ldx--
@@ -1210,7 +1186,7 @@ this function (move code inline and handle the marks by a separate function). We
assume rather stupid ligatures (no complex disc nodes).</p>
--ldx]]--
-function chainprocs.gsub_ligature(start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex)
+function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex)
local startchar = start.char
local subtables = currentlookup.subtables
local lookupname = subtables[1]
@@ -1262,13 +1238,13 @@ function chainprocs.gsub_ligature(start,stop,kind,chainname,currentcontext,looku
end
if trace_ligatures then
if start == stop then
- logprocess("%s: replacing character %s by ligature %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(l2))
+ logprocess("%s: replacing character %s by ligature %s case 3",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(l2))
else
- logprocess("%s: replacing character %s upto %s by ligature %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(stop.char),gref(l2))
+ logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(stop.char),gref(l2))
end
end
- start = toligature(kind,lookupname,start,stop,l2,currentlookup.flags[1],discfound)
- return start, true, nofreplacements
+ head, start = toligature(kind,lookupname,head,start,stop,l2,currentlookup.flags[1],discfound)
+ return head, start, true, nofreplacements
elseif trace_bugs then
if start == stop then
logwarning("%s: replacing character %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar))
@@ -1278,12 +1254,12 @@ function chainprocs.gsub_ligature(start,stop,kind,chainname,currentcontext,looku
end
end
end
- return start, false, 0
+ return head, start, false, 0
end
chainmores.gsub_ligature = chainprocs.gsub_ligature
-function chainprocs.gpos_mark2base(start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname)
+function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname)
local markchar = start.char
if marks[markchar] then
local subtables = currentlookup.subtables
@@ -1308,7 +1284,7 @@ function chainprocs.gpos_mark2base(start,stop,kind,chainname,currentcontext,look
if trace_bugs then
logwarning("%s: no base for mark %s",pref(kind,lookupname),gref(markchar))
end
- return start, false
+ return head, start, false
end
end
end
@@ -1326,7 +1302,7 @@ function chainprocs.gpos_mark2base(start,stop,kind,chainname,currentcontext,look
logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%s,%s)",
cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy)
end
- return start, true
+ return head, start, true
end
end
end
@@ -1344,10 +1320,10 @@ function chainprocs.gpos_mark2base(start,stop,kind,chainname,currentcontext,look
elseif trace_bugs then
logwarning("%s: mark %s is no mark",cref(kind,chainname,chainlookupname),gref(markchar))
end
- return start, false
+ return head, start, false
end
-function chainprocs.gpos_mark2ligature(start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname)
+function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname)
local markchar = start.char
if marks[markchar] then
local subtables = currentlookup.subtables
@@ -1372,12 +1348,12 @@ function chainprocs.gpos_mark2ligature(start,stop,kind,chainname,currentcontext,
if trace_bugs then
logwarning("%s: no base for mark %s",cref(kind,chainname,chainlookupname,lookupname),markchar)
end
- return start, false
+ return head, start, false
end
end
end
-- todo: like marks a ligatures hash
- local index = has_attribute(start,ligacomp)
+ local index = start[a_ligacomp]
local baseanchors = descriptions[basechar].anchors
if baseanchors then
local baseanchors = baseanchors['baselig']
@@ -1394,7 +1370,7 @@ function chainprocs.gpos_mark2ligature(start,stop,kind,chainname,currentcontext,
logprocess("%s, anchor %s, bound %s: anchoring mark %s to baselig %s at index %s => (%s,%s)",
cref(kind,chainname,chainlookupname,lookupname),anchor,a or bound,gref(markchar),gref(basechar),index,dx,dy)
end
- return start, true
+ return head, start, true
end
end
end
@@ -1413,13 +1389,13 @@ function chainprocs.gpos_mark2ligature(start,stop,kind,chainname,currentcontext,
elseif trace_bugs then
logwarning("%s: mark %s is no mark",cref(kind,chainname,chainlookupname),gref(markchar))
end
- return start, false
+ return head, start, false
end
-function chainprocs.gpos_mark2mark(start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname)
+function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname)
local markchar = start.char
if marks[markchar] then
---~ local alreadydone = markonce and has_attribute(start,markmark)
+--~ local alreadydone = markonce and start[a_markmark]
--~ if not alreadydone then
-- local markanchors = descriptions[markchar].anchors markanchors = markanchors and markanchors.mark
local subtables = currentlookup.subtables
@@ -1430,10 +1406,10 @@ function chainprocs.gpos_mark2mark(start,stop,kind,chainname,currentcontext,look
end
if markanchors then
local base = start.prev -- [glyph] [basemark] [start=mark]
- local slc = has_attribute(start,ligacomp)
+ local slc = start[a_ligacomp]
if slc then -- a rather messy loop ... needs checking with husayni
while base do
- local blc = has_attribute(base,ligacomp)
+ local blc = base[a_ligacomp]
if blc and blc ~= slc then
base = base.prev
else
@@ -1457,7 +1433,7 @@ function chainprocs.gpos_mark2mark(start,stop,kind,chainname,currentcontext,look
logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%s,%s)",
cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy)
end
- return start, true
+ return head, start, true
end
end
end
@@ -1478,13 +1454,11 @@ function chainprocs.gpos_mark2mark(start,stop,kind,chainname,currentcontext,look
elseif trace_bugs then
logwarning("%s: mark %s is no mark",cref(kind,chainname,chainlookupname),gref(markchar))
end
- return start, false
+ return head, start, false
end
--- ! ! ! untested ! ! !
-
-function chainprocs.gpos_cursive(start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname)
- local alreadydone = cursonce and has_attribute(start,cursbase)
+function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname)
+ local alreadydone = cursonce and start[a_cursbase]
if not alreadydone then
local startchar = start.char
local subtables = currentlookup.subtables
@@ -1537,18 +1511,18 @@ function chainprocs.gpos_cursive(start,stop,kind,chainname,currentcontext,lookup
end
end
end
- return start, done
+ return head, start, done
else
if trace_cursive and trace_details then
logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(start.char),alreadydone)
end
- return start, false
+ return head, start, false
end
end
- return start, false
+ return head, start, false
end
-function chainprocs.gpos_single(start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex,sequence)
+function chainprocs.gpos_single(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex,sequence)
-- untested .. needs checking for the new model
local startchar = start.char
local subtables = currentlookup.subtables
@@ -1563,12 +1537,12 @@ function chainprocs.gpos_single(start,stop,kind,chainname,currentcontext,lookuph
end
end
end
- return start, false
+ return head, start, false
end
-- when machines become faster i will make a shared function
-function chainprocs.gpos_pair(start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex,sequence)
+function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex,sequence)
-- logwarning("%s: gpos_pair not yet supported",cref(kind,chainname,chainlookupname))
local snext = start.next
if snext then
@@ -1632,11 +1606,11 @@ function chainprocs.gpos_pair(start,stop,kind,chainname,currentcontext,lookuphas
break
end
end
- return start, done
+ return head, start, done
end
end
end
- return start, false
+ return head, start, false
end
-- what pointer to return, spec says stop
@@ -1655,7 +1629,7 @@ local function show_skip(kind,chainname,char,ck,class)
end
end
-local function normal_handle_contextchain(start,kind,chainname,contexts,sequence,lookuphash)
+local function normal_handle_contextchain(head,start,kind,chainname,contexts,sequence,lookuphash)
-- local rule, lookuptype, sequence, f, l, lookups = ck[1], ck[2] ,ck[3], ck[4], ck[5], ck[6]
local flags = sequence.flags
local done = false
@@ -1881,7 +1855,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence
if chainlookup then
local cp = chainprocs[chainlookup.type]
if cp then
- start, done = cp(start,last,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,nil,sequence)
+ head, start, done = cp(head,start,last,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,nil,sequence)
else
logprocess("%s: %s is not yet supported",cref(kind,chainname,chainlookupname),chainlookup.type)
end
@@ -1912,7 +1886,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence
local cp = chainlookup and chainmores[chainlookup.type]
if cp then
local ok, n
- start, ok, n = cp(start,last,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,i,sequence)
+ head, start, ok, n = cp(head,start,last,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,i,sequence)
-- messy since last can be changed !
if ok then
done = true
@@ -1932,7 +1906,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence
else
local replacements = ck[7]
if replacements then
- start, done = chainprocs.reversesub(start,last,kind,chainname,ck,lookuphash,replacements) -- sequence
+ head, start, done = chainprocs.reversesub(head,start,last,kind,chainname,ck,lookuphash,replacements) -- sequence
else
done = true -- can be meant to be skipped
if trace_contexts then
@@ -1942,7 +1916,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence
end
end
end
- return start, done
+ return head, start, done
end
-- Because we want to keep this elsewhere (an because speed is less an issue) we
@@ -1955,7 +1929,7 @@ local verbose_handle_contextchain = function(font,...)
end
otf.chainhandlers = {
- normal = normal_handle_contextchain,
+ normal = normal_handle_contextchain,
verbose = verbose_handle_contextchain,
}
@@ -2018,7 +1992,7 @@ end)
-- fonts.hashes.lookups = lookuphashes
-local constants = fonts.analyzers.constants
+local autofeatures = fonts.analyzers.features -- was: constants
local function initialize(sequence,script,language,enabled)
local features = sequence.features
@@ -2028,7 +2002,7 @@ local function initialize(sequence,script,language,enabled)
if valid then
local languages = scripts[script] or scripts[wildcard]
if languages and (languages[language] or languages[wildcard]) then
- return { valid, constants[kind] or false, sequence.chain or 0, kind, sequence }
+ return { valid, autofeatures[kind] or false, sequence.chain or 0, kind, sequence }
end
end
end
@@ -2149,7 +2123,7 @@ local function featuresprocessor(head,font,attr)
local id = start.id
if id == glyph_code then
if start.font == font and start.subtype<256 then
- local a = has_attribute(start,0)
+ local a = start[0]
if a then
a = a == attr
else
@@ -2162,12 +2136,8 @@ local function featuresprocessor(head,font,attr)
if lookupcache then
local lookupmatch = lookupcache[start.char]
if lookupmatch then
- -- local headnode = start == head
- start, success = handler(start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i)
+ head, start, success = handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i)
if success then
- -- if headnode then
- -- head = start
- -- end
break
end
end
@@ -2201,30 +2171,28 @@ local function featuresprocessor(head,font,attr)
local id = start.id
if id == glyph_code then
if start.font == font and start.subtype<256 then
- local a = has_attribute(start,0)
+ local a = start[0]
if a then
- a = (a == attr) and (not attribute or has_attribute(start,state,attribute))
+ a = (a == attr) and (not attribute or start[a_state] == attribute)
else
- a = not attribute or has_attribute(start,state,attribute)
+ a = not attribute or start[a_state] == attribute
end
if a then
local lookupmatch = lookupcache[start.char]
if lookupmatch then
-- sequence kan weg
- -- local headnode = start == head
local ok
- start, ok = handler(start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1)
+ head, start, ok = handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1)
if ok then
success = true
- -- if headnode then
- -- head = start
- -- end
end
end
if start then start = start.next end
else
start = start.next
end
+elseif id == math_code then
+ start = endofmath(start).next
else
start = start.next
end
@@ -2264,6 +2232,8 @@ local function featuresprocessor(head,font,attr)
end
end
start = start.next
+elseif id == math_code then
+ start = endofmath(start).next
else
start = start.next
end
@@ -2274,11 +2244,11 @@ local function featuresprocessor(head,font,attr)
local id = start.id
if id == glyph_code then
if start.font == font and start.subtype<256 then
- local a = has_attribute(start,0)
+ local a = start[0]
if a then
- a = (a == attr) and (not attribute or has_attribute(start,state,attribute))
+ a = (a == attr) and (not attribute or start[a_state] == attribute)
else
- a = not attribute or has_attribute(start,state,attribute)
+ a = not attribute or start[a_state] == attribute
end
if a then
for i=1,ns do
@@ -2288,14 +2258,10 @@ local function featuresprocessor(head,font,attr)
local lookupmatch = lookupcache[start.char]
if lookupmatch then
-- we could move all code inline but that makes things even more unreadable
- -- local headnode = start == head
local ok
- start, ok = handler(start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i)
+ head, start, ok = handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i)
if ok then
success = true
- -- if headnode then
- -- head = start
- -- end
break
end
end
@@ -2346,6 +2312,8 @@ local function featuresprocessor(head,font,attr)
end
end
start = start.next
+elseif id == math_code then
+ start = endofmath(start).next
else
start = start.next
end
@@ -2622,6 +2590,6 @@ registerotffeature {
}
}
--- this will change but is needed for an experiment:
+-- This can be used for extra handlers, but should be used with care!
otf.handlers = handlers
diff --git a/tex/context/base/font-sol.lua b/tex/context/base/font-sol.lua
index b44594349..874a485cc 100644
--- a/tex/context/base/font-sol.lua
+++ b/tex/context/base/font-sol.lua
@@ -51,8 +51,6 @@ local settings_to_hash = utilities.parsers.settings_to_hash
local find_node_tail = node.tail or node.slide
local free_node = node.free
local free_nodelist = node.flush_list
-local has_attribute = node.has_attribute
-local set_attribute = node.set_attribute
local copy_nodelist = node.copy_list
local traverse_nodes = node.traverse
local traverse_ids = node.traverse_id
@@ -334,7 +332,7 @@ function splitters.split(head)
else
local current = start
while true do
- set_attribute(current,a_word,n)
+ current[a_word] = n
if current == stop then
break
else
@@ -370,7 +368,7 @@ function splitters.split(head)
local id = current.id
if id == glyph_code then
if current.subtype < 256 then
- local a = has_attribute(current,a_split)
+ local a = current[a_split]
if not a then
start, stop = nil, nil
elseif not start then
@@ -440,7 +438,7 @@ local function collect_words(list) -- can be made faster for attributes
-- todo: disc and kern
local id = current.id
if id == glyph_code or id == disc_code then
- local a = has_attribute(current,a_word)
+ local a = current[a_word]
if a then
if a == index then
-- same word
@@ -473,7 +471,7 @@ local function collect_words(list) -- can be made faster for attributes
report_splitters("skipped: %s",utfchar(current.char))
end
end
- elseif id == kern_code and (current.subtype == fontkern_code or has_attribute(current,a_fontkern)) then
+ elseif id == kern_code and (current.subtype == fontkern_code or current[a_fontkern]) then
if first then
last = current
else
@@ -557,17 +555,17 @@ local function doit(word,list,best,width,badness,line,set,listdir)
local first = copy_nodelist(original)
if not trace_colors then
for n in traverse_nodes(first) do -- maybe fast force so no attr needed
- set_attribute(n,0,featurenumber) -- this forces dynamics
+ n[0] = featurenumber -- this forces dynamics
end
elseif set == "less" then
for n in traverse_nodes(first) do
setnodecolor(n,"font:isol") -- yellow
- set_attribute(n,0,featurenumber)
+ n[0] = featurenumber
end
else
for n in traverse_nodes(first) do
setnodecolor(n,"font:medi") -- green
- set_attribute(n,0,featurenumber)
+ n[0] = featurenumber
end
end
local font = found.font
diff --git a/tex/context/base/l-boolean.lua b/tex/context/base/l-boolean.lua
index 2b94de76b..f087f1a4c 100644
--- a/tex/context/base/l-boolean.lua
+++ b/tex/context/base/l-boolean.lua
@@ -15,7 +15,7 @@ function boolean.tonumber(b)
if b then return 1 else return 0 end -- test and return or return
end
-function toboolean(str,tolerant)
+function toboolean(str,tolerant) -- global
if str == nil then
return false
elseif str == false then
@@ -40,18 +40,16 @@ end
string.toboolean = toboolean
function string.booleanstring(str)
- if str == nil then
- return false
- elseif str == false then
+ if str == "0" then
return false
- elseif str == true then
- return true
- elseif str == "true" then
+ elseif str == "1" then
return true
- elseif str == "false" then
+ elseif str == "" then
return false
- elseif str == 0 then
+ elseif str == "false" then
return false
+ elseif str == "true" then
+ return true
elseif (tonumber(str) or 0) > 0 then
return true
else
diff --git a/tex/context/base/lang-wrd.lua b/tex/context/base/lang-wrd.lua
index 84d6107d4..c093d11d7 100644
--- a/tex/context/base/lang-wrd.lua
+++ b/tex/context/base/lang-wrd.lua
@@ -26,13 +26,13 @@ words.threshold = 4
local numbers = languages.numbers
local registered = languages.registered
-local set_attribute = node.set_attribute
-local unset_attribute = node.unset_attribute
local traverse_nodes = node.traverse
local wordsdata = words.data
local chardata = characters.data
local tasks = nodes.tasks
+local unsetvalue = attributes.unsetvalue
+
local nodecodes = nodes.nodecodes
local kerncodes = nodes.kerncodes
@@ -207,7 +207,7 @@ table.setmetatableindex(cache, function(t,k) -- k == language, numbers[k] == tag
else
c = colist["word:" .. (numbers[k] or "unset")] or colist["word:unknown"]
end
- local v = c and function(n) set_attribute(n,a_color,c) end or false
+ local v = c and function(n) n[a_color] = c end or false
t[k] = v
return v
end)
@@ -226,7 +226,7 @@ end
methods[1] = function(head)
for n in traverse_nodes(head) do
- unset_attribute(n,a_color) -- hm, not that selective (reset color)
+ n[a_color] = unsetvalue -- hm, not that selective (reset color)
end
return mark_words(head,sweep)
end
@@ -327,7 +327,7 @@ end
methods[3] = function(head)
for n in traverse_nodes(head) do
- unset_attribute(n,a_color)
+ n[a_color] = unsetvalue
end
return mark_words(head,sweep)
end
diff --git a/tex/context/base/lpdf-tag.lua b/tex/context/base/lpdf-tag.lua
index 0be9d3452..2763633c2 100644
--- a/tex/context/base/lpdf-tag.lua
+++ b/tex/context/base/lpdf-tag.lua
@@ -45,9 +45,11 @@ local glyph_code = nodecodes.glyph
local a_tagged = attributes.private('tagged')
local a_image = attributes.private('image')
-local has_attribute, set_attribute, traverse_nodes, traverse_id = node.has_attribute, node.set_attribute, node.traverse, node.traverse_id
-local tosequence = nodes.tosequence
-local copy_node, slide_nodelist = node.copy, node.slide
+local traverse_nodes = node.traverse
+local traverse_id = node.traverse_id
+local tosequence = nodes.tosequence
+local copy_node = node.copy
+local slide_nodelist = node.slide
local structure_stack = { }
local structure_kids = pdfarray()
@@ -226,7 +228,7 @@ local function collectranges(head,list)
for n in traverse_nodes(head) do
local id = n.id -- 14: image, 8: literal (mp)
if id == glyph_code then
- local at = has_attribute(n,a_tagged)
+ local at = n[a_tagged]
if not at then
range = nil
elseif last ~= at then
@@ -237,9 +239,9 @@ local function collectranges(head,list)
range[4] = n -- stop
end
elseif id == hlist_code or id == vlist_code then
- local at = has_attribute(n,a_image)
+ local at = n[a_image]
if at then
- local at = has_attribute(n,a_tagged)
+ local at = n[a_tagged]
if not at then
range = nil
else
diff --git a/tex/context/base/math-noa.lua b/tex/context/base/math-noa.lua
index 3c67d26a2..2e97750a1 100644
--- a/tex/context/base/math-noa.lua
+++ b/tex/context/base/math-noa.lua
@@ -51,8 +51,9 @@ local report_alternates = logs.reporter("mathematics","alternates")
local report_italics = logs.reporter("mathematics","italics")
local report_families = logs.reporter("mathematics","families")
-local set_attribute = node.set_attribute
-local has_attribute = node.has_attribute
+local a_mathrendering = attributes.private("mathrendering")
+local a_exportstatus = attributes.private("exportstatus")
+
local mlist_to_hlist = node.mlist_to_hlist
local font_of_family = node.family_font
local insert_node_after = node.insert_after
@@ -94,12 +95,12 @@ local tasks = nodes.tasks
local nodecodes = nodes.nodecodes
local noadcodes = nodes.noadcodes
-local noad_ord = noadcodes.ord
-local noad_rel = noadcodes.rel
-local noad_punct = noadcodes.punct
-local noad_opdisplaylimits = noadcodes.opdisplaylimits
-local noad_oplimits = noadcodes.oplimits
-local noad_opnolimits = noadcodes.opnolimits
+local noad_ord = noadcodes.ord
+local noad_rel = noadcodes.rel
+local noad_punct = noadcodes.punct
+local noad_opdisplaylimits= noadcodes.opdisplaylimits
+local noad_oplimits = noadcodes.oplimits
+local noad_opnolimits = noadcodes.opnolimits
local math_noad = nodecodes.noad -- attr nucleus sub sup
local math_accent = nodecodes.accent -- attr nucleus sub sup accent
@@ -201,10 +202,94 @@ end
noads.process = processnoads
+-- experiment (when not present fall back to fam 0) -- needs documentation
+
+-- 0-2 regular
+-- 3-5 bold
+-- 6-8 pseudobold
+
+local families = { }
+local a_mathfamily = attributes.private("mathfamily")
+local boldmap = mathematics.boldmap
+
+local familymap = { [0] =
+ "regular",
+ "regular",
+ "regular",
+ "bold",
+ "bold",
+ "bold",
+ "pseudobold",
+ "pseudobold",
+ "pseudobold",
+}
+
+families[math_char] = function(pointer)
+ if pointer.fam == 0 then
+ local a = pointer[a_mathfamily]
+ if a and a > 0 then
+ pointer[a_mathfamily] = 0
+ if a > 5 then
+ local char = pointer.char
+ local bold = boldmap[char]
+ local newa = a - 3
+ if bold then
+ pointer[a_exportstatus] = char
+ pointer.char = bold
+ if trace_families then
+ report_families("replacing U+%05X (%s) by bold U+%05X (%s), family %s (%s) becomes %s (%s)",
+ char,utfchar(char),bold,utfchar(bold),a,familymap[a],newa,familymap[newa])
+ end
+ else
+ if trace_families then
+ report_families("no bold replacement for U+%05X (%s), family %s (%s) becomes %s (%s)",
+ char,utfchar(char),a,familymap[a],newa,familymap[newa])
+ end
+ end
+ pointer.fam = newa
+ else
+ if trace_families then
+ local char = pointer.char
+ report_families("family of U+%05X (%s) becomes %s (%s)",
+ char,utfchar(char),a,familymap[a])
+ end
+ pointer.fam = a
+ end
+ else
+ -- pointer.fam = 0
+ end
+ end
+end
+
+families[math_delim] = function(pointer)
+ if pointer.small_fam == 0 then
+ local a = pointer[a_mathfamily]
+ if a and a > 0 then
+ pointer[a_mathfamily] = 0
+ if a > 5 then
+ -- no bold delimiters in unicode
+ a = a - 3
+ end
+ pointer.small_fam = a
+ pointer.large_fam = a
+ else
+ pointer.small_fam = 0
+ pointer.large_fam = 0
+ end
+ end
+end
+
+families[math_textchar] = families[math_char]
+
+function handlers.families(head,style,penalties)
+ processnoads(head,families,"families")
+ return true
+end
+
-- character remapping
-local mathalphabet = attributes.private("mathalphabet")
-local mathgreek = attributes.private("mathgreek")
+local a_mathalphabet = attributes.private("mathalphabet")
+local a_mathgreek = attributes.private("mathgreek")
processors.relocate = { }
@@ -212,8 +297,9 @@ local function report_remap(tag,id,old,new,extra)
report_remapping("remapping %s in font %s from U+%05X (%s) to U+%05X (%s)%s",tag,id,old,utfchar(old),new,utfchar(new),extra or "")
end
-local remapalphabets = mathematics.remapalphabets
-local setnodecolor = nodes.tracers.colors.set
+local remapalphabets = mathematics.remapalphabets
+local fallbackstyleattr = mathematics.fallbackstyleattr
+local setnodecolor = nodes.tracers.colors.set
--~ This does not work out well, as there are no fallbacks. Ok, we could
--~ define a poor mans simplify mechanism.
@@ -233,22 +319,62 @@ local function checked(pointer)
if trace_analyzing then
setnodecolor(pointer,"font:isol")
end
- set_attribute(pointer,exportstatus,char) -- testcase: exponentiale
+ pointer[a_exportstatus] = char -- testcase: exponentiale
pointer.char = newchar
return true
end
end
end
+-- processors.relocate[math_char] = function(pointer)
+-- local g = pointer[a_mathgreek] or 0
+-- local a = pointer[a_mathalphabet] or 0
+-- if a > 0 or g > 0 then
+-- if a > 0 then
+-- pointer[a_mathgreek] = 0
+-- end
+-- if g > 0 then
+-- pointer[a_mathalphabet] = 0
+-- end
+-- local char = pointer.char
+-- local newchar = remapalphabets(char,a,g)
+-- if newchar then
+-- local fam = pointer.fam
+-- local id = font_of_family(fam)
+-- local characters = fontcharacters[id]
+-- if characters and characters[newchar] then
+-- if trace_remapping then
+-- report_remap("char",id,char,newchar)
+-- end
+-- if trace_analyzing then
+-- setnodecolor(pointer,"font:isol")
+-- end
+-- pointer.char = newchar
+-- return true
+-- else
+-- if trace_remapping then
+-- report_remap("char",id,char,newchar," fails")
+-- end
+-- end
+-- end
+-- end
+-- if trace_analyzing then
+-- setnodecolor(pointer,"font:medi")
+-- end
+-- if check_coverage then
+-- return checked(pointer)
+-- end
+-- end
+
processors.relocate[math_char] = function(pointer)
- local g = has_attribute(pointer,mathgreek) or 0
- local a = has_attribute(pointer,mathalphabet) or 0
+ local g = pointer[a_mathgreek] or 0
+ local a = pointer[a_mathalphabet] or 0
if a > 0 or g > 0 then
if a > 0 then
- set_attribute(pointer,mathgreek,0)
+ pointer[a_mathgreek] = 0
end
if g > 0 then
- set_attribute(pointer,mathalphabet,0)
+ pointer[a_mathalphabet] = 0
end
local char = pointer.char
local newchar = remapalphabets(char,a,g)
@@ -256,7 +382,7 @@ processors.relocate[math_char] = function(pointer)
local fam = pointer.fam
local id = font_of_family(fam)
local characters = fontcharacters[id]
- if characters and characters[newchar] then
+ if characters[newchar] then
if trace_remapping then
report_remap("char",id,char,newchar)
end
@@ -266,8 +392,27 @@ processors.relocate[math_char] = function(pointer)
pointer.char = newchar
return true
else
- if trace_remapping then
- report_remap("char",id,char,newchar," fails")
+ local fallback = fallbackstyleattr(a)
+ if fallback then
+ local newchar = remapalphabets(char,fallback,g)
+ if newchar then
+ if characters[newchar] then
+ if trace_remapping then
+ report_remap("char",id,char,newchar," (fallback remapping used)")
+ end
+ if trace_analyzing then
+ setnodecolor(pointer,"font:isol")
+ end
+ pointer.char = newchar
+ return true
+ elseif trace_remapping then
+ report_remap("char",id,char,newchar," fails (no fallback character)")
+ end
+ elseif trace_remapping then
+ report_remap("char",id,char,newchar," fails (no fallback remap character)")
+ end
+ elseif trace_remapping then
+ report_remap("char",id,char,newchar," fails (no fallback style)")
end
end
end
@@ -299,15 +444,12 @@ end
-- rendering (beware, not exported)
-local a_mathrendering = attributes.private("mathrendering")
-local a_exportstatus = attributes.private("exportstatus")
-
processors.render = { }
local rendersets = mathematics.renderings.numbers or { } -- store
processors.render[math_char] = function(pointer)
- local attr = has_attribute(pointer,a_mathrendering)
+ local attr = pointer[a_mathrendering]
if attr and attr > 0 then
local char = pointer.char
local renderset = rendersets[attr]
@@ -319,7 +461,7 @@ processors.render[math_char] = function(pointer)
local characters = fontcharacters[id]
if characters and characters[newchar] then
pointer.char = newchar
- set_attribute(pointer,a_exportstatus,char)
+ pointer[a_exportstatus] = char
end
end
end
@@ -347,9 +489,9 @@ local resize = { } processors.resize = resize
resize[math_fence] = function(pointer)
if pointer.subtype == left_fence_code then
- local a = has_attribute(pointer,mathsize)
+ local a = pointer[mathsize]
if a and a > 0 then
- set_attribute(pointer,mathsize,0)
+ pointer[mathsize] = 0
local d = pointer.delim
local df = d.small_fam
local id = font_of_family(df)
@@ -377,9 +519,9 @@ end
-- respace[math_char] = function(pointer,what,n,parent) -- not math_noad .. math_char ... and then parent
-- pointer = parent
-- if pointer and pointer.subtype == noad_ord then
--- local a = has_attribute(pointer,mathpunctuation)
+-- local a = pointer[mathpunctuation]
-- if a and a > 0 then
--- set_attribute(pointer,mathpunctuation,0)
+-- pointer[mathpunctuation] = 0
-- local current_nucleus = pointer.nucleus
-- if current_nucleus.id == math_char then
-- local current_char = current_nucleus.char
@@ -433,7 +575,7 @@ end
-- local current_nucleus = pointer.nucleus
-- if current_nucleus.id == math_char then
-- local current_char = current_nucleus.char
--- local a = has_attribute(pointer,mathpunctuation)
+-- local a = pointer[mathpunctuation]
-- if not a or a == 0 then
-- if current_char == comma then
-- -- default tex: 2,5 or 2, 5 --> 2, 5
@@ -506,6 +648,8 @@ mathpairs[0x2033] = { [0x2032] = 0x2034 } -- (doubleprime,pri
mathpairs[0x222B] = { [0x222B] = 0x222C, [0x222C] = 0x222D }
mathpairs[0x222C] = { [0x222B] = 0x222D }
+mathpairs[0x007C] = { [0x007C] = 0x2016 } -- double bars
+
local validpair = {
[noad_rel] = true,
[noad_ord] = true,
@@ -729,9 +873,9 @@ function mathematics.setalternate(fam,tag)
end
alternate[math_char] = function(pointer)
- local a = has_attribute(pointer,a_mathalternate)
+ local a = pointer[a_mathalternate]
if a and a > 0 then
- set_attribute(pointer,a_mathalternate,0)
+ pointer[a_mathalternate] = 0
local tfmdata = fontdata[font_of_family(pointer.fam)] -- we can also have a famdata
local mathalternatesattributes = tfmdata.shared.mathalternatesattributes
if mathalternatesattributes then
@@ -753,89 +897,6 @@ function handlers.check(head,style,penalties)
return true
end
--- experiment (when not present fall back to fam 0) -- needs documentation
-
--- 0-2 regular
--- 3-5 bold
--- 6-8 pseudobold
-
-local families = { }
-local a_mathfamily = attributes.private("mathfamily")
-local boldmap = mathematics.boldmap
-
-local tracemap = { [0] =
- "regular",
- "regular",
- "regular",
- "bold",
- "bold",
- "bold",
- "pseudobold",
- "pseudobold",
- "pseudobold",
-}
-
-families[math_char] = function(pointer)
- if pointer.fam == 0 then
- local a = has_attribute(pointer,a_mathfamily)
- if a and a > 0 then
- set_attribute(pointer,a_mathfamily,0)
- if a > 5 then
- local char = pointer.char
- local bold = boldmap[char]
- local newa = a - 3
- if bold then
- set_attribute(pointer,exportstatus,char)
- pointer.char = bold
- if trace_families then
- report_families("replacing U+%05X by bold U+%05X, family %s (%s) becomes %s (%s)",
- char,bold,a,tracemap[a],newa,tracemap[newa])
- end
- else
- if trace_families then
- report_families("no bold replacement for U+%05X, family %s (%s) becomes %s (%s)",
- char,a,tracemap[a],newa,tracemap[newa])
- end
- end
- pointer.fam = newa
- else
- if trace_families then
- report_families("family of U+%05X becomes %s (%s)",
- pointer.char,a,tracemap[a])
- end
- pointer.fam = a
- end
- else
- -- pointer.fam = 0
- end
- end
-end
-
-families[math_delim] = function(pointer)
- if pointer.small_fam == 0 then
- local a = has_attribute(pointer,a_mathfamily)
- if a and a > 0 then
- set_attribute(pointer,a_mathfamily,0)
- if a > 5 then
- -- no bold delimiters in unicode
- a = a - 3
- end
- pointer.small_fam = a
- pointer.large_fam = a
- else
- pointer.small_fam = 0
- pointer.large_fam = 0
- end
- end
-end
-
-families[math_textchar] = families[math_char]
-
-function handlers.families(head,style,penalties)
- processnoads(head,families,"families")
- return true
-end
-
-- italics: we assume that only characters matter
--
-- = we check for correction first because accessing nodes is slower
@@ -943,7 +1004,7 @@ trackers.register("math.italics", function(v)
end)
italics[math_char] = function(pointer,what,n,parent)
- local method = has_attribute(pointer,a_mathitalics)
+ local method = pointer[a_mathitalics]
if method and method > 0 then
local char = pointer.char
local font = font_of_family(pointer.fam) -- todo: table
@@ -1103,7 +1164,7 @@ variants[math_char] = function(pointer,what,n,parent) -- also set export value
end
if variant then
pointer.char = variant
- set_attribute(pointer,exportstatus,char) -- we don't export the variant as it's visual markup
+ pointer[a_exportstatus] = char -- we don't export the variant as it's visual markup
if trace_variants then
report_variants("variant (U+%05X,U+%05X) replaced by U+%05X",char,selector,variant)
end
diff --git a/tex/context/base/math-tag.lua b/tex/context/base/math-tag.lua
index c504b610a..6e634fd30 100644
--- a/tex/context/base/math-tag.lua
+++ b/tex/context/base/math-tag.lua
@@ -11,8 +11,6 @@ local insert, remove = table.insert, table.remove
local attributes, nodes = attributes, nodes
-local get_attribute = nodes.getattribute
-local set_attribute = nodes.setattribute
local set_attributes = nodes.setattributes
local traverse_nodes = node.traverse
@@ -64,19 +62,19 @@ local function processsubsup(start)
local nucleus, sup, sub = start.nucleus, start.sup, start.sub
if sub then
if sup then
- set_attribute(start,a_tagged,start_tagged("msubsup"))
+ start[a_tagged] = start_tagged("msubsup")
process(nucleus)
process(sub)
process(sup)
stop_tagged()
else
- set_attribute(start,a_tagged,start_tagged("msub"))
+ start[a_tagged] = start_tagged("msub")
process(nucleus)
process(sub)
stop_tagged()
end
elseif sup then
- set_attribute(start,a_tagged,start_tagged("msup"))
+ start[a_tagged] = start_tagged("msup")
process(nucleus)
process(sup)
stop_tagged()
@@ -97,7 +95,7 @@ process = function(start) -- we cannot use the processor as we have no finalizer
if id == math_char_code then
local char = start.char
-- check for code
- local a = get_attribute(start,a_mathcategory)
+ local a = start[a_mathcategory]
if a then
a = { detail = a }
end
@@ -120,22 +118,22 @@ process = function(start) -- we cannot use the processor as we have no finalizer
tag = "mo"
end
-- print(start,a,tag)
- set_attribute(start,a_tagged,start_tagged(tag,a))
+ start[a_tagged] = start_tagged(tag,a)
stop_tagged()
break -- okay?
elseif id == math_textchar_code then
-- check for code
- local a = get_attribute(start,a_mathcategory)
+ local a = start[a_mathcategory]
if a then
- set_attribute(start,a_tagged,start_tagged("ms",{ detail = a }))
+ start[a_tagged] = start_tagged("ms",{ detail = a })
else
- set_attribute(start,a_tagged,start_tagged("ms"))
+ start[a_tagged] = start_tagged("ms")
end
stop_tagged()
break
elseif id == math_delim_code then
-- check for code
- set_attribute(start,a_tagged,start_tagged("mo"))
+ start[a_tagged] = start_tagged("mo")
stop_tagged()
break
elseif id == math_style_code then
@@ -144,13 +142,13 @@ 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 = get_attribute(start,a_tagged)
+ local attr = start[a_tagged]
local last = attr and taglist[attr]
if last and find(last[#last],"formulacaption[:%-]") then
-- leave alone, will nicely move to the outer level
else
local text = start_tagged("mtext")
- set_attribute(start,a_tagged,text)
+ start[a_tagged] = text
local list = start.list
if not list then
-- empty list
@@ -168,7 +166,7 @@ process = function(start) -- we cannot use the processor as we have no finalizer
local cache = { } -- we can have nested unboxed mess so best local to runner
for n in traverse_nodes(list) do
local id = n.id
- local aa = get_attribute(n,a_tagged)
+ local aa = n[a_tagged]
if aa then
local ac = cache[aa]
if not ac then
@@ -186,9 +184,9 @@ process = function(start) -- we cannot use the processor as we have no finalizer
end
cache[aa] = ac
end
- set_attribute(n,a_tagged,ac)
+ n[a_tagged] = ac
else
- set_attribute(n,a_tagged,text)
+ n[a_tagged] = text
end
if id == hlist_code or id == vlist_code then
runner(n.list)
@@ -202,23 +200,23 @@ process = function(start) -- we cannot use the processor as we have no finalizer
elseif id == math_sub_code then
local list = start.list
if list then
- local attr = get_attribute(start,a_tagged)
+ local attr = start[a_tagged]
local last = attr and taglist[attr]
local action = last and match(last[#last],"maction:(.-)%-")
if action and action ~= "" then
if actionstack[#actionstack] == action then
- set_attribute(start,a_tagged,start_tagged("mrow"))
+ start[a_tagged] = start_tagged("mrow")
process(list)
stop_tagged()
else
insert(actionstack,action)
- set_attribute(start,a_tagged,start_tagged("mrow",{ detail = action }))
+ start[a_tagged] = start_tagged("mrow",{ detail = action })
process(list)
stop_tagged()
remove(actionstack)
end
else
- set_attribute(start,a_tagged,start_tagged("mrow"))
+ start[a_tagged] = start_tagged("mrow")
process(list)
stop_tagged()
end
@@ -226,16 +224,16 @@ process = function(start) -- we cannot use the processor as we have no finalizer
elseif id == math_fraction_code then
local num, denom, left, right = start.num, start.denom, start.left, start.right
if left then
- set_attribute(left,a_tagged,start_tagged("mo"))
+ left[a_tagged] = start_tagged("mo")
process(left)
stop_tagged()
end
- set_attribute(start,a_tagged,start_tagged("mfrac"))
+ start[a_tagged] = start_tagged("mfrac")
process(num)
process(denom)
stop_tagged()
if right then
- set_attribute(right,a_tagged,start_tagged("mo"))
+ right[a_tagged] = start_tagged("mo")
process(right)
stop_tagged()
end
@@ -258,22 +256,22 @@ process = function(start) -- we cannot use the processor as we have no finalizer
local subtype = start.subtype
if subtype == 1 then
-- left
- set_attribute(start,a_tagged,start_tagged("mfenced"))
+ start[a_tagged] = start_tagged("mfenced")
if delim then
- set_attribute(start,a_tagged,start_tagged("mleft"))
+ start[a_tagged] = start_tagged("mleft")
process(delim)
stop_tagged()
end
elseif subtype == 2 then
-- middle
if delim then
- set_attribute(start,a_tagged,start_tagged("mmiddle"))
+ start[a_tagged] = start_tagged("mmiddle")
process(delim)
stop_tagged()
end
elseif subtype == 3 then
if delim then
- set_attribute(start,a_tagged,start_tagged("mright"))
+ start[a_tagged] = start_tagged("mright")
process(delim)
stop_tagged()
end
@@ -289,12 +287,12 @@ process = function(start) -- we cannot use the processor as we have no finalizer
stop_tagged()
end
if degree then -- not good enough, can be empty mlist
- set_attribute(start,a_tagged,start_tagged("mroot"))
+ start[a_tagged] = start_tagged("mroot")
processsubsup(start)
process(degree)
stop_tagged()
else
- set_attribute(start,a_tagged,start_tagged("msqrt"))
+ start[a_tagged] = start_tagged("msqrt")
processsubsup(start)
stop_tagged()
end
@@ -302,19 +300,19 @@ process = function(start) -- we cannot use the processor as we have no finalizer
local accent, bot_accent = start.accent, start.bot_accent
if bot_accent then
if accent then
- set_attribute(start,a_tagged,start_tagged("munderover",{ detail = "accent" }))
+ start[a_tagged] = start_tagged("munderover",{ detail = "accent" })
processsubsup(start)
process(bot_accent)
process(accent)
stop_tagged()
else
- set_attribute(start,a_tagged,start_tagged("munder",{ detail = "accent" }))
+ start[a_tagged] = start_tagged("munder",{ detail = "accent" })
processsubsup(start)
process(bot_accent)
stop_tagged()
end
elseif accent then
- set_attribute(start,a_tagged,start_tagged("mover",{ detail = "accent" }))
+ start[a_tagged] = start_tagged("mover",{ detail = "accent" })
processsubsup(start)
process(accent)
stop_tagged()
@@ -322,10 +320,10 @@ process = function(start) -- we cannot use the processor as we have no finalizer
processsubsup(start)
end
elseif id == glue_code then
- set_attribute(start,a_tagged,start_tagged("mspace"))
+ start[a_tagged] = start_tagged("mspace")
stop_tagged()
else
- set_attribute(start,a_tagged,start_tagged("merror", { detail = nodecodes[i] } ))
+ start[a_tagged] = start_tagged("merror", { detail = nodecodes[i] })
stop_tagged()
end
start = start.next
@@ -335,9 +333,9 @@ end
function noads.handlers.tags(head,style,penalties)
local v_math = start_tagged("math")
local v_mrow = start_tagged("mrow")
- local v_mode = get_attribute(head,a_mathmode)
- set_attribute(head,a_tagged,v_math)
- set_attribute(head,a_tagged,v_mrow)
+ local v_mode = head[a_mathmode]
+ head[a_tagged] = v_math
+ head[a_tagged] = v_mrow
tags.setattributehash(v_math,"mode",v_mode == 1 and "display" or "inline")
process(head)
stop_tagged()
diff --git a/tex/context/base/node-acc.lua b/tex/context/base/node-acc.lua
index d91bb921b..4380ec3a4 100644
--- a/tex/context/base/node-acc.lua
+++ b/tex/context/base/node-acc.lua
@@ -13,8 +13,6 @@ local tasks = nodes.tasks
local traverse_nodes = node.traverse
local traverse_id = node.traverse_id
-local has_attribute = node.has_attribute
-local set_attribute = node.set_attribute
local copy_node = node.copy
local free_nodelist = node.flush_list
@@ -46,17 +44,17 @@ local function injectspaces(head)
g.components = nil
g.subtype = 256
end
- local a = has_attribute(n,a_characters)
+ local a = n[a_characters]
local s = copy_node(n.spec)
g.char, n.spec = 32, s
p.next, g.prev = g, p
g.next, n.prev = n, g
s.width = s.width - g.width
if a then
- set_attribute(g,a_characters,a)
+ g[a_characters] = a
end
- set_attribute(s,a_characters,0)
- set_attribute(n,a_characters,0)
+ s[a_characters] = 0
+ n[a_characters] = 0
end
--~ end
elseif id == hlist_code or id == vlist_code then
@@ -110,7 +108,7 @@ nodes.handlers.accessibility = injectspaces
--~ hyphenated[str] = hsh
--~ codes[hsh] = str
--~ end
---~ set_attribute(n,a_hyphenated,hsh)
+--~ n[a_hyphenated] = hsh
--~ end
--~ elseif id == hlist_code or id == vlist_code then
--~ injectspans(n.list)
@@ -127,7 +125,7 @@ nodes.handlers.accessibility = injectspaces
--~ for n in traverse_nodes(head) do
--~ local id = n.id
--~ if id == disc then
---~ local a = has_attribute(n,a_hyphenated)
+--~ local a = n[a_hyphenated]
--~ if a then
--~ local str = codes[a]
--~ local b = new_pdfliteral(format("/Span << /ActualText %s >> BDC", lpdf.tosixteen(str)))
diff --git a/tex/context/base/node-aux.lua b/tex/context/base/node-aux.lua
index ebfd3976d..d5a4d6f08 100644
--- a/tex/context/base/node-aux.lua
+++ b/tex/context/base/node-aux.lua
@@ -20,6 +20,7 @@ local glyph_code = nodecodes.glyph
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
local attributelist_code = nodecodes.attributelist -- temporary
+local math_code = nodecodes.math
local nodepool = nodes.pool
@@ -30,9 +31,6 @@ local traverse_nodes = node.traverse
local traverse_id = node.traverse_id
local free_node = node.free
local hpack_nodes = node.hpack
-local has_attribute = node.has_attribute
-local set_attribute = node.set_attribute
-local get_attribute = node.get_attribute
local unset_attribute = node.unset_attribute
local first_glyph = node.first_glyph or node.first_character
local copy_node = node.copy
@@ -41,6 +39,8 @@ local slide_nodes = node.slide
local insert_node_after = node.insert_after
local isnode = node.is_node
+local unsetvalue = attributes.unsetvalue
+
local current_font = font.current
local texbox = tex.box
@@ -58,7 +58,7 @@ end
local function set_attributes(head,attr,value)
for n in traverse_nodes(head) do
- set_attribute(n,attr,value)
+ n[attr] = value
local id = n.id
if id == hlist_node or id == vlist_node then
set_attributes(n.list,attr,value)
@@ -68,8 +68,8 @@ end
local function set_unset_attributes(head,attr,value)
for n in traverse_nodes(head) do
- if not has_attribute(n,attr) then
- set_attribute(n,attr,value)
+ if not n[attr] then
+ n[attr] = value
end
local id = n.id
if id == hlist_code or id == vlist_code then
@@ -80,7 +80,7 @@ end
local function unset_attributes(head,attr)
for n in traverse_nodes(head) do
- unset_attribute(n,attr)
+ n[attr] = unsetvalue
local id = n.id
if id == hlist_code or id == vlist_code then
unset_attributes(n.list,attr)
@@ -88,16 +88,16 @@ local function unset_attributes(head,attr)
end
end
+nodes.setattribute = node.set_attribute
+nodes.getattribute = node.has_attribute
+nodes.unsetattribute = node.unset_attribute
+nodes.has_attribute = node.has_attribute
+
nodes.firstglyph = first_glyph
-nodes.setattribute = set_attribute
-nodes.getattribute = has_attribute
-nodes.unsetattribute = unset_attribute
nodes.setattributes = set_attributes
nodes.setunsetattributes = set_unset_attributes
nodes.unsetattributes = unset_attributes
-nodes.has_attribute = has_attribute
-
-- function nodes.is_skipable(a,id) -- skipable nodes at the margins during character protrusion
-- return (
-- id ~= glyph_node
@@ -204,6 +204,13 @@ function nodes.firstcharinbox(n)
return 0
end
+function nodes.endofmath(n)
+ for n in traverse_id(math_code,n.next) do
+ return n
+ end
+end
+
+
-- local function firstline(n)
-- while n do
-- local id = n.id
diff --git a/tex/context/base/node-bck.lua b/tex/context/base/node-bck.lua
index 2630df2f4..feaa2c684 100644
--- a/tex/context/base/node-bck.lua
+++ b/tex/context/base/node-bck.lua
@@ -19,8 +19,6 @@ local vlist_code = nodecodes.vlist
local glyph_code = nodecodes.glyph
local cell_code = listcodes.cell
-local has_attribute = node.has_attribute
-local set_attribute = node.set_attribute
local traverse = node.traverse
local traverse_id = node.traverse_id
@@ -51,25 +49,25 @@ local function add_backgrounds(head) -- rather old code .. to be redone
end
local width = current.width
if width > 0 then
- local background = has_attribute(current,a_background)
+ local background = current[a_background]
if background then
-- direct to hbox
-- colorspace is already set so we can omit that and stick to color
- local mode = has_attribute(current,a_colorspace)
+ local mode = current[a_colorspace]
if mode then
local height = current.height
local depth = current.depth
local skip = id == hlist_code and width or (height + depth)
local glue = new_glue(-skip)
local rule = new_rule(width,height,depth)
- local color = has_attribute(current,a_color)
- local transparency = has_attribute(current,a_transparency)
- set_attribute(rule,a_colorspace,mode)
+ local color = current[a_color]
+ local transparency = current[a_transparency]
+ rule[a_colorspace] = mode
if color then
- set_attribute(rule,a_color,color)
+ rule[a_color] = color
end
if transparency then
- set_attribute(rule,a_transparency,transparency)
+ rule[a_transparency] = transparency
end
rule.next = glue
glue.prev = rule
@@ -99,7 +97,7 @@ local function add_alignbackgrounds(head)
local background = nil
local found = nil
-- for l in traverse(list) do
- -- background = has_attribute(l,a_alignbackground)
+ -- background = l[a_alignbackground]
-- if background then
-- found = l
-- break
@@ -108,7 +106,7 @@ local function add_alignbackgrounds(head)
-- we know that it's a fake hlist (could be user node)
-- but we cannot store tables in user nodes yet
for l in traverse_id(hpack_code,list) do
- background = has_attribute(l,a_alignbackground)
+ background = l[a_alignbackground]
if background then
found = l
end
@@ -119,18 +117,18 @@ local function add_alignbackgrounds(head)
-- current has subtype 5 (cell)
local width = current.width
if width > 0 then
- local mode = has_attribute(found,a_colorspace)
+ local mode = found[a_colorspace]
if mode then
local glue = new_glue(-width)
local rule = new_rule(width,current.height,current.depth)
- local color = has_attribute(found,a_color)
- local transparency = has_attribute(found,a_transparency)
- set_attribute(rule,a_colorspace, mode)
+ local color = found[a_color]
+ local transparency = found[a_transparency]
+ rule[a_colorspace] = mode
if color then
- set_attribute(rule,a_color, color)
+ rule[a_color] = color
end
if transparency then
- set_attribute(rule,a_transparency,transparency)
+ rule[a_transparency] = transparency
end
rule.next = glue
glue.prev = rule
diff --git a/tex/context/base/node-fin.lua b/tex/context/base/node-fin.lua
index 9bcfa0a7b..cad45c6a2 100644
--- a/tex/context/base/node-fin.lua
+++ b/tex/context/base/node-fin.lua
@@ -13,7 +13,6 @@ local next, type, format = next, type, string.format
local attributes, nodes, node = attributes, nodes, node
-local has_attribute = node.has_attribute
local copy_node = node.copy
local find_tail = node.slide
@@ -32,7 +31,7 @@ local pdfliteral_code = whatcodes.pdfliteral
local states = attributes.states
local numbers = attributes.numbers
-local trigger = attributes.private('trigger')
+local a_trigger = attributes.private('trigger')
local triggering = false
local starttiming = statistics.starttiming
@@ -188,7 +187,7 @@ function states.initialize(namespace,attribute,head)
nsforced = namespace.forced
nsselector = namespace.selector
nslistwise = namespace.listwise
- nstrigger = triggering and namespace.triggering and trigger
+ nstrigger = triggering and namespace.triggering and a_trigger
current = 0
current_selector = 0
done = false -- todo: done cleanup
@@ -226,7 +225,7 @@ end
-- while stack do
-- local id = stack.id
-- if id == glyph_code or (id == rule_code and stack.width ~= 0) or (id == glue_code and stack.leader) then -- or disc_code
--- local c = has_attribute(stack,attribute)
+-- local c = stack[attribute]
-- if c then
-- if default and c == inheritance then
-- if current ~= default then
@@ -253,8 +252,8 @@ end
-- current = 0
-- end
-- local ok = false
--- if nstrigger and has_attribute(stack,nstrigger) then
--- local outer = has_attribute(stack,attribute)
+-- if nstrigger and stack[nstrigger] then
+-- local outer = stack[attribute]
-- if outer ~= inheritance then
-- stack.leader, ok = process(namespace,attribute,content,inheritance,outer)
-- else
@@ -282,8 +281,8 @@ end
-- local content = stack.list
-- if content then
-- local ok = false
--- if nstrigger and has_attribute(stack,nstrigger) then
--- local outer = has_attribute(stack,attribute)
+-- if nstrigger and stack[nstrigger] then
+-- local outer = stack[attribute]
-- if outer ~= inheritance then
-- stack.list, ok = process(namespace,attribute,content,inheritance,outer)
-- else
@@ -304,7 +303,7 @@ local function process(namespace,attribute,head,inheritance,default) -- one attr
local stack, done = head, false
local function check()
- local c = has_attribute(stack,attribute)
+ local c = stack[attribute]
if c then
if default and c == inheritance then
if current ~= default then
@@ -332,8 +331,8 @@ local function process(namespace,attribute,head,inheritance,default) -- one attr
end
local function nested(content)
- if nstrigger and has_attribute(stack,nstrigger) then
- local outer = has_attribute(stack,attribute)
+ if nstrigger and stack[nstrigger] then
+ local outer = stack[attribute]
if outer ~= inheritance then
return process(namespace,attribute,content,inheritance,outer)
else
@@ -401,20 +400,20 @@ states.process = process
-- -- if id == glyph_code or (id == whatsit_code and stack.subtype == pdfliteral_code) or (id == rule_code and stack.width ~= 0) or (id == glue_code and stack.leader) then -- or disc_code
-- if id == glyph_code -- or id == disc_code
-- or (id == rule_code and stack.width ~= 0) or (id == glue_code and stack.leader) then -- or disc_code
--- local c = has_attribute(stack,attribute)
+-- local c = stack[attribute]
-- if c then
-- if default and c == inheritance then
-- if current ~= default then
-- local data = nsdata[default]
--- head = insert_node_before(head,stack,copy_node(data[nsforced or has_attribute(stack,nsselector) or nsselector]))
+-- head = insert_node_before(head,stack,copy_node(data[nsforced or stack[nsselector] or nsselector]))
-- current = default
-- done = true
-- end
-- else
--- local s = has_attribute(stack,nsselector)
+-- local s = stack[nsselector]
-- if current ~= c or current_selector ~= s then
-- local data = nsdata[c]
--- head = insert_node_before(head,stack,copy_node(data[nsforced or has_attribute(stack,nsselector) or nsselector]))
+-- head = insert_node_before(head,stack,copy_node(data[nsforced or stack[nsselector] or nsselector]))
-- current = c
-- current_selector = s
-- done = true
@@ -423,7 +422,7 @@ states.process = process
-- elseif default and inheritance then
-- if current ~= default then
-- local data = nsdata[default]
--- head = insert_node_before(head,stack,copy_node(data[nsforced or has_attribute(stack,nsselector) or nsselector]))
+-- head = insert_node_before(head,stack,copy_node(data[nsforced or stack[nsselector] or nsselector]))
-- current = default
-- done = true
-- end
@@ -444,8 +443,8 @@ states.process = process
-- current = 0
-- end
-- local ok = false
--- if nstrigger and has_attribute(stack,nstrigger) then
--- local outer = has_attribute(stack,attribute)
+-- if nstrigger and stack[nstrigger] then
+-- local outer = stack[attribute]
-- if outer ~= inheritance then
-- stack.leader, ok = selective(namespace,attribute,content,inheritance,outer)
-- else
@@ -462,8 +461,8 @@ states.process = process
-- local content = stack.list
-- if content then
-- local ok = false
--- if nstrigger and has_attribute(stack,nstrigger) then
--- local outer = has_attribute(stack,attribute)
+-- if nstrigger and stack[nstrigger] then
+-- local outer = stack[attribute]
-- if outer ~= inheritance then
-- stack.list, ok = selective(namespace,attribute,content,inheritance,outer)
-- else
@@ -484,20 +483,20 @@ local function selective(namespace,attribute,head,inheritance,default) -- two at
local stack, done = head, false
local function check()
- local c = has_attribute(stack,attribute)
+ local c = stack[attribute]
if c then
if default and c == inheritance then
if current ~= default then
local data = nsdata[default]
- head = insert_node_before(head,stack,copy_node(data[nsforced or has_attribute(stack,nsselector) or nsselector]))
+ head = insert_node_before(head,stack,copy_node(data[nsforced or stack[nsselector] or nsselector]))
current = default
done = true
end
else
- local s = has_attribute(stack,nsselector)
+ local s = stack[nsselector]
if current ~= c or current_selector ~= s then
local data = nsdata[c]
- head = insert_node_before(head,stack,copy_node(data[nsforced or has_attribute(stack,nsselector) or nsselector]))
+ head = insert_node_before(head,stack,copy_node(data[nsforced or stack[nsselector] or nsselector]))
current = c
current_selector = s
done = true
@@ -506,7 +505,7 @@ local function selective(namespace,attribute,head,inheritance,default) -- two at
elseif default and inheritance then
if current ~= default then
local data = nsdata[default]
- head = insert_node_before(head,stack,copy_node(data[nsforced or has_attribute(stack,nsselector) or nsselector]))
+ head = insert_node_before(head,stack,copy_node(data[nsforced or stack[nsselector] or nsselector]))
current = default
done = true
end
@@ -518,8 +517,8 @@ local function selective(namespace,attribute,head,inheritance,default) -- two at
end
local function nested(content)
- if nstrigger and has_attribute(stack,nstrigger) then
- local outer = has_attribute(stack,attribute)
+ if nstrigger and stack[nstrigger] then
+ local outer = stack[attribute]
if outer ~= inheritance then
return selective(namespace,attribute,content,inheritance,outer)
else
@@ -595,7 +594,7 @@ local function stacked(namespace,attribute,head,default) -- no triggering, no in
local current, depth = default or 0, 0
local function check()
- local a = has_attribute(stack,attribute)
+ local a = stack[attribute]
if a then
if current ~= a then
head = insert_node_before(head,stack,copy_node(nsdata[a]))
@@ -628,7 +627,7 @@ local function stacked(namespace,attribute,head,default) -- no triggering, no in
if content then
-- the problem is that broken lines gets the attribute which can be a later one
if nslistwise then
- local a = has_attribute(stack,attribute)
+ local a = stack[attribute]
if a and current ~= a and nslistwise[a] then -- viewerlayer / needs checking, see below
local p = current
current, done = a, true
@@ -671,7 +670,7 @@ local function stacker(namespace,attribute,head,default) -- no triggering, no in
local attrib = default or unsetvalue
local function check()
- local a = has_attribute(current,attribute) or unsetvalue
+ local a = current[attribute] or unsetvalue
if a ~= attrib then
local n = nsstep(a)
if n then
@@ -700,7 +699,7 @@ local function stacker(namespace,attribute,head,default) -- no triggering, no in
if not content then
-- skip
elseif nslistwise then
- local a = has_attribute(current,attribute)
+ local a = current[attribute]
if a and attrib ~= a and nslistwise[a] then -- viewerlayer
done = true
head = insert_node_before(head,current,copy_node(nsdata[a]))
diff --git a/tex/context/base/node-fnt.lua b/tex/context/base/node-fnt.lua
index a97c98d83..530659eaa 100644
--- a/tex/context/base/node-fnt.lua
+++ b/tex/context/base/node-fnt.lua
@@ -24,7 +24,6 @@ local fontdata = fonthashes.identifiers
local otf = fonts.handlers.otf
local traverse_id = node.traverse_id
-local has_attribute = node.has_attribute
local starttiming = statistics.starttiming
local stoptiming = statistics.stoptiming
local nodecodes = nodes.nodecodes
@@ -85,9 +84,10 @@ function handlers.characters(head)
report_fonts()
local n = head
while n do
- if n.id == glyph_code then
+ local id = n.id
+ if id == glyph_code then
local font = n.font
- local attr = has_attribute(n,0) or 0
+ local attr = n[0] or 0
report_fonts("font %03i, dynamic %03i, glyph %s",font,attr,utf.char(n.char))
else
report_fonts("[%s]",nodecodes[n.id])
@@ -95,10 +95,11 @@ function handlers.characters(head)
n = n.next
end
end
+ -- todo: time a while and skip over or make a special traverse_id that skips over math
for n in traverse_id(glyph_code,head) do
-- if n.subtype<256 then -- all are 1
local font = n.font
- local attr = has_attribute(n,0) or 0 -- zero attribute is reserved for fonts in context
+ local attr = n[0] or 0 -- zero attribute is reserved for fonts in context
if font ~= prevfont or attr ~= prevattr then
if attr > 0 then
local used = attrfonts[font]
@@ -219,166 +220,5 @@ function handlers.characters(head)
return head, true
end
--- function handlers.characters(head)
--- -- either next or not, but definitely no already processed list
--- starttiming(nodes)
--- local usedfonts, attrfonts, done = { }, { }, false
--- local a, u, prevfont, prevattr = 0, 0, nil, nil
--- local ap = 0
--- if trace_fontrun then
--- run = run + 1
--- report_fonts()
--- report_fonts("checking node list, run %s",run)
--- report_fonts()
--- local n = head
--- while n do
--- if n.id == glyph_code then
--- local font = n.font
--- local attr = has_attribute(n,0) or 0
--- report_fonts("font %03i, dynamic %03i, glyph %s",font,attr,utf.char(n.char))
--- else
--- report_fonts("[%s]",nodecodes[n.id])
--- end
--- n = n.next
--- end
--- end
--- for n in traverse_id(glyph_code,head) do
--- -- if n.subtype<256 then
--- local font = n.font
--- local attr = n.attr
--- if attr ~= prevattr then
--- local an = has_attribute(n,0) or 0
--- if ap ~= an and an > 0 then
--- local used = attrfonts[font]
--- if not used then
--- used = { }
--- attrfonts[font] = used
--- end
--- if not used[an] then
--- local sd = setfontdynamics[font]
--- if sd then -- always true ?
--- local d = sd(font,an) -- can we cache this one?
--- if d then
--- used[an] = d
--- a = a + 1
--- else
--- -- can't happen ... otherwise best use nil/false distinction
--- end
--- end
--- end
--- elseif font ~= prevfont then
--- local used = usedfonts[font]
--- if not used then
--- local fp = fontprocesses[font]
--- if fp then
--- usedfonts[font] = fp
--- u = u + 1
--- else
--- -- can't happen ... otherwise best use nil/false distinction
--- end
--- end
--- end
--- prevfont = font
--- prevattr = attr
--- ap = an
--- elseif font ~= prevfont then
--- local used = usedfonts[font]
--- if not used then
--- local fp = fontprocesses[font]
--- if fp then
--- usedfonts[font] = fp
--- u = u + 1
--- else
--- -- can't happen ... otherwise best use nil/false distinction
--- end
--- end
--- prevfont = font
--- end
--- -- end
--- end
--- if trace_fontrun then
--- report_fonts()
--- report_fonts("statics : %s",(u > 0 and concat(keys(usedfonts)," ")) or "none")
--- report_fonts("dynamics: %s",(a > 0 and concat(keys(attrfonts)," ")) or "none")
--- report_fonts()
--- end
--- -- we could combine these and just make the attribute nil
--- if u == 1 then
--- local font, processors = next(usedfonts)
--- local n = #processors
--- if n > 0 then
--- local h, d = processors[1](head,font,0)
--- head = h or head
--- done = done or d
--- if n > 1 then
--- for i=2,n do
--- local h, d = processors[i](head,font,0)
--- head = h or head
--- done = done or d
--- end
--- end
--- end
--- elseif u > 0 then
--- for font, processors in next, usedfonts do
--- local n = #processors
--- local h, d = processors[1](head,font,0)
--- head = h or head
--- done = done or d
--- if n > 1 then
--- for i=2,n do
--- local h, d = processors[i](head,font,0)
--- head = h or head
--- done = done or d
--- end
--- end
--- end
--- end
--- if a == 1 then
--- local font, dynamics = next(attrfonts)
--- for attribute, processors in next, dynamics do -- attr can switch in between
--- local n = #processors
--- if n == 0 then
--- report_fonts("no processors associated with dynamic %s",attribute)
--- else
--- local h, d = processors[1](head,font,attribute)
--- head = h or head
--- done = done or d
--- if n > 1 then
--- for i=2,n do
--- local h, d = processors[i](head,font,attribute)
--- head = h or head
--- done = done or d
--- end
--- end
--- end
--- end
--- elseif a > 0 then
--- for font, dynamics in next, attrfonts do
--- for attribute, processors in next, dynamics do -- attr can switch in between
--- local n = #processors
--- if n == 0 then
--- report_fonts("no processors associated with dynamic %s",attribute)
--- else
--- local h, d = processors[1](head,font,attribute)
--- head = h or head
--- done = done or d
--- if n > 1 then
--- for i=2,n do
--- local h, d = processors[i](head,font,attribute)
--- head = h or head
--- done = done or d
--- end
--- end
--- end
--- end
--- end
--- end
--- stoptiming(nodes)
--- if trace_characters then
--- nodes.report(head,done)
--- end
--- return head, true
--- end
-
handlers.protectglyphs = node.protect_glyphs
handlers.unprotectglyphs = node.unprotect_glyphs
diff --git a/tex/context/base/node-inj.lua b/tex/context/base/node-inj.lua
index b03ded9f2..e96c6e5fe 100644
--- a/tex/context/base/node-inj.lua
+++ b/tex/context/base/node-inj.lua
@@ -12,6 +12,7 @@ if not modules then modules = { } end modules ['node-inj'] = {
-- that can be of help. Some optimizations can go away when we have faster machines.
local next = next
+local utfchar = utf.char
local trace_injections = false trackers.register("nodes.injections", function(v) trace_injections = v end)
@@ -31,20 +32,17 @@ local nodepool = nodes.pool
local newkern = nodepool.kern
local traverse_id = node.traverse_id
-local unset_attribute = node.unset_attribute
-local has_attribute = node.has_attribute
-local set_attribute = node.set_attribute
local insert_node_before = node.insert_before
local insert_node_after = node.insert_after
-local kernpair = attributes.private('kernpair')
-local ligacomp = attributes.private('ligacomp')
-local markbase = attributes.private('markbase')
-local markmark = attributes.private('markmark')
-local markdone = attributes.private('markdone')
-local cursbase = attributes.private('cursbase')
-local curscurs = attributes.private('curscurs')
-local cursdone = attributes.private('cursdone')
+local a_kernpair = attributes.private('kernpair')
+local a_ligacomp = attributes.private('ligacomp')
+local a_markbase = attributes.private('markbase')
+local a_markmark = attributes.private('markmark')
+local a_markdone = attributes.private('markdone')
+local a_cursbase = attributes.private('cursbase')
+local a_curscurs = attributes.private('curscurs')
+local a_cursdone = attributes.private('cursdone')
-- This injector has been tested by Idris Samawi Hamid (several arabic fonts as well as
-- the rather demanding Husayni font), Khaled Hosny (latin and arabic) and Kaj Eigner
@@ -70,8 +68,8 @@ function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmne
local dx, dy = factor*(exit[1]-entry[1]), factor*(exit[2]-entry[2])
local ws, wn = tfmstart.width, tfmnext.width
local bound = #cursives + 1
- set_attribute(start,cursbase,bound)
- set_attribute(nxt,curscurs,bound)
+ start[a_cursbase] = bound
+ nxt[a_curscurs] = bound
cursives[bound] = { rlmode, dx, dy, ws, wn }
return dx, dy, bound
end
@@ -80,14 +78,14 @@ function injections.setpair(current,factor,rlmode,r2lflag,spec,tfmchr)
local x, y, w, h = factor*spec[1], factor*spec[2], factor*spec[3], factor*spec[4]
-- dy = y - h
if x ~= 0 or w ~= 0 or y ~= 0 or h ~= 0 then
- local bound = has_attribute(current,kernpair)
+ local bound = current[a_kernpair]
if bound then
local kb = kerns[bound]
-- inefficient but singles have less, but weird anyway, needs checking
kb[2], kb[3], kb[4], kb[5] = (kb[2] or 0) + x, (kb[3] or 0) + y, (kb[4] or 0)+ w, (kb[5] or 0) + h
else
bound = #kerns + 1
- set_attribute(current,kernpair,bound)
+ current[a_kernpair] = bound
kerns[bound] = { rlmode, x, y, w, h, r2lflag, tfmchr.width }
end
return x, y, w, h, bound
@@ -99,7 +97,7 @@ function injections.setkern(current,factor,rlmode,x,tfmchr)
local dx = factor*x
if dx ~= 0 then
local bound = #kerns + 1
- set_attribute(current,kernpair,bound)
+ current[a_kernpair] = bound
kerns[bound] = { rlmode, dx }
return dx, bound
else
@@ -109,7 +107,7 @@ end
function injections.setmark(start,base,factor,rlmode,ba,ma,index) -- ba=baseanchor, ma=markanchor
local dx, dy = factor*(ba[1]-ma[1]), factor*(ba[2]-ma[2]) -- the index argument is no longer used but when this
- local bound = has_attribute(base,markbase) -- fails again we should pass it
+ local bound = base[a_markbase] -- fails again we should pass it
local index = 1
if bound then
local mb = marks[bound]
@@ -117,8 +115,8 @@ local index = 1
-- if not index then index = #mb + 1 end
index = #mb + 1
mb[index] = { dx, dy, rlmode }
- set_attribute(start,markmark,bound)
- set_attribute(start,markdone,index)
+ start[a_markmark] = bound
+ start[a_markdone] = index
return dx, dy, bound
else
report_injections("possible problem, U+%05X is base mark without data (id: %s)",base.char,bound)
@@ -127,9 +125,9 @@ index = #mb + 1
-- index = index or 1
index = index or 1
bound = #marks + 1
- set_attribute(base,markbase,bound)
- set_attribute(start,markmark,bound)
- set_attribute(start,markdone,index)
+ base[a_markbase] = bound
+ start[a_markmark] = bound
+ start[a_markdone] = index
marks[bound] = { [index] = { dx, dy, rlmode } }
return dx, dy, bound
end
@@ -142,13 +140,14 @@ local function trace(head)
report_injections("begin run")
for n in traverse_id(glyph_code,head) do
if n.subtype < 256 then
- local kp = has_attribute(n,kernpair)
- local mb = has_attribute(n,markbase)
- local mm = has_attribute(n,markmark)
- local md = has_attribute(n,markdone)
- local cb = has_attribute(n,cursbase)
- local cc = has_attribute(n,curscurs)
- report_injections("char U+%05X, font=%s",n.char,n.font)
+ local kp = n[a_kernpair]
+ local mb = n[a_markbase]
+ local mm = n[a_markmark]
+ local md = n[a_markdone]
+ local cb = n[a_cursbase]
+ local cc = n[a_curscurs]
+ local char = n.char
+ report_injections("char U+%05X, font %s, glyph %s",char,n.font,utfchar(char))
if kp then
local k = kerns[kp]
if k[3] then
@@ -213,7 +212,7 @@ function injections.handler(head,where,keep)
if tm then
mk[n] = tm[n.char]
end
- local k = has_attribute(n,kernpair)
+ local k = n[a_kernpair]
if k then
local kk = kerns[k]
if kk then
@@ -262,9 +261,9 @@ function injections.handler(head,where,keep)
for i=1,nofvalid do -- valid == glyphs
local n = valid[i]
if not mk[n] then
- local n_cursbase = has_attribute(n,cursbase)
+ local n_cursbase = n[a_cursbase]
if p_cursbase then
- local n_curscurs = has_attribute(n,curscurs)
+ local n_curscurs = n[a_curscurs]
if p_cursbase == n_curscurs then
local c = cursives[n_curscurs]
if c then
@@ -325,14 +324,14 @@ function injections.handler(head,where,keep)
if has_marks then
for i=1,nofvalid do
local p = valid[i]
- local p_markbase = has_attribute(p,markbase)
+ local p_markbase = p[a_markbase]
if p_markbase then
local mrks = marks[p_markbase]
local nofmarks = #mrks
for n in traverse_id(glyph_code,p.next) do
- local n_markmark = has_attribute(n,markmark)
+ local n_markmark = n[a_markmark]
if p_markbase == n_markmark then
- local index = has_attribute(n,markdone) or 1
+ local index = n[a_markdone] or 1
local d = mrks[index]
if d then
local rlmode = d[3]
@@ -435,7 +434,7 @@ function injections.handler(head,where,keep)
end
for n in traverse_id(glyph_code,head) do
if n.subtype < 256 then
- local k = has_attribute(n,kernpair)
+ local k = n[a_kernpair]
if k then
local kk = kerns[k]
if kk then
diff --git a/tex/context/base/node-mig.lua b/tex/context/base/node-mig.lua
index 1384f6024..14a9885ba 100644
--- a/tex/context/base/node-mig.lua
+++ b/tex/context/base/node-mig.lua
@@ -10,8 +10,6 @@ local format = string.format
local attributes, nodes, node = attributes, nodes, node
-local has_attribute = node.has_attribute
-local set_attribute = node.set_attribute
local remove_nodes = nodes.remove
local nodecodes = nodes.nodecodes
@@ -22,7 +20,7 @@ local vlist_code = nodecodes.vlist
local insert_code = nodecodes.ins
local mark_code = nodecodes.mark
-local migrated = attributes.private("migrated")
+local a_migrated = attributes.private("migrated")
local trace_migrations = false trackers.register("nodes.migrations", function(v) trace_migrations = v end)
@@ -77,8 +75,8 @@ function nodes.handlers.migrate(head,where)
local id = current.id
-- inserts_too is a temp hack, we should only do them when it concerns
-- newly placed (flushed) inserts
- if id == vlist_code or id == hlist_code or (inserts_too and id == insert_code) and not has_attribute(current,migrated) then
- set_attribute(current,migrated,1)
+ if id == vlist_code or id == hlist_code or (inserts_too and id == insert_code) and not current[a_migrated] then
+ current[a_migrated] = 1
t_sweeps = t_sweeps + 1
local h = current.list
local first, last, ni, nm
diff --git a/tex/context/base/node-ref.lua b/tex/context/base/node-ref.lua
index 7e7b3be3b..f39d29ae3 100644
--- a/tex/context/base/node-ref.lua
+++ b/tex/context/base/node-ref.lua
@@ -68,7 +68,6 @@ local nodepool = nodes.pool
local new_kern = nodepool.kern
-local has_attribute = node.has_attribute
local traverse = node.traverse
local find_node_tail = node.tail or node.slide
local tosequence = nodes.tosequence
@@ -212,7 +211,7 @@ end
-- txtdir = txtdir or "==="
-- while current do
-- local id = current.id
--- local r = has_attribute(current,attribute)
+-- local r = current[attribute]
-- if id == hlist_code or id == vlist_code then
-- -- somehow reference is true so the following fails (second one not done) in
-- -- test \goto{test}[page(2)] test \gotobox{test}[page(2)]
@@ -272,7 +271,7 @@ local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,tx
while current do
local id = current.id
if id == hlist_code or id == vlist_code then
- local r = has_attribute(current,attribute)
+ local r = current[attribute]
-- somehow reference is true so the following fails (second one not done) in
-- test \goto{test}[page(2)] test \gotobox{test}[page(2)]
-- so let's wait till this fails again
@@ -301,7 +300,7 @@ local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,tx
elseif id == glue_code and current.subtype == leftskip_code then -- any glue at the left?
--
else
- local r = has_attribute(current,attribute)
+ local r = current[attribute]
if not r then
-- just go on, can be kerns
elseif not reference then
@@ -333,7 +332,7 @@ end
-- local current = head
-- while current do
-- local id = current.id
--- local r = has_attribute(current,attribute)
+-- local r = current[attribute]
-- if id == hlist_code or id == vlist_code then
-- if r and not done[r] then
-- done[r] = true
@@ -365,7 +364,7 @@ local function inject_area(head,attribute,make,stack,done,parent,pardir,txtdir)
while current do
local id = current.id
if id == hlist_code or id == vlist_code then
- local r = has_attribute(current,attribute)
+ local r = current[attribute]
if r and not done[r] then
done[r] = true
inject_list(id,current,r,make,stack,pardir,txtdir)
@@ -382,7 +381,7 @@ local function inject_area(head,attribute,make,stack,done,parent,pardir,txtdir)
txtdir = current.dir
end
else
- local r = has_attribute(current,attribute)
+ local r = current[attribute]
if r and not done[r] then
done[r] = true
head, current = inject_range(head,current,current,r,make,stack,parent,pardir,txtdir)
@@ -439,9 +438,9 @@ local function colorize(width,height,depth,n,reference,what)
depth = height
end
local rule = new_rule(width,height,depth)
- set_attribute(rule,a_colormodel,1) -- gray color model
- set_attribute(rule,a_color,u_color)
- set_attribute(rule,a_transparency,u_transparency)
+ rule[a_colormodel] = 1 -- gray color model
+ rule[a_color] = u_color
+ rule[a_transparency] = u_transparency
if width < 0 then
local kern = new_kern(width)
rule.width = -width
diff --git a/tex/context/base/node-rul.lua b/tex/context/base/node-rul.lua
index 9dba642f2..c7b7b7be9 100644
--- a/tex/context/base/node-rul.lua
+++ b/tex/context/base/node-rul.lua
@@ -77,8 +77,6 @@ local insert_node_before = node.insert_before
local insert_node_after = node.insert_after
local striprange = nodes.striprange
local list_dimensions = node.dimensions
-local has_attribute = node.has_attribute
-local set_attribute = node.set_attribute
local hpack_nodes = node.hpack
@@ -142,7 +140,7 @@ local function processwords(attribute,data,flush,head,parent) -- we have hlistdi
while n do
local id = n.id
if id == glyph_code or id == rule_code then
- local aa = has_attribute(n,attribute)
+ local aa = n[attribute]
if aa then
if aa == a then
if not f then -- ?
@@ -195,7 +193,7 @@ local function processwords(attribute,data,flush,head,parent) -- we have hlistdi
elseif id == glue_code then
-- catch \underbar{a} \underbar{a} (subtype test is needed)
local subtype = n.subtype
- if continue and has_attribute(n,attribute) and
+ if continue and n[attribute] and
(subtype == userskip_code or subtype == spaceskip_code or subskip == xspaceskip_code) then
l = n
else
@@ -261,9 +259,9 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a
local method, offset, continue, dy, order, max = d.method, d.offset, d.continue, d.dy, d.order, d.max
local rulethickness, unit = d.rulethickness, d.unit
local ma, ca, ta = d.ma, d.ca, d.ta
- local colorspace = (ma > 0 and ma) or has_attribute(f,a_colorspace) or 1
- local color = (ca > 0 and ca) or has_attribute(f,a_color)
- local transparency = (ta > 0 and ta) or has_attribute(f,a_transparency)
+ local colorspace = (ma > 0 and ma) or f[a_colorspace] or 1
+ local color = (ca > 0 and ca) or f[a_color]
+ local transparency = (ta > 0 and ta) or f[a_transparency]
local foreground = order == variables.foreground
local e = dimenfactor(unit,fontdata[f.font]) -- what if no glyph node
@@ -296,18 +294,18 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a
local ht = (offset+(i-1)*dy)*e + rulethickness - m
local dp = -(offset+(i-1)*dy)*e + rulethickness + m
local r = new_rule(w,ht,dp)
- local v = has_attribute(f,a_viewerlayer)
+ local v = f[a_viewerlayer]
-- quick hack
if v then
- set_attribute(r,a_viewerlayer,v)
+ r[a_viewerlayer] = v
end
--
if color then
- set_attribute(r,a_colorspace,colorspace)
- set_attribute(r,a_color,color)
+ r[a_colorspace] = colorspace
+ r[a_color] = color
end
if transparency then
- set_attribute(r,a_transparency,transparency)
+ r[a_transparency] = transparency
end
local k = new_kern(-w)
if foreground then
diff --git a/tex/context/base/node-tra.lua b/tex/context/base/node-tra.lua
index 1d7a19896..3538b5e34 100644
--- a/tex/context/base/node-tra.lua
+++ b/tex/context/base/node-tra.lua
@@ -712,24 +712,21 @@ number.nopts = nopts
local colors = { }
tracers.colors = colors
-local get_attribute = node.has_attribute
-local set_attribute = node.set_attribute
-local unset_attribute = node.unset_attribute
+local unsetvalue = attributes.unsetvalue
local a_color = attributes.private('color')
local a_colormodel = attributes.private('colormodel')
-local a_state = attributes.private('state')
local m_color = attributes.list[a_color] or { }
function colors.set(n,c,s)
local mc = m_color[c]
if not mc then
- unset_attribute(n,a_color)
+ n[a_color] = unsetvalue
else
- if not get_attribute(n,a_colormodel) then
- set_attribute(n,a_colormodel,s or 1)
+ if not n[a_colormodel] then
+ n[a_colormodel] = s or 1
end
- set_attribute(n,a_color,mc)
+ n[a_color] = mc
end
return n
end
@@ -739,12 +736,12 @@ function colors.setlist(n,c,s)
while n do
local mc = m_color[c]
if not mc then
- unset_attribute(n,a_color)
+ n[a_color] = unsetvalue
else
- if not get_attribute(n,a_colormodel) then
- set_attribute(n,a_colormodel,s or 1)
+ if not n[a_colormodel] then
+ n[a_colormodel] = s or 1
end
- set_attribute(n,a_color,mc)
+ n[a_color] = mc
end
n = n.next
end
@@ -752,7 +749,7 @@ function colors.setlist(n,c,s)
end
function colors.reset(n)
- unset_attribute(n,a_color)
+ n[a_color] = unsetvalue
return n
end
@@ -767,9 +764,9 @@ local m_transparency = attributes.list[a_transparency] or { }
function transparencies.set(n,t)
local mt = m_transparency[t]
if not mt then
- unset_attribute(n,a_transparency)
+ n[a_transparency] = unsetvalue
else
- set_attribute(n,a_transparency,mt)
+ n[a_transparency] = mt
end
return n
end
@@ -779,9 +776,9 @@ function transparencies.setlist(n,c,s)
while n do
local mt = m_transparency[c]
if not mt then
- unset_attribute(n,a_transparency)
+ n[a_transparency] = unsetvalue
else
- set_attribute(n,a_transparency,mt)
+ n[a_transparency] = mt
end
n = n.next
end
@@ -789,7 +786,7 @@ function transparencies.setlist(n,c,s)
end
function transparencies.reset(n)
- unset_attribute(n,a_transparency)
+ n[a_transparency] = unsetvalue
return n
end
diff --git a/tex/context/base/page-lin.lua b/tex/context/base/page-lin.lua
index 4dec0deec..76afc6c35 100644
--- a/tex/context/base/page-lin.lua
+++ b/tex/context/base/page-lin.lua
@@ -49,7 +49,6 @@ local current_list = { }
local cross_references = { }
local chunksize = 250 -- not used in boxed
-local has_attribute = node.has_attribute
local traverse_id = node.traverse_id
local traverse = node.traverse
local copy_node = node.copy
@@ -70,7 +69,7 @@ local function resolve(n,m) -- we can now check the 'line' flag (todo)
while n do
local id = n.id
if id == whatsit_code then -- why whatsit
- local a = has_attribute(n,a_linereference)
+ local a = n[a_linereference]
if a then
cross_references[a] = m
end
@@ -190,7 +189,7 @@ end
local function identify(list)
if list then
for n in traverse_id(hlist_code,list) do
- if has_attribute(n,a_linenumber) then
+ if n[a_linenumber] then
return list
end
end
@@ -230,7 +229,7 @@ function boxed.stage_one(n,nested)
-- skip funny hlists -- todo: check line subtype
else
local list = n.list
- local a = has_attribute(list,a_linenumber)
+ local a = list[a_linenumber]
if a and a > 0 then
if last_a ~= a then
local da = data[a]
@@ -245,12 +244,12 @@ function boxed.stage_one(n,nested)
report_lines("starting line number range %s: start %s, continue",a,da.start,da.continue or "no")
end
end
- if has_attribute(n,a_displaymath) then
+ if n[a_displaymath] then
if nodes.is_display_math(n) then
check_number(n,a,skip)
end
else
- local v = has_attribute(list,a_verbatimline)
+ local v = list[a_verbatimline]
if not v or v ~= last_v then
last_v = v
check_number(n,a,skip)
diff --git a/tex/context/base/scrn-hlp.lua b/tex/context/base/scrn-hlp.lua
index 81d68840b..5f8368c6d 100644
--- a/tex/context/base/scrn-hlp.lua
+++ b/tex/context/base/scrn-hlp.lua
@@ -13,7 +13,6 @@ interactions.help = help
local a_help = attributes.private("help")
-local has_attribute = node.has_attribute
local copy_nodelist = node.copy_list
local hpack_nodelist = node.hpack
@@ -62,7 +61,7 @@ local function collect(head,used)
while head do
local id = head.id
if id == hlist_code then
- local a = has_attribute(head,a_help)
+ local a = head[a_help]
if a then
if not used then
used = { a }
diff --git a/tex/context/base/scrp-cjk.lua b/tex/context/base/scrp-cjk.lua
index ab09ce9c8..c44f42e9c 100644
--- a/tex/context/base/scrp-cjk.lua
+++ b/tex/context/base/scrp-cjk.lua
@@ -11,7 +11,6 @@ if not modules then modules = { } end modules ['scrp-cjk'] = {
local utfchar = utf.char
-local has_attribute = node.has_attribute
local insert_node_after = node.insert_after
local insert_node_before = node.insert_before
local remove_node = nodes.remove
@@ -411,7 +410,7 @@ local function process(head,first,last)
while true do
local upcoming, id = first.next, first.id
if id == glyph_code then
- local a = has_attribute(first,a_prestat)
+ local a = first[a_prestat]
local current = numbertocategory[a]
local action = injectors[previous]
if action then
@@ -420,7 +419,7 @@ local function process(head,first,last)
local font = first.font
if font ~= lastfont then
lastfont = font
- set_parameters(font,numbertodataset[has_attribute(first,a_preproc)])
+ set_parameters(font,numbertodataset[first[a_preproc]])
end
action(head,first)
end
@@ -431,7 +430,7 @@ local function process(head,first,last)
if p and n then
local pid, nid = p.id, n.id
if pid == glyph_code and nid == glyph_code then
- local pa, na = has_attribute(p,a_prestat), has_attribute(n,a_prestat)
+ local pa, na = p[a_prestat], n[a_prestat]
local pcjk, ncjk = pa and numbertocategory[pa], na and numbertocategory[na]
if not pcjk or not ncjk
or pcjk == "korean" or ncjk == "korean"
@@ -632,7 +631,7 @@ local function process(head,first,last)
while true do
local upcoming, id = first.next, first.id
if id == glyph_code then
- local a = has_attribute(first,a_prestat)
+ local a = first[a_prestat]
local current = numbertocategory[a]
local action = injectors[previous]
if action then
@@ -641,7 +640,7 @@ local function process(head,first,last)
local font = first.font
if font ~= lastfont then
lastfont = font
- set_parameters(font,numbertodataset[has_attribute(first,a_preproc)])
+ set_parameters(font,numbertodataset[first[a_preproc]])
end
action(head,first)
end
@@ -652,7 +651,7 @@ local function process(head,first,last)
if p and n then
local pid, nid = p.id, n.id
if pid == glyph_code and nid == glyph_code then
- local pa, na = has_attribute(p,a_prestat), has_attribute(n,a_prestat)
+ local pa, na = p[a_prestat], n[a_prestat]
local pcjk, ncjk = pa and numbertocategory[pa], na and numbertocategory[na]
if not pcjk or not ncjk
or pcjk == "korean" or ncjk == "korean"
@@ -854,7 +853,7 @@ local function process(head,first,last)
while true do
local upcoming, id = first.next, first.id
if id == glyph_code then
- local a = has_attribute(first,a_prestat)
+ local a = first[a_prestat]
local current = numbertocategory[a]
local action = injectors[previous]
if action then
@@ -863,7 +862,7 @@ local function process(head,first,last)
local font = first.font
if font ~= lastfont then
lastfont = font
- set_parameters(font,numbertodataset[has_attribute(first,a_preproc)])
+ set_parameters(font,numbertodataset[first[a_preproc]])
end
action(head,first)
end
@@ -874,7 +873,7 @@ local function process(head,first,last)
if p and n then
local pid, nid = p.id, n.id
if pid == glyph_code and nid == glyph_code then
- local pa, na = has_attribute(p,a_prestat), has_attribute(n,a_prestat)
+ local pa, na = p[a_prestat], n[a_prestat]
local pcjk, ncjk = pa and numbertocategory[pa], na and numbertocategory[na]
if not pcjk or not ncjk
or pcjk == "korean" or ncjk == "korean"
diff --git a/tex/context/base/scrp-eth.lua b/tex/context/base/scrp-eth.lua
index 75fad2481..e1b8df432 100644
--- a/tex/context/base/scrp-eth.lua
+++ b/tex/context/base/scrp-eth.lua
@@ -9,7 +9,6 @@ if not modules then modules = { } end modules ['scrp-eth'] = {
-- at some point I will review the script code but for the moment we
-- do it this way; so space settings like with cjk yet
-local has_attribute = node.has_attribute
local insert_node_before = node.insert_before
local nodepool = nodes.pool
@@ -38,7 +37,7 @@ local inter_character_stretch_factor = 1
local inter_character_shrink_factor = 1
local function space_glue(current)
- local data = numbertodataset[has_attribute(current,a_preproc)]
+ local data = numbertodataset[current[a_preproc]]
if data then
inter_character_space_factor = data.inter_character_space_factor or 1
inter_character_stretch_factor = data.inter_character_stretch_factor or 1
@@ -107,7 +106,7 @@ local function process(head,first,last)
while current do
local id = current.id
if id == glyph_code then
- local prestat = has_attribute(current,a_prestat)
+ local prestat = current[a_prestat]
local category = numbertocategory[prestat]
if injector then
local action = injector[category]
diff --git a/tex/context/base/scrp-ini.lua b/tex/context/base/scrp-ini.lua
index 16d33d5d7..e75a32dd2 100644
--- a/tex/context/base/scrp-ini.lua
+++ b/tex/context/base/scrp-ini.lua
@@ -18,8 +18,6 @@ local report_preprocessing = logs.reporter("scripts","preprocessing")
local utfchar = utf.char
-local set_attribute = node.set_attribute
-local has_attribute = node.has_attribute
local first_glyph = node.first_glyph or node.first_character
local traverse_id = node.traverse_id
@@ -347,7 +345,7 @@ scripts.numbertocategory = numbertocategory
local function colorize(start,stop)
for n in traverse_id(glyph_code,start) do
- local kind = numbertocategory[has_attribute(n,a_prestat)]
+ local kind = numbertocategory[n[a_prestat]]
if kind then
local ac = scriptcolors[kind]
if ac then
@@ -388,7 +386,7 @@ function scripts.preprocess(head)
while start do
local id = start.id
if id == glyph_code then
- local a = has_attribute(start,a_preproc)
+ local a = start[a_preproc]
if a then
if a ~= last_a then
if first then
@@ -426,7 +424,7 @@ function scripts.preprocess(head)
end
local h = hash[c]
if h then
- set_attribute(start,a_prestat,categorytonumber[h])
+ start[a_prestat] = categorytonumber[h]
if not first then
first, last = start, start
else
@@ -535,13 +533,13 @@ setmetatableindex(cache_nop,function(t,k) local v = { } t[k] = v return v end)
function autofontfeature.handler(head)
for n in traverse_id(glyph_code,head) do
- -- if has_attribute(n,a_preproc) then
+ -- if n[a_preproc] then
-- -- already tagged by script feature, maybe some day adapt
-- else
local char = n.char
local script = otfscripts[char]
if script then
- local dynamic = has_attribute(n,0) or 0
+ local dynamic = n[0] or 0
local font = n.font
if dynamic > 0 then
local slot = cache_yes[font]
@@ -554,7 +552,7 @@ function autofontfeature.handler(head)
end
end
if attr ~= 0 then
- set_attribute(n,0,attr)
+ n[0] = attr
-- maybe set preproc when associated
end
else
@@ -568,7 +566,7 @@ function autofontfeature.handler(head)
end
end
if attr ~= 0 then
- set_attribute(n,0,attr)
+ n[0] = attr
-- maybe set preproc when associated
end
end
diff --git a/tex/context/base/spac-adj.lua b/tex/context/base/spac-adj.lua
index 4cba2f91e..c87a9d17f 100644
--- a/tex/context/base/spac-adj.lua
+++ b/tex/context/base/spac-adj.lua
@@ -8,17 +8,16 @@ if not modules then modules = { } end modules ['spac-adj'] = {
-- sort of obsolete code
-local attribute = attributes.private('graphicvadjust')
+local a_vadjust = attributes.private('graphicvadjust')
-local nodecodes = nodes.nodecodes
+local nodecodes = nodes.nodecodes
-local hlist_code = nodecodes.hlist
-local vlist_code = nodecodes.vlist
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
-local remove_node = nodes.remove
-local hpack_node = node.hpack
-local vpack_node = node.vpack
-local has_attribute = node.has_attribute
+local remove_node = nodes.remove
+local hpack_node = node.hpack
+local vpack_node = node.vpack
function nodes.handlers.graphicvadjust(head,groupcode) -- we can make an actionchain for mvl only
if groupcode == "" then -- mvl only
@@ -26,7 +25,7 @@ function nodes.handlers.graphicvadjust(head,groupcode) -- we can make an actionc
while h do
local id = h.id
if id == hlist_code or id == vlist_code then
- local a = has_attribute(h,attribute)
+ local a = h[a_vadjust]
if a then
if p then
local n
diff --git a/tex/context/base/spac-ali.lua b/tex/context/base/spac-ali.lua
index 998df3aa6..744b1d810 100644
--- a/tex/context/base/spac-ali.lua
+++ b/tex/context/base/spac-ali.lua
@@ -15,11 +15,11 @@ local prependaction = tasks.prependaction
local disableaction = tasks.disableaction
local enableaction = tasks.enableaction
-local has_attribute = node.has_attribute
-local unset_attribute = node.unset_attribute
local slide_nodes = node.slide
local hpack_nodes = node.hpack -- nodes.fasthpack not really faster here
+local unsetvalue = attributes.unsetvalue
+
local concat_nodes = nodes.concat
local nodecodes = nodes.nodecodes
@@ -61,7 +61,7 @@ local function handler(head,leftpage,realpageno)
local id = current.id
if id == hlist_code then
if current.subtype == line_code then
- local a = has_attribute(current,a_realign)
+ local a = current[a_realign]
if not a or a == 0 then
-- skip
else
@@ -92,7 +92,7 @@ local function handler(head,leftpage,realpageno)
done = true
nofrealigned = nofrealigned + 1
end
- unset_attribute(current,a_realign)
+ current[a_realign] = unsetvalue
end
end
handler(current.list,leftpage,realpageno)
diff --git a/tex/context/base/spac-chr.lua b/tex/context/base/spac-chr.lua
index 2db0b9a7b..8ab7c4b8a 100644
--- a/tex/context/base/spac-chr.lua
+++ b/tex/context/base/spac-chr.lua
@@ -20,8 +20,6 @@ report_characters = logs.reporter("typesetting","characters")
local nodes, node = nodes, node
-local set_attribute = node.set_attribute
-local has_attribute = node.has_attribute
local insert_node_after = node.insert_after
local remove_node = nodes.remove -- ! nodes
local copy_node_list = node.copy_list
@@ -65,8 +63,8 @@ local function inject_quad_space(unicode,head,current,fraction)
local glue = new_glue(fraction)
-- glue.attr = copy_node_list(attr)
glue.attr = attr
-current.attr = nil
- set_attribute(glue,a_character,unicode)
+ current.attr = nil
+ glue[a_character] = unicode
head, current = insert_node_after(head,current,glue)
return head, current
end
@@ -79,7 +77,7 @@ local function inject_char_space(unicode,head,current,parent)
-- glue.attr = copy_node_list(current.attr)
glue.attr = current.attr
current.attr = nil
- set_attribute(glue,a_character,unicode)
+ glue[a_character] = unicode
head, current = insert_node_after(head,current,glue)
return head, current
end
@@ -92,7 +90,7 @@ local function inject_nobreak_space(unicode,head,current,space,spacestretch,spac
glue.attr = attr
current.attr = nil
-- penalty.attr = attr
- set_attribute(glue,a_character,unicode)
+ glue[a_character] = unicode
head, current = insert_node_after(head,current,penalty)
head, current = insert_node_after(head,current,glue)
return head, current
@@ -105,7 +103,7 @@ local methods = {
[0x00A0] = function(head,current) -- nbsp
local para = fontparameters[current.font]
- if has_attribute(current,a_alignstate) == 1 then -- flushright
+ if current[a_alignstate] == 1 then -- flushright
head, current = inject_nobreak_space(0x00A0,head,current,para.space,0,0)
current.subtype = space_skip_code
else
diff --git a/tex/context/base/spac-ver.lua b/tex/context/base/spac-ver.lua
index 68554acb9..50aeb82c0 100644
--- a/tex/context/base/spac-ver.lua
+++ b/tex/context/base/spac-ver.lua
@@ -62,9 +62,6 @@ local a_skiporder = attributes.private('skiporder')
local a_snapmethod = attributes.private('snapmethod')
local a_snapvbox = attributes.private('snapvbox')
-local has_attribute = node.has_attribute
-local unset_attribute = node.unset_attribute
-local set_attribute = node.set_attribute
local find_node_tail = node.tail
local free_node = node.free
local free_node_list = node.flush_list
@@ -240,9 +237,9 @@ local function already_done(parentid,list,a_snapmethod) -- todo: done when only
--~ local i = 0
for n in traverse_nodes(list) do
local id = n.id
---~ i = i + 1 print(i,nodecodes[id],has_attribute(n,a_snapmethod))
+--~ i = i + 1 print(i,nodecodes[id],n[a_snapmethod])
if id == hlist_code or id == vlist_code then
- local a = has_attribute(n,a_snapmethod)
+ local a = n[a_snapmethod]
if not a then
-- return true -- not snapped at all
elseif a == 0 then
@@ -482,8 +479,8 @@ h, d = ch, cd
t[#t+1] = format("after offset: %s (width %s height %s depth %s)",
points(offset),points(current.width),points(current.height),points(current.depth))
end
- set_attribute(shifted,a_snapmethod,0)
- set_attribute(current,a_snapmethod,0)
+ shifted[a_snapmethod] = 0
+ current[a_snapmethod] = 0
end
if not height then
current.height = ch
@@ -802,7 +799,7 @@ function vspacing.snapbox(n,how)
local box = texbox[n]
local list = box.list
if list then
- local s = has_attribute(list,a_snapmethod)
+ local s = list[a_snapmethod]
if s == 0 then
if trace_vsnapping then
-- report_snapper("box list not snapped, already done")
@@ -822,8 +819,8 @@ function vspacing.snapbox(n,how)
report_snapper("box list snapped from (%s,%s) to (%s,%s) using method '%s' (%s) for '%s' (%s lines): %s",
h,d,ch,cd,sv.name,sv.specification,"direct",lines,listtoutf(list))
end
- set_attribute(box, a_snapmethod,0) --
- set_attribute(list,a_snapmethod,0) -- yes or no
+ box[a_snapmethod] = 0 --
+ list[a_snapmethod] = 0 -- yes or no
end
end
end
@@ -896,7 +893,7 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also
-- needs checking, why so many calls
if snap then
local list = current.list
- local s = has_attribute(current,a_snapmethod)
+ local s = current[a_snapmethod]
if not s then
-- if trace_vsnapping then
-- report_snapper("mvl list not snapped")
@@ -925,7 +922,7 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also
elseif trace_vsnapping then
report_snapper("mvl %s not snapped due to unknown snap specification: %s",nodecodes[id],listtoutf(list))
end
- set_attribute(current,a_snapmethod,0)
+ current[a_snapmethod] = 0
end
else
--
@@ -948,9 +945,9 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also
elseif id == glue_code then
local subtype = current.subtype
if subtype == userskip_code then
- local sc = has_attribute(current,a_skipcategory) -- has no default, no unset (yet)
- local so = has_attribute(current,a_skiporder ) or 1 -- has 1 default, no unset (yet)
- local sp = has_attribute(current,a_skippenalty ) -- has no default, no unset (yet)
+ local sc = current[a_skipcategory] -- has no default, no unset (yet)
+ local so = current[a_skiporder] or 1 -- has 1 default, no unset (yet)
+ local sp = current[a_skippenalty] -- has no default, no unset (yet)
if sp and sc == penalty then
if not penalty_data then
penalty_data = sp
@@ -1076,9 +1073,9 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also
end
elseif subtype == lineskip_code then
if snap then
- local s = has_attribute(current,a_snapmethod)
+ local s = current[a_snapmethod]
if s and s ~= 0 then
- set_attribute(current,a_snapmethod,0)
+ current[a_snapmethod] = 0
if current.spec.writable then
local spec = writable_spec(current)
spec.width = 0
@@ -1097,9 +1094,9 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also
current = current.next
elseif subtype == baselineskip_code then
if snap then
- local s = has_attribute(current,a_snapmethod)
+ local s = current[a_snapmethod]
if s and s ~= 0 then
- set_attribute(current,a_snapmethod,0)
+ current[a_snapmethod] = 0
if current.spec.writable then
local spec = writable_spec(current)
spec.width = 0
@@ -1136,9 +1133,9 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also
end
elseif subtype == topskip_code or subtype == splittopskip_code then
if snap then
- local s = has_attribute(current,a_snapmethod)
+ local s = current[a_snapmethod]
if s and s ~= 0 then
- set_attribute(current,a_snapmethod,0)
+ current[a_snapmethod] = 0
local sv = snapmethods[s]
local w, cw = snap_topskip(current,sv)
if trace_vsnapping then
@@ -1254,7 +1251,7 @@ function vspacing.pagehandler(newhead,where)
if id ~= glue_code then
flush = true
elseif n.subtype == userskip_code then
- if has_attribute(n,a_skipcategory) then
+ if n[a_skipcategory] then
stackhack = true
else
flush = true
diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf
index 414724f9e..3bd3b5a33 100644
--- a/tex/context/base/status-files.pdf
+++ b/tex/context/base/status-files.pdf
Binary files differ
diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf
index 4eeba1cd7..bd56f837b 100644
--- a/tex/context/base/status-lua.pdf
+++ b/tex/context/base/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/strc-mar.lua b/tex/context/base/strc-mar.lua
index c7ef2d4e1..1557c1956 100644
--- a/tex/context/base/strc-mar.lua
+++ b/tex/context/base/strc-mar.lua
@@ -22,7 +22,6 @@ local glyph_code = nodecodes.glyph
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
-local getattribute = nodes.getattribute
local traversenodes = node.traverse
local texsetattribute = tex.setattribute
local texbox = tex.box
@@ -103,7 +102,7 @@ local function sweep(head,first,last)
for n in traversenodes(head) do
local id = n.id
if id == glyph_code then
- local a = getattribute(n,a_marks)
+ local a = n[a_marks]
if not a then
-- next
elseif first == 0 then
@@ -112,7 +111,7 @@ local function sweep(head,first,last)
last = a
end
elseif id == hlist_code or id == vlist_code then
- local a = getattribute(n,a_marks)
+ local a = n[a_marks]
if not a then
-- next
elseif first == 0 then
diff --git a/tex/context/base/trac-jus.lua b/tex/context/base/trac-jus.lua
index 412ede90e..9d99f059d 100644
--- a/tex/context/base/trac-jus.lua
+++ b/tex/context/base/trac-jus.lua
@@ -25,8 +25,6 @@ local concat_nodes = nodes.concat
local hpack_nodes = node.hpack
local copy_node = node.copy
local get_list_dimensions = node.dimensions
-local set_attribute = node.set_attribute
-local has_attribute = node.has_attribute
local hlist_code = nodes.nodecodes.hlist
local tex_set_attribute = tex.setattribute
@@ -65,8 +63,8 @@ end)
function checkers.handler(head)
for current in node.traverse_id(hlist_code,head) do
- if has_attribute(current,a_justification,1) then
- set_attribute(current,a_justification,0)
+ if current[a_justification] == 1 then
+ current[a_justification] = 0
local width = current.width
if width > 0 then
local list = current.list
@@ -92,7 +90,7 @@ function checkers.handler(head)
current.list = concat_nodes { list, rule }
-- current.list = concat_nodes { list, new_kern(-naturalwidth+width), rule }
elseif delta <= min_threshold then
- local alignstate = has_attribute(list,a_alignstate)
+ local alignstate = list[a_alignstate]
if alignstate == 1 then
local rule = new_rule(-delta,naturalheight,naturaldepth)
setcolor(rule,"trace:dc")
diff --git a/tex/context/base/trac-vis.lua b/tex/context/base/trac-vis.lua
index e20171959..05b6c724c 100644
--- a/tex/context/base/trac-vis.lua
+++ b/tex/context/base/trac-vis.lua
@@ -8,7 +8,7 @@ if not modules then modules = { } end modules ['trac-vis'] = {
local string, number, table = string, number, table
local node, nodes, attributes, fonts, tex = node, nodes, attributes, fonts, tex
-
+local type = type
local format = string.format
-- This module started out in the early days of mkiv and luatex with
@@ -67,14 +67,13 @@ local copy_node = node.copy
local copy_list = node.copy_list
local free_node = node.free
local free_node_list = node.flush_list
-local has_attribute = node.has_attribute
-local set_attribute = node.set_attribute
-local unset_attribute = node.unset_attribute
local insert_node_before = node.insert_before
local insert_node_after = node.insert_after
local fast_hpack = nodes.fasthpack
+local traverse_nodes = node.traverse
local tex_attribute = tex.attribute
+local tex_box = tex.box
local unsetvalue = attributes.unsetvalue
local current_font = font.current
@@ -100,13 +99,6 @@ local setlisttransparency = tracers.transparencies.setlist
local starttiming = statistics.starttiming
local stoptiming = statistics.stoptiming
--- local function setlistattribute(list,a,v)
--- while list do
--- set_attribute(list,a,v)
--- list = list.next
--- end
--- end
-
local a_visual = attributes.private("visual")
local a_fontkern = attributes.private("fontkern")
local a_layer = attributes.private("viewerlayer")
@@ -296,7 +288,7 @@ local function sometext(str,layer,color)
setlisttransparency(info,c_zero)
info = fast_hpack(info)
if layer then
- set_attribute(info,a_layer,layer)
+ info[a_layer] = layer
end
local width = info.width
info.width = 0
@@ -331,7 +323,7 @@ local function fontkern(head,current)
text,
}
info = fast_hpack(info)
- set_attribute(info,a_layer,l_fontkern)
+ info[a_layer] = l_fontkern
info.width = 0
info.height = 0
info.depth = 0
@@ -382,7 +374,7 @@ local function whatsit(head,current)
else
local tag = whatsitcodes[what]
info = sometext(format("W:%s",tag and tags[tag] or what),usedfont)
- set_attribute(info,a_layer,l_whatsit)
+ info[a_layer] = l_whatsit
w_cache[what] = info
end
head, current = insert_node_after(head,current,copy_list(info))
@@ -396,7 +388,7 @@ local function user(head,current)
-- print("hit user")
else
info = sometext(format("U:%s",what),usedfont)
- set_attribute(info,a_layer,l_user)
+ info[a_layer] = l_user
w_cache[what] = info
end
head, current = insert_node_after(head,current,copy_list(info))
@@ -480,7 +472,7 @@ local function ruledbox(head,current,vertical,layer,what,simple)
info.width = 0
info.height = 0
info.depth = 0
- set_attribute(info,a_layer,layer)
+ info[a_layer] = layer
local info = concat_nodes {
current,
new_kern(-wd),
@@ -535,7 +527,7 @@ local function ruledglyph(head,current)
info.width = 0
info.height = 0
info.depth = 0
- set_attribute(info,a_layer,l_glyph)
+ info[a_layer] = l_glyph
local info = concat_nodes {
current,
new_kern(-wd),
@@ -695,7 +687,7 @@ local function visualize(head,vertical)
local attr = unsetvalue
while current do
local id = current.id
- local a = has_attribute(current,a_visual) or unsetvalue
+ local a = current[a_visual] or unsetvalue
if a ~= attr then
prev_trace_fontkern = trace_fontkern
if a == unsetvalue then
@@ -728,7 +720,7 @@ local function visualize(head,vertical)
attr = a
end
if trace_strut then
- set_attribute(current,a_layer,l_strut)
+ current[a_layer] = l_strut
elseif id == glyph_code then
if trace_glyph then
head, current = ruledglyph(head,current)
@@ -751,7 +743,7 @@ local function visualize(head,vertical)
elseif id == kern_code then
local subtype = current.subtype
-- tricky ... we don't copy the trace attribute in node-inj (yet)
- if subtype == font_kern_code or has_attribute(current,a_fontkern) then
+ if subtype == font_kern_code or current[a_fontkern] then
if trace_fontkern or prev_trace_fontkern then
head, current = fontkern(head,current)
end
@@ -848,7 +840,43 @@ function visualizers.handler(head)
end
function visualizers.box(n)
- tex.box[n].list = visualizers.handler(tex.box[n].list)
+ tex_box[n].list = visualizers.handler(tex_box[n].list)
+end
+
+local last = nil
+local used = nil
+
+local mark = {
+ "trace:1", "trace:2", "trace:3",
+ "trace:4", "trace:5", "trace:6",
+ "trace:7",
+}
+
+local function markfonts(list)
+ for n in traverse_nodes(list) do
+ local id = n.id
+ if id == glyph_code then
+ local font = n.font
+ local okay = used[font]
+ if not okay then
+ last = last + 1
+ okay = mark[last]
+ used[font] = okay
+ end
+ setcolor(n,okay)
+ elseif id == hlist_code or id == vlist_code then
+ markfonts(n.list)
+ end
+ end
+end
+
+function visualizers.markfonts(list)
+ last, used = 0, { }
+ markfonts(type(n) == "number" and tex_box[n].list or n)
+end
+
+function commands.markfonts(n)
+ visualizers.markfonts(n)
end
statistics.register("visualization time",function()
diff --git a/tex/context/base/typo-bld.lua b/tex/context/base/typo-bld.lua
index 87d280541..97893ad2b 100644
--- a/tex/context/base/typo-bld.lua
+++ b/tex/context/base/typo-bld.lua
@@ -30,7 +30,6 @@ constructors.attribute = a_parbuilder
local unsetvalue = attributes.unsetvalue
local texsetattribute = tex.setattribute
-local has_attribute = node.has_attribute
local texnest = tex.nest
local nodepool = nodes.pool
@@ -100,7 +99,7 @@ function constructors.handler(head,followed_by_display)
if type(head) == "boolean" then
return head
else
- local attribute = has_attribute(head,a_parbuilder) -- or mainconstructor
+ local attribute = head[a_parbuilder] -- or mainconstructor
if attribute then
local method = names[attribute]
if method then
diff --git a/tex/context/base/typo-brk.lua b/tex/context/base/typo-brk.lua
index 726518a85..d6326ebeb 100644
--- a/tex/context/base/typo-brk.lua
+++ b/tex/context/base/typo-brk.lua
@@ -20,9 +20,6 @@ local report_breakpoints = logs.reporter("typesetting","breakpoints")
local nodes, node = nodes, node
local settings_to_array = utilities.parsers.settings_to_array
-local has_attribute = node.has_attribute
-local unset_attribute = node.unset_attribute
-local set_attribute = node.set_attribute
local copy_node = node.copy
local copy_nodelist = node.copy_list
local free_node = node.free
@@ -164,9 +161,9 @@ local function process(namespace,attribute,head)
while start do
local id = start.id
if id == glyph_code then
- local attr = has_attribute(start,a_breakpoints)
+ local attr = start[a_breakpoints]
if attr and attr > 0 then
- unset_attribute(start,a_breakpoints) -- maybe test for subtype > 256 (faster)
+ start[a_breakpoints] = unsetvalue -- maybe test for subtype > 256 (faster)
-- look ahead and back n chars
local data = mapping[attr]
if data then
diff --git a/tex/context/base/typo-cap.lua b/tex/context/base/typo-cap.lua
index 3233a6ba2..0b9e52749 100644
--- a/tex/context/base/typo-cap.lua
+++ b/tex/context/base/typo-cap.lua
@@ -16,9 +16,6 @@ local report_casing = logs.reporter("typesetting","casing")
local nodes, node = nodes, node
-local has_attribute = node.has_attribute
-local unset_attribute = node.unset_attribute
-local set_attribute = node.set_attribute
local traverse_id = node.traverse_id
local copy_node = node.copy
@@ -171,8 +168,8 @@ local function Word(start,attribute,attr)
if not prev or prev.id ~= glyph_code then
--- only the first character is treated
for n in traverse_id(glyph_code,start.next) do
- if has_attribute(n,attribute) == attr then
- unset_attribute(n,attribute)
+ if n[attribute] == attr then
+ n[attribute] = unsetvalue
else
-- break -- we can have nested mess
end
@@ -264,13 +261,13 @@ local function process(namespace,attribute,head) -- not real fast but also not u
while start do -- while because start can jump ahead
local id = start.id
if id == glyph_code then
- local attr = has_attribute(start,attribute)
+ local attr = start[attribute]
if attr and attr > 0 then
if attr ~= lastattr then
lastfont = nil
lastattr = attr
end
- unset_attribute(start,attribute)
+ start[attribute] = unsetvalue
local action = actions[attr%100] -- map back to low number
if action then
start, ok = action(start,attribute,attr)
diff --git a/tex/context/base/typo-cln.lua b/tex/context/base/typo-cln.lua
index c6a270791..be00ac10d 100644
--- a/tex/context/base/typo-cln.lua
+++ b/tex/context/base/typo-cln.lua
@@ -28,9 +28,10 @@ local tasks = nodes.tasks
local texattribute = tex.attribute
-local has_attribute = node.has_attribute
local traverse_id = node.traverse_id
+local unsetvalue = attributes.unsetvalue
+
local glyph_code = nodecodes.glyph
local uccodes = characters.uccodes
@@ -52,7 +53,7 @@ local function process(namespace,attribute,head)
if resetter[char] then
inline = false
elseif not inline then
- local a = has_attribute(n,attribute)
+ local a = n[attribute]
if a == 1 then -- currently only one cleaner so no need to be fancy
local upper = uccodes[char]
if type(upper) == "table" then
diff --git a/tex/context/base/typo-dig.lua b/tex/context/base/typo-dig.lua
index a3a0feb3e..30d7d96ac 100644
--- a/tex/context/base/typo-dig.lua
+++ b/tex/context/base/typo-dig.lua
@@ -19,9 +19,6 @@ local report_digits = logs.reporter("typesetting","digits")
local nodes, node = nodes, node
-local has_attribute = node.has_attribute
-local unset_attribute = node.unset_attribute
-local set_attribute = node.set_attribute
local hpack_node = node.hpack
local traverse_id = node.traverse_id
local insert_node_before = node.insert_before
@@ -109,9 +106,9 @@ local function process(namespace,attribute,head)
local done, current, ok = false, head, false
while current do
if current.id == glyph_code then
- local attr = has_attribute(current,attribute)
+ local attr = current[attribute]
if attr and attr > 0 then
- unset_attribute(current,attribute)
+ current[attribute] = unsetvalue
local action = actions[attr%100] -- map back to low number
if action then
head, current, ok = action(head,current,attribute,attr)
diff --git a/tex/context/base/typo-dir.lua b/tex/context/base/typo-dir.lua
index da324b7e2..7f8975082 100644
--- a/tex/context/base/typo-dir.lua
+++ b/tex/context/base/typo-dir.lua
@@ -18,9 +18,6 @@ local trace_directions = false trackers.register("typesetters.directions", func
local report_directions = logs.reporter("typesetting","directions")
-local has_attribute = node.has_attribute
-local unset_attribute = node.unset_attribute
-local set_attribute = node.set_attribute
local traverse_id = node.traverse_id
local insert_node_before = node.insert_before
local insert_node_after = node.insert_after
@@ -168,6 +165,8 @@ end
-- todo: use new dir functions
+local s_isol = fonts.analyzers.states.isol
+
function directions.process(namespace,attribute,start) -- todo: make faster
if not start.next then
return start, false
@@ -193,9 +192,9 @@ function directions.process(namespace,attribute,start) -- todo: make faster
elseif inmath then
current = current.next
else
- local attr = has_attribute(current,attribute)
+ local attr = current[attribute]
if attr and attr > 0 then
- -- unset_attribute(current,attribute) -- slow, needed?
+ -- current[attribute] = unsetvalue -- slow, needed?
if attr == 1 then
-- bidi parsing mode
elseif attr ~= prevattr then
@@ -239,7 +238,7 @@ function directions.process(namespace,attribute,start) -- todo: make faster
end
elseif lro or override < 0 then
if d == "r" or d == "al" then
- set_attribute(current,a_state,4) -- maybe better have a special bidi attr value -> override (9) -> todo
+ current[a_state] = s_isol -- maybe better have a special bidi attr value -> override (9) -> todo
if trace_directions then
list[#list+1] = format("char %s (%s / U+%04X) of class %s overidden to l (bidi=%s) (state=isol)",utfchar(char),char,char,d,attr)
end
@@ -420,7 +419,7 @@ end
--~ if n then
--~ local id = n.id
--~ if id == glyph_code then
---~ local attr = has_attribute(n,attribute)
+--~ local attr = n[attribute]
--~ if attr and attr > 0 then
--~ local d = chardirs[n.char]
--~ if d == "r" or d == "al" then -- override
diff --git a/tex/context/base/typo-itc.lua b/tex/context/base/typo-itc.lua
index d294dd60a..57b4e38b8 100644
--- a/tex/context/base/typo-itc.lua
+++ b/tex/context/base/typo-itc.lua
@@ -25,7 +25,6 @@ local tasks = nodes.tasks
local insert_node_after = node.insert_after
local delete_node = nodes.delete
-local has_attribute = node.has_attribute
local texattribute = tex.attribute
local a_italics = attributes.private("italics")
@@ -121,7 +120,7 @@ local function process(namespace,attribute,head)
lastfont = font
end
if data then
- local attr = forcedvariant or has_attribute(current,attribute)
+ local attr = forcedvariant or current[attribute]
if attr and attr > 0 then
local cd = data[char]
if not cd then
diff --git a/tex/context/base/typo-krn.lua b/tex/context/base/typo-krn.lua
index cd2639c67..6dd3e6bd7 100644
--- a/tex/context/base/typo-krn.lua
+++ b/tex/context/base/typo-krn.lua
@@ -11,8 +11,6 @@ local utfchar = utf.char
local nodes, node, fonts = nodes, node, fonts
-local has_attribute = node.has_attribute
-local unset_attribute = node.unset_attribute
local find_node_tail = node.tail or node.slide
local free_node = node.free
local free_nodelist = node.flush_list
@@ -116,9 +114,9 @@ local function do_process(namespace,attribute,head,force) -- todo: glue so that
local fillup = false
while start do
-- faster to test for attr first
- local attr = force or has_attribute(start,attribute)
+ local attr = force or start[attribute]
if attr and attr > 0 then
- unset_attribute(start,attribute)
+ start[attribute] = unsetvalue
local krn = mapping[attr]
if krn == v_max then
krn = .25
@@ -166,7 +164,7 @@ local function do_process(namespace,attribute,head,force) -- todo: glue so that
if not pid then
-- nothing
elseif pid == kern_code then
- if prev.subtype == kerning_code or has_attribute(prev,a_fontkern) then
+ if prev.subtype == kerning_code or prev[a_fontkern] then
if keeptogether and prev.prev.id == glyph_code and keeptogether(prev.prev,start) then -- we could also pass start
-- keep 'm
else
diff --git a/tex/context/base/typo-mar.lua b/tex/context/base/typo-mar.lua
index db8508a4a..02f425298 100644
--- a/tex/context/base/typo-mar.lua
+++ b/tex/context/base/typo-mar.lua
@@ -115,9 +115,6 @@ local v_first = variables.first
local v_text = variables.text
local v_column = variables.column
-local has_attribute = node.has_attribute
-local set_attribute = node.set_attribute
-local unset_attribute = node.unset_attribute
local copy_node_list = node.copy_list
local slide_nodes = node.slide
local hpack_nodes = node.hpack -- nodes.fasthpack not really faster here
@@ -635,7 +632,7 @@ local function inject(parent,head,candidate)
box.next = head
head = box
end
- set_attribute(box,a_margindata,nofstatus)
+ box[a_margindata] = nofstatus
if trace_margindata then
report_margindata("injected, location: %s, shift: %s",location,shift)
end
@@ -722,10 +719,10 @@ local function flushed(scope,parent) -- current is hlist
done = done or don
end
if done then
- local a = has_attribute(head,a_linenumber) -- hack .. we need a more decent critical attribute inheritance mechanism
+ local a = head[a_linenumber] -- hack .. we need a more decent critical attribute inheritance mechanism
parent.list = hpack_nodes(head,parent.width,"exactly")
if a then
- set_attribute(parent.list,a_linenumber,a)
+ parent.list[a_linenumber] = a
end
-- resetstacked()
end
@@ -744,10 +741,10 @@ local function handler(scope,head,group)
local done = false
while current do
local id = current.id
- if (id == vlist_code or id == hlist_code) and not has_attribute(current,a_margindata) then
+ if (id == vlist_code or id == hlist_code) and not current[a_margindata] then
local don, continue = flushed(scope,current)
if don then
- set_attribute(current,a_margindata,0) -- signal to prevent duplicate processing
+ current[a_margindata] = 0 -- signal to prevent duplicate processing
if continue then
markovershoot(current)
end
@@ -817,7 +814,7 @@ local function finalhandler(head)
while current do
local id = current.id
if id == hlist_code then
- local a = has_attribute(current,a_margindata)
+ local a = current[a_margindata]
if not a or a == 0 then
finalhandler(current.list)
elseif realigned(current,a) then
diff --git a/tex/context/base/typo-pag.lua b/tex/context/base/typo-pag.lua
index 482a3a9f8..6488b7c6b 100644
--- a/tex/context/base/typo-pag.lua
+++ b/tex/context/base/typo-pag.lua
@@ -16,9 +16,8 @@ local penalty_code = nodecodes.penalty
local insert_node_after = node.insert_after
local new_penalty = nodes.pool.penalty
-local has_attribute = node.has_attribute
-local unset_attribute = node.unset_attribute
-local set_attribute = node.set_attribute
+
+local unsetvalue = attributes.unsetvalue
local points = number.points
@@ -40,7 +39,7 @@ function builders.paragraphs.registertogether(line,specification) -- might chang
if not enabled then
nodes.tasks.enableaction("finalizers","builders.paragraphs.keeptogether")
end
- local a = has_attribute(line,a_keeptogether)
+ local a = line[a_keeptogether]
local c = a and cache[a]
if c then
local height = specification.height
@@ -67,7 +66,7 @@ function builders.paragraphs.registertogether(line,specification) -- might chang
if not specification.slack then
specification.slack = 0
end
- set_attribute(line,a_keeptogether,last)
+ line[a_keeptogether] = last
end
if trace_keeptogether then
local a = a or last
@@ -169,10 +168,10 @@ function builders.paragraphs.keeptogether(head)
local current = head
while current do
if current.id == hlist_code then
- local a = has_attribute(current,a_keeptogether)
+ local a = current[a_keeptogether]
if a and a > 0 then
keeptogether(current,a)
- unset_attribute(current,a_keeptogether)
+ current[a_keeptogether] = unsetvalue
cache[a] = nil
done = true
end
diff --git a/tex/context/base/typo-par.lua b/tex/context/base/typo-par.lua
index 0261d2e4e..b25ae4a5b 100644
--- a/tex/context/base/typo-par.lua
+++ b/tex/context/base/typo-par.lua
@@ -29,9 +29,6 @@ local variables = interfaces.variables
local texattribute = tex.attribute
local unsetvalue = attributes.unsetvalue
-local has_attribute = node.has_attribute
-local set_attribute = node.set_attribute
-
local glyph_code = nodecodes.glyph
local hlist_code = nodecodes.hlist
local kern_node = nodecodes.kern
@@ -84,7 +81,7 @@ local function process(namespace,attribute,head)
local done = false
if head.id == whatsit_code and head.subtype == localpar_code then
-- begin of par
- local a = has_attribute(head,attribute)
+ local a = head[attribute]
if a and a > 0 then
if dropper.enabled then
dropper.enabled = false -- dangerous for e.g. nested || in tufte
@@ -112,11 +109,11 @@ local function process(namespace,attribute,head)
local ca = dropper.ca
local ta = dropper.ta
if ca and ca > 0 then
- set_attribute(first,a_colorspace,ma == 0 and 1 or ma)
- set_attribute(first,a_color,ca)
+ first[a_colorspace] = ma == 0 and 1 or ma
+ first[a_color] = ca
end
if ta and ta > 0 then
- set_attribute(first,a_transparency,ta)
+ first[a_transparency] = ta
end
--
local width = first.width
diff --git a/tex/context/base/typo-rep.lua b/tex/context/base/typo-rep.lua
index 0d9bf8cc1..6534bf457 100644
--- a/tex/context/base/typo-rep.lua
+++ b/tex/context/base/typo-rep.lua
@@ -20,7 +20,6 @@ local nodes, node = nodes, node
local delete_node = nodes.delete
local replace_node = nodes.replace
local copy_node = node.copy
-local has_attribute = node.has_attribute
local chardata = characters.data
local collected = false
@@ -79,7 +78,7 @@ function nodes.handlers.stripping(head)
while current do
if current.id == glyph_code then
-- it's more efficient to keep track of what needs to be kept
- local todo = has_attribute(current,a_stripping)
+ local todo = current[a_stripping]
if todo == 1 then
local char = current.char
local what = glyphs[char]
diff --git a/tex/context/base/typo-spa.lua b/tex/context/base/typo-spa.lua
index d40aed579..764ee0cfb 100644
--- a/tex/context/base/typo-spa.lua
+++ b/tex/context/base/typo-spa.lua
@@ -15,8 +15,6 @@ local report_spacing = logs.reporter("typesetting","spacing")
local nodes, fonts, node = nodes, fonts, node
-local has_attribute = node.has_attribute
-local unset_attribute = node.unset_attribute
local insert_node_before = node.insert_before
local insert_node_after = node.insert_after
local remove_node = nodes.remove
@@ -73,12 +71,12 @@ local function process(namespace,attribute,head)
-- penalty followed by glue
while start do
if start.id == glyph_code then
- local attr = has_attribute(start,attribute)
+ local attr = start[attribute]
if attr and attr > 0 then
local data = mapping[attr]
if data then
local map = data.characters[start.char]
- unset_attribute(start,attribute) -- needed?
+ start[attribute] = unsetvalue -- needed?
if map then
local left = map.left
local right = map.right
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index fe68795ec..9b7689ac1 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
-- merged file : luatex-fonts-merged.lua
-- parent file : luatex-fonts.lua
--- merge date : 03/04/13 18:28:23
+-- merge date : 03/05/13 16:40:59
do -- begin closure to overcome local limits and interference
@@ -2209,7 +2209,7 @@ local boolean=boolean
function boolean.tonumber(b)
if b then return 1 else return 0 end
end
-function toboolean(str,tolerant)
+function toboolean(str,tolerant)
if str==nil then
return false
elseif str==false then
@@ -2232,18 +2232,16 @@ function toboolean(str,tolerant)
end
string.toboolean=toboolean
function string.booleanstring(str)
- if str==nil then
- return false
- elseif str==false then
+ if str=="0" then
return false
- elseif str==true then
- return true
- elseif str=="true" then
+ elseif str=="1" then
return true
- elseif str=="false" then
+ elseif str=="" then
return false
- elseif str==0 then
+ elseif str=="false" then
return false
+ elseif str=="true" then
+ return true
elseif (tonumber(str) or 0)>0 then
return true
else