diff options
Diffstat (limited to 'tex/context/base/lang-rep.lua')
-rw-r--r-- | tex/context/base/lang-rep.lua | 295 |
1 files changed, 0 insertions, 295 deletions
diff --git a/tex/context/base/lang-rep.lua b/tex/context/base/lang-rep.lua deleted file mode 100644 index 95a5e545a..000000000 --- a/tex/context/base/lang-rep.lua +++ /dev/null @@ -1,295 +0,0 @@ -if not modules then modules = { } end modules ['lang-rep'] = { - version = 1.001, - comment = "companion to lang-rep.mkiv", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - --- A BachoTeX 2013 experiment, probably not that useful. Eventually I used a simpler --- more generic example. I'm sure no one ever notices of even needs this code. --- --- As a follow up on a question by Alan about special treatment of dropped caps I wonder --- if I can make this one more clever (probably in a few more dev steps). For instance --- injecting nodes or replacing nodes. It's a prelude to a kind of lpeg for nodes, --- although (given experiences so far) we don't really need that. After all, each problem --- is somewhat unique. - -local type, tonumber = type, tonumber -local utfbyte, utfsplit = utf.byte, utf.split -local P, C, U, Cc, Ct, lpegmatch = lpeg.P, lpeg.C, lpeg.patterns.utf8character, lpeg.Cc, lpeg.Ct, lpeg.match -local find = string.find - -local grouped = P("{") * ( Ct((U/utfbyte-P("}"))^1) + Cc(false) ) * P("}")-- grouped -local splitter = Ct((Ct(Cc("discretionary") * grouped * grouped * grouped) + U/utfbyte)^1) - -local trace_replacements = false trackers.register("languages.replacements", function(v) trace_replacements = v end) -local trace_detail = false trackers.register("languages.replacements.detail", function(v) trace_detail = v end) - -local report_replacement = logs.reporter("languages","replacements") - -local glyph_code = nodes.nodecodes.glyph - -local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode - -local setfield = nuts.setfield -local getnext = nuts.getnext -local getprev = nuts.getprev -local getattr = nuts.getattr -local getid = nuts.getid -local getchar = nuts.getchar - -local insert_node_before = nuts.insert_before -local remove_node = nuts.remove -local copy_node = nuts.copy -local flush_list = nuts.flush_list -local insert_after = nuts.insert_after - -local nodepool = nuts.pool -local new_glyph = nodepool.glyph -local new_disc = nodepool.disc - -local texsetattribute = tex.setattribute -local unsetvalue = attributes.unsetvalue - -local v_reset = interfaces.variables.reset - -local implement = interfaces.implement - -local replacements = languages.replacements or { } -languages.replacements = replacements - -local a_replacements = attributes.private("replacements") - -local lists = { } -local last = 0 -local trees = { } - -table.setmetatableindex(lists,function(lists,name) - last = last + 1 - local list = { } - local data = { name = name, list = list, attribute = last } - lists[last] = data - lists[name] = data - trees[last] = list - return data -end) - -lists[v_reset].attribute = unsetvalue -- so we discard 0 - --- todo: glue kern - -local function add(root,word,replacement) - local list = utfsplit(word,true) - local size = #list - for i=1,size do - local l = utfbyte(list[i]) - if not root[l] then - 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, - oldlength = size, - newcodes = newlist, - special = special, - } - end - root = root[l] - end -end - -function replacements.add(category,word,replacement) - local root = lists[category].list - if type(word) == "table" then - for word, replacement in next, word do - add(root,word,replacement) - end - else - add(root,word,replacement or "") - end -end - -local function hit(a,head) - local tree = trees[a] - if tree then - local root = tree[getchar(head)] - if root then - local current = getnext(head) - local lastrun = false - local lastfinal = false - while current and getid(current) == glyph_code do - local newroot = root[getchar(current)] - if not newroot then - return lastrun, lastfinal - else - local final = newroot.final - if final then - if trace_detail then - report_replacement("hitting word %a, replacement %a",final.word,final.replacement) - end - lastrun = current - lastfinal = final - else - root = newroot - end - end - current = getnext(current) - end - if lastrun then - return lastrun, lastfinal - end - end - end -end - -local function tonodes(list,template) - local head, current - for i=1,#list do - local new = copy_node(template) - setfield(new,"char",list[i]) - if head then - head, current = insert_after(head,current,new) - else - head, current = new, new - end - end - return head -end - - -function replacements.handler(head) - head = tonut(head) - local current = head - local done = false - 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 - if trace_replacement then - report_replacement("replacing word %a by %a",final.word,final.replacement) - end - if final.special then - -- easier is to delete and insert (a simple callout to tex would be more efficient) - -- maybe just walk over a replacement string instead - local prev = getprev(current) - local next = getnext(last) - local list = current - setfield(last,"next",nil) - setfield(prev,"next",next) - if next then - setfield(next,"prev",prev) - end - current = prev - if not current then - head = nil - end - for i=1,newlength do - local codes = newcodes[i] - local new = nil - if type(codes) == "table" then - local method = codes[1] - if method == "discretionary" then - local pre, post, replace = codes[2], codes[3], codes[4] - new = new_disc() - if pre then - setfield(new,"pre",tonodes(pre,last)) - end - if post then - setfield(new,"post",tonodes(post,last)) - end - if replace then - setfield(new,"replace",tonodes(replace,last)) - end - else - -- todo - end - else - new = copy_node(last) - setfield(new,"char",codes) - end - if new then - head, current = insert_after(head,current,new) - end - end - flush_list(list) - elseif oldlength == newlength then -- #old == #new - for i=1,newlength do - setfield(current,"char",newcodes[i]) - current = getnext(current) - end - elseif oldlength < newlength then -- #old < #new - for i=1,newlength-oldlength do - local n = copy_node(current) - setfield(n,"char",newcodes[i]) - head, current = insert_node_before(head,current,n) - current = getnext(current) - end - for i=newlength-oldlength+1,newlength do - setfield(current,"char",newcodes[i]) - current = getnext(current) - end - else -- #old > #new - for i=1,oldlength-newlength do - head, current = remove_node(head,current,true) - end - for i=1,newlength do - setfield(current,"char",newcodes[i]) - current = getnext(current) - end - end - done = true - end - end - end - current = getnext(current) - end - return tonode(head), done -end - -local enabled = false - -function replacements.set(n) - if n == v_reset then - n = unsetvalue - else - n = lists[n].attribute - if not enabled then - nodes.tasks.enableaction("processors","languages.replacements.handler") - if trace_replacements then - report_replacement("enabling replacement handler") - end - enabled = true - end - end - texsetattribute(a_replacements,n) -end - --- interface - -implement { - name = "setreplacements", - actions = replacements.set, - arguments = "string" -} - -implement { - name = "addreplacements", - actions = replacements.add, - arguments = { "string", "string", "string" } -} |