diff options
Diffstat (limited to 'tex/context/base/mkiv/font-osd.lua')
-rw-r--r-- | tex/context/base/mkiv/font-osd.lua | 473 |
1 files changed, 349 insertions, 124 deletions
diff --git a/tex/context/base/mkiv/font-osd.lua b/tex/context/base/mkiv/font-osd.lua index a4d408e13..1bdd20fd9 100644 --- a/tex/context/base/mkiv/font-osd.lua +++ b/tex/context/base/mkiv/font-osd.lua @@ -6,7 +6,6 @@ if not modules then modules = { } end modules ['font-osd'] = { -- script devanag license = "see context related readme files" } - -- we need to check nbsphash (context only) -- A few remarks: @@ -81,8 +80,10 @@ if not modules then modules = { } end modules ['font-osd'] = { -- script devanag -- malayalam, oriya, tamil and tolugu but not all are checked. Also, some of the -- code below might need to be adapted to the extra scripts. -local insert, imerge, copy, tohash = table.insert, table.imerge, table.copy, table.tohash -local next, type = next, type +local insert, remove, imerge, copy, tohash = table.insert, table.remove, table.imerge, table.copy, table.tohash +local next, type, rawget = next, type, rawget +local formatters = string.formatters +local settings_to_hash = utilities.parsers.settings_to_hash local report = logs.reporter("otf","devanagari") @@ -98,6 +99,8 @@ local methods = fonts.analyzers.methods local otffeatures = fonts.constructors.features.otf local registerotffeature = otffeatures.register +local trace_steps = false + local nuts = nodes.nuts local getnext = nuts.getnext @@ -130,7 +133,7 @@ local unsetvalue = attributes.unsetvalue local fontdata = fonts.hashes.identifiers -local a_syllabe = "syllable" -- attributes.private('syllabe') -- can be just a property key +local a_syllabe = "syllable" -- attributes.private('syllabe') -- can be just a property key local a_reordered = "reordered" -- attributes.private('reordered') -- can be just a property key local dotted_circle = 0x25CC @@ -157,9 +160,14 @@ replace_all_nbsp = function(head) -- delayed definition end local processcharacters = nil +local logprocess = nil if context then - local fontprocesses = fonts.hashes.processes + + local fontprocesses = fonts.hashes.processes + local tracers = nodes.tracers + local registermessage = (tracers and tracers.steppers.message) or function() end + function processcharacters(head,font) local processors = fontprocesses[font] for i=1,#processors do @@ -167,7 +175,24 @@ if context then end return head end + + -- When we'retrying to fix something it can be handy to have some more + -- details available. + + trackers.register("otf.steps", function(v) trace_steps = v end) + + logprocess = function(str) + if trace_steps then + registermessage("devanagari %s",str) + if trace_steps == "silent" then + return + end + end + report(str) + end + else + function processcharacters(head,font) local processors = fontdata[font].shared.processes for i=1,#processors do @@ -175,6 +200,11 @@ else end return head end + + logprocess = function(str) + -- do nothing + end + end -- We can assume that script are not mixed in the source but if that is the case @@ -303,7 +333,7 @@ local after_subscript = indicgroups.after_subscript local before_main = indicgroups.before_main local after_main = indicgroups.after_main -local mark_four = table.merged ( +local mark_pre_above_below_post = table.merged ( pre_mark, above_mark, below_mark, @@ -316,6 +346,14 @@ local mark_above_below_post = table.merged ( post_mark ) +-- Handy + +local devanagarihash = table.setmetatableindex(function(t,k) + local v = fontdata[k].resources.devanagari or false + t[k] = v + return v +end) + -- We use some pseudo features as we need to manipulate the nodelist based -- on information in the font as well as already applied features. We can -- probably replace some of the code below by injecting 'real' features @@ -461,7 +499,7 @@ local function initializedevanagi(tfmdata) local devanagari = resources.devanagari if not devanagari then -- - report("adding devanagari features to font") + report("adding features to font") -- local gsubfeatures = resources.features.gsub local sequences = resources.sequences @@ -492,7 +530,9 @@ local function initializedevanagi(tfmdata) for k, v in next, pre_mark do local locl = coverage[k] if locl then - if #locl > 0 then --contextchain; KE: is this right? + -- if #locl > 0 then we have a list otherwise a hash; we actually should + -- test properly for gsub_... + if #locl > 0 then for j=1,#locl do local ck = locl[j] local f = ck[4] @@ -513,6 +553,8 @@ local function initializedevanagi(tfmdata) end end end + else + -- useless next if, because locl is a table end if locl then reorder_matras.steps[1].coverage[locl] = true @@ -525,7 +567,7 @@ local function initializedevanagi(tfmdata) if basic_shaping_forms[k] then lastmatch = lastmatch + 1 if s ~= lastmatch then - table.insert(sequences, lastmatch, table.remove(sequences, s)) + insert(sequences,lastmatch,remove(sequences,s)) end end end @@ -546,9 +588,7 @@ local function initializedevanagi(tfmdata) local vatucache = { } local pstfcache = { } local seqsubset = { } - local rephstep = { - coverage = { } -- will be adapted each work - } + local rephstep = { coverage = { } } -- will be adapted each work local devanagari = { reph = false, vattu = false, @@ -578,7 +618,7 @@ local function initializedevanagi(tfmdata) local has_pstf = features.pstf if has_rphf and has_rphf[script] then devanagari.reph = true - elseif (has_blwf and has_blwf[script] ) or (has_vatu and has_vatu[script] ) then + elseif (has_blwf and has_blwf[script]) or (has_vatu and has_vatu[script]) then devanagari.vattu = true for i=1,nofsteps do local step = steps[i] @@ -586,10 +626,8 @@ local function initializedevanagi(tfmdata) if coverage then for k, v in next, coverage do for h, w in next, halant do - if v[h] then - if not blwfcache[k] then - blwfcache[k] = v - end + if v[h] and not blwfcache[k] then + blwfcache[k] = v end if has_vatu and has_vatu[script] and not vatucache[k] then vatucache[k] = v @@ -611,35 +649,40 @@ local function initializedevanagi(tfmdata) for k, v in next, ra do local r = coverage[k] if r then + -- if #r > 0 then we have a list otherwise a hash; we actually should + -- test properly for gsub_... local found = false - if #r > 0 then -- contextchain; KE: is this right? + if #r > 0 then for j=1,#r do - local ck = r[j] - local f = ck[4] + local ck = r[j] + local f = ck[4] local chainlookups = ck[6] - if chainlookups and chainlookups[f] then --KE: why is check for chainlookups[f] necessacy??? + if chainlookups then local chainlookup = chainlookups[f] - for j=1,#chainlookup do - local chainstep = chainlookup[j] - local steps = chainstep.steps - local nofsteps = chainstep.nofsteps - for i=1,nofsteps do - local step = steps[i] - local coverage = step.coverage - if coverage then - local h = coverage[k] - if h then - for k, v in next, h do - -- found = v and v.ligature - found = v and (tonumber(v) or v.ligature) + if chainlookup then + for j=1,#chainlookup do + local chainstep = chainlookup[j] + local steps = chainstep.steps + local nofsteps = chainstep.nofsteps + for i=1,nofsteps do + local step = steps[i] + local coverage = step.coverage + if coverage then + local h = coverage[k] + if h then + for k, v in next, h do + if v then + found = tonumber(v) or v.ligature + if found then + pre_base_reordering_consonants[found] = true + break + end + end + end if found then - pre_base_reordering_consonants[found] = true break end end - if found then - break - end end end end @@ -648,11 +691,12 @@ local function initializedevanagi(tfmdata) end else for k, v in next, r do - -- found = v and v.ligature - found = v and (tonumber(v) or v.ligature) - if found then - pre_base_reordering_consonants[found] = true - break + if v then + found = tonumber(v) or v.ligature + if found then + pre_base_reordering_consonants[found] = true + break + end end end end @@ -670,18 +714,21 @@ local function initializedevanagi(tfmdata) local step = steps[i] local coverage = step.coverage if coverage then - local reph, rephbase = false, false + local reph = false + local base = false if kind == "rphf" then -- rphf acts on consonant + halant for k, v in next, ra do local r = coverage[k] if r then - rephbase = k + -- if #r > 0 then we have a list otherwise a hash; we actually should + -- test properly for gsub_... + base = k local h = false - if #r > 0 then --contextchain; KE: is this right? + if #r > 0 then for j=1,#r do - local ck = r[j] - local f = ck[4] + local ck = r[j] + local f = ck[4] local chainlookups = ck[6] if chainlookups then local chainlookup = chainlookups[f] @@ -698,7 +745,6 @@ local function initializedevanagi(tfmdata) for k, v in next, halant do local h = r[k] if h then - -- reph = h.ligature or false reph = tonumber(h) or h.ligature or false break end @@ -716,7 +762,6 @@ local function initializedevanagi(tfmdata) for k, v in next, halant do local h = r[k] if h then - -- reph = h.ligature or false reph = tonumber(h) or h.ligature or false break end @@ -728,7 +773,9 @@ local function initializedevanagi(tfmdata) end end end - seqsubset[#seqsubset+1] = { kind, coverage, reph, rephbase } +-- if reph then + seqsubset[#seqsubset+1] = { kind, coverage, reph, base } +-- end end end end @@ -742,18 +789,20 @@ local function initializedevanagi(tfmdata) for k, v in next, halant do local h = coverage[k] if h then + -- if #h > 0 then we have a list otherwise a hash; we actually should + -- test properly for gsub_... local found = false - if #h > 0 then -- contextchain; KE: is this right? + if #h > 0 then for j=1,#h do - local ck = h[j] - local f = ck[4] + local ck = h[j] + local f = ck[4] local chainlookups = ck[6] if chainlookups then local chainlookup = chainlookups[f] for j=1,#chainlookup do local chainstep = chainlookup[j] - local steps = chainstep.steps - local nofsteps = chainstep.nofsteps + local steps = chainstep.steps + local nofsteps = chainstep.nofsteps for i=1,nofsteps do local step = steps[i] local coverage = step.coverage @@ -761,11 +810,12 @@ local function initializedevanagi(tfmdata) local h = coverage[k] if h then for k, v in next, h do - -- found = v and v.ligature - found = v and (tonumber(v) or v.ligature) - if found then - pre_base_reordering_consonants[found] = true - break + if v then + found = tonumber(v) or v.ligature + if found then + pre_base_reordering_consonants[found] = true + break + end end end if found then @@ -779,7 +829,6 @@ local function initializedevanagi(tfmdata) end else for k, v in next, h do - -- found = v and v.ligature found = v and (tonumber(v) or v.ligature) if found then pre_base_reordering_consonants[found] = true @@ -807,9 +856,9 @@ local function initializedevanagi(tfmdata) sharedfeatures["dv03"] = true -- dv03_reorder_pre_base_reordering_consonants sharedfeatures["dv04"] = true -- dv04_remove_joiners end - if script == "mlym" or script == "taml" then - devanagari.left_matra_before_base = true - end + -- if script == "mlym" or script == "taml" then + -- devanagari.movematra = "leftbeforebase" + -- end end end end @@ -823,6 +872,56 @@ registerotffeature { }, } +local function initializeconjuncts(tfmdata,value) + if value then + local resources = tfmdata.resources + local devanagari = resources.devanagari + if devanagari then + local conjuncts = "auto" + local conjuncts = "continue" + local movematra = "auto" + if type(value) == "string" and value ~= "auto" then + value = settings_to_hash(value) + conjuncts = rawget(value,"conjuncts") or conjuncts + movematra = rawget(value,"movematra") or movematra + end + if conjuncts == "auto" then + conjuncts = "continue" + -- maybe some day we can figure out bad-fonts logic + -- if script == "mlym" or script == "mlm2" or + -- script == "taml" or script == "tml2" then + -- conjuncts = "continue" + -- else + -- conjuncts = "quit" + -- end + end + if movematra == "auto" and + script == "mlym" or + script == "taml" then + movematra = "leftbeforebase" + else + movematra = "default" + end + devanagari.conjuncts = conjuncts + devanagari.movematra = movematra + -- +-- if trace_steps then + report("conjuncts %a, movematra %a",conjuncts,movematra) +-- end + -- + end + end +end + +registerotffeature { + name = "indic", + description = "control indic", + default = "auto", + initializers = { + node = initializeconjuncts, + }, +} + local show_syntax_errors = false local function inject_syntax_error(head,current,char) @@ -883,7 +982,7 @@ end -- HH: somehow we can get a non context here so for now we check for .n -local function contextchain(contexts, n) +local function contextchain(contexts,n) local char = getchar(n) if not contexts.n then return contexts[char] @@ -950,11 +1049,13 @@ local function order_matras(c) end end +local swapped = table.swapped(states) + local function reorder_one(head,start,stop,font,attr,nbspaces) local reph, vattu, blwfcache, vatucache, pstfcache = initialize_one(font,attr) -- todo: a hash[font] - local devanagari = fontdata[font].resources.devanagari + -- local devanagari = devanagarihash[font] local current = start local n = getnext(start) local base = nil @@ -982,6 +1083,9 @@ local function reorder_one(head,start,stop,font,attr,nbspaces) stop = getprev(stop) head = remove_node(head,current) flushnode(current) + if trace_steps then + logprocess("reorder one, remove nbsp") + end return head, stop, nbspaces else nbspaces = nbspaces + 1 @@ -1025,6 +1129,9 @@ local function reorder_one(head,start,stop,font,attr,nbspaces) stop = current end end + if trace_steps then + logprocess("reorder one, handle nbsp") + end end end end @@ -1086,6 +1193,9 @@ local function reorder_one(head,start,stop,font,attr,nbspaces) if lastcons == stop then stop = n end + if trace_steps then + logprocess("reorder one, handle halant") + end end end @@ -1115,6 +1225,9 @@ local function reorder_one(head,start,stop,font,attr,nbspaces) if matra == stop then stop = n end + if trace_steps then + logprocess("reorder one, handle matra") + end end local current = start @@ -1161,14 +1274,19 @@ local function reorder_one(head,start,stop,font,attr,nbspaces) end local tpm = twopart_mark[ch] - while tpm do - local extra = copy_node(n) - copyinjection(extra,n) - ch = tpm[1] - setchar(n,ch) - setchar(extra,tpm[2]) - head = insertnodeafter(head,current,extra) - tpm = twopart_mark[ch] + if tpm then + while tpm do + local extra = copy_node(n) + copyinjection(extra,n) + ch = tpm[1] + setchar(n,ch) + setchar(extra,tpm[2]) + head = insertnodeafter(head,current,extra) + tpm = twopart_mark[ch] + end + if trace_steps then + logprocess("reorder one, handle mark") + end end while c ~= stop and dependent_vowel[ch] do c = n @@ -1191,10 +1309,11 @@ local function reorder_one(head,start,stop,font,attr,nbspaces) local bp = getprev(firstcons) local cn = getnext(current) local last = getnext(c) + local done = false while cn ~= last do -- move pre-base matras... if pre_mark[getchar(cn)] then - if devanagari.left_matra_before_base then + if devanagarihash[font].movematra == "leftbeforebase" then local prev, next = getboth(cn) setlink(prev,next) if cn == stop then @@ -1232,6 +1351,7 @@ local function reorder_one(head,start,stop,font,attr,nbspaces) end cn = next end + done = true elseif current ~= base and dependent_vowel[getchar(cn)] then local prev, next = getboth(cn) if next then @@ -1244,6 +1364,7 @@ local function reorder_one(head,start,stop,font,attr,nbspaces) setlink(b,cn,getnext(b)) order_matras(cn) cn = next + done = true elseif current == base and dependent_vowel[getchar(cn)] then local cnn = getnext(cn) order_matras(cn) @@ -1257,10 +1378,15 @@ local function reorder_one(head,start,stop,font,attr,nbspaces) end allreordered = c == stop current = getnext(c) + if done and trace_steps then + logprocess("reorder one, matra") + end end if reph or vattu then - local current, cns = start, nil + local current = start + local cns = nil + local done = false while current ~= stop do local c = current local n = getnext(current) @@ -1293,6 +1419,7 @@ local function reorder_one(head,start,stop,font,attr,nbspaces) local next = getnext(b) setlink(c,next) setlink(b,current) + done = true end elseif cns and getnext(cns) ~= current then -- todo: optimize next -- position below-base Ra (vattu) following the consonants on which it is placed (either the base consonant or one of the pre-base consonants) @@ -1301,6 +1428,7 @@ local function reorder_one(head,start,stop,font,attr,nbspaces) setlink(cp,n) setlink(cns,current) -- cns ? setlink(c,cnsn) + done = true if c == stop then stop = cp break @@ -1340,6 +1468,9 @@ local function reorder_one(head,start,stop,font,attr,nbspaces) end current = getnext(current) end + if done and trace_steps then + logprocess("reorder one, handle reph and vata") -- todo: boolean + end end if getchar(base) == c_nbsp then @@ -1386,6 +1517,9 @@ function handlers.devanagari_reorder_matras(head,start) -- no leak setlink(current,start) -- setlink(current,start,next) -- maybe start = startnext + if trace_steps then + logprocess("reorder matra") + end break -- elseif consonant[char] and (not getstate(current) or getstate(current,s_init) then -- startnext = getnext(start) @@ -1451,6 +1585,9 @@ function handlers.devanagari_reorder_reph(head,start) local char = ischar(current,startfont) if char and getprop(current,a_syllabe) == startattr then if halant[char] then + if trace_steps then + logprocess("reorder reph, handling halant") + end local next = getnext(current) if next then local nextchar = ischar(next,startfont) @@ -1488,6 +1625,9 @@ function handlers.devanagari_reorder_reph(head,start) local char = ischar(current,startfont) if char and getprop(current,a_syllabe) == startattr then if consonant[char] and not getstate(current,s_pref) then + if trace_steps then + logprocess("reorder reph, handling consonant") + end startnext = getnext(start) head = remove_node(head,start) setlink(current,start) @@ -1519,6 +1659,9 @@ function handlers.devanagari_reorder_reph(head,start) local char = ischar(current,startfont) if char and getprop(current,a_syllabe) == startattr then if getstate(current,s_pstf) then -- post-base + if trace_steps then + logprocess("reorder reph, before postscript, post base") + end startnext = getnext(start) head = remove_node(head,start) setlink(getprev(current),start) @@ -1533,6 +1676,9 @@ function handlers.devanagari_reorder_reph(head,start) current = getnext(current) else if c then + if trace_steps then + logprocess("reorder reph, before postscript") + end startnext = getnext(start) head = remove_node(head,start) setlink(getprev(c),start) @@ -1564,7 +1710,13 @@ function handlers.devanagari_reorder_reph(head,start) local state = getstate(current) if before_subscript[rephbase] and (state == s_blwf or state == s_pstf) then c = current + if trace_steps then + logprocess("reorder reph, before subscript") + end elseif after_subscript[rephbase] and (state == s_pstf) then + if trace_steps then + logprocess("reorder reph, after subscript") + end c = current end current = getnext(current) @@ -1602,6 +1754,9 @@ function handlers.devanagari_reorder_reph(head,start) end end if start ~= current then + if trace_steps then + logprocess("reorder reph, to end") + end startnext = getnext(start) head = remove_node(head,start) setlink(start,getnext(current)) @@ -1629,6 +1784,8 @@ end -- return head, start, done -- end +-- todo: nodes -> table -> nodes + function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start) if getprop(start,a_reordered) then return head, start, true @@ -1641,6 +1798,9 @@ function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start) local next = getnext(current) if char and getprop(current,a_syllabe) == startattr then if halant[char] then -- state can also be init + if trace_steps then + logprocess("reorder pre base consonants, handle halant") + end if next then local char = ischar(next,startfont) if char and zw_char[char] and getprop(next,a_syllabe) == startattr then @@ -1681,6 +1841,9 @@ function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start) while current and getprop(current,a_syllabe) == startattr do local char = ischar(current) if (not dependent_vowel[char] and (not getstate(current) or getstate(current,s_init))) then + if trace_steps then + logprocess("reorder pre base consonants, handle vowel or initial") + end startnext = getnext(start) head = remove_node(head,start) if current == head then @@ -1724,6 +1887,9 @@ function handlers.devanagari_remove_joiners(head,start,kind,lookupname,replaceme head = stop end flushlist(start) + if trace_steps then + logprocess("remove joiners") + end return head, stop, true end @@ -1750,8 +1916,8 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas local subpos = nil local postpos = nil - reorderreph.coverage = { } - rephbase[font] = { } + reorderreph.coverage = { } -- use local + rephbase[font] = { } -- use local for i=1,#seqsubset do @@ -1761,8 +1927,12 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas local kind = subset[1] local lookupcache = subset[2] if kind == "rphf" then - reorderreph.coverage[subset[3]] = true -- neat - rephbase[font][subset[3]] = subset[4] + -- + local reph = subset[3] + local base = subset[4] + reorderreph.coverage[reph] = true -- neat -- use local + rephbase[font][reph] = base -- use local + -- local current = start local last = getnext(stop) while current ~= last do @@ -1771,16 +1941,15 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas local found = lookupcache[c] if found then local next = getnext(current) - -- if found[getchar(next)] or contextchain(found, next) then --above-base: rphf Consonant + Halant - if contextchain(found, next) then --above-base: rphf Consonant + Halant + if contextchain(found, next) then -- above-base: rphf Consonant + Halant local afternext = next ~= stop and getnext(next) if afternext and zw_char[getchar(afternext)] then -- ZWJ and ZWNJ prevent creation of reph current = afternext -- getnext(next) elseif current == start then setstate(current,s_rphf) - current = next + current = next -- later again next else - current = next + current = next -- later again next end end end @@ -1796,9 +1965,8 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas local found = lookupcache[c] if found then -- pre-base: pref Halant + Consonant local next = getnext(current) - -- if found[getchar(next)] or contextchain(found, next) then if contextchain(found, next) then - if (not getstate(current) and not getstate(next)) then --KE: state can also be init... + if not getstate(current) and not getstate(next) then --KE: state can also be init... setstate(current,s_pref) setstate(next,s_pref) current = next @@ -1817,11 +1985,10 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas local found = lookupcache[c] if found then local next = getnext(current) - -- if found[getchar(next)] or contextchain(found, next) then if contextchain(found, next) then if next ~= stop and getchar(getnext(next)) == c_zwnj then -- zwnj prevent creation of half current = next - elseif (not getstate(current)) then --KE: state can also be init... + elseif not getstate(current) then --KE: state can also be init... setstate(current,s_half) if not halfpos then halfpos = current @@ -1842,9 +2009,8 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas local found = lookupcache[c] if found then local next = getnext(current) - -- if found[getchar(next)] or contextchain(found, next) then if contextchain(found, next) then - if (not getstate(current) and not getstate(next)) then --KE: state can also be init... + if not getstate(current) and not getstate(next) then --KE: state can also be init... setstate(current,s_blwf) setstate(next,s_blwf) current = next @@ -1864,9 +2030,8 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas local found = lookupcache[c] if found then local next = getnext(current) - -- if found[getchar(next)] or contextchain(found, next) then if contextchain(found, next) then - if (not getstate(current) and not getstate(next)) then -- KE: state can also be init... + if not getstate(current) and not getstate(next) then -- KE: state can also be init... setstate(current,s_pstf) setstate(next,s_pstf) current = next @@ -1893,6 +2058,9 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas stop = getprev(stop) head = remove_node(head,current) flushnode(current) + if trace_steps then + logprocess("reorder two, remove nbsp") + end return head, stop, nbspaces else nbspaces = nbspaces + 1 @@ -1933,6 +2101,9 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas end end end + if trace_steps then + logprocess("reorder two, handle nbsp") + end end else -- not Stand Alone cluster local last = getnext(stop) @@ -1989,14 +2160,19 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas local cn = getnext(current) -- not so efficient (needed for malayalam) local tpm = twopart_mark[char] - while tpm do - local extra = copy_node(current) - copyinjection(extra,current) - char = tpm[1] - setchar(current,char) - setchar(extra,tpm[2]) - head = insertnodeafter(head,current,extra) - tpm = twopart_mark[char] + if tpm then + while tpm do + local extra = copy_node(current) + copyinjection(extra,current) + char = tpm[1] + setchar(current,char) + setchar(extra,tpm[2]) + head = insertnodeafter(head,current,extra) + tpm = twopart_mark[char] + end + if tpm and trace_steps then + logprocess("reorder two, handle matra") + end end -- if not moved[current] and dependent_vowel[char] then @@ -2047,6 +2223,9 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas setlink(getprev(pos),current) setlink(current,pos) -- setlink(getprev(pos),current,pos) -- maybe + if trace_steps then + logprocess("reorder two, handle pre mark") + end elseif above_mark[char] then -- after main consonant target = basepos @@ -2090,13 +2269,16 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas setlink(current,getnext(target)) setlink(target,current) -- setlink(target,current,getnext(target)) -- maybe + if trace_steps then + logprocess("reorder two, handle mark") + end end end end current = cn end - -- reorder halant+Ra + -- reorder halant + Ra local current = getnext(start) local last = getnext(stop) @@ -2120,6 +2302,9 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas stop = prev end cn = next + if trace_steps then + logprocess("reorder two, handle halant and ra") + end end end -- after_postscript @@ -2159,6 +2344,9 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas setprev(nextnextnext,current) end setlink(nextnext,c) + if trace_steps then + logprocess("reorder two, handle nukta") + end end if stop == current then break end current = getnext(current) @@ -2171,6 +2359,9 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas nbspaces = nbspaces - 1 head = remove_node(head, base) flushnode(base) + if trace_steps then + logprocess("reorder two, handle nbsp") + end end return head, stop, nbspaces @@ -2267,21 +2458,38 @@ local function analyze_next_chars_one(c,font,variant) -- skip one dependent vowe local already_below_mark -- = false local already_post_mark -- = false while dependent_vowel[v] do - local vowels = twopart_mark[v] or { v } - for k, v in next, vowels do - if pre_mark[v] and not already_pre_mark then + local vowels = twopart_mark[v] + if vowels then + for k=1,#vowels do + local v = vowels[k] + if pre_mark[v] and not already_pre_mark then + already_pre_mark = true + elseif above_mark[v] and not already_above_mark then + already_above_mark = true + elseif below_mark[v] and not already_below_mark then + already_below_mark = true + elseif post_mark[v] and not already_post_mark then + already_post_mark = true + elseif devanagarihash[font].conjuncts == "quit" then + return c + end + end + else + if devanagarihash[font].conjuncts == "quit" then + return c + elseif pre_mark[v] and not already_pre_mark then already_pre_mark = true - elseif above_mark[v] and not already_above_mark then - already_above_mark = true - elseif below_mark[v] and not already_below_mark then - already_below_mark = true elseif post_mark[v] and not already_post_mark then already_post_mark = true + elseif below_mark[v] and not already_below_mark then + already_below_mark = true + elseif above_mark[v] and not already_above_mark then + already_above_mark = true else return c end end - c = getnext(c) + c = n n = getnext(c) if not n then return c @@ -2292,7 +2500,7 @@ local function analyze_next_chars_one(c,font,variant) -- skip one dependent vowe end end if nukta[v] then - c = getnext(c) + c = n n = getnext(c) if not n then return c @@ -2303,7 +2511,7 @@ local function analyze_next_chars_one(c,font,variant) -- skip one dependent vowe end end if halant[v] then - c = getnext(c) + c = n n = getnext(c) if not n then return c @@ -2314,7 +2522,7 @@ local function analyze_next_chars_one(c,font,variant) -- skip one dependent vowe end end if vowel_modifier[v] then - c = getnext(c) + c = n n = getnext(c) if not n then return c @@ -2325,7 +2533,7 @@ local function analyze_next_chars_one(c,font,variant) -- skip one dependent vowe end end if stress_tone_mark[v] then - c = getnext(c) + c = n n = getnext(c) if not n then return c @@ -2456,17 +2664,35 @@ local function analyze_next_chars_two(c,font) local already_above_mark -- = false local already_below_mark -- = false local already_post_mark -- = false + -- inefficient : too many tests but seldom more than one while dependent_vowel[v] do - local vowels = twopart_mark[v] or { v } - for k, v in next, vowels do - if pre_mark[v] and not already_pre_mark then + local vowels = twopart_mark[v] + if vowels then + for k=1,#vowels do + local v = vowels[k] + if pre_mark[v] and not already_pre_mark then + already_pre_mark = true + elseif above_mark[v] and not already_above_mark then + already_above_mark = true + elseif below_mark[v] and not already_below_mark then + already_below_mark = true + elseif post_mark[v] and not already_post_mark then + already_post_mark = true + elseif devanagarihash[font].conjuncts == "quit" then + return c + end + end + else + if devanagarihash[font].conjuncts == "quit" then + return c + elseif pre_mark[v] and not already_pre_mark then already_pre_mark = true - elseif above_mark[v] and not already_above_mark then - already_above_mark = true - elseif below_mark[v] and not already_below_mark then - already_below_mark = true elseif post_mark[v] and not already_post_mark then already_post_mark = true + elseif below_mark[v] and not already_below_mark then + already_below_mark = true + elseif above_mark[v] and not already_above_mark then + already_above_mark = true else return c end @@ -2724,7 +2950,7 @@ local function method_one(head,font,attr) end else if show_syntax_errors then - local mark = mark_four[char] + local mark = mark_pre_above_below_post[char] if mark then head, current = inject_syntax_error(head,current,char) end @@ -2816,7 +3042,6 @@ local function method_two(head,font,attr) syllableend = current elseif consonant[getchar(current)] then -- WHY current INSTEAD OF c ? - -- Consonant syllable: {C+[N]+<H+[<ZWNJ|ZWJ>]|<ZWNJ|ZWJ>+H>} + C+[N]+[A] + [< H+[<ZWNJ|ZWJ>] | {M}+[N]+[H]>]+[SM]+[(VD)] current = analyze_next_chars_two(current,font) -- not c ! syllableend = current @@ -2838,7 +3063,7 @@ local function method_two(head,font,attr) if not syllableend and show_syntax_errors then local char = ischar(current,font) if char and not getstate(current) then -- state can also be init - local mark = mark_four[char] + local mark = mark_pre_above_below_post[char] if mark then head, current = inject_syntax_error(head,current,char) end |