diff options
author | Karl Berry <karl@freefriends.org> | 2017-05-02 21:44:16 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2017-05-02 21:44:16 +0000 |
commit | 4b5f083d84e14a50598792a1035cc601ed39baa9 (patch) | |
tree | 900d09244b082d1215b1cb12d2b7a1dafdf503b8 /Master/texmf-dist | |
parent | 07dc3a0326b2e760470ab8635dcb16036920d5a5 (diff) |
hlist (2may17)
git-svn-id: svn://tug.org/texlive/trunk@44158 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist')
-rw-r--r-- | Master/texmf-dist/doc/generic/hlist/README | 21 | ||||
-rw-r--r-- | Master/texmf-dist/doc/generic/hlist/hlist-fr.pdf | bin | 0 -> 391818 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/generic/hlist/hlist-fr.tex | 462 | ||||
-rw-r--r-- | Master/texmf-dist/doc/generic/hlist/htest-latex.pdf | bin | 0 -> 106461 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/generic/hlist/htest-latex.tex | 162 | ||||
-rw-r--r-- | Master/texmf-dist/doc/generic/hlist/htest-tex.pdf | bin | 0 -> 78134 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/generic/hlist/htest-tex.tex | 173 | ||||
-rw-r--r-- | Master/texmf-dist/tex/generic/hlist/hlist.sty | 6 | ||||
-rw-r--r-- | Master/texmf-dist/tex/generic/hlist/hlist.tex | 838 |
9 files changed, 1662 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/generic/hlist/README b/Master/texmf-dist/doc/generic/hlist/README new file mode 100644 index 00000000000..2d5817c0fba --- /dev/null +++ b/Master/texmf-dist/doc/generic/hlist/README @@ -0,0 +1,21 @@ +___________________________________ + + L'extension + hlist + + v0.1 + + 1er mai 2017 +___________________________________ + +Authors : Christian Tellechea +Maintainer: Christian Tellechea +E-mail : unbonpetit@openmailbox.org (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 + +---------------------------------------------------------------------- + +Horizontal and columned lists diff --git a/Master/texmf-dist/doc/generic/hlist/hlist-fr.pdf b/Master/texmf-dist/doc/generic/hlist/hlist-fr.pdf Binary files differnew file mode 100644 index 00000000000..f7e8a0923ce --- /dev/null +++ b/Master/texmf-dist/doc/generic/hlist/hlist-fr.pdf diff --git a/Master/texmf-dist/doc/generic/hlist/hlist-fr.tex b/Master/texmf-dist/doc/generic/hlist/hlist-fr.tex new file mode 100644 index 00000000000..df32418a419 --- /dev/null +++ b/Master/texmf-dist/doc/generic/hlist/hlist-fr.tex @@ -0,0 +1,462 @@ +% !TeX encoding = ISO-8859-1 +% Ceci est la documentation du package "hlist" +% +% Fichier compilé avec pdflatex +\documentclass[frenchb,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,hlist} +\usepackage[scaled=0.8]{luximono} +\frenchbsetup{og=«,fg=»} +\def\eTeX{\hbox{$\varepsilon$-\TeX}} +\def\HLIST{\texttt{\hlstname}\xspace} +\makeatletter +\def\code{\expandafter\code@i\string} +\def\code@i#1{% + \begingroup + \par\nobreak\medskip\parindent0pt + \leftskip.1\linewidth + \catcode`\^^I 13 \begingroup\lccode`\~`\^^I \lowercase{\endgroup\def~{\leavevmode\space\space\space\space}}% + \let\do\@makeother \dospecials + \ttfamily\small\@noligs + \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\hlstdate\@nil} +\makeatother +\begingroup + \catcode`\_11 + \gdef\cleval#1#2{% + \bigbreak\noindent + \hbox to .25\linewidth{% + \color{teal}\bfseries\ttfamily + \detokenize{#1}=$\langle$\detokenize{#2}$\rangle$\hss}\kern2.5em + (\textit{Défaut} : {\color{teal}\ttfamily + \hlst_eearg\hlst_ifempty{\useKV[hlist]{#1}} + {\detokenize{{}}} + {\detokenize\expandafter\expandafter\expandafter{\useKV[hlist]{#1}}}})% + \par\nobreak + } +\endgroup +\begin{document} +\parindent=0pt +\thispagestyle{empty} +\begin{titlepage} + \begingroup + \centering + \null\vskip.25\vsize + {\large\bfseries L'extension pour \TeX/\LaTeX\par \Huge \hlstname\par} + \bigbreak + v \hlstver + \smallbreak + \longfrhlstdate + \vskip1.5cm + Christian \bsc{Tellechea}\footnote{\texttt{unbonpetit@openmailbox.org}}\par + \endgroup + \vskip2cm + \leftskip=.2\linewidth \rightskip=.2\linewidth \small + Cette petite extension sans prétention permet de créer des listes horizontale d'items; s'ils s'étendent sur plus d'une ligne, ils seront alignés les uns au-dessous des autres, en colonnes de largeurs égales, un peu à la manière d'un tableau. +\end{titlepage} +\parindent1.5em + +\section{Comment ça marche} +Au tout début, j'avais écrit ce code pour présenter des questions courtes \emph{en ligne}, comme on peut le voir parfois dans les manuels scolaires, pour une économie de place verticale dans mes feuilles d'exercices ou de contrôles\footnote{On ne trouve pas ce genre de questions dans mes contrôles !} : + +\exemple/Qu'est ce que \TeX ? +\begin{hlist}3 + \hitem Une marque \emph{distributeur} de vêtements que l'on trouve dans l'enseigne Carrefour; + \hitem Une unité de mesure de la finesse de filaments; + \hitem Un logiciel de composition créé par Donald \bsc{Knuth}; + \hitem Le nom \emph{de scène} de l'humoriste Jean-Christophe \bsc{Le Texier}; + \hitem Une membrane coupe-vent. +\end{hlist}/ + +Le code initial dont je me suis servi pendant longtemps était bien plus basique que celui de cette extension; depuis, il s'est complexifié, mais les méthodes qu'il mettait en \oe uvre sont restées les mêmes. Or, j'avais programmé les listes horizontales en utilisant des \emph{boites} de \TeX{} et non pas des \emph{alignements}. Évidemment, il semble plus naturel de faire appel aux alignements de \TeX{} pour réaliser une telle tâche, mais leur mise en \oe uvre est plus délicate que celle des boites et j'ai été partisan du moindre effort (et je le suis toujours). + +Récemment\footnote{\texttt{http://forum.mathematex.net/latex-f6/macros-a-parametres-indefini-t16733.html\char`\#p155215}}, alors que la finalisation du code avait déjà commencée, j'ai découvert que l'extension \texttt{Tasks} offrait \emph{presque} les mêmes fonctionnalités que \HLIST. Comme \emph{presque} n'est pas synonyme d'\emph{exactement}, je me suis finalement décidé à publier cette extension. Il n'est bien entendu pas dans mon intention de dénigrer le travail de C. \bsc{Niederberger} et encore moins de considérer \HLIST comme meilleure que \texttt{Tasks}, mais au niveau des principales différences entre \texttt{Tasks} et \HLIST, on peut citer : +\begin{itemize} + \item \HLIST peut être utilisé avec \TeX{} (\eTeX en réalité) alors que \texttt{Tasks} requiert \LaTeX; + \item les listes de \HLIST peuvent être imbriquées tandis que celles de \texttt{Tasks} ne le peuvent pas; + \item les changements de catcode (et donc le « verbatim ») sont possibles dans les listes de \HLIST et pas dans celles de \texttt{Tasks}; + \item le code source de \HLIST est plus concis que celui de \texttt{Tasks} (écrit en \LaTeX3) et, contrairement à ce dernier, \HLIST ne fait appel à aucune extension tierce\footnote{Vu les facilités prétendument offertes par \LaTeX3 et les extensions chargées par \texttt{Tasks}, je suis resté médusé face à la longueur du code de \texttt{Tasks}. Je ne m'explique pas un telle différence entre la taille des deux codes alors que \HLIST embarque son propre système de clés/valeurs, ses macros de développement, etc. Avant de me lancer dans une critique sans ménagement de \LaTeX3 et comme j'ai un fort soupçon que quelque chose m'échappe là-dedans, je serais très reconnaissant si quelqu'un, capable de comprendre ce qui se passe, pouvait me fournir une explication.}; + \item la documentation de \texttt{Tasks} est en anglais (son auteur est allemand); celle de \HLIST est en français. Cesser de docilement se plier à cette prétendue nécessité de fournir une documentation en anglais, fusse pour des extensions de \TeX/\LaTeX, compte \emph{beaucoup} à mes yeux. +\end{itemize} + +En revanche, puisque les deux extensions s'appuient sur des constructions de boites, \HLIST partage avec \texttt{Tasks} le principal défaut : une coupure de page ne peut pas avoir lieu au sein d'un item qui s'étendrait sur plusieurs lignes. + +\section{Syntaxe} +L'environnement \HLIST peut être appelé de ces deux manières: +\begin{itemize} + \item façon \LaTeX: \begin{tabular}[t]{l}\relax\verb|\begin{hlist}[<paramètres>]<nombre>|\\\hskip2em \ttfamily contenu de l'environnement\\\verb|\end{hlist}|\end{tabular} + \item façon \TeX: \begin{tabular}[t]{l}\relax\verb|\hlist[<paramètres>]<nombre>|\\\hskip2em \ttfamily contenu de l'environnement\\\verb|\endhlist|\end{tabular} +\end{itemize} + +Les options, décrites plus loin, seront celles qui s'appliquent à cette liste et le \verb|<nombre>| est le nombre de colonnes demandées. + +L'environnement \HLIST doit commencer par un item, c'est-à-dire par la macro \verb|\hitem|, éventuellement suivie des arguments optionnels suivants : + +\begin{enumerate} + \item "\verb|*|" signifiant que cet item doit commencer une nouvelle ligne; + \item "\texttt{>}" signifiant que cet item doit s'étendre sur toutes les colonnes restant disponibles sur la ligne en cours ; + \item l'argument entre crochets "\verb|[<label>]|" spécifie ce que doit être la numérotation de cet item (voir la description de cette fonctionnalité plus loin); + \item l'argument entre parenthèses "\verb|(<n>)|" où \verb|<n>| est un entier, indique sur combien de colonnes doit d'étendre cet item. +\end{enumerate} + +Il faut noter que, s'ils sont présents tous les deux, l'argument optionnel "\verb|*|" \emph{doit} précéder "\texttt{>}". En revanche pour les deux derniers arguments optionnels, l'ordre n'a pas d'importance et donc "\verb|[<label>](<n>)|" et accepté tout comme "\verb|(<n>)[<label>]|". + +\exemple/\def\txtA{Après le pain, l'éducation est le premier besoin du peuple.} +\def\txtB{Comment se fait-il que les enfants étant si intelligents, + la plupart des hommes soient bêtes ?\par Cela doit tenir à l'éducation.} +\hlist3 + \hitem \txtA \hitem \txtB \hitem \txtA + \hitem \txtA \hitem> \txtB + \hitem*> \txtB + \hitem(2) \txtB \hitem \txtA +\endhlist/ + +On peut voir à la page~\pageref{show frame} cette même liste horizontale avec des cadres tracés autour des boites, ce qui peut rendre les choses plus claires pour cet exemple, volontairement complexe et peu réaliste. + +\section{Choix des paramètres} +Nous avons déjà vu qu'écrire \verb|\hlist[<paramètres>]| permet de régler des \verb|<paramètres>| spécifiques à la liste qui suit. + +On peut également régler des \verb|<paramètres>| pour toutes les \HLIST à venir avec +\begin{center} +\verb|\sethlist{<paramètres>}| +\end{center} +mais aussi régler des \verb|<paramètres>| \emph{par défaut} pour les \HLIST à venir avec +\begin{center} +\verb|\setdefaulthlist{<paramètres>}| +\end{center} + +Chaque paramètre est de la forme \verb|<clé>=<valeur>| où la \verb|<clé>| est le plus souvent constituée de deux mots (l'espace entre ces deux mots est \emph{nécessaire}). Les espaces avant et après la \verb|<clé>| et la \verb|<valeur>| sont ignorés. + +Lorsqu'une \verb|<clé>| est seule, elle est comprise comme un \emph{booléen} qui vaut \verb|true|. Pour indiquer qu'un booléen est faux, il faut assigner la valeur \verb|false|. + +Les paramètres de \emph{placement} sont résumés dans le schéma ci-dessous:\par\kern10pt \nobreak + + {\ttfamily\footnotesize + \begin{tikzpicture}[line join=round,x=1.33cm,y=1.33cm] + % tracé du paragraphe précédent la hlist + \draw [dash pattern=on 2pt off 2pt] (11.6,7.6)--(11.1,7.6); + \draw(11.1,7.6)--(1.6,7.6)--(1.6,7.1)--(0,7.1)--(0,6.6)--(11.1,6.6); + \draw[dash pattern=on 2pt off 2pt] (11.6,6.6)--(11.1,6.6); + \draw[-stealth](0,8)--(1.6,8)node[midway,anchor=south]{\string\parindent}; + % tracé du 1er label + \draw(1.2,5.7)--(1.8,5.7)--(1.8,5.3)--(1.2,5.3); + \draw[fill=lightgray](1.2,5.7)--(1.6,5.7)--(1.6,5.3)--(1.2,5.3)--cycle; + \draw(1.4,5.5)node[anchor=center]{\normalfont\large\bfseries1.}; + \draw[-stealth](0,5.8)--(1,5.8)node [midway,anchor=south]{left margin}; + \draw[-stealth](1,6.2)--(2.1,6.2)node [midway,anchor=south]{item offset}; + \draw[line width=1pt,red](1,5.6)--(1.2,5.6); + \draw[-stealth](2.1,5.8)--(1.8,5.8)node [midway,anchor=south]{label sep}; + + \draw[-stealth](1.8,5)--(1.2,5)node [pos=0,anchor=south east]{label width}; + \draw[-stealth](3.2,6.6)--(3.2,5.7)node[midway,anchor=west]{\string\parskip+pre skip}; + % tracé du 1er texte + \draw(2.1,5.7)--(5.5,5.7)--(5.5,4.1)--(2.1,4.1)--cycle; + % tracé du 2e label + \draw[-stealth](5.5,5.8)--(6.3,5.8)node[midway,anchor=south]{col sep}; + \draw(6.3,5.7)--(7,5.7)--(7,5.3)--(6.3,5.3)--cycle; + % tracé du 2e texte + \draw [dash pattern=on 2pt off 2pt](9.5,5.7)--(8.9,5.7); + \draw(8.9,5.7)--(7.3,5.7)--(7.3,4.9)--(8.9,4.9); + \draw [dash pattern=on 2pt off 2pt](8.9,4.9)--(9.5,4.9); + % tracé 2e ligne + \draw(1.2,3.4)--(1.8,3.4)--(1.8,3)--(1.2,3)--cycle; + \draw [dash pattern=on 2pt off 2pt](3.7,3.4)--(3,3.4); + \draw(3,3.4)--(2.1,3.4)--(2.1,3); + \draw [dash pattern=on 2pt off 2pt](2.1,3)--(2.1,2.7); + \draw[-stealth](2.4,4.1)--(2.4,3.4)node[midway,anchor=west]{\string\parskip+item sep}; + \end{tikzpicture}} + +\section{Placement de la liste de plus haut niveau} +\cleval{pre skip}{ressort} +Valeur du \verb|<ressort>| vertical inséré avant la liste \emph{de plus haut niveau d'imbrication}. + +\cleval{post skip}{ressort} +Valeur du \verb|<ressort>| vertical inséré après la liste \emph{de plus haut niveau d'imbrication}. + +\cleval{left margin}{dimension} +Valeur du décalage vers la droite de la liste \emph{de plus haut niveau d'imbrication}. + +\exemple/\parindent=2em +Ceci est un paragraphe s'étendant sur deux ligne et présentant +une liste de questions mises en forme à l'aide de l'extension \texttt{hlist} +et avec les paramètres par défaut : +\hlist3% paramètres par défaut + \hitem Question 1 \hitem Question 2 + \hitem Une question 3 + \hitem Question 4 \hitem Question 5 +\endhlist +Ceci est un paragraphe s'étendant sur deux ligne et présentant +une liste de questions mises en forme à l'aide de l'extension \texttt{hlist} +et avec des paramètres spécifiés par argument optionnel : +\hlist[pre skip = 0pt , post skip = 4pt , left margin = \parindent]3 + \hitem Question 1 \hitem Question 2 + \hitem Une question 3 + \hitem Question 4 \hitem Question 5 +\endhlist +Suite du texte/ + +\section{Label et texte des items} +\cleval{item offset}{dimension} +Cette \verb|<dimension>| est la distance entre la frontière gauche de la boite contenant le label et la frontière gauche de la boite contenant le texte de l'item. + +\cleval{label sep}{dimension} +Espacement entre la boite contenant le label et celle contenant le texte de l'item. + +\cleval{label width}{dimension} +C'est la dimension de la boite accueillant le label. Le label lui-même (en gris sur la figure) peut être plus court que cette dimension auquel cas, il faut jouer avec la clé «\verb|label align|» (voir plus bas) pour indiquer quel alignement on souhaite. + +Si en revanche le label est \emph{plus large} que la largeur «\verb|label width|», alors un dépassement du type «\texttt{Overful hbox}» aura lieu, sauf si on met la clé \verb|autoindent| à la valeur \verb|true| (voir plus bas).\medbreak + +Les trois clés «\verb|item offset|», «\verb|label sep|» et «\verb|label width|» sont en interdépendance pour le placement du label et plusieurs cas peuvent se présenter : + +\begin{itemize} + \item si l'une des 3 trois (et seulement \emph{une seule} sur les trois) vaut «\verb|*|», alors, les 2 autres sont calculées de telles sorte que l'égalité suivante soit vérifiée + \begin{center} + \verb|item offset|${}={}$\verb|label sep|${}+{}$\verb|label width| + \end{center} + \item si \verb|item offset|${}>{}$\verb|label sep|${}+{}$\verb|label width| comme c'est le cas sur la figure, alors la différence entre le membre de gauche et celui de droite (trait rouge sur la figure) est meublé avec un \verb|\hfill|; + \item si \verb|item offset|${}<{}$\verb|label sep|${}+{}$\verb|label width|, ce qui ne devrait pas se produire, un avertissement sera émis. +\end{itemize} + +\cleval{label align}{lettre} +Cette clé représente la consigne d'alignement du label à l'intérieur de sa boite. Elle n'a de sens que lorsque le label occupe moins de place horizontale que «\verb|label width|». On peut demander une consigne \verb|l|, \verb|r| ou \verb|c| selon que l'on souhaite un alignement à gauche, à droite ou centré. + +Seule le première lettre \emph{minuscule} de la valeur est prise en compte. La consigne \verb|left| est donc équivalente à \verb|l|. + +\cleval{label}{code} +Le \verb|<code>| sera exécuté pour afficher le label. Pour afficher des labels en rapport avec le rang de l'item dans la liste, \HLIST met à disposition les macros suivantes : +\begin{itemize} + \item \verb|\arabic{<nom>}| pour afficher un entier; + \item \verb|\roman{<nom>}| et \verb|\Roman{<nom>}| pour afficher des nombres romains, en minuscule ou majuscule ; + \item \verb|\alpha{<nom>}| et \verb|\Alpha{<nom>}| pour afficher des lettres, minuscules ou majuscules. +\end{itemize} + +L'argument de ces macros est le \emph{nom} d'un compteur au format \LaTeX{}, c'est-à-dire que le registre de compteur qui se trouve derrière est \verb|\c@<nom>|\footnote{Les compteurs de \LaTeX{} pour l'environnement \texttt{enumerate}, à savoir \texttt{enumi}, \texttt{enumii}, etc sont bien évidemment admis dans les arguments des macros ci-dessus. En règle générale, tout compteur de \LaTeX{} l'est également (\texttt{section}, \texttt{equation}, \texttt{page}, \texttt{footnote} ou autre).}. + +\HLIST fournit les compteurs nommés «\verb|hilsti|» pour les listes de plus haut niveau, «\verb|hilstii|» pour les listes imbriquées de niveau~1, «\verb|hilstiii|» pour celle de niveau~2, etc. + +\cleval{pre label}{code} +Contient le \verb|<code>| qui sera exécutée avant d'afficher le label. + +\cleval{post label}{code} +Contient le \verb|<code>| qui sera exécutée après avoir affiché le label. + +\exemple/Exemple 1 :\hlist[label=\alpha{hlisti})]3 + \hitem question 1 \hitem question 2 \hitem question 3 \hitem question 4 + \endhlist +Exemple 2:\hlist[label=---]3 + \hitem question 1 \hitem question 2 \hitem question 3 \hitem question 4 + \endhlist +Exemple 3:\hlist[pre label=\begingroup\color{red}\itshape,label=\roman{hlisti}-,post label=\endgroup]3 + \hitem question 1 \hitem question 2 \hitem question 3 \hitem question 4 + \endhlist/ + +Lorsque l'argument optionnel entre crochet de \verb|\hitem| est vide, aucun label ne sera affiché et la valeur «\texttt{item offset}» sera nulle pour cet item. Cela peut s'avérer utile dans le cas de listes imbriquées : + +\exemple|Exemple avec 2\up e label numéroté : +\hlist3 + \hitem question 1 + \hitem% label numéroté pour cet item ! + \hlist[label=\alpha{hlistii}.,col sep=1em]3 + \hitem XX \hitem YY \hitem ZZ + \endhlist + \hitem question 3 \hitem question 4 \hitem question 5 +\endhlist + +Même exemple avec 2\up e label forcé à vide : +\hlist3 + \hitem question 1 + \hitem[]% pas de label pour cet item ! + \hlist[label=\arabic{hlisti}\alpha{hlistii}.]3 + \hitem XX \hitem YY \hitem ZZ + \endhlist + \hitem question 3 \hitem question 4 \hitem question 5 +\endhlist| + +\cleval{pre label}{code} +Il s'agit du \verb|<code>| qui est exécuté juste avant que le label soit affiché. + +\cleval{post label}{code} +Cette valeur contient le \verb|<code>| qui est exécuté juste après l'affichage du label. + +\cleval{resume}{booléen} +Lorsque cette clé est assignée à \verb|true|, la numérotation de la liste n'est pas réinitialisée lorsque la macro \verb|\hlist| est exécutée. + +\cleval{autoindent}{booléen} +Lorsque la largeur du label dépasse la dimension «\verb|label width|, nous avons vu qu'un avertissement du type \texttt{Overful hbox} est produit. Lorsque la clé «\texttt{autoindent}» est mise à \verb|true|, ce dépassement se fait en \emph{indentant la première ligne du texte du label} de telle sorte que subsiste entre le label et le texte l'espace de largeur «\texttt{label sep}». Il n'y a alors plus d'avertissement émis par \TeX. + +Ceci fonctionne évidemment pour un schéma de label \emph{global} passé par la clé «\verb|label={<code>}|», mais trouve surtout une utilité pour des labels \emph{exceptionnels} spécifiés par \verb|\hitem[<label>]|. + +\exemple|\def\txt{et voici le texte de la question} +\hlist[item sep=5pt]3 + \hitem Question 1, \txt \hitem Question 2, \txt \hitem[Bonus] Question 3, \txt + \hitem Question 4, \txt \hitem Question 5, \txt +\endhlist +Texte intermédiaire... +\hlist[item sep=5pt,autoindent=true]3 + \hitem Question 1, \txt \hitem Question 2, \txt \hitem[Bonus] Question 3, \txt + \hitem Question 4, \txt \hitem Question 5, \txt +\endhlist| + +\cleval{pre item}{code} +Le code exécuté juste avant le texte de l'item. + +\cleval{post item}{code} +Le code exécuté juste après le texte de l'item. + +\cleval{show label}{booléen} +Cette clé, lorsqu'elle est assignée à \verb|false|, interdit l'affichage du label et donc, tout se passe comme si les dimensions \texttt{item offset}, \texttt{label width} et \texttt{label sep} valaient \verb|0pt|. + +\exemple|Exemple avec \texttt{show label} : +\hlist3 + \hitem Question 1 \hitem Question 2 + \hitem Une question 3 + \hitem Question 4 \hitem Question 5 +\endhlist +Exemple sans \texttt{show label} : +\hlist[show label=false]3 + \hitem Question 1 \hitem Question 2 + \hitem Une question 3 + \hitem Question 4 \hitem Question 5 +\endhlist| + +\cleval{list parindent}{dimension} +Cette clé spécifie l'indentation des paragraphes de l'item, sauf pour le premier paragraphe de chaque item qui reste non indenté. + +\cleval{show frame}{booléen} +Cette clé, lorsqu'elle est assignée à \verb|true|, encadre les boites contenant le label et le texte de l'item. + +\label{show frame}\exemple/\def\txtA{Après le pain, l'éducation est le premier besoin du peuple.} +\def\txtB{Comment se fait-il que les enfants étant si intelligents, + la plupart des hommes soient bêtes ?\par Cela doit tenir à l'éducation.} +\hlist[show frame=true]3 + \hitem \txtA \hitem \txtB \hitem \txtA + \hitem \txtA \hitem> \txtB + \hitem*> \txtB + \hitem(2) \txtB \hitem \txtA +\endhlist/ + +\section{Le code} +Contrairement à mes habitudes, le code est \emph{abondamment} commenté, trop sans doute. J'espère que cela constituera une source d'information exploitable pour les utilisateurs de cette extension qui souhaitent y comprendre quelque chose ou modifier par eux-même une fonctionnalité. + +Toute suggestion, remontée de bug, remarque, demande, ajout ou modification de fonctionnalité est bienvenue; dans ce cas, j'invite les utilisateurs de \HLIST à m'envoyer un email.\medbreak + +Le code ci-dessous est l'exact verbatim du fichier \verb|hlist.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,% + hlist,endhlist,hitem,hlst_arabic,hlst_roman,% + hlst_Roman,hlst_alpha,hlst_Alpha,inithlist,% + sethlist,setdefaulthlist}, + keywordstyle=\bfseries\color{red!85!black}, + classoffset=0, + ]{hlist.tex} +\end{document}
\ No newline at end of file diff --git a/Master/texmf-dist/doc/generic/hlist/htest-latex.pdf b/Master/texmf-dist/doc/generic/hlist/htest-latex.pdf Binary files differnew file mode 100644 index 00000000000..8af038836ac --- /dev/null +++ b/Master/texmf-dist/doc/generic/hlist/htest-latex.pdf diff --git a/Master/texmf-dist/doc/generic/hlist/htest-latex.tex b/Master/texmf-dist/doc/generic/hlist/htest-latex.tex new file mode 100644 index 00000000000..97fdc26984a --- /dev/null +++ b/Master/texmf-dist/doc/generic/hlist/htest-latex.tex @@ -0,0 +1,162 @@ +% !TeX encoding = ISO-8859-1 +% Ceci est le fichier de test (pdf)(Xe)(lua)LaTex de l'entension hlist +% +% Fichier compilé avec pdflatex +\documentclass[frenchb,a4paper,draft]{article} +\usepackage[latin1]{inputenc} +\usepackage[T1]{fontenc} +\usepackage[margin=2cm]{geometry} +\usepackage{xcolor,hlist,babel} +\begingroup\catcode`\_11 +\gdef\repeatntimes{\begingroup\def\temp{\endgroup}\repeatntimes_i} +\gdef\repeatntimes_i#1#2{% répète #1 fois le code #2 + \hlst_ifnum{#1>0 } + {\expandafter\def\expandafter\temp\expandafter{\temp#2}% + \hlst_exparg\repeatntimes_i{\number\numexpr#1-1}{#2}} + \temp +} +\endgroup +\begin{document} +\hlstdebugmodetrue +\parindent1.5em +\begingroup + \hfill\bfseries\Huge Fichier de test \LaTeX\hfill\null\par +\endgroup + +\section{Test 1} +Voici le texte précédent \repeatntimes{15}{bla bla bla } +\begin{hlist}5 + \hitem \repeatntimes6{bla bla 1 } + \hitem \repeatntimes6{bla bla 2 } + \hitem \repeatntimes6{bla bla 3 } + \hitem \repeatntimes2{bla bla 4 } + \hitem \repeatntimes4{bla bla 5 } + \hitem \repeatntimes3{L2 L2 } + \hitem(3) \repeatntimes9{multicol 3 } + \hitem*(2) \repeatntimes5{retour ligne + multicol 2 } + \hitem> \repeatntimes5{multicol maximal } +\end{hlist} +Voici le texte qui suit la liste \repeatntimes{15}{bla bla bla } + +\section{Test 2} +Voici le texte précédent \repeatntimes{15}{bla bla bla } +\sethlist{% + left margin=\parindent, + label=\arabic{section}\alpha{hlisti}), + item offset=2.5em, + label width=*, + pre item=\begingroup\color, + post item=\endgroup, + autoindent} +\begin{hlist}3 + \hitem {blue}item bleu ! + \hitem {red}\repeatntimes3{bla bla en rouge } + \hitem {cyan}item cyan + \hitem>[LABEL PERSO] {magenta}\repeatntimes4{Long item sur toute la largeur } +\end{hlist} +\inithlist% retour aux valeur par défaut +Voici le texte qui suit la liste \repeatntimes{15}{bla bla bla } + +\section{Test 3} +Voici le texte précédent \repeatntimes{15}{bla bla bla } +\begin{hlist}[pre skip=0pt,post skip=0pt]4 + \hitem Item répété + \hitem Item répété + \hitem Item répété + \hitem Item répété + \hitem Item répété + \hitem Item répété +\end{hlist} +Voici le texte intermédiaire \repeatntimes{15}{bla bla bla } +\begin{hlist}[resume,pre skip=0pt,post skip=0pt]4 + \hitem Item répété + \hitem Item répété + \hitem Item répété + \hitem Item répété + \hitem Item répété + \hitem Item répété +\end{hlist} +Voici le texte qui suit la liste \repeatntimes{15}{bla bla bla } + +\section{Test 4} +\noindent +\begin{minipage}[t]{0.5\linewidth} + Voici le texte précédent \repeatntimes{15}{bla bla bla } + \begin{hlist}[label=$\bullet$,label sep=.33em,label width=.75em, + label align=l,item offset=*,show frame]3 + \hitem Choix A + \hitem Choix B + \hitem Choix C + \hitem Choix D + \hitem Choix E + \end{hlist} +\end{minipage}\hfill\vrule\hfill +\begin{minipage}[t]{0.4\linewidth} + Voici le texte précédent \repeatntimes{8}{bla bla bla } + \begin{hlist}[label=$\bullet$,label sep=.33em,label width=.75em, + label align=l,item offset=*]3 + \hitem Choix A + \hitem Choix B + \hitem Choix C + \hitem Choix D + \hitem Choix E + \end{hlist} +\end{minipage} + +\section{Test 5} +Voici le texte précédent \repeatntimes{15}{bla bla bla } + +\begin{enumerate} + \item Question 1 + \item Question 2\par + \begin{hlist}[label=\arabic{enumi}\alpha{hlisti},pre skip=0pt, + post skip=0pt]3 + \hitem Choix A + \hitem Choix B + \hitem Choix C + \hitem Choix D + \end{hlist} + \item Question 3\par + \begin{hlist}[label=\arabic{enumi}\alpha{hlisti},pre skip=0pt, + post skip=0pt]3 + \hitem Réponse A + \hitem Réponse B + \hitem Réponse C + \hitem Réponse D + \end{hlist} + \item Question 4 +\end{enumerate} +Voici le texte qui suit la liste \repeatntimes{15}{bla bla bla } + +\section{Test 6} +Voici le texte précédent \repeatntimes{15}{bla bla bla } +\begin{hlist}[label sep=0.25em,label width=1.6em,item offset=*, + label=\arabic{section}\alpha{hlisti},col sep=1em,show frame]8 + \repeatntimes{26}{\hitem a\space eou}% +\end{hlist} +Voici le texte qui suit la liste \repeatntimes{15}{bla bla bla } + +\section{Test 7} +Voici le texte précédent \repeatntimes{15}{bla bla bla } +\begin{hlist}[item offset=\parindent,label width=1em,label sep=*,list parindent=\parindent]3 + \hitem Un premier item\par + Une autre ligne pour rien dire ! + \hitem Le \verb|verbatim| est permis avec l'extension \verb|hlist|, la preuve : <<~\verb|# 1\ $% ~|~>>. + \hitem Un troisième item pour le fun et pour remplir une ligne\par + Un autre paragraphe pour prendre deux lignes. + \hitem La fin... des haricots ! +\end{hlist} +Voici le texte qui suit la liste \repeatntimes{15}{bla bla bla } + +\section{Test 8} +Voici le texte précédent \repeatntimes{15}{bla bla bla } +\begin{hlist}[show label=false,show frame,col sep=3em,list parindent=\parindent]3 + \hitem Un premier item\par + Une autre ligne pour ne rien dire ! + \hitem Le \verb|verbatim| est permis dans les items avec l'extension \verb|hlist|, la preuve : <<~\verb|# 1\ $% ~|~>>. + \hitem Un troisième item pour remplir une ligne\par + Un deuxième paragraphe qui prend deux lignes. + \hitem La fin... des haricots ! +\end{hlist} +Voici le texte qui suit la liste \repeatntimes{15}{bla bla bla } +\end{document}
\ No newline at end of file diff --git a/Master/texmf-dist/doc/generic/hlist/htest-tex.pdf b/Master/texmf-dist/doc/generic/hlist/htest-tex.pdf Binary files differnew file mode 100644 index 00000000000..471b4c661d4 --- /dev/null +++ b/Master/texmf-dist/doc/generic/hlist/htest-tex.pdf diff --git a/Master/texmf-dist/doc/generic/hlist/htest-tex.tex b/Master/texmf-dist/doc/generic/hlist/htest-tex.tex new file mode 100644 index 00000000000..e951d06290c --- /dev/null +++ b/Master/texmf-dist/doc/generic/hlist/htest-tex.tex @@ -0,0 +1,173 @@ +% !TeX encoding = ISO-8859-1 +% Ceci est le fichier de test (pdf)(Xe)(lua)tex de l'entension hlist +% +% Fichier compilé avec pdftex +\def\margin{2cm} +\hoffset\dimexpr \margin - 1in \relax +\voffset\dimexpr \margin - 1in \relax +\hsize\dimexpr 21cm - \margin*2 \relax +\vsize\dimexpr 29.7cm - \margin*2 \relax + +\input hlist.tex +\input color.tex + +\begingroup + \catcode`\_11 + \gdef\repeatntimes{\begingroup\def\temp{\endgroup}\repeatntimes_i} + \gdef\repeatntimes_i#1#2{% répète #1 fois le code #2 + \hlst_ifnum{#1>0 } + {\hlst_exparg{\def\temp}{\temp#2}% + \hlst_exparg\repeatntimes_i{\number\numexpr#1-1}{#2}% + } + \temp + } +\endgroup + +\def\verb{\expandafter\verbA\string} +\def\verbA#1{% + \begingroup + \def\verbB##1#1{\tt##1\endgroup}% + \def\do##1{\catcode`##112 }% + \catcode32 13 \begingroup\lccode`\~ 32 \lowercase{\endgroup\let~\space}% + \do\\\do\{\do\}\do\$\do\&\do\#\do\^\do\_\do\%\do\~% + \verbB +} + +\expandafter\newcount\csname c@section\endcsname +\def\section#1{% + \expandafter\advance\csname c@section\endcsname1 + \bigbreak\noindent + \begingroup\hlstsectionfont \the\csname c@section\endcsname\quad#1\endgroup + \smallbreak +} +\font\hlsttitlefont=ecbx2000 % titre +\font\hlstsectionfont=ecbx1400 % section +\font\hlsttextfont=ecrm1000 % texte + +\catcode`\;=13 \def;{\unskip\penalty10000 \ \string;}% caractères actifs de ponctuation française +\catcode`\:=13 \def:{\unskip\penalty10000 \ \string:} +\catcode`\!=13 \def!{\unskip\penalty10000 \ \string!} + +%%%%% DÉBUT DU DOCUMENT +\hlstdebugmodetrue +\hlsttextfont +\parindent1.5em +\begingroup + \hfill\hlsttitlefont Fichier de test \TeX\hfill\null\par +\endgroup + +\section{Test 1} +Voici le texte précédent \repeatntimes{15}{bla bla bla } +\hlist5 + \hitem \repeatntimes6{bla bla 1 } + \hitem \repeatntimes6{bla bla 2 } + \hitem \repeatntimes6{bla bla 3 } + \hitem \repeatntimes2{bla bla 4 } + \hitem \repeatntimes4{bla bla 5 } + \hitem \repeatntimes3{L2 L2 } + \hitem(3) \repeatntimes9{multicol 3 } + \hitem*(2) \repeatntimes5{retour ligne + multicol 2 } + \hitem> \repeatntimes5{multicol maximal } +\endhlist +Voici le texte qui suit la liste \repeatntimes{15}{bla bla bla } + +\section{Test 2} +Voici le texte précédent \repeatntimes{15}{bla bla bla } +\sethlist{% + left margin=\parindent, + label=\arabic{section}\alpha{hlisti}), + item offset=2.5em, + label width=*, + pre item=\begingroup\color, + post item=\endgroup, + autoindent} +\hlist3 + \hitem {blue}item bleu ! + \hitem {red}\repeatntimes3{bla bla en rouge } + \hitem {cyan}item cyan + \hitem>[LABEL PERSO] {magenta}\repeatntimes4{Long item sur toute la largeur } +\endhlist +\inithlist% retour aux valeur par défaut +Voici le texte qui suit la liste \repeatntimes{15}{bla bla bla } + +\section{Test 3} +Voici le texte précédent \repeatntimes{15}{bla bla bla } +\hlist[pre skip=0pt,post skip=0pt]4 + \hitem Item répété + \hitem Item répété + \hitem Item répété + \hitem Item répété + \hitem Item répété + \hitem Item répété +\endhlist +Voici le texte intermédiaire \repeatntimes{15}{bla bla bla } +\hlist[resume,pre skip=0pt,post skip=0pt]4 + \hitem Item répété + \hitem Item répété + \hitem Item répété + \hitem Item répété + \hitem Item répété + \hitem Item répété +\endhlist +Voici le texte qui suit la liste \repeatntimes{15}{bla bla bla } + +\section{Test 4} +\noindent +\vtop{\hsize=.5\hsize + Voici le texte précédent \repeatntimes{15}{bla bla bla } + \hlist[label=$\bullet$,label sep=.33em,label width=.75em, + label align=l,item offset=*,show frame]3 + \hitem Choix A + \hitem Choix B + \hitem Choix C + \hitem Choix D + \hitem Choix E + \endhlist +}\hfill\vrule\hfill +\vtop{\hsize=.4\hsize + Voici le texte précédent \repeatntimes{8}{bla bla bla } + \hlist[label=$\bullet$,label sep=.33em,label width=.75em, + label align=l,item offset=*]3 + \hitem Choix A + \hitem Choix B + \hitem Choix C + \hitem Choix D + \hitem Choix E + \endhlist +}% + +\section{test 5} +Sans objet, l'extension \verb|enumerate| n'est pas disponible pour \TeX. + +\section{Test 6} +Voici le texte précédent \repeatntimes{15}{bla bla bla } +\hlist[label sep=0.25em,label width=1.6em,item offset=*, + label=\arabic{section}\alpha{hlisti},col sep=1em,show frame]8 + \repeatntimes{26}{\hitem a\space eou}% +\endhlist +Voici le texte qui suit la liste \repeatntimes{15}{bla bla bla } + +\section{Test 7} +Voici le texte précédent \repeatntimes{15}{bla bla bla } +\hlist[item offset=\parindent,label width=1em,label sep=*,list parindent=\parindent]3 + \hitem Un premier item\par + Une autre ligne pour rien dire ! + \hitem Le \verb|verbatim| est permis avec l'extension \verb|hlist|, la preuve : <<~\verb|# 1\ $% ~|~>>. + \hitem Un troisième item pour le fun et pour remplir une ligne\par + Un autre paragraphe pour prendre deux lignes. + \hitem La fin... des haricots ! +\endhlist +Voici le texte qui suit la liste \repeatntimes{15}{bla bla bla } + +\section{Test 8} +Voici le texte précédent \repeatntimes{15}{bla bla bla } +\hlist[show label=false,show frame,col sep=3em,list parindent=\parindent]3 + \hitem Un premier item\par + Une autre ligne pour ne rien dire ! + \hitem Le \verb|verbatim| est permis dans les items avec l'extension \verb|hlist|, la preuve : <<~\verb|# 1\ $% ~|~>>. + \hitem Un troisième item pour remplir une ligne\par + Un deuxième paragraphe qui prend deux lignes. + \hitem La fin... des haricots ! +\endhlist +Voici le texte qui suit la liste \repeatntimes{15}{bla bla bla } +\bye
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/hlist/hlist.sty b/Master/texmf-dist/tex/generic/hlist/hlist.sty new file mode 100644 index 00000000000..71b2bb70f29 --- /dev/null +++ b/Master/texmf-dist/tex/generic/hlist/hlist.sty @@ -0,0 +1,6 @@ +% !TeX encoding = ISO-8859-1 +\input hlist.tex +\setKVdefault[hlist]{ + pre label = \bfseries,% code exécuté au début de la boite contenant le label +} +\endinput
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/hlist/hlist.tex b/Master/texmf-dist/tex/generic/hlist/hlist.tex new file mode 100644 index 00000000000..2afdd6ac529 --- /dev/null +++ b/Master/texmf-dist/tex/generic/hlist/hlist.tex @@ -0,0 +1,838 @@ +% !TeX encoding = ISO-8859-1 +% Ce fichier contient le code commenté de l'extension "hlist" +% +% IMPORTANT : pour que les commentaires s'affichent correctement, lire +% ce fichier avec l'encodage ISO-8859-1 +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +\def\hlstname {hlist} % +\def\hlstver {0.1} % +% % +\def\hlstdate {2017/05/01} % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% -------------------------------------------------------------------- +% 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 +% email: unbonpetit@openmailbox.org +% Commentaires, suggestions et signalement de bugs bienvenus ! +% Comments, bug reports and suggestions are welcome. +% -------------------------------------------------------------------- +% L'extension hlist est composée des 9 fichiers suivants : +% - code : hlist (.tex et .sty) +% - manuel en français : hlist-fr (.tex et .pdf) +% - fichiers de test : hlist-latex (.tex et .pdf) +% hlist-tex (.tex et .pdf) +% - fichier lisezmoi : README +% -------------------------------------------------------------------- + +\expandafter\edef\csname hlst_restorecatcode\endcsname{\catcode`\noexpand\_=\the\catcode`\_\relax} +\catcode`\_11 + +%################################################ +%########### macros de développement ############ +%################################################ +% Cette macro est équivalente à 0 et sert notamment à stopper le développement +% de \romannumeral +\chardef\hlst_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\hlst_quark{\hlst_quark} + +% Voici les macros habituelles de sélection d'arguments +\def\hlst_gobarg#1{} +\long\def\hlst_first#1#2{#1}\long\def\hlst_second#1#2{#2} +\long\def\hlst_firsttonil#1#2\_nil{#1} + +% Voici la macro pour 1-développer ou 2-développer le 2e argument (le 1er étant +% dépouillé des accolades) +% \hlst_exparg{<a>}{<b>} devient <a>{<b>} +% \hlst_eearg{<a>}{<b>} devient <a>{**<b>} +\long\def\hlst_exparg#1#2{\expandafter\hlst_exparg_i\expandafter{#2}{#1}}% +\long\def\hlst_eearg#1#2{\expandafter\expandafter\expandafter\hlst_exparg_i\expandafter\expandafter\expandafter{#2}{#1}}% +\long\def\hlst_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)% +% \hlst_expafter{<a>}{<b>} devient <a><*b> +\long\def\hlst_expafter#1#2{\expandafter\hlst_expafter_i\expandafter{#2}{#1}} +\long\def\hlst_expafter_i#1#2{#2#1} + +% Enfin, la macro pour former le nom du 2e argument (le 1er est dépouillé des +% accolades) +% \hlst_argcsname{<a>}{<b>} devient <a>\<b> +\def\hlst_argcsname#1#{\hlst_argcsname_i{#1}} +\def\hlst_argcsname_i#1#2{\hlst_expafter{#1}{\csname#2\endcsname}} + +%################################################ +%################ macros de test ################ +%################################################ +% Voici quelques macros à sélection d'arguments pour les tests +\def\hlst_ifnum#1{\ifnum#1\expandafter\hlst_first\else\expandafter\hlst_second\fi} +\def\hlst_ifcsname#1{\ifcsname#1\endcsname\expandafter\hlst_first\else\expandafter\hlst_second\fi} +\long\def\hlst_ifx#1{\ifx#1\expandafter\hlst_first\else\expandafter\hlst_second\fi} +\long\def\hlst_ifempty#1{\hlst_exparg\hlst_ifx{\expandafter\relax\detokenize{#1}\relax}} +\def\hlst_ifstar#1#2{\def\hlst_ifstar_i{\hlst_ifx{*\hlst_nxttok}{\hlst_first{#1}}{#2}}\futurelet\hlst_nxttok\hlst_ifstar_i} +\def\hlst_eaddtomacro#1#2{\hlst_exparg{\hlst_exparg{\def#1}}{\expandafter#1#2}} + +% Ici, une macro pour définir le token <espace> +\def\hlst_deftok#1#2{\let#1= #2\relax}\hlst_deftok\hlst_sptok{ } + +% Et une macro pour tester le prochain token +\def\hlst_ifnxttok#1#2#3{\hlst_deftok\hlst_toktotest{#1}\def\__truecode{#2}\def\__falsecode{#3}\hlst_ifnxttok_a} +\def\hlst_ifnxttok_a{\futurelet\_futurtok\hlst_ifnxttok_b} +\def\hlst_ifnxttok_b{% + \hlst_ifx{\_futurtok\hlst_sp} + {\afterassignment\hlst_ifnxttok_a\let\_futurtok= } + {\hlst_ifx{\_futurtok\hlst_toktotest}\__truecode\__falsecode}% +} + +% Ces macros sont utiles pour \hlst_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\hlst_ifspacefirst#1{\expandafter\hlst_ifspacefirst_i\detokenize{#10} \_nil} +\long\def\hlst_ifspacefirst_i#1 #2\_nil{\hlst_ifempty{#1}} +\expandafter\def\expandafter\hlst_gobspace\space{} +\def\hlst_removefirstspaces{\romannumeral\hlst_removefirstspaces_i} +\long\def\hlst_removefirstspaces_i#1{\hlst_ifspacefirst{#1}{\expandafter\hlst_removefirstspaces_i\expandafter{\hlst_gobspace#1}}{\hlst_stop#1}} +\begingroup + \catcode0 12 + \long\gdef\hlst_removelastspaces#1{\romannumeral\hlst_removelastspaces_i#1^^00 ^^00\_nil} + \long\gdef\hlst_removelastspaces_i#1 ^^00{\hlst_removelastspaces_ii#1^^00} + \long\gdef\hlst_removelastspaces_ii#1^^00#2\_nil{\hlst_ifspacefirst{#2}{\hlst_removelastspaces_i#1^^00 ^^00\_nil}{\hlst_stop#1}} +\endgroup +\long\def\hlst_removeextremespaces#1{% + \romannumeral\expandafter\expandafter\expandafter\hlst_removelastspaces\expandafter\expandafter\expandafter + {\expandafter\expandafter\expandafter\hlst_stop\hlst_removefirstspaces{#1}}% +} + +%################################################ +%############## système clé/valeur ############## +%################################################ +% Ceci est le booléen indiquant si la lecture de <clés>=<valeurs> définit les +% <clés> _par défaut_ ou qu'il s'agit d'une _redéfinition_ des <clés> déjà +% existantes +\newif\ifhlst_default + +% macros chapeau appelant la même macro avec le booléen préalablement défini +\def\setKVdefault{\hlst_defaulttrue\hlst_readKV} +\def\setKV{\hlst_defaultfalse\hlst_readKV} + +% L'argument obligatoire #1 est le nom du <trousseau> et #2 est l'ensemble +% des <clés>=<valeurs> +\def\hlst_readKV[#1]#2{% + \hlst_ifempty{#2} +% Si aucune <clés>=<valeurs> alors qu'on définit les <valeurs> par défaut, +% message d'erreur et on s'arrête là + {\ifhlst_default\errmessage{No key/val found, no default key/val defined}\fi} +% Sinon, initialiser à <vide> la macro \hlst_[<trousseau>] uniquement si on +% créé les <valeurs> par défaut + {\ifhlst_default\hlst_argcsname\let{hlst_[#1]}\empty\fi +% Puis on passe aux choses sérieuses, on va lire un par un tous les éléments +% <clé>=<valeur> (contenus dans #2) en mettant le quark comme dernier couple +% pour montrer la fin de la liste + \hlst_readKV_i[#1]#2,\hlst_quark,% + }% +} + +\def\hlst_readKV_i[#1]#2,{% +% #2 est le premier couple "<clé>=<valeur>" de la liste qui reste à traiter : +% tout d'abord, on se débarrasse des espaces extrêmes + \hlst_eearg{\def\__temp}{\hlst_removeextremespaces{#2}}% +% Si ce qui en résulte est égal au <quark>, + \hlst_ifx{\__temp\hlst_quark} +% alors, on a fini et on ne fait rien (fin du processus) + {} +% Sinon, si ce qui en résulte est vide (le couple "<clé>=<valeur>" était donc +% vide ou composé d'un espace) + {\hlst_ifx{\__temp\empty} +% On a fini et on ne fait rien (fin du processus) + {} +% dans le cas contraire, on va isoler la <clé> et la <valeur> du couple lu en +% prenant soin de mettre à la fin "=<quark>" pour se prémunir du cas où +% "<clé>=<valeur>" ne contient que la "<clé>" et pas de signe "=", ce qui +% ferait planter la macro à arguments délimités + {\expandafter\hlst_find_kv\__temp=\hlst_quark\_nil[#1]% + }% +% Lorsque la <clé> et la <valeur> est trouvée et stockée, recommencer et aller +% lire le prochain couple "<clé>=<valeur>" + \hlst_readKV_i[#1]% + }% +} + +% Voici la macro à arguments délimités à qui on a transmis +% <clé>=<valeur>=<quark> (si <clé>=<valeur> est l'élément lu) +% ou +% <clé>=<quark> (si <clé> est seule) +% et qui va isoler la <clé> de la <valeur>. +\def\hlst_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 <clé>, 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é "=<quark>". +% On élimine les espaces extrêmes pour obtenir la <clé> définitive stockée dans +% \__key (il faut 2-développer \hlst_removeextremespaces pour qu'elle donne son +% argument sans espace extrême) + \edef\__key{\detokenize\expandafter\expandafter\expandafter{\hlst_removeextremespaces{#1}}}% +% Pour la <valeur>, on lui ôte d'abord les espaces extrêmes + \hlst_eearg{\def\__val}{\hlst_removeextremespaces{#2}}% + \hlst_ifx{\__val\hlst_quark} +% Si elle est égale au <quark>, alors la <valeur> vaut "true" + {\def\__val{true}}% +% Sinon, ôter "=<quark>" 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 \hlst_find_val <valeur>=<quark>) + {\hlst_find_val#2}% +% Si on lit les <clés>=<valeurs> par défaut, + \ifhlst_default +% assigner à la macro "\hlst_[<trousseau>]_<clé>" la <valeur> trouvée + \hlst_argcsname\let{hlst_[#3]_\detokenize\expandafter{\__key}}\__val +% Puis ajouter à la macro "\hlst_[<trousseau>]", qui a été préalablement +% initialisée à <vide> : +% \def\hlst_[<trousseau>]_<clé>{<valeur>} + \hlst_argcsname\hlst_eaddtomacro{hlst_[#3]}% + {\expandafter\def\csname hlst_[#3]_\detokenize\expandafter{\__key}\expandafter\endcsname\expandafter{\__val}}% +% C'est selon ce hashage que sont enregistrés les couples <clé>/<valeur> : les +% <clés> sont contenues dans les noms des macros tandis que les <valeurs> sont +% les textes de remplacement de ces macros. +% C'est rapide et simple : +% a) pour trouver une <valeur> d'après sa <clé>, il suffit de développer la +% macro \hlst_[<trousseau>]_<clé> +% b) pour redéfinir une <clé>, il suffit de redéfinir cette macro avec la +% nouvelle <valeur> +% c) il est facile de vérifier qu'une <clé> 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) <clé> +% contenant une <valeur> donnée, mais cette limitation n'a pas grande +% importance ici (je ne sais pas si les autres systèmes de <clé>/<valeur> +% sont programmés de telle sorte que cela soit simple...) +% Bref, la macro "\hlst_[<trousseau>]" contient donc _toutes_ les définitions +% des macros définissant les <clés>/<valeurs> _par défaut_ et exécuter +% "\hlst_[<trousseau>]" remet donc toutes les <clés> à leur <valeur> par défaut. + \else +% Dans le cas où on _lit_ des nouvelles <valeurs> pour des <clés> + \hlst_ifcsname{hlst_[#3]_\__key} +% Si la <clé> existe (ssi la macro "\hlst_[<trousseau>]_<clé>" est définie), +% alors assigner la <valeur> à cette macro + {\hlst_argcsname\let{hlst_[#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 "<valeur>=<quark>" ne garde que <valeur>, en +% ôte les espaces extrêmes et stocke le résultat dans \__val +\def\hlst_find_val#1=\hlst_quark{\hlst_eearg{\def\__val}{\hlst_removeextremespaces{#1}}} + +% Cette macro remet toutes les <clés> à leur <valeurs> par défaut en exécutant +% la macro "\hlst_[<trousseau>]" +\def\useKVdefault[#1]{% + \hlst_ifcsname{hlst_[#1]} + {\csname hlst_[#1]\endcsname} +% Si la macro "\hlst_[<trousseau>]" n'existe pas, message d'erreur + {\errmessage{Undefined set of keys "#1"}}% +} + +% Cette macro donne la <valeur> correspondant à la <clé> contenue dans #2 +\def\useKV[#1]#2{% +% Avec \romannumeral, la <valeur> sera obtenue après _2_ développements de +% \useKV[<trousseau>]{<clé>} + \romannumeral\hlst_ifempty{#2} +% Si la <clé> est vide, message d'erreur (il ne peut y avoir de <valeur> +% associée à une <clé> vide) + {\hlst_stop\errmessage{Key name missing}} + {\hlst_ifcsname{hlst_[#1]_\hlst_removeextremespaces{#2}} +% Si la macro "\hlst_[<trousseau>]_<clé>" existe, 2-développer le \csname pour +% avoir la <valeur> + {\expandafter\expandafter\expandafter\hlst_stop\csname hlst_[#1]_\hlst_removeextremespaces{#2}\endcsname} +% Sinon, message d'erreur + {\hlst_stop\errmessage{Key "\hlst_removeextremespaces{#2}" not defined}}% + }% +} + +% Voici une macro purement développable qui teste si #2 (la <clé> du <trousseau> +% #1) est égale à "true" ou à "false" et selon l'issue, exécute le 1er ou 2e +% argument qui suit (arguments appelés <vrai> et <faux>) +\def\ifboolKV[#1]#2{% +% Cette macro donnera un des 2 arguments <vrai> ou <faux> en _2_ développements +% grâce au \romannumeral + \romannumeral\hlst_ifempty{#2} +% Si la <clé> est vide, message d'erreur + {\hlst_stop\errmessage{Key name missing}\hlst_second} + {\hlst_ifcsname{hlst_[#1]_\hlst_removeextremespaces{#2}} +% Si la <clé> débarrassée de ses espaces extrêmes existe, tester son contenu + {\hlst_eearg\ifboolKV_i{\csname hlst_[#1]_\hlst_removeextremespaces{#2}\endcsname}} +% Sinon, message d'erreur + {\hlst_stop\errmessage{Key "\hlst_removeextremespaces{#2}" not defined}\hlst_second}% + }% +} + +% Cette macro teste si #1, qui est une <valeur>, vaut "true" ou "false" +\def\ifboolKV_i#1{% +% Tester d'abord si elle vaut "true" + \hlst_ifargtrue{#1} + {\expandafter\hlst_stop\hlst_first} + {\hlst_ifargfalse{#1} +% Puis si elle vaut "false" + {\expandafter\hlst_stop\hlst_second} +% Si ni l'un ni l'autre, la <valeur> n'est pas un booléen acceptable + {\hlst_stop\errmessage{Value "#1" is not a valid boolean}\hlst_second}% + }% +} + +% La macro \hlst_ifargtrue{<argument>} teste de façon purement développable si +% <argument> vaut "true" ou "false". +% Pour cela, on transmet à \hlst_ifargtrue_i l'argument "<argument>true" qui est +% délimité par \_nil +\def\hlst_ifargtrue#1{\hlst_ifargtrue_i#1true\_nil} +% Dans la macro \hlst_ifargtrue_i, l'argument #1 est ce qui se trouve avant +% "true" dans "<argument>true" : +% - s'il n'est pas vide, sélectionner l'argument <faux> +% - s'il est vide, cela signifie que <argument> commence par "true" ; il est +% donc de la forme "true<autre>" +% L'argument #2 est ce qui se trouve après "true" dans "true<autre>true", +% c'est donc "<autre>true". +% Pour être sûr que <autre> est <vide>, on transmet "<autre>true" à +% \hlst_ifargtrue_ii qui teste si la réunion de ce qui est avant le +% premier "true" et ce qui est après est <vide> +\def\hlst_ifargtrue_i#1true#2\_nil{\hlst_ifempty{#1}{\hlst_ifargtrue_ii#2\_nil}\hlst_second} +\def\hlst_ifargtrue_ii#1true#2\_nil{\hlst_ifempty{#1#2}} + +% On procède de même pour tester "false" +\def\hlst_ifargfalse#1{\hlst_ifargfalse_i#1false\_nil} +\def\hlst_ifargfalse_i#1false#2\_nil{\hlst_ifempty{#1}{\hlst_ifargfalse_ii#2\_nil}\hlst_second} +\def\hlst_ifargfalse_ii#1false#2\_nil{\hlst_ifempty{#1#2}} + +%################################################ +%############### macros de hlist ############### +%################################################ +% Voici les registres utilisés : +% 1) le compteur d'imbrication, incrémenté de 1 à chaque nouvelle liste +% imbriquée : +\newcount\hlst_nest + +% 2) Le compteur des \items sur chaque ligne : +\newcount\hlst_colcnt + +% 3) La largeur des \hbox enfermant les <items> (un <item> est le <label> _et_ +% le <texte> de l'item) : +\newdimen\hlst_itemboxwidth + +% 4) L'espace entre chaque <item> : +\newdimen\hlst_colsep + +% 5) La largeur disponible pour loger une ligne d'<items> : +\newdimen\hlst_textwidth + +% 6) La profondeur maximale des \vtop rencontrées jusqu'alors dans une ligne : +\newdimen\hlst_maxdepth + +% 7) La profondeur du dernier élément de la \vtop la plus profonde de la ligne : +\newdimen\hlst_maxprevdepth + +% 8) La boite chapeau contenant l'<item> (<label> + <texte>) : +\newbox\hlst_currenthbox + +% 9) La boite contenant le <label> : +\newbox\hlst_labelbox + +%10) La boite contenant le <texte> +\newbox\hlst_textbox + +%11) Un booléen à fins de débogage et une dimension de débogage +% Il sera mis à faux après la phase de tests et supprimé dès +% la version 0.2 +\newif\ifhlstdebugmode\hlstdebugmodefalse +\newdimen\hlst_debugdim + +% La macro qui écrit les avertissement dans le fichier log de façon équivalente +% à \wlog : +\def\hlst_warning#1{\immediate\write-1 {Package hlist Warning: #1}} + +% Cette macro renvoie le 1er caractère détokénizé de la <valeur> obtenue par +% 2-développement de #1, de la forme \useKV[hlist]{<clé>} +\def\hlst_firstcarof#1{\expandafter\hlst_firsttonil\detokenize\expandafter\expandafter\expandafter{#1}\_nil} + +% Cette macro évalue la dimension contenue dans la <valeur> d'une <clé> +% passée dans l'argument #1 et l'assigne à la <valeur> de cette <clé> +\def\hlst_evaldim#1{% +% On n'évalue que si la <valeur> ne commence pas par "*" qui est réservé + \if\string*\hlst_firstcarof{\useKV[\hlstname]{#1}*}\else + \expandafter\edef\csname hlst_[\hlstname]_\detokenize{#1}\endcsname{\the\dimexpr\useKV[\hlstname]{#1}\relax}% + \fi +} + +% Même principe pour les ressorts +\def\hlst_evalskip#1{\expandafter\edef\csname hlst_[\hlstname]_\detokenize{#1}\endcsname{\the\glueexpr\useKV[\hlstname]{#1}\relax}} + +% Voici la macro par qui tout commence; elle peut être appelée par \hlist façon TeX +% ou par \begin{hlist} façon LaTeX. +% On teste d'abord si elle dispose d'un argument optionnel qui serait les +% <clé>=<valeur> applicables à cette liste +\def\hlist{\begingroup\hlst_ifnxttok[{\hlist_i}{\hlist_i[]}} +\def\hlist_i[#1]{% +% Si les <clé>=<valeur> ne sont pas vide, les définir dans le groupe semi simple +% qui vient d'être ouvert + \hlst_ifempty{#1}{}{\sethlist{#1}}% +% Fixer les dimensions et les ressorts + \hlst_evaldim{list parindent}\hlst_evaldim{item sep}\hlst_evaldim{left margin}\hlst_evaldim{col sep}% + \hlst_evaldim{item offset}\hlst_evaldim{label sep}\hlst_evalskip{pre skip}\hlst_evalskip{post skip}% +% Ensuite, lire un /entier/ et stocker dans \hlst_colcnt le nombre de colonnes voulu + \afterassignment\hlist_ii\hlst_colcnt= +} + +\def\hlist_ii{% +% Incrémenter le compteur d'imbrications + \global\advance\hlst_nest 1 +% Si le compteur de label correspondant à cette imbrication existe, + \hlst_ifcsname{c@hlist\romannumeral\hlst_nest} +% l'initialiser sauf si la <clé> "resume" vaut "true" + {\ifboolKV[\hlstname]{resume}{}{\csname c@hlist\romannumeral\hlst_nest\endcsname\hlst_stop}} +% S'il n'existe pas, le créer (attention, \newcount est \outer)! + {\csname newcount\expandafter\endcsname\csname c@hlist\romannumeral\hlst_nest\endcsname}% + \hlst_ifnum{\hlst_colcnt<1 } +% Envisager le cas où le nombre de colonnes demandé est < 1 et message d'erreur + {\errmessage{Invalid column number "\the\hlst_colcnt", 1 column used instead}\def\hlst_nbcol{1}} +% La macro \hlst_nbcol contient finalement le nombre de colonnes + {\edef\hlst_nbcol{\the\hlst_colcnt}}% +% Si on doit afficher les labels + \ifboolKV[\hlstname]{show label} +% Calculer combien de dimensions explicites sont demandées par l'utilisateur + {\edef\hlst_implicitdim{\the\numexpr + \if\string*\hlst_firstcarof{\useKV[\hlstname]{item offset}*}1\else0\fi+ + \if\string*\hlst_firstcarof{\useKV[\hlstname]{label width}*}1\else0\fi+ + \if\string*\hlst_firstcarof{\useKV[\hlstname]{label sep}*}1\else0\fi\relax + }% +% Si ce nombre est au moins 1 + \ifnum\hlst_implicitdim>0 + \hlst_ifnum{\hlst_implicitdim>1 } +% S'il est plus grand que 1, message d'erreur car parmi les 3 dimensions, _une_ +% seule peut être implicite + {\errmessage{Too many implicit dimensions for labels, default settings used instead}% + \sethlist{item offset=1.5em,label sep=0.25em,label width=1.25em}% + } +% Si ce nombre est égal à 1, calculer la dimension implicite en fonction des 2 +% autres dimensions explicites... + {\if\string*\hlst_firstcarof{\useKV[\hlstname]{item offset}*}% + \edef\hlst_implicitdim{[\hlstname]{item offset=\the\dimexpr\useKV[\hlstname]{label sep}+\useKV[\hlstname]{label width}\relax}}% + \else\if\string*\hlst_firstcarof{\useKV[\hlstname]{label sep}*}% + \edef\hlst_implicitdim{[\hlstname]{label sep=\the\dimexpr\useKV[\hlstname]{item offset}-\useKV[\hlstname]{label width}\relax}}% + \else\if\string*\hlst_firstcarof{\useKV[\hlstname]{label width}*}% + \edef\hlst_implicitdim{[\hlstname]{label width=\the\dimexpr\useKV[\hlstname]{item offset}-\useKV[\hlstname]{label sep}\relax}}% + \fi\fi\fi +% ...et la sauvegarder dans le <trousseau> "hlist" via la <clé> correspondante + \expandafter\setKV\hlst_implicitdim + }% + \fi +% Vérifier que "item offset" >= label sep + label width et dans le cas +% contraire, avertir + \ifdim\useKV[\hlstname]{item offset}<\dimexpr\useKV[\hlstname]{label sep}+\useKV[\hlstname]{label width}\relax + \hlst_warning{incompatibles dimensions: item offset (\the\dimexpr\useKV[\hlstname]{item offset}\relax) < label sep (\the\dimexpr\useKV[\hlstname]{label sep}\relax) + label width (\the\dimexpr\useKV[\hlstname]{label width}\relax)}% + \fi + } + {}% +% Si l'imbrication est 1, on est donc dans la hlist de plus haut niveau + \ifnum\hlst_nest=1 % si liste mère +% Régler la parindent à la <valeur> de la <clé> "left margin" + \parindent\dimexpr\useKV[\hlstname]{left margin}\relax +% et insérer le ressort "pre skip" + \ifhmode\par\fi\vskip\useKV[\hlstname]{pre skip}% + \else +% Sinon, pas d'indentation pour les listes imbriquées + \parindent0pt + \fi +% Sauvegarder la largeur actuelle horizontale + \hlst_textwidth=\dimexpr\ifdefined\linewidth\linewidth\else\hsize\fi-\parindent\relax +% Informations de débogage sur les dimensions des composants + \ifhlstdebugmode + \message{*** hlist mode debug : largeur = \the\hlst_textwidth}% + \hlst_debugdim=0pt \def\hlst_debuglineno{0}% + \edef\hlst_debuglineno{\number\numexpr\hlst_debuglineno+1}% + \def\debuginfoB{\space\space Ligne d'items no \hlst_debuglineno\space:^^J}% + \fi + \leavevmode +% Initialiser le compteur de colonnes \hlst_colcnt à 0 + \hlst_colcnt0 +% Sauvegarder dans \hlst_colsep la <valeur> de la <clé> "col sep" + \hlst_colsep\useKV[\hlstname]{col sep}\relax +% Au début de la liste : pas de multicolonne + \def\hlst_askedmulticol{1}% +% Calculer la largeur de chaque <item> (=<label>+<texte>) s'il est non multicol + \edef\hlst_colwidth{\the\dimexpr(\hlst_textwidth-\useKV[\hlstname]{col sep}*(\hlst_nbcol-1))/(\hlst_nbcol)}% +% Collecter dans une boite tout ce qui se trouve jusqu'au premier \hitem +% (neutraliser l'espace, le tab et le retour charriot) + \setbox0\hbox\bgroup\catcode`\^^I 9 \catcode`\^^M 9 \catcode32 9 +} + +% Voici maintenant la macro qui ferme l'environnement. Elle aussi peut être +% à la TeX par \endhlist ou par \end{hlist} comme on le fait en LaTeX. +\def\endhlist{% +% En premier lieu, il faut exécuter la routine qui achève un \hitem (fermeture +% des boites, calcul de la \vtop la plus profonde et de son \prevdepth, etc) + \hlst_enditem +% Débogage + \ifhlstdebugmode + \message{\debuginfoB\space\space\space\space TOTAL = \the\hlst_debugdim/\the\hlst_textwidth^^J + \space\space\space\space Depassement = \number\numexpr\hlst_debugdim-\hlst_textwidth\relax sp^^J + *** Fin de la liste^^J^^J}% + \ifnum\numexpr\hlst_debugdim-\hlst_textwidth\relax>4 \errmessage{Depassement !}\fi + \fi +% Si la liste est non imbriquée, insérer le ressort "post skip" + \ifnum\hlst_nest=1 \vskip\useKV[\hlstname]{post skip}\fi +% Décrémenter le compteur d'imbrications + \global\advance\hlst_nest -1 +% Fermer le groupe semi simple ouvert avec \hlist et manger les espaces + \endgroup + \ignorespaces +} + +% Voici à présent des macros traduisant un <nombre> en un <label>. +% La première, qui est appelée par toutes les autres, converti le <nombre> en un +% nombre arabe. +\def\hlst_arabic#1{% +% Si le compteur (au modèle latex, c'est-à-dire "\c@<nom>") existe + \hlst_ifcsname{c@\detokenize{#1}} +% Donner le nombre arabe avec \number, sinon, message d'erreur + {\number\csname c@\detokenize{#1}\endcsname} + {\errmessage{Unkonwn counter named "\detokenize{#1}"}}% +} +% Ensuite, ces macros convertissent un <nombre> en nombre romain ou en lettre, +% avec choix de la casse +\def\hlst_roman#1{\romannumeral\hlst_arabic{#1}\relax} +\def\hlst_Roman#1{\uppercase\expandafter\expandafter\expandafter{\hlst_roman{#1}}} +\def\hlst_alpha#1{\ifcase\hlst_arabic{#1}\relax\or a\or b\or c\or d\or e\or f\or g\or h\or i\or j\or + k\or l\or m\or n\or o\or p\or q\or r\or s\or t\or u\or v\or w\or x\or + y\or z\else\errmessage{No letter for a value of \number\numexpr#1\relax}\fi} +\def\hlst_Alpha#1{\ifcase\hlst_arabic{#1}\relax\or A\or B\or C\or D\or E\or F\or G\or H\or I\or J\or + K\or L\or M\or N\or O\or P\or Q\or R\or S\or T\or U\or V\or W\or X\or + Y\or Z\else\errmessage{No letter for a value of \number\numexpr#1\relax}\fi} + +% Voici maintenant la macro \hitem, qui marque le début d'un nouvel <item> +% Tout d'abord, on s'intéresse à ce qui suit, c'est-à-dire aux argument +% optionnels. +% On teste si elle est suivie d'une "*" (qui commande un retour à la ligne pour +% cet item) et on transmet le token 0 ou 1 selon l'issue du test +\def\hitem{\hlst_ifstar{\hlst_hitem_grabopts1}{\hlst_hitem_grabopts0}} + +% Ensuite, on teste si elle est suivie de ">" (qui commande un multicol maximal +% pour cet item) et on transmet le token 0 ou 1 selon l'issue du test +\def\hlst_hitem_grabopts#1{\hlst_ifnxttok>{\hlst_first{\hlst_hitem_grabopts_i#11}}{\hlst_hitem_grabopts_i#10}} + +% La macro \hlst_hitem_grabopts_i reçoit les 2 premiers arguments concernant la +% présence ou pas de "*" et de ">" ; ces 2 tokens seront transmis de proche en +% proche jusqu'à la la macro \hitem_ii qui est la macro qui fait le boulot. +\def\hlst_hitem_grabopts_i#1#2{% +% On teste si une parenthèse (pour demander un multicol) est le prochain token + \hlst_ifnxttok( +% Si oui, aller lire ce qui est à l'intérieur avec \hlst_hitem_grabopts_ii + {\hlst_hitem_grabopts_ii#1#2} +% Sinon, on teste si un crochet (pour forcer un label pour cet item) est le +% prochain token + {\hlst_ifnxttok[ +% Si oui, aller lire ce qu'il contient + {\hlst_hitem_grabopts_iii#1#2} +% Si ni parenthèse ni crochet, transmettre "()[<quark>]" à \hitem_i + {\hitem_i#1#2()[\hlst_quark]}% + }% +} + +% Ici, une parenthèse a été lue en premier, tester si la suite est un crochet +\def\hlst_hitem_grabopts_ii#1#2(#3){\hlst_ifnxttok[{\hitem_i#1#2(#3)}{\hitem_i#1#2(#3)[\hlst_quark]}} + +% Ici, un crochet a été lu en premier, tester si la suite est une parenthèse +\def\hlst_hitem_grabopts_iii#1#2[#3]{\hlst_ifnxttok({\hlst_hitem_grabopts_iv#1#2[#3]}{\hitem_i#1#2()[#3]}} + +% Au cas où le crochet est lu en premier, remettre les argument optionnels dans +% le bon ordre : parenthèse _puis_ crochet +\def\hlst_hitem_grabopts_iv#1#2[#3](#4){\hitem_i#1#2(#4)[#3]} + +% Cette macro mange tous les espaces _explicites_ qui se trouvent éventuellement +% après les arguments optionnels +% Pour résumer, \hitem peut être suivi de "*" _puis_ ">" (ordre imposé) +% Ensuite on peut trouver (<multicol>) et/ou [<label>] dans n'importe quel ordre +\def\hitem_i#1#2(#3)[#4]{% + \hlst_ifnxttok\hlst_sptok + {\def\__temp{\hitem_i#1#2(#3)[#4]}\expandafter\__temp\hlst_gobspace} + {\hitem_ii#1#2(#3)[#4]}% +} + +% Voici la /vraie/ macro qui va faire le boulot et ses arguments : +% - #1 et #2 valent 0 ou 1 selon la présence de "*" et ">" +% - #3 est le nombre de multicolonnes demandé (si vide, comprendre 1) +% - #4 est le label demandé (si <quark>, comprendre absence d'argument +% optionnel) +\def\hitem_ii#1#2(#3)[#4]{% +% si ce n'est _pas_ le 1er de la liste + \hlst_ifnum{\hlst_colcnt>0 } +% Exécuter la routine de fin d'item + {\hlst_enditem + } +% Sinon, fermer la boite ouverte par \hlist + {\egroup +% Si toutes ses dimensions ne sont pas nulles, message d'erreur + \ifnum0\ifnum\wd0=0 1\fi\ifnum\dp0=0 1\fi\ifnum\ht0=0 1\fi<111 + \errmessage{\string\hitem\space expected}% + \fi +% comme il s'agit du 1er item de la liste, initialiser les profondeurs + \hlst_maxdepth0pt \hlst_maxprevdepth0pt + }% +% Incrémenter le compteur de label associé à cette imbrication + \hlst_argcsname\global\advance{c@hlist\romannumeral\hlst_nest} 1 +% Incrémenter le compteur de colonnes du nombre de colonnes sautées précédemment + \advance\hlst_colcnt\hlst_askedmulticol\relax +% Si "*", mettre le compteur de colonnes au maximum pour forcer retour à la +% ligne + \ifnum#1=1 \hlst_colcnt\numexpr\hlst_nbcol+1\relax\fi + \ifnum\hlst_colcnt>1 +% Si ce n'est pas le 1er item de la liste + \hlst_ifnum{\hlst_colcnt=\numexpr\hlst_nbcol+1\relax} +% Si le nombre d'item sur la ligne a atteint son maximum, +% former le paragraphe, sauter l'espace verticale "item sep" + {\par\vskip\useKV[\hlstname]{item sep}\relax +% Débogage + \ifhlstdebugmode + \message{\debuginfoB\space\space\space\space TOTAL = \the\hlst_debugdim/\the\hlst_textwidth^^J + \space\space\space\space Depassement = \number\numexpr\hlst_debugdim-\hlst_textwidth\relax sp^^J}% + \ifnum\numexpr\hlst_debugdim-\hlst_textwidth\relax>\hlst_colcnt \errmessage{Depassement !}\fi% dépassement si plus que <nb colonnes>sp + \edef\hlst_debuglineno{\number\numexpr\hlst_debuglineno+1}% + \def\debuginfoB{\space\space Ligne d'items no \hlst_debuglineno\space:^^J}% + \hlst_debugdim0pt + \fi +% Tromper TeX : ne pas tenir compte des profondeurs des \vtop, mais utiliser la +% profondeur du dernier élément de la \vtop la plus profonde + \prevdepth\hlst_maxprevdepth +% Passer en mode horizontal, initialiser les variables pour commencer une +% nouvelle ligne d'items + \leavevmode + \hlst_maxdepth0pt \hlst_maxprevdepth0pt \hlst_colcnt=1 + } +% S'il reste des items à loger sur la ligne, insérer espace inter-item + {\kern\hlst_colsep\relax +% Débogage + \ifhlstdebugmode + \edef\debuginfoB{\debuginfoB\space\space\space\space colsep (\the\hlst_colsep)^^J}% + \advance\hlst_debugdim\hlst_colsep + \fi + }% + \fi +% Calculer le nombre de multicolonne pour l'item courant + \edef\hlst_askedmulticol{\number\numexpr + \hlst_ifnum{#2=1 } +% Si ">", prendre le maximum disponible + {\hlst_nbcol+1-\hlst_colcnt} +% Sinon, prendre l'argument #3 (s'il est vide ce qui correspond à une absence +% d'argument optionnel, prendre 1) + {\hlst_ifempty{#3}{1}{(#3)}}% + \relax}% + \hlst_ifnum{\hlst_askedmulticol<1 } +% Si l'utilisateur est un joueur ou un abruti ! + {\errmessage{Invalid multicol "(#3)", "(1)" used instead}\def\hlst_askedmulticol{1}} +% Si trop de multicol demandé + {\hlst_ifnum{\numexpr\hlst_colcnt+\hlst_askedmulticol-1\relax>\hlst_nbcol\relax} +% Prendre le maximum et avertir + {\edef\hlst_askedmulticol{\number\numexpr\hlst_nbcol+1-\hlst_colcnt\relax}% + \hlst_warning{too much multicol (#3) asked, (\hlst_askedmulticol) used instead}}% + {}% + }% +% Calculer la largeur de la \hbox contenant l'<items> + \hlst_itemboxwidth\dimexpr\hlst_colwidth*\hlst_askedmulticol+\useKV[\hlstname]{col sep}*(\hlst_askedmulticol-1)\relax +% Définir la boite contenant <label> + <texte> + \setbox\hlst_currenthbox\hbox to \hlst_itemboxwidth\bgroup +% Initialiser le débordement du <label> + \xdef\hlst_labeloverwidth{0pt}% +% Si on affiche les labels ET si #4 n'est pas vide (un label explicitement +% demandé "[]" doit être compris comme "ne pas afficher de label du tout pour +% cet item"). + \hlst_ifnum{\ifboolKV[\hlstname]{show label}10\hlst_ifempty{#4}01=11 }% +% Ouvrir la boite des labels + {\hbox to \useKV[\hlstname]{item offset}{% +% Pousser à droite au cas où "item offset">"label sep"+"label width" + \hfill +% Ouvrir la \hbox contenant le label et forcer sa dimension horizontale à la +% <valeur> "label width" + \hbox to \useKV[\hlstname]{label width}{% +% Trouver la première lettre de la <valeur> "label align", sachant qu'une +% consigne vide sera comprise comme un alignement "l" + \edef\hlst_align{\hlst_firstcarof{\useKV[\hlstname]{label align}l}}% +% Pousser à droite si cette lettre est "r" ou "c" + \if \string r\hlst_align\hfill + \else\if \string c\hlst_align\hfill + \fi\fi +% Localement, (re)définir les macros de formatage pour le label afin qu'elles +% deviennent accessible à l'utilisateur + \let\arabic\hlst_arabic\let\roman\hlst_roman\let\Roman\hlst_Roman\let\alpha\hlst_alpha\let\Alpha\hlst_Alpha +% Mettre dans la boite \hlst_labelbox tout ce qui concerne le label (les codes +% avant/après et le label formaté selon la <valeur> "label") + \setbox\hlst_labelbox\hbox{% + \useKV[\hlstname]{pre label}% + \hlst_ifx{\hlst_quark#4}{\useKV[\hlstname]{label}}{#4}% + \useKV[\hlstname]{post label}% + }% +% Mesurer le dépassement (signé) du label par rapport à sa dimension autorisée +% "label width" + \xdef\hlst_labeloverwidth{\the\dimexpr\wd\hlst_labelbox-\useKV[\hlstname]{label width}\relax}% +% Afficher la boite contenant le label avec ou sans cadre + \ifboolKV[\hlstname]{show frame} + {\fboxrule.4pt \fboxsep-\fboxrule \fbox{\box\hlst_labelbox}} + {\box\hlst_labelbox}% +% Si on gère le dépassement de largeur + \ifboolKV[\hlstname]{autoindent} +% Mettre le ressort \hss pour neutraliser l'avertissement de "overful hbox" + {\ifdim\hlst_labeloverwidth>0pt \hss\fi} + {}% +% Pousser à gauche si l'alignement demandé est "l" ou "c" + \if \string l\hlst_align\hfill + \else\if \string c\hlst_align\hfill + \fi\fi + }% +% Séparation horizontale entre boite de <label> et boite de <texte> + \kern\useKV[\hlstname]{label sep}\relax + }% +% Diminuer la largeur disponible de la largeur de la boite de <label>, soit la +% <valeur> "item offset" + \advance\hlst_itemboxwidth-\useKV[\hlstname]{item offset}\relax + } + {}% +% Maintenant que la boite du <label> est affichée (ou pas si c'est le choix de +% l'utilisateur), il faut passer à la boite qui contient le <texte> du label. +% Bien entendu, on utilise des accolades _implicites_ puisque la fin de la boite +% ne se situe pas dans cette macro. +% Cette boite sera une \vtop... + \setbox\hlst_textbox\vtop\bgroup +% ...de largeur \hlst_itemboxwidth... + \hsize\hlst_itemboxwidth +% ...que l'on copie vers \linewidth pour les utilisateurs de LaTeX, afin que +% cette macro garde sa cohérence + \ifdefined\linewidth\linewidth\hlst_itemboxwidth\fi\relax +% Réglage du parindent à "list parindent" + \parindent\useKV[\hlstname]{list parindent}\relax +% Passage en mode H et pas d'indentation pour le 1er paragraphe si on +% affiche les labels + \ifboolKV[\hlstname]{show label}\noindent\indent +% Après être passé en mode horizontal, on insère l'indentation supplémentaire en +% cas de débordement de la largeur du <label> + \ifboolKV[\hlstname]{autoindent} + {\ifdim\hlst_labeloverwidth>0pt \kern\hlst_labeloverwidth\fi} + {}% +% Puis, on exécute le code inséré juste avant le <texte> de l'item + \useKV[\hlstname]{pre item}% +} +% __________________________________________ +% | | +% | <texte> de l'item entre ces 2 macros | +% |__________________________________________| +% +% Une fois que le <texte> de l'item est /librement/ composé (librement, cela +% autorise les changements de catcode, le "verbatim", etc), la macro de fin du +% <texte> est exécutée. +\def\hlst_enditem{% +% D'abord, exécuter le code de fin d'item + \useKV[\hlstname]{post item}% +% Ensuite, former le paragraphe pour accéder à \prevdepth + \par +% et développer "\the\prevdepth" _avant_ de fermer la \vtop et la \hbox (le +% double \egroup) pour que cette dimension soit le texte de remplacement de +% \hlst_currentdepth + \hlst_exparg{% +% fermeture de la \vtop + \egroup + \ifboolKV[\hlstname]{show frame}{\fboxrule.4pt \fboxsep-.4pt \fbox{\box\hlst_textbox}}{\box\hlst_textbox}% + \egroup + \def\hlst_currentdepth}{\the\prevdepth}% +% Si la profondeur de la \vtop qui vient d?être créé est supérieure à toutes +% celles rencontrées dans cette ligne, + \ifdim\dp\hlst_currenthbox>\hlst_maxdepth +% retenir la valeur de \prevdepth + \hlst_maxprevdepth\hlst_currentdepth\relax +% et mettre à jour la profondeur maximale des \vtop de la ligne en cours. +% Le but de cette manoeuvre est de trouver la profondeur du dernier élément de +% la plus profonde \vtop de la ligne en cours. +% Cette valeur de \prevdepth sera utilisée au prochain \par pour tromper +% TeX qui sinon, prendrait en compte la /grande/ profondeur des \vtop, menant à +% des lignes trop proches. + \hlst_maxdepth\dp\hlst_currenthbox + \fi +% Une fois tout ceci fait, afficher la boite contenant le <texte> + \box\hlst_currenthbox +% Débogage + \ifhlstdebugmode + \edef\debuginfoB{\debuginfoB\space\space\space\space item (\the\hlst_itemboxwidth)^^J}% + \advance\hlst_debugdim\hlst_itemboxwidth + \fi +}% + +\hlst_restorecatcode +% Création, si nécessaire d'une macro \fbox, équivalente à celle de LaTeX +\unless\ifdefined\fbox +% Prendre les réglages par défaut identiques à ceux de laTeX + \newdimen\fboxrule \newdimen\fboxsep \fboxrule=.4pt \fboxsep=3pt +% Pour les explications, voir codes 251 \`a 254 de ce fichier : +% http://progtex.fr/wp-content/uploads/2014/09/code.txt +% et pages 271 \`a 274 de "Apprendre à programmer en TeX" + \def\fbox#1{% + \hbox{% + \vrule width\fboxrule + \vtop{% + \vbox{\hrule height\fboxrule \kern\fboxsep \hbox{\kern\fboxsep#1\kern\fboxsep}}% + \kern\fboxsep \hrule height\fboxrule + }\vrule width\fboxrule + }% + } +\fi + +% Les réglages par défaut (modifiables avec \setdefaulthlist) +\setKVdefault[\hlstname]{ + pre skip = \medskipamount,% ressort vertical avant la liste mère + post skip = \medskipamount,% ressort vertical après la liste mère + left margin = 0pt,% décalage à droite des premières boites de chaque ligne de la liste mère + col sep = 2.5em,% espace de séparation entre colonnes + item offset = 1.75em,% distance entre bord gauche du label et bord gauche de l'item + label sep = 0.25em,% recul du label + label width = *,% largeur du label automatique (=1.75-0.25 em) car "item ofset" = "label width" + "label sep" + label align = left,% consigne d'alignement + show label = true,% afficher les numérotations et tenir compte de leur largeur + pre label = \bf,% code exécuté au début de la boite contenant le label + label = \arabic{hlisti}.,% code du label + post label = {},% code exécuté après le label + item sep = 0pt,% espace vertical supplémentaire entre lignes d'items + list parindent= 0pt,% indentation des paragraphes des items (sauf le 1er) + pre item = {},% code exécuté avant le texte de l'item + post item = {},% code exécuté après le texte de l'item + resume = false,% pas de reprise de numérotation + autoindent = false,% pas d'indentation auto en cas de label trop large + show frame = false% ne pas afficher les cadres autour des boites <label> et <texte> +} + +% La macro \inithlist remet toutes les <clés> à leur <valeur> par défaut +\expandafter\let\expandafter\inithlist\csname hlst_[\hlstname]\endcsname + +% Macros permettant de modifier les <valeurs> des <clés> de hlist... +\def\sethlist#{\setKV[\hlstname]} + +% ... ainsi que les <valeurs> par défaut +\def\setdefaulthlist#{\setKVdefault[\hlstname]} +\endinput + +Versions : + _____________________________________________________________________________ +| Version | Date | Changements | +|-----------------------------------------------------------------------------| +| 0.1 | 01/05/2017 | Première version | +|-----------------------------------------------------------------------------| |