From 4b5f083d84e14a50598792a1035cc601ed39baa9 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Tue, 2 May 2017 21:44:16 +0000 Subject: hlist (2may17) git-svn-id: svn://tug.org/texlive/trunk@44158 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/tex/generic/hlist/hlist.sty | 6 + Master/texmf-dist/tex/generic/hlist/hlist.tex | 838 ++++++++++++++++++++++++++ 2 files changed, 844 insertions(+) create mode 100644 Master/texmf-dist/tex/generic/hlist/hlist.sty create mode 100644 Master/texmf-dist/tex/generic/hlist/hlist.tex (limited to 'Master/texmf-dist/tex/generic/hlist') 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{}{} devient {} +% \hlst_eearg{}{} devient {**} +\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{}{} devient <*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{}{} devient \ +\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 +\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 = définit les +% _par défaut_ ou qu'il s'agit d'une _redéfinition_ des 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 et #2 est l'ensemble +% des = +\def\hlst_readKV[#1]#2{% + \hlst_ifempty{#2} +% Si aucune = alors qu'on définit les 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 à la macro \hlst_[] uniquement si on +% créé les 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 +% = (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 "=" 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 , + \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 "=" é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 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\hlst_find_kv\__temp=\hlst_quark\_nil[#1]% + }% +% Lorsque la et la est trouvée et stockée, recommencer et aller +% lire le prochain couple "=" + \hlst_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\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 , 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 \hlst_removeextremespaces pour qu'elle donne son +% argument sans espace extrême) + \edef\__key{\detokenize\expandafter\expandafter\expandafter{\hlst_removeextremespaces{#1}}}% +% Pour la , 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 , 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 \hlst_find_val =) + {\hlst_find_val#2}% +% Si on lit les = par défaut, + \ifhlst_default +% assigner à la macro "\hlst_[]_" la trouvée + \hlst_argcsname\let{hlst_[#3]_\detokenize\expandafter{\__key}}\__val +% Puis ajouter à la macro "\hlst_[]", qui a été préalablement +% initialisée à : +% \def\hlst_[]_{} + \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 / : 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 \hlst_[]_ +% 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 "\hlst_[]" contient donc _toutes_ les définitions +% des macros définissant les / _par défaut_ et exécuter +% "\hlst_[]" remet donc toutes les à leur par défaut. + \else +% Dans le cas où on _lit_ des nouvelles pour des + \hlst_ifcsname{hlst_[#3]_\__key} +% Si la existe (ssi la macro "\hlst_[]_" est définie), +% alors assigner la à 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 "=" ne garde que , 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 à leur par défaut en exécutant +% la macro "\hlst_[]" +\def\useKVdefault[#1]{% + \hlst_ifcsname{hlst_[#1]} + {\csname hlst_[#1]\endcsname} +% Si la macro "\hlst_[]" 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\hlst_ifempty{#2} +% Si la est vide, message d'erreur (il ne peut y avoir de +% associée à une vide) + {\hlst_stop\errmessage{Key name missing}} + {\hlst_ifcsname{hlst_[#1]_\hlst_removeextremespaces{#2}} +% Si la macro "\hlst_[]_" existe, 2-développer le \csname pour +% avoir la + {\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 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\hlst_ifempty{#2} +% Si la est vide, message d'erreur + {\hlst_stop\errmessage{Key name missing}\hlst_second} + {\hlst_ifcsname{hlst_[#1]_\hlst_removeextremespaces{#2}} +% Si la 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 , 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 n'est pas un booléen acceptable + {\hlst_stop\errmessage{Value "#1" is not a valid boolean}\hlst_second}% + }% +} + +% La macro \hlst_ifargtrue{} teste de façon purement développable si +% vaut "true" ou "false". +% Pour cela, on transmet à \hlst_ifargtrue_i l'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 "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" à +% \hlst_ifargtrue_ii qui teste si la réunion de ce qui est avant le +% premier "true" et ce qui est après est +\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 (un est le