From 85b7bc695629926641c7cb752fd478adfdf374f3 Mon Sep 17 00:00:00 2001 From: Marius Date: Sun, 4 Jul 2010 15:32:09 +0300 Subject: stable 2010-05-24 13:10 --- tex/context/base/typo-spa.lua | 167 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 tex/context/base/typo-spa.lua (limited to 'tex/context/base/typo-spa.lua') diff --git a/tex/context/base/typo-spa.lua b/tex/context/base/typo-spa.lua new file mode 100644 index 000000000..48c7263c7 --- /dev/null +++ b/tex/context/base/typo-spa.lua @@ -0,0 +1,167 @@ +if not modules then modules = { } end modules ['typo-spa'] = { + version = 1.001, + comment = "companion to typo-spa.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- get rid of tex.scale here + +local utf = unicode.utf8 + +local next, type = next, type +local utfchar = utf.char + +local trace_hspacing = false trackers.register("nodes.hspacing", function(v) trace_hspacing = v end) + +local has_attribute = node.has_attribute +local unset_attribute = node.unset_attribute +local insert_node_before = node.insert_before +local insert_node_after = node.insert_after +local remove_node = nodes.remove +local make_penalty_node = nodes.penalty +local make_glue_node = nodes.glue +local glyph = node.id("glyph") + +local fontdata = fonts.identifiers +local quaddata = fonts.quads + +spacings = spacings or { } +spacings.mapping = spacings.mapping or { } +spacings.attribute = attributes.private("spacing") + +storage.register("spacings/mapping", spacings.mapping, "spacings.mapping") + +function spacings.setspacing(id,char,left,right,alternative) + local mapping = spacings.mapping[id] + if not mapping then + mapping = { } + spacings.mapping[id] = mapping + end + local map = mapping[char] + if not map then + map = { } + mapping[char] = map + end + map.left, map.right, map.alternative = left, right, alternative +end + +function spacings.process(namespace,attribute,head) + local done, mapping = false, spacings.mapping + local start = head + -- head is always begin of par (whatsit), so we have at least two prev nodes + -- penalty followed by glue + while start do + if start.id == glyph then + local attr = has_attribute(start,attribute) + if attr and attr > 0 then + local map = mapping[attr] + if map then + map = map[start.char] + unset_attribute(start,attribute) -- needed? + if map then + local left, right, alternative = map.left, map.right, map.alternative + local quad = quaddata[start.font] + local prev = start.prev + if left and left ~= 0 and prev then + local ok = false + if alternative == 1 then + local somespace = nodes.somespace(prev,true) + if somespace then + local prevprev = prev.prev + local somepenalty = nodes.somepenalty(prevprev,10000) + if somepenalty then + if trace_hspacing then + logs.report("spacing","removing penalty and space before %s", utfchar(start.char)) + end + head, _ = remove_node(head,prev,true) + head, _ = remove_node(head,prevprev,true) + else + local somespace = nodes.somespace(prev,true) + if somespace then + if trace_hspacing then + logs.report("spacing","removing space before %s", utfchar(start.char)) + end + head, _ = remove_node(head,prev,true) + end + end + end + ok = true + else + ok = not (nodes.somespace(prev,true) and nodes.somepenalty(prev.prev,true)) or nodes.somespace(prev,true) + end + if ok then + if trace_hspacing then + logs.report("spacing","inserting penalty and space before %s", utfchar(start.char)) + end + insert_node_before(head,start,make_penalty_node(10000)) + insert_node_before(head,start,make_glue_node(tex.scale(quad,left))) + done = true + end + end + local next = start.next + if right and right ~= 0 and next then + local ok = false + if alternative == 1 then + local somepenalty = nodes.somepenalty(next,10000) + if somepenalty then + local nextnext = next.next + local somespace = nodes.somespace(nextnext,true) + if somespace then + if trace_hspacing then + logs.report("spacing","removing penalty and space after %s", utfchar(start.char)) + end + head, _ = remove_node(head,next,true) + head, _ = remove_node(head,nextnext,true) + end + else + local somespace = nodes.somespace(next,true) + if somespace then + if trace_hspacing then + logs.report("spacing","removing space after %s", utfchar(start.char)) + end + head, _ = remove_node(head,next,true) + end + end + ok = true + else + ok = not (nodes.somepenalty(next,10000) and nodes.somespace(next.next,true)) or nodes.somespace(next,true) + end + if ok then + if trace_hspacing then + logs.report("spacing","inserting penalty and space after %s", utfchar(start.char)) + end + insert_node_after(head,start,make_glue_node(tex.scale(quad,right))) + insert_node_after(head,start,make_penalty_node(10000)) + done = true + end + end + end + end + end + end + start = start.next + end + return head, done +end + +lists.handle_spacing = nodes.install_attribute_handler { + name = "spacing", + namespace = spacings, + processor = spacings.process, +} + +function spacings.enable() + tasks.enableaction("processors","lists.handle_spacing") +end + +--~ local data = { +--~ name = "spacing", +--~ namespace = spacings, +--~ processor = spacings.process, +--~ } +--~ nodes.process_attribute = process_attribute +--~ function lists.handle_spacing(head) +--~ return process_attribute(head,data) +--~ end -- cgit v1.2.3