diff options
Diffstat (limited to 'tex/context/base/spac-chr.lua')
-rw-r--r-- | tex/context/base/spac-chr.lua | 131 |
1 files changed, 88 insertions, 43 deletions
diff --git a/tex/context/base/spac-chr.lua b/tex/context/base/spac-chr.lua index db98b42a6..e3fa6d099 100644 --- a/tex/context/base/spac-chr.lua +++ b/tex/context/base/spac-chr.lua @@ -14,24 +14,47 @@ local byte, lower = string.byte, string.lower -- to be redone: characters will become tagged spaces instead as then we keep track of -- spaceskip etc +-- todo: only setattr when export / use properties + local next = next -trace_characters = false trackers.register("typesetters.characters", function(v) trace_characters = v end) +local trace_characters = false trackers.register("typesetters.characters", function(v) trace_characters = v end) +local trace_nbsp = false trackers.register("typesetters.nbsp", function(v) trace_nbsp = v end) -report_characters = logs.reporter("typesetting","characters") +local report_characters = logs.reporter("typesetting","characters") local nodes, node = nodes, node -local insert_node_after = nodes.insert_after -local remove_node = nodes.remove -local copy_node_list = nodes.copy_list -local traverse_id = nodes.traverse_id +local nuts = nodes.nuts + +local tonode = nuts.tonode +local tonut = nuts.tonut + +local getfield = nuts.getfield +local setfield = nuts.setfield +local getnext = nuts.getnext +local getprev = nuts.getprev +local getid = nuts.getid +local getattr = nuts.getattr +local setattr = nuts.setattr +local getfont = nuts.getfont +local getchar = nuts.getchar + +local setcolor = nodes.tracers.colors.set + +local insert_node_before = nuts.insert_before +local insert_node_after = nuts.insert_after +local remove_node = nuts.remove +local copy_node_list = nuts.copy_list +local traverse_id = nuts.traverse_id local tasks = nodes.tasks -local nodepool = nodes.pool +local nodepool = nuts.pool local new_penalty = nodepool.penalty local new_glue = nodepool.glue +local new_kern = nodepool.kern +local new_rule = nodepool.rule local nodecodes = nodes.nodecodes local skipcodes = nodes.skipcodes @@ -41,6 +64,7 @@ local glue_code = nodecodes.glue local space_skip_code = skipcodes["spaceskip"] local chardata = characters.data +local is_punctuation = characters.is_punctuation local typesetters = typesetters @@ -63,48 +87,56 @@ local c_zero = byte('0') local c_period = byte('.') local function inject_quad_space(unicode,head,current,fraction) - local attr = current.attr + local attr = getfield(current,"attr") if fraction ~= 0 then - fraction = fraction * fontquads[current.font] + fraction = fraction * fontquads[getfont(current)] end local glue = new_glue(fraction) --- glue.attr = copy_node_list(attr) - glue.attr = attr - current.attr = nil - glue[a_character] = unicode + setfield(glue,"attr",attr) + setfield(current,"attr",nil) + setattr(glue,a_character,unicode) head, current = insert_node_after(head,current,glue) return head, current end local function inject_char_space(unicode,head,current,parent) - local attr = current.attr - local font = current.font + local attr = getfield(current,"attr") + local font = getfont(current) local char = fontcharacters[font][parent] local glue = new_glue(char and char.width or fontparameters[font].space) - glue.attr = current.attr - current.attr = nil - glue[a_character] = unicode + setfield(glue,"attr",attr) + setfield(current,"attr",nil) + setattr(glue,a_character,unicode) head, current = insert_node_after(head,current,glue) return head, current end local function inject_nobreak_space(unicode,head,current,space,spacestretch,spaceshrink) - local attr = current.attr - local glue = new_glue(space,spacestretch,spaceshrink) + local attr = getfield(current,"attr") + local glue = new_glue(space,spacestretch,spaceshrink) local penalty = new_penalty(10000) - glue.attr = attr - current.attr = nil - glue[a_character] = unicode + setfield(glue,"attr",attr) + setfield(current,"attr",nil) + setattr(glue,a_character,unicode) -- bombs head, current = insert_node_after(head,current,penalty) + if trace_nbsp then + local rule = new_rule(space) + local kern = new_kern(-space) + local penalty = new_penalty(10000) + setcolor(rule,"orange") + head, current = insert_node_after(head,current,rule) + head, current = insert_node_after(head,current,kern) + head, current = insert_node_after(head,current,penalty) + end head, current = insert_node_after(head,current,glue) return head, current end local function nbsp(head,current) - local para = fontparameters[current.font] - if current[a_alignstate] == 1 then -- flushright + local para = fontparameters[getfont(current)] + if getattr(current,a_alignstate) == 1 then -- flushright head, current = inject_nobreak_space(0x00A0,head,current,para.space,0,0) - current.subtype = space_skip_code + setfield(current,"subtype",space_skip_code) else head, current = inject_nobreak_space(0x00A0,head,current,para.space,para.spacestretch,para.spaceshrink) end @@ -121,7 +153,7 @@ end function characters.replacenbspaces(head) for current in traverse_id(glyph_code,head) do - if current.char == 0x00A0 then + if getchar(current) == 0x00A0 then local h = nbsp(head,current) if h then head = remove_node(h,current,true) @@ -146,22 +178,34 @@ local methods = { -- The next one uses an attribute assigned to the character but still we -- don't have the 'local' value. + [0x001F] = function(head,current) + local next = getnext(current) + if next and getid(next) == glyph_code then + local char = getchar(next) + head, current = remove_node(head,current,true) + if not is_punctuation[char] then + local p = fontparameters[getfont(next)] + head, current = insert_node_before(head,current,new_glue(p.space,p.space_stretch,p.space_shrink)) + end + end + end, + [0x00A0] = function(head,current) -- nbsp - local next = current.next - if next and next.id == glyph_code then - local char = next.char + local next = getnext(current) + if next and getid(next) == glyph_code then + local char = getchar(next) if char == 0x200C or char == 0x200D then -- nzwj zwj - next = next.next - if next and nbsphash[next.char] then + next = getnext(next) + if next and nbsphash[getchar(next)] then return false end elseif nbsphash[char] then return false end end - local prev = current.prev - if prev and prev.id == glyph_code and nbsphash[prev.char] then - return false -- kannada + local prev = getprev(current) + if prev and getid(prev) == glyph_code and nbsphash[getchar(prev)] then + return false end return nbsp(head,current) end, @@ -215,11 +259,11 @@ local methods = { end, [0x202F] = function(head,current) -- narrownobreakspace - return inject_nobreak_space(0x202F,head,current,fontquads[current.font]/8) + return inject_nobreak_space(0x202F,head,current,fontquads[getfont(current)]/8) end, [0x205F] = function(head,current) -- math thinspace - return inject_nobreak_space(0x205F,head,current,fontparameters[current.font].space/8) + return inject_nobreak_space(0x205F,head,current,fontparameters[getfont(current)].space/8) end, -- [0xFEFF] = function(head,current) -- zerowidthnobreakspace @@ -228,14 +272,15 @@ local methods = { } -function characters.handler(head) +function characters.handler(head) -- todo: use traverse_id + head = tonut(head) local current = head local done = false while current do - local id = current.id + local id = getid(current) if id == glyph_code then - local next = current.next - local char = current.char + local next = getnext(current) + local char = getchar(current) local method = methods[char] if method then if trace_characters then @@ -249,8 +294,8 @@ function characters.handler(head) end current = next else - current = current.next + current = getnext(current) end end - return head, done + return tonode(head), done end |