From fb4909f4112d8b778570cf1c2e25ca18c63bc1ca Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Fri, 10 Jun 2022 03:02:43 +0000
Subject: CTAN sync 202206100302

---
 macros/luatex/generic/luakeys/luakeys-doc.tex | 1398 +++++++++++++++++++------
 1 file changed, 1061 insertions(+), 337 deletions(-)

(limited to 'macros/luatex/generic/luakeys/luakeys-doc.tex')

diff --git a/macros/luatex/generic/luakeys/luakeys-doc.tex b/macros/luatex/generic/luakeys/luakeys-doc.tex
index 3f7d1b0ea1..bc9a55f632 100644
--- a/macros/luatex/generic/luakeys/luakeys-doc.tex
+++ b/macros/luatex/generic/luakeys/luakeys-doc.tex
@@ -1,6 +1,6 @@
 \documentclass{ltxdoc}
 
-\usepackage{hyperref}
+\usepackage[hidelinks]{hyperref}
 \EnableCrossrefs
 \CodelineIndex
 \RecordChanges
@@ -17,8 +17,24 @@
 \setminted{
   breaklines=true,
   fontsize=\footnotesize,
+  style=manni,
 }
 \def\lua#1{\mintinline{lua}|#1|}
+\def\latex#1{\mintinline{latex}|#1|}
+
+\NewDocumentCommand { \InputLatexExample } { O{} m } {
+  \begin{mdframed}
+  \inputminted[linenos=false,#1]{latex}{examples/#2}
+  \end{mdframed}
+}
+
+\NewDocumentCommand { \InputLuaExample } { O{} m } {
+  \begin{mdframed}
+  \inputminted[linenos=false,#1]{lua}{examples/#2}
+  \end{mdframed}
+}
+
+\catcode`_=12
 
 \begin{document}
 
@@ -30,19 +46,13 @@
   \url{josef@friedrich.rocks}\\%
   \href{https://github.com/Josef-Friedrich/luakeys}{github.com/Josef-Friedrich/luakeys}%
 }
-\date{v0.5 from 2022/04/04}
+\date{v0.6 from 2022/06/09}
 
 \maketitle
 
 \vfill
 
-%level1={level2={level3={dim=1cm,bool=true,num=-0.001,str=lua}}}
-
-\begin{minted}{lua}
-local luakeys = require('luakeys')
-local kv = luakeys.parse('level1={level2={level3={dim=1cm,bool=true,num=-0.001,str=lua}}}')
-luakeys.print(kv)
-\end{minted}
+\InputLuaExample[firstline=4,lastline=7]{first-page.lua}
 
 \noindent
 Result:
@@ -52,149 +62,1016 @@ Result:
 {
   ['level1'] = {
     ['level2'] = {
-      ['level3'] = {
-        ['dim'] = 1864679,
-        ['bool'] = true,
-        ['num'] = -0.001
-        ['str'] = 'lua',
-      }
+      ['naked'] = true,
+      ['dim'] = 1864679,
+      ['bool'] = false,
+      ['num'] = -0.001,
+      ['str'] = 'lua,{}',
     }
   }
 }
 \end{minted}
 \end{center}
 
-\vfill
+\vfill
+
+\strut
+
+\newpage
+
+\tableofcontents
+
+\newpage
+
+\section{Introduction}
+
+\noindent
+% |luakeys| ist ein Lua-Modul / Lua\TeX package, das wie die Pakete ...
+% Schlüssel-Wert-Optionen analysieren kann.
+|luakeys| is a Lua module / Lua\TeX package that can parse key-value
+options like the \TeX{} packages
+\href{https://www.ctan.org/pkg/keyval}{keyval},
+\href{https://www.ctan.org/pkg/kvsetkeys}{kvsetkeys},
+\href{https://www.ctan.org/pkg/kvoptions}{kvoptions},
+\href{https://www.ctan.org/pkg/xkeyval}{xkeyval},
+\href{https://www.ctan.org/pkg/pgfkeys}{pgfkeys} etc.
+%
+% |luakeys|, erfüllt diese Aufgabe jedoch, indem es die Sprache Lua
+% verwendet und nicht auf \TeX{} angewiesen ist.
+|luakeys|, however, accomplishes this task by using the Lua language and
+doesn’t rely on \TeX{}.
+%
+% Deshalb kann dieses Paket nur mit der \TeX{}-Engine Lua\TeX{}
+% verwendet werden.
+Therefore this package can only be used with the
+\TeX{} engine Lua\TeX{}.
+%
+% Da |luakeys| \href{http://www.inf.puc-rio.br/~roberto/lpeg/}{LPeg}
+% verwendet, sollte der Parsing-Mechanismus ziemlich robust sein.
+Since |luakeys| uses
+\href{http://www.inf.puc-rio.br/~roberto/lpeg/}{LPeg}, the parsing
+mechanism should be pretty robust.
+
+The TUGboat article
+\href{http://www.tug.org/tugboat/tb30-1/tb94wright-keyval.pdf}
+{“Implementing key–value input: An introduction” (Volume 30 (2009), No. 1)}
+by \emph{Joseph Wright} and \emph{Christian Feuersänger} gives a good
+overview of the available key-value packages.
+
+This package would not be possible without the article
+\href{https://tug.org/TUGboat/tb40-2/tb125menke-lpeg.pdf}
+{“Parsing complex data formats in LuaTEX with LPEG” (Volume 40 (2019), No. 2)}.
+
+%-----------------------------------------------------------------------
+%
+%-----------------------------------------------------------------------
+
+\section{How the package is loaded}
+
+%%
+%
+%%
+
+\subsection{Using the Lua module \texttt{luakeys.lua}}
+
+% Die Kernfunktionalität dieses Pakets ist in Lua realisiert.
+The core functionality of this package is realized in Lua.
+%
+% Sie können also |luakeys| auch ohne die Wrapper-Dateien
+% \texttt{luakeys.sty} und \texttt{luakeys.tex} verwenden.
+So you can use |luakeys| even without using the wrapper files
+|luakeys.sty| and |luakeys.tex|.
+
+\InputLatexExample{loading/lua.tex}
+
+%%
+%
+%%
+
+\subsection{Using the Lua\LaTeX{} wrapper \texttt{luakeys.sty}}
+
+% Der Paketmanager MikTeX lädt beispielsweise Pakete erst bei Bedarf
+% herunter.
+For example, the MiK\TeX{} package manager downloads packages only when
+needed.
+%
+% Es wurde berichtet, dass dieser automatische Download nur mit Hilfe der
+% Hüll-Dateien funktioniert.
+It has been reported that this automatic download only works with this
+wrapper files.
+%
+% Wahrscheinlich hält MiK\TeX nach einem Auftreten des LaTeX macros
+% “\latex{\usepackage{luakeys}} ”Ausschau.
+Probably MiK\TeX{} is searching for an occurrence of the \LaTeX{} macro
+“\latex{\usepackage{luakeys}}”.
+
+% Die mitgelieferte Lua\LaTeX{}-Datei ist recht klein:
+The supplied Lua\LaTeX{} file is quite small:
+
+\begin{minted}{latex}
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{luakeys}
+\directlua{luakeys = require('luakeys')}
+\end{minted}
+
+\noindent
+It loads the Lua module into the global variable \texttt{luakeys}.
+
+\InputLatexExample{loading/latex.tex}
+
+%%
+%
+%%
+
+\subsection{Using the plain Lua\TeX{} wrapper \texttt{luakeys.tex}}
+
+Even smaller is the file \texttt{luakeys.tex}. It consists of only one
+line:
+
+\begin{minted}{latex}
+\directlua{luakeys = require('luakeys')}
+\end{minted}
+
+\noindent
+It does the same as the Lua\LaTeX{} wrapper and loads the Lua module
+\texttt{luakeys.lua} into the global variable \texttt{luakeys}.
+
+\InputLatexExample{loading/tex.tex}
+
+\section{Lua interface / API}
+
+To learn more about the individual functions (local functions), please
+read the \href{https://josef-friedrich.github.io/luakeys/}{source code
+documentation}, which was created with
+\href{http://stevedonovan.github.io/ldoc/}{LDoc}. The Lua module exports
+this functions and tables:
+
+\InputLuaExample[firstline=3,lastline=12]{export.lua}
+
+\subsection{Lua indentifier names}
+
+% Das Projekt verwendet einige wenige Abkürzungen für Variablennamen,
+% die hoffentlich für externe Leser eindeutig und bekannt sind.
+The project uses a few abbreviations for variable names that are
+hopefully unambiguous and familiar to external readers.
+
+\begin{center}
+\begin{tabular}{lll}
+Abbreviation & spelled out & Example \\\hline
+\lua{kv_string} & Key-value string & \lua{'key=value'} \\
+\lua{opts} & Options (for the parse function) & \lua{ { no_error = false } } \\
+\lua{defs} & Definitions \\
+\lua{def} & Definition \\
+\lua{attr} & Attributes (of a definition) \\
+\end{tabular}
+\end{center}
+
+\noindent
+% Diese nicht abgekürzten Variablennamen werden häufig verwendet.
+These unabbreviated variable names are commonly used.
+\begin{center}
+\begin{tabular}{ll}
+
+\lua{result} &
+% Das Endergebnis aller einzelnen Übersetzungs- und Normalisierungsschritte
+The final result of all individual parsing and normalization steps. \\
+
+\lua{unknown} &
+% Ein Tabelle mit unbekannten, nicht definierten Schlüssel-Wert-Paaren
+A table with unknown, undefinied key-value pairs. \\
+
+\lua{raw} &
+% Das unbearbeitete, rohe Ergebnis der LPeg-Syntaxanalyse.
+The raw result of the Lpeg grammar parser. \\
+\end{tabular}
+\end{center}
+
+%%
+%
+%%
+
+\subsection{Function \texttt{parse(kv_string, opts): result, unknown, raw}}
+\label{parse}
+
+% Die Function parse ist die wichtigste Funktion des Pakets.
+The function \lua{parse(kv_string, opts)} is the most important function
+of the package.
+% Sie konvertiert eine Schlüssel-Wert-Zeichenkette in eine Lua Tabelle.
+It converts a key-value string into a Lua table.
+
+\begin{minted}{latex}
+\newcommand{\mykeyvalcmd}[2][]{
+  \directlua{
+    result = luakeys.parse('#1')
+    luakeys.debug(result)
+  }
+  #2
+}
+\mykeyvalcmd[one=1]{test}
+\end{minted}
+
+\noindent
+In plain \TeX:
+
+\begin{minted}{latex}
+\def\mykeyvalcommand#1{
+  \directlua{
+    result = luakeys.parse('#1')
+    luakeys.debug(result)
+  }
+}
+\mykeyvalcmd{one=1}
+\end{minted}
+
+\subsection{Options to configure the \texttt{parse} function}
+
+\noindent
+The \lua{parse} function can be called with an options table. This
+options are supported:
+
+\InputLuaExample[firstline=5,lastline=69]{opts/all-opts.lua}
+
+\noindent
+The options can also be set globally using the exported table
+|opts|:
+
+\InputLuaExample[firstline=4,lastline=4]{opts/exported-default-opts.lua}
+
+\InputLuaExample[firstline=10,lastline=11]{opts/exported-default-opts.lua}
+
+%%
+%
+%%
+
+\subsubsection{Option “\texttt{convert_dimensions}”}
+
+If you set the option \lua{convert_dimensions} to \lua{true}, |luakeys|
+detects the \TeX{} dimensions and converts them into scaled points using
+the function \lua{tex.sp(dim)}.
+
+\InputLuaExample[firstline=4,lastline=7]{opts/convert-dimensions.lua}
+
+\noindent
+By default the dimensions are not converted into scaled points.
+
+\InputLuaExample[firstline=13,lastline=18]{opts/convert-dimensions.lua}
+
+\noindent
+If you want to convert a scale point into a unit string you can use the module
+\href{https://raw.githubusercontent.com/latex3/lualibs/master/lualibs-util-dim.lua}{lualibs-util-dim.lua}.
+
+\begin{minted}{lua}
+require('lualibs')
+tex.print(number.todimen(tex.sp('1cm'), 'cm', '%0.0F%s'))
+\end{minted}
+
+%%
+%
+%%
+
+\subsubsection{Option “\texttt{debug}”}
+
+If the option “debug” is set to ture, the result table is printed to the
+console.
+
+\begin{minted}{latex}
+\documentclass{article}
+\usepackage{luakeys}
+\begin{document}
+\directlua{
+  luakeys.parse('one,two,three', { debug = true })
+}
+debug
+\end{document}
+\end{minted}
+
+\begin{verbatim}
+This is LuaHBTeX, Version 1.15.0 (TeX Live 2022)
+...
+(./debug.aux) (/usr/local/texlive/texmf-dist/tex/latex/base/ts1cmr.fd)
+{
+  ['three'] = true,
+  ['two'] = true,
+  ['one'] = true,
+}
+ [1{/usr/
+local/texlive/2022/texmf-var/fonts/map/pdftex/updmap/pdftex.map}] (./debug.aux)
+)
+...
+Transcript written on debug.log.
+\end{verbatim}
+
+%%
+%
+%%
+
+\subsubsection{Option “\texttt{default}”}
+\label{option-default}
+
+% Mit der Option \lua{default} kann angegeben werden, welchen Wert
+% nackte Schlüssel (Schlüssel ohne Wert) erhalten. Diese Option hat
+% keinen Einfluss auf Schlüssel mit Werten.
+The option \lua{default} can be used to specify which value naked keys
+(keys without a value) get. This option has no influence on keys with
+values.
+
+\InputLuaExample[firstline=4,lastline=5]{opts/default.lua}
+
+\noindent
+% Standardmäßig erhalten nackte Schlüssel den Wert \lua{true}.
+By default, naked keys get the value \lua{true}.
+
+\InputLuaExample[firstline=11,lastline=12]{opts/default.lua}
+
+%%
+%
+%%
+
+\subsubsection{Option “\texttt{defaults}”}
+\label{options-defaults}
+
+% Mit der Attribut „defaults“ kann nicht nur ein einiger Standardwert
+% angegeben werden, sondern eine ganze Tabelle mit Standardwerten.
+The option “defaults” can be used to specify not only one default value,
+but a whole table of default values.
+% Die Ergebnistabelle wird mit der Tabelle bestehend aus Standardwerten
+% vereinigt.
+The result table is merged into the defaults table.
+% Werte aus der Tabelle mit Standardwerten werden von Werten der
+% Ergebnistabelle überschrieben.
+Values in the defaults table are
+overwritten by values in the result table.
+
+\InputLuaExample[firstline=4,lastline=7]{opts/defaults.lua}
+
+%%
+%
+%%
+
+\subsubsection{Option “\texttt{defs}”}
+
+% Für mehr Information wie Schlüssel definiert werden, lesen sie das
+% kapitel 3.2
+For more informations on how keys are defined, see section \ref{define}.
+% Wenn sie die Option \lua{defs} verwenden, können sie auf den
+% Aufruf der Funktion \lua{define} verzichten.
+If you use the \lua{defs} option, you don't need to call the
+\lua{define} function.
+%
+% Anstatt
+Instead of ...
+
+\InputLuaExample[firstline=4,lastline=5]{opts/defs.lua}
+
+\noindent
+% können wir schreiben ..
+we can write ...
+
+\InputLuaExample[firstline=11,lastline=13]{opts/defs.lua}
+
+%%
+%
+%%
+
+\subsubsection{Option “\texttt{format_keys}”}
+
+\begin{description}
+\item[lower] \strut
+
+\InputLuaExample[firstline=4,lastline=5]{opts/format-keys.lua}
+
+\item[snake] \strut
+
+\InputLuaExample[firstline=11,lastline=12]{opts/format-keys.lua}
+
+\item[upper] \strut
+
+\InputLuaExample[firstline=18,lastline=19]{opts/format-keys.lua}
+\end{description}
+
+%%
+%
+%%
+
+\subsubsection{Option “\texttt{hooks}”}
+
+% Die folgenden Hooks bzw. Callback-Funktionen ermöglichen es in den
+% Verarbeitungsprozess der \lua{parse}-Function einzugreifen.
+The following hooks or callback functions allow to intervene in the
+processing of the \lua{parse} function.
+%
+% Die Funktionen sind in der Verarbeitungsreihenfolge aufgelistet.
+The functions are listed in processing order.
+%
+% \lua{*_before_opts} bedeutet, dass die Hooks nach der LPeg Syntaxanalyse
+% und vor dem Anwenden der Optionen ausgeführt
+\lua{*_before_opts} means that the hooks are executed after the LPeg
+syntax analysis and before the options are applied.
+%
+% Die Hooks \lua{*_before_defs} werden vor dem Anwenden der
+% Schlüssel-Wert-Definitionen ausgeführt
+The \lua{*_before_defs} hooks are executed before applying the key value
+definitions.
+
+\def\TmpSignature#1{
+  {
+    \scriptsize\texttt{ = #1}
+  }
+}
+
+\def\TmpKeySignature{
+  \TmpSignature{function(key, value, depth, current, result): key, value}
+}
+\def\TmpResultSignature{
+  \TmpSignature{function(result): void}
+}
+
+\begin{enumerate}
+\item \lua{kv_string} \TmpSignature{function(kv_string): kv_string}
+\item \lua{keys_before_opts} \TmpKeySignature
+\item \lua{result_before_opts} \TmpResultSignature
+\item \lua{keys_before_def} \TmpKeySignature
+\item \lua{result_before_def} \TmpResultSignature
+\item (\lua{process}) (has to be definied using defs, see \ref{attr-process})
+\item \lua{keys} \TmpKeySignature
+\item \lua{result} \TmpResultSignature
+\end{enumerate}
+
+\paragraph{\texttt{kv_string}}
+
+% Der Hook \lua{kv_string} wird als erste
+% der Hook-Funktionen noch vor der LPeg-Syntax-Analyse aufgerufen.
+The \lua{kv_string} hook is called as the first of the hook functions
+before the LPeg syntax parser is executed.
+
+\InputLuaExample[firstline=4,lastline=11]{hooks/kv-string.lua}
+
+\paragraph{\texttt{keys_*}}
+
+% Die Hooks \lua{keys_*} werden rekursiv auf jeden Schlüssel in der
+% aktuellen Ergebnistabelle aufgerufen.
+The hooks \lua{keys_*} are called recursively on each key in the current
+result table.
+% Die Hook-Funktion muss zwei Werte zurückgeben: \lua{key, value}
+The hook function must return two values: \lua{key, value}.
+%
+% Das folgende Beispiel gibt \lua{key} und \lua{value} unverändert zurück,
+% sodass die Ergebnistabelle nicht verändert wird.
+The following example returns \lua{key} and \lua{value} unchanged, so
+the result table is not changed.
+
+\InputLuaExample[firstline=4,lastline=11]{hooks/keys-unchanged.lua}
+
+\noindent
+% Das nächste Beispiel demonstriert den dritten Parameter \lua{depth}
+% der Hook-Funktion.
+The next example demonstrates the third parameter \lua{depth} of the
+hook function.
+
+\InputLuaExample[firstline=4,lastline=16]{hooks/keys-depth.lua}
+
+\paragraph{\texttt{result_*}}
+
+% Die Hooks \lua{result_*} werden einmal mit der aktuellen
+% Ergebnistabelle als Parameter aufgerufen.
+The hooks \lua{result_*} are called once with the current result table
+as a parameter.
+
+%%
+%
+%%
+
+\subsubsection{Option “\texttt{naked_as_value}”}
+
+% Mit Hilfe der Option \lua{naked_as_value} werden nackte Schlüssel
+% nicht mit einem Standardwert versehen, sondern als Werte in die
+% Lua-Tabelle abgelegt.
+With the help of the option \lua{naked_as_value}, naked keys are not
+given a default value, but are stored as values in a Lua table.
+
+\InputLuaExample[firstline=4,lastline=5]{opts/naked-as-value.lua}
+
+\noindent
+If we set the option \lua{naked_as_value} to \lua{true}:
+
+\InputLuaExample[firstline=11,lastline=14]{opts/naked-as-value.lua}
+
+%%
+%
+%%
+
+\subsubsection{Option “\texttt{no_error}”}
+
+% Standardmaßig wirft parse-Funktion einen Fehler, wenn es unbekannte
+% Schlüssel gibt.
+By default the parse function throws an error if there are unknown keys.
+% Mit Hilfe der Option \lua{no_error} kann dies unterbunden werden.
+This can be prevented with the help of the \lua{no_error} option.
+
+\InputLuaExample[firstline=5,lastline=6]{opts/no-error.lua}
+
+\noindent
+If we set the option \lua{no_error} to \lua{true}:
+
+\InputLuaExample[firstline=9,lastline=10]{opts/no-error.lua}
+
+%%
+%
+%%
+
+\subsubsection{Option “\texttt{unpack}”}
+
+% Mit Hilfe der Option \lua{unpack} werden alle Tabellen, die nur aus
+% einem einzigen nackten Schlüssel bzw. einen einzigen alleinstehenden
+% Wert bestehen, aufgelöst.
+With the help of the option \lua{unpack}, all tables that consist of
+only one a single naked key or a single standalone value are unpacked.
+
+\InputLuaExample[firstline=4,lastline=5]{opts/unpack.lua}
+
+\InputLuaExample[firstline=11,lastline=12]{opts/unpack.lua}
+
+%%
+%
+%%
+
+\subsection{Function \texttt{define(defs, opts): parse}}
+\label{define}
+
+The \lua{define} function returns a \lua{parse} function (see
+\ref{parse}).
+The name of a key can be specified in three ways:
+
+\begin{enumerate}
+\item as a string.
+\item as a key in a Lua table. The definition of the corresponding
+key-value pair is then stored under this key.
+\item by the “name” attribute.
+\end{enumerate}
+
+\InputLuaExample[firstline=4,lastline=16]{functions/define.lua}
+
+\noindent
+For nested definitions, only the last two ways of specifying the key
+names can be used.
+
+\InputLuaExample[firstline=26,lastline=33]{functions/define.lua}
+
+%-----------------------------------------------------------------------
+%
+%-----------------------------------------------------------------------
+
+\subsection{Attributes to define a key-value pair}
+
+% Die Definition eines Schlüssel-Wert-Paares kann mit Hilfe von
+% verschiedenen Attributen vorgenommen werden.
+The definition of a key-value pair can be made with the help of various
+attributes.
+%
+% Der Name „Attribut“ für eine Option, einen Schlüssel, eine Eigenschaft
+% (um nur einige Benennungsmöglichkeiten aufzuzählen) zur
+% Schlüssel-Definition, wurde bewusst gewählt, um sie von den Optionen
+% der Funktion \lua{parse} zu unterscheiden.
+The name \emph{“attribute”} for an option, a key, a property ... (to
+list just a few naming possibilities) to define keys, was deliberately
+chosen to distinguish them from the options of the \lua{parse} function.
+%
+% Das folgende Codebeispiel listet alle Attribute auf, die verwendet
+% werden können, um Schlüssel-Wert-Paare zu definieren.
+The code example below lists all the attributes that can be used to
+define key-value pairs.
+
+\InputLuaExample[firstline=5,lastline=41]{defs/all-attrs.lua}
+
+%%
+%
+%%
+
+\subsubsection{Attribute “\texttt{alias}”}
+
+With the help of the \lua{alias} attribute, other key names can be used.
+The value is always stored under the original key name. A single alias
+name can be specified by a string ...
+
+\InputLuaExample[firstline=4,lastline=7]{defs/attrs/alias.lua}
+
+\noindent
+multiple aliases by a list of strings.
+
+\InputLuaExample[firstline=13,lastline=16]{defs/attrs/alias.lua}
+
+%%
+%
+%%
+
+\subsubsection{Attribute “\texttt{always_present}”}
+
+% Die Option \lua{default} wird nur bei nackten Schlüsseln verwendet.
+The \lua{default} attribute is used only for naked keys.
+
+\InputLuaExample[firstline=4,lastline=5]{defs/attrs/always-present.lua}
+
+\noindent
+% Wird die Option \lua{always_present} auf wahr gesetzt, wird der
+% Schlüssel immer ins Ergebnis mit übernommen.
+If the attribute \lua{always_present} is set to true, the key is always
+included in the result. If no default value is definied, true is taken
+as the value.
+
+\InputLuaExample[firstline=11,lastline=12]{defs/attrs/always-present.lua}
+
+%%
+%
+%%
+
+\subsubsection{Attribute “\texttt{choices}”}
+
+% source: Python argparse documentation.
+Some key values should be selected from a restricted set of choices.
+These can be handled by passing an array table containing choices.
+
+\InputLuaExample[firstline=4,lastline=5]{defs/attrs/choices.lua}
+
+\noindent
+When the key-value pair is parsed, values will be checked, and an error
+message will be displayed if the value was not one of the acceptable
+choices:
+
+\InputLuaExample[firstline=13,lastline=15]{defs/attrs/choices.lua}
+
+%%
+%
+%%
+
+\subsubsection{Attribute “\texttt{data_type}”}
+
+% source: Python argparse documentation.
+The \lua{data_type} attribute allows type-checking and type conversions to
+be performed.
+%
+% Folgende Datentypen werden unterstützt:
+The following data types are supported:
+\lua{'boolean'},
+\lua{'dimension'},
+\lua{'integer'},
+\lua{'number'},
+\lua{'string'}.
+%
+% Bei den drei Datentypen integer, number, dimension kann eine
+% Typenumwandlung scheitern.
+A type conversion can fail with the three data types
+\lua{'dimension'},
+\lua{'integer'},
+\lua{'number'}.
+%
+% Dann wird eine Fehlermeldung ausgegeben.
+Then an error message is displayed.
+
+\InputLuaExample[firstline=4,lastline=8]{defs/attrs/data-type.lua}
+\InputLuaExample[firstline=11,lastline=15]{defs/attrs/data-type.lua}
+
+%%
+%
+%%
+
+\subsubsection{Attribute “\texttt{default}”}
+
+% Verwenden Sie das Attribut „\lua{default}“, um für jeden nackten Schlüssel
+% einzeln einen Standardwert bereit zu stellen.
+Use the \lua{default} attribute to provide a default value for each naked
+key individually.
+%
+% Mit der globalen \lua{default} Option kann für alle nackten Schlüssel ein
+% Standardwert vorgegeben werden.
+With the global \lua{default} attribute (\ref{option-default}) a default
+value can be specified for all naked keys.
+
+\InputLuaExample[firstline=4,lastline=9]{defs/attrs/default.lua}
+
+%%
+%
+%%
+
+\subsubsection{Attribute “\texttt{exclusive_group}”}
+
+% Alle Schlüssel, die der gleichen ausschließenden Gruppe angehören,
+% dürfen nicht gemeinsam angegeben werden.
+All keys belonging to the same exclusive group must not be specified
+together.
+%
+% Nur ein Schlüssel aus dieser Gruppe ist erlaubt.
+Only one key from this group is allowed.
+%
+% Als Name für diese ausschließende Gruppe kann irgend ein beliebiger
+% Wert verwendet werden.
+Any value can be used as a name for this exclusive group.
+
+\InputLuaExample[firstline=4,lastline=9]{defs/attrs/exclusive-group.lua}
+
+% Werden mehrer Schlüssel der Gruppe angegeben, so wird eine
+% Fehlermeldung geworfen.
+If more than one key of the group is specified, an error message is
+thrown.
+
+\InputLuaExample[firstline=21,lastline=23]{defs/attrs/exclusive-group.lua}
+
+%%
+%
+%%
+
+\subsubsection{Attribute “\texttt{opposite_keys}”}
+
+% Die Option \lua{opposite_keys} ermöglicht es, gegensätzliche (nackte)
+% Schlüssel in Wahrheitswerte umzuwandeln und diesen Wahrheitswert unter
+% einem Zielschlüssel zu speichern.
+The \lua{opposite_keys} attribute allows to convert opposite (naked) keys
+into a boolean value and store this boolean under a target key.
+%
+% Lua erlaubt es in Tabellen Wahrheitswerte als Schlüssel zu verwenden.
+% Es müssen jedoch eckige Klammern verwendet werden.
+Lua allows boolean values to be used as keys in tables.
+%
+% Die Wahrheitswerte müssen jedoch in eckige Klammern geschrieben werden.
+However, the boolean values must be written in square brackets, e. g.
+\lua{{ opposite_keys = { [true] = 'show', [false] = 'hide' } }}.
+%
+% Beispiele für gegensätzliche Schlüssel sind:
+Examples of opposing keys are: \lua{show} and \lua{hide}, \lua{dark} and
+\lua{light}, \lua{question} and \lua{solution}.
+%
+% Das untenstehende Beispiel verwendet als gegensätzliches Schlüsselpaar
+% die Schlüssel \lua{show} und \lua{hide}.
+The example below uses the \lua{show} and \lua{hide} keys as the
+opposite key pair.
+%
+% Wird der Schlüssel \lua{show} von der Funktion \lua{parse} gelesen,
+% dann erhält der Zielschlüssel \lua{visibility} den Wert \lua{true}.
+If the key \lua{show} is parsed by the \lua{parse} function, then the
+target key \lua{visibility} receives the value \lua{true}.
+
+\InputLuaExample[firstline=4,lastline=7]{defs/attrs/opposite-keys.lua}
+
+% Wird der Schlüssel \lua{hide} gelesen, dann \lua{falsch}.
+\noindent
+If the key \lua{hide} is parsed, then \lua{false}.
+
+\InputLuaExample[firstline=13,lastline=13]{defs/attrs/opposite-keys.lua}
+
+%%
+%
+%%
+
+\subsubsection{Attribute “\texttt{macro}”}
+
+The attribute \texttt{macro} stores the value in a \TeX{} macro.
+
+\begin{minted}{lua}
+local parse = luakeys.define({
+  key = {
+    macro = 'MyMacro'
+  }
+})
+parse('key=value')
+\end{minted}
+
+\begin{minted}{latex}
+\MyMacro % expands to “value”
+\end{minted}
+
+%%
+%
+%%
+
+\subsubsection{Attribute “\texttt{match}”}
+
+% Der Wert des Schlüssel wird der Lua Funktion übergeben
+The value of the key is passed to the Lua function
+\lua{string.match(value, match)} ((\url{http://www.lua.org/manual/5.3/manual.html#pdf-string.match})).
+% Werfe einen Blick in das Lua-Handbuch, wie man Patterns schreibt.
+Take a look at the Lua manual on how to write patterns
+(\url{http://www.lua.org/manual/5.3/manual.html#6.4.1})
+
+\InputLuaExample[firstline=4,lastline=6]{defs/attrs/match.lua}
+
+\noindent
+% Kann das Pattern im Wert nicht gefunden werden, wird eine
+% Fehlermeldung ausgegeben.
+If the pattern cannot be found in the value, an error message is issued.
+
+\InputLuaExample[firstline=14,lastline=17]{defs/attrs/match.lua}
+
+\noindent
+% Der Schlüssel erhält das Ergebnis der Funktion \lua{string.match(value,
+% match)}, dass bedeutet, dass der ursprüngliche Wert unter
+% Umständen nicht vollständig in den Schlüssel gespeichert wird.
+The key receives the result of the function \lua{string.match(value,
+match)}, which means that the original value may not be stored
+completely in the key.
+
+\InputLuaExample[firstline=22,lastline=23]{defs/attrs/match.lua}
+
+\noindent
+% Das Präfix “waste ” und das Suffix “ rubbisch” der Zeichenketten wird
+% verworfen.
+The prefix “waste ” and the suffix “ rubbisch” of the string are
+discarded.
+
+\InputLuaExample[firstline=29,lastline=29]{defs/attrs/match.lua}
+
+\noindent
+% Da Funktion \lua{string.match(value, match)} immer eine Zeichenkette
+% zurückgibt, ist der Wert des Schlüssel auch immer eine Zeichenkette.
+Since function \lua{string.match(value, match)} always returns a string,
+the value of the key is also always a string.
+
+%%
+%
+%%
+
+\subsubsection{Attribute “\texttt{name}”}
+
+% Die Option \lua{name} ermöglicht eine alternative Notation von
+% Schlüsselnamen.
+The \lua{name} attribute allows an alternative notation of key names.
+%
+% Anstatt ...
+Instead of ...
+
+\InputLuaExample[firstline=4,lastline=5]{defs/attrs/name.lua}
+
+\noindent
+% ... können wir schreiben:
+... we can write:
+
+\InputLuaExample[firstline=11,lastline=15]{defs/attrs/name.lua}
+
+%%
+%
+%%
+
+\subsubsection{Attribute “\texttt{process}”}
+\label{attr-process}
+
+The \lua{process} attribute can be used to define a function whose return
+value is passed to the key. Four parameters are passed when the
+function is called:
+
+\begin{enumerate}
+\item \lua{value}:
+% Der zum schlüssel gehörende aktuelle Wert.
+The current value asssociated with the key.
+
+\item \lua{input}:
+% Die Ergebnis-Tabelle, die vor dem Zeitpunkt geklont wurde, als mit dem
+% Anwenden der Definitionen begonnen wurde.
+The result table cloned before the time the definitions started to be applied.
+
+\item \lua{result}: The table in which the final result will be saved.
+
+\item \lua{unknown}: The table in which the unknown key-value pairs
+are stored.
+\end{enumerate}
+
+% Das folgende Beispiel demonstriert den Parameter \lua{value}.
+\noindent
+The following example demonstrates the \lua{value} parameter:
+\InputLuaExample[firstline=4,lastline=14]{defs/attrs/process.lua}
+
+\noindent
+The following example demonstrates the \lua{input} parameter:
+
+\InputLuaExample[firstline=22,lastline=34]{defs/attrs/process.lua}
+
+\noindent
+The following example demonstrates the \lua{result} parameter:
+
+\InputLuaExample[firstline=42,lastline=50]{defs/attrs/process.lua}
+
+\noindent
+The following example demonstrates the \lua{unknown} parameter:
+
+\InputLuaExample[firstline=58,lastline=65]{defs/attrs/process.lua}
+\InputLuaExample[firstline=69,lastline=69]{defs/attrs/process.lua}
+
+%%
+%
+%%
+
+\subsubsection{Attribute “\texttt{required}”}
 
-\strut
+\InputLuaExample[firstline=4,lastline=5]{defs/attrs/required.lua}
 
-\newpage
+\InputLuaExample[firstline=13,lastline=14]{defs/attrs/required.lua}
 
-\tableofcontents
+\noindent
+A recursive example:
 
-\newpage
+\InputLuaExample[firstline=18,lastline=23]{defs/attrs/required.lua}
+\InputLuaExample[firstline=29,lastline=30]{defs/attrs/required.lua}
+\InputLuaExample[firstline=38,lastline=39]{defs/attrs/required.lua}
 
-\section{Introduction}
+%%
+%
+%%
 
-\noindent
-|luakeys| is a Lua module that can parse key-value options like the
-\TeX{} packages \href{https://www.ctan.org/pkg/keyval}{keyval},
-\href{https://www.ctan.org/pkg/kvsetkeys}{kvsetkeys},
-\href{https://www.ctan.org/pkg/kvoptions}{kvoptions},
-\href{https://www.ctan.org/pkg/xkeyval}{xkeyval},
-\href{https://www.ctan.org/pkg/pgfkeys}{pgfkeys} etc. do. |luakeys|,
-however, accompilshes this task entirely, by using the Lua language and
-doesn’t rely on \TeX{}. Therefore this package can only be used with the
-\TeX{} engine Lua\TeX{}. Since |luakeys| uses
-\href{http://www.inf.puc-rio.br/~roberto/lpeg/}{LPeg}, the parsing
-mechanism should be pretty robust.
+\subsubsection{Attribute “\texttt{sub_keys}”}
 
-The TUGboat article
-\href{http://www.tug.org/tugboat/tb30-1/tb94wright-keyval.pdf}
-{“Implementing key–value input: An introduction” (Volume 30 (2009), No. 1)}
-by Joseph Wright and Christian Feuersänger gives a good overview of the
-available key-value packages.
+% Mit dem Attribut \lua{sub_keys} können ineinander verschachtelte
+% Schlüssel-Wert-Paar-Definitionen aufgebaut werden.
+The \lua{sub_keys} attribute can be used to build nested key-value pair
+definitions.
 
-This package would not be possible without the article
-\href{https://tug.org/TUGboat/tb40-2/tb125menke-lpeg.pdf}
-{Parsing complex data formats in LuaTEX with LPEG (Volume 40 (2019), No. 2)}.
+\InputLuaExample[firstline=4,lastline=16]{defs/attrs/sub-keys.lua}
 
 %-----------------------------------------------------------------------
 %
 %-----------------------------------------------------------------------
 
-\clearpage
+\subsection{Function \texttt{render(result): string}}
+
+The function \lua{render(result)} reverses the function
+\lua{parse(kv_string)}. It takes a Lua table and converts this table
+into a key-value string. The resulting string usually has a different
+order as the input table.
+
+\InputLuaExample[firstline=4,lastline=10]{functions/render.lua}
+
+\noindent
+In Lua only tables with 1-based consecutive integer keys (a.k.a. array
+tables) can be parsed in order.
 
-\section{Usage}
+\InputLuaExample[firstline=16,lastline=17]{functions/render.lua}
 
 %%
 %
 %%
 
-\subsection{Using the Lua module \texttt{luakeys.lua}}
+\subsection{Function \texttt{debug(result): void}}
 
-The core functionality of this package is realized in Lua. So you can
-use \texttt{luakeys} without using the wrapper \TeX{} files
-\texttt{luakeys.sty} and \texttt{luakeys.tex}.
+The function \lua{debug(result)} pretty prints a Lua table to standard
+output (stdout). It is a utility function that can be used to debug and
+inspect the resulting Lua table of the function \lua{parse}. You have to
+compile your \TeX{} document in a console to see the terminal output.
 
-\begin{minted}{latex}
-\documentclass{article}
-\directlua{
-  luakeys = require('luakeys')
-}
+\InputLuaExample[firstline=4,lastline=5]{functions/debug.lua}
 
-\newcommand{\helloworld}[2][]{
-  \directlua{
-    local keys = luakeys.parse('\luaescapestring{\unexpanded{#1}}')
-    luakeys.print(keys)
-    local marg = '#2'
-    tex.print(keys.greeting .. ', ' .. marg .. keys.punctuation)
+\noindent
+The output should look like this:
+
+\begin{minted}{md}
+{
+  ['level1'] = {
+      ['level2'] = {
+        ['key'] = 'value',
+    },
   }
 }
-\begin{document}
-\helloworld[greeting=hello,punctuation=!]{world}
-\end{document}
 \end{minted}
 
 %%
 %
 %%
 
-\subsection{Using the Lua\LaTeX{} wrapper \texttt{luakeys.sty}}
-
-The supplied Lua\LaTeX{} file is quite small:
+\subsection{Function \texttt{save(identifier, result): void}}
 
-\begin{minted}{latex}
-\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{luakeys}
-\directlua{luakeys = require('luakeys')}
-\end{minted}
+The function \lua{save(identifier, result)} saves a result (a
+table from a previous run of \lua{parse}) under an identifier.
+Therefore, it is not necessary to pollute the global namespace to
+store results for the later usage.
 
-\noindent
-It loads the Lua module into the global variable \texttt{luakeys}.
+%%
+%
+%%
 
-\begin{minted}{latex}
-\documentclass{article}
-\usepackage{luakeys}
+\subsection{Function \texttt{get(identifier): result}}
 
-\begin{document}
-  \directlua{
-    local keys = luakeys.parse('one,two,three')
-    tex.print(keys[1])
-    tex.print(keys[2])
-    tex.print(keys[3])
-  }
-\end{document}
-\end{minted}
+The function \lua{get(identifier)} retrieves a saved result from the
+result store.
 
 %%
 %
 %%
 
-\subsection{Using the plain Lua\TeX{} wrapper \texttt{luakeys.tex}}
+\subsection{Table \texttt{is}}
 
-Even smaller is the file \texttt{luakeys.tex}. It consists of only one
-line:
+\subsubsection{Function \texttt{is.boolean(value): boolean}}
+\InputLuaExample[firstline=7,lastline=23]{is-table.lua}
 
-\begin{minted}{latex}
-\directlua{luakeys = require('luakeys')}
-\end{minted}
+\subsubsection{Function \texttt{is.dimension(value): boolean}}
+\InputLuaExample[firstline=27,lastline=37]{is-table.lua}
 
-\noindent
-It does the same as the Lua\LaTeX{} wrapper and loads the Lua module
-\texttt{luakeys.lua} into the global variable \texttt{luakeys}.
+\subsubsection{Function \texttt{is.integer(value): boolean}}
+\InputLuaExample[firstline=41,lastline=46]{is-table.lua}
 
-\begin{minted}{latex}
-\input luakeys.tex
+\subsubsection{Function \texttt{is.number(value): boolean}}
+\InputLuaExample[firstline=50,lastline=57]{is-table.lua}
 
-\directlua{
-  local keys = luakeys.parse('one,two,three')
-  tex.print(keys[1])
-  tex.print(keys[2])
-  tex.print(keys[3])
-}
-\bye
-\end{minted}
+\subsubsection{Function \texttt{is.string(value): boolean}}
+\InputLuaExample[firstline=61,lastline=67]{is-table.lua}
+
+%-----------------------------------------------------------------------
+%
+%-----------------------------------------------------------------------
 
 \section{Syntax of the recognized key-value format}
 
@@ -202,13 +1079,13 @@ It does the same as the Lua\LaTeX{} wrapper and loads the Lua module
 %
 %%
 
-\subsection{A attempt to put the syntax into words}
+\subsection{An attempt to put the syntax into words}
 
 A key-value pair is definied by an equal sign (\texttt{key=value}).
-Several key-value pairs or values without keys are lined up with commas
-(\texttt{key=value,value}) and build a key-value list. Curly brackets
-can be used to create a recursive data structure of nested key-value
-lists (\texttt{level1=\{level2=\{key=value,value\}\}}).
+Several key-value pairs or keys without values (naked keys) are lined up
+with commas (\texttt{key=value,naked}) and build a key-value list. Curly
+brackets can be used to create a recursive data structure of nested
+key-value lists (\texttt{level1=\{level2=\{key=value,naked\}\}}).
 
 %%
 %
@@ -231,9 +1108,17 @@ lists (\texttt{level1=\{level2=\{key=value,value\}\}}).
   \alt <string-quoted>
   \alt <string-unquoted>
 
+<dimension> ::= <number> <unit>
+
+<number> ::= <sign> ( <integer> [ <fractional> ] | <fractional> )
+
+<fractional> ::= `.' <integer>
+
 <sign> ::= `-' | `+'
 
-<integer> ::= `0' | `1' | `2' | `3' | `4' | `5' | `6' | `7' | `8' | `9'
+<integer> ::= <digit> \{ <digit> \}
+
+<digit> ::= `0' | `1' | `2' | `3' | `4' | `5' | `6' | `7' | `8' | `9'
 
 <unit> ::= `bp' | `BP'
   \alt `cc' | `CC'
@@ -297,8 +1182,6 @@ into Lua’s boolean type \lua{true}, the strings \texttt{false},
 %
 %%
 
-\clearpage
-
 \subsubsection{number}
 
 \begin{multicols}{2}
@@ -322,35 +1205,14 @@ into Lua’s boolean type \lua{true}, the strings \texttt{false},
 %
 %%
 
-\clearpage
-
 \subsubsection{dimension}
 
-|luakeys| detects \TeX{} dimensions and automatically converts the
-dimensions into scaled points using the function \lua{tex.sp(dim)}. Use
-the option \lua{convert_dimensions} of the function
-\lua{parse(kv_string, options)} to disalbe the automatic conversion.
-
-\begin{minted}{lua}
-local result = parse('dim=1cm', {
-  convert_dimensions = false,
-})
-\end{minted}
-
-\noindent
-If you want to convert a scale point into a unit string you can use the module
-\href{https://raw.githubusercontent.com/latex3/lualibs/master/lualibs-util-dim.lua}{lualibs-util-dim.lua}.
-
-\begin{minted}{latex}
-\begin{luacode}
-require('lualibs')
-tex.print(number.todimen(tex.sp('1cm'), 'cm', '%0.0F%s'))
-\end{luacode}
-\end{minted}
-
+\begin{multicols}{3}
+\tiny
 \begin{center}
 \begin{tabular}{rl}
-\textbf{Unit name} & \textbf{Description} \\\hline
+% \textbf{Unit name}
+& \textbf{Description} \\\hline
 bp & big point \\
 cc & cicero \\
 cm & centimeter \\
@@ -367,7 +1229,8 @@ sp & scaledpoint \\
 \end{tabular}
 \end{center}
 
-\begin{multicols}{2}
+\columnbreak
+
 \begin{minted}{latex}
 \luakeysdebug{
   bp = 1bp,
@@ -385,6 +1248,9 @@ sp & scaledpoint \\
   sp = 1sp,
 }
 \end{minted}
+
+\columnbreak
+
 \begin{minted}{lua}
 {
   ['bp'] = 65781,
@@ -410,64 +1276,41 @@ sp & scaledpoint \\
 
 \subsubsection{string}
 
-There are two ways to specify strings: With or without quotes. If the
-text have to contain commas or equal signs, then double quotation
-marks must be used.
-
-\begin{multicols}{2}
-\begin{minted}{latex}
-\luakeysdebug{
-  without quotes = no commas and equal signs are allowed,
-  with double quotes = ", and = are allowed",
-}
-\end{minted}
-\begin{minted}{lua}
-{
-  ['without quotes'] = 'no commas and equal signs are allowed',
-  ['with double quotes'] = ', and = are allowed',
-}
-\end{minted}
-\end{multicols}
-
-\subsubsection{Standalone values}
+% Es gibt zwei Möglichkeiten Zeichenketten anzugeben:
+There are two ways to specify strings:
+%
+% Mit oder ohne doppelte Anführungszeichen.
+With or without double quotes.
+%
+% Wenn der Text Kommas, geschweifte Klammern oder Gleichheitszeichen
+% enthalten soll, müssen doppelte Anführungszeichen verwendet werden.
+If the text have to contain commas, curly braces or equal signs, then
+double quotes must be used.
 
-Standalone values are values without a key. They are converted into an
-array. In Lua an array is a table with numeric indexes (The first index
-is 1).
+\InputLuaExample[firstline=4,lastline=17]{data-types/string.lua}
 
-\begin{multicols}{2}
-\begin{minted}{latex}
-\luakeysdebug{one,two,three}
-\end{minted}
-\columnbreak
-\begin{minted}{lua}
-{ 'one', 'two', 'three' }
-\end{minted}
+\subsubsection{Naked keys}
 
-\noindent
-is equivalent to
+% Nackte Schlüssel sind Schlüssel ohne Wert.
+Naked keys are keys without a value.
+%
+% Mit der Option \lua{naked_as_value} können sie als Werte in ein Feld
+% übernommen werden.
+Using the option \lua{naked_as_value} they can be converted into values
+and stored into an array.
+%
+% In Lua ist ein Feld eine Tabelle mit numerischen Indizes (der erste
+% Index ist 1).
+In Lua an array is a table with numeric indexes (The first index is 1).
 
-\begin{minted}{lua}
-{
-  [1] = 'one',
-  [2] = 'two',
-  [3] = 'three',
-}
-\end{minted}
-\end{multicols}
+\InputLatexExample[firstline=5,lastline=12]{luakeysdebug/naked-keys.tex}
 
 \noindent
+% VAlle erkannten Datentypen können als eigenständige Werte verwendet
+% werden.
 All recognized data types can be used as standalone values.
 
-\begin{multicols}{2}
-\begin{minted}{latex}
-\luakeysdebug{one,2,3cm}
-\end{minted}
-\columnbreak
-\begin{minted}{lua}
-{ 'one', 2, 5594039 }
-\end{minted}
-\end{multicols}
+\InputLatexExample[firstline=14,lastline=19]{luakeysdebug/naked-keys.tex}
 
 %-----------------------------------------------------------------------
 %
@@ -475,166 +1318,34 @@ All recognized data types can be used as standalone values.
 
 \clearpage
 
-\section{Exported functions of the Lua module \texttt{luakeys.lua}}
-
-To learn more about the individual functions (local functions), please
-read the \href{https://josef-friedrich.github.io/luakeys/}{source code
-documentation}, which was created with
-\href{http://stevedonovan.github.io/ldoc/}{LDoc}. The Lua module exports
-this functions:
-
-\begin{minted}{lua}
-local luakeys = require('luakeys')
-local parse = luakeys.parse
-local render = luakeys.render
---local print = luakeys.print -- That would overwrite the built-in Lua function
-local save = luakeys.save
-local get = luakeys.get
-\end{minted}
-
-%%
-%
-%%
+\section{Examples}
 
-\subsection{\texttt{parse(kv\_string, options)}: table}
+\subsection{Extend and modify keys of existing macros}
 
-The function \lua{parse(input_string, options)} is the main method of
-this module. It parses a key-value string into a Lua table.
+Extend the includegraphics macro with a new key named \latex{caption}
+and change the accepted values of the \latex{width} key. A number
+between 0 and 1 is allowed and converted into
+\latex{width=0.5\linewidth}
 
-\begin{minted}{latex}
-\newcommand{\mykeyvalcmd}[1][]{
-  \directlua{
-    result = luakeys.parse('#1')
-    luakeys.print(result)
-  }
-  #2
-}
-\mykeyvalcmd[one=1]{test}
-\end{minted}
+\InputLuaExample{extend-includegraphics/extend-keys.lua}
+\InputLatexExample{extend-includegraphics/extend-keys.tex}
 
-\noindent
-In plain \TeX:
+\subsection{Process document class options}
 
 \begin{minted}{latex}
-\def\mykeyvalcommand#1{
-  \directlua{
-    result = luakeys.parse('#1')
-    luakeys.print(result)
-  }
-}
-\mykeyvalcmd{one=1}
-\end{minted}
-
-\noindent
-The function can be called with an options table. This options are
-supported:
-
-\begin{minted}{lua}
-local result = parse('one,two,three', {
-  convert_dimensions = false,
-  unpack_single_array_value = false,
-  standalone_as_true = false,
-  converter = function(key, value, depth, current_table, root_table)
-    return key, value
-  end,
-  case_insensitive_keys = false,
-})
-\end{minted}
-
-\noindent
-The options can also be set globally using the exported table
-|default_options|:
-
-\begin{minted}{lua}
-luakeys.parse('dim=1cm') -- {dim = 1864679}
-luakeys.default_options.convert_dimensions = false
--- or:
--- local defaults = luakeys.default_options
--- defaults.convert_dimensions = false
-luakeys.parse('dim=1cm') -- {dim = '1cm'}
-\end{minted}
-
-%%
-%
-%%
-
-\subsection{\texttt{render(tbl)}: string}
-
-The function \lua{render(tbl)} reverses the function
-\lua{parse(kv_string)}. It takes a Lua table and converts this table
-into a key-value string. The resulting string usually has a different
-order as the input table.
-
-\begin{minted}{lua}
-result = luakeys.parse('one=1,two=2,tree=3,')
-print(luakeys.render(result))
---- one=1,two=2,tree=3,
---- or:
---- two=2,one=1,tree=3,
---- or:
---- ...
-\end{minted}
-
-\noindent
-In Lua only tables with 1-based consecutive integer keys (a.k.a. array
-tables) can be parsed in order.
-
-\begin{minted}{lua}
-result = luakeys.parse('one,two,three')
-print(luakeys.render(result))
---- one,two,three, (always)
+\directlua{luakeys.parse('\@classoptionslist')}
 \end{minted}
 
-%%
-%
-%%
-
-\subsection{\texttt{print(tbl): void}}
-
-The function \lua{print(tbl)} pretty prints a Lua table to standard
-output (stdout). It is a utility function that can be used to debug and
-inspect the resulting Lua table of the function \lua{parse}. You have to
-compile your \TeX{} document in a console to see the terminal output.
-
-%\luakeysdebug{level1={level2={key=value}}}
+\InputLatexExample{class-options/test-class.cls}
+\InputLatexExample{class-options/use-test-class.tex}
 
 \begin{minted}{lua}
-result = luakeys.parse('level1={level2={key=value}}')
-luakeys.print(result)
-\end{minted}
-
-\noindent
-The output should look like this:
-
-\begin{minted}{md}
 {
-  ['level1'] = {
-    ['level2'] = {
-      ['key'] = 'value',
-  },
+  [1] = '12pt',
+  [2] = 'landscape',
 }
 \end{minted}
 
-%%
-%
-%%
-
-\subsection{\texttt{save(identifier, result): void}}
-
-The function \lua{save(identifier, result)} saves a result (a
-table from a previous run of \lua{parse}) under an identifier.
-Therefore, it is not necessary to pollute the global namespace to
-store results for the later usage.
-
-%%
-%
-%%
-
-\subsection{\texttt{get(identifier): table}}
-
-The function \lua{get(identifier)} retrieves a saved result from the
-result store.
-
 %-----------------------------------------------------------------------
 %
 %-----------------------------------------------------------------------
@@ -685,7 +1396,7 @@ An example of how to use the command in \LaTeX:
 \usepackage{luakeys-debug}
 \begin{document}
 \luakeysdebug[
-  unpack single array values=false,
+  unpack=false,
   convert dimensions=false
 ]{one,two,three}
 \end{document}
@@ -723,9 +1434,9 @@ An example of how to use the command in \LaTeX:
 
 \clearpage
 
-\subsection{luakeys.tex}
+\subsection{luakeys.sty}
 
-\inputminted[linenos=true]{latex}{luakeys.tex}
+\inputminted[linenos=true]{latex}{luakeys.sty}
 
 %%
 %
@@ -766,9 +1477,22 @@ An example of how to use the command in \LaTeX:
 }
 \changes{v0.5}{2022/04/04}{
 * Add possibility to change options globally
-* New option: standalone\_as\_true
+* New option: standalone_as_true
 * Add a recursive converter callback / hook to process the parse tree
-* New option: case\_insensitive\_keys
+* New option: case_insensitive_keys
+}
+\changes{v0.6}{2022/06/09}{
+* New feature: keys now can be defined using the function
+  “define(defs, opts)” or “define(kv_string, { defs = { key = { ... } } })”
+* Rename the global options table from “default_options” to “opts”
+* New option “format_keys”
+* Remove option “case_insensitive_keys”. Use
+  “format_keys = \{ lower \}” to achieve the same effect.
+* The default value of the option “convert_dimension” is now false.
+* The option “standalone_as_true” is renamed to “naked_as_value”.
+  The boolean value of the option must be changed to the opposite to
+  produce the previous effect.
+* The function “print()” is now called “debug()”
 }
 \pagebreak
 \PrintChanges
-- 
cgit v1.2.3

