diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/supp-box.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/supp-box.lua | 280 |
1 files changed, 199 insertions, 81 deletions
diff --git a/Master/texmf-dist/tex/context/base/supp-box.lua b/Master/texmf-dist/tex/context/base/supp-box.lua index 3c5a3383d01..7cc71a891dd 100644 --- a/Master/texmf-dist/tex/context/base/supp-box.lua +++ b/Master/texmf-dist/tex/context/base/supp-box.lua @@ -8,13 +8,16 @@ if not modules then modules = { } end modules ['supp-box'] = { -- this is preliminary code, use insert_before etc +local lpegmatch = lpeg.match + local report_hyphenation = logs.reporter("languages","hyphenation") local tex = tex local context = context -local commands = commands local nodes = nodes +local implement = interfaces.implement + local splitstring = string.split local nodecodes = nodes.nodecodes @@ -42,9 +45,12 @@ local setfield = nuts.setfield local setbox = nuts.setbox local free_node = nuts.free -local copy_list = nuts.copy_list +local flush_list = nuts.flush_list local copy_node = nuts.copy +local copy_list = nuts.copy_list local find_tail = nuts.tail +local traverse_id = nuts.traverse_id +local link_nodes = nuts.linked local listtoutf = nodes.listtoutf @@ -52,29 +58,64 @@ local nodepool = nuts.pool local new_penalty = nodepool.penalty local new_hlist = nodepool.hlist local new_glue = nodepool.glue +local new_rule = nodepool.rule +local new_kern = nodepool.kern + +local setlistcolor = nodes.tracers.colors.setlist local texget = tex.get +local texgetbox = tex.getbox -local function hyphenatedlist(head) +local function hyphenatedlist(head,usecolor) local current = head and tonut(head) while current do local id = getid(current) local next = getnext(current) local prev = getprev(current) if id == disc_code then - local hyphen = getfield(current,"pre") - if hyphen then - local penalty = new_penalty(-500) - -- insert_after etc - setfield(hyphen,"next",penalty) - setfield(penalty,"prev",hyphen) - setfield(prev,"next",hyphen) - setfield(next,"prev", penalty) - setfield(penalty,"next",next) - setfield(hyphen,"prev",prev) + local pre = getfield(current,"pre") + local post = getfield(current,"post") + local replace = getfield(current,"replace") + if pre then setfield(current,"pre",nil) - free_node(current) end + if post then + setfield(current,"post",nil) + end + if not usecolor then + -- nothing fancy done + elseif pre and post then + setlistcolor(pre,"darkmagenta") + setlistcolor(post,"darkcyan") + elseif pre then + setlistcolor(pre,"darkyellow") + elseif post then + setlistcolor(post,"darkyellow") + end + if replace then + flush_list(replace) + setfield(current,"replace",nil) + end + -- setfield(current,"replace",new_rule(65536)) -- new_kern(65536*2)) + setfield(current,"next",nil) + setfield(current,"prev",nil) + local list = link_nodes ( + pre and new_penalty(10000), + pre, + current, + post, + post and new_penalty(10000) + ) + local tail = find_tail(list) + if prev then + setfield(prev,"next",list) + setfield(list,"prev",prev) + end + if next then + setfield(tail,"next",next) + setfield(next,"prev",tail) + end + -- free_node(current) elseif id == vlist_code or id == hlist_code then hyphenatedlist(getlist(current)) end @@ -82,11 +123,29 @@ local function hyphenatedlist(head) end end -commands.hyphenatedlist = hyphenatedlist +implement { + name = "hyphenatedlist", + arguments = { "integer", "boolean" }, + actions = function(n,color) + local b = texgetbox(n) + if b then + hyphenatedlist(b.list,color) + end + end +} -function commands.showhyphenatedinlist(list) - report_hyphenation("show: %s",listtoutf(tonut(list),false,true)) -end +-- local function hyphenatedhack(head,pre) +-- pre = tonut(pre) +-- for n in traverse_id(disc_code,tonut(head)) do +-- local hyphen = getfield(n,"pre") +-- if hyphen then +-- flush_list(hyphen) +-- end +-- setfield(n,"pre",copy_list(pre)) +-- end +-- end +-- +-- commands.hyphenatedhack = hyphenatedhack local function checkedlist(list) if type(list) == "number" then @@ -96,12 +155,20 @@ local function checkedlist(list) end end +implement { + name = "showhyphenatedinlist", + arguments = "integer", + actions = function(box) + report_hyphenation("show: %s",listtoutf(checkedlist(n),false,true)) + end +} + local function applytochars(current,doaction,noaction,nested) while current do local id = getid(current) if nested and (id == hlist_code or id == vlist_code) then context.beginhbox() - applytochars(getlist(current),what,nested) + applytochars(getlist(current),doaction,noaction,nested) context.endhbox() elseif id ~= glyph_code then noaction(tonode(copy_node(current))) @@ -124,7 +191,7 @@ local function applytowords(current,doaction,noaction,nested) noaction(tonode(copy_node(current))) elseif nested and (id == hlist_code or id == vlist_code) then context.beginhbox() - applytowords(getlist(current),what,nested) + applytowords(getlist(current),doaction,noaction,nested) context.egroup() elseif not start then start = current @@ -136,17 +203,43 @@ local function applytowords(current,doaction,noaction,nested) end end -commands.applytochars = function(list,what,nested) applytochars(checkedlist(list),context[what or "ruledhbox"],context,nested) end -commands.applytowords = function(list,what,nested) applytowords(checkedlist(list),context[what or "ruledhbox"],context,nested) end +local methods = { + char = applytochars, + characters = applytochars, + word = applytowords, + words = applytowords, +} + +implement { + name = "applytobox", + arguments = { + { + { "box", "integer" }, + { "command" }, + { "method" }, + { "nested", "boolean" }, + } + }, + actions = function(specification) + local list = checkedlist(specification.box) + local action = methods[specification.method or "char"] + if list and action then + action(list,context[specification.command or "ruledhbox"],context,specification.nested) + end + end +} local split_char = lpeg.Ct(lpeg.C(1)^0) local split_word = lpeg.tsplitat(lpeg.patterns.space) local split_line = lpeg.tsplitat(lpeg.patterns.eol) -function commands.processsplit(str,command,how,spaced) - how = how or "word" - if how == "char" then - local words = lpeg.match(split_char,str) +local function processsplit(specification) + local str = specification.data or "" + local command = specification.command or "ruledhbox" + local method = specification.method or "word" + local spaced = specification.spaced + if method == "char" or method == "character" then + local words = lpegmatch(split_char,str) for i=1,#words do local word = words[i] if word == " " then @@ -159,8 +252,8 @@ function commands.processsplit(str,command,how,spaced) context(word) end end - elseif how == "word" then - local words = lpeg.match(split_word,str) + elseif method == "word" then + local words = lpegmatch(split_word,str) for i=1,#words do local word = words[i] if spaced and i > 1 then @@ -172,8 +265,8 @@ function commands.processsplit(str,command,how,spaced) context(word) end end - elseif how == "line" then - local words = lpeg.match(split_line,str) + elseif method == "line" then + local words = lpegmatch(split_line,str) for i=1,#words do local word = words[i] if spaced and i > 1 then @@ -190,63 +283,88 @@ function commands.processsplit(str,command,how,spaced) end end +implement { + name = "processsplit", + actions = processsplit, + arguments = { + { + { "data" }, + { "command" }, + { "method" }, + { "spaced", "boolean" }, + } + } +} + local a_vboxtohboxseparator = attributes.private("vboxtohboxseparator") -function commands.vboxlisttohbox(original,target,inbetween) - local current = getlist(getbox(original)) - local head = nil - local tail = nil - while current do - local id = getid(current) - local next = getnext(current) - if id == hlist_code then - local list = getlist(current) - if head then - if inbetween > 0 then - local n = new_glue(0,0,inbetween) - setfield(tail,"next",n) - setfield(n,"prev",tail) - tail = n - end - setfield(tail,"next",list) - setfield(list,"prev",tail) - else - head = list - end - tail = find_tail(list) - -- remove last separator - if getid(tail) == hlist_code and getattribute(tail,a_vboxtohboxseparator) == 1 then - local temp = tail - local prev = getprev(tail) - if next then - local list = getlist(tail) - setfield(prev,"next",list) - setfield(list,"prev",prev) - setfield(tail,"list",nil) - tail = find_tail(list) +implement { + name = "vboxlisttohbox", + arguments = { "integer", "integer", "dimen" }, + actions = function(original,target,inbetween) + local current = getlist(getbox(original)) + local head = nil + local tail = nil + while current do + local id = getid(current) + local next = getnext(current) + if id == hlist_code then + local list = getlist(current) + if head then + if inbetween > 0 then + local n = new_glue(0,0,inbetween) + setfield(tail,"next",n) + setfield(n,"prev",tail) + tail = n + end + setfield(tail,"next",list) + setfield(list,"prev",tail) else - tail = prev + head = list + end + tail = find_tail(list) + -- remove last separator + if getid(tail) == hlist_code and getattribute(tail,a_vboxtohboxseparator) == 1 then + local temp = tail + local prev = getprev(tail) + if next then + local list = getlist(tail) + setfield(prev,"next",list) + setfield(list,"prev",prev) + setfield(tail,"list",nil) + tail = find_tail(list) + else + tail = prev + end + free_node(temp) end - free_node(temp) + -- done + setfield(tail,"next",nil) + setfield(current,"list",nil) end - -- done - setfield(tail,"next",nil) - setfield(current,"list",nil) + current = next end - current = next + local result = new_hlist() + setfield(result,"list",head) + setbox(target,result) end - local result = new_hlist() - setfield(result,"list",head) - setbox(target,result) -end +} -function commands.hboxtovbox(original) - local b = getbox(original) - local factor = texget("baselineskip").width / texget("hsize") - setfield(b,"depth",0) - setfield(b,"height",getfield(b,"width") * factor) -end +implement { + name = "hboxtovbox", + arguments = "integer", + actions = function(n) + local b = getbox(n) + local factor = texget("baselineskip").width / texget("hsize") + setfield(b,"depth",0) + setfield(b,"height",getfield(b,"width") * factor) + end +} -function commands.boxtostring(n) - context.puretext(nodes.toutf(tex.box[n].list)) -- helper is defined later -end +implement { + name = "boxtostring", + arguments = "integer", + actions = function(n) + context.puretext(nodes.toutf(texgetbox(n).list)) -- helper is defined later + end +} |