Formatage d'algorithmes

Après avoir cherché un peu comment écrire un algorithme pas trop moche en français, voici ce à quoi je suis arrivé pour l'algorithme (trivial) discuté ici. Si vous avez d'autres techniques intéressantes pour présenter les algorithmes, n'hésitez pas à les poster ici : c'est le but du fil.

Voici d'abord un petit package ad-hoc pour éviter de dupliquer le code partout (fichier br-algo-fr.sty ; vous pouvez le mettre dans le même répertoire que votre fichier .tex, ou bien dans l'arborescence TEXMF locale ou personnelle).
% br-algo-fr.sty --- Personnalisations pour algorithmes en français
% -*- coding: utf-8 -*-
%
% Copyright (C) 2020  'brian' du forum
%                     <http://www.les-mathematiques.net/phorum/index.php>
%
% 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 “brian from les-mathematiques.net”.
%
% This work consists of the sole file br-algo-fr.sty.
%
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
\ProvidesPackage{br-algo-fr}[2020/10/30 v0.1
                             Personnalisations pour algorithmes en français]
\RequirePackage{algpseudocode}
% Pour les flottants (on pourrait faire directement avec le package 'float') :
\RequirePackage{algorithm}

\floatname{algorithm}{Algorithme}
\renewcommand{\listalgorithmname}{Liste des algorithmes}
% Redéfinition du formatage de « Algorithme x --- Légende » pour les flottants
% de style 'ruled' définis par le package 'algorithm' (via le package
% 'float'). \CaptionSeparator est définie dans french.ldf de babel-french.
\renewcommand{\floatc@ruled}[2]{{\@fs@cfont #1}\CaptionSeparator #2\par}

% Commande de formatage utilisée pour les mots-clés
\@ifdefinable{\br@algo@keywordfont}{\let\br@algo@keywordfont\textbf}

% Pas de « : » après chaque numéro de ligne dans les algorithmes
\algrenewcommand{\alglinenumber}[1]{\footnotesize #1\enspace}
% Mots-clés en français
\algrenewcommand{\algorithmicprocedure}{\br@algo@keywordfont{Procédure}}
\algrenewcommand{\algorithmicfunction}{\br@algo@keywordfont{Fonction}}
\algrenewcommand{\algorithmicwhile}{\br@algo@keywordfont{Tant que}}
\algrenewcommand{\algorithmicdo}{\br@algo@keywordfont{faire}}
\algrenewcommand{\algorithmicend}{\br@algo@keywordfont{Fin}}
\algrenewcommand{\algorithmicif}{\br@algo@keywordfont{Si}}
\algrenewcommand{\algorithmicthen}{\br@algo@keywordfont{faire}}
\algrenewcommand{\algorithmicelse}{\br@algo@keywordfont{sinon}}
\algrenewtext{ElsIf}{\br@algo@keywordfont{sinon si~}}
% Pour limiter les majuscules dans les fins de blocs
\algrenewtext{EndIf}{\algorithmicend\ \br@algo@keywordfont{si}}
\algrenewtext{EndWhile}{\algorithmicend\ \br@algo@keywordfont{tant que}}
\algrenewtext{EndProcedure}{\algorithmicend\ \br@algo@keywordfont{procédure}}
\algrenewtext{EndFunction}{\algorithmicend\ \br@algo@keywordfont{fonction}}
% Exemple du manuel du package 'algorithmicx' (sur lequel s'appuie
% 'algpseudocode') :
% \algrenewtext{For}[3]{%
%   \algorithmicfor\ #1 \gets #2 \algorithmicto\ #3 \algorithmicdo}
\newcommand*{\brAlgoReturn}{\br@algo@keywordfont{Retourner}~}

% 'algorithm2e' (que je n'utilise pas) définit une telle commande... d'une
% manière pas terrible (\newcommand{\BlankLine}{\vskip 1ex}).
\providecommand*{\BlankLine}{\par\medskip}

% Normalement, french.ldf fournit ça.
\providecommand*{\CaptionSeparator}{\space\textendash\space}

\AtBeginDocument{%
  \@ifpackageloaded{caption}{%
    \DeclareCaptionLabelSeparator{babel-french}{\CaptionSeparator}%
    \captionsetup[algorithm]{labelsep=babel-french}%
  }{}%
  %
  \@ifpackageloaded{algorithm2e}{%
    \PackageError{br-algo-fr}
      {n'est pas fait pour fonctionner en même temps qu'algorithm2e}
      {%
        Nous ne sommes pas d'accord sur la définition à donner à
        \string\BlankLine.%
      }%
  }{}%
}

\endinput
Et maintenant, un exemple de fichier .tex qui utilise le fichier br-algo-fr.sty ci-dessus :
\documentclass[a4paper,french]{article}
\usepackage{lmodern}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
%\usepackage{caption}

\usepackage{br-algo-fr}
\usepackage{amsopn}             % pour \DeclareMathOperator
\usepackage{amssymb}            % pour \leqslant

% Utiliser \textproc{fonction} pour écrire le nom d'une fonction ou procédure
% définie comme algorithme (c'est équivalent à \textsc par défaut).
\DeclareMathOperator{\longueur}{longueur}
\let\leq\leqslant               % coquetterie

\makeatletter
% On récupère la police utilisée pour les mots-clés.
\@ifdefinable{\motcle}{\let\motcle\br@algo@keywordfont}
\makeatother

\begin{document}

\begin{algorithm}
  \caption{Somme des éléments d'une liste}\label{algo-somme}
  \begin{algorithmic}[1]
    \Function{Somme}{$T$}\Comment{$T$ : liste d'éléments deux à deux sommables}
      \State $n \gets \longueur(T)$
      \State $s \gets 0$
      \State $j \gets 1$
      \BlankLine
      \While{$j \leq n$}
        \State $s \gets s + T[j]$
        \State $j \gets j + 1$
      \EndWhile\label{algo-somme-fin-while}
      \BlankLine
      \State \brAlgoReturn $s$\Comment{La somme des éléments de $T$}
    \EndFunction
  \end{algorithmic}
\end{algorithm}

L'algorithme~\ref{algo-somme} est tout simple. À la
ligne~\algref{algo-somme}{algo-somme-fin-while}
(ligne~\ref{algo-somme-fin-while} de l'algorithme~\ref{algo-somme}), les
carottes sont cuites.

\begin{algorithm}
  \caption{Algorithme bidon avec \motcle{Si}... \motcle{sinon
      si}... \motcle{sinon}... \motcle{Fin si}}\label{algo-bidon}
  \begin{algorithmic}[1]
    \Function{Bidon}{$U$}
      \If{$U = 0$}
        \State $x \gets \mathtt{'a'}$
      \ElsIf{$U = 1$}
        \State $x \gets \mathtt{'b'}$
      \Else
        \State $x \gets \mathtt{'@'}$
      \EndIf
      \BlankLine
      \State \brAlgoReturn $x$
    \EndFunction
  \end{algorithmic}
\end{algorithm}

\end{document}

Edits :
  • suppression du « : » qui, par défaut, est mis après chaque numéro de ligne d'un algorithme ;
  • petit complément à l'endroit où je montre comment se référer à une ligne particulière d'un algorithme ;
  • séparation des personnalisations dans un fichier .sty (br-algo-fr.sty) pour éviter de les avoir à cinquante endroits différents ;
  • ajout d'une paire d'accolades qui manquait à la fin du \AtBeginDocument ;
  • support du package caption ;
  • ajout du code du fichier .tex qui donne la capture d'écran ;
  • quelques bricoles de nature cosmétique.
111936

Réponses

  • Bonjour Brian,

    Très esthétique ! (tu)

    Je ne sais pas si c'est intéressant mais l'on arrive à faire de jolies choses aussi avec algorithm2e. Cette extension permet, si on le souhaite, d'obtenir des traits verticaux pour les imbrications.
  • Merci Audeo. J'ai déjà vu les trucs avec traits verticaux... et c'est justement ce que je voulais éviter ! :-)

    J'ai surtout passé mon temps sur la francisation des mots-clés et le formatage de la légende comme pour les figures et tables avec babel-french. Il y a d'autres choses qui pourraient peut-être être améliorées :
    • Le \textbf est peut-être un peu lourd. C'est d'autant plus visible ici qu'il y a peu d'instructions autres que les « Fonction », « Tant que », « Fin tant que », « Retourner », etc. Peut-être que dans un algorithme plus conséquent, cela serait moins voyant (en effet, ce sont surtout les trois lignes finales qui me gênent ici). Sinon, je tenterais bien un truc du genre semi-bold de Latin modern, ou un gras appliqué sur des mots-clés en \sffamily...
    • Pour décrire les données d'entrée, on pourrait peut-être mettre ça au-dessus de l'algorithme. C'est tout à fait possible mais a priori, sans utiliser \Comment. Pour cette approche, il faudrait sans doute écrire une commande dédiée qui laisse un petit espacement vertical avant et après la description des entrées (et de la sortie, tant qu'on y est).
Connectez-vous ou Inscrivez-vous pour répondre.