summaryrefslogtreecommitdiff
path: root/tex/context/base/typo-brk.lua
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2009-05-28 11:23:00 +0200
committerHans Hagen <pragma@wxs.nl>2009-05-28 11:23:00 +0200
commit1d3090326210c6e6f7ec5432799ded25b75bba46 (patch)
treec5921203789ec669e6bccaba4bd56f9c072dc56b /tex/context/base/typo-brk.lua
parent94d83f84758766511c5e324721e39fea6ab71dae (diff)
downloadcontext-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.lua186
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,
+ }