summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/scripts/cloze
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2015-07-08 22:34:57 +0000
committerKarl Berry <karl@freefriends.org>2015-07-08 22:34:57 +0000
commit8c2101ffbcbcfbf4f32b53a8d813b740ea2d9f2f (patch)
tree34985b2d8bf8ce1c937427c4311136ccd6bc2b33 /Master/texmf-dist/scripts/cloze
parentb94fdf191429ee29a013736ff6c683495480d3dd (diff)
cloze (8jul15)
git-svn-id: svn://tug.org/texlive/trunk@37811 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/scripts/cloze')
-rwxr-xr-xMaster/texmf-dist/scripts/cloze/cloze.lua414
1 files changed, 414 insertions, 0 deletions
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