if not modules then modules = { } end modules ['supp-box'] = { version = 1.001, comment = "companion to supp-box.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" } -- this is preliminary code, use insert_before etc local report_hyphenation = logs.reporter("languages","hyphenation") local tex = tex local context = context local commands = commands local nodes = nodes local splitstring = string.split local nodecodes = nodes.nodecodes local disc_code = nodecodes.disc local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist local glue_code = nodecodes.glue local kern_code = nodecodes.kern local glyph_code = nodecodes.glyph local new_penalty = nodes.pool.penalty local new_hlist = nodes.pool.hlist local new_glue = nodes.pool.glue local free_node = nodes.free local copy_list = nodes.copy_list local copy_node = nodes.copy local find_tail = nodes.tail local texsetbox = tex.setbox local texgetbox = tex.getbox local texget = tex.get local function hyphenatedlist(list) while list do local id, next, prev = list.id, list.next, list.prev if id == disc_code then local hyphen = list.pre if hyphen then local penalty = new_penalty(-500) hyphen.next, penalty.prev = penalty, hyphen prev.next, next.prev = hyphen, penalty penalty.next, hyphen.prev = next, prev list.pre = nil free_node(list) end elseif id == vlist_code or id == hlist_code then hyphenatedlist(list.list) end list = next end end commands.hyphenatedlist = hyphenatedlist function commands.showhyphenatedinlist(list) report_hyphenation("show: %s",nodes.listtoutf(list,false,true)) end local function checkedlist(list) if type(list) == "number" then return texgetbox(list).list else return list end end local function applytochars(list,what,nested) local doaction = context[what or "ruledhbox"] local noaction = context local current = checkedlist(list) while current do local id = current.id if nested and (id == hlist_code or id == vlist_code) then context.beginhbox() applytochars(current.list,what,nested) context.endhbox() elseif id ~= glyph_code then noaction(copy_node(current)) else doaction(copy_node(current)) end current = current.next end end local function applytowords(list,what,nested) local doaction = context[what or "ruledhbox"] local noaction = context local current = checkedlist(list) local start while current do local id = current.id if id == glue_code then if start then doaction(copy_list(start,current)) start = nil end noaction(copy_node(current)) elseif nested and (id == hlist_code or id == vlist_code) then context.beginhbox() applytowords(current.list,what,nested) context.egroup() elseif not start then start = current end current = current.next end if start then doaction(copy_list(start)) end end commands.applytochars = applytochars commands.applytowords = applytowords 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) for i=1,#words do local word = words[i] if word == " " then if spaced then context.space() end elseif command then context[command](word) else context(word) end end elseif how == "word" then local words = lpeg.match(split_word,str) for i=1,#words do local word = words[i] if spaced and i > 1 then context.space() end if command then context[command](word) else context(word) end end elseif how == "line" then local words = lpeg.match(split_line,str) for i=1,#words do local word = words[i] if spaced and i > 1 then context.par() end if command then context[command](word) else context(word) end end else context(str) end end local a_vboxtohboxseparator = attributes.private("vboxtohboxseparator") function commands.vboxlisttohbox(original,target,inbetween) local current = texgetbox(original).list local head = nil local tail = nil while current do local id = current.id local next = current.next if id == hlist_code then local list = current.list if head then if inbetween > 0 then local n = new_glue(0,0,inbetween) tail.next = n n.prev = tail tail = n end tail.next = list list.prev = tail else head = list end tail = find_tail(list) -- remove last separator if tail.id == hlist_code and tail[a_vboxtohboxseparator] == 1 then local temp = tail local prev = tail.prev if next then local list = tail.list prev.next = list list.prev = prev tail.list = nil tail = find_tail(list) else tail = prev end free_node(temp) end -- done tail.next = nil current.list = nil end current = next end local result = new_hlist() result.list = head texsetbox(target,result) end function commands.hboxtovbox(original) local b = texgetbox(original) local factor = texget("baselineskip").width / texget("hsize") b.depth = 0 b.height = b.width * factor end function commands.boxtostring(n) context.puretext(nodes.toutf(tex.box[n].list)) -- helper is defined later end