summaryrefslogtreecommitdiff
path: root/tex
diff options
context:
space:
mode:
Diffstat (limited to 'tex')
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/font-imp-dimensions.lua5
-rw-r--r--tex/context/base/mkiv/font-ots.lua564
-rw-r--r--tex/context/base/mkiv/font-ott.lua6
-rw-r--r--tex/context/base/mkiv/mult-low.lua2
-rw-r--r--tex/context/base/mkiv/mult-prm.lua1
-rw-r--r--tex/context/base/mkiv/spac-ver.lua21
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin25407 -> 26155 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin257519 -> 257718 bytes
-rw-r--r--tex/context/base/mkxl/cont-new.mkxl2
-rw-r--r--tex/context/base/mkxl/context.mkxl2
-rw-r--r--tex/context/base/mkxl/font-ots.lmt569
-rw-r--r--tex/context/base/mkxl/lang-ini.lmt572
-rw-r--r--tex/context/base/mkxl/lang-ini.mkxl16
-rw-r--r--tex/context/base/mkxl/lpdf-pde.lmt2
-rw-r--r--tex/context/base/mkxl/mlib-svg.lmt6
-rw-r--r--tex/context/base/mkxl/spac-ver.lmt21
-rw-r--r--tex/context/base/mkxl/syst-ini.mkxl4
-rw-r--r--tex/context/base/mkxl/toks-aux.lmt30
-rw-r--r--tex/context/modules/mkiv/s-languages-goodies.lmt67
-rw-r--r--tex/context/modules/mkiv/s-languages-goodies.mkxl21
-rw-r--r--tex/context/patterns/lmtx/lang-de.llg4
-rw-r--r--tex/context/patterns/lmtx/lang-en.llg453
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua516
27 files changed, 1884 insertions, 1008 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index 8abe3c057..a0151c54d 100644
--- a/tex/context/base/mkii/cont-new.mkii
+++ b/tex/context/base/mkii/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2021.03.31 18:00}
+\newcontextversion{2021.04.09 19:54}
%D This file is loaded at runtime, thereby providing an
%D excellent place for hacks, patches, extensions and new
diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii
index aa9e7e08f..5313df6e6 100644
--- a/tex/context/base/mkii/context.mkii
+++ b/tex/context/base/mkii/context.mkii
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2021.03.31 18:00}
+\edef\contextversion{2021.04.09 19:54}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 241e31a2e..e81cbb7d9 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -13,7 +13,7 @@
% \normalend % uncomment this to get the real base runtime
-\newcontextversion{2021.03.31 18:00}
+\newcontextversion{2021.04.09 19:54}
%D This file is loaded at runtime, thereby providing an excellent place for hacks,
%D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index f878dd195..5062c3a10 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -45,7 +45,7 @@
%D {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2021.03.31 18:00}
+\edef\contextversion{2021.04.09 19:54}
%D Kind of special:
diff --git a/tex/context/base/mkiv/font-imp-dimensions.lua b/tex/context/base/mkiv/font-imp-dimensions.lua
index 760ce3719..66e218e0f 100644
--- a/tex/context/base/mkiv/font-imp-dimensions.lua
+++ b/tex/context/base/mkiv/font-imp-dimensions.lua
@@ -42,6 +42,7 @@ local function initialize(tfmdata,key,value)
local newwidth = false
local newheight = false
local newdepth = false
+ local newshift = false
if value == "strut" then
newheight = gettexdimen("strutht")
newdepth = gettexdimen("strutdp")
@@ -55,6 +56,7 @@ local function initialize(tfmdata,key,value)
newwidth = spec[1]
newheight = spec[2]
newdepth = spec[3]
+ newshift = spec[4]
local quad = parameters.quad or 0
local ascender = parameters.ascender or 0
local descender = parameters.descender or 0
@@ -87,6 +89,7 @@ local function initialize(tfmdata,key,value)
parameters.x_heigth = (ascender + descender) / 2
end
end
+ -- todo: hshift too
if newwidth or newheight or newdepth then
for unicode, character in next, characters do
local oldwidth = character.width
@@ -101,7 +104,7 @@ local function initialize(tfmdata,key,value)
character.depth = depth
if oldwidth ~= width then
local commands = character.commands
- local hshift = rightcommand[(width - oldwidth) / 2]
+ local hshift = rightcommand[newshift or ((width - oldwidth) / 2)]
if commands then
character.commands = prependcommands (
commands,
diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua
index 880bcb6d5..56a91dbbb 100644
--- a/tex/context/base/mkiv/font-ots.lua
+++ b/tex/context/base/mkiv/font-ots.lua
@@ -2480,115 +2480,247 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
-- report("no hit in %a at %i of %i contexts",sequence.type,k,nofcontexts)
goto next
end
- local s = seq.n -- or #seq
- local l = ck[5] -- last current
- local current = start
- local last = start
-
+ local s = seq.n -- or #seq
if s == 1 then
- goto next
- end
+ -- bit weird case: why use a chain, but it is a hit
+ else
+ local l = ck[5] -- last current
+ local current = start
+ local last = start
- -- current match
+ -- current match
- if l > f then
- -- before/current/after | before/current | current/after
- local discfound -- = nil
- local n = f + 1
- last = startnext -- the second in current (first already matched)
- while n <= l do
- if postreplace and not last then
- last = getnext(sweepnode)
- sweeptype = nil
- end
- if last then
- local char, id = ischar(last,currentfont)
- if char then
- if skiphash and skiphash[char] then
- skipped = true
- if trace_skips then
- show_skip(dataset,sequence,char,ck,classes[char])
- end
- last = getnext(last)
- elseif seq[n][char] then
- if n < l then
+ if l > f then
+ -- before/current/after | before/current | current/after
+ local discfound -- = nil
+ local n = f + 1
+ last = startnext -- the second in current (first already matched)
+ while n <= l do
+ if postreplace and not last then
+ last = getnext(sweepnode)
+ sweeptype = nil
+ end
+ if last then
+ local char, id = ischar(last,currentfont)
+ if char then
+ if skiphash and skiphash[char] then
+ skipped = true
+ if trace_skips then
+ show_skip(dataset,sequence,char,ck,classes[char])
+ end
last = getnext(last)
- end
- n = n + 1
- elseif discfound then
- notmatchreplace[discfound] = true
- if notmatchpre[discfound] then
- goto next
+ elseif seq[n][char] then
+ if n < l then
+ last = getnext(last)
+ end
+ n = n + 1
+ elseif discfound then
+ notmatchreplace[discfound] = true
+ if notmatchpre[discfound] then
+ goto next
+ else
+ break
+ end
else
- break
- end
- else
- goto next
- end
- elseif char == false then
- if discfound then
- notmatchreplace[discfound] = true
- if notmatchpre[discfound] then
goto next
+ end
+ elseif char == false then
+ if discfound then
+ notmatchreplace[discfound] = true
+ if notmatchpre[discfound] then
+ goto next
+ else
+ break
+ end
else
- break
+ goto next
end
- else
- goto next
- end
- elseif id == disc_code then
- -- elseif id == disc_code and (not discs or discs[last]) then
- discseen = true
- discfound = last
- notmatchpre[last] = nil
- notmatchpost[last] = true
- notmatchreplace[last] = nil
- local pre, post, replace = getdisc(last)
- if pre then
- local n = n
- while pre do
- if seq[n][getchar(pre)] then
- n = n + 1
- if n > l then
+ elseif id == disc_code then
+ -- elseif id == disc_code and (not discs or discs[last]) then
+ discseen = true
+ discfound = last
+ notmatchpre[last] = nil
+ notmatchpost[last] = true
+ notmatchreplace[last] = nil
+ local pre, post, replace = getdisc(last)
+ if pre then
+ local n = n
+ while pre do
+ if seq[n][getchar(pre)] then
+ n = n + 1
+ if n > l then
+ break
+ end
+ pre = getnext(pre)
+ else
+ notmatchpre[last] = true
break
end
- pre = getnext(pre)
- else
+ end
+ if n <= l then
notmatchpre[last] = true
- break
end
- end
- if n <= l then
+ else
notmatchpre[last] = true
end
+ if replace then
+ -- so far we never entered this branch
+ while replace do
+ if seq[n][getchar(replace)] then
+ n = n + 1
+ if n > l then
+ break
+ end
+ replace = getnext(replace)
+ else
+ notmatchreplace[last] = true
+ if notmatchpre[last] then
+ goto next
+ else
+ break
+ end
+ end
+ end
+ -- why here again
+ if notmatchpre[last] then
+ goto next
+ end
+ end
+ -- maybe only if match
+ last = getnext(last)
else
- notmatchpre[last] = true
+ goto next
end
- if replace then
- -- so far we never entered this branch
- while replace do
- if seq[n][getchar(replace)] then
- n = n + 1
- if n > l then
- break
+ else
+ goto next
+ end
+ end
+ end
+
+ -- before
+
+ if f > 1 then
+ if startprev then
+ local prev = startprev
+ if prereplace and prev == checkdisc then
+ prev = getprev(sweepnode)
+ end
+ if prev then
+ local discfound -- = nil
+ local n = f - 1
+ while n >= 1 do
+ if prev then
+ local char, id = ischar(prev,currentfont)
+ if char then
+ if skiphash and skiphash[char] then
+ skipped = true
+ if trace_skips then
+ show_skip(dataset,sequence,char,ck,classes[char])
+ end
+ prev = getprev(prev)
+ elseif seq[n][char] then
+ if n > 1 then
+ prev = getprev(prev)
+ end
+ n = n - 1
+ elseif discfound then
+ notmatchreplace[discfound] = true
+ if notmatchpost[discfound] then
+ goto next
+ else
+ break
+ end
+ else
+ goto next
end
- replace = getnext(replace)
- else
- notmatchreplace[last] = true
- if notmatchpre[last] then
+ elseif char == false then
+ if discfound then
+ notmatchreplace[discfound] = true
+ if notmatchpost[discfound] then
+ goto next
+ end
+ else
goto next
+ end
+ break
+ elseif id == disc_code then
+ -- elseif id == disc_code and (not discs or discs[prev]) then
+ -- the special case: f i where i becomes dottless i ..
+ discseen = true
+ discfound = prev
+ notmatchpre[prev] = true
+ notmatchpost[prev] = nil
+ notmatchreplace[prev] = nil
+ local pre, post, replace, pretail, posttail, replacetail = getdisc(prev,true)
+ -- weird test: needs checking
+ if pre ~= start and post ~= start and replace ~= start then
+ if post then
+ local n = n
+ while posttail do
+ if seq[n][getchar(posttail)] then
+ n = n - 1
+ if posttail == post or n < 1 then
+ break
+ else
+ posttail = getprev(posttail)
+ end
+ else
+ notmatchpost[prev] = true
+ break
+ end
+ end
+ if n >= 1 then
+ notmatchpost[prev] = true
+ end
+ else
+ notmatchpost[prev] = true
+ end
+ if replace then
+ -- we seldom enter this branch (e.g. on brill efficient)
+ while replacetail do
+ if seq[n][getchar(replacetail)] then
+ n = n - 1
+ if replacetail == replace or n < 1 then
+ break
+ else
+ replacetail = getprev(replacetail)
+ end
+ else
+ notmatchreplace[prev] = true
+ if notmatchpost[prev] then
+ goto next
+ else
+ break
+ end
+ end
+ end
+ else
+ -- notmatchreplace[prev] = true -- not according to Kai
+ end
+ end
+ prev = getprev(prev)
+ -- elseif id == glue_code and seq[n][32] and isspace(prev,threshold,id) then
+ -- elseif seq[n][32] and spaces[prev] then
+ -- n = n - 1
+ -- prev = getprev(prev)
+ elseif id == glue_code then
+ local sn = seq[n]
+ if (sn[32] and spaces[prev]) or sn[0xFFFC] then
+ n = n - 1
+ prev = getprev(prev)
else
- break
+ goto next
end
+ elseif seq[n][0xFFFC] then
+ n = n - 1
+ prev = getprev(prev)
+ else
+ goto next
end
- end
- -- why here again
- if notmatchpre[last] then
+ else
goto next
end
end
- -- maybe only if match
- last = getnext(last)
else
goto next
end
@@ -2596,37 +2728,35 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
goto next
end
end
- end
- -- before
+ -- after
- if f > 1 then
- if startprev then
- local prev = startprev
- if prereplace and prev == checkdisc then
- prev = getprev(sweepnode)
+ if s > l then
+ local current = last and getnext(last)
+ if not current and postreplace then
+ current = getnext(sweepnode)
end
- if prev then
+ if current then
local discfound -- = nil
- local n = f - 1
- while n >= 1 do
- if prev then
- local char, id = ischar(prev,currentfont)
+ local n = l + 1
+ while n <= s do
+ if current then
+ local char, id = ischar(current,currentfont)
if char then
if skiphash and skiphash[char] then
skipped = true
if trace_skips then
show_skip(dataset,sequence,char,ck,classes[char])
end
- prev = getprev(prev)
+ current = getnext(current) -- was absent
elseif seq[n][char] then
- if n > 1 then
- prev = getprev(prev)
+ if n < s then -- new test
+ current = getnext(current) -- was absent
end
- n = n - 1
+ n = n + 1
elseif discfound then
notmatchreplace[discfound] = true
- if notmatchpost[discfound] then
+ if notmatchpre[discfound] then
goto next
else
break
@@ -2637,217 +2767,87 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
elseif char == false then
if discfound then
notmatchreplace[discfound] = true
- if notmatchpost[discfound] then
+ if notmatchpre[discfound] then
goto next
+ else
+ break
end
else
goto next
end
- break
elseif id == disc_code then
- -- elseif id == disc_code and (not discs or discs[prev]) then
- -- the special case: f i where i becomes dottless i ..
- discseen = true
- discfound = prev
- notmatchpre[prev] = true
- notmatchpost[prev] = nil
- notmatchreplace[prev] = nil
- local pre, post, replace, pretail, posttail, replacetail = getdisc(prev,true)
- -- weird test: needs checking
- if pre ~= start and post ~= start and replace ~= start then
- if post then
- local n = n
- while posttail do
- if seq[n][getchar(posttail)] then
- n = n - 1
- if posttail == post or n < 1 then
- break
- else
- posttail = getprev(posttail)
- end
- else
- notmatchpost[prev] = true
+ -- elseif id == disc_code and (not discs or discs[current]) then
+ discseen = true
+ discfound = current
+ notmatchpre[current] = nil
+ notmatchpost[current] = true
+ notmatchreplace[current] = nil
+ local pre, post, replace = getdisc(current)
+ if pre then
+ local n = n
+ while pre do
+ if seq[n][getchar(pre)] then
+ n = n + 1
+ if n > s then
break
+ else
+ pre = getnext(pre)
end
+ else
+ notmatchpre[current] = true
+ break
end
- if n >= 1 then
- notmatchpost[prev] = true
- end
- else
- notmatchpost[prev] = true
end
- if replace then
- -- we seldom enter this branch (e.g. on brill efficient)
- while replacetail do
- if seq[n][getchar(replacetail)] then
- n = n - 1
- if replacetail == replace or n < 1 then
- break
- else
- replacetail = getprev(replacetail)
- end
+ if n <= s then
+ notmatchpre[current] = true
+ end
+ else
+ notmatchpre[current] = true
+ end
+ if replace then
+ -- so far we never entered this branch
+ while replace do
+ if seq[n][getchar(replace)] then
+ n = n + 1
+ if n > s then
+ break
else
- notmatchreplace[prev] = true
- if notmatchpost[prev] then
- goto next
- else
- break
- end
+ replace = getnext(replace)
+ end
+ else
+ notmatchreplace[current] = true
+ if notmatchpre[current] then
+ goto next
+ else
+ break
end
end
- else
- -- notmatchreplace[prev] = true -- not according to Kai
end
+ else
+ -- notmatchreplace[current] = true -- not according to Kai
end
- prev = getprev(prev)
- -- elseif id == glue_code and seq[n][32] and isspace(prev,threshold,id) then
- -- elseif seq[n][32] and spaces[prev] then
- -- n = n - 1
- -- prev = getprev(prev)
+ current = getnext(current)
elseif id == glue_code then
local sn = seq[n]
- if (sn[32] and spaces[prev]) or sn[0xFFFC] then
- n = n - 1
- prev = getprev(prev)
+ if (sn[32] and spaces[current]) or sn[0xFFFC] then
+ n = n + 1
+ current = getnext(current)
else
goto next
end
elseif seq[n][0xFFFC] then
- n = n - 1
- prev = getprev(prev)
- else
- goto next
- end
- else
- goto next
- end
- end
- else
- goto next
- end
- else
- goto next
- end
- end
-
- -- after
-
- if s > l then
- local current = last and getnext(last)
- if not current and postreplace then
- current = getnext(sweepnode)
- end
- if current then
- local discfound -- = nil
- local n = l + 1
- while n <= s do
- if current then
- local char, id = ischar(current,currentfont)
- if char then
- if skiphash and skiphash[char] then
- skipped = true
- if trace_skips then
- show_skip(dataset,sequence,char,ck,classes[char])
- end
- current = getnext(current) -- was absent
- elseif seq[n][char] then
- if n < s then -- new test
- current = getnext(current) -- was absent
- end
- n = n + 1
- elseif discfound then
- notmatchreplace[discfound] = true
- if notmatchpre[discfound] then
- goto next
- else
- break
- end
- else
- goto next
- end
- elseif char == false then
- if discfound then
- notmatchreplace[discfound] = true
- if notmatchpre[discfound] then
- goto next
- else
- break
- end
- else
- goto next
- end
- elseif id == disc_code then
- -- elseif id == disc_code and (not discs or discs[current]) then
- discseen = true
- discfound = current
- notmatchpre[current] = nil
- notmatchpost[current] = true
- notmatchreplace[current] = nil
- local pre, post, replace = getdisc(current)
- if pre then
- local n = n
- while pre do
- if seq[n][getchar(pre)] then
- n = n + 1
- if n > s then
- break
- else
- pre = getnext(pre)
- end
- else
- notmatchpre[current] = true
- break
- end
- end
- if n <= s then
- notmatchpre[current] = true
- end
- else
- notmatchpre[current] = true
- end
- if replace then
- -- so far we never entered this branch
- while replace do
- if seq[n][getchar(replace)] then
- n = n + 1
- if n > s then
- break
- else
- replace = getnext(replace)
- end
- else
- notmatchreplace[current] = true
- if notmatchpre[current] then
- goto next
- else
- break
- end
- end
- end
- else
- -- notmatchreplace[current] = true -- not according to Kai
- end
- current = getnext(current)
- elseif id == glue_code then
- local sn = seq[n]
- if (sn[32] and spaces[current]) or sn[0xFFFC] then
n = n + 1
current = getnext(current)
else
goto next
end
- elseif seq[n][0xFFFC] then
- n = n + 1
- current = getnext(current)
else
goto next
end
- else
- goto next
end
+ else
+ goto next
end
- else
- goto next
end
end
diff --git a/tex/context/base/mkiv/font-ott.lua b/tex/context/base/mkiv/font-ott.lua
index f4d7e05a1..aa1defd6a 100644
--- a/tex/context/base/mkiv/font-ott.lua
+++ b/tex/context/base/mkiv/font-ott.lua
@@ -821,13 +821,13 @@ local features = allocate {
["dist"] = "distances",
["dlig"] = "discretionary ligatures",
["dnom"] = "denominators",
- ["dtls"] = "dotless forms", -- math
+ ["dtls"] = "dotless forms", -- math
["expt"] = "expert forms",
["falt"] = "final glyph alternates",
["fin2"] = "terminal forms #2",
["fin3"] = "terminal forms #3",
["fina"] = "terminal forms",
- ["flac"] = "flattened accents over capitals", -- math
+ ["flac"] = "flattened accents over capitals", -- math
["frac"] = "fractions",
["fwid"] = "full width",
["half"] = "half forms",
@@ -836,7 +836,7 @@ local features = allocate {
["hist"] = "historical forms",
["hkna"] = "horizontal kana alternates",
["hlig"] = "historical ligatures",
- ["hngl"] = "hangul",
+ ["hngl"] = "hangul", -- depricated
["hojo"] = "hojo kanji forms",
["hwid"] = "half width",
["init"] = "initial forms",
diff --git a/tex/context/base/mkiv/mult-low.lua b/tex/context/base/mkiv/mult-low.lua
index ee924b469..05e5f28e5 100644
--- a/tex/context/base/mkiv/mult-low.lua
+++ b/tex/context/base/mkiv/mult-low.lua
@@ -174,6 +174,8 @@ return {
"frozenflagcode", "tolerantflagcode", "protectedflagcode", "primitiveflagcode", "permanentflagcode", "noalignedflagcode", "immutableflagcode", "mutableflagcode",
"globalflagcode", "overloadedflagcode", "immediateflagcode", "conditionalflagcode", "valueflagcode", "instanceflagcode",
--
+ "prewordcode", "postwordcode",
+ --
"continuewhenlmtxmode"
},
["helpers"] = {
diff --git a/tex/context/base/mkiv/mult-prm.lua b/tex/context/base/mkiv/mult-prm.lua
index a6b81af7e..c2b11df3d 100644
--- a/tex/context/base/mkiv/mult-prm.lua
+++ b/tex/context/base/mkiv/mult-prm.lua
@@ -443,6 +443,7 @@ return {
"tolerant",
"tpack",
"tracingfonts",
+ "tracinghyphenation",
"tracingmath",
"undent",
"unletfrozen",
diff --git a/tex/context/base/mkiv/spac-ver.lua b/tex/context/base/mkiv/spac-ver.lua
index 2fc926321..efa1dd967 100644
--- a/tex/context/base/mkiv/spac-ver.lua
+++ b/tex/context/base/mkiv/spac-ver.lua
@@ -2128,19 +2128,20 @@ do
end
end
- local trace = false
- local last = nil
- local vmode_code = tex.modelevels.vertical
- local temp_code = nodecodes.temp
- local getnest = tex.getnest
- local getlist = tex.getlist
+ local trace = false
+ local last = nil
+ local vmode_code = tex.modelevels.vertical
+ local temp_code = nodecodes.temp
+ local texgetnest = tex.getnest
+ local texgetlist = tex.getlist
+ local getnodetail = nodes.tail
trackers.register("vspacing.forcestrutdepth",function(v) trace = v end)
-- abs : negative is inner
function vspacing.checkstrutdepth(depth)
- local nest = getnest()
+ local nest = texgetnest()
if abs(nest.mode) == vmode_code and nest.head then
local tail = nest.tail
local id = tail.id
@@ -2149,10 +2150,10 @@ do
tail.depth = depth
end
nest.prevdepth = depth
- elseif id == temp_code and getnest("ptr") == 0 then
- local head = getlist("page_head")
+ elseif id == temp_code and texgetnest("ptr") == 0 then
+ local head = texgetlist("page_head")
if head then
- tail = nodes.tail(head)
+ tail = getnodetail(head)
if tail and tail.id == hlist_code then
if tail.depth < depth then
tail.depth = depth
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 3b842839c..cffa6fdb6 100644
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index a47f44479..fea56a359 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl
index ba8893ea6..87175b22d 100644
--- a/tex/context/base/mkxl/cont-new.mkxl
+++ b/tex/context/base/mkxl/cont-new.mkxl
@@ -13,7 +13,7 @@
% \normalend % uncomment this to get the real base runtime
-\newcontextversion{2021.03.31 18:00}
+\newcontextversion{2021.04.09 19:54}
%D This file is loaded at runtime, thereby providing an excellent place for hacks,
%D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkxl/context.mkxl b/tex/context/base/mkxl/context.mkxl
index 1ace620b2..84bdd0277 100644
--- a/tex/context/base/mkxl/context.mkxl
+++ b/tex/context/base/mkxl/context.mkxl
@@ -29,7 +29,7 @@
%D {YYYY.MM.DD HH:MM} format.
\immutable\edef\contextformat {\jobname}
-\immutable\edef\contextversion{2021.03.31 18:00}
+\immutable\edef\contextversion{2021.04.09 19:54}
%overloadmode 1 % check frozen / warning
%overloadmode 2 % check frozen / error
diff --git a/tex/context/base/mkxl/font-ots.lmt b/tex/context/base/mkxl/font-ots.lmt
index d5d04e978..be5b0ce40 100644
--- a/tex/context/base/mkxl/font-ots.lmt
+++ b/tex/context/base/mkxl/font-ots.lmt
@@ -2524,115 +2524,246 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
-- report("no hit in %a at %i of %i contexts",sequence.type,k,nofcontexts)
goto next
end
- local s = seq.n -- or #seq
- local l = ck[5] -- last current
- local current = start
- local last = start
-
+ local s = seq.n -- or #seq
if s == 1 then
- goto next
- end
-
- -- current match
+ -- bit weird case: why use a chain, but it is a hit
+ else
+ local l = ck[5] -- last current
+ local current = start
+ local last = start
- if l > f then
- -- before/current/after | before/current | current/after
- local discfound -- = nil
- local n = f + 1
- last = startnext -- the second in current (first already matched)
- while n <= l do
- if postreplace and not last then
- last = getnext(sweepnode)
- sweeptype = nil
- end
- if last then
- local nxt, char, id = isnextchar(last,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
- if char then
- if skiphash and skiphash[char] then
- skipped = true
- if trace_skips then
- show_skip(dataset,sequence,char,ck,classes[char])
- end
- last = nxt
- elseif seq[n][char] then
- if n < l then
+ if l > f then
+ -- before/current/after | before/current | current/after
+ local discfound -- = nil
+ local n = f + 1
+ last = startnext -- the second in current (first already matched)
+ while n <= l do
+ if postreplace and not last then
+ last = getnext(sweepnode)
+ sweeptype = nil
+ end
+ if last then
+ local nxt, char, id = isnextchar(last,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
+ if char then
+ if skiphash and skiphash[char] then
+ skipped = true
+ if trace_skips then
+ show_skip(dataset,sequence,char,ck,classes[char])
+ end
last = nxt
- end
- n = n + 1
- elseif discfound then
- notmatchreplace[discfound] = true
- if notmatchpre[discfound] then
- goto next
+ elseif seq[n][char] then
+ if n < l then
+ last = nxt
+ end
+ n = n + 1
+ elseif discfound then
+ notmatchreplace[discfound] = true
+ if notmatchpre[discfound] then
+ goto next
+ else
+ break
+ end
else
- break
- end
- else
- goto next
- end
- elseif char == false then
- if discfound then
- notmatchreplace[discfound] = true
- if notmatchpre[discfound] then
goto next
+ end
+ elseif char == false then
+ if discfound then
+ notmatchreplace[discfound] = true
+ if notmatchpre[discfound] then
+ goto next
+ else
+ break
+ end
else
- break
+ goto next
end
- else
- goto next
- end
- elseif id == disc_code then
- -- elseif id == disc_code and (not discs or discs[last]) then
- discseen = true
- discfound = last
- notmatchpre[last] = nil
- notmatchpost[last] = true
- notmatchreplace[last] = nil
- local pre, post, replace = getdisc(last)
- if pre then
- local n = n
- while pre do
- if seq[n][getchar(pre)] then
- n = n + 1
- if n > l then
+ elseif id == disc_code then
+ -- elseif id == disc_code and (not discs or discs[last]) then
+ discseen = true
+ discfound = last
+ notmatchpre[last] = nil
+ notmatchpost[last] = true
+ notmatchreplace[last] = nil
+ local pre, post, replace = getdisc(last)
+ if pre then
+ local n = n
+ while pre do
+ if seq[n][getchar(pre)] then
+ n = n + 1
+ if n > l then
+ break
+ end
+ pre = getnext(pre)
+ else
+ notmatchpre[last] = true
break
end
- pre = getnext(pre)
- else
+ end
+ if n <= l then
notmatchpre[last] = true
- break
end
- end
- if n <= l then
+ else
notmatchpre[last] = true
end
+ if replace then
+ -- so far we never entered this branch
+ while replace do
+ if seq[n][getchar(replace)] then
+ n = n + 1
+ if n > l then
+ break
+ end
+ replace = getnext(replace)
+ else
+ notmatchreplace[last] = true
+ if notmatchpre[last] then
+ goto next
+ else
+ break
+ end
+ end
+ end
+ -- why here again
+ if notmatchpre[last] then
+ goto next
+ end
+ end
+ -- maybe only if match
+ last = nxt
else
- notmatchpre[last] = true
+ goto next
end
- if replace then
- -- so far we never entered this branch
- while replace do
- if seq[n][getchar(replace)] then
- n = n + 1
- if n > l then
- break
+ else
+ goto next
+ end
+ end
+ end
+
+ -- before
+
+ if f > 1 then
+ if startprev then
+ local prev = startprev
+ if prereplace and prev == checkdisc then
+ prev = getprev(sweepnode)
+ end
+ if prev then
+ local discfound -- = nil
+ local n = f - 1
+ while n >= 1 do
+ if prev then
+ local prv, char, id = isprevchar(prev,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
+ if char then
+ if skiphash and skiphash[char] then
+ skipped = true
+ if trace_skips then
+ show_skip(dataset,sequence,char,ck,classes[char])
+ end
+ prev = prv
+ elseif seq[n][char] then
+ if n > 1 then
+ prev = prv
+ end
+ n = n - 1
+ elseif discfound then
+ notmatchreplace[discfound] = true
+ if notmatchpost[discfound] then
+ goto next
+ else
+ break
+ end
+ else
+ goto next
end
- replace = getnext(replace)
- else
- notmatchreplace[last] = true
- if notmatchpre[last] then
+ elseif char == false then
+ if discfound then
+ notmatchreplace[discfound] = true
+ if notmatchpost[discfound] then
+ goto next
+ end
+ else
goto next
+ end
+ break
+ elseif id == disc_code then
+ -- elseif id == disc_code and (not discs or discs[prev]) then
+ -- the special case: f i where i becomes dottless i ..
+ discseen = true
+ discfound = prev
+ notmatchpre[prev] = true
+ notmatchpost[prev] = nil
+ notmatchreplace[prev] = nil
+ local pre, post, replace, pretail, posttail, replacetail = getdisc(prev,true)
+ -- weird test: needs checking
+ if pre ~= start and post ~= start and replace ~= start then
+ if post then
+ local n = n
+ while posttail do
+ if seq[n][getchar(posttail)] then
+ n = n - 1
+ if posttail == post or n < 1 then
+ break
+ else
+ posttail = getprev(posttail)
+ end
+ else
+ notmatchpost[prev] = true
+ break
+ end
+ end
+ if n >= 1 then
+ notmatchpost[prev] = true
+ end
+ else
+ notmatchpost[prev] = true
+ end
+ if replace then
+ -- we seldom enter this branch (e.g. on brill efficient)
+ while replacetail do
+ if seq[n][getchar(replacetail)] then
+ n = n - 1
+ if replacetail == replace or n < 1 then
+ break
+ else
+ replacetail = getprev(replacetail)
+ end
+ else
+ notmatchreplace[prev] = true
+ if notmatchpost[prev] then
+ goto next
+ else
+ break
+ end
+ end
+ end
+ else
+ -- notmatchreplace[prev] = true -- not according to Kai
+ end
+ end
+ -- prev = getprev(prev)
+ prev = prv
+ -- elseif id == glue_code and seq[n][32] and isspace(prev,threshold,id) then
+ -- elseif seq[n][32] and spaces[prev] then
+ -- n = n - 1
+ -- prev = prv
+ elseif id == glue_code then
+ local sn = seq[n]
+ if (sn[32] and spaces[prev]) or sn[0xFFFC] then
+ n = n - 1
+ prev = prv
else
- break
+ goto next
end
+ elseif seq[n][0xFFFC] then
+ n = n - 1
+ prev = prv
+ else
+ goto next
end
- end
- -- why here again
- if notmatchpre[last] then
+ else
goto next
end
end
- -- maybe only if match
- last = nxt
else
goto next
end
@@ -2640,37 +2771,35 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
goto next
end
end
- end
- -- before
+ -- after
- if f > 1 then
- if startprev then
- local prev = startprev
- if prereplace and prev == checkdisc then
- prev = getprev(sweepnode)
+ if s > l then
+ local current = last and getnext(last)
+ if not current and postreplace then
+ current = getnext(sweepnode)
end
- if prev then
+ if current then
local discfound -- = nil
- local n = f - 1
- while n >= 1 do
- if prev then
- local prv, char, id = isprevchar(prev,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
+ local n = l + 1
+ while n <= s do
+ if current then
+ local nxt, char, id = isnextchar(current,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
if char then
if skiphash and skiphash[char] then
skipped = true
if trace_skips then
show_skip(dataset,sequence,char,ck,classes[char])
end
- prev = prv
+ current = nxt -- was absent
elseif seq[n][char] then
- if n > 1 then
- prev = prv
+ if n < s then -- new test
+ current = nxt -- was absent
end
- n = n - 1
+ n = n + 1
elseif discfound then
notmatchreplace[discfound] = true
- if notmatchpost[discfound] then
+ if notmatchpre[discfound] then
goto next
else
break
@@ -2681,222 +2810,90 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
elseif char == false then
if discfound then
notmatchreplace[discfound] = true
- if notmatchpost[discfound] then
+ if notmatchpre[discfound] then
goto next
+ else
+ break
end
else
goto next
end
- break
elseif id == disc_code then
- -- elseif id == disc_code and (not discs or discs[prev]) then
- -- the special case: f i where i becomes dottless i ..
- discseen = true
- discfound = prev
- notmatchpre[prev] = true
- notmatchpost[prev] = nil
- notmatchreplace[prev] = nil
- local pre, post, replace, pretail, posttail, replacetail = getdisc(prev,true)
- -- weird test: needs checking
- if pre ~= start and post ~= start and replace ~= start then
- if post then
- local n = n
- while posttail do
- if seq[n][getchar(posttail)] then
- n = n - 1
- if posttail == post or n < 1 then
- break
- else
- posttail = getprev(posttail)
- end
- else
- notmatchpost[prev] = true
+ -- elseif id == disc_code and (not discs or discs[current]) then
+ discseen = true
+ discfound = current
+ notmatchpre[current] = nil
+ notmatchpost[current] = true
+ notmatchreplace[current] = nil
+ local pre, post, replace = getdisc(current)
+ -- no detailed checking here, todo ?
+ if pre then
+ local n = n
+ while pre do
+ if seq[n][getchar(pre)] then
+ n = n + 1
+ if n > s then
break
+ else
+ pre = getnext(pre)
end
+ else
+ notmatchpre[current] = true
+ break
end
- if n >= 1 then
- notmatchpost[prev] = true
- end
- else
- notmatchpost[prev] = true
end
- if replace then
- -- we seldom enter this branch (e.g. on brill efficient)
- while replacetail do
- if seq[n][getchar(replacetail)] then
- n = n - 1
- if replacetail == replace or n < 1 then
- break
- else
- replacetail = getprev(replacetail)
- end
+ if n <= s then
+ notmatchpre[current] = true
+ end
+ else
+ notmatchpre[current] = true
+ end
+ if replace then
+ -- so far we never entered this branch
+ while replace do
+ if seq[n][getchar(replace)] then
+ n = n + 1
+ if n > s then
+ break
else
- notmatchreplace[prev] = true
- if notmatchpost[prev] then
- goto next
- else
- break
- end
+ replace = getnext(replace)
+ end
+ else
+ notmatchreplace[current] = true
+ if notmatchpre[current] then
+ goto next
+ else
+ break
end
end
- else
- -- notmatchreplace[prev] = true -- not according to Kai
end
+ else
+ -- notmatchreplace[current] = true -- not according to Kai
end
- -- prev = getprev(prev)
- prev = prv
- -- elseif id == glue_code and seq[n][32] and isspace(prev,threshold,id) then
- -- elseif seq[n][32] and spaces[prev] then
- -- n = n - 1
- -- prev = prv
+ current = getnext(current)
elseif id == glue_code then
local sn = seq[n]
- if (sn[32] and spaces[prev]) or sn[0xFFFC] then
- n = n - 1
- prev = prv
+ if (sn[32] and spaces[current]) or sn[0xFFFC] then
+ n = n + 1
+ current = nxt
else
goto next
end
elseif seq[n][0xFFFC] then
- n = n - 1
- prev = prv
- else
- goto next
- end
- else
- goto next
- end
- end
- else
- goto next
- end
- else
- goto next
- end
- end
-
- -- after
-
- if s > l then
- local current = last and getnext(last)
- if not current and postreplace then
- current = getnext(sweepnode)
- end
- if current then
- local discfound -- = nil
- local n = l + 1
- while n <= s do
- if current then
- local nxt, char, id = isnextchar(current,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
- if char then
- if skiphash and skiphash[char] then
- skipped = true
- if trace_skips then
- show_skip(dataset,sequence,char,ck,classes[char])
- end
- current = nxt -- was absent
- elseif seq[n][char] then
- if n < s then -- new test
- current = nxt -- was absent
- end
- n = n + 1
- elseif discfound then
- notmatchreplace[discfound] = true
- if notmatchpre[discfound] then
- goto next
- else
- break
- end
- else
- goto next
- end
- elseif char == false then
- if discfound then
- notmatchreplace[discfound] = true
- if notmatchpre[discfound] then
- goto next
- else
- break
- end
- else
- goto next
- end
- elseif id == disc_code then
- -- elseif id == disc_code and (not discs or discs[current]) then
- discseen = true
- discfound = current
- notmatchpre[current] = nil
- notmatchpost[current] = true
- notmatchreplace[current] = nil
- local pre, post, replace = getdisc(current)
- -- no detailed checking here, todo ?
- if pre then
- local n = n
- while pre do
- if seq[n][getchar(pre)] then
- n = n + 1
- if n > s then
- break
- else
- pre = getnext(pre)
- end
- else
- notmatchpre[current] = true
- break
- end
- end
- if n <= s then
- notmatchpre[current] = true
- end
- else
- notmatchpre[current] = true
- end
- if replace then
- -- so far we never entered this branch
- while replace do
- if seq[n][getchar(replace)] then
- n = n + 1
- if n > s then
- break
- else
- replace = getnext(replace)
- end
- else
- notmatchreplace[current] = true
- if notmatchpre[current] then
- goto next
- else
- break
- end
- end
- end
- else
- -- notmatchreplace[current] = true -- not according to Kai
- end
- current = getnext(current)
- elseif id == glue_code then
- local sn = seq[n]
- if (sn[32] and spaces[current]) or sn[0xFFFC] then
n = n + 1
current = nxt
else
goto next
end
- elseif seq[n][0xFFFC] then
- n = n + 1
- current = nxt
else
goto next
end
- else
- goto next
end
+ else
+ goto next
end
- else
- goto next
end
end
-
if trace_contexts then
chaintrac(head,start,dataset,sequence,rlmode,skipped and skiphash,ck,true,discseen,sweepnode)
end
diff --git a/tex/context/base/mkxl/lang-ini.lmt b/tex/context/base/mkxl/lang-ini.lmt
index 7364eb7c7..a0bed0d0a 100644
--- a/tex/context/base/mkxl/lang-ini.lmt
+++ b/tex/context/base/mkxl/lang-ini.lmt
@@ -19,10 +19,12 @@ if not modules then modules = { } end modules ['lang-ini'] = {
-- todo: no foo:bar but foo(bar,...)
+-- https://wortschatz.uni-leipzig.de/de/download/German : lots of lists
+
local type, tonumber, next = type, tonumber, next
local utfbyte, utflength = utf.byte, utf.length
local format, gsub, gmatch, find = string.format, string.gsub, string.gmatch, string.find
-local concat, sortedkeys, sortedpairs, keys, insert = table.concat, table.sortedkeys, table.sortedpairs, table.keys, table.insert
+local concat, sortedkeys, sortedpairs, keys, insert, tohash = table.concat, table.sortedkeys, table.sortedpairs, table.keys, table.insert, table.tohash
local setmetatableindex = table.setmetatableindex
local utfvalues, strip, utfcharacters = string.utfvalues, string.strip, utf.characters
@@ -35,6 +37,7 @@ local settings_to_set = utilities.parsers.settings_to_set
local trace_patterns = false trackers.register("languages.patterns", function(v) trace_patterns = v end)
local trace_goodies = false trackers.register("languages.goodies", function(v) trace_goodies = v end)
+local trace_applied = false trackers.register("languages.applied", function(v) trace_applied = v end)
local report_initialization = logs.reporter("languages","initialization")
local report_goodies = logs.reporter("languages","goodies")
@@ -246,7 +249,7 @@ end
-- 2'2 conflicts with 4' ... and luatex barks on it
-local P, S, R, Cs, Ct, lpegmatch, lpegpatterns = lpeg.P, lpeg.S, lpeg.R, lpeg.Cs, lpeg.Ct, lpeg.match, lpeg.patterns
+local P, S, R, C, Cs, Ct, lpegmatch, lpegpatterns = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.match, lpeg.patterns
local utfsplit = utf.split
@@ -558,6 +561,15 @@ function languages.setexceptions(tag,str)
end
end
+function languages.setpatterns(tag,str)
+ local data, instance = resolve(tag)
+ if data then
+ str = strip(str) -- we need to strip leading spaces
+ collecthjcodes(data,str)
+ instance:patterns(str)
+ end
+end
+
local function setwordhandler(tag,action)
local data, instance = resolve(tag)
if data then
@@ -569,6 +581,8 @@ languages.setwordhandler = setwordhandler
function languages.setoptions(tag,str)
languages.addgoodiesdata(tag,{ { words = str } })
+ -- for now:
+ languages.setgoodieshandler { tag = tag, goodies = tag }
end
function languages.hyphenate(tag,str)
@@ -594,6 +608,23 @@ do
local nuts = nodes.nuts
local nextglyph = nuts.traversers.glyph
local setoptions = nuts.setoptions
+
+ local getnext = nuts.getnext
+ local getprev = nuts.getprev
+ local setchar = nuts.setchar
+ local setnext = nuts.setnext
+ local setlink = nuts.setlink
+ local setfield = nuts.setfield
+ local setdisc = nuts.setdisc
+ local getprop = nuts.getprop
+ local setprop = nuts.setprop
+ local setattrlist = nuts.setattrlist
+
+ local new_disc = nuts.pool.disc
+ local new_glyph = nuts.pool.glyph
+ local copy_node = nuts.copy
+ local flush_list = nuts.flush_list
+
local glyphoptioncodes = tex.glyphoptioncodes
local lower = characters.lower
@@ -602,21 +633,6 @@ do
local report = logs.reporter("languages","goodies")
-local getnext = nuts.getnext
-local getprev = nuts.getprev
-local setchar = nuts.setchar
-local setnext = nuts.setnext
-local setlink = nuts.setlink
-local setdisc = nuts.setdisc
-local getprop = nuts.getprop
-local setprop = nuts.setprop
-local setattrlist = nuts.setattrlist
-
-local new_disc = nuts.pool.disc
-local new_glyph = nuts.pool.glyph
-local copy_node = nuts.copy
-local flush_list = nuts.flush_list
-
-- can be shared
local goodiesdata = setmetatableindex(function(t,k)
@@ -624,6 +640,7 @@ local flush_list = nuts.flush_list
properties = { },
replacements = { },
characters = { },
+ exceptions = { },
}
t[k] = v
return v
@@ -631,11 +648,15 @@ local flush_list = nuts.flush_list
-- can be a helper
- local function setcompound(current,id)
+ local compound_disc_code = tex.discoptioncodes.preword | tex.discoptioncodes.postword
+
+ local function setcompound(current,id,first,last,lh,rh)
local prev = getprev(current)
- local language = tolang(id)
- local prechar = prehyphenchar(language)
- local postchar = posthyphenchar(language)
+ -- local language = tolang(id)
+ -- local prechar = prehyphenchar(language)
+ -- local postchar = posthyphenchar(language)
+ local prechar = prehyphenchar(id)
+ local postchar = posthyphenchar(id)
local pre = prechar and copy_node(current)
local post = postchar and copy_node(current)
local disc = new_disc()
@@ -649,8 +670,26 @@ local flush_list = nuts.flush_list
setoptions(disc,0x3) -- todo foo_code
setdisc(disc,pre,post)
setlink(prev,disc,current)
+ if lh then
+ setfield(first,"rhmin",rh)
+ end
+
+ if rh then
+ setfield(current,"lhmin",lh)
+ end
+
end
+ local setcompounds = setmetatableindex(function(t,l)
+ local v = setmetatableindex(function(t,r)
+ local v = function(current,id,first,last) return setcompound(current,id,first,last,l,r) end
+ t[r] = v
+ return v
+ end)
+ t[l] = v
+ return v
+ end)
+
local function replaceword(first,last,old,new,oldlen)
local oldlen = utflength(old)
local newlen = utflength(new)
@@ -689,14 +728,22 @@ local flush_list = nuts.flush_list
end
end
+ -- local optioncodes = table.copy(glyphoptioncodes)
+ --
+ -- optioncodes.nokerns = optioncodes.noleftkern | optioncodes.norightkern
+ -- optioncodes.noligatures = optioncodes.noleftligature | optioncodes.norightligature
+
+ local lh, rh = false, false
+
local cache = setmetatableindex(function(t,k)
local v = 0
if k == "compound" then
- v = setcompound
+ v = setcompounds[lh][rh]
else
v = 0
for s in gmatch(k,"%w+") do
local o = glyphoptioncodes[s]
+ -- local o = optioncodes[s]
if o then
v = v | o
end
@@ -720,18 +767,74 @@ local flush_list = nuts.flush_list
end
end
--- statistics.starttiming(languages)
--- statistics.stoptiming(languages)
+ -- statistics.starttiming(languages)
+ -- statistics.stoptiming(languages)
+
+ -- 1: restart 2: exceptions+patterns 3: patterns *: next word
+
+ local sequencers = utilities.sequencers
+ local newsequencer = sequencers.new
+ local appendgroup = sequencers.appendgroup
+ local appendaction = sequencers.appendaction
+ local enableaction = sequencers.enableaction
+ local disableaction = sequencers.disableaction
+
+ local template = {
+ arguments = "s",
+ returnvalues = "r,i",
+ results = "r,i",
+ }
+
+ local registeredactions = setmetatableindex ( function(t,tag)
+ local actions = newsequencer(template)
+ appendgroup(actions,"user")
+ t[tag] = actions
+ return actions
+ end )
+
+ languages.registeredactions = registeredactions
+
+ function languages.installhandler(tag,func)
+ local todo = not rawget(registeredactions,tag)
+ local actions = registeredactions[tag]
+ appendaction(actions,"user",func)
+ enableaction(actions,func)
+ report("installing handler %a for language %a",func,tag)
+ if todo then
+ setwordhandler(tag,function(n,original,remapped,length,first,last)
+ local runner = actions.runner
+ if runner then
+ if getprop(first,"replaced") then
+ -- maybe some deadcycles
+ else
+ local r, result = runner(original)
+ if not r or original == r then
+ return result or 0
+ else
+ setprop(first,"replaced",true)
+ replaceword(first,last,original,r,length)
+ return 1
+ end
+ end
+ end
+ return 2
+ end)
+ end
+ end
+
+ local appliedoptions = setmetatableindex("table")
+ languages.appliedoptions = appliedoptions
languages.setgoodieshandler = function(specification) -- will become a table specifier
if type(specification) == "table" then
local tag = specification.tag
local goodies = specification.goodies or tag
- local result = specification.result or false
+ local result = specification.result or 2
local data = goodiesdata[goodies]
local properties = data.properties
local replacements = data.replacements
local characters = data.characters
+ local exceptions = data.exceptions
local replacer = nil
local d, instance = resolve(tag)
local done = false
@@ -757,54 +860,107 @@ local flush_list = nuts.flush_list
end
done = true
end
+ if type(exceptions) == "table" and next(exceptions) then
+ done = true
+ else
+ exceptions = false
+ end
if done then
- setwordhandler(tag,
- function(n,original,remapped,length,first,last)
- local restart = nil
- local o = properties[remapped]
- if o then
- if trace_goodies then
- report("properties: %s %s",original,remapped)
- end
- local index = 0
- for g, c in nextglyph, first do
- index = index + 1
- local oi = o[index]
- if oi == setcompound then
- setcompound(g,n)
- restart = getprev(first)
- elseif oi then
- setoptions(g,oi)
- end
- if g == last then
- break
+ local registered = registeredactions[tag]
+ local applied = appliedoptions[tag]
+ setwordhandler(tag,function(n,original,remapped,length,first,last)
+ local runner = registered.runner
+ if runner then
+ if getprop(first,"replaced") then
+ -- maybe some deadcycles
+ else
+ local r, result = runner(original)
+ if not r then
+ if trace_goodies then
+ report_goodies("kept by runner: %s => %s, result %i",original,remapped, result or 0)
end
- end
- elseif replacer then
- -- todo: check lengths so that we can avoid a check
- if getprop(first,"replaced") then
- -- maybe some deadcycles
- else
- local r = lpegmatch(replacer,original)
- if original == r then
+ return result or 0
+ elseif original == r then
+ if result then
if trace_goodies then
- report_goodies("kept: %s => %s",original,remapped)
+ report_goodies("kept by runner: %s => %s, result %i",original,remapped, result)
end
+ return result
else
if trace_goodies then
- report_goodies("replaced: %s => %s => %s",original,remapped,r)
+ report_goodies("kept by runner: %s => %s, continue",original,remapped)
end
- setprop(first,"replaced",true)
- replaceword(first,last,original,r,length)
- restart = getprev(first)
end
+ else
+ if trace_goodies then
+ report_goodies("replaced by runner: %s => %s => %s, restart",original,remapped,r)
+ end
+ setprop(first,"replaced",true)
+ replaceword(first,last,original,r,length)
+ return 1
+ end
+ end
+ end
+ local result = 2
+ local o = properties[remapped]
+ if o then
+ if trace_goodies then
+ report("properties: %s %s",original,remapped)
+ end
+ if trace_applied then
+ applied[original] = (applied[original] or 0) + 1
+ end
+ local index = 0
+ for g, c in nextglyph, first do
+ index = index + 1
+ local oi = o[index]
+ if oi then
+ if type(oi) == "function" then
+ oi(g,n,first,last) -- maybe return value
+ result = 1
+ else
+ setoptions(g,oi)
+ end
+ end
+ if g == last then
+ break
end
+ end
+ elseif replacer then
+ -- todo: check lengths so that we can avoid a check
+ if getprop(first,"replaced") then
+ -- maybe some deadcycles
else
+ local r = lpegmatch(replacer,original)
+ if original == r then
+ if trace_goodies then
+ report_goodies("kept: %s => %s",original,remapped)
+ end
+ else
+ if trace_goodies then
+ report_goodies("replaced: %s => %s => %s",original,remapped,r)
+ end
+ setprop(first,"replaced",true)
+ replaceword(first,last,original,r,length)
+ result = 1
+ end
+ end
+ elseif exceptions then
+ local exception = exceptions[original]
+ if exception then
if trace_goodies then
- report_goodies("ignored: %s => %s",original,remapped)
+ report_goodies("exception: %s => %s",original,exception)
end
+ result = exception
+ else
+ result = 3
+ end
+ else
+ if trace_goodies then
+ report_goodies("ignored: %s => %s",original,remapped)
end
- return result, restart
+ end
+ return result
end)
elseif trace_goodies then
report_goodies("nothing useable in %a for %a",goodies,tag)
@@ -814,84 +970,111 @@ local flush_list = nuts.flush_list
end
end
- -- local function xreplacer(t,n)
- -- local i = 0
- -- local h = table.tohash(n)
- -- if #h == 0 then
- -- local p = Cs((utfchartabletopattern(t) / t + utf8char)^0)
- -- return function(s)
- -- return lpegmatch(p,s)
- -- end
- -- else
- -- local f = function(k) i = i + 1 if h[i] then return t[k] else return k end end
- -- local p = Cs((utfchartabletopattern(t) / f + utf8char)^0)
- -- return function(s)
- -- i = 0
- -- return lpegmatch(p,s)
- -- end
- -- end
- -- end
-
- local function blockligature(v,n)
- if n > 0 then
- local vv = v[n-1]
- if vv then
- v[n-1] = vv .. " norightligature"
- else
- v[n-1] = "norightligature"
+ local norightligature_option = glyphoptioncodes.norightligature
+ local noleftligature_option = glyphoptioncodes.noleftligature
+ local norightkern_option = glyphoptioncodes.norightkern
+ local noleftkern_option = glyphoptioncodes.noleftkern
+
+ local function applyaction(oc,v,n)
+ if oc == "noligature" then
+ if n > 0 then
+ local vv = v[n-1]
+ if vv then
+ v[n-1] = vv | norightligature_option
+ else
+ v[n-1] = norightligature_option
+ end
+ end
+ v[n] = noleftligature_option
+ elseif oc == "compound" then
+ if n > 1 then
+ -- v[n] = setcompound
+ v[n] = setcompounds[lh][rh]
+ return true
+ end
+ elseif oc == "nokern" then
+ if n > 0 then
+ local vv = v[n-1]
+ if vv then
+ v[n-1] = vv | norightkern_option
+ else
+ v[n-1] = norightkern_option
+ end
+ end
+ v[n] = noleftkern_option
+ elseif oc == "noleftkern" then
+ v[n] = noleftkern_option
+ elseif oc == "norightkern" then
+ if n > 0 then
+ local vv = v[n-1]
+ if vv then
+ v[n-1] = vv | norightkern_option
+ else
+ v[n-1] = norightkern_option
+ end
+ end
+ else
+ for s in gmatch(oc,"%w+") do
+ if applyaction(s,v,n) then
+ return
+ end
end
end
- v[n] = "noleftligature"
end
- local function analyzed(m,t,k)
+ -- a|b : a:norightligature b:noleftligature
+ -- a=b : a:norightkern b:noleftkern
+ -- a<b : b:noleftkern
+ -- a>b : a:norightkern
+ -- a+b : compound
+
+ local actions = {
+ ["|"] = "noligature",
+ ["="] = "nokern",
+ ["<"] = "noleftkern",
+ [">"] = "norightkern",
+ ["+"] = "compound",
+ }
+
+ local function analyzed(m,a,t,k)
local v = { }
local n = 1
if m == true then
for c in gmatch(k,".") do
- if c == "|" then
- blockligature(v,n)
- elseif c == "=" then
- v[n] = setcompound
- else
+ local ac = a[c]
+ if not ac then
n = n + 1
+ else
+ applyaction(ac,v,n)
end
end
elseif type(m) == "number" then
local i = 0
for c in gmatch(k,".") do
- if c == "|" then
- i = i + 1
- if i == m then
- blockligature(v,n)
- break
- end
- elseif c == "=" then
+ local ac = a[c]
+ if not ac then
+ n = n + 1
+ else
i = i + 1
if i == m then
- v[n] = setcompound
+ applyaction(ac,v,n)
break
end
- else
- n = n + 1
end
end
elseif type(m) == "table" then
+ -- happens here, otherwise no stable caching key, we could hash these too
+ m = tohash(m)
local i = 0
- m = table.tohash(m)
for c in gmatch(k,".") do
- if c == "|" then
- i = i + 1
- if m[i] then
- blockligature(v,n)
- end
- elseif c == "=" then
+ local ac = a[c]
+ if not ac then
+ n = n + 1
+ else
i = i + 1
if m[i] then
- v[n] = setcompound
+ applyaction(ac,v,n)
end
- else
- n = n + 1
end
end
else
@@ -902,26 +1085,87 @@ local flush_list = nuts.flush_list
end
local cache = setmetatableindex(function(t,m)
- local v = setmetatableindex(function(t,k)
- return analyzed(m,t,k)
+ local v = setmetatableindex(function(t,a)
+ local v = setmetatableindex(function(t,k)
+ return analyzed(m,a,t,k)
+ end)
+ t[m] = v
+ return v
end)
t[m] = v
return v
end)
- local replace1 = Cs ( ( S("|=")/"" + lpeg.patterns.utf8character )^0 )
- local replace2 = Cs ( ( S("|=") + lpeg.patterns.utf8character/".")^0 )
+ -- maybe also a skip symbol
+
+ local replace1 = Cs ( ( S("|=<>+.0123456789")/"" + lpegpatterns.utf8character )^0 )
+ local replace2 = Cs ( ( S("|=<>+.0123456789") + lpegpatterns.utf8character/".")^0 )
local function stripped(str)
- str = gsub(str,"[%-%%]+[^\n]+\n","")
+ -- todo : lpeg
+ str = gsub(str,"%-%-[^\n]+\n","")
+ str = gsub(str,"%%[^\n]+\n","")
str = gsub(str,"%s+"," ")
+ str = gsub(str,"^%s+","")
+ str = gsub(str,"%s+$","")
return str
end
+ local registerexceptions do
+
+ local lbrace = P("{")
+ local rbrace = P("}")
+ local lbracket = P("[")
+ local rbracket = P("]")
+ local lparent = P("(")
+ local rparent = P(")")
+ local hyphen = P("-")
+
+ local p = Cs ( (
+ lbrace * ((1-rbrace)^0) * rbrace
+ * lbrace * ((1-rbrace)^0) * rbrace
+ * lbrace * C((1-rbrace)^0) * rbrace * (lparent * C((1-rparent)^0) * rparent)^0 / function(a,b) return b or a end
+ + (lbracket * (1-rbracket)^0 * rbracket) / ""
+ + hyphen / ""
+ + lpegpatterns.utf8character
+ )^0 )
+
+ registerexceptions = function(target,str)
+ local kind = type(str)
+ if kind == "string" then
+ for v in gmatch(stripped(str),"%S+") do
+ local k = lpegmatch(p,v)
+ if k ~= v then
+ target[k] = v
+ end
+ end
+ elseif kind == "table" then
+ local n = #str
+ if n > 0 then
+ for i=1,n do
+ local v = str[i]
+ local k = lpegmatch(p,v)
+ if k ~= v then
+ target[k] = v
+ end
+ end
+ else
+ -- maybe check for sanity
+ for k, v in next, str do
+ target[k] = v
+ end
+ end
+ end
+ end
+
+ end
+
function languages.strippedgoodiewords(str)
return lpegmatch(replace1,stripped(str))
end
+ local splitter = lpeg.tsplitat(" ")
+
local function addgoodies(tag,list,filename)
local np = 0
local nd = 0
@@ -932,25 +1176,44 @@ local flush_list = nuts.flush_list
local properties = data.properties
local replacements = data.replacements
local characters = data.characters
+ local exceptions = data.exceptions
if filename then
if not data.goodies then
data.goodies = { }
end
- table.insert(data.goodies,filename)
+ insert(data.goodies,filename)
end
--
+ lh = false
+ rh = false
+ --
for i=1,nl do
local l = list[i]
if type(l) == "table" then
- local w = l.words
- local p = l.patterns
- local c = l.characters
+ local w = l.words
+ local p = l.patterns
+ local c = l.characters
+ local e = l.exceptions
+ lh = l.left or false -- for practical reasons these are semi-global
+ rh = l.right or false -- for practical reasons these are semi-global
if c then
for v in utfvalues(c) do
characters[v] = true
end
end
if w then
+ local prefixes = l.prefixes
+ local nofprefixes = 0
+ local suffixes = l.suffixes
+ local nofsuffixes = 0
+ if prefixes then
+ prefixes = lpegmatch(splitter,lower(stripped(prefixes)))
+ nofprefixes = #prefixes
+ end
+ if suffixes then
+ suffixes = lpegmatch(splitter,lower(stripped(suffixes)))
+ nofsuffixes = #suffixes
+ end
w = lower(stripped(w))
if p then
local pattern = Cs((utfchartabletopattern(p) / p + 1)^0)
@@ -959,19 +1222,72 @@ local flush_list = nuts.flush_list
else
nd = nd + 1
end
- local cach = cache[l.matches or true]
- for s in gmatch(w,"%S+") do
- properties[lpegmatch(replace1,s)] = cach[lpegmatch(replace2,s)]
- nw = nw + 1
+ local m = l.matches
+ if not m then
+ m = true
+ end
+ local a = l.actions
+ if a then
+ setmetatableindex(a,actions)
+ else
+ a = actions
+ end
+ local cach = cache[m][a]
+ if nofprefixes > 0 then
+ if nofsuffixes > 0 then
+ for wrd in gmatch(w,"%S+") do
+ properties[lpegmatch(replace1,wrd)] = cach[lpegmatch(replace2,wrd)]
+ nw = nw + 1
+ for i=1,nofprefixes do
+ local tmp = prefixes[i] .. wrd
+ for i=1,nofsuffixes do
+ local str = tmp .. suffixes[i]
+ properties[lpegmatch(replace1,str)] = cach[lpegmatch(replace2,str)]
+ nw = nw + 1
+ end
+ end
+ end
+ else
+ for wrd in gmatch(w,"%S+") do
+ properties[lpegmatch(replace1,wrd)] = cach[lpegmatch(replace2,wrd)]
+ nw = nw + 1
+ for i=1,nofprefixes do
+ local str = prefixes[i] .. wrd
+ properties[lpegmatch(replace1,str)] = cach[lpegmatch(replace2,str)]
+ nw = nw + 1
+ end
+ end
+ end
+ elseif nofsuffixes > 0 then
+ for wrd in gmatch(w,"%S+") do
+ properties[lpegmatch(replace1,wrd)] = cach[lpegmatch(replace2,wrd)]
+ nw = nw + 1
+ for i=1,nofsuffixes do
+ local str = wrd .. suffixes[i]
+ properties[lpegmatch(replace1,str)] = cach[lpegmatch(replace2,str)]
+ nw = nw + 1
+ end
+ end
+ else
+ for wrd in gmatch(w,"%S+") do
+ properties[lpegmatch(replace1,wrd)] = cach[lpegmatch(replace2,wrd)]
+ nw = nw + 1
+ end
end
elseif p then
for k, v in next, p do
-- todo: warning overload
replacements[k] = v
end
+ elseif e then
+ registerexceptions(exceptions,e)
end
end
end
+
+ lh = false
+ rh = false
+
return { np = np, nd = nd, nw = nw, nl = nl }
end
@@ -1156,6 +1472,12 @@ implement {
}
implement {
+ name = "setlanguagepatterns",
+ actions = languages.setpatterns,
+ arguments = "2 strings"
+}
+
+implement {
name = "setlanguageoptions",
actions = languages.setoptions,
arguments = "2 strings"
diff --git a/tex/context/base/mkxl/lang-ini.mkxl b/tex/context/base/mkxl/lang-ini.mkxl
index 6af61077b..c4a109f3b 100644
--- a/tex/context/base/mkxl/lang-ini.mkxl
+++ b/tex/context/base/mkxl/lang-ini.mkxl
@@ -740,10 +740,22 @@
\clf_setlanguageexceptions{\askedlanguage}{#2}%
\endgroup}
+\permanent\let\stoppatterns\relax
+
+\tolerant\permanent\protected\def\startpatterns[#1]#:#2\stoppatterns
+ {\begingroup
+ \edef\askedlanguage{\reallanguagetag{#1}}%
+ \ifempty\askedlanguage
+ \let\askedlanguage\currentlanguage
+ \fi
+ \clf_setlanguagepatterns{\askedlanguage}{#2}%
+ \endgroup}
+
+
\pushoverloadmode
-\permanent\protected\def\hyphenation
- {\clf_setlanguageexceptions{\currentlanguage}}
+\permanent\protected\def\hyphenation{\clf_setlanguageexceptions{\currentlanguage}}
+\permanent\protected\def\patterns {\clf_setlanguagepatterns {\currentlanguage}}
\popoverloadmode
diff --git a/tex/context/base/mkxl/lpdf-pde.lmt b/tex/context/base/mkxl/lpdf-pde.lmt
index 7fb14ada2..f8778f602 100644
--- a/tex/context/base/mkxl/lpdf-pde.lmt
+++ b/tex/context/base/mkxl/lpdf-pde.lmt
@@ -422,7 +422,7 @@ function resolvers.pages(document)
__xrefs__[pagedata] = pagereference
__cache__[pagereference] = pagedata
else
- report_epdf("missing pagedata for page %i, case %i",pagenumber,1)
+ report_epdf("missing pagedata for page %i, case %i",pagenumber,1)
end
else
report_epdf("missing pagedata for page %i, case %i",pagenumber,2)
diff --git a/tex/context/base/mkxl/mlib-svg.lmt b/tex/context/base/mkxl/mlib-svg.lmt
index e76580862..961176e07 100644
--- a/tex/context/base/mkxl/mlib-svg.lmt
+++ b/tex/context/base/mkxl/mlib-svg.lmt
@@ -2004,7 +2004,9 @@ local fraction = offset and asnumber_p(offset)
local o = at["stroke-opacity"] or (opacity and at["opacity"])
if o == "none" then
o = nil
- elseif o then
+ elseif o == "transparent" then
+ o = f_opacity(0)
+ else
o = asnumber_r(o)
if o == ignoredopacity then
o = nil
@@ -2112,7 +2114,7 @@ local fraction = offset and asnumber_p(offset)
end
end
end
- for c in xmlcollected(c,"(symbol|radialGradient|linearGradient") do
+ for c in xmlcollected(c,"(symbol|radialGradient|linearGradient)") do
local id = rawget(c.at,"id")
if id then
definitions["#" .. id ] = c
diff --git a/tex/context/base/mkxl/spac-ver.lmt b/tex/context/base/mkxl/spac-ver.lmt
index 2d4aace24..3e606552a 100644
--- a/tex/context/base/mkxl/spac-ver.lmt
+++ b/tex/context/base/mkxl/spac-ver.lmt
@@ -2233,19 +2233,20 @@ do
end
end
- local trace = false
- local last = nil
- local vmode_code = tex.modelevels.vertical
- local temp_code = nodecodes.temp
- local getnest = tex.getnest
- local getlist = tex.getlist
+ local trace = false
+ local last = nil
+ local vmode_code = tex.modelevels.vertical
+ local temp_code = nodecodes.temp
+ local texgetnest = tex.getnest
+ local texgetlist = tex.getlist
+ local getnodetail = nodes.tail
trackers.register("vspacing.forcestrutdepth",function(v) trace = v end)
-- abs : negative is inner
function vspacing.checkstrutdepth(depth)
- local nest = getnest()
+ local nest = texgetnest()
if abs(nest.mode) == vmode_code and nest.head then
local tail = nest.tail
local id = tail.id
@@ -2254,10 +2255,10 @@ do
tail.depth = depth
end
nest.prevdepth = depth
- elseif id == temp_code and getnest("ptr") == 0 then
- local head = getlist("page_head")
+ elseif id == temp_code and texgetnest("ptr") == 0 then
+ local head = texgetlist("page_head")
if head then
- tail = nodes.tail(head)
+ tail = getnodetail(head)
if tail and tail.id == hlist_code then
if tail.depth < depth then
tail.depth = depth
diff --git a/tex/context/base/mkxl/syst-ini.mkxl b/tex/context/base/mkxl/syst-ini.mkxl
index 45536d4e4..fb85531b7 100644
--- a/tex/context/base/mkxl/syst-ini.mkxl
+++ b/tex/context/base/mkxl/syst-ini.mkxl
@@ -1320,4 +1320,8 @@
\tracinglevels\plusthree
+%D We just report duplicate patterns being ignored:
+
+\tracinghyphenation\plusone
+
\protect \endinput
diff --git a/tex/context/base/mkxl/toks-aux.lmt b/tex/context/base/mkxl/toks-aux.lmt
index 03f4dc2c1..4f9ed7eb1 100644
--- a/tex/context/base/mkxl/toks-aux.lmt
+++ b/tex/context/base/mkxl/toks-aux.lmt
@@ -130,30 +130,19 @@ interfaces.implement {
local groupcodes = { }
local glyphoptioncodes = { }
+local discoptioncodes = { }
local hyphenationcodes = { }
local frozenparcodes = { }
local flagcodes = { }
local normalizecodes = { }
-for k, v in next, tex.getgroupvalues() do
- groupcodes[k] = gsub(v,"[_ ]","")
-end
-for k, v in next, tex.gethyphenationvalues() do
- hyphenationcodes[k] = gsub(v,"[_ ]","")
-end
-for k, v in next, tex.getglyphoptionvalues() do
- glyphoptioncodes[k] = gsub(v,"[_ ]","")
-end
-for k, v in next, tex.getfrozenparvalues() do
- frozenparcodes[k] = gsub(v,"[_ ]","")
-end
-for k, v in next, tex.getflagvalues() do
- flagcodes[k] = gsub(v,"[_ ]","")
-end
-for k, v in next, tex.getnormalizevalues() do
- normalizecodes[k] = gsub(v,"[_ ]","")
-end
-
+for k, v in next, tex.getgroupvalues() do groupcodes[k] = gsub(v,"[_ ]","") end
+for k, v in next, tex.gethyphenationvalues() do hyphenationcodes[k] = gsub(v,"[_ ]","") end
+for k, v in next, tex.getglyphoptionvalues() do glyphoptioncodes[k] = gsub(v,"[_ ]","") end
+for k, v in next, tex.getdiscoptionvalues() do discoptioncodes[k] = gsub(v,"[_ ]","") end
+for k, v in next, tex.getfrozenparvalues() do frozenparcodes[k] = gsub(v,"[_ ]","") end
+for k, v in next, tex.getflagvalues() do flagcodes[k] = gsub(v,"[_ ]","") end
+for k, v in next, tex.getnormalizevalues() do normalizecodes[k] = gsub(v,"[_ ]","") end
if environment.initex then
@@ -161,6 +150,7 @@ if environment.initex then
for k, v in next, groupcodes do texintegerdef(v .. "groupcode", k,"immutable") end
for k, v in next, glyphoptioncodes do texintegerdef(v .. "code", k,"immutable") end
+ for k, v in next, discoptioncodes do texintegerdef(v .. "code", k,"immutable") end
for k, v in next, hyphenationcodes do texintegerdef(v .. "hyphenationmodecode",k,"immutable") end
for k, v in next, frozenparcodes do texintegerdef("frozen" .. v .. "code", k,"immutable") end
for k, v in next, flagcodes do texintegerdef(v .. "flagcode", k,"immutable") end
@@ -170,6 +160,7 @@ end
groupcodes = utilities.storage.allocate(table.swapped(groupcodes, groupcodes))
glyphoptioncodes = utilities.storage.allocate(table.swapped(glyphoptioncodes,glyphoptioncodes))
+discoptioncodes = utilities.storage.allocate(table.swapped(discoptioncodes, discoptioncodes))
hyphenationcodes = utilities.storage.allocate(table.swapped(hyphenationcodes,hyphenationcodes))
frozenparcodes = utilities.storage.allocate(table.swapped(frozenparcodes, frozenparcodes))
flagcodes = utilities.storage.allocate(table.swapped(flagcodes, flagcodes))
@@ -177,6 +168,7 @@ normalizecodes = utilities.storage.allocate(table.swapped(normalizecodes,
tex.groupcodes = groupcodes
tex.glyphoptioncodes = glyphoptioncodes
+tex.discoptioncodes = discoptioncodes
tex.hyphenationcodes = hyphenationcodes
tex.frozenparcodes = frozenparcodes
tex.flagcodes = flagcodes
diff --git a/tex/context/modules/mkiv/s-languages-goodies.lmt b/tex/context/modules/mkiv/s-languages-goodies.lmt
index cb17680d1..7256fd35d 100644
--- a/tex/context/modules/mkiv/s-languages-goodies.lmt
+++ b/tex/context/modules/mkiv/s-languages-goodies.lmt
@@ -21,8 +21,20 @@ function moduledata.languages.goodies.show(specification)
local l = list[i]
local w = l.words
if w then
+ local pre = l.prefixes
+ local suf = l.suffixes
context.startsubject { title = table.concat(table.sortedkeys(l.patterns)," ") }
context(languages.strippedgoodiewords(w))
+ if pre then
+ context.blank()
+ context.bold("prefixes: ")
+ context(languages.strippedgoodiewords(pre))
+ end
+ if suf then
+ context.blank()
+ context.bold("suffixes: ")
+ context(languages.strippedgoodiewords(suf))
+ end
context.stopsubject()
end
end
@@ -30,3 +42,58 @@ function moduledata.languages.goodies.show(specification)
end
end
end
+
+local lpegmatch = lpeg.match
+
+moduledata.languages.goodies.ligaturehandlers = { }
+
+function moduledata.languages.goodies.ligatures(specification)
+
+ specification = interfaces.checkedspecification(specification)
+ local language = specification.language
+ local filename = specification.file
+
+ if not language then
+ elseif moduledata.languages.goodies.ligaturehandlers[language] then
+ else
+ -- fb ff ffb fff ffh ffi ffj ffk ffl fft fi fk fl ft
+ local list = specification.list or "ff fi fl ffi fff ffl"
+ local hash = table.tohash(lpeg.split(" ",list)) -- also strip
+ local pattern = (1-lpeg.utfchartabletopattern(hash))^1 * lpeg.P(-1)
+ local checked = { }
+
+ moduledata.languages.goodies.ligaturehandlers[language] = function(original)
+ if not checked[original] and not lpegmatch(pattern,original) then
+ checked[original] = true
+ end
+ return original
+ end
+
+ languages.installhandler(language,"moduledata.languages.goodies.ligaturehandlers." .. language .. "")
+
+ statistics.register(string.formatters["'% t' ligatures checked for language %a"](table.sortedkeys(hash), language), function()
+ return next(checked) and table.concat(table.sortedkeys(checked)," ") or nil
+ end)
+
+ local applied = languages.appliedoptions[language]
+
+ trackers.enable("languages.applied")
+
+ if applied then
+ statistics.register(string.formatters["options applied for language %a"](language), function()
+ return next(applied) and table.concat(table.sortedkeys(applied)," ") or nil
+ end)
+ statistics.register(string.formatters["missed ligatures for language %a"](language), function()
+ for k, v in next, applied do
+ checked[k] = nil
+ end
+ for k, v in next, hash do
+ checked[k] = nil
+ end
+ return next(checked) and table.concat(table.sortedkeys(checked)," ") or nil
+ end)
+ end
+
+ end
+
+end
diff --git a/tex/context/modules/mkiv/s-languages-goodies.mkxl b/tex/context/modules/mkiv/s-languages-goodies.mkxl
index b98df2c26..669a7b3b8 100644
--- a/tex/context/modules/mkiv/s-languages-goodies.mkxl
+++ b/tex/context/modules/mkiv/s-languages-goodies.mkxl
@@ -15,7 +15,8 @@
\registerctxluafile{s-languages-goodies}{autosuffix}
-\installmodulecommandluasingle \showlanguagegoodies {moduledata.languages.goodies.show}
+\installmodulecommandluasingle \showlanguagegoodies {moduledata.languages.goodies.show}
+\installmodulecommandluasingle \showlanguageligatures {moduledata.languages.goodies.ligatures}
\stopmodule
@@ -26,6 +27,7 @@
% \setupbodyfont[libertine]
\setuplanguage[de][goodies={lang-de.llg}]
+\setuplanguage[en][goodies={lang-en.llg}]
\mainlanguage[de]
@@ -35,6 +37,21 @@
% Zapf|innovation
% \stoplanguageoptions
+% \tracinghyphenation3 \tracingonline2
+
\starttext
- \showlanguagegoodies[file={lang-de.llg}]
+ \showlanguageligatures[language=de,list=ff fi fl fk ft fb ffi ffl fff ffk fft ffb ffh ffj]
+ \showlanguageligatures[language=en,list=ff fi fl fk ft fb ffi ffl fff ffk fft ffb ffh ffj]
+
+ \starttitle[title={DE}]
+ \start \de \showlanguagegoodies [file={lang-de.llg}] \stop
+ \stoptitle
+
+ \starttitle[title={EN}]
+ \start \en \showlanguagegoodies[file={lang-en.llg}] \stop
+ \stoptitle
+
+% oeps effe
+% nonexistentffitestcase
+% nonexistentffltestcase
\stoptext
diff --git a/tex/context/patterns/lmtx/lang-de.llg b/tex/context/patterns/lmtx/lang-de.llg
index 9e64eb3b1..db45d004c 100644
--- a/tex/context/patterns/lmtx/lang-de.llg
+++ b/tex/context/patterns/lmtx/lang-de.llg
@@ -10,6 +10,8 @@
-- users add stuff. The main reason is to deal with compound words (for which we have multiple
-- mechanisms) in a more automates way, using modern LMTX features. So this is not for MKIV (at least
-- not now). This mechanism can and will also deal with some other language issues.
+--
+-- https://typography.guru/journal/whats-a-ligature/
-- Comment : this is a starting point, not de definitve list of words
-- Todo : break down this list in more meaningfull categories (like 'matches')
@@ -575,7 +577,7 @@ return {
-- For Hans (an example of a compound word):
-- {
-- patterns = {
- -- ffl = "ff=l",
+ -- ffl = "ff+l",
-- },
-- words = [[
-- whatever=whatever
diff --git a/tex/context/patterns/lmtx/lang-en.llg b/tex/context/patterns/lmtx/lang-en.llg
new file mode 100644
index 000000000..5378e0aa9
--- /dev/null
+++ b/tex/context/patterns/lmtx/lang-en.llg
@@ -0,0 +1,453 @@
+-- The starting point of this list is a post at:
+--
+-- https://english.stackexchange.com/a/50957/22099
+-- https://english.stackexchange.com/questions/50660/when-should-i-not-use-a-ligature-in-english-typesetting
+-- mentioned on the ConTeXt mailing list after some discussion
+-- about this mechanism.
+
+return {
+ name = "english",
+ version = "1.00",
+ comment = "English ligature suppression",
+ author = "Mico Loretan, Dave Jarvis, & Hans Hagen",
+ copyright = "Public domain",
+ options = {
+ {
+ patterns = {
+ fi = "f|i",
+ fl = "f|l",
+ },
+ words = [[
+ -- f|i
+ deafish
+ dwarfish
+ elfish
+ oafish
+ selfish
+ serfish
+ unselfish
+ wolfish
+
+ -- f|l
+ beefless
+ briefless
+ hoofless
+ leafless
+ roofless
+ selfless
+ turfless
+ ]],
+ suffixes = [[
+ ness
+ ly
+ ]],
+ },
+ {
+ patterns = {
+ fi = "f|i",
+ },
+ words = [[
+ proofing
+ ]],
+ prefixes = [[
+ air
+ child
+ fire
+ flame
+ moth
+ rust
+ sound
+ water
+ weather
+ ]],
+ },
+ {
+ patterns = {
+ ff = "f|f",
+ fi = "f|i",
+ fl = "f|l",
+ ffi = "f|fi",
+ ffl = "f|fl",
+ },
+ words = [[
+ -- f|f
+ bookshelfful
+ mantelshelfful
+ shelfful
+
+ -- f|i
+ elfin
+
+ chafing
+ leafing
+ loafing
+ sheafing
+ strafing
+ vouchsafing
+ beefing
+ reefing
+ briefing
+ debriefing
+ coifing
+ fifing
+ jackknifing
+ knifing
+ midwifing
+ waifing
+ wifing
+
+ goofing
+ hoofing
+ roofing
+ reroofing
+ spoofing
+ whoofing
+ woofing
+
+ gulfing
+ begulfing
+ engulfing
+ ingulfing
+ golfing
+ gulfing
+ rolfing
+ selfing
+ wolfing
+ barfing
+ bedwarfing
+ dwarfing
+ enserfing
+ kerfing
+ scarfing
+ snarfing
+ surfing
+ windsurfing
+ turfing
+ wharfing
+
+ beefier
+ comfier
+ goofier
+ gulfier
+ leafier
+ surfier
+ turfier
+ beefiest
+ comfiest
+ goofiest
+ gulfiest
+ leafiest
+ surfiest
+ turfiest
+
+ beefily
+ goofily
+ goofiness
+
+ -- f|l
+ aloofly
+ briefly
+ chiefly
+ deafly
+ liefly
+
+ calflike
+ dwarflike
+ elflike
+ gulflike
+ hooflike
+ leaflike
+ rooflike
+ serflike
+ sheaflike
+ shelflike
+ surflike
+ turflike
+ waiflike
+ wolflike
+
+ halflife
+ shelflife
+ halfline
+ roofline
+
+ leaflet
+ leaflets
+ leafleted
+ leafleting
+ leafletting
+ leafletted
+ leafleteer
+
+ pdflatex
+
+ -- f|fi
+ chaffinch
+ wolffish
+
+ -- f|fl
+ safflower
+ safflowers
+ ]],
+ },
+ {
+ patterns = {
+ ffi = "ff|i",
+ },
+ words = [[
+ -- ff|i
+ cuffing
+ ]],
+ prefixes = [[
+ hand
+ un
+ ]],
+ },
+ {
+ patterns = {
+ ffi = "ff|i",
+ },
+ words = [[
+ -- ff|i
+ feoffing
+ ]],
+ prefixes = [[
+ en
+ in
+ ]],
+ },
+ {
+ patterns = {
+ ffi = "ff|i",
+ },
+ words = [[
+ -- ff|i
+ staffing
+ stuffing
+ ]],
+ prefixes = [[
+ re
+ over
+ under
+ ]],
+ },
+ {
+ patterns = {
+ ffi = "ff|i",
+ },
+ words = [[
+ -- ff|i
+ ruffing
+ ]],
+ prefixes = [[
+ cross
+ over
+ under
+ ]],
+ },
+ {
+ patterns = {
+ ffi = "ff|i",
+ ffl = "ff|l",
+ },
+ words = [[
+ -- ff|i
+ draffish
+ giraffish
+ gruffish
+ offish
+ raffish
+ sniffish
+ standoffish
+ stiffish
+ toffish
+
+ -- ff|l
+ cuffless
+ stuffless
+ ]],
+ suffixes = [[
+ ly
+ ]],
+ },
+ {
+ patterns = {
+ ffl = "ff|l",
+ },
+ words = [[
+ -- ff|l
+ scofflaw
+ cufflink
+ offline
+ offload
+ ]],
+ suffixes = [[
+ s
+ ed
+ ing
+ ]],
+ },
+ {
+ patterns = {
+ ffi = "ff|i",
+ ffl = "ff|l",
+ },
+ words = [[
+ -- ff|i
+ baffing
+ biffing
+ boffing
+ bluffing
+ outbluffing
+ buffing
+ rebuffing
+ chaffing
+ cheffing
+ chuffing
+ coffing
+ coiffing
+ daffing
+ doffing
+ fluffing
+ gaffing
+ gruffing
+ huffing
+ luffing
+ miffing
+ muffing
+ offing
+ piaffing
+ puffing
+ quaffing
+ reffing
+ riffing
+ sclaffing
+ scoffing
+ scuffing
+ shroffing
+ sluffing
+ sniffing
+ snuffing
+ spiffing
+ stiffing
+ stuffing
+ tariffing
+ tiffing
+ waffing
+ whiffing
+ yaffing
+
+ buffier
+ chaffier
+ chuffier
+ cliffier
+ daffier
+ fluffier
+ gruffier
+ huffier
+ iffier
+ miffier
+ puffier
+ scruffier
+ sniffier
+ snuffier
+ spiffier
+ stuffier
+ buffiest
+ chaffiest
+ chuffiest
+ cliffiest
+ daffiest
+ fluffiest
+ gruffiest
+ huffiest
+ iffiest
+ miffiest
+ puffiest
+ scruffiest
+ sniffiest
+ snuffiest
+ spiffiest
+ stuffiest
+
+ daffily
+ fluffily
+ gruffily
+ huffily
+ puffily
+ scruffily
+ sniffily
+ snuffily
+ spiffily
+ stuffily
+
+ fluffiness
+ huffiness
+ iffiness
+ puffiness
+ scruffiness
+ sniffiness
+ spiffiness
+ stuffiness
+
+ baffies
+ biffies
+ jiffies
+ taffies
+ toffies
+
+ waffie
+
+ Pfaffian
+ Wolffian
+ Wulffian
+
+ -- ff|l
+ bluffly
+ gruffly
+ ruffly
+ snuffly
+ stiffly
+
+ rufflike
+ clifflike
+ ]],
+ },
+ {
+ patterns = {
+ ft = "f|t",
+ fft = "ff|t",
+ },
+ words = [[
+ -- f|t
+ chieftain
+ chieftains
+ chieftaincy
+ chieftainship
+
+ fifteen
+ fifteens
+ fifteenth
+ fifteenths
+ fifth
+ fifthly
+ fifths
+ fifties
+ fiftieth
+ fiftieths
+ fifty
+ fiftyish
+
+ halftime
+ halftone
+
+ rooftop
+ rooftops
+ rooftree
+
+ -- ff|t
+ offtrack
+ ]]
+ }
+ }
+}
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 14c50d6b7..868d224f3 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
-- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
-- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date : 2021-03-31 18:00
+-- merge date : 2021-04-09 19:54
do -- begin closure to overcome local limits and interference
@@ -28572,105 +28572,225 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
goto next
end
local s=seq.n
- local l=ck[5]
- local current=start
- local last=start
if s==1 then
- goto next
- end
- if l>f then
- local discfound
- local n=f+1
- last=startnext
- while n<=l do
- if postreplace and not last then
- last=getnext(sweepnode)
- sweeptype=nil
- end
- if last then
- local char,id=ischar(last,currentfont)
- if char then
- if skiphash and skiphash[char] then
- skipped=true
- if trace_skips then
- show_skip(dataset,sequence,char,ck,classes[char])
- end
- last=getnext(last)
- elseif seq[n][char] then
- if n<l then
+ else
+ local l=ck[5]
+ local current=start
+ local last=start
+ if l>f then
+ local discfound
+ local n=f+1
+ last=startnext
+ while n<=l do
+ if postreplace and not last then
+ last=getnext(sweepnode)
+ sweeptype=nil
+ end
+ if last then
+ local char,id=ischar(last,currentfont)
+ if char then
+ if skiphash and skiphash[char] then
+ skipped=true
+ if trace_skips then
+ show_skip(dataset,sequence,char,ck,classes[char])
+ end
last=getnext(last)
- end
- n=n+1
- elseif discfound then
- notmatchreplace[discfound]=true
- if notmatchpre[discfound] then
- goto next
+ elseif seq[n][char] then
+ if n<l then
+ last=getnext(last)
+ end
+ n=n+1
+ elseif discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpre[discfound] then
+ goto next
+ else
+ break
+ end
else
- break
- end
- else
- goto next
- end
- elseif char==false then
- if discfound then
- notmatchreplace[discfound]=true
- if notmatchpre[discfound] then
goto next
+ end
+ elseif char==false then
+ if discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpre[discfound] then
+ goto next
+ else
+ break
+ end
else
- break
+ goto next
end
- else
- goto next
- end
- elseif id==disc_code then
- discseen=true
- discfound=last
- notmatchpre[last]=nil
- notmatchpost[last]=true
- notmatchreplace[last]=nil
- local pre,post,replace=getdisc(last)
- if pre then
- local n=n
- while pre do
- if seq[n][getchar(pre)] then
- n=n+1
- if n>l then
+ elseif id==disc_code then
+ discseen=true
+ discfound=last
+ notmatchpre[last]=nil
+ notmatchpost[last]=true
+ notmatchreplace[last]=nil
+ local pre,post,replace=getdisc(last)
+ if pre then
+ local n=n
+ while pre do
+ if seq[n][getchar(pre)] then
+ n=n+1
+ if n>l then
+ break
+ end
+ pre=getnext(pre)
+ else
+ notmatchpre[last]=true
break
end
- pre=getnext(pre)
- else
+ end
+ if n<=l then
notmatchpre[last]=true
- break
end
- end
- if n<=l then
+ else
notmatchpre[last]=true
end
+ if replace then
+ while replace do
+ if seq[n][getchar(replace)] then
+ n=n+1
+ if n>l then
+ break
+ end
+ replace=getnext(replace)
+ else
+ notmatchreplace[last]=true
+ if notmatchpre[last] then
+ goto next
+ else
+ break
+ end
+ end
+ end
+ if notmatchpre[last] then
+ goto next
+ end
+ end
+ last=getnext(last)
else
- notmatchpre[last]=true
+ goto next
end
- if replace then
- while replace do
- if seq[n][getchar(replace)] then
- n=n+1
- if n>l then
- break
+ else
+ goto next
+ end
+ end
+ end
+ if f>1 then
+ if startprev then
+ local prev=startprev
+ if prereplace and prev==checkdisc then
+ prev=getprev(sweepnode)
+ end
+ if prev then
+ local discfound
+ local n=f-1
+ while n>=1 do
+ if prev then
+ local char,id=ischar(prev,currentfont)
+ if char then
+ if skiphash and skiphash[char] then
+ skipped=true
+ if trace_skips then
+ show_skip(dataset,sequence,char,ck,classes[char])
+ end
+ prev=getprev(prev)
+ elseif seq[n][char] then
+ if n>1 then
+ prev=getprev(prev)
+ end
+ n=n-1
+ elseif discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpost[discfound] then
+ goto next
+ else
+ break
+ end
+ else
+ goto next
end
- replace=getnext(replace)
- else
- notmatchreplace[last]=true
- if notmatchpre[last] then
+ elseif char==false then
+ if discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpost[discfound] then
+ goto next
+ end
+ else
goto next
+ end
+ break
+ elseif id==disc_code then
+ discseen=true
+ discfound=prev
+ notmatchpre[prev]=true
+ notmatchpost[prev]=nil
+ notmatchreplace[prev]=nil
+ local pre,post,replace,pretail,posttail,replacetail=getdisc(prev,true)
+ if pre~=start and post~=start and replace~=start then
+ if post then
+ local n=n
+ while posttail do
+ if seq[n][getchar(posttail)] then
+ n=n-1
+ if posttail==post or n<1 then
+ break
+ else
+ posttail=getprev(posttail)
+ end
+ else
+ notmatchpost[prev]=true
+ break
+ end
+ end
+ if n>=1 then
+ notmatchpost[prev]=true
+ end
+ else
+ notmatchpost[prev]=true
+ end
+ if replace then
+ while replacetail do
+ if seq[n][getchar(replacetail)] then
+ n=n-1
+ if replacetail==replace or n<1 then
+ break
+ else
+ replacetail=getprev(replacetail)
+ end
+ else
+ notmatchreplace[prev]=true
+ if notmatchpost[prev] then
+ goto next
+ else
+ break
+ end
+ end
+ end
+ else
+ end
+ end
+ prev=getprev(prev)
+ elseif id==glue_code then
+ local sn=seq[n]
+ if (sn[32] and spaces[prev]) or sn[0xFFFC] then
+ n=n-1
+ prev=getprev(prev)
else
- break
+ goto next
end
+ elseif seq[n][0xFFFC] then
+ n=n-1
+ prev=getprev(prev)
+ else
+ goto next
end
- end
- if notmatchpre[last] then
+ else
goto next
end
end
- last=getnext(last)
else
goto next
end
@@ -28678,34 +28798,32 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
goto next
end
end
- end
- if f>1 then
- if startprev then
- local prev=startprev
- if prereplace and prev==checkdisc then
- prev=getprev(sweepnode)
+ if s>l then
+ local current=last and getnext(last)
+ if not current and postreplace then
+ current=getnext(sweepnode)
end
- if prev then
+ if current then
local discfound
- local n=f-1
- while n>=1 do
- if prev then
- local char,id=ischar(prev,currentfont)
+ local n=l+1
+ while n<=s do
+ if current then
+ local char,id=ischar(current,currentfont)
if char then
if skiphash and skiphash[char] then
skipped=true
if trace_skips then
show_skip(dataset,sequence,char,ck,classes[char])
end
- prev=getprev(prev)
+ current=getnext(current)
elseif seq[n][char] then
- if n>1 then
- prev=getprev(prev)
+ if n<s then
+ current=getnext(current)
end
- n=n-1
+ n=n+1
elseif discfound then
notmatchreplace[discfound]=true
- if notmatchpost[discfound] then
+ if notmatchpre[discfound] then
goto next
else
break
@@ -28716,202 +28834,84 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
elseif char==false then
if discfound then
notmatchreplace[discfound]=true
- if notmatchpost[discfound] then
+ if notmatchpre[discfound] then
goto next
+ else
+ break
end
else
goto next
end
- break
elseif id==disc_code then
discseen=true
- discfound=prev
- notmatchpre[prev]=true
- notmatchpost[prev]=nil
- notmatchreplace[prev]=nil
- local pre,post,replace,pretail,posttail,replacetail=getdisc(prev,true)
- if pre~=start and post~=start and replace~=start then
- if post then
- local n=n
- while posttail do
- if seq[n][getchar(posttail)] then
- n=n-1
- if posttail==post or n<1 then
- break
- else
- posttail=getprev(posttail)
- end
- else
- notmatchpost[prev]=true
+ discfound=current
+ notmatchpre[current]=nil
+ notmatchpost[current]=true
+ notmatchreplace[current]=nil
+ local pre,post,replace=getdisc(current)
+ if pre then
+ local n=n
+ while pre do
+ if seq[n][getchar(pre)] then
+ n=n+1
+ if n>s then
break
+ else
+ pre=getnext(pre)
end
+ else
+ notmatchpre[current]=true
+ break
end
- if n>=1 then
- notmatchpost[prev]=true
- end
- else
- notmatchpost[prev]=true
end
- if replace then
- while replacetail do
- if seq[n][getchar(replacetail)] then
- n=n-1
- if replacetail==replace or n<1 then
- break
- else
- replacetail=getprev(replacetail)
- end
+ if n<=s then
+ notmatchpre[current]=true
+ end
+ else
+ notmatchpre[current]=true
+ end
+ if replace then
+ while replace do
+ if seq[n][getchar(replace)] then
+ n=n+1
+ if n>s then
+ break
else
- notmatchreplace[prev]=true
- if notmatchpost[prev] then
- goto next
- else
- break
- end
+ replace=getnext(replace)
+ end
+ else
+ notmatchreplace[current]=true
+ if notmatchpre[current] then
+ goto next
+ else
+ break
end
end
- else
end
+ else
end
- prev=getprev(prev)
+ current=getnext(current)
elseif id==glue_code then
local sn=seq[n]
- if (sn[32] and spaces[prev]) or sn[0xFFFC] then
- n=n-1
- prev=getprev(prev)
+ if (sn[32] and spaces[current]) or sn[0xFFFC] then
+ n=n+1
+ current=getnext(current)
else
goto next
end
elseif seq[n][0xFFFC] then
- n=n-1
- prev=getprev(prev)
- else
- goto next
- end
- else
- goto next
- end
- end
- else
- goto next
- end
- else
- goto next
- end
- end
- if s>l then
- local current=last and getnext(last)
- if not current and postreplace then
- current=getnext(sweepnode)
- end
- if current then
- local discfound
- local n=l+1
- while n<=s do
- if current then
- local char,id=ischar(current,currentfont)
- if char then
- if skiphash and skiphash[char] then
- skipped=true
- if trace_skips then
- show_skip(dataset,sequence,char,ck,classes[char])
- end
- current=getnext(current)
- elseif seq[n][char] then
- if n<s then
- current=getnext(current)
- end
- n=n+1
- elseif discfound then
- notmatchreplace[discfound]=true
- if notmatchpre[discfound] then
- goto next
- else
- break
- end
- else
- goto next
- end
- elseif char==false then
- if discfound then
- notmatchreplace[discfound]=true
- if notmatchpre[discfound] then
- goto next
- else
- break
- end
- else
- goto next
- end
- elseif id==disc_code then
- discseen=true
- discfound=current
- notmatchpre[current]=nil
- notmatchpost[current]=true
- notmatchreplace[current]=nil
- local pre,post,replace=getdisc(current)
- if pre then
- local n=n
- while pre do
- if seq[n][getchar(pre)] then
- n=n+1
- if n>s then
- break
- else
- pre=getnext(pre)
- end
- else
- notmatchpre[current]=true
- break
- end
- end
- if n<=s then
- notmatchpre[current]=true
- end
- else
- notmatchpre[current]=true
- end
- if replace then
- while replace do
- if seq[n][getchar(replace)] then
- n=n+1
- if n>s then
- break
- else
- replace=getnext(replace)
- end
- else
- notmatchreplace[current]=true
- if notmatchpre[current] then
- goto next
- else
- break
- end
- end
- end
- else
- end
- current=getnext(current)
- elseif id==glue_code then
- local sn=seq[n]
- if (sn[32] and spaces[current]) or sn[0xFFFC] then
n=n+1
current=getnext(current)
else
goto next
end
- elseif seq[n][0xFFFC] then
- n=n+1
- current=getnext(current)
else
goto next
end
- else
- goto next
end
+ else
+ goto next
end
- else
- goto next
end
end
if trace_contexts then