From fb4909f4112d8b778570cf1c2e25ca18c63bc1ca Mon Sep 17 00:00:00 2001 From: Norbert Preining 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 \alt + ::= + + ::= ( [ ] | ) + + ::= `.' + ::= `-' | `+' - ::= `0' | `1' | `2' | `3' | `4' | `5' | `6' | `7' | `8' | `9' + ::= \{ \} + + ::= `0' | `1' | `2' | `3' | `4' | `5' | `6' | `7' | `8' | `9' ::= `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