% (c) Olivier Pirson --- DragonSoft --- Knots.sty
% http://www.opimedia.be/DS/
% olivier_pirson_opi@yahoo.fr
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{Knots}[2011/12/23 Knots theory]

\usepackage{calc}
\usepackage{ebezier}
\renewcommand{\qbeziermax}{1000}  % augmente le nombre de points possibles pour \cbezier



%%%%%%%%%%%%%
% Variables %
%%%%%%%%%%%%%
\newif\ifKgrid  % si true alors affiche les cadres en gris, sinon ne les affiche pas
\Kgridfalse

\newcounter{Knotslen}  % taille des cadres
\setcounter{Knotslen}{20}

\newcounter{Knotsshape}  % taille pour l'arrondi
\setcounter{Knotsshape}{\theKnotslen/5}

\newcounter{Knotsx}  % position courante en x dans l'environnement picture
\newcounter{Knotsy}  % position courante en y dans l'environnement picture



%%%%%%%%%%%%%%%%%%%%%
% Variables privées %
%%%%%%%%%%%%%%%%%%%%%
\newcounter{Knots@littlelen}  % taille de la "moitié" d'un brin du dessous
\setcounter{Knots@littlelen}{\theKnotslen/2}
\addtocounter{Knots@littlelen}{-2}

\newcounter{Knots@tmpA}  % compteur temporaire
\newcounter{Knots@tmpB}  % compteur temporaire



%%%%%%%%%%%%%
% Commandes %
%%%%%%%%%%%%%
% Commande utilisée pour fixer le style des labels A et B
\DeclareRobustCommand*{\KlabelStyle}{}

% Affiche un noeud de nb_width colonnes pour nb_height lignes.
% Les éléments du noeuds sont à spécifier dans commands,
% qui peut aussi contenir des commandes de l'environnement picture
\DeclareRobustCommand{\Knots}[3]{% nb_width, nb_height, commands
  {\setcounter{Knots@tmpA}{#1*\theKnotslen}%
    \setcounter{Knots@tmpB}{#2*\theKnotslen}%
    \Knots@def
    \begin{picture}(\theKnots@tmpA,\theKnots@tmpB)(0,0)
      \setcounter{Knots@tmpA}{0}%
      \addtocounter{Knots@tmpB}{-\theKnotslen}%
      \setcounter{Knotsx}{\theKnots@tmpA}%
      \setcounter{Knotsy}{\theKnots@tmpB}%
      #3%
    \end{picture}}}

% Fixe la taille des cadres à len
% et la taille de la "moitié" d'un brin du dessous à littlelen
\DeclareRobustCommand*{\Ksetsize}[2]{% len, littlelen
  \setcounter{Knotslen}{#1}%
  \setcounter{Knotsshape}{\theKnotslen/5}%
  \setcounter{Knots@littlelen}{#2}}



%%%%%%%%%%%%%%%%%%%
% Commande privée %
%%%%%%%%%%%%%%%%%%%
% Définis les raccourcis vers les commandes de morceaux de noeuds
\DeclareRobustCommand*{\Knots@def}{%
  \def\e{\Kempty}%
  \def\){\Kleft}%
  \def\({\Kright}%
  \def\^{\Ktop}%
  \def\_{\Kbottom}%
  \def\/{\Kup}%
  \def\\{\Kdown}%
  \def\"{\Kvert}%
  \def\={\Khori}%
  \def\%{\Kcrossup}%
  \def\&{\Kcrossdown}%
  %
  \def\A{\KcrossupA}%
  \def\B{\KcrossupB}%
  \def\a{\KcrossdownA}%
  \def\b{\KcrossdownB}%
  %
  \def\x{\Kcross}%
  %
  \def\l{\Klightbox}%
  \def\E{\Kback}%
  \def\n{\Knewline}%
  \def\N{\Kpreviousline}%
  \def\Z{\Kupbroken}%
  \def\z{\Kdownbroken}}



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Commandes des morceaux de noeuds pour l'environnement picture des morceaux de noeuds %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Déplacement d'un cadre vers la gauche
\DeclareRobustCommand*{\Kback}{%
  \addtocounter{Knotsx}{-\theKnotslen}}

% Cadre bottom : \
\DeclareRobustCommand*{\Kbottom}[1][0]{% [n]
  \put(\theKnotsx,\theKnotsy){\ifKgrid\Klightbox\fi}%
  %
  \setcounter{Knots@tmpA}{\theKnotsy}%
  \addtocounter{Knots@tmpA}{\theKnotsshape}%
  \setcounter{Knots@tmpB}{\theKnotsx}%
  \addtocounter{Knots@tmpB}{\theKnotslen}%
  \cbezier[#1](\theKnotsx,\theKnotsy)(\theKnotsx,\theKnots@tmpA)%
              (\theKnots@tmpB,\theKnots@tmpA)(\theKnots@tmpB,\theKnotsy)%
  \addtocounter{Knotsx}{\theKnotslen}}

% Cadre vide
\DeclareRobustCommand*{\Kempty}{%
  \put(\theKnotsx,\theKnotsy){\ifKgrid\Klightbox\fi}%
  \addtocounter{Knotsx}{\theKnotslen}}

% Cadre cross : x
\DeclareRobustCommand*{\Kcross}[1][0]{% [n]
  \Kup[#1]%
  \Kback
  \Kdown[#1]}

% Cadre crossdown : &
\DeclareRobustCommand*{\Kcrossdown}[1][0]{% [n]
  \Kdown[#1]%
  \Kback
  \Kupbroken}

% Cadre crossdownA : a
\DeclareRobustCommand*{\KcrossdownA}[1][0]{% [n]
  \put(\theKnotsx,\theKnotsy){\makebox(\theKnotslen,\theKnotslen){\KlabelStyle A}}%
  \Khori[#1]}

% Cadre crossdownB : b
\DeclareRobustCommand*{\KcrossdownB}[1][0]{% [n]
  \put(\theKnotsx,\theKnotsy){\makebox(\theKnotslen,\theKnotslen){\KlabelStyle B}}%
  \Kvert[#1]}

% Cadre crossup : %
\DeclareRobustCommand*{\Kcrossup}[1][0]{% [n]
  \Kup[#1]%
  \Kback
  \Kdownbroken}

% Cadre crossupA : A
\DeclareRobustCommand*{\KcrossupA}[1][0]{% [n]
  \put(\theKnotsx,\theKnotsy){\makebox(\theKnotslen,\theKnotslen){\KlabelStyle A}}%
  \Kvert[#1]}

% Cadre crossupB : B
\DeclareRobustCommand*{\KcrossupB}[1][0]{% [n]
  \put(\theKnotsx,\theKnotsy){\makebox(\theKnotslen,\theKnotslen){\KlabelStyle B}}%
  \Khori[#1]}

% Cadre down : \
\DeclareRobustCommand*{\Kdown}[1][0]{% [n]
  \put(\theKnotsx,\theKnotsy){\ifKgrid\Klightbox\fi}%
  \setcounter{Knots@tmpA}{\theKnotsx}%
  \addtocounter{Knotsx}{\theKnotslen}%
  \setcounter{Knots@tmpB}{\theKnotsy}%
  \addtocounter{Knots@tmpB}{\theKnotslen}%
  \lbezier[#1](\theKnots@tmpA,\theKnots@tmpB)(\theKnotsx,\theKnotsy)}

% Cadre down brisé : \
\DeclareRobustCommand*{\Kdownbroken}[1][0]{% [n]
  \put(\theKnotsx,\theKnotsy){\ifKgrid\Klightbox\fi}%
  %
  \setcounter{Knots@tmpA}{\theKnotsx}%
  \addtocounter{Knots@tmpA}{\theKnots@littlelen}%
  \addtocounter{Knotsy}{\theKnotslen}%
  \setcounter{Knots@tmpB}{\theKnotsy}%
  \addtocounter{Knots@tmpB}{-\theKnots@littlelen}%
  \lbezier(\theKnotsx,\theKnotsy)(\theKnots@tmpA,\theKnots@tmpB)%
  %
  \addtocounter{Knotsx}{\theKnotslen}%
  \setcounter{Knots@tmpA}{\theKnotsx}%
  \addtocounter{Knots@tmpA}{-\theKnots@littlelen}%
  \addtocounter{Knotsy}{-\theKnotslen}%
  \setcounter{Knots@tmpB}{\theKnotsy}%
  \addtocounter{Knots@tmpB}{\theKnots@littlelen}%
  \lbezier(\theKnots@tmpA,\theKnots@tmpB)(\theKnotsx,\theKnotsy)}

% Cadre hori : =
\DeclareRobustCommand*{\Khori}[1][0]{% [n]
  \Kbottom[#1]%
  \Kback
  \Ktop[#1]}

% Cadre left : )
\DeclareRobustCommand*{\Kleft}[1][0]{% [n]
  \put(\theKnotsx,\theKnotsy){\ifKgrid\Klightbox\fi}%
  \setcounter{Knots@tmpA}{\theKnotsx}%
  \addtocounter{Knots@tmpA}{\theKnotsshape}%
  \setcounter{Knots@tmpB}{\theKnotsy}%
  \addtocounter{Knots@tmpB}{\theKnotslen}%
  \cbezier[#1](\theKnotsx,\theKnotsy)(\theKnots@tmpA,\theKnotsy)%
              (\theKnots@tmpA,\theKnots@tmpB)(\theKnotsx,\theKnots@tmpB)%
  \addtocounter{Knotsx}{\theKnotslen}}

% Cadre gris (quelque soit la valeur de \ifKgrid)
\DeclareRobustCommand*{\Klightbox}{%
  \color{Gray}%
  \linethickness{.1pt}%
  \framebox(\theKnotslen,\theKnotslen){}}

% Passe à la ligne (de cadres) suivante
\DeclareRobustCommand*{\Knewline}{%
  \setcounter{Knotsx}{0}%
  \addtocounter{Knotsy}{-\theKnotslen}}

% Passe à la ligne (de cadres) précédente
\DeclareRobustCommand*{\Kpreviousline}{%
  \setcounter{Knotsx}{0}%
  \addtocounter{Knotsy}{+\theKnotslen}}

% Cadre right : (
\DeclareRobustCommand*{\Kright}[1][0]{% [n]
  \put(\theKnotsx,\theKnotsy){\ifKgrid\Klightbox\fi}%
  \addtocounter{Knotsx}{\theKnotslen}%
  \setcounter{Knots@tmpA}{\theKnotsx}%
  \addtocounter{Knots@tmpA}{-\theKnotsshape}%
  \setcounter{Knots@tmpB}{\theKnotsy}%
  \addtocounter{Knots@tmpB}{\theKnotslen}%
  \cbezier[#1](\theKnotsx,\theKnotsy)(\theKnots@tmpA,\theKnotsy)%
              (\theKnots@tmpA,\theKnots@tmpB)(\theKnotsx,\theKnots@tmpB)}

% Cadre top : ^
\DeclareRobustCommand*{\Ktop}[1][0]{% [n]
  \put(\theKnotsx,\theKnotsy){\ifKgrid\Klightbox\fi}%
  \addtocounter{Knotsy}{\theKnotslen}%
  \setcounter{Knots@tmpA}{\theKnotsy}%
  \addtocounter{Knots@tmpA}{-\theKnotsshape}%
  \setcounter{Knots@tmpB}{\theKnotsx}%
  \addtocounter{Knots@tmpB}{\theKnotslen}%
  \cbezier[#1](\theKnotsx,\theKnotsy)(\theKnotsx,\theKnots@tmpA)%
              (\theKnots@tmpB,\theKnots@tmpA)(\theKnots@tmpB,\theKnotsy)%
  \addtocounter{Knotsy}{-\theKnotslen}%
  \addtocounter{Knotsx}{\theKnotslen}}

% Cadre up : /
\DeclareRobustCommand*{\Kup}[1][0]{% [n]
  \put(\theKnotsx,\theKnotsy){\ifKgrid\Klightbox\fi}%
  \setcounter{Knots@tmpA}{\theKnotsx}%
  \addtocounter{Knotsx}{\theKnotslen}%
  \setcounter{Knots@tmpB}{\theKnotsy}%
  \addtocounter{Knots@tmpB}{\theKnotslen}%
  \lbezier[#1](\theKnots@tmpA,\theKnotsy)(\theKnotsx,\theKnots@tmpB)}

% Cadre up brisé : /
\DeclareRobustCommand*{\Kupbroken}[1][0]{% [n]
  \put(\theKnotsx,\theKnotsy){\ifKgrid\Klightbox\fi}%
  %
  \setcounter{Knots@tmpA}{\theKnotsx}%
  \addtocounter{Knots@tmpA}{\theKnots@littlelen}%
  \setcounter{Knots@tmpB}{\theKnotsy}%
  \addtocounter{Knots@tmpB}{\theKnots@littlelen}%
  \lbezier(\theKnotsx,\theKnotsy)(\theKnots@tmpA,\theKnots@tmpB)%
  %
  \addtocounter{Knotsx}{\theKnotslen}%
  \setcounter{Knots@tmpA}{\theKnotsx}%
  \addtocounter{Knots@tmpA}{-\theKnots@littlelen}%
  \addtocounter{Knotsy}{\theKnotslen}%
  \setcounter{Knots@tmpB}{\theKnotsy}%
  \addtocounter{Knots@tmpB}{-\theKnots@littlelen}%
  \lbezier(\theKnots@tmpA,\theKnots@tmpB)(\theKnotsx,\theKnotsy)%
  \addtocounter{Knotsy}{-\theKnotslen}}

% Cadre vert : "
\DeclareRobustCommand*{\Kvert}[1][0]{% [n]
  \Kleft[#1]%
  \Kback
  \Kright[#1]}
