summaryrefslogtreecommitdiff
path: root/tex/context/base/spac-chr.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/spac-chr.lua')
-rw-r--r--tex/context/base/spac-chr.lua157
1 files changed, 157 insertions, 0 deletions
diff --git a/tex/context/base/spac-chr.lua b/tex/context/base/spac-chr.lua
new file mode 100644
index 000000000..601b90645
--- /dev/null
+++ b/tex/context/base/spac-chr.lua
@@ -0,0 +1,157 @@
+if not modules then modules = { } end modules ['spac-chr'] = {
+ version = 1.001,
+ comment = "companion to spac-chr.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local byte = string.byte
+
+----- trace_characters = false trackers.register("typesetters.characters", function(v) trace_characters = v end)
+-----
+----- report_characters = logs.reporter("typesetting","characters")
+
+local nodes, node = nodes, node
+
+local set_attribute = node.set_attribute
+local insert_node_after = node.insert_after
+local remove_node = nodes.remove -- ! nodes
+
+local nodepool = nodes.pool
+local tasks = nodes.tasks
+
+local new_penalty = nodepool.penalty
+local new_glue = nodepool.glue
+
+local nodecodes = nodes.nodecodes
+local glyph_code = nodecodes.glyph
+
+local typesetters = typesetters
+
+local characters = { }
+typesetters.characters = characters
+
+local fontparameters = fonts.hashes.parameters
+local fontcharacters = fonts.hashes.characters
+
+local a_character = attributes.private("characters")
+
+local c_zero = byte('0')
+local c_period = byte('.')
+
+local function inject_quad_space(unicode,head,current,fraction)
+ local attr = current.attr
+ if fraction ~= 0 then
+ fraction = fraction * fontparameters[current.font].quad
+ end
+ head, current = insert_node_after(head,current,new_glue(fraction))
+ current.attr = attr
+ set_attribute(current,a_character,unicode)
+ return head, current
+end
+
+local function inject_char_space(unicode,head,current,parent)
+ local attr = current.attr
+ local char = fontcharacters[current.font][parent]
+ head, current = insert_node_after(head,current,new_glue(char and char.width or fontparameters[current.font].space))
+ current.attr = attr
+ set_attribute(current,a_character,unicode)
+ return head, current
+end
+
+local function inject_nobreak_space(unicode,head,current,space,spacestretch,spaceshrink)
+ local attr = current.attr
+ head, current = insert_node_after(head,current,new_glue(space,spacestretch,spaceshrink))
+ current.attr = attr
+ set_attribute(current,a_character,unicode)
+ head, current = insert_node_after(head,current,new_penalty(10000))
+ return head, current
+end
+
+local methods = {
+
+ [0x00A0] = function(head,current) -- nobreakspace
+ local para = fontparameters[current.font]
+ return inject_nobreak_space(0x00A0,head,current,para.space,para.spacestretch,para.spaceshrink)
+ end,
+
+ [0x2000] = function(head,current) -- enquad
+ return inject_quad_space(0x2000,head,current,1/2)
+ end,
+
+ [0x2001] = function(head,current) -- emquad
+ return inject_quad_space(0x2001,head,current,1)
+ end,
+
+ [0x2002] = function(head,current) -- enspace
+ return inject_quad_space(0x2002,head,current,1/2)
+ end,
+
+ [0x2003] = function(head,current) -- emspace
+ return inject_quad_space(0x2003,head,current,1)
+ end,
+
+ [0x2004] = function(head,current) -- threeperemspace
+ return inject_quad_space(0x2004,head,current,1/3)
+ end,
+
+ [0x2005] = function(head,current) -- fourperemspace
+ return inject_quad_space(0x2005,head,current,1/4)
+ end,
+
+ [0x2006] = function(head,current) -- sixperemspace
+ return inject_quad_space(0x2006,head,current,1/6)
+ end,
+
+ [0x2007] = function(head,current) -- figurespace
+ return inject_char_space(0x2007,head,current,c_zero)
+ end,
+
+ [0x2008] = function(head,current) -- punctuationspace
+ return inject_char_space(0x2008,head,current,c_period)
+ end,
+
+ [0x2009] = function(head,current) -- breakablethinspace
+ return inject_quad_space(0x2009,head,current,1/8) -- same as next
+ end,
+
+ [0x200A] = function(head,current) -- hairspace
+ return inject_quad_space(0x200A,head,current,1/8) -- same as previous (todo)
+ end,
+
+ [0x200B] = function(head,current) -- zerowidthspace
+ return inject_quad_space(0x200B,head,current,0)
+ end,
+
+ [0x202F] = function(head,current) -- narrownobreakspace
+ return inject_nobreak_space(0x202F,head,current,fontparameters[current.font].space/8)
+ end,
+
+ [0x205F] = function(head,current) -- math thinspace
+ return inject_nobreak_space(0x205F,head,current,fontparameters[current.font].space/8)
+ end,
+
+ -- [0xFEFF] = function(head,current) -- zerowidthnobreakspace
+ -- return head, current
+ -- end,
+
+}
+
+function characters.handler(head)
+ local current = head
+ local done = false
+ while current do
+ local next = current.next
+ if current.id == glyph_code then
+ local method = methods[current.char]
+ if method then
+ head = method(head,current)
+ head = remove_node(head,current,true)
+ done = true
+ end
+ end
+ current = next
+ end
+ return head, done
+end