% !TeX TS-program = lualatex % !TeX encoding = UTF-8 % Ceci est la documentation du package "simplekv" \documentclass[french,a4paper,10pt]{article} \usepackage[utf8]{inputenc} \usepackage[margin=2cm]{geometry} \usepackage[bottom]{footmisc} \usepackage{libertine,boites,tikz,enumitem,babel,xspace,listings,simplekv,hyperref} \usepackage[scaled=0.8]{GoMono} \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 à «\/\» pour \TeX{} ou \LaTeX. Elle comporte juste l'essentiel, aucune fioriture inutile n'a été codée et aucune extension tierce n'est nécessaire à son fonctionnement. \end{titlepage} Cette petite extension se veut minimaliste. Trop sans doute puisqu'on ne la juge pas au niveau d'autres, jugées plus « \href{https://tex.stackexchange.com/questions/560014/}{sérieuses}.» Quoiqu'il en soit, simplekv a le mérite d'exister et se place à l'opposé des usines à gaz que l'on peut trouver dans cet exercice de style. Elle est écrite en \TeX{}, fonctionne donc sous tous les moteurs et ne requiert aucun package. \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 \. \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 le signe \verb|=|) 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|; une \, même si cela revêt peu de signification, peut être vide; \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 lorsqu'une valeur est entourée de \emph{plusieurs} imbrications d'accolades, seul le niveau externe est retiré et donc \verb|={{}}| est compris comme \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 entre 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 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{Les macros \texttt{\char`\\setKV} et \texttt{\char`\\setKVdefault}} Ces commandes définissent des \ et leur assignent des \ dans un \. La seule différence entre les deux macros est que \verb|\setKVdefault|, en plus d'assigner les \ aux \, les sauvegarde en vue d'une restauration ultérieure avec \verb|\restoreKV|. On écrit \code|\setKV[]{=,=,...,=}| Il faut noter que \begin{itemize} \item pour parvenir à leurs fins, ces macros peuvent être utilisées une ou plusieurs fois, avec un nombre de couples \/\ quelconque; \item un ensemble \=\ réduit à 0 caractère après suppression des espaces est ignoré; \item lors de la lecture des \/\, la virgule et le signe égal doivent avoir un catcode de 12 sans quoi ils ne seront pas compris comme frontières entre \ et \ et ne joueront pas leur rôle; \item le nom du \, bien qu'entre crochets, est \emph{obligatoire} , il peut éventuellement être vide bien que cela ne soit pas conseillé; \item les espaces autour du nom du \ ne sont \emph{pas} retirés et donc le trousseau «\verb|foo|» n'est pas le même que le trousseau «\verb*|foo |» \item si une même \ est définie plusieurs fois, la \ retenue sera celle de la dernière assignation; \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|\setKV[foo]{mon bool}| est équivalent à \code|\setKV[foo]{mon bool = true}| \end{itemize} \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é définie, 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|\setKV[foo]{nombre = 5 , lettres= AB \textit{CD} , mon bool} a) \useKV[foo]{nombre}.\qquad b) \useKV[foo]{lettres}.\qquad c) \useKV[foo]{mon bool}. \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`\\restoreKV}} La macro \verb|\restoreKV[]| réinitialise toutes les \ du \ aux \ qui ont été définies lors des précédentes exécutions de \verb|\setKVdefault|. La macro \verb|\useKVdefault[]| lui est équivalente. \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`\\ifkeyKV}} Cette macro teste si une \ est définie selon la syntaxe \code|\ifkeyKV[]{}{}{}| La macro est purement développable et nécessite 2 développements pour donner l'un des deux codes. \paragraph{La macro \texttt{\char`\\ifemptyKV}} Cette macro teste si la \ d'une \ est vide selon la syntaxe \code|\ifemptyKV[]{}{}{}| La macro est purement développable et nécessite 2 développements pour donner l'un des deux codes. \paragraph{La macro \texttt{\char`\\showKV}} Cette commande écrit dans le fichier \texttt{log} la \ et le \ assignés à une \ d'un \: \code|\showKV[]{}| Si la \ n'est pas définie, «\texttt{non défini}» est affiché dans le fichier log. Il en est de même pour le \. \section{Code} En plus d'une \, un \ arbitraire peut être assigné à n'importe quelle \. Pour ce faire, on écrit \begin{center} \verb|\defKV[]{=,=,...,=}| \end{center} Chaque \ peut contenir «\verb|#1|» qui représente la \ de la \. Ce \ est exécuté lorsque une \ est assignée à la \ avec \verb|\setKV|, \verb|\setKVdefault| ou \verb|\restoreKV|. \bigbreak Ainsi déclarer \code|\defKV[x]{ mykey = \def\foo{\textbf{#1}}| va définir une macro \verb|\foo| dès que la \ «\texttt{mykey}» va être définie (ou redéfinie) et donc, si l'on écrit \code|\setKV[x]{ mykey = bonjour }| le code qui est exécuté en coulisses est \code|\def\foo{\textbf{bonjour}}| \exemple|\defKV[x]{ mykey = \def\foo{\textbf{#1}} } \setKV[x]{ mykey = bonjour }% définition 1) \meaning\foo\par 2) \useKV[x]{ mykey } \setKV[x]{ mykey = hello }% redéfinition 3) \meaning\foo\par 4) \useKV[x]{ mykey }| La macro \verb|\testboolKV| permet de tester, par exemple dans un \, si son argument est «true» ou «false» \code|\testboolKV{}{}{}| La macro est purement développable, elle nécessite 2 développements pour donner l'un des deux codes, et exige que l'\ soit booléen sans quoi un message d'erreur est émis. \exemple|\defKV[x]{ x = \def\test{\testboolKV{#1}{test positif}{test négatif}}} \setKV[x]{ x = true} 1) \test \setKV[x]{ x= false} 2) \test| Toute autre valeur que «\verb|true|» ou «\verb|false|» génèrera un message d'erreur. \section{Un exemple d'utilisation} Voici comment on pourrait programmer une macro qui affiche un cadre sur une ligne, grâce à la macro \verb|\fbox| et l'environnement \verb|center| de \LaTeX. 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{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}); \item \texttt{style} qui contient le code exécuté avant le texte. \end{itemize} Une première façon de faire, sans recours à \verb|\defKV|; \exemple|\setKVdefault[frame]{ sep = 3pt, line width = 0.5pt, style = \bfseries, inline } \newcommand\frametxt[2][]{% \restoreKV[frame]% revenir au valeurs par défaut \setKV[frame]{#1}% lit les arguments optionnels \fboxsep = \useKV[frame]{sep} \fboxrule= \useKV[frame]{line width} \ifboolKV[frame]{inline} {} {\begin{center}}% \fbox{\useKV[frame]{style}#2}% \ifboolKV[frame]{inline} {} {\end{center}}% } Un essai en ligne par défaut \frametxt{essai} puis un autre \frametxt[sep=5pt,line width=2pt]{essai} et un dernier \frametxt[sep=1pt,style=\itshape]{essai}. Un essai hors ligne : \frametxt[inline = false, style=\bfseries\color{red}]{essai centré}| Dans l'exemple repris ci-dessous et grâce à \verb|\defKV|, on stocke tous les paramètres lors de leur assignation. Il y a bien moins de verbosité dans le code de \verb|frametxt| ce qui le rend plus léger et plus lisible. \exemple|\defKV[frame]{% sep = {\fboxsep = #1 }, line width = {\fboxrule= #1 }, inline = \testboolKV{#1} {\def\hookpre{}\def\hookpost{}} {\def\hookpre{\begin{center}}\def\hookpost{\end{center}}}, style = \def\fstyle{#1} } \setKVdefault[frame]{ sep = 3pt, line width = 0.5pt, style = \bfseries, inline } \newcommand\frametxt[2][]{% \restoreKV[frame]% revenir au valeurs par défaut \setKV[frame]{#1}% lit les arguments optionnels \hookpre \fbox{\fstyle #2}% \hookpost } Un essai en ligne par défaut \frametxt{essai} puis un autre \frametxt[sep=5pt,line width=2pt]{essai} et un dernier \frametxt[sep=1pt,style=\itshape]{essai}. Un essai hors ligne : \frametxt[inline = false, style=\bfseries\color{red}]{essai centré}| \end{document}