% Ce fichier contient le code TeX de l'extension "autoaligne" % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % \def\aanom {autoaligne} % \def\aaversion {1.2} % % % \def\aadate {2016/10/22} % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % -------------------------------------------------------------------- % 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 ! % -------------------------------------------------------------------- % L'extension autoaligne est compos\'ee des 5 fichiers suivants : % - code : listofitems (.tex et .sty) % - manuel en francais : listofitems-fr (.tex et .pdf) % - fichier lisezmoi : README % -------------------------------------------------------------------- \expandafter\edef\csname aa_restaure_catcode\endcsname{\catcode\number`\_=\number\catcode`\_\relax} \catcode`\_11 \def\aa_listofitems_version_mini{1.1} \ifdefined\PackageError \def\aa_erreur#1{\PackageError\aanom{#1}{Read the manual}}% pour LaTeX \else \def\aa_erreur#1{\errmessage{Package \aanom\space Error: #1^^J}}% pour TeX \fi \begingroup \edef\__tempa{\meaning\eTeXversion}\edef\__tempb{\string\eTeXversion}% \ifx\__tempa\__tempb\endgroup \else\endgroup \aa_erreur{Vous n'utilisez pas un moteur eTeX, \aanom\space ne peut donc pas fonctionner}% \expandafter\aa_restaure_catcode\expandafter\endinput \fi \unless\ifdefined\loiname \input listofitems.tex \fi \ifdim\loiver pt<\aa_listofitems_version_mini pt \aa_erreur{\loiname\space est en version v\loiver\space et \aanom\space requiert la v\aa_listofitems_version_mini\space ou plus}% \expandafter\aa_restaure_catcode\expandafter\endinput \fi \let\aa_sep_terme_vide\relax \let\aa_sep_membre_vide\relax \def\aa_compose_en_mode_math#1{$\relax#1$} \def\aa_devdev_arg#1{\loi_exparg{\loi_exparg{#1}}} \def\aavcoeff#{\def\aa_v_coeff} \newtoks\aa_liste_tokens \def\aa_ajoute_au_toks#1{\aa_liste_tokens\expandafter{\the\aa_liste_tokens#1}} \def\aa_developpe_et_ajoute_au_toks#1{\loi_exparg\aa_ajoute_au_toks{#1}} \def\egaldevantmembrevide{\chardef\aa_egal_devant_membre_vide} \egaldevantmembrevide=0% pas de signe = devant un membre vide \def\aa_def_tok#1#2{\let#1= #2\empty}\aa_def_tok\aa_tok_espace{ } \def\aa_si_prochain_tok_est#1#2#3{% \aa_def_tok\aa_test_tok{#1}\def\aa_code_vrai{#2}\def\aa_code_faux{#3}% \aa_si_prochain_tok_est_i } \def\aa_si_prochain_tok_est_i{\futurelet\aa_prochain_token\aa_si_prochain_tok_est_ii} \def\aa_si_prochain_tok_est_ii{% \loi_ifx{\aa_prochain_token\aa_tok_espace} {\afterassignment\aa_si_prochain_tok_est_i\let\aa_prochain_token= } {\loi_ifx{\aa_prochain_token\aa_test_tok}\aa_code_vrai\aa_code_faux}% } \def\aa_si_commence_par#1#2{% \def\aa_si_commence_par_i##1#2##2\_nil{\loi_exparg\loi_ifempty{\loi_gobarg##1}}% \aa_si_commence_par_i\relax#1#2\_nil } \def\definirseparateurs#1#2#3{% \loi_ifempty{#1} {\aa_erreur{Separateur entre lignes non permis, "\string\\" retenu}% \definirseparateurs{\\}{#2}{#3}% } {\loi_ifempty{#2#3} {\aa_erreur{Separateurs de membre et de terme : "=" et "+||-" retenus}% \definirseparateurs{#1}{=}{+||-}% } {\loi_ifempty{#2} {\definirseparateurs{#1}{\aa_sep_membre_vide}{#3}% } {\loi_ifempty{#3} {\def\aa_liste_separateurs{#1_#2_\aa_sep_terme_vide}} {\def\aa_liste_separateurs{#1_#2_#3}}% }% }% }% } \definirseparateurs{\\}{=}{+||-}% s\'eparateurs par d\'efaut \def\definirespacements{\aa_si_prochain_tok_est[\definirespacements_i{\definirespacements_i[,]}} \def\definirespacements_i[#1,#2]#3#4{% #3=espace avant & apr\`es s\'eparateurs 2 #4=espace avant & apr\`es s\'eparateurs 3 \edef\aa_insere_espacement_avant{\aa_devdev_arg\loi_ifempty{\loi_removeextremespaces{#1}}{}{\hskip\glueexpr#1\relax}}% \edef\aa_insere_espacement_apres{\aa_devdev_arg\loi_ifempty{\loi_removeextremespaces{#2}}{}{\hskip\glueexpr#2\relax}}% \edef\aa_espacement_signe{\dimexpr\loi_ifempty{#3}{0pt}{#3}\relax}% \edef\aa_espacement_terme{\dimexpr\loi_ifempty{#4}{0pt}{#4}\relax}% } \definirespacements[,]{0pt}{0pt}% espacements par d\'efaut \def\aa_si_contient_moins#1{\aa_si_contient_moins_i||#1||||-||\_nil}% "||-||" est-il dans #1 ? \def\aa_si_contient_moins_i#1||-||#2\_nil{\loi_ifempty{#2}\loi_second\loi_first} \def\aa_trouver_moins_dans_separateur_de_termes{\expandafter\aa_trouver_moins_dans_separateur_de_termes_i\aa_liste_separateurs\_nil} \def\aa_trouver_moins_dans_separateur_de_termes_i#1_#2_#3\_nil{% \aa_si_contient_moins{#2} {2} {\aa_si_contient_moins{#3}{3}{-1}}% } \def\aa_ajoute_si_existe#1{\ifcsname#1\endcsname\loi_argcsname\aa_developpe_et_ajoute_au_toks{#1}\fi} \def\aa_alignement_signe{\hfil\kern\aa_espacement_signe${}##{}$\kern\aa_espacement_signe\hfil}% pour "=", "+" ou "-" \def\aa_alignement_terme_c{\hfil\kern\aa_espacement_terme$##$\kern\aa_espacement_terme\hfil} \def\aa_alignement_terme_d{\hfil\kern\aa_espacement_terme$##$\kern\aa_espacement_terme} \def\aa_alignement_terme_g{\kern\aa_espacement_terme$##$\kern\aa_espacement_terme\hfil} \def\autoaligne{% \relax\iffalse{\fi\ifnum0=`}\fi \begingroup \aa_si_prochain_tok_est[ {\autoaligne_crochet} {\aa_si_prochain_tok_est({\autoaligne_paren}{\autoaligne_i[*d](c)}}% } \def\autoaligne_crochet[#1]{\aa_si_prochain_tok_est({\autoaligne_i[#1]}{\autoaligne_i[#1](c)}} \def\autoaligne_paren(#1){\aa_si_prochain_tok_est[{\autoaligne_permute_argopt(#1)}{\autoaligne_i[*d](#1)}} \def\autoaligne_permute_argopt(#1)[#2]{\autoaligne_i[#2](#1)} \def\autoaligne_i[#1]{% \loi_ifempty{#1} {\aa_erreur{Consigne d'alignement vide, "*d" est retenue}% \autoaligne_i[*d]% } {\def\aa_consigne_alignement_general{}% \aa_si_commence_par{#1}* {\aa_trouve_consigne_alignement_general#1d\_nil} {\aa_trouve_consigne_alignement_par_membre{#1}}% \autoaligne_ii }% } \def\autoaligne_ii(#1){% \loi_ifempty{#1} {\aa_erreur{Consigne de position vide, "c" est retenue} \autoaligne_ii(c)% } {\edef\aa_consigne_alignement_vertical{\aa_verifie_consigne_alignement chb{#1}}% \loi_ifnum{\aa_consigne_alignement_vertical=0 } {\aa_erreur{Consigne d'alignement vertical "\detokenize{#1}" non reconnue, "c" est retenue}% \def\aa_consigne_alignement_general{1}% }% {}% \autoaligne_iii }% } \def\aa_trouve_consigne_alignement_general*#1#2\_nil{% \loi_ifnum{\aa_verifie_consigne_alignement cdg{#1}=0 } {\aa_erreur{Consigne d'alignement "\detokenize{#1}" non reconnue, "d" est retenue}% \def\aa_consigne_alignement_general{d}% } {\def\aa_consigne_alignement_general{#1}}% } \def\aa_trouve_consigne_alignement_par_membre#1{\aa_trouve_consigne_alignement_par_membre_i1#1\loi_quark} \def\aa_trouve_consigne_alignement_par_membre_i#1#2{% \loi_ifx{#2\loi_quark} {} {\loi_ifnum{\aa_verifie_consigne_alignement cdg{#2}=0 } {\aa_erreur{Consigne d'alignement "\detokenize{#2}" non reconnue, "d" est retenue}% \loi_argcsname\def{aa_alignement_membre[#1]}{d}% } {\loi_argcsname\def{aa_alignement_membre[#1]}{#2}}% \loi_exparg\aa_trouve_consigne_alignement_par_membre_i{\number\numexpr#1+1}% }% } \def\aa_verifie_consigne_alignement#1#2#3#4{% #1,#2,#3=lettres admises #4=consigne c, d ou g --> renvoie un nombre (1,2 ou 3=ok, 0=erreur) 0\if\string #1\expandafter\loi_firsttonil\detokenize{#4x}\_nil1\else \if\string #2\expandafter\loi_firsttonil\detokenize{#4x}\_nil2\else \if\string #3\expandafter\loi_firsttonil\detokenize{#4x}\_nil3\fi\fi\fi } \def\autoaligne_iii#1{% #1=tableau \def\-{-}\def\+{+}% \loi_exparg{\setsepchar[_]}{\aa_liste_separateurs}% \edef\aa_numero_separateur_contenant_signe_moins{\aa_trouver_moins_dans_separateur_de_termes}% \def\readlist_iii##1||##2\_nil##3{% red\'efinir \readlist_iii pour que \loi_ifnum{\loi_nestcnt=\aa_numero_separateur_contenant_signe_moins\relax}% si la profondeur est celle o\`u il a y a un "-" {\aa_si_commence_par{##30}{-}% et que la liste restant \`a examiner commence par "-" alors {\loi_exparg{\readlist_iv1}{\expandafter\-\loi_gobarg##3##1}}% remplacer ce "-" par \- {\readlist_iv1{##3##1}}% } {\readlist_iv1{##3##1}}% }% \reademptyitems \readlist\aa_termes{#1}% \let\aa_nombre_de_lignes\aa_termeslen% nombre de lignes \def\aa_nombre_de_membres{0}% \loi_fornum\aa_ligne_index=1to\aa_termeslen\do{% pour chaque ligne \ifnum\csname aa_termeslen[\aa_ligne_index,0]\endcsname>\aa_nombre_de_membres \loi_argcsname\let\aa_nombre_de_membres{aa_termeslen[\aa_ligne_index,0]}% mettre \`a jour le nombre max de membres \fi \loi_fornum\aa_membre_index=1to\csname aa_termeslen[\aa_ligne_index,0]\endcsname\do{% pour chaque membre \loi_argcsname\let\aa_nombre_de_termes_courant{aa_termeslen[\aa_ligne_index,\aa_membre_index,0]}% \ifcsname aa_nbtermes_\aa_membre_index\endcsname% mettre \`a jour le nombre max de termes dans ce membre \ifnum\aa_nombre_de_termes_courant>\csname aa_nbtermes_\aa_membre_index\endcsname\relax \loi_argcsname\let{aa_nbtermes_\aa_membre_index}\aa_nombre_de_termes_courant \fi \else \loi_argcsname\let{aa_nbtermes_\aa_membre_index}\aa_nombre_de_termes_courant \fi }% }% \aa_liste_tokens{}% % construction du pr\'eambule de l'alignement \loi_fornum\aa_membre_index=1to\aa_nombre_de_membres\do{% \loi_fornum\aa_terme_index=1to\csname aa_nbtermes_\aa_membre_index\endcsname\do{% \ifx\aa_consigne_alignement_general\empty \ifcsname aa_alignement_membre[\aa_membre_index]\endcsname \loi_argcsname\aa_developpe_et_ajoute_au_toks{aa_alignement_terme_\csname aa_alignement_membre[\aa_membre_index]\endcsname}% terme \else \aa_erreur{Pas assez de consignes d'alignement, "d" est retenue}% \aa_developpe_et_ajoute_au_toks{\aa_alignement_terme_d}% \fi \else \loi_argcsname\aa_developpe_et_ajoute_au_toks{aa_alignement_terme_\aa_consigne_alignement_general}% \fi \ifnum\aa_terme_index<\csname aa_nbtermes_\aa_membre_index\endcsname\relax \aa_developpe_et_ajoute_au_toks{\expandafter&\aa_alignement_signe&}% signe \fi }% \ifnum\aa_membre_index<\aa_nombre_de_membres\relax \aa_developpe_et_ajoute_au_toks{\expandafter&\aa_alignement_signe&}% \'egalit\'e \fi }% \aa_ajoute_au_toks\cr % fin du pr\'eambule, construction du corps de l'alignement \loi_fornum\aa_ligne_index=1to\aa_termeslen\do{% pour chaque ligne, \loi_fornum\aa_membre_index=1to\aa_nombre_de_membres\do{% chaque membre \def\aa_terme_non_vide_vu{0}% \loi_fornum\aa_terme_index=1to\csname aa_nbtermes_\aa_membre_index\endcsname\do{% et chaque terme \aa_ajoute_si_existe{aa_termes[\aa_ligne_index,\aa_membre_index,\aa_terme_index]}% ajouter le terme \ifcsname aa_termes[\aa_ligne_index,\aa_membre_index,\aa_terme_index]\endcsname% si le terme existe \loi_argcsname\loi_exparg\loi_ifempty{aa_termes[\aa_ligne_index,\aa_membre_index,\aa_terme_index]} {} {\def\aa_terme_non_vide_vu{1}}% et qu'il est non vide, s'en souvenir \fi \ifnum\aa_terme_index<\csname aa_nbtermes_\aa_membre_index\endcsname\relax% passer \`a l'ajout \'eventuel du signe + ou - \aa_ajoute_au_toks&% \loi_ifnum{% ins\'erer signe si index correct ET terme suivant non vide ET (un terme non vide a \'et\'e rencontr\'e OU signe="-" \numexpr1\loi_ifnum{\aa_terme_index<\csname aa_termeslen[\aa_ligne_index,\aa_membre_index,0]\endcsname\space}10% \loi_exparg{\loi_exparg\loi_ifempty}{\csname aa_termes[\aa_ligne_index,\aa_membre_index,\number\numexpr\aa_terme_index+1]\endcsname}01% +\aa_terme_non_vide_vu +\if\string-\expandafter\loi_firsttonil\detokenize\expandafter\expandafter\expandafter{\csname aa_termessep[\aa_ligne_index,\aa_membre_index,\aa_terme_index]\endcsname}\_nil1\else0\fi>111 } {\aa_ajoute_si_existe{aa_termessep[\aa_ligne_index,\aa_membre_index,\aa_terme_index]}}% {\aa_ajoute_au_toks{\hphantom{\hbox{${}+{}$}}}}% sinon, encombrement horizontal \aa_ajoute_au_toks&% \fi }% \ifnum\aa_membre_index<\aa_nombre_de_membres\relax \aa_ajoute_au_toks&% puis, ajouter le signe "=" si... \ifcsname aa_termes[\aa_ligne_index,\number\numexpr\aa_membre_index+1]\endcsname% le terme suivant existe \ifnum\aa_egal_devant_membre_vide=0 % et si on ne tient compte des = devant les membres vides \loi_argcsname\loi_exparg\loi_ifempty{aa_termes[\aa_ligne_index,\number\numexpr\aa_membre_index+1]} {}% et si'il n'est pas vide {\aa_ajoute_si_existe{aa_termessep[\aa_ligne_index,\aa_membre_index]}}% \else \aa_ajoute_si_existe{aa_termessep[\aa_ligne_index,\aa_membre_index]}% \fi \fi \aa_ajoute_au_toks&% \fi }% \aa_ajoute_au_toks\cr }% \aa_ajoute_au_toks\crcr \aa_insere_espacement_avant \ifcase\aa_consigne_alignement_vertical\relax \or \let\aa_boite_externe\vcenter \csname\ifmmode loi_identity\else aa_compose_en_mode_math\fi\expandafter\endcsname \or \let\aa_boite_externe\vtop \expandafter\loi_identity \or \let\aa_boite_externe\vbox \expandafter\loi_identity \fi {\aa_boite_externe{% \lineskiplimit0pt \lineskip0pt \baselineskip\aa_v_coeff\baselineskip \halign\expandafter{\the\aa_liste_tokens}% }% }% \aa_insere_espacement_apres \endgroup } \aavcoeff{1}% par d\'efaut \aa_restaure_catcode \endinput v1.0 01/09/2016 - premi\`ere version publique v1.1 06/10/2016 - correction d'un bug dans \autoaligne_iii qui mangeait le \endgroup final v1.2 22/10/2016 - possibilit\'e de d\'efinir les s\'eparateurs - possibilit\'e de d\'efinir les espaces additionnelles autour des s\'eparateurs - possibilit\'e de d\'efinir les espaces ins\'er\'ees avant et apr\`es l'alignement