From c2d6f5036f52ba820291bce134396a26215d95dc Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Tue, 8 Aug 2017 20:40:20 +0000 Subject: simplekv (8aug17) git-svn-id: svn://tug.org/texlive/trunk@44986 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/generic/simplekv/README | 21 ++ .../doc/generic/simplekv/simplekv-fr.pdf | Bin 0 -> 329306 bytes .../doc/generic/simplekv/simplekv-fr.tex | 271 +++++++++++++++++ .../texmf-dist/doc/generic/simplekv/simplekv.tex | 329 +++++++++++++++++++++ 4 files changed, 621 insertions(+) create mode 100644 Master/texmf-dist/doc/generic/simplekv/README create mode 100644 Master/texmf-dist/doc/generic/simplekv/simplekv-fr.pdf create mode 100644 Master/texmf-dist/doc/generic/simplekv/simplekv-fr.tex create mode 100644 Master/texmf-dist/doc/generic/simplekv/simplekv.tex (limited to 'Master/texmf-dist/doc/generic') diff --git a/Master/texmf-dist/doc/generic/simplekv/README b/Master/texmf-dist/doc/generic/simplekv/README new file mode 100644 index 00000000000..d612d38b6b7 --- /dev/null +++ b/Master/texmf-dist/doc/generic/simplekv/README @@ -0,0 +1,21 @@ +___________________________________ + + L'extension + simplekv + + v0.1 + + 8 aout 2017 +___________________________________ + +Authors : Christian Tellechea +Maintainer: Christian Tellechea +E-mail : unbonpetit@netc.fr (CT) + Commentaires, signalements de bugs et + suggestions bienvenus +Licence : Released under the LaTeX Project Public License v1.3c or + later, see http://www.latex-project.org/lppl.txt + +---------------------------------------------------------------------- + +A simple key/value system for TeX. diff --git a/Master/texmf-dist/doc/generic/simplekv/simplekv-fr.pdf b/Master/texmf-dist/doc/generic/simplekv/simplekv-fr.pdf new file mode 100644 index 00000000000..797171dd55e Binary files /dev/null and b/Master/texmf-dist/doc/generic/simplekv/simplekv-fr.pdf differ diff --git a/Master/texmf-dist/doc/generic/simplekv/simplekv-fr.tex b/Master/texmf-dist/doc/generic/simplekv/simplekv-fr.tex new file mode 100644 index 00000000000..c899feeb738 --- /dev/null +++ b/Master/texmf-dist/doc/generic/simplekv/simplekv-fr.tex @@ -0,0 +1,271 @@ +% !TeX encoding = ISO-8859-1 +% Ceci est la documentation du package "hlist" +% +% Fichier compilé avec pdflatex +\documentclass[french,a4paper,10pt]{article} +\usepackage[latin1]{inputenc} +\usepackage[T1]{fontenc} +\usepackage[margin=2cm]{geometry} +\usepackage[bottom]{footmisc} +\usepackage{libertine,boites,tikz,enumitem,MnSymbol,babel,xspace,listings,simplekv} +\usepackage[scaled=0.8]{luximono} +\frenchbsetup{og=«,fg=»} +\def\eTeX{\hbox{$\varepsilon$-\TeX}} +\def\SKV{\texttt{\skvname}\xspace} +\makeatletter +\def\code{\expandafter\code@i\string} +\def\code@i#1{% + \begingroup + \par\nobreak\medskip\parindent0pt + \leftskip.1\linewidth + \make@car@active\^^I{\leavevmode\space\space\space\space}% + \let\do\@makeother \dospecials + \ttfamily\small\@noligs + \make@car@active\<{\begingroup$\langle$\itshape}% + \make@car@active\>{$\rangle$\endgroup}% + \obeylines\obeyspaces + \def\code@ii##1#1{##1\par\medbreak\endgroup}% + \code@ii +} +\long\def\grab@toks#1\relax{\gdef\right@content{#1}} + +\newcommand\disable@lig[1]{% + \catcode`#1\active + \begingroup + \lccode`\~`#1\relax + \lowercase{\endgroup\def~{\leavevmode\kern\z@\string#1}}% +} + +\newcommand\make@car@active[1]{% + \catcode`#1\active + \begingroup + \lccode`\~`#1\relax + \lowercase{\endgroup\def~}% +} + +\newcommand\exemple{% + \begingroup + \parskip\z@ + \exemple@} + +\newcommand\exemple@{% + \medbreak\noindent + \begingroup + \let\do\@makeother\dospecials + \make@car@active\ { {}}% + \make@car@active\^^M{\par\leavevmode}% + \make@car@active\^^I{\space\space}% + \make@car@active\,{\leavevmode\kern\z@\string,}% + \make@car@active\-{\leavevmode\kern\z@\string-}% + \make@car@active\>{\leavevmode\kern\z@\string>}% + \make@car@active\<{\leavevmode\kern\z@\string<}% + \@makeother\;\@makeother\!\@makeother\?\@makeother\:% neutralise frenchb + \exemple@@ +} + +\newcommand\exemple@@[1]{% + \def\@tempa##1#1{\exemple@@@{##1}}% + \@tempa +} + +\newcommand\exemple@@@[1]{% + \xdef\the@code{#1}% + \endgroup + \begingroup + \fboxrule0.4pt \fboxsep=5pt + \let\breakboxparindent\z@ + \def\bkvz@top{\hrule\@height\fboxrule}% + \def\bkvz@bottom{\hrule\@height\fboxrule}% + \let\bkvz@before@breakbox\relax + \def\bkvz@set@linewidth{\advance\linewidth\dimexpr-2\fboxrule-2\fboxsep\relax}% + \def\bkvz@left{\vrule\@width\fboxrule\kern\fboxsep}% + \def\bkvz@right{\kern\fboxsep\vrule\@width\fboxrule}% + \breakbox + \kern.5ex\relax + \begingroup + \ttfamily\small\the@code\par + \endgroup + \kern3pt + \hrule height0.1pt width\linewidth depth0.1pt + \vskip5pt + \newlinechar`\^^M\everyeof{\noexpand}\scantokens{#1}\par + \endbreakbox + \endgroup + \medbreak + \endgroup +} +\begingroup + \catcode`\<13 \catcode`\>13 + \gdef\verb{\relax\ifmmode\hbox\else\leavevmode\null\fi + \bgroup + \verb@eol@error \let\do\@makeother \dospecials + \verbatim@font\@noligs + \catcode`\<13 \catcode`\>13 \def<{\begingroup$\langle$\itshape}\def>{\/$\rangle$\endgroup}% + \@ifstar\@sverb\@verb} +\endgroup +\def\longfrhlstdate@i#1/#2/#3\@nil{\number#3\relax\space \ifcase#2 \or janvier\or février\or mars\or avril\or mai\or juin\or juillet\or aout\or septembre\or octobre\or novembre\or décembre\fi\space#1} +\edef\longfrhlstdate{\expandafter\longfrhlstdate@i\skvdate\@nil} +\def\<#1>{$\langle$\textit{#1}$\rangle$} +\makeatother + +\begin{document} +\parindent=0pt +\thispagestyle{empty} +\begin{titlepage} + \begingroup + \centering + \null\vskip.25\vsize + {\large\bfseries L'extension pour \TeX/\LaTeX\par \Huge \skvname\par} + \bigbreak + v \skvver + \smallbreak + \longfrhlstdate + \vskip1.5cm + Christian \bsc{Tellechea}\par + \texttt{unbonpetit@netc.fr}\par + \endgroup + \vskip2cm + \leftskip=.2\linewidth \rightskip=.2\linewidth \small + Cette petite extension est une implémentation d'un système dit à «clé/valeurs» pour \TeX{} ou \LaTeX. Aucune fioriture inutile n'a été codée, elle comporte juste l'essentiel. +\end{titlepage} + +\section{Clés, valeurs} +Lorsqu'une macro doit recevoir des paramètres dont le nombre n'est pas fixe ou connu, il est commode de procéder par \ et \. Beaucoup d'extensions allant en ce sens existent déjà. + +Le but de celle-ci n'est pas de grossir le nombre déjà trop grand de ces extensions, c'est simplement un morceau de l'extension \texttt{hlist} qui a été converti en extension car ce système \/\ est également utilisé par l'extension \texttt{scratch}.\medskip + +Voici brièvement les définitions et les limitations des structures mises à disposition : + +\begin{itemize} + \item une \ est un mot désignant un paramètre; il est formé de préférence avec des caractères de code de catégorie 11 (lettres), 12 (autres caractères sauf la virgule) et 10 (l'espace). On peut cependant y mettre des caractères ayant d'autres codes de catégorie, dans la limitation de ce qui est admis dans la primitive \verb|\detokenize|; + \item la syntaxe pour assigner une \ à une \ est : \hbox{\=\}; + \item les espaces qui précèdent et qui suivent la \ et la \ sont ignorés, mais \emph{pas ceux} qui se trouvent à l'intérieur de la \ ou de la \; + \item une \ est un \ arbitraire; + \item si une \ est entourée d'accolades, ces dernières seront retirées : \verb|=| est donc équivalent à \verb|={}|; + \item lorsque plusieurs couples de \/\ doivent être spécifiés, ils sont séparés les uns des autres par des virgules; + \item une virgule ne peut figurer dans une \ que si la virgule est dans un niveau d'accolades; par exemple, \verb|foo=1,5| n'est pas valide car la \ s'étend jusqu'au 1. Il faudrait écrire \verb|foo={1,5}| pour spécifier une valeur de \verb|1,5|; + \item lorsqu'une valeur est entourée de \emph{plusieurs} d'accolades, seul le niveau externe est retiré; + \item les \ sont stockées \emph{telles qu'elles sont lues} ; en particulier, aucun développement n'est effectué; + \item les définitions sont \emph{locales} : par conséquent, toute \ définie ou modifiée dans un groupe est restaurée à son état antérieur à la sortie du groupe; + \item des \/\ destinées à une même macro ou à un même usage doivent être regroupées dans un ensemble dont on choisit le nom. Un tel ensemble est appelé \. +\end{itemize} + +\section{Commandes mises à disposition} + +\paragraph{La macro \texttt{\char`\\setKVdefault}} +Cette commande est un préalable à toute utilisation de \ puisqu'elle définit un \ contenant des \ et leurs \ par défaut. + +On écrit +\begin{center} \verb|\setKVdefault[]{=,=,...,=}| +\end{center} + +Il faut noter que +\begin{itemize} + \item l'argument entre accolades contenant les \ et les \ ne peut pas être vide; + \item le nom du \, bien qu'entre crochet, est \emph{obligatoire}, mais il peut être vide bien que cela ne soit pas conseillé; + \item si plusieurs \ sont identiques, seule la dernière \ sera prise en compte; + \item les \ peuvent être booléennes, auquel cas, elles \emph{doivent} être «\texttt{true}» ou «\texttt{false}» en caractères de catcode 11; + \item si une \ est omise, elle est comprise comme étant «\texttt{true}». Ainsi, écrire + \code|\setKVdefault[foo]{mon bool}| + est équivalent à + \code|\setKVdefault[foo]{mon bool = true}| + \item il est \emph{déconseillé} d'exécuter plusieurs fois \verb|\setKVdefault| pour le même \. Si cela est indispensable, il convient de redéfinir \emph{toutes} les \ qui figuraient dans les précédents appels de \verb|\setKVdefault|. +\end{itemize} + +\paragraph{La macro \texttt{\char`\\setKV}} +Cette macro fonctionne selon les mêmes principes et limitations que \verb|\setKVdefault|, sauf qu'elle redéfinit une ou plusieurs \ dont les \ ont précédemment été définies par \verb|\setKVdefault|. + +Si une \ n'a pas été prédéfinie par \verb|\setKVdefault|, une erreur sera émise. + +\paragraph{La macro \texttt{\char`\\useKV}} +Cette macro purement développable renvoie la \ préalablement associée à une \ dans un \: +\code|\useKV[]{}| + +Il faut noter que +\begin{itemize} + \item si la \ n'a pas été prédéfinie par \verb|\setKVdefault|, une erreur sera émise; + \item si la \ est booléenne, le texte «\texttt{true}» ou «\texttt{false}» sera renvoyé; + \item il faut 2 développements à \verb|\useKV[]{}| pour donner la \ associée à la \. +\end{itemize} + +\exemple|\setKVdefault[foo]{nombre = 5 , lettres= AB \textit{CD} , mon bool} +a) \useKV[foo]{nombre}.\qquad b) \useKV[foo]{lettres}.\qquad c) \useKV[foo]{mon bool}.\par +\setKV[foo]{lettres = X Y Z \textbf{123} } +a) \useKV[foo]{nombre}.\qquad b) \useKV[foo]{lettres}.\qquad c) \useKV[foo]{mon bool}.| + +\paragraph{La macro \texttt{\char`\\useKVdefault}} +L'exécution de cette macro par \verb|\useKVdefault[]| réinitialise toutes les \ du \ aux \ qui ont été définies lors de l'exécution \verb|\setKVdefault|. + +\paragraph{La macro \texttt{\char`\\ifboolKV}} +Cette macro permet, selon la valeur d'une \, d'exécuter un des deux \ donnés. La syntaxe est +\code|\ifboolKV[]{}{}{}| + +La macro est purement développable, elle nécessite 2 développements pour donner l'un des deux codes, et exige que la \ soit booléenne sans quoi un message d'erreur est émis. + +\paragraph{La macro \texttt{\char`\\showKV}} +Cette commande écrit dans le fichier \texttt{log} la \ assignée à une \ d'un \: +\code|\showKV[]{}| + +Si la \ n'est pas définie, «\texttt{not defined}» est affiché dans le fichier log. + +\section{Un exemple d'utilisation} +Voici comment on pourrait programmer une macro qui affiche un cadre sur une ligne. Pour cela les \ suivantes seront utilisées: +\begin{itemize} + \item le booléen \texttt{inline} qui affichera le cadre dans le texte s'il est vrai et sur une ligne dédié s'il est faux; + \item \texttt{left code} et \texttt{right code} qui sont deux codes exécutés avant et après le cadre si le booléen est faux (par défaut : \verb|\hfill| et \verb|\hfill| pour un centrage sur la ligne); + \item \texttt{sep} qui est une dimension mesurant la distance entre le texte et le cadre (par défaut \texttt{3pt}); + \item \texttt{width} qui est la largeur des traits du cadre (par défaut \texttt{0.5pt}). +\end{itemize} + +\exemple|\setKVdefault[frame]{inline , left code = \hfill, right code = \hfill, sep = 3pt, width=0.5pt } +\newcommand\frametxt[2][]{% + \setKV[frame]{#1}% lit les arguments optionnels + \ifboolKV[frame]{inline}{}{\par\noindent\useKV[frame]{left code}}% + \fboxsep=\useKV[frame]{sep}\relax + \fboxrule=\useKV[frame]{width}\relax + \fbox{#2}% + \ifboolKV[frame]{inline}{}{\useKV[frame]{right code}\null\par}% +} +Un essai en ligne par défaut \frametxt{essai} puis un autre \frametxt[sep=5pt,width=2pt]{essai} +et un dernier \frametxt[sep=0.5pt]{essai}. + +\useKVdefault[frame]% revenir au valeurs par défaut +Un essai centré \frametxt[inline = false]{essai centré} +un autre fer à gauche \frametxt[left code={}]{essai à gauche} +un dernier indenté \frametxt[left code=\hskip 5em, right code={}, sep=1pt, width=2pt]{essai indenté}| + + +\section{Le code} +Le code ci-dessous est l'exact verbatim du fichier \verb|simplekv.tex| : + +\lstinputlisting[ + language=TeX, + moretexcs={unless,ifcsname,ifdefined,detokenize,numexpr,dimexpr,glueexpr,unexpanded}, + basicstyle=\small\ttfamily\color{black!25}, + identifierstyle=\bfseries\color{white},% + backgroundcolor=\color{black!85}, + keywordstyle=\bfseries\color{orange}, + commentstyle=\color{cyan!66}, + columns=fixed, + alsoletter={\_}, + tabsize=2, + extendedchars=true, + showspaces=false, + showstringspaces=false, + numbers=left, + numberstyle=\tiny\ttfamily\color{black}, + breaklines=true, + prebreak={\hbox{$\rhookswarrow$}}, + breakindent=3em, + breakautoindent=true, + xleftmargin=1em, + xrightmargin=0pt, + lineskip=0pt, + numbersep=1em, + classoffset=1, + alsoletter={\_}, + morekeywords={setKVdefault,setKV,useKVdefault,useKV,ifboolKV,}, + keywordstyle=\bfseries\color{red!85!black}, + classoffset=0, + ]{simplekv.tex} +\end{document} \ No newline at end of file diff --git a/Master/texmf-dist/doc/generic/simplekv/simplekv.tex b/Master/texmf-dist/doc/generic/simplekv/simplekv.tex new file mode 100644 index 00000000000..d4ca63d9ebd --- /dev/null +++ b/Master/texmf-dist/doc/generic/simplekv/simplekv.tex @@ -0,0 +1,329 @@ +% !TeX encoding = ISO-8859-1 +% Ce fichier contient le code commenté de l'extension "simplekv" +% +% IMPORTANT : pour que les commentaires s'affichent correctement, +% ouvrir ce fichier avec l'encodage ISO-8859-1 +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +\def\skvname {simplekv} % +\def\skvver {0.1} % +% % +\def\skvdate {2017/08/08} % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% -------------------------------------------------------------------- +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% +% % http://www.latex-project.org/lppl.txt +% +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% -------------------------------------------------------------------- +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Christian Tellechea +% Copyright : Christian Tellechea 2017 +% email: unbonpetit@netc.fr +% Commentaires, suggestions et signalement de bugs bienvenus ! +% Comments, bug reports and suggestions are welcome. +% Copyright: Christian Tellechea 2017 +% -------------------------------------------------------------------- +% L'extension simplekv est composée des 5 fichiers suivants : +% - code : simplekv (.tex et .sty) +% - manuel en français : simplekv-fr (.tex et .pdf) +% - fichier lisezmoi : README +% -------------------------------------------------------------------- + +\expandafter\edef\csname skv_restorecatcode\endcsname{\catcode`\noexpand\_=\the\catcode`\_\relax} +\catcode`\_11 + +%################################################ +%################################################ +% Cette macro est équivalente à 0 et sert notamment à stopper le développement +% de \romannumeral +\chardef\skv_stop 0 + +% Définition du quark, notamment inséré à la fin d'une liste pour en reconnaitre +% la fin et stopper la récursivité +\def\skv_quark{\skv_quark} + +% Voici les macros habituelles de sélection d'arguments +\long\def\skv_first#1#2{#1} +\long\def\skv_second#1#2{#2} + +% Voici la macro pour 1-développer ou 2-développer le 2e argument (le 1er étant +% dépouillé des accolades) +% \skv_exparg{}{} devient {} +% \skv_eearg{}{} devient {**} +\long\def\skv_exparg#1#2{\expandafter\skv_exparg_i\expandafter{#2}{#1}}% +\long\def\skv_eearg#1#2{\expandafter\expandafter\expandafter\skv_exparg_i\expandafter\expandafter\expandafter{#2}{#1}}% +\long\def\skv_exparg_i#1#2{#2{#1}} + +% Et la macro pour 1-développer le 2e argument (le 1er et le 2e argument sont +% dépouillés des accolades)% +% \skv_expafter{}{} devient <*b> +\long\def\skv_expafter#1#2{\expandafter\skv_expafter_i\expandafter{#2}{#1}} +\long\def\skv_expafter_i#1#2{#2#1} + +% Enfin, la macro pour former le nom du 2e argument (le 1er est dépouillé des +% accolades) +% \skv_argcsname{}{} devient \ +\def\skv_argcsname#1#{\skv_argcsname_i{#1}} +\def\skv_argcsname_i#1#2{\skv_expafter{#1}{\csname#2\endcsname}} + +\def\skv_eaddtomacro#1#2{\skv_exparg{\skv_exparg{\def#1}}{\expandafter#1#2}} + +%################################################ +%################ macros de test ################ +%################################################ +% Voici quelques macros à sélection d'arguments pour les tests +\def\skv_ifcsname#1{\ifcsname#1\endcsname\expandafter\skv_first\else\expandafter\skv_second\fi} +\long\def\skv_ifx#1{\ifx#1\expandafter\skv_first\else\expandafter\skv_second\fi} +\long\def\skv_ifempty#1{\skv_exparg\skv_ifx{\expandafter\relax\detokenize{#1}\relax}} + +% Ces macros sont utiles pour \skv_removeextremespaces, qui retire les +% espaces extrêmes de son argument +% Voir codes 320-324 (http://progtex.fr/wp-content/uploads/2014/09/code.txt) +% et pages 339-343 de "Apprendre à programmer en TeX" +\long\def\skv_ifspacefirst#1{\expandafter\skv_ifspacefirst_i\detokenize{#10} \_nil} +\long\def\skv_ifspacefirst_i#1 #2\_nil{\skv_ifempty{#1}} +\expandafter\def\expandafter\skv_gobspace\space{} +\def\skv_removefirstspaces{\romannumeral\skv_removefirstspaces_i} +\long\def\skv_removefirstspaces_i#1{\skv_ifspacefirst{#1}{\expandafter\skv_removefirstspaces_i\expandafter{\skv_gobspace#1}}{\skv_stop#1}} +\begingroup + \catcode0 12 + \long\gdef\skv_removelastspaces#1{\romannumeral\skv_removelastspaces_i#1^^00 ^^00\_nil} + \long\gdef\skv_removelastspaces_i#1 ^^00{\skv_removelastspaces_ii#1^^00} + \long\gdef\skv_removelastspaces_ii#1^^00#2\_nil{\skv_ifspacefirst{#2}{\skv_removelastspaces_i#1^^00 ^^00\_nil}{\skv_stop#1}} +\endgroup +\long\def\skv_removeextremespaces#1{% + \romannumeral\expandafter\expandafter\expandafter\skv_removelastspaces\expandafter\expandafter\expandafter + {\expandafter\expandafter\expandafter\skv_stop\skv_removefirstspaces{#1}}% +} + +%################################################ +%############## système clé/valeur ############## +%################################################ +% Ceci est le booléen indiquant si la lecture de = définit les +% _par défaut_ ou qu'il s'agit d'une _redéfinition_ des déjà +% existantes +\newif\ifskv_default + +% macros chapeau appelant la même macro avec le booléen préalablement défini +\def\setKVdefault{\skv_defaulttrue\skv_readKV} +\def\setKV{\skv_defaultfalse\skv_readKV} + +% L'argument obligatoire #1 est le nom du et #2 est l'ensemble +% des = +\def\skv_readKV[#1]#2{% + \skv_ifempty{#2} +% Si aucune = alors qu'on définit les par défaut, +% message d'erreur et on s'arrête là + {\ifskv_default\errmessage{No key/val found, no default key/val defined}\fi} +% Sinon, initialiser à la macro \skv_[] uniquement si on +% créé les par défaut + {\ifskv_default\skv_argcsname\let{skv_[#1]}\empty\fi +% Puis on passe aux choses sérieuses, on va lire un par un tous les éléments +% = (contenus dans #2) en mettant le quark comme dernier couple +% pour montrer la fin de la liste + \skv_readKV_i[#1]#2,\skv_quark,% + }% +} + +\def\skv_readKV_i[#1]#2,{% +% #2 est le premier couple "=" de la liste qui reste à traiter : +% tout d'abord, on se débarrasse des espaces extrêmes + \skv_eearg{\def\__temp}{\skv_removeextremespaces{#2}}% +% Si ce qui en résulte est égal au , + \skv_ifx{\__temp\skv_quark} +% alors, on a fini et on ne fait rien (fin du processus) + {} +% Sinon, si ce qui en résulte est vide (le couple "=" était donc +% vide ou composé d'un espace) + {\skv_ifx{\__temp\empty} +% On a fini et on ne fait rien (fin du processus) + {} +% dans le cas contraire, on va isoler la et la du couple lu en +% prenant soin de mettre à la fin "=" pour se prémunir du cas où +% "=" ne contient que la "" et pas de signe "=", ce qui +% ferait planter la macro à arguments délimités + {\expandafter\skv_find_kv\__temp=\skv_quark\_nil[#1]% + }% +% Lorsque la et la est trouvée et stockée, recommencer et aller +% lire le prochain couple "=" + \skv_readKV_i[#1]% + }% +} + +% Voici la macro à arguments délimités à qui on a transmis +% == (si = est l'élément lu) +% ou +% = (si est seule) +% et qui va isoler la de la . +\def\skv_find_kv#1=#2\_nil[#3]{% +% #1 est ce qui se trouve avant le _premier_ signe "=" et +% #2 est ce qui se trouve entre le premier signe "=" et le \_nil +% Pour la , pas de problème, c'est _obligatoirement_ ce qui est avant le +% signe "=", que ce signe soit présent dans le couple lu ou pas puisqu'on y a +% rajouté "=". +% On élimine les espaces extrêmes pour obtenir la définitive stockée dans +% \__key (il faut 2-développer \skv_removeextremespaces pour qu'elle donne son +% argument sans espace extrême) + \edef\__key{\detokenize\expandafter\expandafter\expandafter{\skv_removeextremespaces{#1}}}% +% Pour la , on lui ôte d'abord les espaces extrêmes + \skv_eearg{\def\__val}{\skv_removeextremespaces{#2}}% + \skv_ifx{\__val\skv_quark} +% Si elle est égale au , alors la vaut "true" + {\def\__val{true}}% +% Sinon, ôter "=" de la fin de l'argument #2, éliminer les espaces +% extrêmes de ce qui en résulte et stocker le tout dans \__val (tout ceci est +% effectué par la macro \skv_find_val =) + {\skv_find_val#2}% +% Si on lit les = par défaut, + \ifskv_default +% assigner à la macro "\skv_[]_" la trouvée + \skv_argcsname\let{skv_[#3]_\detokenize\expandafter{\__key}}\__val +% Puis ajouter à la macro "\skv_[]", qui a été préalablement +% initialisée à : +% \def\skv_[]_{} + \skv_argcsname\skv_eaddtomacro{skv_[#3]}% + {\expandafter\def\csname skv_[#3]_\detokenize\expandafter{\__key}\expandafter\endcsname\expandafter{\__val}}% +% C'est selon ce hashage que sont enregistrés les couples / : les +% sont contenues dans les noms des macros tandis que les sont +% les textes de remplacement de ces macros. +% C'est rapide et simple : +% a) pour trouver une d'après sa , il suffit de développer la +% macro \skv_[]_ +% b) pour redéfinir une , il suffit de redéfinir cette macro avec la +% nouvelle +% c) il est facile de vérifier qu'une existe en vérifiant que la macro +% associée est définie, la primitive \ifcsname le fait très bien +% d) en revanche, on ne peut pas faire de recherche _inverse_ de façon +% pratique : il est en effet plus difficile de trouver la (ou les) +% contenant une donnée, mais cette limitation n'a pas grande +% importance ici (je ne sais pas si les autres systèmes de / +% sont programmés de telle sorte que cela soit simple...) +% Bref, la macro "\skv_[]" contient donc _toutes_ les définitions +% des macros définissant les / _par défaut_ et exécuter +% "\skv_[]" remet donc toutes les à leur par défaut. + \else +% Dans le cas où on _lit_ des nouvelles pour des + \skv_ifcsname{skv_[#3]_\__key} +% Si la existe (ssi la macro "\skv_[]_" est définie), +% alors assigner la à cette macro + {\skv_argcsname\let{skv_[#3]_\__key}\__val}% +% Sinon, émettre un message d'erreur et ne rien faire de plus + {\errmessage{Key "\__key" is not defined: nothing is modified}}% + \fi +} + +% Cette macro à qui on a transmis "=" ne garde que , en +% ôte les espaces extrêmes et stocke le résultat dans \__val +\def\skv_find_val#1=\skv_quark{\skv_eearg{\def\__val}{\skv_removeextremespaces{#1}}} + +% Cette macro remet toutes les à leur par défaut en exécutant +% la macro "\skv_[]" +\def\useKVdefault[#1]{% + \skv_ifcsname{skv_[#1]} + {\csname skv_[#1]\endcsname} +% Si la macro "\skv_[]" n'existe pas, message d'erreur + {\errmessage{Undefined set of keys "#1"}}% +} + +% Cette macro donne la correspondant à la contenue dans #2 +\def\useKV[#1]#2{% +% Avec \romannumeral, la sera obtenue après _2_ développements de +% \useKV[]{} + \romannumeral\skv_ifempty{#2} +% Si la est vide, message d'erreur (il ne peut y avoir de +% associée à une vide) + {\skv_stop\errmessage{Key name missing}} + {\skv_ifcsname{skv_[#1]_\skv_removeextremespaces{#2}} +% Si la macro "\skv_[]_" existe, 2-développer le \csname pour +% avoir la + {\expandafter\expandafter\expandafter\skv_stop\csname skv_[#1]_\skv_removeextremespaces{#2}\endcsname} +% Sinon, message d'erreur + {\skv_stop\errmessage{Key "\skv_removeextremespaces{#2}" not defined}}% + }% +} + +% Voici une macro purement développable qui teste si #2 (la du +% #1) est égale à "true" ou à "false" et selon l'issue, exécute le 1er ou 2e +% argument qui suit (arguments appelés et ) +\def\ifboolKV[#1]#2{% +% Cette macro donnera un des 2 arguments ou en _2_ développements +% grâce au \romannumeral + \romannumeral\skv_ifempty{#2} +% Si la est vide, message d'erreur + {\skv_stop\errmessage{Key name missing}\skv_second} + {\skv_ifcsname{skv_[#1]_\skv_removeextremespaces{#2}} +% Si la débarrassée de ses espaces extrêmes existe, tester son contenu + {\skv_eearg\ifboolKV_i{\csname skv_[#1]_\skv_removeextremespaces{#2}\endcsname}} +% Sinon, message d'erreur + {\skv_stop\errmessage{Key "\skv_removeextremespaces{#2}" not defined}\skv_second}% + }% +} + +% Cette macro teste si #1, qui est une , vaut "true" ou "false" +\def\ifboolKV_i#1{% +% Tester d'abord si elle vaut "true" + \skv_ifargtrue{#1} + {\expandafter\skv_stop\skv_first} + {\skv_ifargfalse{#1} +% Puis si elle vaut "false" + {\expandafter\skv_stop\skv_second} +% Si ni l'un ni l'autre, la n'est pas un booléen acceptable + {\skv_stop\errmessage{Value "#1" is not a valid boolean}\skv_second}% + }% +} + +% La macro \skv_ifargtrue{} teste de façon purement développable si +% vaut "true" ou "false". +% Pour cela, on transmet à \skv_ifargtrue_i l'argument "true" qui est +% délimité par \_nil +\def\skv_ifargtrue#1{\skv_ifargtrue_i#1true\_nil} +% Dans la macro \skv_ifargtrue_i, l'argument #1 est ce qui se trouve avant +% "true" dans "true" : +% - s'il n'est pas vide, sélectionner l'argument +% - s'il est vide, cela signifie que commence par "true" ; il est +% donc de la forme "true" +% L'argument #2 est ce qui se trouve après "true" dans "truetrue", +% c'est donc "true". +% Pour être sûr que est , on transmet "true" à +% \skv_ifargtrue_ii qui teste si la réunion de ce qui est avant le +% premier "true" et ce qui est après est +\def\skv_ifargtrue_i#1true#2\_nil{\skv_ifempty{#1}{\skv_ifargtrue_ii#2\_nil}\skv_second} +\def\skv_ifargtrue_ii#1true#2\_nil{\skv_ifempty{#1#2}} + +% On procède de même pour tester "false" +\def\skv_ifargfalse#1{\skv_ifargfalse_i#1false\_nil} +\def\skv_ifargfalse_i#1false#2\_nil{\skv_ifempty{#1}{\skv_ifargfalse_ii#2\_nil}\skv_second} +\def\skv_ifargfalse_ii#1false#2\_nil{\skv_ifempty{#1#2}} + +\def\showKV[#1]#2{% +% Ecrire dans le fichier log "Key []=" + \immediate\write-1 {Key [#1]\skv_removeextremespaces{#2}=% + \skv_ifcsname{skv_[#1]_\skv_removeextremespaces{#2}} +% si la est définie, prendre le \meaning de la macro correspondante + {\expandafter\expandafter\expandafter\skv_show\expandafter + \meaning\csname skv_[#1]_\skv_removeextremespaces{#2}\endcsname} +% Sinon, afficher + {not defined}% + }% +} +% Mange ce qui se trouve jusqu'à "->" dans le développement de \meaning +\def\skv_show#1->{} +\skv_restorecatcode +\endinput + +Versions : + _____________________________________________________________________________ +| Version | Date | Changements | +|-----------------------------------------------------------------------------| +| 0.1 | 08/08/2017 | Première version | +|-----------------------------------------------------------------------------| -- cgit v1.2.3