diff --git a/logiciels/latex/nouveau_package.tml b/logiciels/latex/nouveau_package.tml new file mode 100644 index 0000000..98b3c81 --- /dev/null +++ b/logiciels/latex/nouveau_package.tml @@ -0,0 +1,517 @@ + + + + +Son package + + + +

Écrire son propre package

+ +

Pourquoi ?

+ +

+Définir son propre package permet :

+ + + +

Principe

+ +

Nous allons créer un fichier « mon_package.sty » (ou +tout autre nom qui ne crée de doublon) qui comportera les instructions +qui permettront :

+ + + +

Organisation

+ +

Listing

+ +
+%% Informations générales
+\NeedsTeXFormat{LaTeX2e}[1999/01/01]
+\ProvidesPackage{mon_package}[2003/01/01]
+
+%% Chargement des extensions
+\RequirePackage[dvips]{graphicx}
+
+%% Déclaration des options
+\DeclareOption{option}{...}
+\DeclareOption*{...}
+\ProcessOptions
+
+%% Définition des commandes
+\newcommand{\blabla}{Super commande}
+
+%% Fin du package
+\endinput
+
+ +

Explications

+ + + +

Exemple simple

+ +

Supposons qu'il m'arrive d'écrire des documents sans algorithmes et +d'autres avec. Lorsque j'en ai besoin je charge les packages +algorithm et algorithmic qui permettent de +mettre en forme des algorithmes, d'en faire une « liste des +algorithmes » et de les rendre flottants (voir la page...). Je peux +encore utiliser mon propre package pour gérer ces cas, il suffit +d'introduire une option « algo » quand on a besoin des fonctionnalités +idoines. Voilà comment :

+ +
+%% (...) \NeedsTeXFormat et \ProvidesPackage
+\newif\if@algo \@algofalse
+\DeclareOption{algo}{\@algotrue}
+\DeclareOption*{}%% Ne rien faire quand une option est inconnue
+\ProcessOptions
+
+\if@algo
+  \RequirePackage{algorithm}
+  \RequirePackage{algorithmic}
+  \RequirePackage{mes-commandes-algo}
+  \newcommand{\algorithme}{Blabla}
+\fi
+%% (...) \newcommand's et \endinput
+
+ +

+La commande \newif\ifquelquechose crée trois +commandes :

+ + + +

Dans notre exemple on crée une instruction conditionnelle +\if@algo qui est équivalente à if false (à cause +de \@algofalse). Cependant, si l'option « algo » est +passée au package, on exécute \@algotrue qui a pour effet +de rendre \if@algo équivalent à if true. Les +packages relatifs à l'algo (et les commandes définies dans le bloc) +seront chargés si et seulement si l'option « algo » aura été passée dans +le fichier .tex :

+ + + +

Remarque : notons que dans les packages « @ » est une lettre +(contrairement aux document .tex où « @ » est un symbole) +et que donc on peut écrire des noms de commandes avec « @ ». D'où les +noms \makeatletter et \makeatother utilisées +dans des cas un peu exceptionnels. Dans un fichier .tex, +« \if@algo » aurait été interprétée comme la commande +\if suivie de « @algo ».

+ +

Exemple moins simple, plus réaliste

+ +

Listing

+ +
+\NeedsTeXFormat{LaTeX2e}[1999/01/01]
+\ProvidesPackage{mon_package}[2003/01/01]
+
+\newif\if@algo     \@algofalse
+\newif\if@listings \@listingsfalse
+
+\DeclareOption{listings}{\@listingstrue}
+\DeclareOption{algo}{\@algotrue}
+\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{babel}}
+\ProcessOptions
+
+\RequirePackage{babel}
+
+\if@algo
+  \RequirePackage{algorithm}
+  \RequirePackage{algorithmic}
+  \RequirePackage{mes-commandes-algo}
+\fi
+
+\if@listings
+  \RequirePackage{listings}
+  \RequirePackage{verbatim}
+  \RequirePackage{moreverb}
+  \RequirePackage{mes-commandes-listings}
+\fi
+
+\endinput
+
+ +

Explications

+ +

On déclare comme précédemment deux options « normales » : +algo et listings mais quand on est face à +une option inconnue on la passe à babel, ainsi :

+ +
+\documentclass[a4paper]{article}
+\usepackage[algo, listings, english, greek, francais]{mon_package}
+\begin{document}
+ .
+ .
+ .
+\end{document}
+
+ +

+sera équivalent à charger les modules d'algorithmiques, les modules de +d'écriture de programmes, et babel avec les options +english, greek et francais +(dans cet ordre). La commande \PassOptionsToPackage{<options>}{<package>} ne charge pas le package +<package>, elle rajoute les +<options> à la liste d'options qui seront passées +au package <package> lors de l'appel +\RequirePackage{<package>}. +

+ +

+Remarque : les options déclarées avec +\DeclareOption{...}{...} peuvent être passées comme +options globales du document comme dans : +

+ +
+\documentclass[a4paper, algo, listings]{article}
+\usepackage[english, greek, francais]{mon_package}
+\begin{document}
+ .
+ .
+ .
+\end{document}
+
+ +

+En revanche les langages doivent être passés au package lui-même +(notamment babel n'a pas tenté de trouver un langage nommé « a4paper » +ce qui aurait abouti à une erreur). +

+ +

Limitations

+ +

D'une part on ne peut pas utiliser ce mécanisme pour plusieurs +packages auquel on passerait les options non déclarées avec +\DeclareOption{...}{...} et d'autre part on ne peut pas +s'abstenir de passer au moins une option de langage au package.

+ +

Exemple (très) compliqué

+ +

Prérequis

+ + + +

Listing général

+ +
+\NeedsTeXFormat{LaTeX2e}[1999/01/01]
+\ProvidesPackage{mon_package}[2003/01/01]
+\RequirePackage{keyval}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Pour gérer les deux types d'options :                                  %
+%  1. les options normales (\DeclareOption{...}{...})                    %
+%  2. les options type key-val option=value (\define@key{...}{...}{...}) %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\@ifundefined{my@unusedlist}{%
+  \let\my@unusedlist\@empty}{}
+\@ifundefined{my@extractkey}{%
+  \def\my@extractkey#1=#2\my@extractkey{#1}}{}
+\newcommand{\ProcessUnusedOptions}[1]{%
+  \let\my@tempa\@empty
+  \let\my@tempb\@empty
+  \@for\CurrentOption:=\my@unusedlist\do{%
+    \expandafter\expandafter\expandafter\def
+    \expandafter\expandafter\expandafter\my@key
+    \expandafter\expandafter\expandafter{%
+      \expandafter\my@extractkey\CurrentOption=\my@extractkey}%
+    \@ifundefined{KV@#1@\my@key}{%
+      \edef\my@tempa{\my@tempa,\CurrentOption,}}{%
+      \edef\my@tempb{\my@tempb,\CurrentOption,}}}%
+  \@for\CurrentOption:=\my@tempa\do{%
+    \ifx\CurrentOption\@empty\else
+      \PackageWarning{mypack}{`\CurrentOption' not defined.}\fi}%
+  \edef\my@tempb{%
+    \noexpand\setkeys{#1}{\my@tempb}}%
+  \my@tempb
+  \AtEndOfPackage{\let\@unprocessedoptions\relax}}
+
+\DeclareOption*{%
+  \expandafter\expandafter\expandafter\def
+  \expandafter\expandafter\expandafter\my@unusedlist
+  \expandafter\expandafter\expandafter{%
+    \expandafter\my@unusedlist\expandafter,%
+    \CurrentOption}}
+%%%%%%%%%%%%%%%
+% Fin du bloc %
+%%%%%%%%%%%%%%%
+
+%% Options «normales»
+\DeclareOption{foo}{<action foo>}
+\DeclareOption{bar}{<action bar>}
+
+%% Options passées sous forme key=val
+\define@key{mypack}{<key1>}{<action 1> dépendant de #1}
+\define@key{mypack}{<key2>}[<default>]{<action 2> dépendant de #1}
+
+\ProcessOptions
+\ProcessUnusedOptions{mypack}
+
+\endinput
+
+ +

Explications

+ +

Dans l'exemple suivant

+ +
+\documentclass[foo]{article}
+\usepackage[foo, key1=value1, key2=value2]{mypack}
+\begin{document}
+ .
+ .
+ .
+\end{document}
+
+ +

l'option foo va agir comme dans les exemples simples, +key1=value1 va exécuter le code <action 1> +en utilisant value1 en lieu et place de #1. Idem +pour key2=value2 sauf que on peut omettre la partie +« =value2 » auquel cas <action 2> est exécuté +en utilisant <default> à la place de #1. +Par exemple si mon_package.sty contient :

+ +
+%% (...) 
+\newcounter{nombre}
+\define@key{mypack}{number}[14]{%
+  \setcounter{nombre}{#1}}
+%% (...) 
+
+ +

on pourra l'appeler ainsi

+ +
+\documentclass[foo]{article}
+\usepackage[number=10]{mypack}
+\begin{document}
+ .
+\thenombre\ affiche 10.
+ .
+ .
+\end{document}
+
+ +

ou encore comme cela

+ +
+\documentclass[foo]{article}
+\usepackage[number]{mypack}
+\begin{document}
+ .
+\thenombre\ affiche 14.
+ .
+ .
+\end{document}
+
+ +

ou bien sûr sans option du tout (auquel cas le code +\setcounter ne sera pas exécuté et donc le compteur +nombre vaudra zéro).

+ +

Exemple d'application

+ +

Si mon_package contient :

+ +
+\newcommand{\pack@languages}{francais}
+\define@key{mypack}{language}{%
+  \renewcommand{\pack@languages}{#1}}
+\RequirePackage[\pack@languages]{babel}
+
+ +

alors on peut l'appeler ainsi

+ +
+\documentclass[a4paper]{article}
+\usepackage[language={english, francais}]{mon_package}
+\newcommand{\option}{\texttt}
+\begin{document}
+ .
+\paragraph{Remarque}
+Noter les accolades pour que l'option \option{francais} ne soit pas
+passée comme une option à part.
+ .
+ .
+\end{document}
+
+ +

ou encore ainsi :

+ +
+\documentclass[a4paper]{article}
+\usepackage{mon_package}
+\newcommand{\option}{\texttt}
+\begin{document}
+ .
+Babel chargé avec l'option \option{francais}.
+ .
+ .
+\end{document}
+
+ +

+Là encore les options de langages ne pourront pas être spécifiées +globalement avec la commande \documentclass. (La raison en est +que les options globales qui ne correspondent pas à des options déclarées +avec \DeclareOption ne sont pas transmises à +\DeclareOption*.) +

+ +

Utiliser son package

+ +

Le package mon_package doit pouvoir être trouvé par LaTeX, +pour cela on peut :

+ + + +

Documentation et aide

+ +

Pour une documentation concernant l'écriture de classe et de +packages : clsguide (à noter également les documentations +fntguide, usrguide)  pour une documentation +générale sur LaTeX : source2e ou plus soft The not so +short introduction to LaTeX (disponible en français !).

+ +

Sur internet : CTAN, les +newsgroup fr.comp.text.tex et comp.text.tex sur +lesquels on peut faire une recherche via Google. Par +exemple  comment réaliser le symbole « 1 » avec une double +barre pour désigner une fonction indicatrice ? La réponse se trouve +sur Google, groupes et taper « group:fr.comp.text.tex 1 barre +indicatrice ». C'est une source d'informations inépuisable. +Sinon les tuteurs ou forum ens.forum.informatique.tex.

+ +
Auteur : Josselin Noirel + (16/03/2003)
+ + +