diff options
author | Hans Hagen <pragma@wxs.nl> | 2009-05-28 11:23:00 +0200 |
---|---|---|
committer | Hans Hagen <pragma@wxs.nl> | 2009-05-28 11:23:00 +0200 |
commit | 1d3090326210c6e6f7ec5432799ded25b75bba46 (patch) | |
tree | c5921203789ec669e6bccaba4bd56f9c072dc56b /tex/context/base/typo-brk.lua | |
parent | 94d83f84758766511c5e324721e39fea6ab71dae (diff) | |
download | context-1d3090326210c6e6f7ec5432799ded25b75bba46.tar.gz |
beta 2009.05.28 11:23
Diffstat (limited to 'tex/context/base/typo-brk.lua')
-rw-r--r-- | tex/context/base/typo-brk.lua | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/tex/context/base/typo-brk.lua b/tex/context/base/typo-brk.lua new file mode 100644 index 000000000..d01b9d653 --- /dev/null +++ b/tex/context/base/typo-brk.lua @@ -0,0 +1,186 @@ +if not modules then modules = { } end modules ['typo-brk'] = { + version = 1.001, + comment = "companion to typo-brk.tex", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- this code dates from the beginning and is kind of experimental; it +-- will be optimized and improved soon + +local next, type = next, type +local format = string.format + +local has_attribute = node.has_attribute +local unset_attribute = node.unset_attribute +local set_attribute = node.set_attribute +local copy_node = node.copy +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 glyph = node.id("glyph") +local kern = node.id("kern") + +breakpoints = breakpoints or { } +breakpoints.mapping = breakpoints.mapping or { } +breakpoints.methods = breakpoints.methods or { } +breakpoints.enabled = false + +storage.register("breakpoints/mapping", breakpoints.mapping, "breakpoints.mapping") + +local mapping = breakpoints.mapping + +function breakpoints.setreplacement(id,char,kind,before,after,language) + local map = mapping[id] + if not map then + map = { } + mapping[id] = map + end + local cmap = map[char] + if not cmap then + cmap = { } + map[char] = cmap + end + cmap[language or ""] = { kind or 1, before or 1, after or 1 } +end + +breakpoints.methods[1] = function(head,start) + if start.prev and start.next then + insert_node_before(head,start,make_penalty_node(10000)) + 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(0)) + end + return head, start +end +breakpoints.methods[2] = function(head,start) -- ( => (- + if start.prev and start.next then + local tmp = start + start = make_disc_node() + start.prev, start.next = tmp.prev, tmp.next + tmp.prev.next, tmp.next.prev = start, start + tmp.prev, tmp.next = nil, nil + start.replace = tmp + local tmp, hyphen = copy_node(tmp), copy_node(tmp) + hyphen.char = languages.prehyphenchar(tmp.lang) + tmp.next, hyphen.prev = hyphen, tmp + start.post = tmp + insert_node_before(head,start,make_penalty_node(10000)) + 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(10000)) + end + return head, start +end +breakpoints.methods[3] = function(head,start) -- ) => -) + if start.prev and start.next then + local tmp = start + start = make_disc_node() + start.prev, start.next = tmp.prev, tmp.next + tmp.prev.next, tmp.next.prev = start, start + tmp.prev, tmp.next = nil, nil + start.replace = tmp + local tmp, hyphen = copy_node(tmp), copy_node(tmp) + hyphen.char = languages.prehyphenchar(tmp.lang) + tmp.prev, hyphen.next = hyphen, tmp + start.pre = hyphen + insert_node_before(head,start,make_penalty_node(10000)) + 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(10000)) + end + return head, start +end +breakpoints.methods[4] = function(head,start) -- - => - - - + if start.prev and start.next then + local tmp = start + start = make_disc_node() + start.prev, start.next = tmp.prev, tmp.next + tmp.prev.next, tmp.next.prev = start, start + tmp.prev, tmp.next = nil, nil + -- maybe prehyphenchar etc + start.pre = copy_node(tmp) + start.post = copy_node(tmp) + start.replace = tmp + insert_node_before(head,start,make_penalty_node(10000)) + 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(10000)) + end + return head, start +end + +function breakpoints.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 + local attr = has_attribute(start,attribute) + if attr and attr > 0 then + unset_attribute(start,attribute) -- maybe test for subtype > 256 (faster) + -- look ahead and back n chars + local map = mapping[attr] + if map then + local cmap = map[start.char] + if cmap then + local smap = cmap[numbers[start.lang]] or cmap[""] + if smap then + if n >= smap[2] then + local m = smap[3] + local next = start.next + while next do -- gamble on same attribute + local id = next.id + if id == glyph then -- gamble on same attribute + if map[next.char] then + break + elseif m == 1 then + local method = breakpoints.methods[smap[1]] + if method then + head, start = method(head,start) + done = true + end + break + else + m = m - 1 + next = next.next + end + elseif id == kern and next.subtype == 0 then + next = next.next + -- ignore intercharacter kerning, will go way + else + -- we can do clever and set n and jump ahead but ... not now + break + end + end + end + n = 0 + else + n = n + 1 + end + else + n = n + 1 + end + else + n = 0 + end + end + elseif id == kern and start.subtype == 0 then + -- ignore intercharacter kerning, will go way + else + n = 0 + end + start = start.next + end + return head, done +end + +chars.handle_breakpoints = nodes.install_attribute_handler { + name = "breakpoint", + namespace = breakpoints, + processor = breakpoints.process, + } |