\documentclass{ltxdoc} \EnableCrossrefs \CodelineIndex \RecordChanges \usepackage{mdframed} \usepackage{minted} \usepackage{luakeys} \usepackage{luakeys-debug} \usepackage{multicol} \usepackage{luacode} \usepackage{syntax} \usepackage{graphicx} \definecolor{bg}{rgb}{0.95,0.95,0.95} \usemintedstyle{friendly} \setminted{ breaklines=true, fontsize=\footnotesize, style=manni, } \def\lua#1{\mintinline{lua}|#1|} \def\latex#1{\mintinline{latex}|#1|} \NewDocumentCommand { \InputLatex } { O{} m } { \inputminted[ linenos=false, bgcolor=bg, #1 ]{latex}{examples/#2} } \NewDocumentCommand { \InputLua } { O{} m } { \inputminted[ linenos=false, bgcolor=bg, #1 ]{lua}{examples/#2} } \catcode`_=12 \def\DefaultOpt#1{% \texttt{\directlua{ tex.print(luakeys.print_default('opts', '#1')) }}% } \def\DefaultOptDescription#1{ \noindent The default value of the option “\texttt{#1}” is: \DefaultOpt{#1}. } \begin{document} \providecommand*{\url}{\texttt} \title{The \textsf{luakeys} package} \author{% Josef Friedrich\\% \url{josef@friedrich.rocks}\\% \href{https://github.com/Josef-Friedrich/luakeys} {github.com/Josef-Friedrich/luakeys}% } \date{v0.14.0 from 2024/04/09} \maketitle \vfill \InputLua[firstline=4,lastline=7]{first-page.lua} \noindent Result: \begin{center} \begin{minted}{lua} { ['level1'] = { ['level2'] = { ['naked'] = true, ['dim'] = 1864679, ['bool'] = false, ['num'] = -0.001, ['str'] = 'lua,{}', } } } \end{minted} \end{center} \vfill \strut \newpage \tableofcontents \newpage % \section{Einführung} \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. % Der Artikel TUGboat % \href{http://www.tug.org/tugboat/tb30-1/tb94wright-keyval.pdf} % {“Implementing key–value input: An introduction” (Volume 30 (2009), No. % 1)} von \emph{Joseph Wright} und \emph{Christian Feuersänger} gibt einen % einen guten Überblick über die verfügbaren Key-Value-Pakete. 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. % % Dieser Artikel geht auf eine auf tex.stackexchange.com von Will % Robertson: gestellte Frage zurück. This article is based on a question asked on tex.stackexchange.com by Will Robertson: \href{https://tex.stackexchange.com/questions/26771} {A big list of every keyval package}. % % CTAN stellt auch eine Übersichtsseite zum Thema bereit. CTAN also provides an overview page on the subject of \href{https://www.ctan.org/topic/keyval} {Key-Val: packages with key-value argument systems}. % Dieses Paket wäre ohne den Artikel % \href{https://tug.org/TUGboat/tb40-2/tb125menke-lpeg.pdf} % {"Parsing complex data formats in LuaTEX with LPEG" (Volume 40 (2019), % No. 2)} nicht möglich gewesen. 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)}. \subsection{Pros of \texttt{luakeys}} \begin{itemize} % \item Schlüssel-Wert-Paare können unabhängig vom Makro-Paket (latex or % context) analysiert werden. \item Key-value pairs can be parsed independently of the macro collection (\LaTeX{} or Con\TeX{}t). % Sogar in Plain LuaTex können Schlüssel analysiert werden Even in plain Lua\TeX{} keys can be parsed. % \item |luakeys| kann mit ineinander verschachtelten listen an % Schlüssel-Wert-Paaren umgehen, d. h. es kann mit einer rekursiven % Datenstruktur an Schlüssel umgehen. \item |luakeys| can handle nested lists of key-value pairs, i.e. it can handle a recursive data structure of keys. % \item Schlüssel müssen nicht, aber können definiert werden. \item Keys do not have to be defined, but can they can be defined. \end{itemize} \subsection{Cons of \texttt{luakeys}} \begin{itemize} % \item Das Packet funktioniert nur in der Verbindung mit Lua\TeX. \item The package works only in combination with Lua\TeX. % \item Du musst zwei Sprachen beherrschen: \TeX{} und Lua. \item You need to know two languages: \TeX{} and Lua. \end{itemize} %----------------------------------------------------------------------- % %----------------------------------------------------------------------- % \section{Wie das Paket geladen wird} \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|. \InputLatex{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 Datei \texttt{luakeys.sty} lädt das Lua-Modul in die globale % Variable \texttt{luakeys}. The \texttt{luakeys.sty} file loads the Lua module into the global variable \texttt{luakeys}. \InputLatex{loading/tex-latex.tex} %% % %% % \subsection{Verwendung des Plain-Lua\TeX{}-Hüllpakets % \texttt{luakeys.tex}} \subsection{Using the plain Lua\TeX{} wrapper \texttt{luakeys.tex}} \noindent % Es macht dasselbe wie das Lua\LaTeX{}-Hüllpacket und lädt das % Lua-Modul \texttt{luakeys.lua} in die globale Variable % \texttt{luakeys}. The file \texttt{luakeys.tex} does the same as the Lua\LaTeX{} wrapper and loads the Lua module \texttt{luakeys.lua} into the global variable \texttt{luakeys}. \InputLatex{loading/tex-plain.tex} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Lua interface / API} % Luakeys exportiert nur eine Funktion, die aufgerufen werden muss, um auf % die öffentliche API zuzugreifen Luakeys exports only one function that must be called to access the public API. % % Diese Exportfunktion gibt eine Tabelle zurück, die die öffentlichen % Funktionen und weiteren Tabellen enthält: This export function returns a table containing the public functions and additional tables: \InputLua[firstline=3,lastline=16]{export.lua} \noindent % 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} \noindent % Es wird empfohlen, beim Entwickeln im Texteditor luakeys zusammen mit % dem Lua-Language-Server zu verwenden. It is recommended to use luakeys together with the \href{https://github.com/sumneko/lua-language-server}{github.com/sumneko/lua-language-server} when developing in a text editor. % % Luakeys unterstützt nämlich das vom Server angeboten Annotationsformat luakeys supports the annotation format offered by the server. % Sie sollten dann Warnungen erhalten, wenn Sie die mittlerweile % ziemlich große API von luakeys falsch verwenden. You should then get warnings if you misuse luakeys’ now rather large API. %% % %% \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. \InputLatex{functions/parse/tex-latex.tex} \noindent In plain \TeX: \InputLatex{functions/parse/tex-plain.tex} \subsection{Options to configure the \texttt{parse} function} \noindent % Die Funktion \lua{parse} kann mit einer Optionstabelle aufgerufen % werden. The \lua{parse} function can be called with an options table. % Diese Optionen werden unterstützt: This options are supported: \catcode`_=12 \directlua{luakeys.print_names('opts')} \InputLua[firstline=7,lastline=99]{opts/all-opts.lua} \subsection{Table “\texttt{opts}”} \label{table-opts} \noindent % Die Optionen können auch global über die exportierte Tabelle % \lua{opts} gesetzt werden: The options can also be set globally using the exported table \lua{opts}: \InputLua[firstline=4,lastline=4]{opts/exported-default-opts.lua} \InputLua[firstline=10,lastline=11]{opts/exported-default-opts.lua} \noindent % Damit es zu keinen Wechselwirkungen mit anderen Paketen kommt, die auch % |luakeys| verwenden und die Optionen global setzen, ist es anzuraten, % die Funktion \lua{get_private_instance()} zum Laden das Paket verwenden. To avoid interactions with other packages that also use |luakeys| and set the options globally, it is recommended to use the \lua{get_private_instance()} function (\ref{function:get-private-instance}) to load the package. %% % %% \subsubsection{Option “\texttt{accumulated_result}”} % Streng genommen handelt es sich hier um keine Option Strictly speaking, this is not an option. % % Mit der Option \lua{accumulated_result} kann eine Ergebnistabelle % angegeben werden, die bei jedem Aufruf der \lua{parse}-Funktion weiter % befüllt wird. The \lua{accumulated_result} “option” can be used to specify a result table that is filled with each call of the \lua{parse} function. \InputLua[firstline=5,lastline=14]{opts/accumulated-result.lua} %% % %% \subsubsection{Option “\texttt{assignment_operator}”} \label{option:assignment-operator} \label{options-delimiter} The option \lua{assignment_operator} configures the delimiter that assigns a value to a key. The default value of this option is \texttt{"="}. The code example below demonstrates all six delimiter related options. \InputLua[firstline=4,lastline=13]{opts/delimiters.lua} \begin{tabular}{ll} \textbf{Delimiter options} & \textbf{Section} \\ assignment_operator & \ref{option:assignment-operator}\\ group_begin & \ref{option:group-begin}\\ group_end & \ref{option:group-end}\\ list_separator & \ref{option:list-separator}\\ quotation_begin & \ref{option:quotation-begin}\\ quotation_end & \ref{option:quotation-end}\\ \end{tabular} %% % %% \subsubsection{Option “\texttt{convert_dimensions}”} % Wenn Sie die Option \lua{convert_dimensions} auf \lua{true} setzen, % erkennt |luakeys| die \TeX{}-Dimensionen und konvertiert sie mit Hilfe % der die Funktion \lua{tex.sp(dim)} in scaled points. 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)}. \InputLua[firstline=4,lastline=7]{opts/convert-dimensions/true.lua} \noindent % Standardmäßig werden die Dimensionen nicht in skalierte Punkte % umgewandelt. By default the dimensions are not converted into scaled points. \InputLua[firstline=4,lastline=9]{opts/convert-dimensions/false.lua} \noindent % Wenn Sie eine skalierte Punktzahl in einen Dimensionszeichenketten % umwandeln möchten, können Sie das Modul If you want to convert a scaled points number into a dimension 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} \DefaultOptDescription{convert_dimensions} %% % %% \subsubsection{Option “\texttt{debug}”} % Wenn die Option \lua{debug} auf true gesetzt ist, wird die % Ergebnistabelle in der Konsole ausgegeben. If the option \lua{debug} is set to true, the result table is printed to the console. \InputLatex{opts/debug-latex.tex} \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} \DefaultOptDescription{debug} %% % %% \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. \InputLua[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}. \InputLua[firstline=11,lastline=12]{opts/default.lua} \DefaultOptDescription{default} %% % %% \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. \InputLua[firstline=4,lastline=7]{opts/defaults.lua} \DefaultOptDescription{defaults} %% % %% \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 ... \InputLua[firstline=4,lastline=5]{opts/defs.lua} \noindent % können wir schreiben .. we can write ... \InputLua[firstline=11,lastline=13]{opts/defs.lua} \DefaultOptDescription{defs} %% % %% \subsubsection{Option “\texttt{false_aliases}”} \label{option:false-aliases} % Mit den den Optionen \lua{true_aliases} and \lua{false_aliases} können % die Zeichenketten festgelegt werden, die vom Parser als Wahrheitswerte % erkannt werden. The \lua{true_aliases} and \lua{false_aliases} options can be used to specify the strings that will be recognized as boolean values by the parser. % Standardmäßig sind folgende Zeichenketten konfiguriert The following strings are configured by default. \InputLua[firstline=4,lastline=8]{opts/boolean-aliases.lua} \InputLua[firstline=14,lastline=18]{opts/boolean-aliases.lua} \InputLua[firstline=24,lastline=28]{opts/boolean-aliases.lua} % Siehe Abschnitt \label{option:true-aliases} für die entsprechende % Option. See section \ref{option:true-aliases} for the corresponding option. %% % %% \subsubsection{Option “\texttt{format_keys}”} % Mit Hilfe der Option \lua{format_keys} können die Schlüssel formatiert % werden. With the help of the option \lua{format_keys} the keys can be formatted. % Die Werte dieser Option müssen in einer Tabelle angegeben werden. The values of this option must be specified in a table. \begin{description} \item[lower] % Um alle Schlüssel in \emph{Kleinbuchstaben} umzuwandeln, geben sie in % der Optionentabelle \lua{lower} an. To convert all keys to \emph{lowercase}, specify \lua{lower} in the options table. \InputLua[firstline=4,lastline=5]{opts/format-keys.lua} \item[snake] % Um alle Schlüssel in \emph{snake case} (Die Wörter sind durch % Unterstriche getrennt) umzuwandeln, geben sie in der Optionentabelle % \lua{snake} an. To make all keys \emph{snake case} (The words are separated by underscores), specify \lua{snake} in the options table. \InputLua[firstline=11,lastline=12]{opts/format-keys.lua} \item[upper] % Um alle Schlüssel in \emph{Grossbuchstaben} umzuwandeln, geben sie in % der Optionentabelle \lua{upper} an. To convert all keys to \emph{uppercase}, specify \lua{upper} in the options table. \InputLua[firstline=18,lastline=19]{opts/format-keys.lua} \end{description} % Sie können auch mehrere Formatierungsarten kombinieren. You can also combine several types of formatting. \InputLua[firstline=25,lastline=26]{opts/format-keys.lua} \DefaultOptDescription{format_keys} %% % %% \subsubsection{Option “\texttt{group_begin}”} \label{option:group-begin} The option \lua{group_begin} configures the delimiter that marks the beginning of a group. The default value of this option is \texttt{"\{"}. A code example can be found in section \ref{options-delimiter}. %% % %% \subsubsection{Option “\texttt{group_end}”} \label{option:group-end} The option \lua{group_end} configures the delimiter that marks the end of a group. The default value of this option is \texttt{"\}"}. A code example can be found in section \ref{options-delimiter}. %% % %% \subsubsection{Option “\texttt{invert_flag}”} % Wird ein nackter Schlüssel mit einem vorangestellten Ausrufezeichen versehen, so wird sein Standardwert invertiert. If a naked key is prefixed with an exclamation mark, its default value is inverted. % Statt \lua{true} nimmt der Schlüssel jetzt den Wert \lua{falsch} an. Instead of \lua{true} the key now takes the value \lua{false}. \InputLua[firstline=4,lastline=5]{opts/invert-flat.lua} \noindent % Mit der Option \lua{invert_flag} kann dieses Invertierungszeichen % geändert werden. The \lua{invert_flag} option can be used to change this inversion character. \InputLua[firstline=11,lastline=12]{opts/invert-flat.lua} \noindent % Ist der Standardwert für nackte Schlüssel beispielweise auf \lua{false} % gesetzt, so nehmen die mit dem Umkehrungszeichen versehenen nackten % Schlüssel den Wert \lua{true} an. For example, if the default value for naked keys is set to \lua{false}, the naked keys prefixed with the invert flat take the value \lua{true}. \InputLua[firstline=18,lastline=19]{opts/invert-flat.lua} \noindent % Setzen sie die Option \lua{invert_flag} auf \lua{false}, um diese % automatische Wertumkehrung zu deaktivieren. Set the \lua{invert_flag} option to \lua{false} to disable this automatic boolean value inversion. \InputLua[firstline=25,lastline=26]{opts/invert-flat.lua} %% % %% \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. \InputLua[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. \InputLua[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. \InputLua[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{list_separator}”} \label{option:list-separator} The option \lua{list_separator} configures the delimiter that separates list items from each other. The default value of this option is \texttt{","}. A code example can be found in section \ref{options-delimiter}. %% % %% \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. \InputLua[firstline=4,lastline=5]{opts/naked-as-value.lua} \noindent If we set the option \lua{naked_as_value} to \lua{true}: \InputLua[firstline=11,lastline=14]{opts/naked-as-value.lua} \DefaultOptDescription{naked_as_value} %% % %% \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. \InputLua[firstline=5,lastline=6]{opts/no-error.lua} \noindent If we set the option \lua{no_error} to \lua{true}: \InputLua[firstline=9,lastline=10]{opts/no-error.lua} \DefaultOptDescription{no_error} %% % %% \subsubsection{Option “\texttt{quotation_begin}”} \label{option:quotation-begin} The option \lua{quotation_begin} configures the delimiter that marks the beginning of a string. The default value of this option is \texttt{'"'} (double quotes). A code example can be found in section \ref{options-delimiter}. %% % %% \subsubsection{Option “\texttt{quotation_end}”} \label{option:quotation-end} The option \lua{quotation_end} configures the delimiter that marks the end of a string. The default value of this option is \texttt{'"'} (double quotes). A code example can be found in section \ref{options-delimiter}. %% % %% \subsubsection{Option “\texttt{true_aliases}”} \label{option:true-aliases} See section \ref{option:false-aliases}. %% % %% \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 a single naked key or a single standalone value are unpacked. \InputLua[firstline=4,lastline=5]{opts/unpack.lua} \InputLua[firstline=11,lastline=12]{opts/unpack.lua} \DefaultOptDescription{unpack} %% % %% \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} \InputLua[firstline=4,lastline=16]{functions/define.lua} \noindent % Bei verschachtelten Definitionen können nur die letzten beiden % Möglichkeiten zur Angabe der Schlüsselnamen verwendet werden. For nested definitions, only the last two ways of specifying the key names can be used. \InputLua[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. % % Diese Attribute sind erlaubt. These attributes are allowed: \directlua{luakeys.print_names('attrs')}. % % 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. \InputLua[firstline=5,lastline=62]{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 ... \InputLua[firstline=4,lastline=7]{defs/attrs/alias.lua} \noindent multiple aliases by a list of strings. \InputLua[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. \InputLua[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. \InputLua[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. \InputLua[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: \InputLua[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'}, \lua{'list'}. % % 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. \InputLua[firstline=4,lastline=8]{defs/attrs/data-type.lua} \InputLua[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. \InputLua[firstline=4,lastline=9]{defs/attrs/default.lua} %% % %% \subsubsection{Attribute “\texttt{description}”} % Dieses Attribut wird momentan nicht weiterverarbeitet. This attribute is currently not processed further. % Es kann als Kommentar dienen. It can serve as a comment. %% % %% \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. \InputLua[firstline=4,lastline=9]{defs/attrs/exclusive-group.lua} \noindent % 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. \InputLua[firstline=21,lastline=23]{defs/attrs/exclusive-group.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 zuerst der Lua Funktion % \lua{string.match(value, match)} übergeben, bevor er dem Schlüssel % zugewiesen wird. The value of the key is first passed to the Lua function \lua{string.match(value, match)} (\url{http://www.lua.org/manual/5.3/manual.html#pdf-string.match}) before being assigned to the key. % % Du kannst das Attribut \lua{match} deshalb mit einer Pattern-Matching- % Zeichenkette konfigurieren, wie sie in Lua zu Einsatz kommt. You can therefore configure the \lua{match} attribute with a pattern matching string used in Lua. % % 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}). \InputLua[firstline=4,lastline=7]{defs/attrs/match/birthday.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. \InputLua[firstline=15,lastline=18]{defs/attrs/match/birthday.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. % % Im nächsten Beispiel wird der gesamte Eingabewert akzeptiert: In the next example, the entire input value is accepted: \InputLua[firstline=4,lastline=5]{defs/attrs/match/year.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. \InputLua[firstline=11,lastline=11]{defs/attrs/match/year.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 ... \InputLua[firstline=4,lastline=8]{defs/attrs/name/as-key.lua} \noindent % ... können wir schreiben: ... we can write: \InputLua[firstline=4,lastline=8]{defs/attrs/name/name-attr.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}. \InputLua[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}. \InputLua[firstline=13,lastline=13]{defs/attrs/opposite-keys.lua} \noindent % Gegensätzliche Schlüsselpaare können in einer Kurzschreibweise % angegeben werden, nämlich als Liste Opposing key pairs can be specified in a short form, namely as a list: % Der gegensätzliche Schlüssel, der den Wahrwert repräsentiert, muss in % dieser Liste zuerst angegeben werden, dann folgt der Falschwert. The opposite key, which represents the true value, must be specified first in this list, followed by the false value. \InputLua[firstline=19,lastline=21]{defs/attrs/opposite-keys.lua} %% % %% \subsubsection{Attribute “\texttt{pick}”} % Das Attribut \lua{pick} sucht nach einem Wert, der keinem Schlüssel % zugeordnet ist. The attribute \lua{pick} searches for a value not assigned to a key. % Der zuerst gefundene Wert, d. h. der weiter links stehende Wert, wird % einem Schlüssel zugewiesen. The first value found, i.e. the one further to the left, is assigned to a key. \InputLua[firstline=4,lastline=6]{defs/attrs/pick/dimension.lua} \noindent % Es wird nur in der aktuellen Ergebnistabelle gesucht und nicht auf % anderen Ebenen in der rekursiven Datenstruktur. Only the current result table is searched, not other levels in the recursive data structure. \InputLua[firstline=4,lastline=11]{defs/attrs/pick/different-levels.lua} \noindent % Die Suche nach Werte wird aktiviert, wenn das Attribut \lua{pick} auf % \lua{true} gesetzt wird. The search for values is activated when the attribute \lua{pick} is set to a data type. % Mit diesen Datentypen kann nach Werten gesucht werden These data types can be used to search for values: string, number, dimension, integer, boolean, any. % Verwendet den Datentyp any um jeden beliebigen Wert zu akzeptieren. Use the data type “any” to accept any value. % Wird einem Schlüssel bereits bei der Eingabe ein Wert zugewiesen, dann % wird nicht weiter nach Werten gesucht. If a value is already assigned to a key when it is entered, then no further search for values is performed. \InputLua[firstline=4,lastline=8]{defs/attrs/pick/value-set.lua} \noindent % Das Attribut \lua{pick} akzeptiert auch mehrere Datentypen, die in % einer Tabelle angegeben werden. The \lua{pick} attribute also accepts multiple data types specified in a table. \InputLua[firstline=4,lastline=10]{defs/attrs/pick/multiple-data-types.lua} %% % %% \subsubsection{Attribute “\texttt{process}”} \label{attr-process} % Das Attribut \lua{process} kann dazu verwendet werden, um eine Funktion % zu definieren, deren Rückgabewert an den Schlüssel übergeben wird. The \lua{process} attribute can be used to define a function whose return value is passed to the key. % % Beim Aufruf der Funktion werden vier Parameter übergeben: 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} \noindent % Das folgende Beispiel demonstriert den Parameter \lua{value}: The following example demonstrates the \lua{value} parameter: \InputLua[firstline=4,lastline=14]{defs/attrs/process/parameter-value.lua} \noindent % Das folgende Beispiel demonstriert den Parameter \lua{input}: The following example demonstrates the \lua{input} parameter: \InputLua[firstline=4,lastline=16]{defs/attrs/process/parameter-input.lua} \noindent % Das folgende Beispiel demonstriert den Parameter \lua{result}: The following example demonstrates the \lua{result} parameter: \InputLua[firstline=4,lastline=12]{defs/attrs/process/parameter-result.lua} \noindent % Das folgende Beispiel demonstriert den Parameter \lua{unknown}: The following example demonstrates the \lua{unknown} parameter: \InputLua[firstline=4,lastline=11]{defs/attrs/process/parameter-unknown.lua} \InputLua[firstline=15,lastline=15]{defs/attrs/process/parameter-unknown.lua} %% % %% \subsubsection{Attribute “\texttt{required}”} % Durch das Attribut \lua{required} kann erzwungen werden, dass ein % bestimmter Schlüssel angegeben werden muss. The \lua{required} attribute can be used to enforce that a specific key must be specified. % % Im untenstehenden Beispiel wird der Schlüssel \lua{important} als % zwingend notwendig definiert. In the example below, the key \lua{important} is defined as mandatory. \InputLua[firstline=4,lastline=5]{defs/attrs/required.lua} \noindent % Fehlt der Schlüssel \lua{important} in der Eingabe, so tritt eine % Fehlermeldung auf. If the key \lua{important} is missing in the input, an error message occurs. \InputLua[firstline=13,lastline=14]{defs/attrs/required.lua} \noindent A recursive example: \InputLua[firstline=18,lastline=23]{defs/attrs/required.lua} \noindent % Der Schlüssel \lua{important2} auf der Ebene 2 fehlt. The \lua{important2} key on level 2 is missing. \InputLua[firstline=29,lastline=30]{defs/attrs/required.lua} \noindent % Der Schlüssel \lua{important1} auf der untersten Schlüssel-Ebene fehlt. The \lua{important1} key at the lowest key level is missing. \InputLua[firstline=38,lastline=39]{defs/attrs/required.lua} %% % %% \subsubsection{Attribute “\texttt{sub_keys}”} % 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. \InputLua[firstline=4,lastline=16]{defs/attrs/sub-keys.lua} %----------------------------------------------------------------------- % %----------------------------------------------------------------------- \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. \InputLua[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. \InputLua[firstline=16,lastline=17]{functions/render.lua} %% % %% \subsection{Function “\texttt{debug(result): void}”} 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. \InputLua[firstline=4,lastline=5]{functions/debug.lua} \noindent The output should look like this: \begin{minted}{md} { ['level1'] = { ['level2'] = { ['key'] = 'value', }, } } \end{minted} %% % %% \subsection{Function “\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{Function “\texttt{get(identifier): result}”} The function \lua{get(identifier)} retrieves a saved result from the result store. %% % %% \subsection{Class “\texttt{DefinitionManager()}”} % Die Klasse DefinitionManager ermöglicht es Schlüssel-Wert-Definitionen % in einem Objekt abzulegen. The DefinitionManager class makes it possible to store key-value definitions in a central location. % Über die Methoden \lua{include} und \lue{exclude} können auf Basis der % gespeicherten Definitionen neue Teilmengen an Definitionen gebildet % werden. New subsets of definitions can be formed based on the saved definitions using the \lua{include} and \lua{exclude} methods. \InputLua[firstline=4]{definition-manager.lua} %% % %% \subsection{Table “\texttt{is}”} % In der Tabelle \lua{is} werden einige Funktionen zusammengefasst, die % überprüft ob eine Eingabe einem bestimmen Datentyp entspricht. In the table \lua{is} some functions are summarized, which check whether an input corresponds to a certain data type. % % Einige Funktionen akzeptieren nicht nur die entsprechenden % Lua-Datentypen, sondern auch Eingaben als Zeichenketten. Some functions accept not only the corresponding Lua data types, but also input as strings. % % Beispielsweise wird die Zeichenkette \lua{'true'} von der % \lua{is.boolean()}-Funktion als Wahrheitswert erkannt. For example, the string \lua{'true'} is recognized by the \lua{is.boolean()} function as a boolean value. \subsubsection{Function “\texttt{is.boolean(value): boolean}”} \InputLua[firstline=6,lastline=23]{functions/is/boolean.lua} \subsubsection{Function “\texttt{is.dimension(value): boolean}”} \InputLua[firstline=6,lastline=16]{functions/is/dimension.lua} \subsubsection{Function “\texttt{is.integer(value): boolean}”} \InputLua[firstline=6,lastline=11]{functions/is/integer.lua} \subsubsection{Function “\texttt{is.number(value): boolean}”} \InputLua[firstline=6,lastline=13]{functions/is/number.lua} \subsubsection{Function “\texttt{is.string(value): boolean}”} \InputLua[firstline=6,lastline=12]{functions/is/string.lua} \subsubsection{Function “\texttt{is.list(value): boolean}”} \InputLua[firstline=6,lastline=16]{functions/is/list.lua} \subsubsection{Function “\texttt{is.any(value): boolean}”} % Die Funktion \lua{is.any(value)} gibt immer wahr zurück und % akzeptiert deshalb jeden Datentyp. The function \lua{is.any(value)} always returns \lua{true} and therefore accepts any data type. %% % %% \subsection{Table “\texttt{utils}”} % In der Tabelle \lua{utils} sind einige Hilfsfunktionen gebündelt. The \lua{utils} table bundles some auxiliary functions. \InputLua[firstline=3,lastline=35]{utils/all.lua} %% % %% \subsubsection{Function “\texttt{utils.merge_tables(target, source, overwrite): table}”} % Die Funktion \lua{merge_tables} führt zwei Tabellen in die erste % angegebene Tabelle zusammen. Sie kopiert Schlüssel aus der % `source` Tabelle in die `target`-Tabelle. Sie gibt die geänderte % Zieltabelle zurück. The function \lua{merge_tables} merges two tables into the first specified table. It copies keys from the `source` table into the `target` table. It returns the target table. % Wird der Parameter \lua{overwrite} auf wahr gesetzten, so werden Werte % in der Zieltabelle überschrieben If the \lua{overwrite} parameter is set to \lua{true}, values in the target table are overwritten. \InputLua[firstline=4,lastline=8]{utils/merge-tables.lua} \noindent % Geben sie dem Parameter \lua{overwrite} den Wert \lua{false}, um Werte % in der Zieltabelle zu überschreiben. Give the parameter \lua{overwrite} the value \lua{false} to overwrite values in the target table. \InputLua[firstline=14,lastline=18]{utils/merge-tables.lua} %% % %% \subsection{Table “version”} % Das luakeys Projekt verwendet semantic versioning The luakeys project uses semantic versioning. % Die drei Versionenzahlen des Semantic Versioning Schemas werden in % einer Tabelle in der Reihenfolge MAJOR, MINOR, PATCH als Ganzzahlen % abgelegt. The three version numbers of the semantic versioning scheme are stored in a table as integers in the order MAJOR, MINOR, PATCH. % Mit Hilfe dieser Tabelle kann überprüft werden, ob die richtige % Version installiert ist. This table can be used to check whether the correct version is installed. \InputLua[firstline=4,lastline=10]{version.lua} %% % %% \subsection{Table “error_messages”} \InputLua[firstline=4,lastline=17]{error-messages.lua} \begin{description} \directlua{luakeys.print_error_messages()} \end{description} %----------------------------------------------------------------------- % %----------------------------------------------------------------------- \section{Syntax of the recognized key-value format} %% % %% \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 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\}\}}). %% % %% \subsection{An (incomplete) attempt to put the syntax into the Extended Backus-Naur Form} \begin{grammar} ::= \{ \} ::= `{' `}' ::= ( | | ) [ `,' ] ::= `=' ( | ) ::= \alt \alt \alt \alt ::= ::= ( [ ] | ) ::= `.' ::= `-' | `+' ::= \{ \} ::= `0' | `1' | `2' | `3' | `4' | `5' | `6' | `7' | `8' | `9' ::= `bp' | `BP' \alt `cc' | `CC' \alt `cm' | `CM' \alt `dd' | `DD' \alt `em' | `EM' \alt `ex' | `EX' \alt `in' | `IN' \alt `mm' | `MM' \alt `mu' | `MU' \alt `nc' | `NC' \alt `nd' | `ND' \alt `pc' | `PC' \alt `pt' | `PT' \alt `px' | `PX' \alt `sp' | `SP' ::= | ::= `true' | `TRUE' | `True' ::= `false' | `FALSE' | `False' \end{grammar} ... to be continued %% % %% \subsection{Recognized data types} \subsubsection{boolean} The strings \texttt{true}, \texttt{TRUE} and \texttt{True} are converted into Lua’s boolean type \lua{true}, the strings \texttt{false}, \texttt{FALSE} and \texttt{False} into \lua{false}. \begin{multicols}{2} \InputLatex[firstline=5,lastline=12]{luakeysdebug/boolean-latex.tex} \columnbreak \begin{minted}{lua} { ['lower case true'] = true, ['upper case true'] = true, ['title case true'] = true, ['lower case false'] = false, ['upper case false'] = false ['title case false'] = false, } \end{minted} \end{multicols} %% % %% \subsubsection{number} \begin{multicols}{2} \InputLatex[firstline=5,lastline=13]{luakeysdebug/number-latex.tex} \columnbreak \begin{minted}{lua} { ['num0'] = 42, ['num1'] = 42, ['num2'] = -42, ['num3'] = 4.2, ['num4'] = 0.42, ['num5'] = 0.42, ['num6'] = '0 . 42', -- string } \end{minted} \end{multicols} %% % %% \subsubsection{dimension} % Luakeys versucht alle Einheiten zu erkennen, die in der TeX-Welt % verwendet werden. |luakeys| tries to recognize all units used in the \TeX{} world. % % Nach dem Lua\TeX-Quellcode . According to the Lua\TeX{} source code (\href{https://github.com/TeX-Live/luatex/blob/51db1985f5500dafd2393aa2e403fefa57d3cb76/source/texk/web2c/luatexdir/lua/ltexlib.c#L434-L625} {source/texk/web2c/luatexdir/lua/ltexlib.c}) % % und nach dem Dimensionen-Modul der lulibs-Bibliothek and the dimension module of the lualibs library (\href{https://raw.githubusercontent.com/latex3/lualibs/master/lualibs-util-dim.lua} {lualibs-util-dim.lua}), % % müssten alle Einheiten erkannt werden all units should be recognized. \begin{multicols}{3} \tiny \begin{center} \begin{tabular}{rl} % \textbf{Unit name} & \textbf{Description} \\\hline bp & big point \\ cc & cicero \\ cm & centimeter \\ dd & didot \\ em & horizontal measure of \emph{M} \\ ex & vertical measure of \emph{x} \\ in & inch \\ mm & milimeter \\ mu & math unit \\ nc & new cicero \\ nd & new didot \\ pc & pica \\ pt & point \\ px & x height current font \\ sp & scaledpoint \\ \end{tabular} \end{center} \columnbreak \InputLatex[firstline=5,lastline=21]{luakeysdebug/dimension/all-latex.tex} \columnbreak \begin{minted}{lua} { ['bp'] = 65781, ['cc'] = 841489, ['cm'] = 1864679, ['dd'] = 70124, ['em'] = 655360, ['ex'] = 282460, ['in'] = 4736286, ['mm'] = 186467, ['mu'] = 65536, ['nc'] = 839105, ['nd'] = 69925, ['pc'] = 786432, ['pt'] = 65536, ['px'] = 65781, ['sp'] = 1, } \end{minted} \end{multicols} \noindent % Im nächsten Beispiel werden die unterschiedlichen Notationsformen der % Dimensionen illustriert. The next example illustrates the different notations of the dimensions. \begin{multicols}{2} \InputLatex[firstline=5,lastline=12]{luakeysdebug/dimension/notations-latex.tex} \columnbreak \begin{minted}{lua} { ['upper'] = 1864679, ['lower'] = 1864679, ['space'] = 1864679, ['plus'] = 1864679, ['minus'] = -1864679, ['nodim'] = '1 c m', -- string } \end{minted} \end{multicols} %% % %% \subsubsection{string} % 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. \InputLua[firstline=4,lastline=17]{data-types/string.lua} \subsubsection{Naked keys} % 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). \InputLatex[firstline=5,lastline=12]{luakeysdebug/naked-keys-latex.tex} \noindent % Alle erkannten Datentypen können als eigenständige Werte verwendet % werden. All recognized data types can be used as standalone values. \InputLatex[firstline=14,lastline=19]{luakeysdebug/naked-keys-latex.tex} %----------------------------------------------------------------------- % %----------------------------------------------------------------------- \clearpage \section{Examples} %% % %% \subsection{Extend and modify keys of existing macros} 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} \InputLua{extend-includegraphics/extend-keys.lua} \InputLatex{extend-includegraphics/extend-keys-latex.tex} %% % %% \subsection{Process document class options} % Auf die Optionen einer \LaTeX{} Dokumentenklasse kann über das Macro % \latex{\LuakeysGetClassOptions} zu gegriffen werden. The options of a \LaTeX{} document class can be accessed via the \latex{\LuakeysGetClassOptions} macro. % % \latex{\LuakeysGetClassOptions} ist ein anderer Name für \latex{\LuakeysGetClassOptions} is an alias for \begin{center} \latex{\luaescapestring{\@raw@classoptionslist}}. \end{center} \InputLatex{class-options/test-class.cls} \InputLatex{class-options/use-test-class-latex.tex} %% % %% \subsection{Process package options} \noindent % Auf die Optionen eines \LaTeX{}-Pakets kann über das Macro % \latex{\LuakeysGetPackageOptions} zu gegriffen werden. The options of a \LaTeX{} package can be accessed via the \latex{\LuakeysGetPackageOptions} macro. % \latex{\LuakeysGetPackageOptions} ist ein anderer Name für \latex{\LuakeysGetPackageOptions} is an alias for \begin{center} \latex{\luaescapestring{\@ptionlist{\@currname.\@currext}}}. \end{center} \InputLatex{package-options/test-package.sty} \InputLatex{package-options/use-test-package-latex.tex} %----------------------------------------------------------------------- % %----------------------------------------------------------------------- \clearpage \section{Debug packages} Two small debug packages are included in |luakeys|. One debug package can be used in \LaTeX{} (luakeys-debug.sty) and one can be used in plain \TeX{} (luakeys-debug.tex). Both packages provide only one command: |\luakeysdebug{kv-string}| \begin{minted}{latex} \luakeysdebug{one,two,three} \end{minted} \noindent Then the following output should appear in the document: \bigskip \luakeysdebug{one,two,three} %% % %% \subsection{For plain \TeX: luakeys-debug.tex} An example of how to use the command in plain \TeX: \begin{minted}{latex} \input luakeys-debug.tex \luakeysdebug{one,two,three} \bye \end{minted} %% % %% \subsection{For \LaTeX: luakeys-debug.sty} An example of how to use the command in \LaTeX: \begin{minted}{latex} \documentclass{article} \usepackage{luakeys-debug} \begin{document} \luakeysdebug[ unpack=false, convert dimensions=false ]{one,two,three} \end{document} \end{minted} \section{Activity diagramm of the parsing process} \begin{center} \includegraphics[width=0.8\linewidth]{Activity-Diagramm.eps} \end{center} %----------------------------------------------------------------------- % %----------------------------------------------------------------------- \clearpage \section{Implementation} %% % %% \subsection{luakeys.lua} \inputminted[linenos=true]{lua}{luakeys.lua} %% % %% \clearpage \subsection{luakeys.tex} \inputminted[linenos=true]{latex}{luakeys.tex} %% % %% \clearpage \subsection{luakeys.sty} \inputminted[linenos=true]{latex}{luakeys.sty} %% % %% \clearpage \subsection{luakeys-debug.tex} \inputminted[linenos=true]{latex}{luakeys-debug.tex} %% % %% \clearpage \subsection{luakeys-debug.sty} \inputminted[linenos=true]{latex}{luakeys-debug.sty} \pagebreak \PrintIndex \end{document}