diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/typo-brk.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/typo-brk.lua | 128 |
1 files changed, 86 insertions, 42 deletions
diff --git a/Master/texmf-dist/tex/context/base/typo-brk.lua b/Master/texmf-dist/tex/context/base/typo-brk.lua index 8f7a00f9df9..fe0258bccd6 100644 --- a/Master/texmf-dist/tex/context/base/typo-brk.lua +++ b/Master/texmf-dist/tex/context/base/typo-brk.lua @@ -13,32 +13,56 @@ local next, type, tonumber = next, type, tonumber local utfbyte, utfchar = utf.byte, utf.char local format = string.format -local settings_to_array = aux.settings_to_array +local trace_breakpoints = false trackers.register("typesetters.breakpoints", function(v) trace_breakpoints = v end) + +local report_breakpoints = logs.reporter("typesetting","breakpoints") + +local nodes, node = nodes, node + +local settings_to_array = utilities.parsers.settings_to_array local has_attribute = node.has_attribute local unset_attribute = node.unset_attribute local set_attribute = node.set_attribute local copy_node = node.copy +local copy_nodelist = node.copy_list local free_node = node.free local insert_node_before = node.insert_before local insert_node_after = node.insert_after -local make_penalty_node = nodes.penalty -local make_glue_node = nodes.glue -local make_disc_node = nodes.disc -local make_glyph_node = nodes.glyph local remove_node = nodes.remove -- ! nodes -local tonodes = blobs.tonodes +local link_nodes = nodes.link + +local texattribute = tex.attribute + +local nodepool = nodes.pool +local tasks = nodes.tasks + +local new_penalty = nodepool.penalty +local new_glue = nodepool.glue +local new_disc = nodepool.disc + +local nodecodes = nodes.nodecodes +local kerncodes = nodes.kerncodes + +local glyph_code = nodecodes.glyph +local kern_code = nodecodes.kern + +local kerning_code = kerncodes.kerning + +local typesetters = typesetters -local glyph = node.id("glyph") -local kern = node.id("kern") +typesetters.breakpoints = typesetters.breakpoints or {} +local breakpoints = typesetters.breakpoints -breakpoints = breakpoints or { } -breakpoints.mapping = breakpoints.mapping or { } -breakpoints.methods = breakpoints.methods or { } -breakpoints.attribute = attributes.private("breakpoint") +breakpoints.mapping = breakpoints.mapping or { } +local mapping = breakpoints.mapping -storage.register("breakpoints/mapping", breakpoints.mapping, "breakpoints.mapping") +breakpoints.methods = breakpoints.methods or { } +local methods = breakpoints.methods -local mapping = breakpoints.mapping +local a_breakpoints = attributes.private("breakpoint") +breakpoints.attribute = a_breakpoints + +storage.register("typesetters/breakpoints/mapping", breakpoints.mapping, "typesetters.breakpoints.mapping") function breakpoints.setreplacement(id,char,language,settings) char = utfbyte(char) @@ -54,33 +78,35 @@ function breakpoints.setreplacement(id,char,language,settings) end local left, right, middle = settings.left, settings.right, settings.middle cmap[language or ""] = { - kind = tonumber(settings.kind) or 1, + type = tonumber(settings.type) or 1, nleft = tonumber(settings.nleft) or 1, nright = tonumber(settings.nright) or 1, left = left ~= "" and left or nil, right = right ~= "" and right or nil, middle = middle ~= "" and middle or nil, - } -- was { kind or 1, before or 1, after or 1 } + } -- was { type or 1, before or 1, after or 1 } end local function insert_break(head,start,before,after) - insert_node_before(head,start,make_penalty_node(before)) - insert_node_before(head,start,make_glue_node(0)) - insert_node_after(head,start,make_glue_node(0)) - insert_node_after(head,start,make_penalty_node(after)) + insert_node_before(head,start,new_penalty(before)) + insert_node_before(head,start,new_glue(0)) + insert_node_after(head,start,new_glue(0)) + insert_node_after(head,start,new_penalty(after)) end -breakpoints.methods[1] = function(head,start) +methods[1] = function(head,start) if start.prev and start.next then insert_break(head,start,10000,0) end return head, start end -breakpoints.methods[2] = function(head,start) -- ( => (- + +methods[2] = function(head,start) -- ( => (- if start.prev and start.next then local tmp head, start, tmp = remove_node(head,start) - head, start = insert_node_before(head,start,make_disc_node()) + head, start = insert_node_before(head,start,new_disc()) + start.attr = copy_nodelist(tmp.attr) -- todo: critical only start.replace = tmp local tmp, hyphen = copy_node(tmp), copy_node(tmp) hyphen.char = languages.prehyphenchar(tmp.lang) @@ -90,11 +116,13 @@ breakpoints.methods[2] = function(head,start) -- ( => (- end return head, start end -breakpoints.methods[3] = function(head,start) -- ) => -) + +methods[3] = function(head,start) -- ) => -) if start.prev and start.next then local tmp head, start, tmp = remove_node(head,start) - head, start = insert_node_before(head,start,make_disc_node()) + head, start = insert_node_before(head,start,new_disc()) + start.attr = copy_nodelist(tmp.attr) -- todo: critical only start.replace = tmp local tmp, hyphen = copy_node(tmp), copy_node(tmp) hyphen.char = languages.prehyphenchar(tmp.lang) @@ -104,36 +132,41 @@ breakpoints.methods[3] = function(head,start) -- ) => -) end return head, start end -breakpoints.methods[4] = function(head,start) -- - => - - - + +methods[4] = function(head,start) -- - => - - - if start.prev and start.next then local tmp head, start, tmp = remove_node(head,start) - head, start = insert_node_before(head,start,make_disc_node()) + head, start = insert_node_before(head,start,new_disc()) + start.attr = copy_nodelist(tmp.attr) -- todo: critical only start.pre, start.post, start.replace = copy_node(tmp), copy_node(tmp), tmp insert_break(head,start,10000,10000) end return head, start end -breakpoints.methods[5] = function(head,start,settings) -- x => p q r + +methods[5] = function(head,start,settings) -- x => p q r if start.prev and start.next then local tmp head, start, tmp = remove_node(head,start) - head, start = insert_node_before(head,start,make_disc_node()) - start.pre, start.post, start.replace = tonodes(settings.right,tmp), tonodes(settings.left,tmp), tonodes(settings.middle,tmp) + head, start = insert_node_before(head,start,new_disc()) + local attr = tmp.attr + start.attr = copy_nodelist(attr) -- todo: critical only + start.pre = link_nodes(settings.right,tmp,attr) + start.post = link_nodes(settings.left,tmp,attr) + start.replace = link_nodes(settings.middle,tmp,attr) free_node(tmp) insert_break(head,start,10000,10000) end return head, start end -local methods = breakpoints.methods - -function breakpoints.process(namespace,attribute,head) +local function process(namespace,attribute,head) local done, numbers = false, languages.numbers local start, n = head, 0 while start do local id = start.id - if id == glyph then + if id == glyph_code then local attr = has_attribute(start,attribute) if attr and attr > 0 then unset_attribute(start,attribute) -- maybe test for subtype > 256 (faster) @@ -151,11 +184,11 @@ function breakpoints.process(namespace,attribute,head) local next = start.next while next do -- gamble on same attribute (not that important actually) local id = next.id - if id == glyph then -- gamble on same attribute (not that important actually) + if id == glyph_code then -- gamble on same attribute (not that important actually) if map[next.char] then break elseif m == 1 then - local method = methods[smap.kind] + local method = methods[smap.type] if method then head, start = method(head,start,smap) done = true @@ -165,7 +198,7 @@ function breakpoints.process(namespace,attribute,head) m = m - 1 next = next.next end - elseif id == kern and next.subtype == 0 then + elseif id == kern_code and next.subtype == kerning_code then next = next.next -- ignore intercharacter kerning, will go way else @@ -187,7 +220,7 @@ function breakpoints.process(namespace,attribute,head) else -- n = n + 1 -- if we want single char handling (|-|) then we will use grouping and then we need this end - elseif id == kern and start.subtype == 0 then + elseif id == kern_code and start.subtype == kerning_code then -- ignore intercharacter kerning, will go way else n = 0 @@ -197,12 +230,23 @@ function breakpoints.process(namespace,attribute,head) return head, done end -chars.handle_breakpoints = nodes.install_attribute_handler { - name = "breakpoint", +function breakpoints.set(n) + if trace_breakpoints then + report_breakpoints("enabling breakpoints handler") + end + tasks.enableaction("processors","typesetters.breakpoints.handler") + function breakpoints.set(n) + texattribute[a_breakpoints] = n + end + breakpoints.set(n) +end + +breakpoints.handler = nodes.installattributehandler { + name = "breakpoint", namespace = breakpoints, - processor = breakpoints.process, + processor = process, } function breakpoints.enable() - tasks.enableaction("processors","chars.handle_breakpoints") + tasks.enableaction("processors","typesetters.breakpoints.handler") end |