diff options
author | Karl Berry <karl@freefriends.org> | 2020-05-27 21:40:08 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2020-05-27 21:40:08 +0000 |
commit | 609b1679823e76c76ff093008fd840e1a10ca02b (patch) | |
tree | 445bde2ec4a1355d3220918907ba68549528e520 /Master | |
parent | c25adb343a3ddbab8ff40167b3f6b40d7713cee6 (diff) |
cloze (27may20)
git-svn-id: svn://tug.org/texlive/trunk@55296 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
-rw-r--r-- | Master/texmf-dist/doc/lualatex/cloze/README | 53 | ||||
-rw-r--r-- | Master/texmf-dist/doc/lualatex/cloze/README.md | 54 | ||||
-rw-r--r-- | Master/texmf-dist/doc/lualatex/cloze/cloze.pdf | bin | 257712 -> 318609 bytes | |||
-rwxr-xr-x | Master/texmf-dist/scripts/cloze/cloze.lua | 702 | ||||
-rw-r--r-- | Master/texmf-dist/source/lualatex/cloze/cloze.dtx | 1207 | ||||
-rw-r--r-- | Master/texmf-dist/source/lualatex/cloze/cloze.ins | 9 | ||||
-rw-r--r-- | Master/texmf-dist/tex/lualatex/cloze/cloze.sty | 4 |
7 files changed, 813 insertions, 1216 deletions
diff --git a/Master/texmf-dist/doc/lualatex/cloze/README b/Master/texmf-dist/doc/lualatex/cloze/README deleted file mode 100644 index 1369553b812..00000000000 --- a/Master/texmf-dist/doc/lualatex/cloze/README +++ /dev/null @@ -1,53 +0,0 @@ -# Description - -EN: `cloze` is a LuaLaTeX/LaTeX package to generate cloze. It uses the -capabilities of the modern TeX engine LuaTex. - -DE: `cloze` ist a LuaLaTeX/LaTeX-Paket zum Erstellen von Lückentexten. -Es nutzt die Möglichkeiten der modernen TeX-Engine LuaTeX. - -# License - -Copyright (C) 2015 by Josef Friedrich <josef@friedrich.rocks> ------------------------------------------------------------------------- -This work may be distributed and/or modified under the conditions of -the LaTeX Project Public License, either version 1.3 of this license -or (at your option) any later version. The latest version of this -license is in: - - http://www.latex-project.org/lppl.txt - -and version 1.3 or later is part of all distributions of LaTeX -version 2005/12/01 or later. - -# CTAN - -Since July 2015 the cloze package is included in the Comprehensive TeX -Archive Network (CTAN). - -* TeX archive: http://mirror.ctan.org/tex-archive/macros/luatex/latex/cloze -* Package page: https://www.ctan.org/pkg/cloze - -# Repository - -https://github.com/Josef-Friedrich/cloze - -# Installation - -Get source: - - git clone git@github.com:Josef-Friedrich/cloze.git - cd cloze - -Compile: - - make - -or manually: - - luatex cloze.ins - lualatex cloze.dtx - makeindex -s gglo.ist -o cloze.gls cloze.glo - makeindex -s gind.ist -o cloze.ind cloze.idx - lualatex cloze.dtx - diff --git a/Master/texmf-dist/doc/lualatex/cloze/README.md b/Master/texmf-dist/doc/lualatex/cloze/README.md index 1369553b812..04dc316ef3d 100644 --- a/Master/texmf-dist/doc/lualatex/cloze/README.md +++ b/Master/texmf-dist/doc/lualatex/cloze/README.md @@ -8,7 +8,7 @@ Es nutzt die Möglichkeiten der modernen TeX-Engine LuaTeX. # License -Copyright (C) 2015 by Josef Friedrich <josef@friedrich.rocks> +Copyright (C) 2015-2020 by Josef Friedrich <josef@friedrich.rocks> ------------------------------------------------------------------------ This work may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3 of this license @@ -46,8 +46,56 @@ Compile: or manually: luatex cloze.ins - lualatex cloze.dtx + lualatex --shell-escape cloze.dtx makeindex -s gglo.ist -o cloze.gls cloze.glo makeindex -s gind.ist -o cloze.ind cloze.idx - lualatex cloze.dtx + lualatex --shell-escape cloze.dtx +# Development + +First delete the stable version installed by TeX Live. Because the +package `cloze` belongs to the collection `collection-latexextra`, the +option `--force` must be used to delete the package. + + tlmgr remove --force cloze + +## Deploying a new version + +Update the version number in the file `cloze.dtx` on this locations: + +### In the markup for the file `cloze.sty` (approximately at the line number 30) + + %<*package> + [2020/05/20 v1.4 Package to typeset cloze worksheets or cloze tests] + %<*package> + +### In the markup for the package documentation (approximately at the line number 1250) + +Add a changes entry: + +```latex +\changes{v1.4}{2020/05/20}{...} +``` + +### In the markup for the file `cloze.lua` (approximately at the line number 1900) + +```lua +if not modules then modules = { } end modules ['cloze'] = { + version = '1.4' +} +``` + +### Update the copyright year: + +``` +sed -i 's/(C) 2015-2020/(C) 2015-2021/g' cloze.ins +sed -i 's/(C) 2015-2020/(C) 2015-2021/g' cloze.dtx +``` + +### Command line tasks: + +``` +git tag v1.4 +make +make ctan +``` diff --git a/Master/texmf-dist/doc/lualatex/cloze/cloze.pdf b/Master/texmf-dist/doc/lualatex/cloze/cloze.pdf Binary files differindex 7afedd6a8ca..8f9b26bf235 100644 --- a/Master/texmf-dist/doc/lualatex/cloze/cloze.pdf +++ b/Master/texmf-dist/doc/lualatex/cloze/cloze.pdf diff --git a/Master/texmf-dist/scripts/cloze/cloze.lua b/Master/texmf-dist/scripts/cloze/cloze.lua index 41b5ea00f02..b9490354a5b 100755 --- a/Master/texmf-dist/scripts/cloze/cloze.lua +++ b/Master/texmf-dist/scripts/cloze/cloze.lua @@ -1,12 +1,39 @@ +--- Cloze uses [LDoc](https://github.com/stevedonovan/ldoc) for the +-- source code documentation. The supported tags are described on in +-- the [wiki](https://github.com/stevedonovan/LDoc/wiki). +-- +-- <h3>Naming conventions</h3> +-- +-- * _Variable_ names for _nodes_ are suffixed with `_node`, for example +-- `head_node`. +-- * _Variable_ names for _lengths_ (dimensions) are suffixed with +-- `_length`, for example `width_length`. +-- +-- @module cloze + +-- __cloze.lua}__ + +-- __Initialisation of the function tables__ + +-- It is good form to provide some background informations about this Lua +-- module. if not modules then modules = { } end modules ['cloze'] = { - version = '1.4', + version = '1.5', 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' } + +--- `nodex` is a abbreviation for __node eXtended__. local nodex = {} + +--- All values and functions, which are related to the option management, +-- are stored in a table called `registry`. local registry = {} + +--- I didn't know what value I should take as `user_id`. Therefore I +-- took my birthday and transformed it to a large number. registry.user_id = 3121978 registry.storage = {} registry.defaults = { @@ -30,10 +57,31 @@ registry.defaults = { } registry.global_options = {} registry.local_options = {} + +-- All those functions are stored in the table `cloze` that are +-- registered as callbacks to the pre and post linebreak filters. local cloze = {} +-- In the status table are stored state information, which are necessary +-- for the recursive cloze generation. cloze.status = {} + +-- The `base` table contains some basic functions. `base` is the only +-- table of this Lua module that will be exported. local base = {} base.is_registered = {} + +--- Node precessing (nodex) +-- @section nodex + +-- All functions in this section are stored in a table called `nodex`. +-- `nodex` is a abbreviation for __node eXtended__. The `nodex` table +-- bundles all functions, which extend the built-in `node` library. + +-- __Color handling (color)__ + +-- __create_colorstack__ +-- Create a whatsit node of the subtype `pdf_colorstack`. `data` is a PDF +-- colorstack string like `0 0 0 rg 0 0 0 RG`. function nodex.create_colorstack(data) if not data then data = '0 0 0 rg 0 0 0 RG' -- black @@ -43,6 +91,12 @@ function nodex.create_colorstack(data) whatsit.data = data return whatsit end + +--- +-- `nodex.create_color()` is a wrapper for the function +-- `nodex.create_colorstack()`. It queries the current values of the +-- options `linecolor` and `textcolor`. The argument `option` accepts the +-- strings `line`, `text` and `reset`. function nodex.create_color(option) local data if option == 'line' then @@ -56,6 +110,13 @@ function nodex.create_color(option) end return nodex.create_colorstack(data) end + +-- __Line handling (line)__ + +--- Create a rule node, which is used as a line for the cloze texts. The +-- `depth` and the `height` of the rule are calculated form the options +-- `thickness` and `distance`. The argument `width` must have the length +-- unit __scaled points__. function nodex.create_line(width) local rule = node.new(node.id('rule')) local thickness = tex.sp(registry.get_value('thickness')) @@ -65,19 +126,55 @@ function nodex.create_line(width) rule.width = width return rule end -function nodex.insert_list(position, current, list, head) - if not head then - head = current + +--- Insert a `list` of nodes after or before the `current`. The `head` +-- argument is optional. In some edge cases it is unfortately necessary. +-- if `head` is omitted the `current` node is used. The argument +-- `position` can take the values `'after'` or `'before'`. +function nodex.insert_list(position, current, list, head_node) + if not head_node then + head_node = current end for i, insert in ipairs(list) do if position == 'after' then - head, current = node.insert_after(head, current, insert) + head_node, current = node.insert_after(head_node, current, insert) elseif position == 'before' then - head, current = node.insert_before(head, current, insert) + head_node, current = node.insert_before(head_node, current, insert) end end return current end + +--- Enclose a rule node (cloze line) with two PDF colorstack whatsits. +-- The first colorstack node dyes the line, the seccond resets the +-- color. +-- +-- __Node list__ +-- +-- <table> +-- <thead> +-- <tr> +-- <th>`n.color_line`</th> +-- <th>`whatsit`</th> +-- <th>`pdf_colorstack`</th> +-- <th>Line color</th> +-- </tr> +-- </thead> +-- <tbody> +-- <tr> +-- <td>`n.line`</td> +-- <td>`rule`</td> +-- <td></td> +-- <td>`width`</td> +-- </tr> +-- <tr> +-- <td>`n.color_reset`</td> +-- <td>`whatsit`</td> +-- <td>`pdf_colorstack`</td> +-- <td>Reset color</td> +-- </tr> +-- </tbody> +-- </table> function nodex.insert_line(current, width) return nodex.insert_list( 'after', @@ -89,11 +186,48 @@ function nodex.insert_line(current, width) } ) end + +--- This function enclozes a rule node with color nodes as it the function +-- `nodex.insert_line` does. In contrast to `nodex.insert_line` the three +-- nodes are appended to \TeX’s ‘current list’. They are not inserted in +-- a node list, which is accessed by a Lua callback. +-- +-- __Node list__ +-- +-- <table> +-- <thead> +-- <tr> +-- <th>-</th> +-- <th>`whatsit`</th> +-- <th>`pdf_colorstack`</th> +-- <th>Line color</th> +-- </tr> +-- </thead> +-- <tbody> +-- <tr> +-- <td>-</td> +-- <td>`rule`</td> +-- <td></td> +-- <td>`width`</td> +-- </tr> +-- <tr> +-- <td>-</td> +-- <td>`whatsit`</td> +-- <td>`pdf_colorstack`</td> +-- <td>Reset color</td> +-- </tr> +-- </tbody> +-- </table> 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 + +-- __Handling of extendable lines (linefil)__ + +--- This function creates a line which stretchs indefinitely in the +-- horizontal direction. function nodex.create_linefil() local glue = node.new('glue') glue.subtype = 100 @@ -104,37 +238,90 @@ function nodex.create_linefil() glue.leader = rule return glue end + +--- The function `nodex.write_linefil` surrounds a indefinitely strechable +-- line with color whatsits and puts it to \TeX’s ‘current (node) list’. 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 + +-- __Kern handling (kern)__ + +--- This function creates a kern node with a given width. The argument +-- `width` had to be specified in scaled points. +local function create_kern_node(width) + local kern_node = node.new(node.id('kern')) + kern_node.kern = width + return kern_node +end + +--- Add at the beginning of each `hlist` node list a strut (a invisible +-- character). +-- +-- Now we can add line, color etc. nodes after the first node of a hlist +-- not before - after is much more easier. +-- +-- @tparam node hlist_node +-- +-- @treturn node hlist_node +-- @treturn node strut_node +-- @treturn node head_node +local function insert_strut_into_hlist(hlist_node) + local head_node = hlist_node.head + local kern_node = create_kern_node(0) + local strut_node = node.insert_before(hlist_node.head, head_node, kern_node) + hlist_node.head = head_node.prev + return hlist_node, strut_node, head_node +end + +--- Write kern nodes to the current node list. This kern nodes can be used +-- to build a margin. function nodex.write_margin() - local kern = nodex.create_kern(tex.sp(registry.get_value('margin'))) + local kern = create_kern_node(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) + +--- Search for a `hlist` (subtype `line`). +-- +-- Insert a strut node into the list if a hlist is found. +-- +-- @tparam node head_node The head of a node list. +-- +-- @treturn node|false Return false, if no `hlist` can +-- be found. +local function search_hlist(head_node) + while head_node do + if head_node.id == node.id('hlist') and head_node.subtype == 1 then + return insert_strut_into_hlist(head_node) end - head = head.next + head_node = head_node.next end return false end + +--- Option handling. +-- +-- The table `registry` bundels functions that deal with option handling. +-- +-- <h2>Marker processing (marker)</h2> +-- +-- A marker is a whatsit node of the subtype `user_defined`. A marker has +-- two purposes: +-- +-- * Mark the begin and the end of a gap. +-- * Store a index number, that points to a Lua table, which holds +-- some additional data like the local options. +-- @section registry + +--- We create a user defined whatsit node that can store a number (type +-- = 100). +-- +-- In order to distinguish this node from other user defined whatsit +-- nodes we set the `user_id` to a large number. We call this whatsit +-- node a marker. The argument `index` is a number, which is associated +-- to values in the `registry.storage` table. function registry.create_marker(index) local marker = node.new('whatsit','user_defined') marker.type = 100 -- number @@ -142,11 +329,19 @@ function registry.create_marker(index) marker.value = index return marker end + +--- Write a marker node to \TeX's current node list. +-- +-- The argument `mode` accepts the string values `basic`, `fix` and +-- `par`. The argument `position`. The argument `position` is either set +-- to `start` or to `stop`. function registry.write_marker(mode, position) local index = registry.set_storage(mode, position) local marker = registry.create_marker(index) node.write(marker) end + +--- This functions checks if the given node `item` is a marker. function registry.is_marker(item) if item.id == node.id('whatsit') and item.subtype == node.subtype('user_defined') @@ -156,6 +351,12 @@ function registry.is_marker(item) return false end end + +--- This functions tests, whether the given node `item` is a marker. +-- +-- The argument `item` is a node. The argument `mode` accepts the string +-- values `basic`, `fix` and `par`. The argument `position` is either +-- set to `start` or to `stop`. 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 @@ -164,6 +365,12 @@ function registry.check_marker(item, mode, position) return false end end + +--- `registry.get_marker` returns the given marker. +-- +-- The argument `item` is a node. The argument `mode` accepts the string +-- values `basic`, `fix` and `par`. The argument `position` is either +-- set to `start` or to `stop`. function registry.get_marker(item, mode, position) local out if registry.check_marker(item, mode, position) then @@ -176,6 +383,11 @@ function registry.get_marker(item, mode, position) end return out end + +--- `registry.get_marker_data` tests whether the node `item` is a +-- marker. +-- +-- The argument `item` is a node of unspecified type. function registry.get_marker_data(item) if item.id == node.id('whatsit') and item.subtype == node.subtype('user_defined') @@ -185,14 +397,27 @@ function registry.get_marker_data(item) return false end end + +--- First this function saves the associatied values of a marker to the +-- local options table. Second it returns this values. The argument +-- `marker` is a whatsit node. function registry.get_marker_values(marker) local data = registry.get_marker_data(marker) registry.local_options = data.values return data.values end + +--- This function removes a given whatsit marker. +-- +-- It only deletes a node, if a marker is given. function registry.remove_marker(marker) if registry.is_marker(marker) then node.remove(marker, marker) end end + +-- __Storage functions (storage)__ + +--- `registry.index` is a counter. The functions `registry.get_index()` +-- increases the counter by one and then returns it. function registry.get_index() if not registry.index then registry.index = 0 @@ -200,6 +425,13 @@ function registry.get_index() registry.index = registry.index + 1 return registry.index end + +--- `registry.set_storage()` stores the local options in the Lua table +-- `registry.storage`. +-- +-- It returns a numeric index number. This index number is the key, +-- where the local options in the Lua table are stored. The argument +-- `mode` accepts the string values `basic`, `fix` and `par`. function registry.set_storage(mode, position) local index = registry.get_index() local data = { @@ -210,9 +442,23 @@ function registry.set_storage(mode, position) registry.storage[index] = data return index end + +--- The function `registry.get_storage()` retrieves values which belong +-- to a whatsit marker. +-- +-- The argument `index` is a numeric value. function registry.get_storage(index) return registry.storage[index] end + +-- __Option processing (option)__ + +--- This function stores a value `value` and his associated key `key` +-- either to the global (`registry.global_options`) or to the local +-- (`registry.local_options`) option table. +-- +-- The global boolean variable `registry.local_options` controls in +-- which table the values are stored. function registry.set_option(key, value) if value == '' or value == '\\color@ ' then return false @@ -223,15 +469,27 @@ function registry.set_option(key, value) registry.local_options[key] = value end end + +--- `registry.set_is_global()` sets the variable `registry.is_global` to +-- the value `value`. It is intended, that the variable takes boolean +-- values. function registry.set_is_global(value) registry.is_global = value end + +--- This function unsets the local options. function registry.unset_local_options() registry.local_options = {} end + +--- `registry.unset_global_options` empties the global options storage. function registry.unset_global_options() registry.global_options = {} end + +--- Retrieve a value from a given key. First search for the value in the +-- local options, then in the global options. If both option storages are +-- empty, the default value will be returned. function registry.get_value(key) if registry.has_value(registry.local_options[key]) then return registry.local_options[key] @@ -241,6 +499,12 @@ function registry.get_value(key) end return registry.defaults[key] end + + +--- The function `registry.get_value_show()` returns the boolean value +-- `true` if the option `show` is true. In contrast to the function +-- `registry.get_value()` it converts the string value `true' to a +-- boolean value. function registry.get_value_show() if registry.get_value('show') == true @@ -252,6 +516,9 @@ function registry.get_value_show() return false end end + +--- This function tests whether the value `value` is not empty and has a +-- value. function registry.has_value(value) if value == nil or value == '' or value == '\\color@ ' then return false @@ -259,84 +526,120 @@ function registry.has_value(value) return true end end + +--- `registry.get_defaults(option)` returns a the default value of the +-- given option. function registry.get_defaults(option) return registry.defaults[option] end -function cloze.basic_make(start, stop) - local n = {} - local l = {} - n.head = start - if not start or not stop then + +--- Assembly to cloze texts. +-- @section cloze_functions + +--- The function `cloze.basic_make()` makes one gap. The argument `start` +-- is the node, where the gap begins. The argument `stop` is the node, +-- where the gap ends. +function cloze.basic_make(start_node, end_node) + local node_head = start_node + if not start_node or not end_node then return end - n.start = start - n.stop = stop - l.width = node.dimensions( + local line_width = node.dimensions( cloze.status.hlist.glue_set, cloze.status.hlist.glue_sign, cloze.status.hlist.glue_order, - n.start, - n.stop + start_node, + end_node ) - n.line = nodex.insert_line(n.start, l.width) - n.color_text = nodex.insert_list('after', n.line, {nodex.create_color('text')}) + local line_node = nodex.insert_line(start_node, line_width) + local color_text_node = nodex.insert_list('after', line_node, {nodex.create_color('text')}) if registry.get_value_show() then - nodex.insert_list('after', n.color_text, {nodex.create_kern(-l.width)}) - nodex.insert_list('before', n.stop, {nodex.create_color('reset')}, n.head) + nodex.insert_list('after', color_text_node, {create_kern_node(-line_width)}) + nodex.insert_list('before', end_node, {nodex.create_color('reset')}, node_head) else - n.line.next = n.stop.next - n.stop.prev = n.line.prev + line_node.next = end_node.next + end_node.prev = line_node -- not line_node.prev -> line color leaks out end - registry.remove_marker(n.start) - registry.remove_marker(n.stop) -end -function cloze.basic_search_stop(head) - local stop - while head do + -- In some edge cases the lua callbacks get fired up twice. After the + -- cloze has been created, the start and stop whatsit markers can be + -- deleted. + registry.remove_marker(start_node) + registry.remove_marker(end_node) +end + +--- Search for a stop marker. +-- +-- @tparam node head_node The head of a node list. +-- +-- @treturn node The end node. +function cloze.basic_search_stop(head_node) + local end_node + while head_node do cloze.status.continue = true - stop = head - if registry.check_marker(stop, 'basic', 'stop') then + end_node = head_node + if registry.check_marker(end_node, 'basic', 'stop') then cloze.status.continue = false break end - head = head.next + head_node = head_node.next end - return stop -end -function cloze.basic_search_start(head) - local start - local stop - local n = {} + return end_node +end + +--- Search for a start marker or begin a new cloze if the value +-- `cloze.status.continue` is true. +-- +-- We have to find a hlist node and use its on the field `head` +-- attached node list to search for a start marker. +-- +-- @tparam node head_node The head of a node list. +function cloze.basic_search_start(head_node) + local start_node, end_node, hlist_node 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 + hlist_node = search_hlist(head_node) + if hlist_node then + cloze.status.hlist = hlist_node + start_node = hlist_node.head end - elseif registry.check_marker(head, 'basic', 'start') then - start = head + elseif registry.check_marker(head_node, 'basic', 'start') then + start_node = head_node end - if start then - stop = cloze.basic_search_stop(start) - cloze.basic_make(start, stop) + if start_node then + end_node = cloze.basic_search_stop(start_node) + cloze.basic_make(start_node, end_node) end end -function cloze.basic_recursion(head) - while head do - if head.head then - cloze.status.hlist = head - cloze.basic_recursion(head.head) + +--- Parse the node tree recursivley. +-- +-- Start and end markers could be nested deeply in the node tree. +-- +-- @tparam node head_node The head of a node list. +function cloze.basic_recursion(head_node) + while head_node do + if head_node.head then + cloze.status.hlist = head_node + cloze.basic_recursion(head_node.head) else - cloze.basic_search_start(head) + cloze.basic_search_start(head_node) end - head = head.next + head_node = head_node.next end end -function cloze.basic(head) + +--- The corresponding LaTeX command to this lua function is `\cloze`. +-- +-- @tparam node head_node The head of a node list. +-- +-- @treturn node The head of the node list. +function cloze.basic(head_node) cloze.status.continue = false - cloze.basic_recursion(head) - return head + cloze.basic_recursion(head_node) + return head_node end + +--- Calculate the length of the whitespace before (`l.kern_start`) and +-- after (`l.kern_stop`) the text. function cloze.fix_length(start, stop) local l = {} l.width = tex.sp(registry.get_value('width')) @@ -355,6 +658,97 @@ function cloze.fix_length(start, stop) end return l.width, l.kern_start, l.kern_stop end + +--- The function `cloze.fix_make` generates a gap of fixed width. +-- +-- __Node lists__ +-- +-- __Show text:__ +-- +-- <table> +-- <tbody> +-- <tr> +-- <td>`n.start`</td> +-- <td>`whatsit`</td> +-- <td>`user_definded`</td> +-- <td>`index`</td> +-- </tr> +-- <tr> +-- <td>`n.line`</td> +-- <td>`rule`</td> +-- <td></td> +-- <td>`l.width`</td> +-- </tr> +-- <tr> +-- <td>`n.kern_start`</td> +-- <td>`kern`</td> +-- <td>& Depends on `align`</td> +-- <td></td> +-- </tr> +-- <tr> +-- <td>`n.color_text`</td> +-- <td>`whatsit`</td> +-- <td>`pdf_colorstack`</td> +-- <td>Text color</td> +-- </tr> +-- <tr> +-- <td></td> +-- <td>`glyphs`</td> +-- <td>& Text to show</td> +-- <td></td> +-- </tr> +-- <tr> +-- <td>`n.color_reset`</td> +-- <td>`whatsit`</td> +-- <td>`pdf_colorstack`</td> +-- <td>Reset color</td> +-- </tr> +-- <tr> +-- <td>`n.kern_stop`</td> +-- <td>`kern`</td> +-- <td>& Depends on `align`</td> +-- <td></td> +-- </tr> +-- <tr> +-- <td>`n.stop`</td> +-- <td>`whatsit`</td> +-- <td>`user_definded`</td> +-- <td>`index`</td> +-- </tr> +-- </tbody> +-- </table> +-- +-- __Hide text:__ +-- +-- <table> +-- <thead> +-- <tr> +-- <th>`n.start`</th> +-- <th>`whatsit`</th> +-- <th>`user_definded`</th> +-- <th>`index`</th> +-- </tr> +-- </thead> +-- <tbody> +-- <tr> +-- <td>`n.line`</td> +-- <td>`rule`</td> +-- <td></td> +-- <td>`l.width`</td> +-- </tr> +-- <tr> +-- <td>`n.stop`</td> +-- <td>`whatsit`</td> +-- <td>`user_definded`</td> +-- <td>`index`</td> +-- </tr> +-- </tbody> +-- </table> +-- +-- Make fixed size cloze. +-- +-- @param start The node, where the gap begins +-- @param stop The node, where the gap ends function cloze.fix_make(start, stop) local l = {} -- length local n = {} -- node @@ -365,7 +759,7 @@ function cloze.fix_make(start, stop) 'after', n.line, { - nodex.create_kern(l.kern_start), + create_kern_node(l.kern_start), nodex.create_color('text') } ) @@ -374,7 +768,7 @@ function cloze.fix_make(start, stop) stop, { nodex.create_color('reset'), - nodex.create_kern(l.kern_stop) + create_kern_node(l.kern_stop) }, start ) @@ -384,61 +778,164 @@ function cloze.fix_make(start, stop) registry.remove_marker(start) registry.remove_marker(stop) end -function cloze.fix_recursion(head) + +--- Function to recurse the node list and search after marker. +-- +-- @tparam node head_node The head of a node list. +function cloze.fix_recursion(head_node) local n = {} -- node n.start, n.stop = false - while head do - if head.head then - cloze.fix_recursion(head.head) + while head_node do + if head_node.head then + cloze.fix_recursion(head_node.head) else if not n.start then - n.start = registry.get_marker(head, 'fix', 'start') + n.start = registry.get_marker(head_node, 'fix', 'start') end if not n.stop then - n.stop = registry.get_marker(head, 'fix', 'stop') + n.stop = registry.get_marker(head_node, '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 + head_node = head_node.next end end -function cloze.fix(head) - cloze.fix_recursion(head) - return head -end -function cloze.par(head) + +--- The corresponding LaTeX command to this Lua function is `\clozefix`. +-- +-- @tparam node head_node The head of a node list. +function cloze.fix(head_node) + cloze.fix_recursion(head_node) + return head_node +end + +--- The corresponding LaTeX environment to this lua function is +-- `clozepar`. +-- +-- __Node lists__ +-- +-- __Show text:__ +-- +-- <table> +-- <thead> +-- <tr> +-- <th>`n.strut`</th> +-- <th>`kern`</th> +-- <th></th> +-- <th>width = 0</th> +-- </tr> +-- </thead> +-- <tbody> +-- <tr> +-- <td>`n.line`</td> +-- <td>`rule`</td> +-- <td></td> +-- <td>`l.width` (Width from hlist)</td> +-- </tr> +-- <tr> +-- <td>`n.kern`</td> +-- <td>`kern`</td> +-- <td></td> +-- <td>`-l.width`</td> +-- </tr> +-- <tr> +-- <td>`n.color_text`</td> +-- <td>`whatsit`</td> +-- <td>`pdf_colorstack`</td> +-- <td>Text color</td> +-- </tr> +-- <tr> +-- <td></td> +-- <td>`glyphs`</td> +-- <td></td> +-- <td>Text to show</td> +-- </tr> +-- <tr> +-- <td>`n.tail`</td> +-- <td>`glyph`</td> +-- <td></td> +-- <td>Last glyph in hlist</td> +-- </tr> +-- <tr> +-- <td>`n.color_reset`</td> +-- <td>`whatsit`</td> +-- <td>`pdf_colorstack`</td> +-- <td>Reset color</td> +-- </tr> +-- </tbody> +-- </table> +-- +-- __Hide text:__ +-- +-- <table> +-- <thead> +-- <tr> +-- <th>`n.strut`</th> +-- <th>`kern`</th> +-- <th></th> +-- <th>width = 0</th> +-- </tr> +-- </thead> +-- <tbody> +-- <tr> +-- <td>`n.line`</td> +-- <td>`rule`</td> +-- <td></td> +-- <td>`l.width` (Width from hlist)</td> +-- </tr> +-- </tbody> +-- </table> +-- +-- @tparam node head_node The head of a node list. +function cloze.par(head_node) local l = {} -- length local n = {} -- node - for hlist in node.traverse_id(node.id('hlist'), head) do + for hlist in node.traverse_id(node.id('hlist'), head_node) 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) + hlist, n.strut, n.head = insert_strut_into_hlist(hlist) n.line = nodex.insert_line(n.strut, l.width) if registry.get_value_show() then nodex.insert_list( 'after', n.line, { - nodex.create_kern(-l.width), + create_kern_node(-l.width), nodex.create_color('text') } ) nodex.insert_list( 'after', - node.tail(head), + node.tail(head_node), {nodex.create_color('reset')} ) else n.line.next = nil end end - return head -end + return head_node +end + +--- Basic module functions. +-- The `base` table contains functions which are published to the +-- `cloze.sty` file. +-- @section base + +--- This function registers the functions `cloze.par`, `cloze.basic` and +-- `cloze.fix` the Lua callbacks. +-- +-- `cloze.par` and `cloze.basic` are registered to the callback +-- `post_linebreak_filter` and `cloze.fix` to the callback +-- `pre_linebreak_filter`. The argument `mode` accepts the string values +-- `basic`, `fix` and `par`. A special treatment is needed for clozes in +-- display math mode. The `post_linebreak_filter` is not called on +-- display math formulas. I’m not sure if the `pre_output_filter` is the +-- right choice to capture the display math formulas. function base.register(mode) local basic if mode == 'par' then @@ -456,6 +953,11 @@ function base.register(mode) cloze.basic, mode ) + luatexbase.add_to_callback( + 'pre_output_filter', + cloze.basic, + mode + ) elseif mode == 'fix' then luatexbase.add_to_callback( 'pre_linebreak_filter', @@ -468,15 +970,24 @@ function base.register(mode) base.is_registered[mode] = true end end + +--- `base.unregister(mode)` deletes the registered functions from the +-- Lua callbacks. +-- +-- @tparam string mode The argument `mode` accepts the string values +-- `basic`, `fix` and `par`. function base.unregister(mode) if mode == 'basic' then luatexbase.remove_from_callback('post_linebreak_filter', mode) + luatexbase.remove_from_callback('pre_output_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 + +-- Publish some functions to the `cloze.sty` file. base.linefil = nodex.write_linefil base.line = nodex.write_line base.margin = nodex.write_margin @@ -487,4 +998,5 @@ base.reset = registry.unset_global_options base.get_defaults = registry.get_defaults base.get_value = registry.get_value base.marker = registry.write_marker + return base diff --git a/Master/texmf-dist/source/lualatex/cloze/cloze.dtx b/Master/texmf-dist/source/lualatex/cloze/cloze.dtx index e8d7e3ea171..f2ec1be8c53 100644 --- a/Master/texmf-dist/source/lualatex/cloze/cloze.dtx +++ b/Master/texmf-dist/source/lualatex/cloze/cloze.dtx @@ -28,7 +28,7 @@ %<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01] %<package>\ProvidesPackage{cloze} %<*package> - [2020/05/20 v1.4 Package to typeset cloze worksheets or cloze tests] + [2020/05/27 v1.5 Package to typeset cloze worksheets or cloze tests] %</package> %<*driver> \documentclass{ltxdoc} @@ -52,6 +52,16 @@ urlcolor=red, ]{hyperref} +\usepackage{minted} +\usemintedstyle{colorful} +\BeforeBeginEnvironment{minted}{\begin{mdframed}[backgroundcolor=gray!3]} +\AfterEndEnvironment{minted}{\end{mdframed}} +\setminted{ + breaklines=true, + fontsize=\footnotesize, +} + + \MakeShortVerb{\|} \setlength{\fboxrule}{0.2pt} @@ -357,17 +367,17 @@ Using the option |align| you can make nice tabulars like this: The macro name |clozenol| stands for \emph{“cloze no line”}. As the the name suggests this macro typesets cloze texts without a line. -\begin{verbatim} +\begin{minted}{latex} Lorem \clozenol{ipsum dolor} sit amet. -\end{verbatim} +\end{minted} \begin{example} Lorem \clozenol{ipsum dolor} sit amet. \end{example} -\begin{verbatim} +\begin{minted}{latex} Lorem \clozenol[textcolor=green]{ipsum dolor} sit amet. -\end{verbatim} +\end{minted} \begin{example} Lorem \clozenol[textcolor=green]{ipsum dolor} sit amet. @@ -403,7 +413,7 @@ Ut enim \clozefil{ad minim veniam} exercitation. The command |\clozeextend| adds some invisible placeholders to extend some cloze texts with blank space. -\begin{verbatim} +\begin{minted}{latex} \begin{itemize} \item \clozefil{Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna @@ -411,7 +421,7 @@ aliqua.} \item \clozefil{Ut enim ad minim veniam \clozeextend[20]} \item \clozefil{quis nostrud \clozeextend[20]} \end{itemize} -\end{verbatim} +\end{minted} \begin{example} \begin{itemize} @@ -462,12 +472,12 @@ around the box. Use the options |boxwidth| and |boxheight| to specify the dimensions of the box. By default the width of the box is |\linewidth|. -\begin{verbatim} +\begin{minted}{latex} \begin{clozebox} Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \end{clozebox} -\end{verbatim} +\end{minted} \bigskip \noindent @@ -499,12 +509,12 @@ tempor incididunt ut labore et dolore magna aliqua. \label{sec:command-clozebox-boxwidth} See the documentation about the option \secref{sec:option-boxwidth}. -\begin{verbatim} +\begin{minted}{latex} \begin{clozebox}[boxwidth=5cm] Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \end{clozebox} -\end{verbatim} +\end{minted} \begin{center} \begin{clozebox}[boxwidth=5cm] @@ -517,12 +527,12 @@ tempor incididunt ut labore et dolore magna aliqua. \label{sec:command-clozebox-boxheight} See the documentation about the option \secref{sec:option-boxheight}. -\begin{verbatim} +\begin{minted}{latex} \begin{clozebox}[boxwidth=5cm,boxheight=5cm] Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \end{clozebox} -\end{verbatim} +\end{minted} \begin{center} \begin{clozebox}[boxwidth=5cm,boxheight=5cm] @@ -534,12 +544,12 @@ tempor incididunt ut labore et dolore magna aliqua. \paragraph{starred} % starred -\begin{verbatim} +\begin{minted}{latex} \begin{clozebox}*[boxwidth=5cm,boxheight=5cm] Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \end{clozebox} -\end{verbatim} +\end{minted} \begin{center} \begin{clozebox}*[boxwidth=5cm,boxheight=5cm] @@ -558,7 +568,7 @@ tempor incididunt ut labore et dolore magna aliqua. \DescribeEnv{clozespace} |\begin{clozespace}|\oarg{options} \dots \textit{some text} \dots |\end{clozespace}| -\begin{verbatim} +\begin{minted}{latex} \begin{clozespace}[spacing=2] \clozesetfont{\ttfamily\Huge} Lorem \cloze{ipsum} dolor sit \cloze{amet}, consectetur adipisicing @@ -567,7 +577,7 @@ aliqua. Ut enim ad minim veniam, quis \cloze{nostrud} exercitation ullamco \cloze{laboris} nisi ut aliquip ex ea commodo consequat. \end{clozespace} -\end{verbatim} +\end{minted} \begin{example} \begin{clozespace}[spacing=2] @@ -595,11 +605,11 @@ To create a cloze line of a certain width, use the command \tt{\getdefaults{width}}. In combination with the other cloze commands you can create for example an irregular alignment of the cloze text. -\begin{verbatim} +\begin{minted}{latex} Ut enim ad \clozeline[width=1cm]\cloze{minim}\clozeline[width=3cm] minim veniam -\end{verbatim} +\end{minted} \begin{example} Ut enim ad \clozeline[width=1cm]\cloze{minim}\clozeline[width=3cm] minim @@ -633,17 +643,17 @@ Lorem\clozelinefil \DescribeMacro{\clozestrike} \cmd{\clozestrike}\oarg{options}\marg{wrong text}\marg{correct text} -\begin{verbatim} +\begin{minted}{latex} Lorem \clozestrike{ipsum}{dolor} sit amet. -\end{verbatim} +\end{minted} \begin{example} Lorem \clozestrike{ipsum}{dolor} sit amet. \end{example} -\begin{verbatim} +\begin{minted}{latex} Lorem \clozestrike[textcolor=red]{ipsum}{dolor} sit amet. -\end{verbatim} +\end{minted} \begin{example} Lorem \clozestrike[textcolor=red]{ipsum}{dolor} sit amet. @@ -705,10 +715,10 @@ declaration, the cloze package offers a special command to set \cmd{\clozeset}\marg{global options}: The command can set \emph{global} options for each paragraph. -\begin{verbatim} +\begin{minted}{latex} \clozeset{textcolor=red} Lorem \cloze{ipsum} dolor \par \clozeset{textcolor=green} Lorem \cloze{ipsum} dolor -\end{verbatim} +\end{minted} \begin{example} \clozeset{textcolor=red} Lorem \cloze{ipsum} dolor \par @@ -719,10 +729,10 @@ options for each paragraph. paragraph. As you can see in the example below the last \cmd{\clozeset} applies the color green for both gaps. -\begin{verbatim} +\begin{minted}{latex} \clozeset{textcolor=red} Lorem \cloze{ipsum} dolor \clozeset{textcolor=green} Lorem \cloze{ipsum} dolor -\end{verbatim} +\end{minted} \begin{example} \clozeset{textcolor=red} Lorem \cloze{ipsum} dolor @@ -742,14 +752,14 @@ applies the color green for both gaps. \cmd{\clozereset}: The command resets all \emph{global} options to the default values. It has no effect on the \emph{local} options. -\begin{verbatim} +\begin{minted}{latex} \clozeset{ thickness=3mm, linecolor=yellow, textcolor=magenta, margin=-2pt } -\end{verbatim} +\end{minted} \clozeset{thickness=3mm,linecolor=yellow,textcolor=magenta,margin=-2pt} @@ -757,9 +767,9 @@ default values. It has no effect on the \emph{local} options. Very \cloze{silly} global \cloze{options}. \end{example} -\begin{verbatim} +\begin{minted}{latex} \clozereset -\end{verbatim} +\end{minted} \clozereset \begin{example} @@ -778,9 +788,9 @@ Very \cloze{silly} global \cloze{options}. \cmd{\clozeshow} and \cmd{\clozehide}: This commands are shortcuts for \cmd{\clozeset}\marg{show} and \cmd{\clozeset}\marg{hide}. -\begin{verbatim} +\begin{minted}{latex} \clozehide -\end{verbatim} +\end{minted} \clozehide \begin{example} @@ -788,9 +798,9 @@ Lorem \cloze{ipsum dolor sit} amet, consectetur \cloze{adipisicing} elit. \end{example} -\begin{verbatim} +\begin{minted}{latex} \clozeshow -\end{verbatim} +\end{minted} \clozeshow \begin{example} @@ -914,10 +924,10 @@ options -- |hide| and |show| -- the last option "wins". Values for both color options are color names used by the xcolor package. To define your own color use the following command: -\begin{verbatim} +\begin{minted}{latex} \definecolor{myclozecolor}{rgb}{0.1,0.4,0.6} \cloze[textcolor=myclozecolor]{Lorem ipsum} -\end{verbatim} +\end{minted} \definecolor{myclozecolor}{rgb}{0.1,0.4,0.6} \newcommand{\optioncolor}[2]{% @@ -941,6 +951,17 @@ package. To define your own color use the following command: \optioncolor{linecolor}{green} \end{example} +\noindent +And now hide the clozes: + +\clozehide +\begin{example} +\optioncolor{linecolor}{myclozecolor} +\optioncolor{linecolor}{red} +\optioncolor{linecolor}{green} +\end{example} +\clozeshow + %% % margin %% @@ -1051,18 +1072,72 @@ option is \tt{\getdefaults{width}}. \subsection{Special application areas} +This section lists examples that didn’t work in older versions of +the cloze package and required special treatment to work as expected. + +\subsubsection{The math mode} + +By default the package uses |\itshape| to format the cloze text. In +math mode you have to reset the cloze text format by calling +|\clozesetfont{}|. A known bug ist: You can’t show and hide +single display math formulas. Only the last |\clozeshow| or |\clozehide| +takes effect on the whole document. Side note: The usage of the \TeX +primitive syntax |$$| is not recommended. + +\clozesetfont{} + +\begin{minted}{latex} +\clozesetfont{} +$$1 + 1 = \cloze{2}$$ +\clozesetfont{\itshape} +\end{minted} + +$$1 + 1 = \cloze{2}$$ + +\noindent +|\[\]| should be used instead. + +\begin{minted}{latex} +\[123 + 456 = \cloze{579}\] +\end{minted} + +\[123 + 456 = \cloze{579}\] + +\begin{minted}{latex} +\begin{displaymath} +2^{\cloze{2}} = 4 +\end{displaymath} +\end{minted} + +\begin{displaymath} +2^{\cloze{2}} = 4 +\end{displaymath} + +\noindent +The inline math mode works too: + +\begin{minted}{latex} +${\sqrt[3]{\cloze{8}}} = 2$ and ${\sqrt[\cloze{3}]{\cloze{8}}} = 2$ +\end{minted} + +\begin{center} +${\sqrt[3]{\cloze{8}}} = 2$ and ${\sqrt[\cloze{3}]{\cloze{8}}} = 2$ +\end{center} + +\clozesetfont{\itshape} + %% % tabbing %% \subsubsection{The \tt{tabbing} environment} -\begin{verbatim} +\begin{minted}{latex} \begin{tabbing} col1 \hspace{1cm} \= col2 \hspace{1cm} \= col3 \hspace{1cm} \= col4 \\ \cloze{col1} \> \> \clozefix{col3} \\ \end{tabbing} -\end{verbatim} +\end{minted} \begin{example} \begin{tabbing} @@ -1077,13 +1152,13 @@ col1 \hspace{1cm} \= col2 \hspace{1cm} \= col3 \hspace{1cm} \= col4 \\ \subsubsection{The \tt{picture} environment} -\begin{verbatim} +\begin{minted}{latex} \begin{picture}(320,100) \put(80,25){\cloze{Lorem}} \put(160,50){\clozefix{ipsum}} \put(240,75){\clozefil{dolor}} \end{picture} -\end{verbatim} +\end{minted} \begin{example} \begin{picture}(320,100) @@ -1099,13 +1174,13 @@ col1 \hspace{1cm} \= col2 \hspace{1cm} \= col3 \hspace{1cm} \= col4 \\ \subsubsection{The \tt{tabular} environment} -\begin{verbatim} +\begin{minted}{latex} \begin{tabular}{l c} \cloze{Lorem} & \cloze{ipsum} \\ \clozefix{amet} & \clozefix{consectetur} \\ \cloze{sed} & \cloze{do} \\ \end{tabular} -\end{verbatim} +\end{minted} % No |c| inside because of short verbatim. @@ -1118,68 +1193,32 @@ col1 \hspace{1cm} \= col2 \hspace{1cm} \= col3 \hspace{1cm} \= col4 \\ \end{tabular} \end{example} - \DocInput{cloze.dtx} - \pagebreak - \PrintChanges - \pagebreak - \PrintIndex -\end{document} -%</driver> -%<*readme> -# Description - -EN: `cloze` is a LuaLaTeX/LaTeX package to generate cloze. It uses the -capabilities of the modern TeX engine LuaTex. - -DE: `cloze` ist a LuaLaTeX/LaTeX-Paket zum Erstellen von Lückentexten. -Es nutzt die Möglichkeiten der modernen TeX-Engine LuaTeX. +\section{Some graphics for better understanding of the node tree} -# License +\subsection{Paragraph} -Copyright (C) 2015 by Josef Friedrich <josef@friedrich.rocks> ------------------------------------------------------------------------- -This work may be distributed and/or modified under the conditions of -the LaTeX Project Public License, either version 1.3 of this license -or (at your option) any later version. The latest version of this -license is in: +\noindent\includegraphics[width=\linewidth]{graphics/par} - http://www.latex-project.org/lppl.txt +\subsection{Tabular environment} -and version 1.3 or later is part of all distributions of LaTeX -version 2005/12/01 or later. +\noindent\includegraphics[width=\linewidth]{graphics/tabular} -# CTAN +\subsection{Picture environment} -Since July 2015 the cloze package is included in the Comprehensive TeX -Archive Network (CTAN). +\noindent\includegraphics[width=\linewidth]{graphics/picture} -* TeX archive: http://mirror.ctan.org/tex-archive/macros/luatex/latex/cloze -* Package page: https://www.ctan.org/pkg/cloze +\DocInput{cloze.dtx} -# Repository +\subsection{The file cloze.lua} -https://github.com/Josef-Friedrich/cloze +\inputminted{lua}{cloze.lua} -# Installation - -Get source: - - git clone git@github.com:Josef-Friedrich/cloze.git - cd cloze - -Compile: - - make - -or manually: - - luatex cloze.ins - lualatex cloze.dtx - makeindex -s gglo.ist -o cloze.gls cloze.glo - makeindex -s gind.ist -o cloze.ind cloze.idx - lualatex cloze.dtx - -%</readme> +\pagebreak +\PrintChanges +\pagebreak +\PrintIndex +\end{document} +%</driver> % \fi % % \CheckSum{0} @@ -1202,17 +1241,34 @@ or manually: % % % \changes{v0.1}{2015/06/16}{Converted to DTX file} +% % \changes{v1.0}{2015/07/08}{Inital release} +% % \changes{v1.1}{2016/06/13}{Make cloze compatible to LuaTeX version % 0.95} +% % \changes{v1.2}{2016/06/23}{The cloze makros are now working in % tabular, tabbing and picture environments} +% % \changes{v1.3}{2017/03/13}{Add the new macros \cmd{\clozenol} and % \cmd{\clozeextend} and the environments \texttt{clozebox} and % \texttt{clozespace} (This version was not published on CTAN.)} +% % \changes{v1.4}{2020/05/20}{Add the new macro \cmd{\clozestrike} and % improve the documentation} % +% \changes{v1.5}{2020/05/27}{ +% The Lua part of the package (cloze.lua) is now being developed in a +% separate file. +% The readme file is now a standalone mardown file and not embedded in +% the dtx file any more. +% \href{https://github.com/stevedonovan/LDoc}{LDoc} is being used +% to generate +% \href{https://josef-friedrich.github.io/cloze}{source code documentation}. +% This version fixes two bugs (cloze in display math, line color and +% hide). +% } +% % \DoNotIndex{\newcommand,\newenvironment,\def,\directlua} % % \StopEventually{} @@ -1867,967 +1923,6 @@ or manually: % % \iffalse %</package> -%<*lua> -% \fi -% -% \makeatletter -% \c@CodelineNo 0 \relax -% \makeatother -% -% \subsection{The file \tt{cloze.lua}} -% -% \setlength{\parindent}{0pt} -% -% \paragraph{Initialisation of the function tables} -% -% It is good form to provide some background informations about this Lua -% module. -% \begin{macrocode} -if not modules then modules = { } end modules ['cloze'] = { - version = '1.4', - 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' -} -% \end{macrocode} -% -% |nodex| is a abbreviation for \emph{node eXtended}. -% \begin{macrocode} -local nodex = {} -% \end{macrocode} -% -% All values and functions, which are related to the option management, -% are stored in a table called |registry|. -% -% \begin{macrocode} -local registry = {} -% \end{macrocode} -% -% I didn't know what value I should take as |user_id|. Therefore I took -% my birthday and transformed it to a large number. -% \begin{macrocode} -registry.user_id = 3121978 -registry.storage = {} -registry.defaults = { - ['align'] = 'l', - ['boxheight'] = false, - ['boxwidth'] = '\\linewidth', - ['distance'] = '1.5pt', - ['hide'] = false, - ['linecolor'] = '0 0 0 rg 0 0 0 RG', -- black - ['linecolor_name'] = 'black', - ['margin'] = '3pt', - ['resetcolor'] = '0 0 0 rg 0 0 0 RG', -- black - ['resetcolor_name'] = 'black', - ['show_text'] = true, - ['show'] = true, - ['spacing'] = '1.6', - ['textcolor'] = '0 0 1 rg 0 0 1 RG', -- blue - ['textcolor_name'] = 'blue', -- blue - ['thickness'] = '0.4pt', - ['width'] = '2cm', -} -registry.global_options = {} -registry.local_options = {} -% \end{macrocode} -% -% All those functions are stored in the table |cloze| that are -% registered as callbacks to the pre and post linebreak filters. -% \begin{macrocode} -local cloze = {} -% \end{macrocode} -% In the status table are stored state information, which are necessary -% for the recursive cloze generation. -% \begin{macrocode} -cloze.status = {} -% \end{macrocode} -% -% The |base| table contains some basic functions. |base| is the only -% table of this Lua module that will be exported. -% \begin{macrocode} -local base = {} -base.is_registered = {} -% \end{macrocode} -% -% \subsubsection{Node precessing (nodex)} -% -% All functions in this section are stored in a table called |nodex|. -% |nodex| is a abbreviation for \emph{node eXtended}. The |nodex| table -% bundles all functions, which extend the built-in |node| library. -% -% \paragraph{Color handling (color)} -% -% \clozeluafunction{create_colorstack} -% Create a whatsit node of the subtype |pdf_colorstack|. |data| is a PDF -% colorstack string like |0 0 0 rg 0 0 0 RG|. -% \begin{macrocode} -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 -% \end{macrocode} -% -% \clozeluafunction{create_color} -% |nodex.create_color()| is a wrapper for the function -% |nodex.create_colorstack()|. It queries the current values of the -% options |linecolor| and |textcolor|. The argument |option| accepts the -% strings |line|, |text| and |reset|. -% \begin{macrocode} -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 -% \end{macrocode} -% -% \paragraph{Line handling (line)} -% -% \clozeluafunction{create_line} -% Create a rule node, which is used as a line for the cloze texts. The -% |depth| and the |height| of the rule are calculated form the options -% |thickness| and |distance|. The argument |width| must have the length -% unit \emph{scaled points}. -% \begin{macrocode} -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 -% \end{macrocode} -% -% \clozeluafunction{insert_list} -% Insert a |list| of nodes after or before the |current|. The |head| -% argument is optional. In some edge cases it is unfortately necessary. -% if |head| is omitted the |current| node is used. The argument -% |position| can take the values |'after'| or |'before'|. -% \begin{macrocode} -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 -% \end{macrocode} -% -% \clozeluafunction{insert_line} -% Enclose a rule node (cloze line) with two PDF colorstack whatsits. The -% first colorstack node dyes the line, the seccond resets the color. -% -% \subparagraph*{Node list:} -% -% \begin{nodelist} -% |n.color_line| & |whatsit| & |pdf_colorstack| & Line color \\ -% |n.line| & |rule| & & |width| \\ -% |n.color_reset| & |whatsit| & |pdf_colorstack| & Reset color \\ -% \end{nodelist} -% -% \begin{macrocode} -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 -% \end{macrocode} -% -% \clozeluafunction{write_line} -% This function enclozes a rule node with color nodes as it the function -% |nodex.insert_line| does. In contrast to |nodex.insert_line| the three -% nodes are appended to \TeX’s ‘current list’. They are not inserted in -% a node list, which is accessed by a Lua callback. -% -% \subparagraph*{Node list:} -% -% \begin{nodelist} -% - & |whatsit| & |pdf_colorstack| & Line color \\ -% - & |rule| & & |width| \\ -% - & |whatsit| & |pdf_colorstack| & Reset color \\ -% \end{nodelist} -% -% \begin{macrocode} -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 -% \end{macrocode} -% -% \paragraph{Handling of extendable lines (linefil)} -% -% \clozeluafunction{create_linefil} -% This function creates a line which stretchs indefinitely in the -% horizontal direction. -% \begin{macrocode} -function nodex.create_linefil() - local glue = node.new('glue') - glue.subtype = 100 - glue.stretch = 65536 - glue.stretch_order = 3 - local rule = nodex.create_line(0) - rule.dir = 'TLT' - glue.leader = rule - return glue -end -% \end{macrocode} -% -% \clozeluafunction{write_linefil} -% The function |nodex.write_linefil| surrounds a indefinitely strechable -% line with color whatsits and puts it to \TeX’s ‘current (node) list’. -% \begin{macrocode} -function nodex.write_linefil() - node.write(nodex.create_color('line')) - node.write(nodex.create_linefil()) - node.write(nodex.create_color('reset')) -end -% \end{macrocode} -% -% \paragraph{Kern handling (kern)} -% -% \clozeluafunction{create_kern} -% This function creates a kern node with a given width. The argument -% |width| had to be specified in scaled points. -% \begin{macrocode} -function nodex.create_kern(width) - local kern = node.new(node.id('kern')) - kern.kern = width - return kern -end -% \end{macrocode} -% -% \clozeluafunction{strut_to_hlist} -% To make life easier: We add at the beginning of each hlist a strut. -% Now we can add line, color etc. nodes after the first node of a hlist -% not before - after is much more easier. -% \begin{macrocode} -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 -% \end{macrocode} -% -% \clozeluafunction{write_margin} -% Write kern nodes to the current node list. This kern nodes can be used -% to build a margin. -% \begin{macrocode} -function nodex.write_margin() - local kern = nodex.create_kern(tex.sp(registry.get_value('margin'))) - node.write(kern) -end -% \end{macrocode} -% -% \clozeluafunction{search_hlist} -% Search for a |hlist| (subtype |line|). Return false, if no |hlist| can -% be found. -% \begin{macrocode} -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 -% \end{macrocode} -% -% \subsubsection{Option handling (registry)} -% -% The table |registry| bundels functions that deal with option handling. -% -% \paragraph{Marker processing (marker)} -% -% A marker is a whatsit node of the subtype |user_defined|. A marker has -% two purposes: -% -% \begin{enumerate} -% \item Mark the begin and the end of a gap. -% \item Store a index number, that points to a Lua table, which holds -% some additional data like the local options. -% \end{enumerate} -% -% \clozeluafunction{create_marker} -% We create a user defined whatsit node that can store a number (type = -% 100). In order to distinguish this node from other user defined -% whatsit nodes we set the |user_id| to a large number. We call this -% whatsit node a marker. The argument |index| is a number, which is -% associated to values in the |registry.storage| table. -% \begin{macrocode} -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 -% \end{macrocode} -% -% \clozeluafunction{write_marker} -% Write a marker node to \TeX's current node list. The argument |mode| -% accepts the string values |basic|, |fix| and |par|. The argument -% |position|. The argument |position| is either set to |start| or to -% |stop|. -% \begin{macrocode} -function registry.write_marker(mode, position) - local index = registry.set_storage(mode, position) - local marker = registry.create_marker(index) - node.write(marker) -end -% \end{macrocode} -% -% \clozeluafunction{is_marker} -% This functions checks if the given node |item| is a marker. -% \begin{macrocode} -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 -% \end{macrocode} -% -% \clozeluafunction{check_marker} -% This functions tests, whether the given node |item| is a marker. The -% argument |item| is a node. The argument |mode| accepts the string -% values |basic|, |fix| and |par|. The argument |position| is either set -% to |start| or to |stop|. -% \begin{macrocode} -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 -% \end{macrocode} -% -% \clozeluafunction{get_marker} -% |registry.get_marker| returns the given marker. The argument |item| is -% a node. The argument |mode| accepts the string values |basic|, |fix| -% and |par|. The argument |position| is either set to |start| or to -% |stop|. -% \begin{macrocode} -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 -% \end{macrocode} -% -% \clozeluafunction{get_marker_data} -% |registry.get_marker_data| tests whether the node |item| is a marker. -% The argument |item| is a node of unspecified type. -% \begin{macrocode} -function registry.get_marker_data(item) - if item.id == node.id('whatsit') - and item.subtype == node.subtype('user_defined') - and item.user_id == registry.user_id then - return registry.get_storage(item.value) - else - return false - end -end -% \end{macrocode} -% -% \clozeluafunction{get_marker_values} -% First this function saves the associatied values of a marker to the -% local options table. Second it returns this values. The argument -% |marker| is a whatsit node. -% \begin{macrocode} -function registry.get_marker_values(marker) - local data = registry.get_marker_data(marker) - registry.local_options = data.values - return data.values -end -% \end{macrocode} -% -% \clozeluafunction{remove_marker} -% This function removes a given whatsit marker. It only deletes a node, -% if a marker is given. -% \begin{macrocode} -function registry.remove_marker(marker) - if registry.is_marker(marker) then node.remove(marker, marker) end -end -% \end{macrocode} -% -% \paragraph{Storage functions (storage)} -% -% \clozeluafunction{get_index} -% |registry.index| is a counter. The functions |registry.get_index()| -% increases the counter by one and then returns it. -% \begin{macrocode} -function registry.get_index() - if not registry.index then - registry.index = 0 - end - registry.index = registry.index + 1 - return registry.index -end -% \end{macrocode} -% -% \clozeluafunction{set_storage} -% |registry.set_storage()| stores the local options in the Lua table -% |registry.storage|. It returns a numeric index number. This index -% number is the key, where the local options in the Lua table are -% stored. The argument |mode| accepts the string values |basic|, |fix| -% and |par|. -% \begin{macrocode} -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 -% \end{macrocode} -% -% \clozeluafunction{get_storage} -% The function |registry.get_storage()| retrieves values which belong to -% a whatsit marker. The argument |index| is a numeric value. -% \begin{macrocode} -function registry.get_storage(index) - return registry.storage[index] -end -% \end{macrocode} -% -% \paragraph{Option processing (option)} -% -% \clozeluafunction{set_option} -% This function stores a value |value| and his associated key |key| -% either to the global (|registry.global_options|) or to the local -% (|registry.local_options|) option table. The global boolean variable -% |registry.local_options| controls in which table the values are -% stored. -% \begin{macrocode} -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 -% \end{macrocode} -% -% \clozeluafunction{set_is_global} -% |registry.set_is_global()| sets the variable |registry.is_global| to -% the value |value|. It is intended, that the variable takes boolean -% values. -% \begin{macrocode} -function registry.set_is_global(value) - registry.is_global = value -end -% \end{macrocode} -% -% \clozeluafunction{unset_local_options} -% This function unsets the local options. -% \begin{macrocode} -function registry.unset_local_options() - registry.local_options = {} -end -% \end{macrocode} -% -% \clozeluafunction{unset_global_options} -% |registry.unset_global_options| empties the global options storage. -% \begin{macrocode} -function registry.unset_global_options() - registry.global_options = {} -end -% \end{macrocode} -% -% \clozeluafunction{get_value} -% Retrieve a value from a given key. First search for the value in the -% local options, then in the global options. If both option storages are -% empty, the default value will be returned. -% \begin{macrocode} -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 -% \end{macrocode} -% -% \clozeluafunction{get_value_show} -% The function |registry.get_value_show()| returns the boolean value -% |true| if the option |show| is true. In contrast to the function -% |registry.get_value()| it converts the string value `true' to a -% boolean value. -% \begin{macrocode} -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 -% \end{macrocode} -% -% \clozeluafunction{has_value} -% This function tests whether the value |value| is not empty and has a -% value. -% \begin{macrocode} -function registry.has_value(value) - if value == nil or value == '' or value == '\\color@ ' then - return false - else - return true - end -end -% \end{macrocode} -% -% \clozeluafunction{get_defaults} -% |registry.get_defaults(option)| returns a the default value of the -% given option. -% \begin{macrocode} -function registry.get_defaults(option) - return registry.defaults[option] -end -% \end{macrocode} -% -% \subsubsection{Assembly to cloze texts (cloze)} -% -% Some graphics for better understanding of the node tree: -% -% \paragraph{Paragraph} -% -% \noindent\includegraphics[width=\linewidth]{graphics/par} -% -% \paragraph{Tabular environment} -% -% \noindent\includegraphics[width=\linewidth]{graphics/tabular} -% -% \paragraph{Picture environment} -% -% \noindent\includegraphics[width=\linewidth]{graphics/picture} -% -% \clozeluafunction{basic_make} -% The function |cloze.basic_make()| makes one gap. The argument |start| -% is the node, where the gap begins. The argument |stop| is the node, -% where the gap ends. -% \begin{macrocode} -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( - cloze.status.hlist.glue_set, - cloze.status.hlist.glue_sign, - cloze.status.hlist.glue_order, - n.start, - n.stop - ) - 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 - 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 -% \end{macrocode} -% I some edge cases the lua callbacks get fired up twice. After the -% cloze has been created, the start and stop whatsit markers can be -% deleted. -% \begin{macrocode} - registry.remove_marker(n.start) - registry.remove_marker(n.stop) -end -% \end{macrocode} -% -% \clozeluafunction{basic_search_stop} -% Search for a stop marker. -% \begin{macrocode} -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 -% \end{macrocode} -% -% \clozeluafunction{basic_search_start} -% Search for a start marker. Also begin a new cloze, if the boolean -% value |cloze.status.continue| is true. The knowledge of the last -% hlist node is a requirement to begin a cloze. -% \begin{macrocode} -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 - 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 -% \end{macrocode} -% -% \clozeluafunction{basic_recursion} -% Parse recursivley the node tree. Start and stop markers can be nested -% deeply into the node tree. -% \begin{macrocode} -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 -% \end{macrocode} -% -% \clozeluafunction{basic} -% The corresponding \LaTeX{} command to this lua function is \cmd{\cloze} -% \secref{sec:command-cloze}. The argument |head| is the head node of a -% node list. -% \begin{macrocode} -function cloze.basic(head) - cloze.status.continue = false - cloze.basic_recursion(head) - return head -end -% \end{macrocode} -% -% \clozeluafunction{fix_length} -% Calculate the length of the whitespace before (|l.kern_start|) and -% after (|l.kern_stopt|) the text. -% \begin{macrocode} -function cloze.fix_length(start, stop) - local l = {} - l.width = tex.sp(registry.get_value('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 l.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 - return l.width, l.kern_start, l.kern_stop -end -% \end{macrocode} -% -% \clozeluafunction{fix_make} -% The function |cloze.fix_make| generates a gap of fixed width. -% -% \subparagraph*{Node lists} -% -% \subparagraph*{Show text:} -% -% \begin{nodelist} -% |n.start| & |whatsit| & |user_definded| & |index| \\ -% |n.line| & |rule| & & |l.width| \\ -% |n.kern_start| & |kern| & & Depends on |align| \\ -% |n.color_text| & |whatsit| & |pdf_colorstack| & Text color \\ -% & |glyphs| & & Text to show \\ -% |n.color_reset| & |whatsit| & |pdf_colorstack| & Reset color \\ -% |n.kern_stop| & |kern| & & Depends on |align| \\ -% |n.stop| & |whatsit| & |user_definded| & |index| \\ -% \end{nodelist} -% -% \subparagraph*{Hide text:} -% -% \begin{nodelist} -% |n.start| & |whatsit| & |user_definded| & |index| \\ -% |n.line| & |rule| & & |l.width| \\ -% |n.stop| & |whatsit| & |user_definded| & |index| \\ -% \end{nodelist} -% -% The argument |start| is the node, where the gap begins. The argument -% |stop| is the node, where the gap ends. -% \begin{macrocode} -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 - 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 = stop.next - end - registry.remove_marker(start) - registry.remove_marker(stop) -end -% \end{macrocode} -% -% \clozeluafunction{fix_recursion} -% Function to recurse the node list and search after marker. |head| is -% the head node of a node list. -% \begin{macrocode} -function cloze.fix_recursion(head) - local n = {} -- node - 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 -% \end{macrocode} -% -% \clozeluafunction{fix} -% The corresponding \LaTeX{} command to this Lua function is -% \cmd{\clozefix} \secref{sec:command-clozefix}. The argument |head| is -% the head node of a node list. -% \begin{macrocode} -function cloze.fix(head) - cloze.fix_recursion(head) - return head -end -% \end{macrocode} -% -% \clozeluafunction{par} -% The corresponding \LaTeX{} environment to this lua function is -% |clozepar| \secref{sec:command-clozepar}. -% -% \subparagraph*{Node lists} -% -% \subparagraph*{Show text:} -% -% \begin{nodelist} -% |n.strut| & |kern| & & width = 0 \\ -% |n.line| & |rule| & & |l.width| (Width from hlist) \\ -% |n.kern| & |kern| & & |-l.width| \\ -% |n.color_text| & |whatsit| & |pdf_colorstack| & Text color \\ -% & |glyphs| & & Text to show \\ -% |n.tail| & |glyph| & & Last glyph in hlist \\ -% |n.color_reset| & |whatsit| & |pdf_colorstack| & Reset color \\ -% \end{nodelist} -% -% \subparagraph*{Hide text:} -% -% \begin{nodelist} -% |n.strut| & |kern| & & width = 0 \\ -% |n.line| & |rule| & & |l.width| (Width from hlist) \\ -% \end{nodelist} -% -% The argument |head| is the head node of a node list. -% \begin{macrocode} -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) - n.line = nodex.insert_line(n.strut, l.width) - if registry.get_value_show() then - 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 - end - return head -end -% \end{macrocode} -% -% \subsubsection{Basic module functions (base)} -% -% The |base| table contains functions which are published to the -% |cloze.sty| file. -% -% \clozeluafunction{register} -% This function registers the functions |cloze.par|, |cloze.basic| and -% |cloze.fix| the Lua callbacks. |cloze.par| and |cloze.basic| are -% registered to the callback |post_linebreak_filter| and |cloze.fix| to -% the callback |pre_linebreak_filter|. The argument |mode| accepts the -% string values |basic|, |fix| and |par|. -% \begin{macrocode} -function base.register(mode) - local basic - 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 -% \end{macrocode} -% -% \clozeluafunction{unregister} -% |base.unregister(mode)| deletes the registered functions from the Lua -% callbacks. The argument |mode| accepts the string values |basic|, -% |fix| and |par|. -% \begin{macrocode} -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 -% \end{macrocode} -% -% Publish some functions to the |cloze.sty| file. -% \begin{macrocode} -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.get_value = registry.get_value -base.marker = registry.write_marker -% \end{macrocode} -% -% \begin{macrocode} -return base -% \end{macrocode} -% \iffalse -%</lua> % \fi % % \Finale diff --git a/Master/texmf-dist/source/lualatex/cloze/cloze.ins b/Master/texmf-dist/source/lualatex/cloze/cloze.ins index 87a4e09d25d..75f4839276f 100644 --- a/Master/texmf-dist/source/lualatex/cloze/cloze.ins +++ b/Master/texmf-dist/source/lualatex/cloze/cloze.ins @@ -1,4 +1,4 @@ -% Copyright (C) 2015-2016 by Josef Friedrich <josef@friedrich.rocks> +% Copyright (C) 2015-2020 by Josef Friedrich <josef@friedrich.rocks> % ---------------------------------------------------------------------- % This work may be distributed and/or modified under the conditions of % the LaTeX Project Public License, either version 1.3c of this license @@ -22,7 +22,7 @@ This is a generated file. -Copyright (C) 2015-2016 by Josef Friedrich <josef@friedrich.rocks> +Copyright (C) 2015-2020 by Josef Friedrich <josef@friedrich.rocks> ---------------------------------------------------------------------- This work may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3c of this license @@ -38,11 +38,6 @@ version 2008/05/05 or later. \generate{\file{cloze.sty}{\from{cloze.dtx}{package}}} -\nopreamble -\nopostamble -\generate{\file{cloze.lua}{\from{cloze.dtx}{lua}}} -\generate{\file{README.md}{\from{cloze.dtx}{readme}}} - \obeyspaces \Msg{*************************************************************} \Msg{* *} diff --git a/Master/texmf-dist/tex/lualatex/cloze/cloze.sty b/Master/texmf-dist/tex/lualatex/cloze/cloze.sty index e092711f518..a7f604dbbc0 100644 --- a/Master/texmf-dist/tex/lualatex/cloze/cloze.sty +++ b/Master/texmf-dist/tex/lualatex/cloze/cloze.sty @@ -8,7 +8,7 @@ %% %% This is a generated file. %% -%% Copyright (C) 2015-2016 by Josef Friedrich <josef@friedrich.rocks> +%% Copyright (C) 2015-2020 by Josef Friedrich <josef@friedrich.rocks> %% ---------------------------------------------------------------------- %% This work may be distributed and/or modified under the conditions of %% the LaTeX Project Public License, either version 1.3c of this license @@ -22,7 +22,7 @@ %% \NeedsTeXFormat{LaTeX2e}[1999/12/01] \ProvidesPackage{cloze} - [2020/05/20 v1.4 Package to typeset cloze worksheets or cloze tests] + [2020/05/27 v1.5 Package to typeset cloze worksheets or cloze tests] \RequirePackage{fontspec} \RequirePackage{luatexbase-mcb} \RequirePackage{kvoptions} |