% !TeX encoding = UTF-8 % Ce fichier contient le code de l'extension "systeme" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % \def\SYSname {systeme} % \def\SYSver {0.4} % % % \def\SYSdate {2025/05/13} % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % Author : Christian Tellechea % % Status : Maintained % % Email : unbonpetit@netc.fr % % Package URL: https://www.ctan.org/pkg/systeme % % Copyright : Christian Tellechea 2011-2025 % % Licence : Released under the LaTeX Project Public License v1.3c % % or later, see http://www.latex-project.org/lppl.txt % % Files : 1) systeme.tex % % 2) systeme.sty % % 3) systeme-fr.tex % % 4) systeme-fr.pdf % % 5) README % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %--------------------------------------------------------------------- %---------------- Annonce package et autres pré-requis --------------- %--------------------------------------------------------------------- \csname SYS_load_once\endcsname \expandafter\let\csname SYS_load_once\endcsname\endinput \ifdefined\SYSstyfile \expandafter\def\csname SYS_error\endcsname#1{\PackageError\SYSname{#1}{Lire le manuel de \SYSname}}% pour LaTeX \else \immediate\write-1 {Package: \SYSname\space\SYSdate\space\space v\SYSver\space\space Saisie naturelle de systèmes d'équations (CT)}% \expandafter\def\csname SYS_error\endcsname#1{\errmessage{Package \SYSname\space Error: #1^^J}}% pour TeX \fi \expandafter\edef\csname SYS_restore_catcode\endcsname{\catcode\number`\_=\number\catcode`\_\relax} \catcode`\_11 \def\SYS_antefi#1\fi{\fi#1} \unless\ifdefined\xstringversion \SYS_antefi\input xstring.tex\relax% TODO : mettre un loadonce dans xstring, c'est insupportable \fi \input simplekv.tex \ifdefined\usepackage\else% on n'utilise pas LaTeX ? \newskip\normalbaselineskip \normalbaselineskip=12pt \fi %--------------------------------------------------------------------- %---------------------------- Allocations ---------------------------- %--------------------------------------------------------------------- \newtoks\SYS_tab_toks % contient le code du corps du \halign \newtoks\SYS_preamble_toks % contient le préamlule du \halogn \newif\ifSYS_first_term \newif\ifSYS_align_terms \newif\ifSYS_extra_col \newif\ifSYS_autonum \newif\ifSYS_autonum_continue \newif\ifSYS_left_member \newcount\SYSeqnum % compteur d'éqution principal %--------------------------------------------------------------------- %------------------------- Macros auxiliaires ------------------------ %--------------------------------------------------------------------- \begingroup \catcode`\_8 \expandafter\gdef\csname SYS\string_underscore\endcsname{_} \endgroup \def\SYS_deftok#1#2{\let#1= #2\relax} \SYS_deftok\SYS_sptoken{ } \def\SYS_ifnxttok#1#2#3{% \SYS_deftok\SYS_toksmatch{#1}% \def\SYS__truecode{#2}% \def\SYS__falsecode{#3}% \SYS_ifnxttok_a } \def\SYS_ifnxttok_a{\futurelet\SYS__futurtok\SYS_ifnxttok_b} \def\SYS_ifnxttok_b{% \SYS_ifx{\SYS__futurtok\SYS_sptoken} {% \afterassignment\SYS_ifnxttok_a\let\SYS__futurtok= } {% \SYS_ifx{\SYS__futurtok\SYS_toksmatch} \SYS__truecode \SYS__falsecode }% } \def\SYS_testopt#1#2{\SYS_ifnxttok[{#1}{#1[{#2}]}} \def\SYS_exec_first#1#2{#1} \def\SYS_exec_second#1#2{#2} \def\SYS_id#1{#1} \def\SYS_gobone#1{} \def\SYS_gobtwo#1#2{} \def\SYS_gobtonil#1\_nil{} \def\SYS_earg#1#2{\expandafter\SYS_earg_a\expandafter{#2}{#1}}% \def\SYS_earg_a#1#2{#2{#1}} \def\SYS_eearg#1#2{\SYS_earg{\SYS_earg{#1}}{#2}} \def\SYS_addtotok#1#2{#1\expandafter{\the#1#2}} \def\SYS_xaddtotok#1#2{\SYS_eaddtotok#1{\expanded{#2}}} \def\SYS_eaddtotok#1#2{\SYS_earg{\SYS_addtotok#1}{#2}} \def\SYS_add_to_tab{\SYS_addtotok\SYS_tab_toks} \def\SYS_addtomacro#1#2{\SYS_earg{\def#1}{#1#2}} \def\SYS_eaddtomacro#1#2{\SYS_earg{\SYS_addtomacro#1}{#2}} \def\SYS_eeaddtomacro#1#2{\SYS_earg{\SYS_eaddtomacro#1}{#2}} \def\SYS_csdef#1{\expandafter\def\csname#1\endcsname} \def\SYS_cslet#1{\expandafter\let\csname#1\endcsname} \def\SYS_letcs#1#2{\expandafter\let\expandafter#1\csname#2\endcsname} \def\SYS_first_in_list#1,#2\_nil{#1} \def\SYS_remove_first_in_list#1,{} \def\SYS_if#1{\if#1\expandafter\SYS_exec_first\else\expandafter\SYS_exec_second\fi} \def\SYS_ifx#1{\ifx#1\expandafter\SYS_exec_first\else\expandafter\SYS_exec_second\fi} \def\SYS_ifnum#1{\ifnum#1\expandafter\SYS_exec_first\else\expandafter\SYS_exec_second\fi} \def\SYS_ifempty#1{\SYS_if{\relax\detokenize{#1}\relax}} \def\SYS_ifinstr#1#2{% \def\SYS_ifinstr_a##1#2##2\_nil{\SYS_ifempty{##2}\SYS_exec_second\SYS_exec_first}% \SYS_ifinstr_a#1\SYS__nil#2\_nil } \def\SYS_ifplus#1{\SYS_if{+#1}} \def\SYS_stripsp#1{% \def\SYS_stripsp##1##2{\expanded{\SYS_stripsp_a\_marksp##2\SYS__nil\_marksp#1\_marksp\_nil{##1}}}% \def\SYS_stripsp_a##1\_marksp#1##2\_marksp##3\_nil{\SYS_stripsp_b##3##1##2\SYS__nil#1\SYS__nil\_nil}% \def\SYS_stripsp_b##1#1\SYS__nil##2\_nil{\SYS_stripsp_c##1##2\_nil}% \def\SYS_stripsp_c##1##2\SYS__nil##3\_nil##4{\unexpanded{##4{##2}}}% } \SYS_stripsp{ } \def\SYS_remove_item_in_list#1#2{% enlève l'item #2 de la sc #1 qui contient une liste \saveexpandmode\expandarg \IfSubStr{\expandafter,#1,}{,#2,} {% \StrSubstitute{\expandafter\_nil\expandafter,#1,\_nil}{,#2,},[#1]% \StrDel#1{\noexpand\_nil,}[#1]% \StrDel#1{,\_nil}[#1]% }% {}% \restoreexpandmode } \def\SYS_first_to_nil#1#2\_nil{#1} \def\SYS_if_first_letter#1#2{\SYS_stripsp{\SYS_if_first_letter_a{#1}}{#2}} \def\SYS_if_first_letter_a#1#2{\SYS_if{\string#1\expandafter\SYS_first_to_nil\detokenize{#2.}\_nil}} \def\SYS_enter_math#1{$\relax#1$} %--------------------------------------------------------------------- %-------------- Pattern des noms des macros de stockages ------------- %--------------------------------------------------------------------- \def\SYS_set_member#1{\edef\SYS_member_index{\SYS_format_member_number{#1}}} \def\SYS_format_member_number#1{[#1]} \def\SYS_format_term_name#1#2#3{(#1)#2_\detokenize\expandafter{#3}}% #1=n° equation #2=membre \SYS_member_index #3=inconnue \def\SYS_format_const_name#1#2{\SYS_format_term_name{#1}{#2}{const}}% #1=n° equation #2=membre \SYS_member_index \def\SYS_format_membersep_name#1{(#1)} %--------------------------------------------------------------------- %------------------ Macros exécutant les réglages -------------------- %--------------------------------------------------------------------- %## setalign \def\SYS_set_align#1{% \SYS_ifempty{#1} {% \SYS_set_align_a r% } {% \SYS_set_align_a#1% },l,\_nil } \def\SYS_set_align_a#1,#2,#3\_nil{% \SYS_csdef{SYS_column_\SYS_format_member_number{1}_right}{\hfil}% \SYS_if_first_letter c{#1}% {% \SYS_csdef{SYS_column_\SYS_format_member_number{1}_left}{\hfil}% } {% \SYS_if_first_letter l{#1}% {% \SYS_cslet{SYS_column_\SYS_format_member_number{1}_left}\empty } {% \SYS_csdef{SYS_column_\SYS_format_member_number{1}_left}{\hfil}% \SYS_cslet{SYS_column_\SYS_format_member_number{1}_right}\empty }% }% \SYS_csdef{SYS_column_\SYS_format_member_number{2}_left}{\hfil}% \SYS_if_first_letter c{#2}% {% \SYS_csdef{SYS_column_\SYS_format_member_number{2}_right}{\hfil}% } {% \SYS_if_first_letter r{#2}% {% \SYS_cslet{SYS_column_\SYS_format_member_number{2}_right}\empty } {% \SYS_cslet{SYS_column_\SYS_format_member_number{2}_left}\empty \SYS_csdef{SYS_column_\SYS_format_member_number{2}_right}{\hfil}% }% }% } %## add_membersep_subst \def\SYS_membersep_subst_list{} \def\SYS_add_membersep_susbt#1{% \SYS_add_membersep_susbt_a#1\_nil } \def\SYS_add_membersep_susbt_a#1,#2\_nil{% \SYS_stripsp{\SYS_stripsp\SYS_add_membersep_susbt_b{#1}}{#2}% } \def\SYS_add_membersep_susbt_b#1#2{% \IfSubStr\SYS_membersep_subst_list{\noexpand#1,} {} {% \SYS_addtomacro\SYS_membersep_subst_list{#1,}% }% \SYS_csdef{SYS_membersep_subst__\detokenize{#1}}{#2}% } %## set_sign_space \def\SYS_set_sign_space#1{% \edef\SYS_sign_space{% \ifdim#1>0pt \hskip\the\dimexpr#1\relax\relax\fi }% } %## set_membresep_space \def\SYS_set_membersep_space#1{% \edef\SYS_membersep_space{% \ifdim#1>0pt \hskip\the\dimexpr#1\relax\relax\fi }% } %## set_delim \def\SYS_set_delim#1{% \SYS_set_delim_a#1\_nil } \def\SYS_set_delim_a#1,#2\_nil{% \edef\SYS_delim_left {% \left \SYS_ifempty{#1} {\noexpand\{} {\noexpand#1}% }% \edef\SYS_delim_right{% \right \SYS_ifempty{#2} {.} {\noexpand#2}% }% } %## add_membersep_sign \def\SYS_add_membersep_sign#1{% \saveexpandmode\expandarg \IfSubStr{\expandafter,\SYS_membersep_list,}{,#1,} {} {% \SYS_earg{\def\SYS_membersep_list}{\SYS_membersep_list,#1}% }% \restoreexpandmode } %## remove_membersep \def\SYS_remove_membersep#1{% \SYS_remove_item_in_list\SYS_membersep_list{#1}% \SYS_remove_item_in_list\SYS_membersep_subst_list{#1}% } \def\SYS_set_extra_col_sign#1{ \expandafter\SYS_set_extra_col_sign_a\detokenize{#1@}\relax } \def\SYS_set_extra_col_sign_a#1#2\relax{% \def\SYS_extra_col_sign{#1}% } %## set_autonum \def\SYS_set_autonum#1{% \SYS_ifempty{#1} {% \SYS_extra_colfalse \SYS_autonumfalse } {% \SYS_extra_coltrue \SYS_autonumtrue \def\SYS_autonum_arg{#1}% }% } %## set_sort \def\SYS_set_sort#1{% \StrDel{\noexpand#1}{ }[\SYS_sort_directives]% \IfSubStr\SYS_sort_directives= {% \StrCut\SYS_sort_directives=\SYS_sort_left\SYS_sort_right } {% \let\SYS_sort_left\SYS_sort_directives \let\SYS_sort_right\SYS_sort_directives }% } %## coeff_space \def\SYS_set_term_coeff_space#1{% \def\SYS_term_coeff_space{}% \SYS_ifempty{#1} {} {% \begingroup \setbox0\hbox{$\mkern#1$}% \expandafter\endgroup \ifdim\wd0<0pt \SYS_error{L'espace math doit être positive, 0mu retenu}% \fi \edef\SYS_term_coeff_space{\ifdim\wd0>0pt \mkern#1\relax\fi}% }% } %## post subst \def\SYS_set_post_subst#1{% \let\SYS_post_subst_list\empty \SYS_ifempty{#1} {} {% \SYS_set_post_subst_a#1\SYS_set_post_subst\SYS_set_post_subst }% } \def\SYS_set_post_subst_a#1#2{% #1->#2 par substitution \SYS_ifx{#1\SYS_set_post_subst} {}% {% \SYS_ifx{#2\SYS_set_post_subst} {% \SYS_error{'post subst' requiert un nombre pair^^Jd'arguments, consigne ignorée}% \let\SYS_post_subst_list\empty \SYS_gobone }% {% \SYS_addtomacro\SYS_post_subst_list{\StrSubstitute\SYS_system_code{\noexpand#1}{\noexpand#2}[\SYS_system_code]}% \SYS_set_post_subst_a }% }% } %## set store \def\SYS_set_store#1{% \saveexpandmode \saveexploremode \exploregroups \expandarg \StrRemoveBraces{\noexpand#1}[\SYS_store_directive]% \StrDel\SYS_store_directive{ }[\SYS_store_directive]% \restoreexpandmode \restoreexploremode \SYS_earg\SYS_ifempty{\SYS_store_directive} {} {% \SYS_eearg\SYS_ifempty{\expandafter\SYS_gobone\SYS_store_directive} {% \ifcat\relax\expandafter\noexpand\SYS_store_directive \show\SYS_store_directive \else \SYS_error{La consigne 'store' doit contenir une macro}% \fi } {% \SYS_error{La consigne 'store' doit contenir une macro}% }% }% } %--------------------------------------------------------------------- %------------------------------ Réglages ----------------------------- %--------------------------------------------------------------------- \defKV[systeme]{% eq sep = \SYS_stripsp{\def\SYS_eqsep}{#1}, delim = \SYS_set_delim{#1}, align = \SYS_set_align{#1}, sign space = \SYS_set_sign_space{#1}, member sep space = \SYS_set_membersep_space{#1}, line skip coeff = \def\SYS_lineskip_coeff{#1}, member sep subst = \SYS_add_membersep_susbt{#1}, add member sep = \SYS_add_membersep_sign{#1}, remove member sep = \SYS_remove_membersep{#1}, extra col sign = \SYS_set_extra_col_sign{#1}, extra col pre = \def\SYS_extra_col_start{#1}, extra col post = \def\SYS_extra_col_end{#1}, autonum code = \SYS_set_autonum{#1}, autonum continue = \testboolKV{#1}\SYS_autonum_continuetrue\SYS_autonum_continuefalse, sort = \SYS_set_sort{#1}, align terms = \testboolKV{#1}\SYS_align_termstrue\SYS_align_termsfalse, main eq count = \global\SYSeqnum\numexpr#1\relax, extra height = \edef\SYS_dim_extrastrut{\the\dimexpr#1\relax}% \ifdim\SYS_dim_extrastrut<0pt \def\SYS_dim_extrastrut{0pt}\fi, member sep list = \saveexpandmode \noexpandarg \StrDel{#1}{ }[\SYS_membersep_list]% \restoreexpandmode, coeff space = \SYS_set_term_coeff_space{#1}, post subst = \SYS_set_post_subst{#1}, store = \SYS_set_store{#1}, } \setKVdefault[systeme]{ eq sep = { , }, delim = { \{ , . }, align = { r , l }, member sep list = { <= , >= , = , < , > , \leq , \geq , \leqslant , \geqslant }, member sep subst = { <= , \leq }, member sep subst = { >= , \geq }, sign space = 0pt, member sep space = 0pt, line skip coeff = 1.25, coeff space = 0mu, sort = {*=*}, extra col sign = @, extra col pre = \kern1.5em$, extra col post = $, autonum code = {}, autonum continue = false, align terms = true, extra height = 1.5pt, post subst = {}, store = {} } \setKV[systeme]{ main eq count = 0 } \def\setsysteme#{\setKV[systeme]} \def\resetsysteme{\restoreKV[systeme]} %--------------------------------------------------------------------- %------ Analyse des équations, séparation en membres et termes ------- %--------------------------------------------------------------------- \def\SYS_split_equation_in_members#1#2#3#4{% #1=équation #2=sc membre gauche #3=sc signe égal #4=sc membre droite \def#2{#1}% \let#3\empty \let#4\empty \expandafter\SYS_split_equation_in_members_a\SYS_membersep_list,\_nil#2#3#4% } \def\SYS_split_equation_in_members_a#1,#2\_nil#3#4#5{% \IfSubStr#3{\noexpand#1}% si l'équation contient un des signes {% \SYS_left_membertrue \StrCut#3{\noexpand#1}#3#5% procède à la séparation en deux membres \IfSubStr{\expandafter,\SYS_membersep_subst_list}{,#1,}% si le signe est dans la liste des substitutions {% \SYS_letcs#4{SYS_membersep_subst__\detokenize{#1}}% le remplacer } {% \def#4{#1}% ou sauveagrder le signe tel quel }% }% {% \SYS_ifempty{#2} {}% aucun séparateur de membre trouvé {% \SYS_split_equation_in_members_a#2\_nil#3#4#5% sinon, recommencer en enlevant le 1er signe }% }% } \def\SYS_split_equation_in_terms#1{% \IfSubStr{\noexpand#1}\SYS_extra_col_sign% y a t-il un signe de colonne supplémentaire ? {% \StrCut{\noexpand#1}\SYS_extra_col_sign\SYS_true_eq\SYS__tmp \SYS_cslet{SYS_extra_col_\SYS_eqnumber}\SYS__tmp \SYS_extra_coltrue }% {% \def\SYS_true_eq{#1}% }% \SYS_earg\SYS_split_equation_in_members{\SYS_true_eq}\SYS_left_member\SYS_current_membersep\SYS_right_member% trouver les membres de gauche et droite et le signe qui les sépare \SYS_split_member_in_terms1\SYS_left_member% membre de gauche \SYS_ifx{\SYS_current_membersep\empty}% {}% {% \SYS_cslet{SYS_membersep_\SYS_format_membersep_name\SYS_eqnumber}\SYS_current_membersep% stocker ce signe s'il existe \SYS_split_member_in_terms2\SYS_right_member% membre de droite }% } \def\SYS_split_member_in_terms#1#2{% #1=1 ou 2 #2=\SYS_left_member || \SYS_right_member \SYS_set_member{#1}% \IfBeginWith#2\space {% \StrGobbleLeft#21[#2]% } {}% pas d'espace pour commencer le membre de gauche \IfBeginWith#2+% amputer le membre de gauche du premier signe et le stocker temporairement s'il existe et sinon... {% \StrSplit#21\SYS_current_sign#2% }% {% \IfBeginWith#2-% {% \StrSplit#21\SYS_current_sign#2% } {% \def\SYS_current_sign{+}% ce signe est "+" }% }% \SYS_earg\SYS_split_member_in_terms_b{#2}% \SYS_cslet{SYS_letter_list\SYS_member_index}\SYS_letter_list } \def\SYS_split_member_in_terms_b#1{% #1=membre courant \def\SYS_current_member{#1}% \SYS_letcs\SYS_letter_list{SYS_letter_list\SYS_member_index}% \SYS_split_member_in_terms_c } \def\SYS_split_member_in_terms_c{% \StrPosition\SYS_current_member+[\SYS_plus_position]% \StrPosition\SYS_current_member-[\SYS_minus_position]% \SYS_ifnum{\numexpr\SYS_plus_position+\SYS_minus_position=0 }% il n'y a ni "+" ni "-" {% \SYS_earg\SYS_store_term{\SYS_current_member}% et assigner ce dernier terme avec le dernier signe trouvé } {% \edef\SYS_next_sign{% décider de ce qu'est le prochain signe \ifnum\SYS_plus_position=0 -% \else \ifnum\SYS_minus_position=0 +% \else \ifnum\SYS_plus_position<\SYS_minus_position +% \else -% \fi \fi \fi }% \StrBefore\SYS_current_member\SYS_next_sign[\SYS_current_term]% prendre ce qu'il y a avant \StrBehind\SYS_current_member\SYS_next_sign[\SYS_current_member]% et stocker ce qu'il y a ensuite pour après \SYS_earg\SYS_store_term{\SYS_current_term}% assigner ce qu'il y a avant avec le dernier signe trouvé \let\SYS_current_sign\SYS_next_sign% on continue, le prochain signe devient le signe courant \SYS_split_member_in_terms_c }% } %--------------------------------------------------------------------- %---------------- Stockage des termes dans des macros ---------------- %--------------------------------------------------------------------- \def\SYS_store_term#1{% #1=terme en cours \SYS_find_letter{#1}% trouver le nom de la variable \SYS_ifx{\SYS_letter_found\empty} {% \SYS_csdef{SYS_const_term\SYS_member_index}{1}% \ifcsname SYS_term\SYS_format_const_name{\SYS_eqnumber}{\SYS_member_index}\endcsname% si terme constant déjà rencontré, l'ajouter à celui qui existe \expandafter\SYS_eaddtomacro\csname SYS_term\SYS_format_const_name{\SYS_eqnumber}{\SYS_member_index}\endcsname{\SYS_current_sign#1}% \else \SYS_cslet{SYS_sign\SYS_format_const_name{\SYS_eqnumber}{\SYS_member_index}}\SYS_current_sign% sinon procéder aux assignations \SYS_csdef{SYS_term\SYS_format_const_name{\SYS_eqnumber}{\SYS_member_index}}{#1}% \fi } {% \ifcsname SYS_term\SYS_format_term_name{\SYS_eqnumber}{\SYS_member_index}{\SYS_letter_found}\endcsname \SYS_error{l'inconnue "\detokenize\expandafter{\SYS_letter_found}" a déjà été trouvée dans l'équation !}% \fi \ifnum\csname SYS_sort_variable\SYS_member_index\endcsname=1 \SYS_insert_letter_in_list\SYS_letter_found\SYS_letter_list% l'insérer si besoin dans la liste ordonnée des variables \else% si tri manu : ajouter l'inconnue à \SYS_letter_found_list[1||2] si elle matche avec la consigne de tri \expandafter\IfSubStr\csname SYS_letter_found_list\SYS_member_index\endcsname\SYS_letter_found% lettre déjà rencontrée ? {}% {% \expandafter\SYS_eaddtomacro\csname SYS_letter_found_list\SYS_member_index\endcsname\SYS_letter_found% non : la rajouter }% \fi \SYS_cslet{SYS_sign\SYS_format_term_name{\SYS_eqnumber}{\SYS_member_index}{\SYS_letter_found}}\SYS_current_sign% procéder aux assignations \SYS_ifx{\empty\SYS_term_coeff_space} {% \SYS_csdef{SYS_term\SYS_format_term_name{\SYS_eqnumber}{\SYS_member_index}{\SYS_letter_found}}{#1}% } {% \expandafter\SYS_store_term_a\SYS_letter_found\_nil{#1}% }% }% } \def\SYS_store_term_a#1#2\_nil#3{% #1=letter #2=indice #3=terme en cours \def\SYS_store_term_b##1#1##2\_nil{% ##1=coeff #1=variable courante ##2=après variable \expandafter\edef\csname SYS_term\SYS_format_term_name{\SYS_eqnumber}{\SYS_member_index}{\SYS_letter_found}\endcsname{% \SYS_ifempty{##1} {} {% \unexpanded{##1}% \SYS_term_coeff_space }% \unexpanded{#1##2}}% }% \SYS_store_term_b#3\_nil } % cherche la première lettre minuscule dans #1 \def\SYS_find_letter#1{% \saveexploremode\exploregroups \StrRemoveBraces{#1}[\SYS_current_letter]% \let\SYS_letter_found\empty \SYS_find_letter_a \restoreexploremode } \def\SYS_find_letter_a{% \StrSplit\SYS_current_letter1\SYS_current_char\SYS_current_letter \ifnum\csname SYS_sort_variable\SYS_member_index\endcsname=1 % si le tri auto est activé \ifcat\relax\expandafter\noexpand\SYS_current_char \let\SYS_do_next\SYS_exec_second% faux si c'est une sc \else \SYS_ifnum{\expandafter`\SYS_current_char<`a } {% \let\SYS_do_next\SYS_exec_second% pas une lettre minuscule } {% \SYS_ifnum{\expandafter`\SYS_current_char>`z } {% \let\SYS_do_next\SYS_exec_second% pas une lettre minuscule } {% \SYS_grab_subscript\SYS_current_letter\SYS_current_char% prendre en plus l'éventuel indice \let\SYS_do_next\SYS_exec_first }% }% \fi \else \noexploregroups \IfSubStr\SYS_letter_list\SYS_current_char% ce qui est trouvé est dans la liste ? {% \SYS_grab_subscript\SYS_current_letter\SYS_current_char% prendre en plus l'éventuel indice \let\SYS_do_next\SYS_exec_first }% {% \let\SYS_do_next\SYS_exec_second }% \exploregroups \fi \SYS_do_next {% \let\SYS_letter_found\SYS_current_char \IfSubStr\SYS_letter_found\SYS_underscore\relax{\SYS_eaddtomacro\SYS_letter_found{\SYS_underscore{-1}}}% }% {% \SYS_ifx{\SYS_current_letter\empty} {} {% \SYS_find_letter_a }% }% } % teste si \SYS_current_letter commence par "_" et si oui, rajoute _ + argument suivant à \SYS_current_char et les enlève à \SYS_current_letter % teste si la sc #1 commence par "_" et si oui, rajoute _ + argument suivant à #2 et les enlève à #1 \def\SYS_grab_subscript#1#2{% \noexploregroups \IfBeginWith#1\SYS_underscore {% \SYS_eearg{\def#1}{\expandafter\SYS_gobone#1}% enlève le "_" \expandafter\SYS_grab_subscript_a#1\_nil#2% } {}% \exploregroups } \def\SYS_grab_subscript_a#1\_nil#2{% #1=indice \IfInteger{#1} {} {% \errmessage{L'indice non entier '\detokenize{#1}' est pris comme '\integerpart'.}% }% \SYS_eeaddtomacro#2{\expandafter\SYS_underscore\expandafter{\integerpart}}% } \def\SYS_insert_letter_in_list#1#2{% #1=sc contenant l'inconnue #2=sc contenant la liste dans laquelle l'insérer \IfSubStr#2{#1}% {} {% \let\SYS_temp_variable_list#2% \let\SYS_ins_current_letter#1% \StrChar{#1}3[\SYS_ins_num]% \StrRemoveBraces\SYS_ins_num[\SYS_ins_num]% \StrChar{#1}1[\SYS_current_insert_letter]% \let\SYS_temp_variable_list_left\empty \let\SYS_temp_variable_list_right\SYS_temp_variable_list \SYS_insert_letter_in_list_a \let#2\SYS_temp_variable_list }% } \def\SYS_insert_letter_in_list_a{% \SYS_ifx{\SYS_temp_variable_list_right\empty}% l'inconnue viendra à la fin de \SYS_temp_variable_list {% \SYS_eaddtomacro\SYS_temp_variable_list_left\SYS_ins_current_letter \let\SYS_temp_variable_list\SYS_temp_variable_list_left } {% \StrChar\SYS_temp_variable_list_right1[\SYS_currentletter]% la lettre suivante \SYS_ifnum{\expandafter`\SYS_current_insert_letter>\expandafter`\SYS_currentletter\relax}% lettre pas bonne ? {% \StrSplit\SYS_temp_variable_list_right3\SYS_currentletter\SYS_temp_variable_list_right \SYS_eaddtomacro\SYS_temp_variable_list_left\SYS_currentletter \SYS_insert_letter_in_list_a }% sinon {% \let\SYS_temp_variable_list_right_right\SYS_temp_variable_list_right \let\SYS_temp_variable_list_right_left\empty \SYS_insert_letter_in_list_b% }% }% } \def\SYS_insert_letter_in_list_b{% \SYS_ifx{\SYS_temp_variable_list_right_right\empty} {% \let\SYS_temp_variable_list\SYS_temp_variable_list_left \SYS_eaddtomacro\SYS_temp_variable_list\SYS_temp_variable_list_right_left \SYS_eaddtomacro\SYS_temp_variable_list\SYS_ins_current_letter } {% \StrChar\SYS_temp_variable_list_right_right1[\SYS_currentletter]% la lettre suivante \SYS_ifnum{\expandafter`\SYS_current_insert_letter<\expandafter`\SYS_currentletter\relax}% est elle une autre ? {% \let\SYS_temp_variable_list\SYS_temp_variable_list_left \SYS_eaddtomacro\SYS_temp_variable_list\SYS_temp_variable_list_right_left \SYS_eaddtomacro\SYS_temp_variable_list\SYS_ins_current_letter \SYS_eaddtomacro\SYS_temp_variable_list\SYS_temp_variable_list_right_right } {% \StrChar\SYS_temp_variable_list_right_right3[\SYS_currentsubscript]% le prochain indice \StrRemoveBraces\SYS_currentsubscript[\SYS_currentsubscript]% \SYS_ifnum{\SYS_ins_num>\SYS_currentsubscript\relax}% est-il le bon, c'est-à-dire trop grand ? {% \StrSplit\SYS_temp_variable_list_right_right3\SYS_currentletter\SYS_temp_variable_list_right_right \SYS_eaddtomacro\SYS_temp_variable_list_right_left\SYS_currentletter \SYS_insert_letter_in_list_b } {% \let\SYS_temp_variable_list\SYS_temp_variable_list_left \SYS_eaddtomacro\SYS_temp_variable_list\SYS_temp_variable_list_right_left \SYS_eaddtomacro\SYS_temp_variable_list\SYS_ins_current_letter \SYS_eaddtomacro\SYS_temp_variable_list\SYS_temp_variable_list_right_right }% }% }% } %--------------------------------------------------------------------- %---------------------- Construction d'un membre --------------------- %--------------------------------------------------------------------- \def\SYS_build_member{% \SYS_letcs\SYS_number_of_variable{SYS_number_of_variable\SYS_member_index}% \SYS_letcs\SYS_letter_list_tmp{SYS_letter_list\SYS_member_index}% \SYS_first_termtrue \SYS_build_member_a } \def\SYS_build_member_a#1#2{% #1=no ligne, #2=no inconnue \SYS_ifnum{#2>\SYS_number_of_variable\relax} {% \SYS_ifnum{\csname SYS_const_term\SYS_member_index\endcsname=1 } {% \SYS_ifnum{\SYS_number_of_variable=0 }% terme constant seulement ? {% /!\ pour le 2e membre, saut colonne déjà inséré après le signe = \SYS_ifplus{\csname SYS_sign\SYS_format_const_name{#1}{\SYS_member_index}\endcsname} {} {% \SYS_eearg\SYS_add_to_tab{\csname SYS_sign\SYS_format_const_name{#1}{\SYS_member_index}\endcsname}% }% \SYS_eearg\SYS_add_to_tab{\csname SYS_term\SYS_format_const_name{#1}{\SYS_member_index}\endcsname}% } {% \ifcsname SYS_sign\SYS_format_const_name{#1}{\SYS_member_index}\endcsname% si le terme constant existe dans cette ligne \ifSYS_align_terms \SYS_add_to_tab&% \fi \SYS_ifnum{\ifSYS_first_term1\fi\SYS_ifplus{\csname SYS_sign\SYS_format_const_name{#1}{\SYS_member_index}\endcsname}10=11 } {}% si premier terme et signe -> ne pas ajouter le signe {% \SYS_eearg\SYS_add_to_tab{\csname SYS_sign\SYS_format_const_name{#1}{\SYS_member_index}\endcsname}% }% \ifSYS_align_terms \SYS_add_to_tab&% \fi \SYS_eearg\SYS_add_to_tab{\csname SYS_term\SYS_format_const_name{#1}{\SYS_member_index}\endcsname}% \else \ifSYS_align_terms \SYS_add_to_tab{&&}% \fi \fi }% } {}% }% {% \StrSplit\SYS_letter_list_tmp3\SYS_currentvariable\SYS_letter_list_tmp \ifcsname SYS_sign\SYS_format_term_name{#1}{\SYS_member_index}{\SYS_currentvariable}\endcsname \SYS_ifnum{#2=1 }% première variable ? {% \SYS_ifplus{\csname SYS_sign\SYS_format_term_name{#1}{\SYS_member_index}{\SYS_currentvariable}\endcsname}% signe + ? {} {% terme := signe + terme \expandafter\edef\csname SYS_term\SYS_format_term_name{#1}{\SYS_member_index}{\SYS_currentvariable}\endcsname{% \unexpanded\expandafter\expandafter\expandafter{% \csname SYS_sign\SYS_format_term_name{#1}{\SYS_member_index}{\SYS_currentvariable}\endcsname }% \unexpanded\expandafter\expandafter\expandafter{% \csname SYS_term\SYS_format_term_name{#1}{\SYS_member_index}{\SYS_currentvariable}\endcsname }% }% }% } {% \SYS_ifnum{% \SYS_ifplus{\csname SYS_sign\SYS_format_term_name{#1}{\SYS_member_index}{\SYS_currentvariable}\endcsname}10% \ifSYS_first_term1\else0\fi=11 % si 1er terme et signe + } {} {% \SYS_eearg\SYS_add_to_tab{\csname SYS_sign\SYS_format_term_name{#1}{\SYS_member_index}{\SYS_currentvariable}\endcsname}% }% }% \SYS_first_termfalse \fi \SYS_ifnum{#2=1 } {} {% \ifSYS_align_terms \SYS_add_to_tab&% \fi }% \ifcsname SYS_term\SYS_format_term_name{#1}{\SYS_member_index}{\SYS_currentvariable}\endcsname \SYS_eearg\SYS_add_to_tab{\csname SYS_term\SYS_format_term_name{#1}{\SYS_member_index}{\SYS_currentvariable}\endcsname}% \fi \SYS_ifnum{#2<\SYS_number_of_variable\relax} {% \ifSYS_align_terms \SYS_add_to_tab&% \fi } {}% \SYS_earg{\SYS_build_member_a{#1}}{\number\numexpr#2+1}% }% } %--------------------------------------------------------------------- %--------------- Construction du préambule du \halign ---------------- %--------------------------------------------------------------------- %Construction préambule d'un membre : % %def build_preamble#1 % #1=n° de membre % calculer \SYS_number_of_variable % pour i:=1 to \SYS_number_of_variable % ajouter colonne terme % si i<\SYS_number_of_variable % ajouter & % ajouter colonne signe % ajouter & % finsi % finpour % si terme constant % si \SYS_number_of_variable>0 % ajouter & % finsi % ajouter colonne signe % ajouter & % ajouter colonne terme % finsi % si \ifSYS_extra_col ET #1==2 % ajouter & % ajouter colonne extracol % finsi \def\SYS_buid_preamble{% \begingroup \setbox0\hbox{${}+{}$}% \expanded{% \endgroup \def\noexpand\SYS_signcolumn{\hbox to\the\wd0{\hss$####$\hss}}}% colonne de largeur imposée Bugfix 0.34 \expandafter\StrCount\csname SYS_letter_list\SYS_format_member_number{1}\endcsname\SYS_underscore[\SYS_number_of_variable]% \SYS_buid_preamble_a11% \ifSYS_left_member \SYS_xaddtotok\SYS_preamble_toks{&\hfil\SYS_membersep_space$##$\SYS_membersep_space\hfil&}% ajouter 1 colonne pour le signe = \expandafter\StrCount\csname SYS_letter_list\SYS_format_member_number{2}\endcsname\SYS_underscore[\SYS_number_of_variable]% \SYS_buid_preamble_a12% \fi \ifSYS_extra_col \SYS_xaddtotok\SYS_preamble_toks{&\SYS_extra_col_start##\SYS_extra_col_end\hfil}% la colonne supplémentaire (pas de mode math) \fi \SYS_xaddtotok\SYS_preamble_toks{\cr\SYS_strutup}% ajouter la fin du préambule et le strut de première ligne } \def\SYS_buid_preamble_a#1#2{% #1=n°inconnue #2=n°membre \SYS_ifnum{#1>\SYS_number_of_variable\relax} {% toutes les inconnues épuisées \ifSYS_align_terms \SYS_ifnum{\csname SYS_const_term\SYS_format_member_number{#2}\endcsname=1 } {% si terme constant \SYS_ifnum{\SYS_number_of_variable>0 } {% \SYS_xaddtotok\SYS_preamble_toks{% &% ajouter saut colonne si des colonnes pour variable existent \SYS_sign_space\SYS_signcolumn\SYS_sign_space% TODO ça serait pas mieux carrément : \hss\SYS_sign_space$##$\SYS_sign_space$\hss &% }% } {}% \SYS_xaddtotok\SYS_preamble_toks{% \csname SYS_column_\SYS_format_member_number{#2}_left\endcsname $##$% \csname SYS_column_\SYS_format_member_number{#2}_right\endcsname }% colonne terme_addtotok } {}% \fi } {% on n'a pas épuisé les inconnues \SYS_ifnum{\ifSYS_align_terms1\else#1\fi=1 } {% \SYS_xaddtotok\SYS_preamble_toks{% \csname SYS_column_\SYS_format_member_number{#2}_left\endcsname $##$% \csname SYS_column_\SYS_format_member_number{#2}_right\endcsname }% une colonne pour le terme }% {}% \SYS_ifnum{#1<\SYS_number_of_variable\relax} {% si ce n'est pas la dernière inconnue \ifSYS_align_terms \SYS_xaddtotok\SYS_preamble_toks{% &% \SYS_sign_space\SYS_signcolumn\SYS_sign_space% TODO ça serait pas mieux carrément : \hss\SYS_sign_space$##$\SYS_sign_space$\hss &% }% \fi } {}% \SYS_earg\SYS_buid_preamble_a{\number\numexpr#1+1}{#2}% }% } %--------------------------------------------------------------------- %---------------------- Construction du tableau ---------------------- %--------------------------------------------------------------------- \def\SYS_build_system{% \SYS_tab_toks{}% \SYS_build_system_a1% } \def\SYS_build_system_a#1{% #1=no ligne \SYS_set_member{1}% \SYS_ifnum{\csname SYS_sort_variable\SYS_member_index\endcsname=1 } {% \expandafter\StrCount\csname SYS_letter_list\SYS_member_index\endcsname\SYS_underscore[\SYS__tmp]% } {% \expandafter\StrCount\csname SYS_letter_found_list\SYS_member_index\endcsname\SYS_underscore[\SYS__tmp]% }% \SYS_cslet{SYS_number_of_variable\SYS_member_index}\SYS__tmp \SYS_build_member{#1}{1}% \ifSYS_left_member \SYS_add_to_tab{&{}}% \SYS_eearg\SYS_add_to_tab{\csname SYS_membersep_\SYS_format_membersep_name{#1}\endcsname{}&}% \SYS_set_member{2}% \SYS_ifnum{\csname SYS_sort_variable\SYS_member_index\endcsname=1 } {% \expandafter\StrCount\csname SYS_letter_list\SYS_member_index\endcsname\SYS_underscore[\SYS__tmp]% } {% \expandafter\StrCount\csname SYS_letter_found_list\SYS_member_index\endcsname\SYS_underscore[\SYS__tmp]% }% \SYS_cslet{SYS_number_of_variable\SYS_member_index}\SYS__tmp \SYS_build_member{#1}{1}% \fi \saveexploremode\exploregroups \ifcsname SYS_extra_col_#1\endcsname \SYS_add_to_tab&% \expandafter\IfSubStr\csname SYS_extra_col_#1\endcsname{**}% le contenu de l'extra col contient-il "**" ? {% \SYS_letcs\SYS_autonum_arg{SYS_extra_col_#1}% \StrSubstitute\SYS_autonum_arg{**}{\number\numexpr\SYSeqnum+#1-\SYS_eqnumber}[\SYS_current_autonum]% \SYS_cslet{SYS_extra_col_#1}\SYS_current_autonum \SYS_autonumtrue }% {% \expandafter\IfSubStr\csname SYS_extra_col_#1\endcsname*% le contenu de l'extra col contient-il "*" ? {% \SYS_letcs\SYS_autonum_arg{SYS_extra_col_#1}% \StrSubstitute\SYS_autonum_arg*{\noexpand#1}[\SYS_current_autonum]% \SYS_cslet{SYS_extra_col_#1}\SYS_current_autonum \SYS_autonumtrue }% {% \ifSYS_autonum \IfSubStr\SYS_autonum_arg{**}% {% \StrSubstitute\SYS_autonum_arg{**}{\number\numexpr\SYSeqnum+#1-\SYS_eqnumber}[\SYS_current_autonum]% }% {% \StrSubstitute\SYS_autonum_arg*{\noexpand#1}[\SYS_current_autonum]% }% \SYS_earg\SYS_add_to_tab\SYS_current_autonum \fi }% }% \SYS_eearg\SYS_add_to_tab{\csname SYS_extra_col_#1\endcsname}% \else% pas d'extra colonne pour cette ligne ? \ifSYS_autonum% mais si il y un autonum \SYS_add_to_tab&% \IfSubStr\SYS_autonum_arg{**}% {% \StrSubstitute\SYS_autonum_arg{**}{\number\numexpr\SYSeqnum+#1-\SYS_eqnumber}[\SYS_current_autonum]% }% {% \StrSubstitute\SYS_autonum_arg*{\noexpand#1}[\SYS_current_autonum]% }% \SYS_earg\SYS_add_to_tab\SYS_current_autonum \fi \fi \restoreexploremode \SYS_ifnum{#1<\SYS_eqnumber\relax} {% \SYS_add_to_tab\cr \SYS_first_termtrue \SYS_earg\SYS_build_system_a{\number\numexpr#1+1}% } {% fin de l'alignement \SYS_earg\SYS_add_to_tab{\SYS_strutdown\cr}% }% } %--------------------------------------------------------------------- %-------------- Construction de la liste des inconnues --------------- %--------------------------------------------------------------------- \def\SYS_scan_letter_list#1#2{% #1=sc contenant la liste inconnues ; #2= sortie dans sc (inconnues indicées à -1 si besoin) \let#2\empty \let\SYS_letters_remaining#1% \SYS_scan_letter_list_a#2% } \def\SYS_scan_letter_list_a#1{% \StrSplit\SYS_letters_remaining1\SYS_current_char\SYS_letters_remaining \SYS_eaddtomacro#1\SYS_current_char \IfBeginWith\SYS_letters_remaining\SYS_underscore {% \StrChar\SYS_letters_remaining2[\SYS_current_char]% \StrRemoveBraces\SYS_current_char[\SYS_current_char]% \SYS_eeaddtomacro#1{\expandafter\SYS_underscore\expandafter{\SYS_current_char}}% \StrGobbleLeft\SYS_letters_remaining2[\SYS_letters_remaining]% }% {% \SYS_eaddtomacro#1{\SYS_underscore{-1}}% }% \SYS_ifx{\SYS_letters_remaining\empty} {} {% \SYS_scan_letter_list_a#1% }% } %--------------------------------------------------------------------- %---------------------- Macro publique \systeme ---------------------- %--------------------------------------------------------------------- \def\systeme{% \relax\iffalse{\fi\ifnum0=`}\fi \SYS_testopt\SYS_systeme_a{}% } \def\SYS_systeme_a[#1]{% \begingroup \setKV[systeme]{#1}% \IfSubStr{\SYS_sort_left}* {% tri auto \SYS_cslet{SYS_letter_list\SYS_format_member_number{1}}\empty \SYS_csdef{SYS_sort_variable\SYS_format_member_number{1}}{1}% } {% \expandafter\SYS_scan_letter_list\expandafter\SYS_sort_left\csname SYS_letter_list\SYS_format_member_number{1}\endcsname% ajoute des _{-1} si besoin \SYS_csdef{SYS_sort_variable\SYS_format_member_number{1}}{0}% \SYS_cslet{SYS_letter_found_list\SYS_format_member_number{1}}\empty% liste des inconnues réellement rencontrées et matchant avec la consigne de tri manuel }% \IfSubStr{\SYS_sort_right}* {% tri auto \SYS_cslet{SYS_letter_list\SYS_format_member_number{2}}\empty \SYS_csdef{SYS_sort_variable\SYS_format_member_number{2}}{1}% } {% \expandafter\SYS_scan_letter_list\expandafter\SYS_sort_right\csname SYS_letter_list\SYS_format_member_number{2}\endcsname% ajoute des _{-1} si besoin \SYS_csdef{SYS_sort_variable\SYS_format_member_number{2}}{0}% \SYS_cslet{SYS_letter_found_list\SYS_format_member_number{2}}\empty% liste des inconnues réellement rencontrées et matchant avec la consigne de tri manuel }% \mathcode`\, "013B \catcode`\^ 7 \catcode`\_ 8 \expandarg\noexploregroups \begingroup \setbox0 \hbox{$($}% \expandafter \endgroup \expanded{% \edef\noexpand\SYS_strutup {\vrule depth0pt width0pt height\the\dimexpr\ht0 +\SYS_dim_extrastrut\relax}% \edef\noexpand\SYS_strutdown{\vrule height0pt width0pt depth\the\dimexpr\dp0 +\SYS_dim_extrastrut\relax}% }% \SYS_cslet++% \SYS_cslet--% \SYS_set_member{1}% \SYS_csdef{SYS_const_term\SYS_format_member_number{1}}{0}% \SYS_csdef{SYS_const_term\SYS_format_member_number{2}}{0}% \SYS_earg\SYS_systeme_b{\SYS_eqsep}% } \def\SYS_systeme_b#1#2{% \def\SYS_systeme_d##1#1##2\_nil{% \SYS_ifempty{##1} {% \SYS_add_to_tab\cr% on a une ligne vide }% {% \SYS_split_equation_in_terms{##1}% analyser l'éq courante }% \SYS_ifempty{##2}% tant qu'il reste des équations {} {% \edef\SYS_eqnumber{\number\numexpr\SYS_eqnumber+1}% augmenter de 1 leur nombre \global\advance\SYSeqnum1 \SYS_systeme_d##2\_nil% recommencer avec ce qu'il reste }% }% \global\advance\SYSeqnum1 \def\SYS_eqnumber{1}% \ifdefined\SYS_autonum_arg \SYS_ifx{\SYS_autonum_arg\empty}% on initialise que si \SYS_autonum_arg est vide {% \SYS_extra_colfalse \SYS_autonumfalse } {}% \else \SYS_extra_colfalse \SYS_autonumfalse \fi \SYS_left_memberfalse% à priori, pas de signe = ni de second membre \SYS_systeme_d#2#1\_nil% analyser toutes les équations et en faire des termes et des signes \SYS_preamble_toks{}% \SYS_buid_preamble \let\SYS_letter_list_tmp\SYS_letter_list \SYS_build_system% construire le système... \xdef\truc{\halign{\the\SYS_preamble_toks\the\SYS_tab_toks}}% \SYS_ifx{\SYS_post_subst_list\empty} {} {% \edef\SYS_system_code{\the\SYS_tab_toks}% \SYS_post_subst_list \SYS_tab_toks\expandafter{\SYS_system_code}% }% \SYS_ifx{\empty\SYS_store_directive} {% ...l'afficher en mode math \csname SYS_\ifmmode id\else enter_math\fi\endcsname {% \SYS_delim_left \vcenter{% \lineskiplimit=0pt \lineskip=0pt \baselineskip\SYS_lineskip_coeff\normalbaselineskip \halign\expandafter\expandafter\expandafter{% \expandafter\the\expandafter\SYS_preamble_toks \the\SYS_tab_toks }% }% \SYS_delim_right }% } {% \expandafter\xdef\SYS_store_directive{% assignation globale \unexpanded{\csname SYS_\ifmmode id\else enter_math\fi\endcsname}% {% \unexpanded\expandafter{\SYS_delim_left}% \vcenter{% \noexpand\lineskiplimit=0pt \noexpand\lineskip=0pt \noexpand\baselineskip\SYS_lineskip_coeff\noexpand\normalbaselineskip \halign{% \the\SYS_preamble_toks \the\SYS_tab_toks }% }% \unexpanded\expandafter{\SYS_delim_right}% }% }% }% \endgroup \unless\ifSYS_autonum_continue \ifdefined\SYS_autonum_arg \let\SYS_autonum_arg\empty% annule la numérotation auto \fi \fi \setKV[systeme]{store={}}% \ifnum0=`{\fi\iffalse}\fi } \SYS_restore_catcode \def\aligncal{% \systeme[% delim={.,.}, align terms=false, align={r,l}, sort={{}={}}, extra col pre=\kern1.5em, extra col post={} ]% } \endinput --------------------------------------------------------------------- ---------------------------- Historique ---------------------------- --------------------------------------------------------------------- v0.1 27/02/2011 - Première version publique sur le CTAN. ---------------------------------------------------------------------- v0.2 08/03/2011 - Le premier argument optionnel met en place de nouvelles fonctionnalités. - Possibilité d'avoir des inconnues indicées. - Mise en place d'une colonne supplémentaire et d'une numérotation automatique. - La commande étoilée \systeme* dégrade l'alignement pour ne plus prendre en compte que les signes d'égalité. - Une substitution est possible en fin de traitement, juste avant d'afficher le système. ---------------------------------------------------------------------- v0.2a 15/05/2011 - Bug corrigé lorsque les termes comportent des accolades. ---------------------------------------------------------------------- v0.2b 23/06/2011 - La commande \setdelim permet de modifier les délimiteurs extensibles placés de part et d'autre du système. ---------------------------------------------------------------------- v0.3 21/12/2013 - Un terme constant est permis dans le membre de gauche. ---------------------------------------------------------------------- v0.31 01/01/2018 - Il manquait un "&" après le terme constant, merci à Thomas Soll de l'avoir signalé. ---------------------------------------------------------------------- v0.32 13/01/2019 - Correction d'un bug : les espaces étaient pris en compte dans les noms des termes. - Correction d'un bug : si version étoilée et terme constant dans membre de gauche, défaut d'alignement. - Nettoyage du code. ---------------------------------------------------------------------- v0.33 13/04/2020 - possibilité de choisir un espacement avant et après les signes + et - avec \SYS_set_sign_space{}. De même pour = avec \SYS_set_membersep_space{} - possibilité de choisir l'alignement des colonnes des termes à gauche du signe = et celle à droite avec \SYS_set_align{x,y} où x et y sont "c", "r", ou "l" ---------------------------------------------------------------------- v0.34 3/05/2020 - bugfix : la largeur des colonnes contenant les signes est désormais imposée (évite une incohérence à l'affichage en cas de colonne vide) ---------------------------------------------------------------------- v0.35 16/02/2025 - bugfix : ce qui est après un indice est correctement pris en compte ---------------------------------------------------------------------- v0.4 13/05/2025 - utilisation de simplekv pour effectuer les réglages via clés/valeurs ; mise à disposition de la macro \setsysteme et de l'argument optionnel de la macro \systeme pour y spécifier les clés/valeurs -> rupture de compatibilité - macros abandonnées : \sysdelim, \syseqsep, \sysalign, \syssignspace, \syseqspace, \syslineskipcoeff, \sysequivsign, \sysaddeqsign, \sysremoveeqsign, \sysextracolsign, \syscodeextracol, \sysautonum, \syssubstitute et \sysnosubstitute - inconnues acceptées, triées et alignées dans le membre de droite - mise en place de la clé 'coeff code' pour insérer une espace entre le coefficient (si présent) et l'inconnue - possibilité de stocker le code produit dans une macro spécifiée avec la clé 'store' - suppression des macros privées de xstring - réécriture des 3/4 du code, mise en ordre, assainissement et donc création de bugs. Forcément !