From da070a532bdc1e46d94957df1a7b62a1b90b63dd Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Thu, 23 Jun 2016 21:36:11 +0000 Subject: cloze (23jun16) git-svn-id: svn://tug.org/texlive/trunk@41531 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/scripts/cloze/cloze.lua | 265 +++++++++++++++++++----------- 1 file changed, 168 insertions(+), 97 deletions(-) (limited to 'Master/texmf-dist/scripts/cloze') diff --git a/Master/texmf-dist/scripts/cloze/cloze.lua b/Master/texmf-dist/scripts/cloze/cloze.lua index aa48473a349..ffde9ca20f2 100755 --- a/Master/texmf-dist/scripts/cloze/cloze.lua +++ b/Master/texmf-dist/scripts/cloze/cloze.lua @@ -25,6 +25,7 @@ registry.defaults = { registry.global_options = {} registry.local_options = {} local cloze = {} +cloze.status = {} local base = {} base.is_registered = {} function nodex.create_colorstack(data) @@ -58,14 +59,29 @@ function nodex.create_line(width) rule.width = width return rule end -function nodex.insert_line(head, current, width) - local n = {} -- node - n.color_line = nodex.create_color('line') - head, n.color_line = node.insert_after(head, current, n.color_line) - n.line = nodex.create_line(width) - head, n.line = node.insert_after(head, n.color_line, n.line) - n.color_reset = nodex.create_color('reset') - return node.insert_after(head, n.line, n.color_reset) +function nodex.insert_list(position, current, list, head) + if not head then + head = current + end + for i, insert in ipairs(list) do + if position == 'after' then + head, current = node.insert_after(head, current, insert) + elseif position == 'before' then + head, current = node.insert_before(head, current, insert) + end + end + return current +end +function nodex.insert_line(current, width) + return nodex.insert_list( + 'after', + current, + { + nodex.create_color('line'), + nodex.create_line(width), + nodex.create_color('reset') + } + ) end function nodex.write_line() node.write(nodex.create_color('line')) @@ -104,6 +120,15 @@ function nodex.write_margin() local kern = nodex.create_kern(tex.sp(registry.get_value('margin'))) node.write(kern) end +function nodex.search_hlist(head) + while head do + if head.id == node.id('hlist') and head.subtype == 1 then + return nodex.strut_to_hlist(head) + end + head = head.next + end + return false +end function registry.create_marker(index) local marker = node.new('whatsit','user_defined') marker.type = 100 -- number @@ -116,6 +141,15 @@ function registry.write_marker(mode, position) local marker = registry.create_marker(index) node.write(marker) end +function registry.is_marker(item) + if item.id == node.id('whatsit') + and item.subtype == node.subtype('user_defined') + and item.user_id == registry.user_id then + return true + else + return false + end +end function registry.check_marker(item, mode, position) local data = registry.get_marker_data(item) if data and data.mode == mode and data.position == position then @@ -150,6 +184,9 @@ function registry.get_marker_values(marker) registry.local_options = data.values return data.values end +function registry.remove_marker(marker) + if registry.is_marker(marker) then node.remove(marker, marker) end +end function registry.get_index() if not registry.index then registry.index = 0 @@ -219,124 +256,151 @@ end function registry.get_defaults(option) return registry.defaults[option] end -function cloze.basic_make(head, hlist, start, stop) +function cloze.basic_make(start, stop) local n = {} local l = {} + n.head = start if not start or not stop then return end n.start = start n.stop = stop l.width = node.dimensions( - hlist.glue_set, - hlist.glue_sign, - hlist.glue_order, + cloze.status.hlist.glue_set, + cloze.status.hlist.glue_sign, + cloze.status.hlist.glue_order, n.start, n.stop ) - head, n.line = nodex.insert_line(head, n.start, l.width) - n.color_text = nodex.create_color('text') - head, n.color_text = node.insert_after( - hlist.head, - n.line, - n.color_text - ) + n.line = nodex.insert_line(n.start, l.width) + n.color_text = nodex.insert_list('after', n.line, {nodex.create_color('text')}) if registry.get_value_show() then - n.kern = nodex.create_kern(-l.width) - node.insert_after(head, n.color_text, n.kern) - n.color_reset = nodex.create_color('reset') - node.insert_after(head, n.stop, n.color_reset) + nodex.insert_list('after', n.color_text, {nodex.create_kern(-l.width)}) + nodex.insert_list('before', n.stop, {nodex.create_color('reset')}, n.head) else n.line.next = n.stop.next n.stop.prev = n.line.prev end - + registry.remove_marker(n.start) + registry.remove_marker(n.stop) +end +function cloze.basic_search_stop(head) + local stop + while head do + cloze.status.continue = true + stop = head + if registry.check_marker(stop, 'basic', 'stop') then + cloze.status.continue = false + break + end + head = head.next + end + return stop end -function cloze.basic(head) - local n = {} -- node - local b = {} -- boolean - local l = {} -- length - local t = {} -- temp - for hlist in node.traverse_id(node.id('hlist'), head) do - hlist = nodex.strut_to_hlist(hlist) - if b.line_end then - b.init_cloze = true +function cloze.basic_search_start(head) + local start + local stop + local n = {} + if cloze.status.continue then + n.hlist = nodex.search_hlist(head) + if n.hlist then + cloze.status.hlist = n.hlist + start = cloze.status.hlist.head end - n.current = hlist.head - while n.current do - if - registry.check_marker(n.current, 'basic', 'start') - or - b.init_cloze - then - b.init_cloze = false - n.start = n.current - while n.current do - b.line_end = true - n.stop = n.current - if registry.check_marker(n.stop, 'basic', 'stop') then - b.line_end = false - break - end - n.current = n.current.next - end - cloze.basic_make(head, hlist, n.start, n.stop) - n.current = n.stop - else - n.current = n.current.next - end + elseif registry.check_marker(head, 'basic', 'start') then + start = head + end + if start then + stop = cloze.basic_search_stop(start) + cloze.basic_make(start, stop) + end +end +function cloze.basic_recursion(head) + while head do + if head.head then + cloze.status.hlist = head + cloze.basic_recursion(head.head) + else + cloze.basic_search_start(head) end + head = head.next end +end +function cloze.basic(head) + cloze.status.continue = false + cloze.basic_recursion(head) return head end -function cloze.fix_make(head, start, stop) - local l = {} -- length +function cloze.fix_length(start, stop) + local l = {} l.width = tex.sp(registry.get_value('width')) - local n = {} -- node - n.start = start - n.stop = stop - l.text_width = node.dimensions(n.start, n.stop) - local align = registry.get_value('align') - if align == 'right' then - l.kern_start = -l.text_width + l.text_width = node.dimensions(start, stop) + l.align = registry.get_value('align') + if l.align == 'right' then + l.kern_start = - l.text_width l.kern_stop = 0 - elseif align == 'center' then + elseif l.align == 'center' then l.half = (l.width - l.text_width) / 2 - l.kern_start = -l.half - l.text_width + l.kern_start = - l.half - l.text_width l.kern_stop = l.half else - l.kern_start = -l.width + l.kern_start = - l.width l.kern_stop = l.width - l.text_width end - head, n.line = nodex.insert_line(head, n.start, l.width) + return l.width, l.kern_start, l.kern_stop +end +function cloze.fix_make(start, stop) + local l = {} -- length + local n = {} -- node + l.width, l.kern_start, l.kern_stop = cloze.fix_length(start, stop) + n.line = nodex.insert_line(start, l.width) if registry.get_value_show() then - n.kern_start = nodex.create_kern(l.kern_start) - head, n.kern_start = node.insert_after(head, n.line, n.kern_start) - n.color_text = nodex.create_color('text') - node.insert_after(head, n.kern_start, n.color_text) - n.color_reset = nodex.create_color('reset') - node.insert_before(head, n.stop, n.color_reset) - n.kern_stop = nodex.create_kern(l.kern_stop) - node.insert_before(head, n.stop, n.kern_stop) + nodex.insert_list( + 'after', + n.line, + { + nodex.create_kern(l.kern_start), + nodex.create_color('text') + } + ) + nodex.insert_list( + 'before', + stop, + { + nodex.create_color('reset'), + nodex.create_kern(l.kern_stop) + }, + start + ) else - n.line.next = n.stop.next + n.line.next = stop.next end + registry.remove_marker(start) + registry.remove_marker(stop) end -function cloze.fix(head) +function cloze.fix_recursion(head) local n = {} -- node n.start, n.stop = false - for current in node.traverse_id(node.id('whatsit'), head) do - if not n.start then - n.start = registry.get_marker(current, 'fix', 'start') - end - if not n.stop then - n.stop = registry.get_marker(current, 'fix', 'stop') - end - if n.start and n.stop then - cloze.fix_make(head, n.start, n.stop) - n.start, n.stop = false + while head do + if head.head then + cloze.fix_recursion(head.head) + else + if not n.start then + n.start = registry.get_marker(head, 'fix', 'start') + end + if not n.stop then + n.stop = registry.get_marker(head, 'fix', 'stop') + end + if n.start and n.stop then + cloze.fix_make(n.start, n.stop) + n.start, n.stop = false + end end + head = head.next end +end +function cloze.fix(head) + cloze.fix_recursion(head) return head end function cloze.par(head) @@ -348,15 +412,21 @@ function cloze.par(head) end l.width = hlist.width hlist, n.strut, n.head = nodex.strut_to_hlist(hlist) - head, n.line = nodex.insert_line(head, n.strut, l.width) + n.line = nodex.insert_line(n.strut, l.width) if registry.get_value_show() then - n.kern = nodex.create_kern(-l.width) - head, n.kern = node.insert_after(head, n.line, n.kern) - n.color_text = nodex.create_color('text') - node.insert_after(head, n.kern, n.color_text) - n.tail = node.tail(n.head) - n.color_reset = nodex.create_color('reset') - node.insert_after(n.head, n.tail, n.color_reset) + nodex.insert_list( + 'after', + n.line, + { + nodex.create_kern(-l.width), + nodex.create_color('text') + } + ) + nodex.insert_list( + 'after', + node.tail(head), + {nodex.create_color('reset')} + ) else n.line.next = nil end @@ -364,6 +434,7 @@ function cloze.par(head) return head end function base.register(mode) + local basic if mode == 'par' then luatexbase.add_to_callback( 'post_linebreak_filter', -- cgit v1.2.3