summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/supp-box.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/supp-box.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/supp-box.lua280
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
+}