From 8c2101ffbcbcfbf4f32b53a8d813b740ea2d9f2f Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Wed, 8 Jul 2015 22:34:57 +0000 Subject: cloze (8jul15) git-svn-id: svn://tug.org/texlive/trunk@37811 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/scripts/cloze/cloze.lua | 414 ++++++++++++++++++++++++++++++ 1 file changed, 414 insertions(+) create mode 100755 Master/texmf-dist/scripts/cloze/cloze.lua (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 new file mode 100755 index 00000000000..dc05de9af43 --- /dev/null +++ b/Master/texmf-dist/scripts/cloze/cloze.lua @@ -0,0 +1,414 @@ +if not modules then modules = { } end modules ['cloze'] = { + version = '0.1', + comment = 'cloze', + author = 'Josef Friedrich, R.-M. Huber', + copyright = 'Josef Friedrich, R.-M. Huber', + license = 'The LaTeX Project Public License Version 1.3c 2008-05-04' +} +local nodex = {} +local registry = {} +registry.user_id = 3121978 +registry.storage = {} +registry.defaults = { + ['align'] = 'l', + ['distance'] = '1.5pt', + ['hide'] = false, + ['linecolor'] = '0 0 0 rg 0 0 0 RG', -- black + ['margin'] = '3pt', + ['resetcolor'] = '0 0 0 rg 0 0 0 RG', -- black + ['show_text'] = true, + ['show'] = true, + ['textcolor'] = '0 0 1 rg 0 0 1 RG', -- blue + ['thickness'] = '0.4pt', + ['width'] = '2cm', +} +registry.global_options = {} +registry.local_options = {} +local cloze = {} +local base = {} +base.is_registered = {} +function nodex.create_colorstack(data) + if not data then + data = '0 0 0 rg 0 0 0 RG' -- black + end + local whatsit = node.new('whatsit', 'pdf_colorstack') + whatsit.stack = 0 + whatsit.data = data + return whatsit +end +function nodex.create_color(option) + local data + if option == 'line' then + data = registry.get_value('linecolor') + elseif option == 'text' then + data = registry.get_value('textcolor') + elseif option == 'reset' then + data = nil + else + data = nil + end + return nodex.create_colorstack(data) +end +function nodex.create_line(width) + local rule = node.new(node.id('rule')) + local thickness = tex.sp(registry.get_value('thickness')) + local distance = tex.sp(registry.get_value('distance')) + rule.depth = distance + thickness + rule.height = - distance + 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) +end +function nodex.write_line() + node.write(nodex.create_color('line')) + node.write(nodex.create_line(tex.sp(registry.get_value('width')))) + node.write(nodex.create_color('reset')) +end +function nodex.create_linefil() + local glue = node.new('glue') + glue.subtype = 100 + local glue_spec = node.new('glue_spec') + glue_spec.stretch = 65536 + glue_spec.stretch_order = 3 + glue.spec = glue_spec + local rule = nodex.create_line(0) + rule.dir = 'TLT' + glue.leader = rule + return glue +end +function nodex.write_linefil() + node.write(nodex.create_color('line')) + node.write(nodex.create_linefil()) + node.write(nodex.create_color('reset')) +end +function nodex.create_kern(width) + local kern = node.new(node.id('kern')) + kern.kern = width + return kern +end +function nodex.strut_to_hlist(hlist) + local n = {} -- node + n.head = hlist.head + n.kern = nodex.create_kern(0) + n.strut = node.insert_before(n.head, n.head, n.kern) + hlist.head = n.head.prev + return hlist, n.strut, n.head +end +function nodex.write_margin() + local kern = nodex.create_kern(tex.sp(registry.get_value('margin'))) + node.write(kern) +end +function registry.create_marker(index) + local marker = node.new('whatsit','user_defined') + marker.type = 100 -- number + marker.user_id = registry.user_id + marker.value = index + return marker +end +function registry.write_marker(mode, position) + local index = registry.set_storage(mode, position) + local marker = registry.create_marker(index) + node.write(marker) +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 + return true + else + return false + end +end +function registry.get_marker(item, mode, position) + local out + if registry.check_marker(item, mode, position) then + out = item + else + out = false + end + if out and position == 'start' then + registry.get_marker_values(item) + end + return out +end +function registry.get_marker_data(item) + if item.id == node.id('whatsit') + and item.subtype == 44 + and item.user_id == registry.user_id then + return registry.get_storage(item.value) + else + return false + end +end +function registry.get_marker_values(marker) + local data = registry.get_marker_data(marker) + registry.local_options = data.values + return data.values +end +function registry.get_index() + if not registry.index then + registry.index = 0 + end + registry.index = registry.index + 1 + return registry.index +end +function registry.set_storage(mode, position) + local index = registry.get_index() + local data = { + ['mode'] = mode, + ['position'] = position + } + data.values = registry.local_options + registry.storage[index] = data + return index +end +function registry.get_storage(index) + return registry.storage[index] +end +function registry.set_option(key, value) + if value == '' or value == '\\color@ ' then + return false + end + if registry.is_global == true then + registry.global_options[key] = value + else + registry.local_options[key] = value + end +end +function registry.set_is_global(value) + registry.is_global = value +end +function registry.unset_local_options() + registry.local_options = {} +end +function registry.unset_global_options() + registry.global_options = {} +end +function registry.get_value(key) + if registry.has_value(registry.local_options[key]) then + return registry.local_options[key] + end + if registry.has_value(registry.global_options[key]) then + return registry.global_options[key] + end + return registry.defaults[key] +end +function registry.get_value_show() + if + registry.get_value('show') == true + or + registry.get_value('show') == 'true' + then + return true + else + return false + end +end +function registry.has_value(value) + if value == nil or value == '' or value == '\\color@ ' then + return false + else + return true + end +end +function registry.get_defaults(option) + return registry.defaults[option] +end +function cloze.basic_make(head, hlist, start, stop) + local n = {} + local l = {} + 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, + 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 + ) + 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) + else + n.line.next = n.stop.next + n.stop.prev = n.line.prev + end + +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 + 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 + end + end + return head +end +function cloze.fix_make(head, start, stop) + local l = {} -- length + 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.kern_stop = 0 + elseif align == 'center' then + l.half = (l.width - l.text_width) / 2 + l.kern_start = -l.half - l.text_width + l.kern_stop = l.half + else + 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) + 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) + else + n.line.next = n.stop.next + end +end +function cloze.fix(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 + end + end + return head +end +function cloze.par(head) + local l = {} -- length + local n = {} -- node + for hlist in node.traverse_id(node.id('hlist'), head) do + for whatsit in node.traverse_id(node.id('whatsit'), hlist.head) do + registry.get_marker(whatsit, 'par', 'start') + 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) + 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) + else + n.line.next = nil + end + end + return head +end +function base.register(mode) + if mode == 'par' then + luatexbase.add_to_callback( + 'post_linebreak_filter', + cloze.par, + mode + ) + return true + end + if not base.is_registered[mode] then + if mode == 'basic' then + luatexbase.add_to_callback( + 'post_linebreak_filter', + cloze.basic, + mode + ) + elseif mode == 'fix' then + luatexbase.add_to_callback( + 'pre_linebreak_filter', + cloze.fix, + mode + ) + else + return false + end + base.is_registered[mode] = true + end +end +function base.unregister(mode) + if mode == 'basic' then + luatexbase.remove_from_callback('post_linebreak_filter', mode) + elseif mode == 'fix' then + luatexbase.remove_from_callback('pre_linebreak_filter', mode) + else + luatexbase.remove_from_callback('post_linebreak_filter', mode) + end +end +base.linefil = nodex.write_linefil +base.line = nodex.write_line +base.margin = nodex.write_margin +base.set_option = registry.set_option +base.set_is_global = registry.set_is_global +base.unset_local_options = registry.unset_local_options +base.reset = registry.unset_global_options +base.get_defaults = registry.get_defaults +base.marker = registry.write_marker +return base -- cgit v1.2.3