summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Master/texmf-dist/doc/generic/autoaligne/README4
-rw-r--r--Master/texmf-dist/doc/generic/autoaligne/autoaligne-fr.pdfbin326038 -> 355272 bytes
-rw-r--r--Master/texmf-dist/tex/generic/autoaligne/autoaligne-fr.tex102
-rw-r--r--Master/texmf-dist/tex/generic/autoaligne/autoaligne.tex94
4 files changed, 157 insertions, 43 deletions
diff --git a/Master/texmf-dist/doc/generic/autoaligne/README b/Master/texmf-dist/doc/generic/autoaligne/README
index d9c877de157..189c14d9198 100644
--- a/Master/texmf-dist/doc/generic/autoaligne/README
+++ b/Master/texmf-dist/doc/generic/autoaligne/README
@@ -3,9 +3,9 @@ ___________________________________
L'extension
autoaligne
- v1.1
+ v1.2
- 06/10/2016
+ 22/10/2016
___________________________________
Authors : Christian Tellechea
diff --git a/Master/texmf-dist/doc/generic/autoaligne/autoaligne-fr.pdf b/Master/texmf-dist/doc/generic/autoaligne/autoaligne-fr.pdf
index 5baf372478b..f1033cdf013 100644
--- a/Master/texmf-dist/doc/generic/autoaligne/autoaligne-fr.pdf
+++ b/Master/texmf-dist/doc/generic/autoaligne/autoaligne-fr.pdf
Binary files differ
diff --git a/Master/texmf-dist/tex/generic/autoaligne/autoaligne-fr.tex b/Master/texmf-dist/tex/generic/autoaligne/autoaligne-fr.tex
index 97328788a1a..bcef9440176 100644
--- a/Master/texmf-dist/tex/generic/autoaligne/autoaligne-fr.tex
+++ b/Master/texmf-dist/tex/generic/autoaligne/autoaligne-fr.tex
@@ -12,38 +12,33 @@
\usepackage{fancybox,xcolor,hyperref}
\def\eTeX{\hbox{$\varepsilon$-\TeX}}
\makeatletter
+\long\def\defactive#1#2{\catcode`#1=13 \begingroup\lccode`\~`#1 \lowercase{\endgroup\long\def~{#2}}}
+\newcommand\disable@lig[1]{\defactive#1{\leavevmode\kern\z@\string#1}}
\def\code{\expandafter\code@i\string}
\def\code@i#1{%
\begingroup
\par\nobreak\medskip\parindent0pt
\leftskip.1\linewidth
- \catcode`\^^I 13 \begingroup\lccode`\~`\^^I \lowercase{\endgroup\def~{\leavevmode\space\space\space\space}}%
+ \defactive\^^I{\leavevmode\space\space\space\space}%
+ \defactive\<{\begingroup$\langle$\itshape}%
+ \defactive\>{$\rangle$\endgroup}%
\let\do\@makeother \dospecials
- \ttfamily\small\@noligs
+ \ttfamily\small
\obeylines\obeyspaces
\def\code@ii##1#1{##1\par\medbreak\endgroup}%
\code@ii
}
\long\def\grab@toks#1\relax{\gdef\right@content{#1}}
-\newcommand\disable@lig[1]{%
- \catcode`#1\active
- \begingroup
- \lccode`\~`#1\relax
- \lowercase{\endgroup\def~{\leavevmode\kern\z@\string#1}}%
-}
-
\newcommand\exemple[1][60]{%
- \edef\par@@indent{\the\parindent}%
\par\nobreak\vskip5pt \noindent
\def\part@coeff{#1}%
\relax\leavevmode\null
\bgroup
\let\do\@makeother\dospecials
- \catcode`\^^M\active \catcode`\ \active
- \begingroup
- \lccode`\~`\ \lowercase{\def~{ {}}}%
- \lccode`\~`\^^M\lowercase{\endgroup\def~{\par\noexpand\leavevmode}}%
+ \defactive\ {\space}%
+ \defactive\^^M{\par\noexpand\leavevmode}%
+ \defactive\^^I{\leavevmode\space\space\space\space}%
\@makeother:\disable@lig,\disable@lig-%
\exemple@@
}
@@ -62,9 +57,7 @@
\@tempa
}
-\begingroup
-\catcode`#=12
-\gdef\exemple@@@{%
+\def\exemple@@@{%
\begingroup
\fboxsep1pt\relax
\edef\part@left{\the\dimexpr0.\part@coeff\linewidth-\fboxsep-\fboxrule}%
@@ -76,7 +69,7 @@
\vskip7.5pt\relax
\endgroup
}
-\endgroup
+
\begingroup
\catcode`\<13 \catcode`\>13
\gdef\verb{\relax\ifmmode\hbox\else\leavevmode\null\fi
@@ -116,7 +109,7 @@
\section{Avant propos}
C'est à force de voir, aussi bien sur \href{http://tex.stackexchange.com/}{\texttt{tex.stackexchange}} que dans ma boite \href{mailto:unbonpetit@openmailbox.org}{email}, des questions concernant l'extension \href{https://www.ctan.org/pkg/systeme}{\texttt{systeme}} que j'ai décidé d'écrire une extension à la fois plus générale et plus simple que ne l'est \texttt{systeme}. En effet trop de ces questions ont pour but de faire réaliser à \texttt{systeme} des choses pour lesquelles elle n'est pas conçue !
-À l'aide de la récente extension \href{https://www.ctan.org/pkg/listofitems}{\listofitems}, coder \aa{} deviendrait (presque) une formalité tant les choses deviennent plus simples.
+À l'aide de la récente extension \href{https://www.ctan.org/pkg/listofitems}{\listofitems}, coder \aa{} deviendrait (presque) une formalité tant les choses tendent à devenir plus simples.
Ayant constaté que beaucoup de non francophones ne semblent en rien gênés que le manuel de \texttt{systeme} soit rédigé uniquement en français, détestant pour ma part traduire le français vers l'anglais ce qui s'apparente à un calvaire et enfin, voulant à tout prix défendre l'existence du français face au globbish dans la sphère \TeX/\LaTeX{} et ailleurs, j'ai voulu que cette extension soit 100\% en français et qu'elle le reste ! Même dans le code, les noms des macros sont en français ce qui, une fois l'habitude prise, est fort agréable.
\bigbreak
@@ -131,7 +124,7 @@ et sous (pdf)(Xe)(lua)\TeX{} par
\paragraph{La macro \texttt{\char`\\autoaligne}}
Cette macro attend un argument obligatoire entre accolades contenant les lignes qui sont des expressions où l'alignement automatique doit entrer en vigueur.
-Chaque ligne est séparée de sa voisine par \og\verb|\\|\fg. Dans chaque ligne, on peut trouver autant de membres que l'on souhaite, séparés les uns des autres par \og\verb|=|\fg. Dans ces membres peuvent se trouver autant de termes que nécessaire, chacun séparé de son voisin par \og\verb|+|\fg{} ou \og\verb|-|\fg.
+Chaque ligne est séparée de sa voisine par \og\verb|\\|\fg. Dans chaque ligne, on peut trouver autant de membres que l'on souhaite, séparés les uns des autres par \og\verb|=|\fg. Dans ces membres peuvent se trouver autant de termes que nécessaire, chacun séparé de son voisin par \og\verb|+|\fg{} ou \og\verb|-|\fg. Pour choisir d'autres séparateurs, voir page~\pageref{choix.separateurs}.
La macro \verb|\autoaligne| va bâtir un alignement de type \verb|\halign| dans lequel chaque terme et chaque signe est contenu dans une colonne. Toutes les colonnes sont composées en mode mathématique. Visuellement, le résultat se traduit par des termes et des signes alignés les uns au desous des autres comme on peut le constater dans cet exemple simple :
\exemple|\autoaligne{x-3y+z=2-i\\5x+y-6z=1+5i\\x-y-z=-3+i}|
@@ -191,7 +184,7 @@ Le coefficient défini par \verb|\aavcoeff{<coeff>}| permet de modifier l'espace
\aavcoeff{1.75}étendu \autoaligne{a+2b=1\\a-b=2}/
\paragraph{Position verticale de l'alignement}
-La macro \verb|\autoaligne| admet un autre argument entre parenthèses qui permet de spécifier quelle sera la position verticale de l'alignement créé par rapport à la ligne de base. Cet argument est une \verb|<lettre>| qui vaut \og\verb|c|\fg, \og\verb|h|\fg{} ou \og\verb|b|\fg{} pour que la ligne de base de l'alignement soit au centre de celui-ci, sur la ligne du haut ou sur celle du bas. La position centrée est celle par défaut. Lorsque les deux arguments optionnels sont présents (celui entre crochets et celui entre parenthèses), l'ordre des arguments optionnels \emph{est sans importance}, \verb|[<consigne>](<lettre>)| est accepté tout comme \verb|(<lettre>)[<consigne>]|.
+La macro \verb|\autoaligne| admet un autre argument optionnel entre parenthèses qui spécifie quelle sera la position verticale de l'alignement créé par rapport à la ligne de base. Cet argument est une \verb|<lettre>| qui vaut \og\verb|c|\fg, \og\verb|h|\fg{} ou \og\verb|b|\fg{} pour que la ligne de base de l'alignement soit au centre de celui-ci, sur la ligne du haut ou sur celle du bas. La position centrée est celle par défaut. Lorsque les deux arguments optionnels sont présents (celui entre crochets et celui entre parenthèses), l'ordre des arguments optionnels \emph{est sans importance}, \verb|[<consigne>](<lettre>)| est accepté tout comme \verb|(<lettre>)[<consigne>]|.
\exemple/Alignement c :
\autoaligne(c){4=1+1+1+1\\=1+1+2\\=2+2\\=3+1}\medbreak
@@ -201,4 +194,71 @@ Alignement h :
Alignement b :
\autoaligne(b){4=1+1+1+1\\=1+1+2\\=2+2\\=3+1}/
+
+\paragraph{Choix des séparateurs}\label{choix.separateurs}
+Depuis la version 1.2, il est possible de choisir les séparateurs qui sont par défaut \og\verb|\\|\fg{} pour le changement de ligne, \og\verb|=|\fg{} pour le séparateur entre membres et \og\verb/+||-/\fg{} pour le séparateur entre termes.
+
+La macro
+
+\code|\definirseparateurs{<sep ligne>}{<sep membres>}{<sep termes>}|
+
+permet de les définir à sa convenance selon les contraintes suivantes:
+
+\begin{enumerate}
+ \item le \verb|<sep ligne>| doit être défini, c'est-à-dire qu'il ne peut pas être vide;
+ \item \verb|<sep membres>| et \verb|<sep termes>| ne peuvent pas être vides tous les deux, auquel cas, \og\verb|=|\fg{} et \og\verb/+||-/\fg{} sont pris par défaut;
+ \item un des deux séparateurs \verb|<sep membres>| ou \verb|<sep termes>| peut être vide, ce qui signifie que l'alignement ne tiendra compte que de deux séparateurs.
+\end{enumerate}
+
+Voici un exemple où seulement deux séparateurs sont définis :
+
+\exemple/Un calcul :
+\definirseparateurs{\\}{+||-}{}
+\autoaligne[*c](h){15+2\times3-4\times5\\
+15+6-20\\
+21+-20\\
+1}/
+
+\paragraph{Choix des espaces additionnels}
+Si l'on tente de créer une macro \verb|\determinant| qui affiche un déterminant de matrice dont les éléments sont séparés par \og\verb|\\|\fg{} et \og\verb*/ /\fg{}, on constate que le séparateur \og\verb*/ /\fg{}, composé en mode mathématique dans une colonne, est ignoré ce qui se traduit une colonne de largeur nulle conduisant à des espacement incorrects\footnote{Pour des raisons \TeX niques, le caractère \og\texttt{\char`\#}\fg{} est écrit deux fois dans les cadres, mais il ne doit être écrit qu'une seule fois dans du code \TeX.}.
+
+\exemple/\def\determinant##1{\begingroup
+ \definirseparateurs{\\}{ }{}%
+ \hbox{$\left|\autoaligne[*c]{##1}\right|$}%
+ \endgroup
+}
+Un déterminant \determinant{a -b 0\\b 0 a\\0 -a -b}/
+
+La macro
+
+\code|\definirespacements{<espace membres>}{<espace termes>}|
+
+définit les espaces placées \emph{de part et d'autre} de chaque séparateur de membres ou de termes. Ces deux espaces sont nulles par défaut, mais deviennent nécessaires dans l'exemple ci-dessus :
+
+\exemple/\def\determinant##1{\begingroup
+ \definirseparateurs{\\}{ }{}%
+ \definirespacements{.75em}{}%
+ \hbox{$\left|\autoaligne[*c]{##1}\right|$}%
+ \endgroup
+}
+Un déterminant \determinant{a -b 0\\b 0 a\\0 -a -b}/
+
+\paragraph{Choix des espacements autour de l'alignement}
+L'espacement autour de l'alignement lui-même est nul par défaut, ce qui se traduit par des traits verticaux un peu trop proches de la matrice dans l'exemple ci-dessus.
+
+La macro \verb/\definirespacements/ admet un argument optionnel entre crochets de la forme
+
+\code|[<ressort 1>,<ressort 2>]|
+
+où \verb|<ressort 1>| est le ressort inséré avant l'alignement et \verb|<ressort 2>| celui inséré après.
+
+\exemple/\def\determinant##1{\begingroup
+ \definirseparateurs{\\}{ }{}%
+ \definirespacements[3pt,3pt]{.75em}{}%
+ \hbox{$\left|\autoaligne[*c]{##1}\right|$}%
+ \endgroup
+}
+Un déterminant \determinant{a -b 0\\b 0 a\\0 -a -b}/
+
+Si \verb|<ressort 1>| est vide, aucun ressort n'est inséré via \verb|\hskip|. Il en est de même avec \verb|<ressort 2>|. Les valeurs de ces ressorts sont vides par défaut, ce qui signifie qu'aucun ressort n'est inséré avant ou après les alignements créés.
\end{document} \ No newline at end of file
diff --git a/Master/texmf-dist/tex/generic/autoaligne/autoaligne.tex b/Master/texmf-dist/tex/generic/autoaligne/autoaligne.tex
index 4fdf8a605af..24555de4ab8 100644
--- a/Master/texmf-dist/tex/generic/autoaligne/autoaligne.tex
+++ b/Master/texmf-dist/tex/generic/autoaligne/autoaligne.tex
@@ -3,9 +3,9 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
\def\aanom {autoaligne} %
-\def\aaversion {1.1} %
+\def\aaversion {1.2} %
% %
-\def\aadate {2016/10/06} %
+\def\aadate {2016/10/22} %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
@@ -58,10 +58,13 @@
\expandafter\aa_restaure_catcode\expandafter\endinput
\fi
-\def\aa_mode_math#1{$\relax#1$}
+\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_aligne_toks
-\def\aa_ajoute_au_toks#1{\aa_aligne_toks\expandafter{\the\aa_aligne_toks#1}}
+\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
@@ -80,10 +83,47 @@
\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\aa_liste_separateurs{\\_=_+||-}% liste s\'eparateurs par d\'efaut. N'a _pas_ \`a \^etre modifi\'ee !!!
+\def\definirseparateurs#1#2#3{%
+ \loi_ifempty{#1}
+ {\aa_erreur{Separateur <vide> entre lignes non permis, "\string\\" retenu}%
+ \definirseparateurs{\\}{#2}{#3}%
+ }
+ {\loi_ifempty{#2#3}
+ {\aa_erreur{Separateurs de membre <vide> et de terme <vide> : "=" 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${}##{}$\hfil}% pour "=", "+" ou "-"
-\def\aa_alignement_terme_c{\hfil$##$\hfil}\def\aa_alignement_terme_d{\hfil$##$}\def\aa_alignement_terme_g{$##$\hfil}
+\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
@@ -147,8 +187,9 @@
\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=3 }% si la profondeur est de 3
+ \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}}%
@@ -164,17 +205,17 @@
\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_membre_courant{aa_termeslen[\aa_ligne_index,\aa_membre_index,0]}%
+ \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_membre_courant>\csname aa_nbtermes_\aa_membre_index\endcsname\relax
- \loi_argcsname\let{aa_nbtermes_\aa_membre_index}\aa_nombre_de_membre_courant
+ \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_membre_courant
+ \loi_argcsname\let{aa_nbtermes_\aa_membre_index}\aa_nombre_de_termes_courant
\fi
}%
}%
- \aa_aligne_toks{}%
+ \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{%
@@ -237,11 +278,11 @@
\aa_ajoute_au_toks\cr
}%
\aa_ajoute_au_toks\crcr
- \leavevmode
+ \aa_insere_espacement_avant
\ifcase\aa_consigne_alignement_vertical\relax
\or
\let\aa_boite_externe\vcenter
- \loi_antefi{\ifmmode\expandafter\loi_identity\else\expandafter\aa_mode_math\fi}%
+ \csname\ifmmode loi_identity\else aa_compose_en_mode_math\fi\expandafter\endcsname
\or
\let\aa_boite_externe\vtop
\expandafter\loi_identity
@@ -249,7 +290,14 @@
\let\aa_boite_externe\vbox
\expandafter\loi_identity
\fi
- {\aa_boite_externe{\lineskiplimit0pt \lineskip0pt \baselineskip\aa_v_coeff\baselineskip\halign\expandafter{\the\aa_aligne_toks}}}%
+ {\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
@@ -257,7 +305,13 @@
\endinput
v1.0 01/09/2016
- premi\`ere version publique
+ - premi\`ere version publique
v1.1 06/10/2016
- correction d'un bug dans \autoaligne_iii qui mangeait le
- \endgroup final \ No newline at end of file
+ - 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 \ No newline at end of file