diff options
author | Marius <mariausol@gmail.com> | 2010-07-04 15:32:09 +0300 |
---|---|---|
committer | Marius <mariausol@gmail.com> | 2010-07-04 15:32:09 +0300 |
commit | 85b7bc695629926641c7cb752fd478adfdf374f3 (patch) | |
tree | 80293f5aaa7b95a500a78392c39688d8ee7a32fc /tex/context/base/typo-cap.lua | |
download | context-85b7bc695629926641c7cb752fd478adfdf374f3.tar.gz |
stable 2010-05-24 13:10
Diffstat (limited to 'tex/context/base/typo-cap.lua')
-rw-r--r-- | tex/context/base/typo-cap.lua | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/tex/context/base/typo-cap.lua b/tex/context/base/typo-cap.lua new file mode 100644 index 000000000..5f741da7c --- /dev/null +++ b/tex/context/base/typo-cap.lua @@ -0,0 +1,210 @@ +if not modules then modules = { } end modules ['typo-cap'] = { + version = 1.001, + comment = "companion to typo-cap.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local next, type = next, type +local format, insert = string.format, table.insert + +local trace_casing = false trackers.register("nodes.casing", function(v) trace_casing = v end) + +local has_attribute = node.has_attribute +local unset_attribute = node.unset_attribute +local set_attribute = node.set_attribute +local traverse_id = node.traverse_id + +local glyph = node.id("glyph") +local kern = node.id("kern") + +local fontdata = fonts.ids +local fontchar = fonts.chr +local chardata = characters.data + +cases = cases or { } +cases.actions = { } +cases.attribute = attributes.private("case") + +local actions = cases.actions +local lastfont = nil + +-- we use char0 as placeholder for the larger font + +local function helper(start, code, codes, special, attribute, once) + local char = start.char + local dc = chardata[char] + if dc then + local fnt = start.font + if special then + if start.char == 0 then + lastfont = fnt + local prev, next = start.prev, start.next + prev.next = next + if next then + next.prev = prev + end + return prev, true + elseif lastfont and start.prev.id ~= glyph then + fnt = lastfont + start.font = lastfont + end + end + -- local ifc = fontdata[fnt].characters + local ifc = fontchar[fnt] + local ucs = dc[codes] + if ucs then + local ok = true + for i=1,#ucs do + ok = ok and ifc[ucs[i]] + end + if ok then + local prev, original = start, start + for i=1,#ucs do + local chr = ucs[i] + prev = start + if i == 1 then + start.char = chr + else + local g = copy_node(original) + g.char = chr + local next = start.next + g.prev = start + if next then + g.next = next + start.next = g + next.prev = g + end + start = g + end + end + if once then lastfont = nil end + return prev, true + end + if once then lastfont = nil end + return start, false + end + local uc = dc[code] + if uc and ifc[uc] then + start.char = uc + if once then lastfont = nil end + return start, true + end + end + if once then lastfont = nil end + return start, false +end + +actions[1] = function(start,attribute) + lastfont = nil + return helper(start,'uccode','uccodes') +end + +actions[2] = function(start,attribute) + lastfont = nil + return helper(start,'lccode','lccodes') +end + +actions[3] = function(start,attribute) + lastfont = nil + local prev = start.prev + if prev and prev.id == kern and prev.subtype == 0 then + prev = prev.prev + end + if not prev or prev.id ~= glyph then + --- only the first character is treated + for n in traverse_id(glyph,start.next) do + if has_attribute(n,attribute) then + unset_attribute(n,attribute) + end + end + return helper(start,'uccode','uccodes') + else + return start, false + end +end + +actions[4] = function(start,attribute) + lastfont = nil + local prev = start.prev + if prev and prev.id == kern and prev.subtype == 0 then + prev = prev.prev + end + if not prev or prev.id ~= glyph then + return helper(start,'uccode','uccodes') + else + return start, false + end +end + +actions[5] = function(start,attribute) -- 3 + return helper(start,'uccode','uccodes',true,attribute,true) +end + +actions[6] = function(start,attribute) -- 4 + return helper(start,'uccode','uccodes',true,attribute,false) +end + +actions[8] = function(start) + lastfont = nil + local ch = start.char + local mr = math.random + -- local tfm = fontdata[start.font].characters + local tfm = fontchar[start.font] + if chardata[ch].lccode then + while true do + local d = chardata[mr(1,0xFFFF)] + if d then + local uc = d.uccode + if uc and tfm[uc] then + start.char = uc + return start, true + end + end + end + elseif chardata[ch].uccode then + while true do + local d = chardata[mr(1,0xFFFF)] + if d then + local lc = d.lccode + if lc and tfm[lc] then + start.char = lc + return start, true + end + end + end + else + return start, false + end +end + +-- node.traverse_id_attr + +function cases.process(namespace,attribute,head) -- not real fast but also not used on much data + lastfont = nil + local done = false + for start in traverse_id(glyph,head) do + local attr = has_attribute(start,attribute) + if attr and attr > 0 then + unset_attribute(start,attribute) + local action = actions[attr] + if action then + local _, ok = action(start,attribute) + done = done and ok + end + end + end + lastfont = nil + return head, done +end + +chars.handle_casing = nodes.install_attribute_handler { + name = "case", + namespace = cases, + processor = cases.process, +} + +function cases.enable() + tasks.enableaction("processors","chars.handle_casing") +end |