%  __________________________________________________________________
% |                                                                  |
% |                                                                  |
% |                           systeme v0.3                           |
% |                                                                  |
% |                       21 d\'ecembre 2013                         |
% |                                                                  |
% |__________________________________________________________________|
%
% Ce fichier est systeme.tex, le code TeX de l'extention "systeme".
%
% Maintainer: Christian Tellechea
% E-mail    : unbonpetit@gmail.com
%             Commentaires, remont\'ees de bugs, et suggestions
%             sont les bienvenus.
% Licence   : Released under the LaTeX Project Public License v1.3c or
%             later, see http://www.latex-project.org/lppl.txt
% Copyright : Christian Tellechea 2013
%
% Le package "systeme" est constitu\'e de ces 5 fichiers :
%   systeme.tex (ce fichier)
%   systeme.sty (le fichier pour LaTeX)
%   README
%   systeme_doc_fr.tex, systeme_doc_fr.pdf (manuel en francais)
%
% --------------------------------------------------------------------
% 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
% --------------------------------------------------------------------

\expandafter\edef\csname SYS@savedatcatcode\endcsname{\number\catcode`\@}

\catcode`\@11

\def\SYS@newmacro#1{%
	\ifdefined#1%
		\errmessage{Package systeme Error: la macro \string#1\space existe deja. Contacter l'auteur svp.}%
	\fi
	\def#1%
}

\SYS@newmacro\SYS@ver        {0.3}
\SYS@newmacro\SYS@date       {2013/12/21}
\SYS@newmacro\SYS@longdate   {21 d\'ecembre 2013}
\SYS@newmacro\SYS@packagename{systeme}

\newtoks\SYS@systemecode
\newtoks\SYS@systempreamble

\newif\ifSYS@firstterm
\newif\ifSYS@sortvariable
\newif\ifSYS@star
\newif\ifSYS@extracol
\newif\ifSYS@autonum
\newif\ifSYS@followautonum
\newif\ifSYS@constterm

\newcount\SYSeqnum

\expandafter\ifx\csname @latexerr\endcsname\relax% on n'utilise pas LaTeX ?
	\ifdefined\xstringversion\else\def\SYS@nextaction{\input xstring.tex}\expandafter\SYS@nextaction\fi
	\immediate\write\m@ne{Package: \SYS@packagename\space\SYS@date\space\space v\SYS@ver\space\space Saisie naturelle de systemes d'equations}%
	\newskip\normalbaselineskip \normalbaselineskip=12pt
	\long\def\@firstoftwo#1#2{#1}
	\long\def\@secondoftwo#1#2{#2}
	\long\def\@firstofone#1{#1}
	\long\def\@gobble#1{}
	\long\def\@ifnextchar#1#2#3{%
		\let\reserved@d=#1%
		\def\reserved@a{#2}%
		\def\reserved@b{#3}%
		\futurelet\@let@arg\@ifnch}
	\def\@ifnch{%
		\ifx\@let@arg\@sptoken
			\let\reserved@c\@xifnch
		\else
			\ifx\@let@arg\reserved@d
				\let\reserved@c\reserved@a
			\else
				\let\reserved@c\reserved@b
			\fi
		\fi
		\reserved@c}
	\def\:{\let\@sptoken= } \:
	\def\:{\@xifnch} \expandafter\def\: {\futurelet\@let@arg\@ifnch}
	\long\def\@testopt#1#2{\@ifnextchar[{#1}{#1[{#2}]}}
	\def\@ifstar#1{\@ifnextchar *{\@firstoftwo{#1}}}
	\def\@empty{}
	\def\space{ }
\fi

% d\'efinit ce qu'est le s\'eparateur des \'equations par d\'efaut
\SYS@newmacro\syseqsep{\def\SYS@defaulteqsep}
\syseqsep{,}

% d\'efinit le coefficient pour l'espacement interligne
\SYS@newmacro\syslineskipcoeff{\def\SYS@lineskipcoeff}
\syslineskipcoeff{1.25}

% d\'efinit le signe qui marquera une colonne suppl\'ementaire \`a droite du tableau
\SYS@newmacro\sysextracolsign{\def\SYS@extracolsign}
\expandafter\sysextracolsign\expandafter{\string @}% on d\'efinit l'arobas avec le bon catcode.

% d\'efinit ce qui sera ins\'er\'e au d\'ebut et \`a la fin de la colonne suppl\'ementaire
\SYS@newmacro\syscodeextracol#1#2{\def\SYS@extracolstart{#1}\def\SYS@extracolend{#2}}
\syscodeextracol{\kern1.5em$}{$}

\SYS@newmacro\sysreseteqnum{\global\SYSeqnum\z@}

\SYS@newmacro\SYS@cslet#1{\expandafter\let\csname#1\endcsname}

% d\'efinit l'autonum\'erotation
\SYS@newmacro\sysautonum{\@ifstar{\SYS@followautonumtrue\SYS@autonum}{\SYS@followautonumfalse\SYS@autonum}}

\SYS@newmacro\SYS@autonum#1{%
	\ifx\@empty#1\@empty
		\SYS@extracolfalse
		\SYS@autonumfalse
	\else
		\SYS@extracoltrue
		\SYS@autonumtrue
		\def\SYS@autonumarg{#1}%
	\fi
}

% dimension qui sera ajout\'ee \`a la hauteur et \`a la profondeur du strutup ou strutdown
% ins\'er\'e \`a la premi\`ere et la derni\`ere \'equation
\SYS@newmacro\SYS@extrastrutdim{1.5pt}

% liste des signes devant \^etre compris comme signe d'\'egalit\'e s\'eparant les 2 membres de l'\'equation
\SYS@newmacro\SYS@equalsignlist{<=,>=,=,<,>,\leq,\geq,\leqslant,\geqslant}

\SYS@newmacro\sysaddeqsign#1{%
	\saveexpandmode\expandarg
	\IfSubStr{\expandafter,\SYS@equalsignlist,}{,#1,}
		\relax
		{\expandafter\def\expandafter\SYS@equalsignlist\expandafter{\SYS@equalsignlist,#1}}%
	\restoreexpandmode
}

% enl\`eve l'item #2 de la sc #1 qui contient une liste
\SYS@newmacro\SYS@removeiteminlist#1#2{%
	\saveexpandmode\expandarg
	\IfSubStr{\expandafter,#1,}{,#2,}
		{\StrSubstitute{\expandafter\@nil\expandafter,#1,\@nil}{,#2,},[#1]%
		\StrDel#1{\noexpand\@nil,}[#1]%
		\StrDel#1{,\@nil}[#1]%
		}%
		\relax
	\restoreexpandmode
}

\SYS@newmacro\sysremoveeqsign#1{%
	\SYS@removeiteminlist\SYS@equalsignlist{#1}%
	\SYS@removeiteminlist\SYS@equivsignlist{#1}%
}

% d\'efinit le signe d'\'egalit\'e #1 comme devant \^etre remplac\'e par #2 lors de l'affichage
\SYS@newmacro\sysequivsign#1#2{%
	\IfSubStr\SYS@equivsignlist{\noexpand#1,}\relax{\expandafter\def\expandafter\SYS@equivsignlist\expandafter{\SYS@equivsignlist#1,}}%
	\expandafter\def\csname SYS@equivsign@\string#1\endcsname{#2}%
}

\SYS@newmacro\SYS@equivsignlist{}

\sysequivsign{<=}\leq
\sysequivsign{>=}\geq

\SYS@newmacro\SYS@firstiteminlist#1,#2\@nil{#1}

\SYS@newmacro\SYS@removefirstiteminlist#1,{}

% #1 est l'\'equation courante. La macro la s\'epare en 2 membres -> \SYS@leftmember et \SYS@rightmember
% le signe de s\'eparation entre les 2 membres se trouve dans \SYS@currenteqsign
\SYS@newmacro\SYS@splitinmembers#1{%
	\def\SYS@leftmember{#1}\let\SYS@currenteqsign\@empty\let\SYS@rightmember\@empty
	\expandafter\SYS@splitinmembers@i\expandafter{\SYS@equalsignlist,}% parcourt \SYS@equalsignlist pour s\'eparer en 2 membres
	\IfSubStr{\expandafter,\SYS@equivsignlist}{\expandafter,\SYS@currenteqsign,}% si le signe est dans la liste des substitutions
		{\expandafter\let\expandafter\SYS@currenteqsign\csname SYS@equivsign@\detokenize\expandafter{\SYS@currenteqsign}\endcsname}% le remplacer
		\relax
}

% #1 est la liste des signes d'\'egalit\'e
\SYS@newmacro\SYS@splitinmembers@i#1{%
	\ifx\@empty#1\@empty
	\else
		\IfSubStr\SYS@leftmember{\SYS@firstiteminlist#1\@nil}% si l'\'equation contient un des signes
			{\expandafter\def\expandafter\SYS@currenteqsign\expandafter{\SYS@firstiteminlist#1\@nil}% sauvagarde le signe
			\StrBehind\SYS@leftmember\SYS@currenteqsign[\SYS@rightmember]% proc\`ede \`a la s\'eparation
			\StrBefore\SYS@leftmember\SYS@currenteqsign[\SYS@leftmember]% en deux membres
			\let\SYS@nextaction\relax
			}%
			{\def\SYS@nextaction{\expandafter\SYS@splitinmembers@i\expandafter{\SYS@removefirstiteminlist#1}}}% sinon, recommencer en enlevant le 1er signe
		\expandafter\SYS@nextaction
	\fi
}

\SYS@newmacro\SYS@ifcontains#1#2{%
	\def\SYS@ifcontains@i##1#2##2\@nil{\ifx\@empty##2\@empty\expandafter\@secondoftwo\else\expandafter\@firstoftwo\fi}%
	\SYS@ifcontains@i#1\@@nil#2\@nil
}

% analyse une \'equation et la d\'ecoupe en termes et signes
\SYS@newmacro\SYS@spliteqinterms#1{%
	\IfSubStr{\noexpand#1}\SYS@extracolsign% y a t-il un signe de colonne suppl\'ementaire ?
		{\StrBefore{\noexpand#1}\SYS@extracolsign[\SYS@leftmember]%
		\StrBehind{\noexpand#1}\SYS@extracolsign[\SYS@rightmember]%
		\SYS@cslet{SYS@extracol@\SYS@eqnumber}\SYS@rightmember
		\SYS@extracoltrue
		}%
		{\def\SYS@leftmember{#1}}%
	\expandafter\SYS@splitinmembers\expandafter{\SYS@leftmember}% trouver les membres de gauche et droite et le signe qui les s\'epare
	\unless\ifx\SYS@currenteqsign\@empty
		\SYS@cslet{SYS@eqsign@\SYS@eqnumber}\SYS@currenteqsign% stocker ce signe s'il existe
	\fi
	\IfBeginWith\SYS@leftmember\space{\StrGobbleLeft\SYS@leftmember\@ne[\SYS@leftmember]}\relax% pas d'espace pour commencer le membre de gauche
	\IfBeginWith\SYS@leftmember+% amputer le membre de gauche du premier signe et le stocker temporairement s'il existe et sinon...
		{\StrSplit\SYS@leftmember\@ne\SYS@currentsign\SYS@leftmember}%
		{\IfBeginWith\SYS@leftmember-%
			{\StrSplit\SYS@leftmember\@ne\SYS@currentsign\SYS@leftmember}%
			{\def\SYS@currentsign{+}}}% ce signe est "+"
	\SYS@spliteqinterms@i\@ne
	\SYS@cslet{SYS@right@\SYS@eqnumber}\SYS@rightmember
}

\SYS@newmacro\SYS@spliteqinterms@i#1{%
	\StrPosition\SYS@leftmember+[\SYS@posplus]%
	\StrPosition\SYS@leftmember-[\SYS@posminus]%
	\ifnum\numexpr\SYS@posplus+\SYS@posminus=\z@ % il n'y a ni "+" ni "-"
		\let\SYS@currentterm\SYS@leftmember% prendre tout ce qui reste
		\SYS@assignterm% et assigner ce dernier terme avec le dernier signe trouv\'e
	\else
		\edef\SYS@nextsign{\ifnum\SYS@posplus=\z@-\else\ifnum\SYS@posminus=\z@+\else\ifnum\SYS@posplus<\SYS@posminus+\else-\fi\fi\fi}% d\'ecider de ce qu'est le prochain signe
		\StrBefore\SYS@leftmember\SYS@nextsign[\SYS@currentterm]% prendre ce qu'il y a avant
		\StrBehind\SYS@leftmember\SYS@nextsign[\SYS@leftmember]% et stocker ce qu'il y a ensuite pour apr\`es
		\SYS@assignterm% assigner ce qu'il y a avant avec le dernier signe trouv\'e
		\let\SYS@currentsign\SYS@nextsign% on continue, le prochain signe devient le signe courant
		\expandafter\SYS@spliteqinterms@i\expandafter{\number\numexpr#1+1\expandafter}%
	\fi
}

\SYS@newmacro\SYS@assignterm{%
	\expandafter\SYS@findletter\expandafter{\SYS@currentterm}% trouver le nom de la variable
	\ifx\SYS@letterfound\@empty
		\SYS@consttermtrue
		\def\SYS@letterfound{const}%
	\else
		\ifcsname SYS@term@\detokenize\expandafter{\SYS@letterfound}@\SYS@eqnumber\endcsname
			\errmessage{Package systeme Error: l'inconnue "\detokenize\expandafter{\SYS@letterfound}" a deja ete trouvee dans l'equation !}%
		\fi
		\ifSYS@sortvariable
			\SYS@insletter\SYS@letterfound% l'ins\'erer si besoin dans la liste ordonn\'ee des variables
		\fi
	\fi
	\SYS@cslet{SYS@sign@\detokenize\expandafter{\SYS@letterfound}@\SYS@eqnumber}\SYS@currentsign% proc\'eder aux assignations
	\SYS@cslet{SYS@term@\detokenize\expandafter{\SYS@letterfound}@\SYS@eqnumber}\SYS@currentterm
}

% cherche la premi\`ere lettre minuscule dans #1
\SYS@newmacro\SYS@findletter#1{%
	\saveexploremode\exploregroups
	\StrRemoveBraces{#1}[\SYS@currentfindletter]%
	\let\SYS@letterfound\@empty
	\SYS@findletter@i
	\restoreexploremode
}

\SYS@newmacro\SYS@findletter@i{%
	\StrSplit\SYS@currentfindletter\@ne\SYS@currentchar\SYS@currentfindletter
	\ifSYS@sortvariable% si le tri auto est activ\'e
		\ifcat\relax\expandafter\noexpand\SYS@currentchar
			\let\SYS@nextaction\@secondoftwo% faux si c'est une sc
		\else
			\ifnum\expandafter`\SYS@currentchar<`a
				\let\SYS@nextaction\@secondoftwo% pas une lettre minuscule
			\else
				\ifnum\expandafter`\SYS@currentchar>`z
					\let\SYS@nextaction\@secondoftwo% pas une lettre minuscule
				\else
					\SYS@testsubscript% tester s'il y a un indice
					\let\SYS@nextaction\@firstoftwo
				\fi
			\fi
		\fi
	\else
		\noexploregroups
		\IfSubStr\SYS@letterlist\SYS@currentchar% ce qui est trouv\'e est dans la liste ?
			{\SYS@testsubscript% tester s'il y a un indice apr\`es le caract\`ere courant
			\let\SYS@nextaction\@firstoftwo
			}%
			{\let\SYS@nextaction\@secondoftwo}%
		\exploregroups
	\fi
	\SYS@nextaction
		{\let\SYS@letterfound\SYS@currentchar
		\IfSubStr\SYS@letterfound_\relax{\SYS@addtocs\SYS@letterfound{_{-1}}}%
		}%
		{\unless\ifx\SYS@currentfindletter\@empty\expandafter\SYS@findletter@i\fi}%
}

\SYS@newmacro\SYS@addtocs#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}}

\SYS@newmacro\SYS@expaddtocs#1#2{\expandafter\SYS@addtocs\expandafter#1\expandafter{#2}}

% teste si \SYS@currentfindletter commence par "_" et si oui, rajoute les 2 caract\`eres \`a \SYS@currentchar et les enl\`eve \`a \SYS@currentfindletter
\SYS@newmacro\SYS@testsubscript{%
	\noexploregroups
	\IfBeginWith\SYS@currentfindletter_%
		{\StrChar\SYS@currentfindletter\tw@[\SYS@currentletterafter]%
		\exploregroups
		\StrRemoveBraces\SYS@currentletterafter[\SYS@currentletterafter]%
		\IfInteger\SYS@currentletterafter
			{\ifnum\SYS@currentletterafter=\m@ne\errmessage{L'indice ne doit pas etre -1.}\fi}%
			{\errmessage{L'indice n'est pas un nombre entier !}}%
		\SYS@expaddtocs\SYS@currentchar{\expandafter_\expandafter{\SYS@currentletterafter}}%
		}\relax
	\exploregroups
}

% ins\`ere l'inconnue dans la sc #1 \`a sa place dans \SYS@letterlist
\SYS@newmacro\SYS@insletter#1{%
	\IfSubStr\SYS@letterlist{#1}%
		\relax
		{\let\SYS@insunknown#1%
		\StrChar{#1}\thr@@[\SYS@insnum]%
		\StrRemoveBraces\SYS@insnum[\SYS@insnum]%
		\StrChar{#1}\@ne[\SYS@currentinsletter]%
		\let\SYS@letterlist@left\@empty
		\let\SYS@letterlist@right\SYS@letterlist
		\SYS@insletter@i}%
}

\SYS@newmacro\SYS@insletter@i{%
	\ifx\SYS@letterlist@right\@empty% l'inconnue viendra \`a la fin de \SYS@letterlist
		\SYS@expaddtocs\SYS@letterlist@left\SYS@insunknown
		\let\SYS@letterlist\SYS@letterlist@left
	\else
		\StrChar\SYS@letterlist@right\@ne[\SYS@currentletter]% la lettre suivante
		\unless\ifnum\expandafter`\SYS@currentinsletter>\expandafter`\SYS@currentletter% est elle la bonne ?
			\let\SYS@letterlist@right@right\SYS@letterlist@right
			\let\SYS@letterlist@right@left\@empty
			\expandafter\expandafter\expandafter\SYS@insletter@ii%
		\else% sinon
			\StrSplit\SYS@letterlist@right\thr@@\SYS@currentletter\SYS@letterlist@right
			\SYS@expaddtocs\SYS@letterlist@left\SYS@currentletter
			\expandafter\expandafter\expandafter\SYS@insletter@i
		\fi
	\fi
}

\SYS@newmacro\SYS@insletter@ii{%
	\ifx\SYS@letterlist@right@right\@empty
		\let\SYS@letterlist\SYS@letterlist@left
		\SYS@expaddtocs\SYS@letterlist\SYS@letterlist@right@left
		\SYS@expaddtocs\SYS@letterlist\SYS@insunknown
	\else
		\StrChar\SYS@letterlist@right@right\@ne[\SYS@currentletter]% la lettre suivante
		\ifnum\expandafter`\SYS@currentinsletter<\expandafter`\SYS@currentletter% est elle une autre ?
			\let\SYS@letterlist\SYS@letterlist@left
			\SYS@expaddtocs\SYS@letterlist\SYS@letterlist@right@left
			\SYS@expaddtocs\SYS@letterlist\SYS@insunknown
			\SYS@expaddtocs\SYS@letterlist\SYS@letterlist@right@right
		\else
			\StrChar\SYS@letterlist@right@right\thr@@[\SYS@currentsubscript]% le prochain indice
			\StrRemoveBraces\SYS@currentsubscript[\SYS@currentsubscript]%
			\unless\ifnum\SYS@insnum>\SYS@currentsubscript% est-il le bon, c'est-\`a-dire trop grand ?
				\let\SYS@letterlist\SYS@letterlist@left
				\SYS@expaddtocs\SYS@letterlist\SYS@letterlist@right@left
				\SYS@expaddtocs\SYS@letterlist\SYS@insunknown
				\SYS@expaddtocs\SYS@letterlist\SYS@letterlist@right@right
			\else
				\StrSplit\SYS@letterlist@right@right\thr@@\SYS@currentletter\SYS@letterlist@right@right
				\SYS@expaddtocs\SYS@letterlist@right@left\SYS@currentletter
				\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\SYS@insletter@ii
			\fi
		\fi
	\fi
}

\SYS@newmacro\SYS@addtotok#1#2{#1\expandafter{\the#1#2}}

\SYS@newmacro\SYS@expaddtotok#1#2{\expandafter\SYS@addtotok\expandafter#1\expandafter{#2}}

\SYS@newmacro\SYS@addtocode{\SYS@addtotok\SYS@systemecode}

\SYS@newmacro\SYS@expaddtocode#1{\expandafter\SYS@addtocode\expandafter{#1}}

% reconstruit le code du tableau qui sera dans le \halign
\SYS@newmacro\SYS@buildsystem#1#2{% #1=no ligne, #2=no inconnue
	\StrSplit\SYS@letterlist@tmp3\SYS@currentvariable\SYS@letterlist@tmp
	\ifcsname SYS@sign@\detokenize\expandafter{\SYS@currentvariable}@#1\endcsname
		\expandafter\expandafter\expandafter\ifx\csname SYS@sign@\detokenize\expandafter{\SYS@currentvariable}@#1\endcsname+% signe + ?
			\ifnum#2=\@ne% premi\`ere variable ?
				\let\SYS@nextaction\@gobble
			\else
				\ifSYS@firstterm% premier terme de l'\'equation ?'
					\let\SYS@nextaction\@gobble
				\else
					\let\SYS@nextaction\@firstofone
				\fi
			\fi
		\else
			\ifnum#2=\@ne
				\expandafter\def\csname SYS@term@\detokenize\expandafter{\SYS@currentvariable}@#1\expandafter\expandafter\expandafter\endcsname
					\expandafter\expandafter\expandafter{%
					\csname SYS@sign@\detokenize\expandafter{\SYS@currentvariable}@#1\expandafter\expandafter\expandafter\endcsname
					\csname SYS@term@\detokenize\expandafter{\SYS@currentvariable}@#1\endcsname}%
				\let\SYS@nextaction\@gobble
			\else
				\let\SYS@nextaction\@firstofone
			\fi
		\fi
		\SYS@nextaction{%
			\SYS@addtocode{{}}%
			\expandafter\SYS@expaddtocode\expandafter{\csname SYS@sign@\detokenize\expandafter{\SYS@currentvariable}@#1\endcsname{}}%
			}%
		\SYS@firsttermfalse
	\fi
	\unless\ifSYS@star
		\unless\ifnum#2=\@ne\SYS@addtocode&\fi
	\fi
	\ifcsname SYS@term@\detokenize\expandafter{\SYS@currentvariable}@#1\endcsname
		\expandafter\SYS@expaddtocode\expandafter{\csname SYS@term@\detokenize\expandafter{\SYS@currentvariable}@#1\endcsname}%
	\fi
	\unless\ifSYS@star\SYS@addtocode&\fi
	\ifnum#2<\SYS@numberofvariable
		\edef\SYS@nextaction{\noexpand\SYS@buildsystem{#1}{\number\numexpr#2+1}}%
		\expandafter\SYS@nextaction
	\else
		\ifSYS@constterm
			\SYS@addtocode{{}}%
			\expandafter\SYS@expaddtocode\expandafter{\csname SYS@sign@const@#1\endcsname{}&}%
			\expandafter\SYS@expaddtocode\expandafter{\csname SYS@term@const@#1\endcsname}%
		\fi
		\ifcsname SYS@eqsign@#1\endcsname
			\SYS@addtocode{{}}%
			\expandafter\SYS@expaddtocode\expandafter{\csname SYS@eqsign@#1\endcsname{}&}%
			\expandafter\SYS@expaddtocode\expandafter{\csname SYS@right@#1\endcsname}%
		\else
			\SYS@addtocode&%
		\fi
		\saveexploremode\exploregroups
		\ifcsname SYS@extracol@#1\endcsname
			\SYS@addtocode&%
			\expandafter\IfSubStr\csname SYS@extracol@#1\endcsname{**}% le contenu de l'extra col contient-il "**" ?
				{\expandafter\let\expandafter\SYS@autonumarg\csname SYS@extracol@#1\endcsname
				\StrSubstitute\SYS@autonumarg{**}{\number\numexpr\SYSeqnum+#1-\SYS@eqnumber}[\SYS@currentautonum]%
				\SYS@cslet{SYS@extracol@#1}\SYS@currentautonum
				\SYS@autonumtrue
				}%
				{\expandafter\IfSubStr\csname SYS@extracol@#1\endcsname*% le contenu de l'extra col contient-il "*" ?
					{\expandafter\let\expandafter\SYS@autonumarg\csname SYS@extracol@#1\endcsname
					\StrSubstitute\SYS@autonumarg*{\noexpand#1}[\SYS@currentautonum]%
					\SYS@cslet{SYS@extracol@#1}\SYS@currentautonum
					\SYS@autonumtrue
					}%
					{\ifSYS@autonum
						\IfSubStr\SYS@autonumarg{**}%
							{\StrSubstitute\SYS@autonumarg{**}{\number\numexpr\SYSeqnum+#1-\SYS@eqnumber}[\SYS@currentautonum]}%
							{\StrSubstitute\SYS@autonumarg*{\noexpand#1}[\SYS@currentautonum]}%
						\SYS@expaddtocode\SYS@currentautonum
					\fi
					}%
				}%
			\expandafter\SYS@expaddtocode\expandafter{\csname SYS@extracol@#1\endcsname}%
		\else% pas d'extra colonne pour cette ligne ?
			\ifSYS@autonum% mais si il y un autonum
				\SYS@addtocode&%
				\IfSubStr\SYS@autonumarg{**}%
					{\StrSubstitute\SYS@autonumarg{**}{\number\numexpr\SYSeqnum+#1-\SYS@eqnumber}[\SYS@currentautonum]}%
					{\StrSubstitute\SYS@autonumarg*{\noexpand#1}[\SYS@currentautonum]}%
				\SYS@expaddtocode\SYS@currentautonum
			\fi
		\fi
		\restoreexploremode
		\ifnum#1<\SYS@eqnumber
			\SYS@addtocode\cr
			\SYS@firsttermtrue
			\let\SYS@letterlist@tmp\SYS@letterlist
			\edef\SYS@nextaction{\noexpand\SYS@buildsystem{\number\numexpr#1+1}{1}}%
			\expandafter\expandafter\expandafter\SYS@nextaction
		\else% fin de l'alignement
			\SYS@addtocode{\SYS@strutdown\cr}%
		\fi
	\fi
}

% ajoute "_\m@ne" \`a tous les tokens de #1 qui n'ont pas un indice
\SYS@newmacro\SYS@scanletterlist#1{%
	\let\SYS@letterlist\@empty
	\def\SYS@lettersremaining{#1}%
	\SYS@scanletterlist@i
}

\SYS@newmacro\SYS@scanletterlist@i{%
	\StrSplit\SYS@lettersremaining\@ne\SYS@currentchar\SYS@lettersremaining
	\SYS@expaddtocs\SYS@letterlist\SYS@currentchar
	\IfBeginWith\SYS@lettersremaining_%
		{\StrChar\SYS@lettersremaining\tw@[\SYS@currentchar]%
		\StrRemoveBraces\SYS@currentchar[\SYS@currentchar]%
		\SYS@expaddtocs\SYS@letterlist{\expandafter_\expandafter{\SYS@currentchar}}%
		\StrGobbleLeft\SYS@lettersremaining\tw@[\SYS@lettersremaining]%
		}%
		{\SYS@addtocs\SYS@letterlist{_{-1}}}%
	\unless\ifx\SYS@lettersremaining\empty\expandafter\SYS@scanletterlist@i\fi
}

\SYS@newmacro\sysdelim#1#2{\def\SYS@delim@left{\left#1}\def\SYS@delim@right{\right#2}}
\sysdelim\{.

\SYS@newmacro\systeme{\@ifstar{\SYS@startrue\SYS@systeme@i}{\SYS@starfalse\SYS@systeme@i}}

\SYS@newmacro\SYS@systeme@i{%
	\relax\iffalse{\fi\ifnum0=`}\fi
	\begingroup
		\mathcode`\,="013B
		\catcode`\^7 \catcode`\_8
		\expandarg\noexploregroups
		\setbox\z@\hbox{$($}%
		\edef\SYS@strutup{\vrule depth\z@ width\z@ height\dimexpr\ht\z@+\SYS@extrastrutdim\relax}%
		\edef\SYS@strutdown{\vrule height\z@ width\z@ depth\dimexpr\dp\z@+\SYS@extrastrutdim\relax}%
		\SYS@cslet++\SYS@cslet--%
		\@testopt\SYS@systeme@ii{}%
}

\SYS@newmacro\SYS@systeme@ii[#1]{%
		\ifx\@empty#1\@empty
			\let\SYS@letterlist\@empty
			\SYS@sortvariabletrue
		\else
			\SYS@scanletterlist{#1}% ajoute des _{-1} si besoin
			\SYS@sortvariablefalse
		\fi
		\SYS@consttermfalse
		\expandafter\@testopt\expandafter\SYS@systeme@iii\expandafter{\SYS@defaulteqsep}%
}

\SYS@newmacro\SYS@systeme@iii[#1]#2{%
		\SYS@newmacro\SYS@systeme@iv##1#1##2\@nil{%
			\ifx\@empty##1\@empty
				\SYS@addtocode\cr% une ligne vide
			\else
				\SYS@spliteqinterms{##1}% analyser l'eq courante
			\fi
			\ifx\@empty##2\@empty% tant qu'il reste des \'equations
			\else
				\edef\SYS@eqnumber{\number\numexpr\SYS@eqnumber+\@ne}% augmenter de 1 leur nombre
				\global\advance\SYSeqnum\@ne
				\def\SYS@nextaction{\SYS@systeme@iv##2\@nil}% recommencer avec ce qu'il reste
				\expandafter\SYS@nextaction
			\fi
		}%
		\global\advance\SYSeqnum\@ne
		\def\SYS@eqnumber{1}%
		\ifdefined\SYS@autonumarg
			\ifx\SYS@autonumarg\@empty% on initialise que si \SYS@autonumarg est vide
				\SYS@extracolfalse
				\SYS@autonumfalse
			\fi
		\else
			\SYS@extracolfalse
			\SYS@autonumfalse
		\fi
		\SYS@systeme@iv#2#1\@nil% analyser toutes les \'equations et en faire des termes et des signes
		\StrCount\SYS@letterlist_[\SYS@numberofvariable]%
		\SYS@systemecode{}\SYS@systempreamble{}%
		\ifSYS@star
			\SYS@makesyspreamble\@ne
		\else
			\SYS@makesyspreamble\SYS@numberofvariable% fabriquer le pr\'eambule du \halign
		\fi
		\SYS@firsttermtrue
		\let\SYS@letterlist@tmp\SYS@letterlist
		\SYS@buildsystem11% construire le syst\`eme...
		\ifdefined\SYS@substlist
			\unless\ifx\SYS@substlist\@empty
				\edef\SYS@systemcs{\the\SYS@systemecode}%
				\SYS@substlist
				\SYS@systemecode\expandafter{\SYS@systemcs}%
			\fi
		\fi
		\ifmmode
			\expandafter\@firstofone
		\else
			\expandafter\SYS@entermath
		\fi
			{\SYS@delim@left
			\vcenter{%
				\lineskiplimit\z@\lineskip\z@
				\baselineskip\SYS@lineskipcoeff\normalbaselineskip
				\halign\expandafter\expandafter\expandafter{\expandafter\the\expandafter\SYS@systempreamble\the\SYS@systemecode}%
				}%
			\SYS@delim@right
			}% ...l'afficher en mode math
	\endgroup
	\ifnum0=`{\fi\iffalse}\fi
	\unless\ifSYS@followautonum
		\ifdefined\SYS@autonumarg
			\let\SYS@autonumarg\@empty% annule la num\'erotation auto
		\fi
	\fi
}

% Construire le pr\'eambule du \halign
\SYS@newmacro\SYS@makesyspreamble#1{%
	\def\SYS@preamblenum{#1}%
	\SYS@makesyspreamble@i\@ne
}

\SYS@newmacro\SYS@makesyspreamble@i#1{%
	\ifnum#1<\SYS@preamblenum% tant qu'il reste des variables
		\SYS@addtotok\SYS@systempreamble{\hfil$##$&\hfil$##$&}% une colonne pour le terme et une pour le signe
		\expandafter\SYS@makesyspreamble@i\expandafter{\number\numexpr#1+\@ne\expandafter}%
	\else
		\ifSYS@constterm
			\SYS@addtotok\SYS@systempreamble{\hfil$##$&\hfil$##$&}% une colonne pour le terme constant et son signe
		\fi
		\SYS@addtotok\SYS@systempreamble{\hfil$##$&$##$&$##$\hfil\null}% ajouter 1 colonne pour le signe = et une pour le terme de droite
		\ifSYS@extracol
			\SYS@addtotok\SYS@systempreamble{&\SYS@extracolstart##\SYS@extracolend\hfil\null}% la colonne suppl\'ementaire (pas de mode math)
		\fi
		\SYS@addtotok\SYS@systempreamble{\cr\SYS@strutup}% ajouter la fin du pr\'eambule et le strut de premi\`ere ligne
	\fi
}

\SYS@newmacro\SYS@entermath#1{$\relax#1$}

% d\'efinit les substitutions \`a faire dans le tableau avant l'affichage
\SYS@newmacro\syssubstitute{%
	\unless\ifdefined\SYS@substlist\let\SYS@substlist\@empty\fi
	\SYS@substitute@i
}

\SYS@newmacro\SYS@substitute@i#1{%
	\ifx\@empty#1\@empty
	\else
		\SYS@addtocs\SYS@substlist{\StrSubstitute\SYS@systemcs}%
		\StrChar{\noexpand#1}\@ne[\SYS@currentchar]\StrRemoveBraces\SYS@currentchar[\SYS@currentchar]%
		\SYS@expaddtocs\SYS@substlist{\expandafter{\expandafter\noexpand\SYS@currentchar}}%
		\StrChar{\noexpand#1}\tw@[\SYS@currentchar]\StrRemoveBraces\SYS@currentchar[\SYS@currentchar]%
		\SYS@expaddtocs\SYS@substlist{\expandafter{\expandafter\noexpand\SYS@currentchar}[\SYS@systemcs]}%
		\def\SYS@nextaction{\expandafter\SYS@substitute@i\expandafter{\@gobbletwo#1}}%
		\expandafter\SYS@nextaction
	\fi
}

% annule les substitutions
\SYS@newmacro\sysnosubstitute{\let\SYS@substlist\@empty}

\catcode`\@\SYS@savedatcatcode\relax

\endinput

######################################################################
#                             Historique                             #
######################################################################

v0.1        27/02/2011
	- Premi\`ere version publique sur le CTAN
----------------------------------------------------------------------
v0.2        08/03/2011
    - Le premier argument optionnel met en place de nouvelles
      fonctionnalit\'es
    - Possibilit\'e d'avoir des inconnues indic\'ees
    - Mise en place d'une colonne suppl\'ementaire et d'une
      num\'erotation automatique
    - La commande \'etoil\'ee \systeme* d\'egrade l'alignement pour ne
      plus prendre en compte que les signes d'\'egalit\'e
    - Une substitution est possible en fin de traitement, juste
      avant d'afficher le syst\`eme.
----------------------------------------------------------------------
v0.2a       15/05/2011
    - Bug corrig\'e lorsque les termes comportent des accolades
----------------------------------------------------------------------
v0.2b       2011/06/23
    - La commande \setdelim permet de modifier les d\'elimiteurs
      extensibles plac\'es de part et d'autre du syst\`eme.
----------------------------------------------------------------------
v0.3        21/12/2013
    - Un terme constant est permis dans le membre de gauche