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 @@ + + + +
++Définir son propre package permet :
+ ++\usepackage[francais]{babel} +\usepackage[latin1]{inputenc} +\usepackage[T1]{fontenc} +\usepackage[dvips]{graphicx} +\usepackage{amsmath} +\usepackage{amssymb} ++
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 :
+%% 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 ++ +
\NeedsTeXFormat{<formar>}[<version>]
:
+ informe TeX du format (LaTeX2e, donc refus de LaTeX2.09, plain TeX,
+ eplain TeX, AMS-TeX, etc.) nécessaire pour l'utilisation du
+ package, on peut spécifier un argument optionnel (entre crochets)
+ permettant d'utiliser des versions récentes dudit format ;\ProvidesPackage{<package>}[<version>]
:
+ le package s'identifie (là encore on peut donner en argument
+ optionnel une date de version) ;\RequirePackage[<options>]{<package>}
:
+ équivalent de \usepackage
pour l'écriture d'un package
+ ou d'une classe, on peut passer des options au package comme
+ habituellement ;\DeclareOption{<option>}{<action>}
:
+ déclare une option qui peut être passée lors de l'appel du
+ package, lorsque l'option <option>
est passée
+ <action>
est exécutée ;\DeclareOption*{<action>}
:
+ comportement adopté par le package quand il est confronté à une
+ option passée qui n'est pas déclarée ;\ProcessOptions
: exécute le code des options
+ passées, si cette commande n'existe pas dans le package les options
+ seront sans effet (bien prendre conscience que les declarations
+ n'exécutent pas de code!) ;\newcommand{\commande}{<code>}
:
+ définition d'une nouvelle commande (voir la page sur les
+ macros) ;\endinput
: fin du package.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 :
\ifquelquechose
à utiliser ainsi (la
+partie « else » est facultative)
++\ifquelquechose + Code si oui +\else + Code si non +\fi +
\quelquechosetrue
+ \ifquelquechose
devient
+ équivalent à if true ;\quelquechosefalse
+ \ifquelquechose
devient
+ équivalent à if false.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
:
\usepackage
++\documentclass[a4paper, dvips]{article} +\usepackage[algo]{mon_package} +\begin{document} + . + . + . +\end{document} +
\documentclass
++\documentclass[a4paper, dvips, algo]{article} +\usepackage{mon_package} +\begin{document} + . + . + . +\end{document} +
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 ».
+\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 ++ +
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). +
+ +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.
keyval
de David Carliste (ou
+ peut-être prochainement une page tuteurs à ce sujet) ;\@ifundefined{commande}{<then>}{<else>}
: si
+ \commande
(avec le backslash contrairement à l'argument
+ de \@ifundefined
) n'est pas définie alors exécute
+ <then>
sinon exécute
+ <else>
(LaTeX interne) ;\PackageWarning{<package>}{<texte>}
: produit un warning lors de la
+ compilation (par opposition à \PackageError{...}{...}
) ;\CurrentOption
: l'option en cours de
+ traitement ;+\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 ++ +
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).
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*
.)
+
Le package mon_package
doit pouvoir être trouvé par LaTeX,
+pour cela on peut :
mon_package
dans le même répertoire que
+les fichier .tex
qui l'utilisent ;~/texmf/tex/latex/perso/
et créer la variable d'environnement
+export TEXINPUTS=$HOME/texmf//:
(certaines distributions
+permettent de créer un fichier ls-R grâce à la commande
+texhash
) ;mktexlsr
.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
.