diff options
Diffstat (limited to 'tex/context/base/mkiv/lang-rep.lua')
-rw-r--r-- | tex/context/base/mkiv/lang-rep.lua | 68 |
1 files changed, 52 insertions, 16 deletions
diff --git a/tex/context/base/mkiv/lang-rep.lua b/tex/context/base/mkiv/lang-rep.lua index 6fde353f7..172454fc2 100644 --- a/tex/context/base/mkiv/lang-rep.lua +++ b/tex/context/base/mkiv/lang-rep.lua @@ -15,7 +15,8 @@ if not modules then modules = { } end modules ['lang-rep'] = { -- although (given experiences so far) we don't really need that. After all, each problem -- is somewhat unique. -local type, tonumber = type, tonumber +local type, tonumber, next = type, tonumber, next +local gmatch, gsub = string.gmatch, string.gsub local utfbyte, utfsplit = utf.byte, utf.split local P, C, U, Cc, Ct, Cs, lpegmatch = lpeg.P, lpeg.C, lpeg.patterns.utf8character, lpeg.Cc, lpeg.Ct, lpeg.Cs, lpeg.match local find = string.find @@ -51,8 +52,6 @@ local getid = nuts.getid local getchar = nuts.getchar local isglyph = nuts.isglyph -local setfield = nuts.setfield -local getfield = nuts.getfield local setattr = nuts.setattr local setlink = nuts.setlink local setnext = nuts.setnext @@ -78,6 +77,9 @@ local v_reset = interfaces.variables.reset local implement = interfaces.implement +local processors = typesetters.processors +local splitprocessor = processors.split + local replacements = languages.replacements or { } languages.replacements = replacements @@ -103,7 +105,8 @@ lists[v_reset].attribute = unsetvalue -- so we discard 0 -- todo: glue kern attr local function add(root,word,replacement) - local replacement = lpegmatch(stripper,replacement) or replacement + local processor, replacement = splitprocessor(replacement,true) -- no check + replacement = lpegmatch(stripper,replacement) or replacement local list = utfsplit(word,true) local size = #list for i=1,size do @@ -112,16 +115,12 @@ local function add(root,word,replacement) root[l] = { } end if i == size then - -- local newlist = utfsplit(replacement,true) - -- for i=1,#newlist do - -- newlist[i] = utfbyte(newlist[i]) - -- end local special = find(replacement,"{",1,true) local newlist = lpegmatch(splitter,replacement) - -- root[l].final = { word = word, replacement = replacement, + processor = processor, oldlength = size, newcodes = newlist, special = special, @@ -142,6 +141,26 @@ function replacements.add(category,word,replacement) end end +-- local strip = lpeg.stripper("{}") + +function languages.replacements.addlist(category,list) + local root = lists[category].list + if type(list) == "string" then + for new in gmatch(list,"%S+") do + local old = gsub(new,"[{}]","") + -- local old = lpegmatch(strip,new) + add(root,old,new) + end + else + for i=1,#list do + local new = list[i] + local old = gsub(new,"[{}]","") + -- local old = lpegmatch(strip,new) + add(root,old,new) + end + end +end + local function hit(a,head) local tree = trees[a] if tree then @@ -151,7 +170,10 @@ local function hit(a,head) local lastrun = false local lastfinal = false while current do - local char = isglyph(current) + local char, id = isglyph(current) + -- if not char and id == glue_code then + -- char = " " -- if needed we can also deal with spaces and special nbsp and such + -- end if char then local newroot = root[char] if not newroot then @@ -194,20 +216,21 @@ local function tonodes(list,template) return head end - function replacements.handler(head) head = tonut(head) - local current = head - local done = false + local current = head + local done = false + local overload = attributes.applyoverloads while current do if getid(current) == glyph_code then local a = getattr(current,a_replacements) if a then local last, final = hit(a,current) if last then - local oldlength = final.oldlength - local newcodes = final.newcodes - local newlength = #newcodes + local precurrent = getprev(current) or head + local oldlength = final.oldlength + local newcodes = final.newcodes + local newlength = newcodes and #newcodes or 0 if trace_replacement then report_replacement("replacing word %a by %a",final.word,final.replacement) end @@ -269,6 +292,9 @@ function replacements.handler(head) i = i + 1 end flush_list(list) + elseif newlength == 0 then + -- nothing gets replaced + current = getnext(last) elseif oldlength == newlength then -- #old == #new if final.word == final.replacement then -- nothing to do but skip @@ -298,10 +324,14 @@ function replacements.handler(head) current = getnext(current) end end + if overload then + overload(final,getnext(precurrent),getprev(current)) + end done = true end end end + -- we're one ahead now but we need to because we handle words current = getnext(current) end return tonode(head), done @@ -338,3 +368,9 @@ implement { actions = replacements.add, arguments = { "string", "string", "string" } } + +implement { + name = "addreplacementslist", + actions = replacements.addlist, + arguments = { "string", "string" } +} |