texlive[49044] Master/texmf-dist: listofitems (1nov18)

commits+karl at tug.org commits+karl at tug.org
Thu Nov 1 23:08:53 CET 2018


Revision: 49044
          http://tug.org/svn/texlive?view=revision&revision=49044
Author:   karl
Date:     2018-11-01 23:08:53 +0100 (Thu, 01 Nov 2018)
Log Message:
-----------
listofitems (1nov18)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/generic/listofitems/README
    trunk/Master/texmf-dist/doc/generic/listofitems/listofitems-en.pdf
    trunk/Master/texmf-dist/doc/generic/listofitems/listofitems-en.tex
    trunk/Master/texmf-dist/doc/generic/listofitems/listofitems-fr.pdf
    trunk/Master/texmf-dist/doc/generic/listofitems/listofitems-fr.tex
    trunk/Master/texmf-dist/tex/generic/listofitems/listofitems.tex

Modified: trunk/Master/texmf-dist/doc/generic/listofitems/README
===================================================================
--- trunk/Master/texmf-dist/doc/generic/listofitems/README	2018-11-01 22:08:42 UTC (rev 49043)
+++ trunk/Master/texmf-dist/doc/generic/listofitems/README	2018-11-01 22:08:53 UTC (rev 49044)
@@ -4,9 +4,9 @@
              listofitems
                package
                
-                v1.53
+                v1.6
 
-             13/03/2018
+             01/11/2018
 ___________________________________
 
 Authors   : Christian Tellechea, Steven B. Segletes
@@ -27,4 +27,4 @@
 
 This package allows one to capture all the items of a list, for which
 the parsing character has been selected by the user, and to access any
-of these items with a simple syntax.
+of these items with a simple syntax.
\ No newline at end of file

Modified: trunk/Master/texmf-dist/doc/generic/listofitems/listofitems-en.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/generic/listofitems/listofitems-en.tex
===================================================================
--- trunk/Master/texmf-dist/doc/generic/listofitems/listofitems-en.tex	2018-11-01 22:08:42 UTC (rev 49043)
+++ trunk/Master/texmf-dist/doc/generic/listofitems/listofitems-en.tex	2018-11-01 22:08:53 UTC (rev 49044)
@@ -9,6 +9,7 @@
 \usepackage[margin=3cm]{geometry}
 \usepackage{fancybox}
 \usepackage{xcolor}
+\usepackage{listings,MnSymbol}
 \def\listofitems{\textsf{\loiname}\xspace}
 \def\eTeX{\hbox{$\varepsilon$-\TeX}}
 \makeatletter
@@ -485,4 +486,103 @@
 A word = \word|
 
 The macro \verb|\gitemtomacro| makes a global assignment.
+
+\section{Balanced Tokens}
+
+For the parsing of items, it is possible, with version 1.6, to take into 
+  account the presence of \emph{balanced tokens}. 
+Thus, if a list of paired tokens is defined, then each parsed item
+  in the list will extend to the first \verb|<separator>|, while assuring
+  that any paired tokens are balanced (i.e., occur in matched pairs within
+  the item).
+
+To define a list of balanced-token pairs, we use
+
+\code|\defpair{<tok1><tok2><tok3><tok4>...}|
+
+where the token list is read in pairs to form each matched-token pair. 
+A \verb|<token>| that serves within a matched pair must consist of 
+  a single character---% 
+macros, primitives, spaces, braces, the token 
+  "\verb|#|", as well as sets of several-tokens-between-%
+  braces are all forbidden. 
+The two tokens which form a pair \emph{must} be different from 
+  each other.
+
+\exemple/\setsepchar{+||-}
+\defpair{()[]}
+\readlist\terms{1+2*[3+4*(5+6-7)+8]-9+10}
+\showitems\terms/
+
+To return to the package's default behavior, that is, without 
+  paired tokens, you must execute
+
+\code|\defpair{}|
+
+In an expression, in order to store in a macro that which
+  is between two matched tokens, we can call on
+
+\code|\insidepair<tok1><tok2>{<expression>}\macro|
+
+which will put in the \verb|\macro| that which lies between the pair 
+  \verb|<tok1><tok2>| in the \verb|<expression>|.
+
+\exemple/\setsepchar{+||-}
+\defpair{()}
+\readlist\terms{1+2*(3+4*(5+6-7)+8)-9+10}
+\showitems\terms
+
+\itemtomacro\terms[2]\parenterm
+In the outer parenthesis:
+\insidepair()\parenterm\inbigparen
+"\inbigparen"
+
+In the inner parenthesis:
+\insidepair()\inbigparen\insmallparen
+"\insmallparen"/
+
+\section{The Code}
+
+Any suggestion, bug report, remark, request, addition or modification 
+  of functionality is welcome; in this case, I invite users of 
+  \listofitems to send me an email to \verb|unbonpetit at netc.fr|.\medbreak
+
+The code below is the exact verbatim of the file \verb|listofitems.tex|. 
+I hope that the few comments scattered throughout it will
+  be enough for the user or the curious to understand the internal 
+  machinery of this package:
+
+
+\lstinputlisting[
+		language=TeX,
+		inputencoding=latin1,
+		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={defpair,insidepair,setsepchar,greadlist,readlist,listlen,foreachitem,%
+			showitems,showitemsmacro,itemtomacro,gitemtomacro,ignoreemptyitems,reademptyitems},
+		keywordstyle=\bfseries\color{red!85!black},
+		classoffset=0,
+		]{listofitems.tex}
 \end{document}
\ No newline at end of file

Modified: trunk/Master/texmf-dist/doc/generic/listofitems/listofitems-fr.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/generic/listofitems/listofitems-fr.tex
===================================================================
--- trunk/Master/texmf-dist/doc/generic/listofitems/listofitems-fr.tex	2018-11-01 22:08:42 UTC (rev 49043)
+++ trunk/Master/texmf-dist/doc/generic/listofitems/listofitems-fr.tex	2018-11-01 22:08:53 UTC (rev 49044)
@@ -1,16 +1,16 @@
-% Ceci est la documentation du package "listofitems"%
+% !TeX encoding = UTF-8
+% Ceci est la documentation du package "listofitems"
 %
 % Fichier compilé avec pdflatex
-\documentclass[frenchb,a4paper]{article}
+\documentclass[french,a4paper]{article}
 \usepackage[utf8]{inputenc}
 \usepackage[T1]{fontenc}
-\usepackage{listofitems,babel,xspace}
+\usepackage{listofitems,babel}
 \usepackage[bottom]{footmisc}
 \usepackage{libertine}\usepackage[italic,frenchmath]{mathastext}
 \usepackage[scaled=0.8]{luximono}
 \usepackage[margin=3cm]{geometry}
-\usepackage{fancybox}
-\usepackage{xcolor}
+\usepackage{fancybox,xcolor,xspace,listings,MnSymbol}
 \def\listofitems{\loiname\xspace}
 \def\eTeX{\hbox{$\varepsilon$-\TeX}}
 \makeatletter
@@ -23,6 +23,9 @@
 		\let\do\@makeother \dospecials
 		\ttfamily\small\@noligs
 		\obeylines\obeyspaces
+		\catcode`\<13 \catcode`\>13
+		\begingroup\lccode`\~`\<\lowercase{\endgroup\def~{\begingroup$\langle$\itshape}}%
+		\begingroup\lccode`\~`\>\lowercase{\endgroup\def~{\/$\rangle$\endgroup}}%
 		\def\code at ii##1#1{##1\par\medbreak\endgroup}%
 		\code at ii
 }
@@ -88,7 +91,7 @@
 			\catcode`\<13 \catcode`\>13 \def<{\begingroup$\langle$\itshape}\def>{$\rangle$\endgroup}%
 			\@ifstar\@sverb\@verb}
 \endgroup
-\def\longfrloidate at 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}
+\def\longfrloidate at i#1/#2/#3\@nil{\number#3\relax\ifnum#3=1 \ier\fi\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}
 \def\longfrloidate{\expandafter\longfrloidate at i\loidate\@nil}
 \makeatother
 \begin{document}
@@ -111,7 +114,7 @@
 	\vskip2cm
 	\leftskip=.2\linewidth \rightskip=.2\linewidth \small
 	Cette petite extension pour est destinée à lire une liste d'éléments dont le séparateur peut être choisi par l'utilisateur. Une fois la liste lue, ses éléments sont stockés dans une structure qui se comporte comme un tableau unidimensionnel et ainsi, il devient très facile d'accéder à un élément de la liste par son numéro. Par exemple, si la liste est stockée dans la macro \verb|\foo|, l'élément \no3 est désigné par \verb|\foo[3]|.
-	
+
 	Un élément peut à son tour être une liste disposant d'un autre séparateur que celui de la liste de niveau supérieur, ce qui ouvre la voie à des imbrications et donne une syntaxe rappelant celle des tableaux à plusieurs dimensions du type \verb|\foo[3,2]| pour accéder à l'élément \no2 de la liste contenue dans l'élément \no3 de la liste de plus haut niveau.
 \end{titlepage}
 \def\listofitems{\textsf\loiname\xspace}
@@ -354,4 +357,80 @@
 Un mot = \mot|
 
 La macro \verb|\gitemtomacro| fait une assignation globale.
+
+\section{Tokens appariés}
+Pour le découpage des items, il est possible à partir de la version 1.6, de tenir compte de la présence de caractères \emph{appariés}. Ainsi, si une liste de caractères appariés est définie, chaque item s'étend jusqu'au prochain \verb|<séparateur>| qui équilibre les tokens appariés.
+
+Pour définir une liste de tokens appariés, on utilise
+
+\code|\defpair{<tok1><tok2><tok3><tok4>...}|
+
+où les tokens sont lus deux par deux pour former les paires d'appariement. Un \verb|<token>| d'appariement doit être constitué d'un seul caractère; les macros, primitives, espaces, accolades, token «\verb|#|», ensembles de plusieurs tokens entre accolades sont interdits. Deux tokens formant une paire \emph{doivent} être différents.
+
+\exemple/\setsepchar{+||-}
+\defpair{()[]}
+\readlist\termes{1+2*[3+4*(5+6-7)+8]-9+10}
+\showitems\termes/
+
+Pour revenir au comportement par défaut, c'est-à-dire sans tokens appariés, il faut exécuter
+
+\code|\defpair{}|
+
+Dans une expression, pour stocker dans une macro ce qui se trouve entre deux tokens appariés, on peut faire appel à
+
+\code|\insidepair<tok1><tok2>{<expression>}\macro|
+
+qui mettra dans la \verb|\macro| ce qui de trouve entre la paire \verb|<tok1><tok2>| dans l'\verb|<expression>|.
+
+\exemple/\setsepchar{+||-}
+\defpair{()}
+\readlist\termes{1+2*(3+4*(5+6-7)+8)-9+10}
+\showitems\termes
+
+\itemtomacro\termes[2]\parenterm
+Dans la parenthèse extérieure :
+\insidepair()\parenterm\inbigparen
+"\inbigparen"
+
+Dans la parenthèse intérieure :
+\insidepair()\inbigparen\insmallparen
+"\insmallparen"/
+
+\section{Le code}
+Toute suggestion, remontée de bug, remarque, demande, ajout ou modification de fonctionnalité est bienvenue; dans ce cas, j'invite les utilisateurs de \listofitems à m'envoyer un email à \verb|unbonpetit at netc.fr|.\medbreak
+
+Le code ci-dessous est l'exact verbatim du fichier \verb|listofitems.tex|. J'espère que les quelques commentaires qui le parsèment de-ci de-là seront suffisants pour que l'utilisateur ou le curieux comprenne la machinerie interne de ce package :
+
+\lstinputlisting[
+		language=TeX,
+		inputencoding=latin1,
+		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={defpair,insidepair,setsepchar,greadlist,readlist,listlen,foreachitem,%
+			showitems,showitemsmacro,itemtomacro,gitemtomacro,ignoreemptyitems,reademptyitems},
+		keywordstyle=\bfseries\color{red!85!black},
+		classoffset=0,
+		]{listofitems.tex}
 \end{document}
\ No newline at end of file

Modified: trunk/Master/texmf-dist/tex/generic/listofitems/listofitems.tex
===================================================================
--- trunk/Master/texmf-dist/tex/generic/listofitems/listofitems.tex	2018-11-01 22:08:42 UTC (rev 49043)
+++ trunk/Master/texmf-dist/tex/generic/listofitems/listofitems.tex	2018-11-01 22:08:53 UTC (rev 49044)
@@ -1,32 +1,33 @@
+% !TeX encoding = ISO-8859-1
 % Ce fichier contient le code de l'extension "listofitems"
 %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %                                                                    %
 \def\loiname                 {listofitems}                           %
-\def\loiver                     {1.53}                               %
+\def\loiver                      {1.6}                               %
 %                                                                    %
-\def\loidate                  {2018/03/13}                           %
+\def\loidate                  {2018/11/01}                           %
 %                                                                    %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% Author     : Christian Tellechea, Steven B. Segletes
-% Status     : Maintained
-% Maintainer : Christian Tellechea
-% Email      : unbonpetit at netc.fr
-%              steven.b.segletes.civ at mail.mil
-% Package URL: https://www.ctan.org/pkg/listofitems
-% Bug tracker: https://framagit.org/unbonpetit/listofitems/issues
+%                                                                    %
+% Author     : Christian Tellechea, Steven B. Segletes               %
+% Status     : Maintained                                            %
+% Maintainer : Christian Tellechea                                   %
+% Email      : unbonpetit at netc.fr                                    %
+%              steven.b.segletes.civ at mail.mil                        %
+% Package URL: https://www.ctan.org/pkg/listofitems                  %
+% Bug tracker: https://framagit.org/unbonpetit/listofitems/issues    %
 % Repository : https://framagit.org/unbonpetit/listofitems/tree/master
-% Copyright  : Christian Tellechea 2017-2018
-% Licence    : Released under the LaTeX Project Public License v1.3c
-%              or later, see http://www.latex-project.org/lppl.txt
-% Files      : 1) listofitems.tex
-%              2) listofitems.sty
-%              3) listofitems-fr.tex
-%              4) listofitems-fr.pdf
-%              5) listofitems-en.tex
-%              6) listofitems-en.pdf
-%              7) README
+% Copyright  : Christian Tellechea 2016-2018                         %
+% Licence    : Released under the LaTeX Project Public License v1.3c %
+%              or later, see http://www.latex-project.org/lppl.txt   %
+% Files      : 1) listofitems.tex                                    %
+%              2) listofitems.sty                                    %
+%              3) listofitems-fr.tex                                 %
+%              4) listofitems-fr.pdf                                 %
+%              5) listofitems-en.tex                                 %
+%              6) listofitems-en.pdf                                 %
+%              7) README                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \ifdefined\ProvidesPackage\else
 	\immediate\write -1 {%
@@ -46,7 +47,7 @@
 \fi
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%% v\'erification de la pr`'esence de etex %%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%% v\xE9rification de la pr\xE9sence de etex %%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \begingroup
 \edef\__tempa{\meaning\eTeXversion}\edef\__tempb{\string\eTeXversion}%
@@ -55,38 +56,41 @@
 \else
 	\endgroup
 	\loi_error{You are not using an eTeX engine, listofitems cannot work.}%
-	\expandafter\loi_restorecatcode\expandafter\endinput
+	\loi_restorecatcode\expandafter\endinput
 \fi
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%% macros auxiliaires %%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%---- macros de d\'eveloppement et de manipulation d'arguments
 \chardef\loi_stop=0
 \def\loi_quark{\loi_quark}
 \long\def\loi_identity#1{#1}
-\def\loi_gobarg#1{}
+\long\def\loi_gobarg#1{}
 \long\def\loi_first#1#2{#1}
 \long\def\loi_second#1#2{#2}
 \long\def\loi_firsttonil#1#2\_nil{#1}
 \long\def\loi_antefi#1#2\fi{#2\fi#1}
-\long\def\loi_exparg#1#2{\expandafter\loi_exparg_i\expandafter{#2}{#1}}% \loi_exparg{<a>}{<b>} devient <a>{<*b>}
-\long\def\loi_exparg_i#1#2{#2{#1}}
-\long\def\loi_expafter#1#2{\expandafter\loi_expafter_i\expandafter{#2}{#1}}% \loi_expafter{<a>}{<b>} devient <a><*b>
-\long\def\loi_expafter_i#1#2{#2#1}
+\long\def\loi_exparg#1#2{\expandafter\loi_exparg_a\expandafter{#2}{#1}}% \loi_exparg{<a>}{<b>} devient <a>{<*b>}
+\long\def\loi_exparg_a#1#2{#2{#1}}
+\long\def\loi_expafter#1#2{\expandafter\loi_expafter_a\expandafter{#2}{#1}}% \loi_expafter{<a>}{<b>} devient <a><*b>
+\long\def\loi_expafter_a#1#2{#2#1}
 \def\loi_macroname{\loi_ifinrange\escapechar[[0:255]]{\expandafter\loi_gobarg}{}\string}
-\def\loi_argcsname#1#{\loi_argcsname_i{#1}}
-\def\loi_argcsname_i#1#2{\loi_expafter{#1}{\csname#2\endcsname}}
+\def\loi_argcsname#1#{\loi_argcsname_a{#1}}
+\def\loi_argcsname_a#1#2{\loi_expafter{#1}{\csname#2\endcsname}}
+\long\def\loi_addtomacro#1#2{\loi_exparg{\def#1}{#1#2}}
 
-%--- macros de test
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%% macros de test %%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \long\def\loi_ifnum#1{\ifnum#1\expandafter\loi_first\else\expandafter\loi_second\fi}
 \long\def\loi_ifx#1{\ifx#1\expandafter\loi_first\else\expandafter\loi_second\fi}
 \long\def\loi_ifempty#1{\loi_exparg\loi_ifx{\expandafter\relax\detokenize{#1}\relax}}
-\def\loi_ifstar#1#2{\def\loi_ifstar_i{\loi_ifx{*\loi_nxttok}{\loi_first{#1}}{#2}}\futurelet\loi_nxttok\loi_ifstar_i}
+\def\loi_ifstar#1#2{\def\loi_ifstar_a{\loi_ifx{*\loi_nxttok}{\loi_first{#1}}{#2}}\futurelet\loi_nxttok\loi_ifstar_a}
 \long\def\loi_ifprimitive#1{\edef\loi_tempa{\meaning#1}\edef\loi_tempb{\string#1}\loi_ifx{\loi_tempa\loi_tempb}}
-\long\def\loi_ifcs#1{% #1 est-il une sc (n'\'etant pas une primitive) ?
+\long\def\loi_ifcs#1{% #1 est-il une sc (n'\xE9tant pas une primitive) ?
 	\loi_ifempty{#1}
-		\loi_second% si #1 est vide, faux
+		{\loi_second
+		}
 		{\loi_ifspacefirst{#1}
 			\loi_second% si espace en 1er, faux
 			{\loi_exparg\loi_ifempty{\loi_gobarg#1}% 1 seul token ?
@@ -99,36 +103,176 @@
 						\endgroup\expandafter\loi_second
 					\fi
 				}
-				\loi_second% si plusieurs tokens, faux
+				{\loi_second% si plusieurs tokens, faux
+				}%
 			}%
 		}%
 }
 \def\loi_ifinrange#1[[#2:#3]]{\loi_ifnum{\numexpr(#1-#2)*(#1-#3)>0 }\loi_second\loi_first}
+\def\loi_ifstring#1\in#2{% si la chaine #1 est contenue dans #2
+	\def\loi_ifstring_a##1#1##2\_nil{\loi_ifempty{##2}\loi_second\loi_first}%
+	\loi_ifstring_a#2#1\@nil% appel de la macro auxiliaire
+}
 
-%--- macro de type for
-%      Voir codes 150 \`a 155 ici --> http://progtex.fr/wp-content/uploads/2014/09/code.txt
-%      et pages 175 \`a 184 du livre "Apprendre \`a programmer en TeX"
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%% macros \loi_foreach %%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\newcount\loi_cnt_foreach_nest \loi_cnt_foreach_nest=0
+\def\end_foreach{\end_foreach}
+\def\loi_def_foreachsep#1{%
+	\long\def\loi_foreach##1\in##2##3{%
+		\global\advance\loi_cnt_foreach_nest1
+		\loi_argcsname\def{loop_code_\number\loi_cnt_foreach_nest}{##3}%
+		\loi_foreach_a##1##2#1\end_foreach#1%
+		\loi_argcsname\let{loop_code_\number\loi_cnt_foreach_nest}\empty
+		\global\advance\loi_cnt_foreach_nest-1
+	}%
+	\long\def\loi_foreach_a##1##2#1{%
+		\def##1{##2}%
+		\loi_ifx{\end_foreach##1}
+			{}
+			{\csname loop_code_\number\loi_cnt_foreach_nest\endcsname% ex\xE9cute le code
+			\loi_foreach_a##1%
+			}%
+	}%
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%% macros g\xE9rant l'appariement %%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\long\def\defpair#1{%
+	\let\loi_listofpair\empty
+	\loi_ifempty{#1}
+		{}
+		{\defpair_a{}#1\loi_quark\loi_quark}%
+}
+\long\def\defpair_a#1#2#3{%
+	\loi_ifx{\loi_quark#2}
+		{\def\loi_sanitizelist##1,\_nil{\def\loi_listofpair{##1}}%
+		\loi_sanitizelist#1\_nil
+		}
+		{\loi_if_validpair#2#3%
+			{\long\def\loi_paired_a{#2}\long\def\loi_paired_b{#3}%
+			\loi_ifx{\loi_paired_a\loi_paired_b}
+				{\loi_error{Paired tokens must not be equal, the pair \detokenize{#2#3} is ignored}%
+				\defpair_a{#1}%
+				}
+				{\defpair_a{#1#2#3,}%
+				}%
+			}
+			{\loi_error{Invalid paired tokens, the pair "\detokenize{#2}" and "\detokenize{#3}" is ignored}%
+			\defpair_a{#1}%
+			}%
+		}%
+}
+\long\def\loi_if_validpair#1#2{%
+	\def\loi_validpair{1}%
+	\loi_if_invalid_pairtoken{#1}{\def\loi_validpair{0}}%
+	\loi_if_invalid_pairtoken{#2}{\def\loi_validpair{0}}%
+	\loi_ifnum{\loi_validpair=1 }
+}
+\long\def\loi_if_invalid_pairtoken#1{%
+	\loi_ifempty{#1}
+		{\loi_identity
+		}
+		{\loi_ifspacefirst{#1}
+			{\loi_identity
+			}
+			{\loi_exparg\loi_ifempty{\loi_gobarg#1}% 1 seul token ?
+				{\ifcat\relax\noexpand#1\expandafter\loi_identity\else\expandafter\loi_gobarg\fi}
+				{\loi_identity}% si plusieurs tokens, faux
+			}%
+		}%
+}
+\long\def\loi_count_occur#1\in#2:#3{% compte le nombre d'occurrences de #1 dans #2 et met le r\xE9sultat dans la macro #3
+	\long\def\loi_count_occur_a##1##2#1##3\_nil{%
+		\loi_ifempty{##3}
+			{\def#3{##1}}
+			{\expandafter\loi_count_occur_a\number\numexpr##1+1\relax##3\_nil}%
+	}%
+	\loi_count_occur_a0#2#1\_nil
+}
+\long\def\loi_check_pair#1#2\in#3{% teste l'appariement de #1 et #2 dans #3
+	\loi_ifempty{#3}
+		{\loi_second
+		}
+		{\loi_count_occur#1\in#3:\loi_tempa
+		\loi_count_occur#2\in#3:\loi_tempb
+		\loi_ifnum{\loi_tempa=\loi_tempb\relax}%
+		}%
+}
+\long\def\loi_grabpaired_expr#1#2#3#4#5{% #1=liste de paires  #2=expression  #3=s\xE9parateur   #4=r\xE9sultat    #5=ce qui reste
+	\let#4\empty
+	\def\loi_remain{#2#3}%
+	\loi_foreach\loi_pair\in{#1}{\expandafter\loi_grabpaired_expr_a\loi_pair{#3}#4}%
+	\def\loi_remove_lastsep##1#3\_nil{\def#4{##1}}%
+	\expandafter\loi_remove_lastsep#4\_nil
+	\expandafter\long\expandafter\def\expandafter\loi_grab_remain#4##1\_nil{\loi_ifempty{##1}{\let#5\empty}{\loi_exparg{\def#5}{\loi_gobarg##1}}}%
+	\loi_grab_remain#2\_nil
+}
+\long\def\loi_grabpaired_expr_a#1#2#3#4{% #1#2=paire en cours  #3=s\xE9parateur   #4=r\xE9sultat
+	\loi_exparg{\loi_check_pair#1#2\in}#4% si les paires sont appari\xE9es dans le r\xE9sultat
+		{}% passer \xE0 la paire suivante
+		{\long\def\loi_grabpaired_expr_b##1#3##2\_nil{%
+			\loi_addtomacro#4{##1#3}% ajouter au r\xE9sultat ce qui est jusqu'au prochain s\xE9parateur
+			\def\loi_remain{##2}%
+			\loi_exparg{\loi_check_pair#1#2\in}{#4}
+				{}
+				{\loi_ifempty{##2}
+					{\loi_error{"\detokenize{#1}" and "\detokenize{#2}" are not paired}}
+					{\loi_grabpaired_expr_b##2\_nil}%
+				}%
+			}%
+		\expandafter\loi_grabpaired_expr_b\loi_remain\_nil
+		}%
+}
+\def\insidepair#1#2#3#4{% #1#2=paire  #3=expr  #4=macro re\xE7evant le resultat
+	\loi_if_validpair#1#2%
+		{\loi_ifcs{#3}
+			{\loi_exparg{\insidepair#1#2}{#3}#4%
+			}
+			{\loi_check_pair#1#2\in{#3}% si les paires sont appari\xE9es dans le r\xE9sultat
+				{\def\insidepair_a##1#1##2\_nil{\insidepair_b##2\_nil{#1}}%
+				\def\insidepair_b##1#2##2\_nil##3{%
+					\loi_check_pair#1#2\in{##3##1#2}
+						{\loi_exparg{\def#4}{\loi_gobarg##3##1}}%
+						{\insidepair_b##2\_nil{##3##1#2}}%
+					}%
+				\insidepair_a#3\_nil
+				}
+				{\loi_error{"\detokenize{#1}" and "\detokenize{#2}" are not paired in "#3"}%
+				}%
+			}%
+		}
+		{\loi_error{Invalid paired tokens "\detokenize{#1}" and "\detokenize{#2}", empty \string#4 returned}% et bim
+		\let#4\empty% voil\xE0, bien fait pour vos gueules
+		}%
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%% macro \loi_fornum %%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \def\loi_fornum#1=#2to#3\do{%
 	\edef#1{\number\numexpr#2}\edef\loi_sgncmp{\ifnum#1<\numexpr#3\relax>+\else<-\fi}%
-	\expandafter\loi_fornum_i\csname loi_fornum_\string#1\expandafter\endcsname\expandafter{\number\numexpr#3\expandafter}\loi_sgncmp#1%
+	\expandafter\loi_fornum_a\csname loi_fornum_\string#1\expandafter\endcsname\expandafter{\number\numexpr#3\expandafter}\loi_sgncmp#1%
 }
-\long\def\loi_fornum_i#1#2#3#4#5#6{\def#1{\unless\ifnum#5#3#2\relax\loi_antefi{#6\edef#5{\number\numexpr#5#41\relax}#1}\fi}#1}
+\long\def\loi_fornum_a#1#2#3#4#5#6{\def#1{\unless\ifnum#5#3#2\relax\loi_antefi{#6\edef#5{\number\numexpr#5#41\relax}#1}\fi}#1}
 
-%--- macros retirant les espaces extr\^emes
-%      Voir codes 320 \`a 324 ici --> http://progtex.fr/wp-content/uploads/2014/09/code.txt
-%      et pages 339 \`a 343 de "Apprendre \`a programmer en TeX"
-\long\def\loi_ifspacefirst#1{\expandafter\loi_ifspacefirst_i\detokenize{#10} \_nil}
-\long\def\loi_ifspacefirst_i#1 #2\_nil{\loi_ifempty{#1}}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%% macro retirant les espaces extr\xEAmes %%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\long\def\loi_ifspacefirst#1{\expandafter\loi_ifspacefirst_a\detokenize{#10} \_nil}
+\long\def\loi_ifspacefirst_a#1 #2\_nil{\loi_ifempty{#1}}
 \expandafter\def\expandafter\loi_gobspace\space{}
-\def\loi_removefirstspaces{\romannumeral\loi_removefirstspaces_i}
-\long\def\loi_removefirstspaces_i#1{\loi_ifspacefirst{#1}{\expandafter\loi_removefirstspaces_i\expandafter{\loi_gobspace#1}}{\loi_stop#1}}
+\def\loi_removefirstspaces{\romannumeral\loi_removefirstspaces_a}
+\long\def\loi_removefirstspaces_a#1{\loi_ifspacefirst{#1}{\expandafter\loi_removefirstspaces_a\expandafter{\loi_gobspace#1}}{\loi_stop#1}}
 \edef\loi_restorezerocatcode{\catcode0=\number\catcode0 \relax}
 \catcode0 12
-\long\def\loi_removelastspaces#1{\romannumeral\loi_removelastspaces_i#1^^00 ^^00\_nil}
-\long\def\loi_removelastspaces_i#1 ^^00{\loi_removelastspaces_ii#1^^00}
-\long\def\loi_removelastspaces_ii#1^^00#2\_nil{\loi_ifspacefirst{#2}{\loi_removelastspaces_i#1^^00 ^^00\_nil}{\loi_stop#1}}
+\long\def\loi_removelastspaces#1{\romannumeral\loi_removelastspaces_a#1^^00 ^^00\_nil}
+\long\def\loi_removelastspaces_a#1 ^^00{\loi_removelastspaces_b#1^^00}
+\long\def\loi_removelastspaces_b#1^^00#2\_nil{\loi_ifspacefirst{#2}{\loi_removelastspaces_a#1^^00 ^^00\_nil}{\loi_stop#1}}
 \loi_restorezerocatcode
-\long\def\loi_removeextremespaces#1{% #1=texte o\`u les espaces extr\^emes sont retir\'es
+\long\def\loi_removeextremespaces#1{% #1=texte o\xF9 les espaces extr\xEAmes sont retir\xE9s
 	\romannumeral\expandafter\expandafter\expandafter\loi_removelastspaces\expandafter\expandafter\expandafter
 	{\expandafter\expandafter\expandafter\loi_stop\loi_removefirstspaces{#1}}%
 }
@@ -136,27 +280,31 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%% macro publique \setsepchar %%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\def\setsepchar{\futurelet\loi_nxttok\setsepchar_i}
-\def\setsepchar_i{\loi_ifx{[\loi_nxttok}\setsepchar_ii{\setsepchar_ii[/]}}
-\long\def\setsepchar_ii[#1]#2{% #1=sepcar de <liste des sepcar>  #2=<liste des sepcar>
+\def\setsepchar{\futurelet\loi_nxttok\setsepchar_a}
+\def\setsepchar_a{\loi_ifx{[\loi_nxttok}\setsepchar_b{\setsepchar_b[/]}}
+\long\def\setsepchar_b[#1]#2{% #1=sepcar de <liste des sepcar>  #2=<liste des sepcar>
 	\loi_ifempty{#1}
 		{\loi_error{Empty separator not allowed, separator "/" used}%
-		\setsepchar_ii[/]{#2}%
+		\setsepchar_b[/]{#2}%
 		}
 		{\def\loi_currentsep{#1}%
 		\_removeextremespacesfalse
-		\loi_nestcnt1 % r\'einitaliser niveau initial \`a 1
+		\loi_nestcnt1 % r\xE9initaliser niveau initial \xE0 1
 		\def\nestdepth{1}%
 		\loi_argcsname\let{loi_previndex[\number\loi_nestcnt]}\empty
 		\def\loi_listname{loi_listofsep}%
 		\let\loi_def\def \let\loi_edef\edef \let\loi_let\let
+		\let\loi_listofpair_saved\loi_list_ofpair
+		\let\loi_list_ofpair\empty
 		\loi_ifempty{#2}
 			{\loi_error{Empty list of separators not allowed, "," used}%
-			\readlist_iv1{,}%
+			\readlist_e1{,}%
 			}
-			{\readlist_iv1{#2}}%
+			{\readlist_e1{#2}%
+			}%
 		\loi_argcsname\let\nestdepth{loi_listofseplen[0]}%
-		\loi_argcsname\let\loi_currentsep{loi_listofsep[1]}% 1er car de s\'eparation
+		\loi_argcsname\let\loi_currentsep{loi_listofsep[1]}% 1er car de s\xE9paration
+		\let\loi_listofpair\loi_listofpair_saved
 		}%
 }
 
@@ -166,65 +314,68 @@
 \def\loi_normalizeindex#1#2#3{% #1=macroname  #2=liste d'index  #3=profondeur max --> renvoie {err}{indx norm}
 	\loi_ifempty{#2}
 		{\loi_stop{}{}}
-		{\loi_normalizeindex_i1{}{#3}{#1}#2,\loi_quark,}%
+		{\loi_normalizeindex_a1{}{#3}{#1}#2,\loi_quark,}%
 }%
-\def\loi_normalizeindex_i#1#2#3#4#5,{% #1=compteur de profondeur #2=index pr\'ec\'edents  #3=profondeur max #4=macroname  #5=index courant
+\def\loi_normalizeindex_a#1#2#3#4#5,{% #1=compteur de profondeur #2=index pr\xE9c\xE9dents  #3=profondeur max #4=macroname  #5=index courant
 	\loi_ifx{\loi_quark#5}
-		{\loi_normalizeindex_iii#2\loi_quark}% supprimer la derni\`ere virgule
+		{\loi_normalizeindex_c#2\loi_quark% supprimer la derni\xE8re virgule
+		}
 		{\loi_ifnum{#1>#3 }
-			{\loi_invalidindex{Too deeply nested index, index [.] retained}{#2}}% si profondeur trop grande
+			{\loi_invalidindex{Too deeply nested index, index [.] retained}{#2}% si profondeur trop grande
+			}
 			{\loi_ifinrange\ifnum\numexpr#5<0 -1*\fi(#5)[[1:\csname #4len[#20]\endcsname]]% si abs(#5) hors de [1,len]
-				{\loi_exparg\loi_normalizeindex_ii{\number\numexpr#5\ifnum\numexpr#5<0 +\csname #4len[#20]\endcsname+1\fi}{#1}{#2}{#3}{#4}}
+				{\loi_exparg\loi_normalizeindex_b{\number\numexpr#5\ifnum\numexpr#5<0 +\csname #4len[#20]\endcsname+1\fi}{#1}{#2}{#3}{#4}}
 				{\loi_invalidindex{#5 is an invalid index, index [.] retained}{#2}}%
 			}%
 		}%
 }
-\def\loi_normalizeindex_ii#1#2#3{\loi_exparg\loi_normalizeindex_i{\number\numexpr#2+1}{#3#1,}}% #1=index \`a rajouter  #2=compteur de profondeur #3=index pr\'ec\'edents
-\def\loi_normalizeindex_iii#1,\loi_quark{\loi_stop{}{#1}}
-\def\loi_invalidindex#1#2{\loi_ifempty{#2}{\loi_invalidindex_i{#1},}\loi_invalidindex_i{#1}{#2}}
-\def\loi_invalidindex_i#1#2{\loi_invalidindex_ii#1\loi_quark#2\loi_quark}
-\def\loi_invalidindex_ii#1[.]#2\loi_quark#3,\loi_quark#4\loi_quark,{\loi_stop{#1[#3]#2}{#3}}% #4= index ignor\'es
+\def\loi_normalizeindex_b#1#2#3{\loi_exparg\loi_normalizeindex_a{\number\numexpr#2+1}{#3#1,}}% #1=index \xE0 rajouter  #2=compteur de profondeur #3=index pr\xE9c\xE9dents
+\def\loi_normalizeindex_c#1,\loi_quark{\loi_stop{}{#1}}
+\def\loi_invalidindex#1#2{\loi_ifempty{#2}{\loi_invalidindex_a{#1},}\loi_invalidindex_a{#1}{#2}}
+\def\loi_invalidindex_a#1#2{\loi_invalidindex_b#1\loi_quark#2\loi_quark}
+\def\loi_invalidindex_b#1[.]#2\loi_quark#3,\loi_quark#4\loi_quark,{\loi_stop{#1[#3]#2}{#3}}% #4= index ignor\xE9s
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%% macro publique \readlist %%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \newcount\loi_nestcnt
-\def\greadlist{\let\loi_def\gdef\let\loi_edef\xdef\def\loi_let{\global\let}\readlist_o}%
-\def\readlist{\let\loi_def\def\let\loi_edef\edef\let\loi_let\let\readlist_o}
-\def\readlist_o{%
+\def\greadlist{\let\loi_def\gdef\let\loi_edef\xdef\def\loi_let{\global\let}\readlist_a}%
+\def\readlist{\let\loi_def\def\let\loi_edef\edef\let\loi_let\let\readlist_a}
+\def\readlist_a{%
 	\loi_nestcnt1 % niveau initial = 1
 	\loi_argcsname\let{loi_previndex[\number\loi_nestcnt]}\empty
-	\loi_ifstar{\_removeextremespacestrue\readlist_i}{\_removeextremespacesfalse\readlist_i}%
+	\loi_ifstar{\_removeextremespacestrue\readlist_b}{\_removeextremespacesfalse\readlist_b}%
 }
-\long\def\readlist_i#1#2{% #1=macro stockant les \'el\'ements  #2=liste des \'el\'ements
+\long\def\readlist_b#1#2{% #1=macro stockant les \xE9l\xE9ments  #2=liste des \xE9l\xE9ments
 	\loi_ifcs{#2}
-		{\loi_exparg{\readlist_i#1}{#2}}
+		{\loi_exparg{\readlist_b#1}{#2}%
+		}
 		{\loi_edef\loi_listname{\loi_macroname#1}%
 		\loi_argcsname\loi_let{\loi_listname nest}\nestdepth
-		\loi_argcsname\loi_def{\loi_listname[]}{#2}% la liste enti\`ere
-		\loi_argcsname\loi_def{\loi_listname sep[]}{}% s\'eparateur vide
+		\loi_argcsname\loi_def{\loi_listname[]}{#2}% la liste enti\xE8re
+		\loi_argcsname\loi_def{\loi_listname sep[]}{}% s\xE9parateur vide
 		\loi_ifempty{#2}
 			{\loi_def#1[##1]{}%
 			\loi_argcsname\loi_def{\loi_listname len}{0}\loi_argcsname\loi_def{\loi_listname len[0]}{0}%
 			\loi_error{Empty list ignored, nothing to do}%
 			}
-			{\loi_edef#1[##1]{\unexpanded{\romannumeral\expandafter\loi_auxmacrolistitem\romannumeral\loi_normalizeindex}{\loi_listname}{##1}{\csname\loi_listname nest\endcsname}{\loi_listname}}%
-			\loi_argcsname\loi_edef{\loi_listname sep}[##1]{\unexpanded{\romannumeral\expandafter\loi_auxmacrolistitem\romannumeral\loi_normalizeindex}{\loi_listname}{##1}{\csname\loi_listname nest\endcsname}{\loi_listname sep}}%
-			\readlist_ii{#2}%
+			{\loi_edef#1[##1]{\unexpanded{\romannumeral\expandafter\loi_checkindex\romannumeral\loi_normalizeindex}{\loi_listname}{##1}{\csname\loi_listname nest\endcsname}{\loi_listname}}%
+			\loi_argcsname\loi_edef{\loi_listname sep}[##1]{\unexpanded{\romannumeral\expandafter\loi_checkindex\romannumeral\loi_normalizeindex}{\loi_listname}{##1}{\csname\loi_listname nest\endcsname}{\loi_listname sep}}%
+			\readlist_c{#2}%
 			\loi_argcsname\loi_argcsname\loi_let{\loi_listname len}{\loi_listname len[0]}% longueur du niveau 0
 			}%
 		}%
 }
-\def\loi_auxmacrolistitem#1#2#3{%
+\def\loi_checkindex#1#2#3{%
 	\expandafter\expandafter\expandafter\loi_stop\csname#3[#2]\expandafter\endcsname
 	\romannumeral\loi_ifempty{#1}{\loi_stop}{\loi_stop\loi_error{#1}}%
 }
-\def\readlist_ii{%
+\def\readlist_c{%
 	\loi_argcsname\loi_let\loi_currentsep{loi_listofsep[\number\loi_nestcnt]}%
-	\expandafter\readlist_iii\loi_currentsep||\_nil
+	\expandafter\readlist_d\loi_currentsep||\_nil
 }
-\long\def\readlist_iii#1||#2\_nil#3{\readlist_iv1{#3#1}}% #1=<sep courant simple>  #3=liste -> rajoute un \'el\'ement vide pour le test ifempty ci dessous
-\long\def\readlist_iv#1#2{% #1=compteur d'index  #2=liste d'\'el\'ements \`a examiner
+\long\def\readlist_d#1||#2\_nil#3{\readlist_e1{#3#1}}% #1=<sep courant simple>  #3=liste -> rajoute un \xE9l\xE9ment vide pour le test \ifempty ci dessous
+\long\def\readlist_e#1#2{% #1=compteur d'index  #2=liste d'\xE9l\xE9ments \xE0 examiner termin\xE9e par <sep courant simple> >>RIEN laiss\xE9 apr\xE8s
 	\loi_ifempty{#2}
 		{\loi_argcsname\loi_edef{\loi_listname len[\csname loi_previndex[\number\loi_nestcnt]\endcsname0]}{\number\numexpr#1-1\relax}%
 		\loi_argcsname\loi_let{\loi_listname sep[\csname loi_previndex[\number\loi_nestcnt]\endcsname\number\numexpr#1-1\relax]}\empty% le dernier <sep> est <vide> ##NEW v1.52
@@ -231,43 +382,57 @@
 		\advance\loi_nestcnt-1
 		\loi_argcsname\loi_let\loi_currentsep{loi_listofsep[\number\loi_nestcnt]}%
 		}
-		{\loi_expafter{\readlist_vi{#2}{}}\loi_currentsep||\loi_quark||#2\_nil{#1}}% aller isoler le 1er item
+		{\loi_expafter{\readlist_f{#2}{}}\loi_currentsep||\loi_quark||#2\_nil{#1}% aller isoler le 1er item
+		}%
 }
-\long\def\readlist_v#1#2{\readlist_vi{#2}{}#1||\loi_quark||#2\_nil}% #1=liste s\'eparateurs (s\'ep=||)  #2=chaine de tokens
-\long\def\readlist_vi#1#2#3||{% #1=liste restante   #2=dernier <sep utile>  #3=<sep courant>
-	\loi_ifx{\loi_quark#3}
-		{\loi_ifempty{#2}% si #1 vide, aucun <sep utile> n'a \'et\'e trouv\'e, il reste \`a lire "<liste compl\`ete>\_nil"
-			{\long\def\readlist_vii##1\_nil##2{\loi_exparg{\readlist_ix{##2}{}}{\loi_gobarg##1}{#2}}}% ##2=compteur d'index
-			{\long\def\readlist_vii##1#2{\loi_exparg\readlist_viii{\loi_gobarg##1}\relax}%
-			\long\def\readlist_viii##1##2\_nil##3{\loi_exparg{\readlist_ix{##3}}{\loi_gobarg##2}{##1}{#2}}% ##3=compteur d'index
+\long\def\readlist_f#1#2#3||{% #1=liste restante   #2=<dernier sep utilis\xE9>  #3=<sep courant>
+	\loi_ifx{\loi_quark#3}% on a \xE9puis\xE9 tous les <s\xE9parateurs> ? RESTE \xE0 lire <expr+sep1>\_nil{<compteur>}
+		{\loi_ifempty{#2}% si #2 vide, aucun <sep utilis\xE9> n'a \xE9t\xE9 trouv\xE9, il reste \xE0 lire "<liste compl\xE8te>\_nil"
+			{\long\def\readlist_g##1\_nil##2{\loi_exparg{\readlist_h{##2}{}}{\loi_gobarg##1}{#2}}% ##2=compteur d'index
+			}
+			{\loi_ifx{\loi_listofpair\empty}% paires d\xE9finies ?
+				{\long\def\readlist_g##1#2##2\_nil##3{\loi_exparg{\readlist_h{##3}{##2}}{\loi_gobarg##1}{#2}}%
+				}
+				{\long\def\readlist_g##1\_nil##2{%
+					\loi_exparg{\loi_exparg\loi_grabpaired_expr\loi_listofpair}{\loi_gobarg##1}{#2}\loi_grabpaired_result\loi_grabpaired_remain
+					\loi_exparg{\loi_exparg{\readlist_h{##2}}{\loi_grabpaired_remain}}{\loi_grabpaired_result}{#2}}%
+				}%
 			}%
-		\readlist_vii\relax% le \relax meuble l'argument d\'elimit\'e
+		\readlist_g\relax% le \relax meuble l'argument d\xE9limit\xE9
 		}
-		{\long\def\readlist_vii##1#3##2\_nil{%
+		{\long\def\readlist_g##1#3##2\_nil{%
 			\loi_ifempty{##2}% si <liste restante> ne contient pas le <sep courant>
-				{\readlist_vi{#1}{#2}}% recommencer avec le m\^eme <sep utile>
-				{\loi_exparg\readlist_vi{\loi_gobarg##1#3}{#3}}% sinon raccourcir <liste restante> et <sep courant>:=<sep utile>% ##BUGFIX v1.53
+				{\readlist_f{#1}{#2}% recommencer avec le m\xEAme <sep utile>
+				}%
+				{\loi_ifx{\loi_listofpair\empty}% si pas de paires d\xE9finies
+					{\loi_exparg\readlist_f{\loi_gobarg##1#3}{#3}% raccourcir <liste restante> et <sep courant>:=<sep utile>% ##BUGFIX v1.53
+					}%
+					{\loi_exparg\loi_grabpaired_expr\loi_listofpair{#1}{#3}\loi_grabpaired_result\loi_grabpaired_remain
+					\loi_exparg\readlist_f{\loi_grabpaired_result#3}{#3}%
+					}%
+				}%
 			}%
-		\readlist_vii\relax#1#3\_nil% ##BUGFIX v1.53
+		\readlist_g\relax#1#3\_nil% ##BUGFIX v1.53
 		}%
 }
-\long\def\readlist_ix#1#2#3{% #1=compteur d'index  #2=liste restante  #3=\'el\'ement courant
-	\loi_ifnum{0\loi_exparg\loi_ifspacefirst{\loi_currentsep}{}1\if_removeextremespaces1\fi=11 }% s'il faur retirer les espaces extr\^emes
-		{\loi_exparg{\loi_exparg{\readlist_x{#1}{#2}}}{\loi_removeextremespaces{#3}}}% red\'efinir l'\'el\'ement courant
-		{\readlist_x{#1}{#2}{#3}}%
+\long\def\readlist_h#1#2#3{% #1=compteur d'index  #2=liste restante  #3=\xE9l\xE9ment courant
+	\loi_ifnum{0\loi_exparg\loi_ifspacefirst{\loi_currentsep}{}1\if_removeextremespaces1\fi=11 }% s'il faur retirer les espaces extr\xEAmes
+		{\loi_exparg{\loi_exparg{\readlist_i{#1}{#2}}}{\loi_removeextremespaces{#3}}}% red\xE9finir l'\xE9l\xE9ment courant
+		{\readlist_i{#1}{#2}{#3}}%
 }
-\long\def\readlist_x#1#2#3#4{% #1=compteur d'index  #2=liste restante  #3=\'el\'ement courant   #4=sep utilis\'e
+\long\def\readlist_i#1#2#3#4{% #1=compteur d'index  #2=liste restante  #3=\xE9l\xE9ment courant   #4=sep utilis\xE9
 	\loi_ifnum{0\if_ignoreemptyitems1\fi\loi_ifempty{#3}1{}=11 }
-		{\readlist_iv{#1}{#2}}% si l'on n'ignore pas les \'el\'ements vides :
-		{\loi_argcsname\loi_def{\loi_listname[\csname loi_previndex[\number\loi_nestcnt]\endcsname#1]}{#3}% assignation de l'item ctuel \`a la macro
-		\loi_argcsname\loi_def{\loi_listname sep[\csname loi_previndex[\number\loi_nestcnt]\endcsname#1]}{#4}% assignation du <sep> actuel \`a la macro \<macrolist>sep
+		{\readlist_e{#1}{#2}% si l'on n'ignore pas les \xE9l\xE9ments vides
+		}%
+		{\loi_argcsname\loi_def{\loi_listname[\csname loi_previndex[\number\loi_nestcnt]\endcsname#1]}{#3}% assignation de l'item ctuel \xE0 la macro
+		\loi_argcsname\loi_def{\loi_listname sep[\csname loi_previndex[\number\loi_nestcnt]\endcsname#1]}{#4}% assignation du <sep> actuel \xE0 la macro \<macrolist>sep
 		\loi_ifnum{\loi_nestcnt<\nestdepth\relax}% si imbrication max non atteinte
 			{\advance\loi_nestcnt1
 			\loi_argcsname\edef{loi_previndex[\number\loi_nestcnt]}{\csname loi_previndex[\number\numexpr\loi_nestcnt-1]\endcsname#1,}%
-			\readlist_ii{#3}% recommencer avec l'\'el\'ement courant
+			\readlist_c{#3}% recommencer avec l'\xE9l\xE9ment courant
 			}
 			{}%
-		\loi_exparg\readlist_iv{\number\numexpr#1+1}{#2}% puis chercher l'\'el\'ement suivant dans la liste restante
+		\loi_exparg\readlist_e{\number\numexpr#1+1}{#2}% puis chercher l'\xE9l\xE9ment suivant dans la liste restante
 		}%
 }
 
@@ -277,12 +442,12 @@
 \def\listlen#1[#2]{%
 	\romannumeral\loi_ifempty{#2}
 		{\expandafter\expandafter\expandafter\loi_stop\csname\loi_macroname#1len[0]\endcsname}
-		{\loi_exparg\listlen_i{\romannumeral-`\.\loi_macroname#1}{#2}}%
+		{\loi_exparg\listlen_a{\romannumeral-`\.\loi_macroname#1}{#2}}%
 }
-\def\listlen_i#1#2{% #1=macro name   #2=index non normalis\'e    prendre <profondeur max-1>
-	\loi_exparg{\expandafter\listlen_ii\romannumeral\loi_normalizeindex{#1}{#2}}{\number\numexpr\csname#1nest\endcsname-1}{#1}%
+\def\listlen_a#1#2{% #1=macro name   #2=index non normalis\xE9    prendre <profondeur max-1>
+	\loi_exparg{\expandafter\listlen_b\romannumeral\loi_normalizeindex{#1}{#2}}{\number\numexpr\csname#1nest\endcsname-1}{#1}%
 }
-\def\listlen_ii#1#2#3{% #1=err   #2=index normalis\'e  #3=macroname
+\def\listlen_b#1#2#3{% #1=err   #2=index normalis\xE9  #3=macroname
 	\expandafter\expandafter\expandafter\loi_stop\csname#3len[#2,0]\expandafter\endcsname
 	\romannumeral\loi_ifempty{#1}{\loi_stop}{\loi_stop\loi_error{#1}}%
 }
@@ -291,15 +456,15 @@
 %%%%%%%%%%%%%%%%%%%%%%%%% macro \foreachitem %%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \def\foreachitem#1\in#2{%
-	\edef\foreachitem_i{\noexpand\foreachitem_iii\noexpand#1{\expandafter\noexpand\csname\loi_macroname#1cnt\endcsname}{\loi_macroname#2}}%
-	\futurelet\loi_nxttok\foreachitem_ii
+	\edef\foreachitem_a{\noexpand\foreachitem_c\noexpand#1{\expandafter\noexpand\csname\loi_macroname#1cnt\endcsname}{\loi_macroname#2}}%
+	\futurelet\loi_nxttok\foreachitem_b
 }
-\def\foreachitem_ii{\loi_ifx{\loi_nxttok[}\foreachitem_i{\foreachitem_i[]}}
-\def\foreachitem_iii#1#2#3[#4]{% prendre <profondeur max-1>
-	\loi_exparg{\expandafter\foreachitem_iv\romannumeral\loi_normalizeindex{#3}{#4}}{\number\numexpr\csname#3nest\endcsname-1}#1{#2}{#3}%
+\def\foreachitem_b{\loi_ifx{\loi_nxttok[}\foreachitem_a{\foreachitem_a[]}}
+\def\foreachitem_c#1#2#3[#4]{% prendre <profondeur max-1>
+	\loi_exparg{\expandafter\foreachitem_d\romannumeral\loi_normalizeindex{#3}{#4}}{\number\numexpr\csname#3nest\endcsname-1}#1{#2}{#3}%
 }
-\def\foreachitem_iv#1#2{\loi_ifempty{#2}{\foreachitem_v{#1}{}}{\foreachitem_v{#1}{#2,}}}% #1=err  #2=index norm
-\long\def\foreachitem_v#1#2#3#4#5#6{% #1=err  #2=index norm  #3=macroiter  #4=compteur associ\'e  #5=nom de macrolist  #6=code
+\def\foreachitem_d#1#2{\loi_ifempty{#2}{\foreachitem_e{#1}{}}{\foreachitem_e{#1}{#2,}}}% #1=err  #2=index norm
+\long\def\foreachitem_e#1#2#3#4#5#6{% #1=err  #2=index norm  #3=macroiter  #4=compteur associ\xE9  #5=nom de macrolist  #6=code
 	\loi_ifnum{\csname#5len[#20]\endcsname>0 }
 		{\loi_ifempty{#1}{}{\loi_error{#1}}%
 		\loi_fornum#4=1to\csname#5len[#20]\endcsname\do{\loi_argcsname\let#3{#5[#2#4]}#6}%
@@ -310,14 +475,14 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%% macro \showitem %%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\def\showitems{\loi_ifstar{\let\showitems_cmd\detokenize\showitems_i}{\let\showitems_cmd\loi_identity\showitems_i}}
-\def\showitems_i#1{\def\showitems_ii{\showitems_iv#1}\futurelet\loi_nxttok\showitems_iii}
-\def\showitems_iii{\loi_ifx{\loi_nxttok[}\showitems_ii{\showitems_ii[]}}
-\def\showitems_iv#1[#2]{\foreachitem\showitems_iter\in#1[#2]{\showitemsmacro{\expandafter\showitems_cmd\expandafter{\showitems_iter}}}}
+\def\showitems{\loi_ifstar{\let\showitems_cmd\detokenize\showitems_a}{\let\showitems_cmd\loi_identity\showitems_a}}
+\def\showitems_a#1{\def\showitems_b{\showitems_d#1}\futurelet\loi_nxttok\showitems_c}
+\def\showitems_c{\loi_ifx{\loi_nxttok[}\showitems_b{\showitems_b[]}}
+\def\showitems_d#1[#2]{\foreachitem\showitems_ater\in#1[#2]{\showitemsmacro{\expandafter\showitems_cmd\expandafter{\showitems_ater}}}}
 \unless\ifdefined\fbox
-	\newdimen\fboxrule \newdimen\fboxsep \fboxrule=.4pt \fboxsep=3pt % r\'eglages identiques \`a LaTeX
-	\def\fbox#1{% imitation de la macro \fbox de LaTeX, voir codes 251 \`a 254 ici --> http://progtex.fr/wp-content/uploads/2014/09/code.txt
-		\hbox{% et pages 271 \`a 274 de "Apprendre \`a programmer en TeX"
+	\newdimen\fboxrule \newdimen\fboxsep \fboxrule=.4pt \fboxsep=3pt % r\xE9glages identiques \xE0 LaTeX
+	\def\fbox#1{% imitation de la macro \fbox de LaTeX, voir pages 271 \xE0 274 de "Apprendre \xE0 programmer en TeX"
+		\hbox{%
 			\vrule width\fboxrule
 			\vtop{%
 				\vbox{\hrule height\fboxrule \kern\fboxsep \hbox{\kern\fboxsep#1\kern\fboxsep}}%
@@ -326,7 +491,7 @@
 		}%
 	}
 \fi
-\def\showitemsmacro#1{% encadrement par d\'efaut
+\def\showitemsmacro#1{% encadrement par d\xE9faut
 	\begingroup\fboxsep=0.25pt \fboxrule=0.5pt \fbox{\strut#1}\endgroup
 	\hskip0.25em\relax
 }
@@ -336,19 +501,19 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \def\itemtomacro#1[#2]{% #1[#2]=item  non encore lu: #3=macro
 	\edef\loi_listname{\loi_macroname#1}%
-	\loi_exparg{\expandafter\itemtomacro_i\romannumeral\expandafter\loi_normalizeindex\expandafter{\loi_listname}{#2}}{\csname\loi_listname nest\endcsname}\let
+	\loi_exparg{\expandafter\itemtomacro_a\romannumeral\expandafter\loi_normalizeindex\expandafter{\loi_listname}{#2}}{\csname\loi_listname nest\endcsname}\let
 }
 \def\gitemtomacro#1[#2]{% #1[#2]=item
 	\xdef\loi_listname{\loi_macroname#1}%
-	\loi_exparg{\expandafter\itemtomacro_i\romannumeral\expandafter\loi_normalizeindex\expandafter{\loi_listname}{#2}}{\csname\loi_listname nest\endcsname}{\global\let}%
+	\loi_exparg{\expandafter\itemtomacro_a\romannumeral\expandafter\loi_normalizeindex\expandafter{\loi_listname}{#2}}{\csname\loi_listname nest\endcsname}{\global\let}%
 }
-\def\itemtomacro_i#1#2#3#4{%
+\def\itemtomacro_a#1#2#3#4{%
 	\loi_ifempty{#1}{}{\loi_error{#1}}%
 	\loi_argcsname#3#4{\loi_listname[#2]}%
 }
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%% r\'eglages par d\'efaut %%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%% r\xE9glages par d\xE9faut %%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \newif\if_removeextremespaces
 \newif\if_ignoreemptyitems
@@ -355,6 +520,8 @@
 \let\ignoreemptyitems\_ignoreemptyitemstrue
 \let\reademptyitems\_ignoreemptyitemsfalse
 \setsepchar{,}
+\defpair{}
+\loi_def_foreachsep{,}
 \reademptyitems
 
 \loi_restorecatcode
@@ -361,25 +528,25 @@
 \endinput
 
 ######################################################################
-#                             Historique                             #
+############################  Historique #############################
 ######################################################################
 
 v1.0  19/8/2016
-  - Premi\`ere version publique
+  - Premi\xE8re version publique
 
 v1.1  01/09/2016
-  - Stockage des s\'eparateurs dans <macrolist>sep
-  - bug corrig\'e dans \loi_restorecatcode
+  - Stockage des s\xE9parateurs dans <macrolist>sep
+  - bug corrig\xE9 dans \loi_restorecatcode
 
 v1.2  22/10/2016
-  - macros \greadlist et \gitemtomacro pour la globalit\'e
+  - macros \greadlist et \gitemtomacro pour la globalit\xE9
 
 v1.3  18/11/2016
-  - bugs corrig\'es dans la gestion de la globalit\'e
+  - bugs corrig\xE9s dans la gestion de la globalit\xE9
 
 v1.4  05/10/2017
-  - test \loi_ifprimitive ajout\'e au test \loi_ifcs
-  - suppression de \loi_expafternil, cr\'eation de \loi_expafter,
+  - test \loi_ifprimitive ajout\xE9 au test \loi_ifcs
+  - suppression de \loi_expafternil, cr\xE9ation de \loi_expafter,
     modification de \loi_argcsname
   - correction d'un bug : \setsepchar{\par} ne provoque plus
     d'erreur. \loi_ifnum devient \long
@@ -391,7 +558,10 @@
   - correction d'un bug dans \loi_ifcs
 
 v1.52 13/01/2018
-  - le dernier s\'eparateur est <vide>
+  - le dernier s\xE9parateur est <vide>
 
 v1.53 13/03/2018
-  - correction d'un bug dans \readlist_vii
\ No newline at end of file
+  - correction d'un bug dans \readlist_g
+
+v1.6 01/11/2018
+  - possibilit\xE9 d'appariement de tokens dans les items
\ No newline at end of file



More information about the tex-live-commits mailing list