summaryrefslogtreecommitdiff
path: root/macros/luatex/latex/cloze/cloze.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/luatex/latex/cloze/cloze.dtx')
-rw-r--r--macros/luatex/latex/cloze/cloze.dtx1207
1 files changed, 151 insertions, 1056 deletions
diff --git a/macros/luatex/latex/cloze/cloze.dtx b/macros/luatex/latex/cloze/cloze.dtx
index e8d7e3ea17..f2ec1be8c5 100644
--- a/macros/luatex/latex/cloze/cloze.dtx
+++ b/macros/luatex/latex/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