% boites.sty
% (c) 1998-1999 Vincent Zoonekynd <zoonek@math.jussieu.fr>
% Distributed under the GNU Public Licence
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% Mars 1999 : Il y a certaines lignes �� ne pas num��roter (par
%%             exemple, celles qui ne contiennent que des espaces
%%             verticaux avant ou apr��s une ��num��ration).
%% Mars 1999 : commentaires
%%
%% Modifiations par VZ, Juillet 1998
%%
%% Il y a quelques bugs, en particulier des traits qui sont trop
%% longs, trop courts, trop ��pais ou trop fins. Si Quelqu'un sait ��
%% quoi c'est d��, qu'il me le dise.
%%
%% Il ne devrait plus y avoir de probl��me �� cause d'un environement de
%% type liste (itemize, enumerate, etc.) �� l'int��rieur des boites.
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% D'apr��s :
% eclbkbox.sty by Hideki Isozaki, 1992
% Date: May  28, 1993

\ProvidesFile{boites.sty}
\ProvidesPackage{boites}[2013/11/21 v1.1 Colored, framed and breakable across pages boxes]

\newbox\bk@bxb
\newbox\bk@bxa
\newif\if@bkcont 
\newif\ifbkcount
\newcount\bk@lcnt

\def\breakboxskip{2pt}
\def\breakboxparindent{1.8em}

%% Param��tres modifiables
%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\bkvz@before@breakbox{\ifhmode\par\fi\vskip\breakboxskip\relax}

% Ce que l'on met �� gauche du texte, par exemple, une ligne verticale
% pour faire un cadre, ou une ligne qui ondule.
\def\bkvz@left{\vrule \@width\fboxrule\hskip\fboxsep}

% De m��me, ce que l'on met �� droite,
\def\bkvz@right{\hskip\fboxsep\vrule \@width\fboxrule}

% en haut
\def\bkvz@top{\hrule\@height\fboxrule}

% ou en bas
\def\bkvz@bottom{\hrule\@height\fboxrule}

% Si vous modifiez l'une de ces macros, il ne faut pas oublier de
% modifier aussi la suivante, qui change la valeur de \linewidth en
% lui retirant la largeur de tout ce que l'on vient de mettre sur le
% c��t��. 
\def\bkvz@set@linewidth{%
  \advance\linewidth -2\fboxrule
  \advance\linewidth -2\fboxsep
}

%% FIN DES PARAM��TRES MODIFIABLES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% Le d��but de l'environement
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\breakbox{%
    % On n'est pas n��cessairement en mode vertical.
    % C'est \bkvz@before@breakbox qui s'en occupe (ou non).
  \bkvz@before@breakbox
    % on met tout dans une \vbox (\bk@bxb)
  \setbox\bk@bxb\vbox\bgroup
    % �� l'int��rieur de cette \vbox, on change la valeur de \hsize (et
    % aussi \linewidth).
  \bkvz@set@linewidth
  \hsize\linewidth
    % je ne sais pas ce que fait la commande \@parboxrestore.
  \@parboxrestore
    % On indente ��ventuellement, si l'utilisateur le d��sire. 
  \parindent\breakboxparindent\relax
}

%% On coupe la boite
%%%%%%%%%%%%%%%%%%%%%%
% \@tempdimb: amount of vertical skip 
% between the first line (\bk@bxa) and the rest (\bk@bxb)
\def\bk@split{%
    % On calcule la hauteur totale (hauteur + profondeur) de la boite.
  \@tempdimb\ht\bk@bxb % height of original box
  \advance\@tempdimb\dp\bk@bxb 
    % On coupe, �� l'aide de la commande \vsplit... to 0pt
    % Le morceau du haut se retrouve dans \bk@bxa, 
    % celui du bas dans \bk@bxb.
  \setbox\bk@bxa\vsplit\bk@bxb to\z@ % split it
    % L'un des probl��mes, c'est que la premi��re boite a une hauteur vide. 
    % On peut lui redonner sa hauteur initiale grace �� \vbox{\unvbox...}
  \setbox\bk@bxa\vbox{\unvbox\bk@bxa}% recover height & depth of \bk@bxa
    % L'autre probl��me, c'est que l'on a perdu l'espace (interligne) entre
    % nos deux boites. Pour le r��cup��rer, on ajoute la hauteur de ces deux
    % boites, et on fait la diff��rence avec la hauteur initiale.
  \setbox\@tempboxa\vbox{\copy\bk@bxa\copy\bk@bxb}% naive concatenation
  \advance\@tempdimb-\ht\@tempboxa 
  \advance\@tempdimb-\dp\@tempboxa
    % D��sormais, \@tempdimb contient l'espace entre les deux boites, que
    % l'on utilisera avec \bk@addskipdp.
}% gap between two boxes
 
%% Rajouter \fboxsep �� la premi��re ligne
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \@tempdima: height of the first line (\bk@bxa) + fboxsep
\def\bk@addfsepht{%
  \setbox\bk@bxa\vbox{\vskip\fboxsep\box\bk@bxa}%
}

%% cette macro n'est pas utilis��e
\def\bk@addskipht{%
  \setbox\bk@bxa\vbox{\vskip\@tempdimb\box\bk@bxa}%
}

%% Rajouter \fboxsep �� la derni��re ligne
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \@tempdima: depth of the first line (\bk@bxa) + fboxsep
\def\bk@addfsepdp{%
  \@tempdima\dp\bk@bxa
  \advance\@tempdima\fboxsep
  \dp\bk@bxa\@tempdima
}

%% Rajouter l'espace qui a ��t�� perdu par \vsplit... to 0pt
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \@tempdima: depth of the first line (\bk@bxa) + vertical skip
\def\bk@addskipdp{%
  \@tempdima\dp\bk@bxa
  \advance\@tempdima\@tempdimb
  \dp\bk@bxa\@tempdima
}

%% On ne compte pas toutes les lignes, mais uniquement celles qui en
%% sont vraiment. J'ai pris comme crit��re une largeur sup��rieure ��
%% 1mm.  La m��me distance se retrouve un peu plus loin, dans
%% \bk@line. 
\def\bkvz@countlines{%
  \ifdim\wd\bk@bxa>1mm
    \advance\bk@lcnt\@ne
  \fi
}

%% Afficher la ligne que l'on vient de couper
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\bk@line{%
  \hbox to \linewidth{%
    \ifdim\wd\bk@bxa>1mm
      \ifbkcount\smash{\llap{\the\bk@lcnt\ }}\fi
    \fi
    \bkvz@left
    \box\bk@bxa
      % Il arrive que la boite ne soit pas aussi large que la ligne
      % (par exemple, espace avant une ��num��ration)
    \hfil
    \bkvz@right
  }%
}

%% La fin de l'environement
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\endbreakbox{%
    % On ferme la \vbox (\bk@bxb)
  \egroup
  %\ifhmode\par\fi
  {%
    \noindent
      % On remet le compteur de lignes �� un.
    \bk@lcnt 0%
      % Le bool��en que nous allons utiliser dans la boucle plus loin.
    \@bkconttrue
      % Comme on va empiler des boites, on met certains ressorts �� z��ro,
      % pour ��viter les espaces verticaux non d��sir��s.
    \splittopskip\z@ % glue inserted at the top of a box resulting from a \vsplit
    \baselineskip\z@
    \lineskiplimit\z@
    \lineskip\z@
    \vfuzz\maxdimen
      % On coupe la boite
    \bk@split
      % On ajoute un peu d'espace vertical (\fboxsep) au dessus
    \bk@addfsepht
      % On ajoute en dessous l'espace qui avait ��t�� perdu par la commande
      % \vsplit.
    \bk@addskipdp
      % De deux choses l'une,
    \ifvoid\bk@bxb
        % Soit, il n'y a qu'une ligne
      \def\bk@fstln{%
          % On rajoute un peu d'espace (\fboxsep) en dessous.
        \bk@addfsepdp
          % On construit la boite : le haut, le milieu (qui contient la gauche
          % et la droite) et le bas.
        \bkvz@countlines
        \vbox{\bk@singleline}%
      }%
      % Soit, il y en a plusieurs.
    \else
      \def\bk@fstln{%
          % On met le haut
        \bkvz@countlines
        \vbox{\bk@firstline}%
          % ??? (Si on l'enl��ve, ��a ne marche plus.)
        \hfil
          % On commence �� compter les lignes
        %\advance\bk@lcnt\@ne %%%%%%%%%%%%%%%%%%%% Voir \bkvz@countlines
          % D��but de la boucle
        \loop
            % On coupe ce qui reste de la boite.
          \bk@split
            % On rajoute l'espace vertical qui a ��t�� perdu.
          \bk@addskipdp
            % ��ventuellement, on augmente le num��ro de la ligne
          \bkvz@countlines
            % ???
          \leavevmode
            % S'il s'agit de la derni��re ligne
          \ifvoid\bk@bxb
              % On met le bool��en indiquant que la boucle doit se poursuivre �� FAUX.
            \@bkcontfalse
              % On met un peu d'espace vertical (\fboxsep)
            \bk@addfsepdp
              % En envoie la derni��re ligne.
              % POURQUOI \vtop ??? Pour que l'��ventuel num��ro de ligne soit �� la
              % bonne hauteur.
            \vtop{\bk@lastline}%
          \else               % 2,...,(n-1)
            \bk@middleline
          \fi
          \hfil
          %\advance\bk@lcnt\@ne %%%%%%%%%%%%%%%% Voir \bkvz@countlines
          \if@bkcont\repeat
      }%
    \fi
    \leavevmode\bk@fstln\par
  }%
  \vskip\breakboxskip\relax
}

\bkcountfalse

\def\bk@singleline{%
  \bkvz@top
  \bk@line
  \bkvz@bottom
}

\def\bk@firstline{%
  \bkvz@top
  \bk@line
}

\def\bk@middleline{%
  \bk@line
}

\def\bk@lastline{%
  \bk@line
  \bkvz@bottom
}