\documentclass{amsart}
\input{boxdiag}

\usepackage{tikz}
\usetikzlibrary{shapes.multipart, positioning,
decorations.pathreplacing, decorations.markings,
decorations.pathmorphing, calc, matrix, cd}
\usepackage[calc]{picture}
\usepackage{graphicx}
\usepackage{scalerel}
\usepackage{relsize}


\theoremstyle{definition}
\newtheorem{chunk}{}[section]

\tikzset{fontscale/.style = {font=\relsize{#1}}
}

\pgfkeys{braceDec/.style = {hline left = -1, hline right = 1, hline
      vert = 1.05, hline
      dec = brace}}
 \pgfkeys{justLabel/.style = {input color = white, input two color =
     white, output color = white, box line color = white, box fill
     color = white}}

%%%-------------------------------------------------------------------
%%%-------------------------------------------------------------------
%%%-------------------------------------------------------------------
%%%-------------------------------------------------------------------
%%%-------------------------------------------------------------------
%%%-------------------------------------------------------------------
%%%-------------------------------------------------------------------
\begin{document}
\title{Box diagrams in TikZ}\author{Jesse Burke}
\maketitle

\section{Introduction}
Box diagrams are a rudimentary form of string diagram used to represent a
function or morphism in a category. We implement them as a type of
object in tikz, analogous to a node. Some examples created with this
package include:
\begin{displaymath}
  \begin{tikzpicture}
    \boxdiagram[label = \alpha, width = .25cm, input height = .5cm]{ab};
    \drawBox{ab};
    \drawInput[input color = black!20!red, input dec = coil, input dec
    amp = 2, input dec seg length = .1cm]{ab}{0};
    \drawOutput[output color = black!20!green, output dec = coil, output dec
    amp = 2, output dec seg length = .1cm]{ab}{0};
    \coordBottomOutput{ab}{coor1}{-1.2};
    \boxdiagram[label = \nu, coord = (coor1), output height = 1.5cm]{n};
    \drawBox{n};
    \drawInput{n}{-1}; \drawInput{n}{1};
    \drawHLine{n};
    \drawOutput{n}{-.5};
  \end{tikzpicture}
  \quad \quad \quad \quad
  \begin{tikzpicture}
    \boxdiagram[width = 1cm]{h};
    \drawNoInput[output color = black!20!red, output dash pattern = densely
    dashed, output line width = .6mm]{h};
    \coordTopBox{h}{coor1}{-1};
    \coordTopBox{h}{coor2}{0};
    \coordTopBox{h}{coor3}{1};
    \boxdiagram[coord = (coor1), width = .35cm]{g};
    \boxdiagram[coord = (coor2), label = \bs{\ldots}, width = .35cm]{gtwo};
    \boxdiagram[coord = (coor3), width = .35cm, label = g]{gk};
    \drawBd[output color = blue, output dash pattern =  dotted, output
    line width =
    1mm]{g};
    \drawBd[output color = blue, output dash pattern =  dotted, output
    line width = 1mm]{gk};
    %\drawBd[/justLabel]{gtwo};
    \drawHLine{g};
    \drawHLine{gk};
  \end{tikzpicture}
  \quad \quad \quad \quad
  \begin{tikzpicture}
    \boxdiagram[width = 1.2cm, label = g, input height =
    1.75cm]{g};
    \drawInput{g}{-1};
    \drawBox{g};
    \drawOutput[output dec = snake,output color =
    black!60!green]{g}{0};
    \drawHLine[hline left = -.9, hline right = -.7]{g};
    \drawInput{g}{-.6};
    \coordTopBox{g}{coor}{-.05};
    \boxdiagram[coord = (coor), label = \nu]{n};
    \drawBd{n};
    \drawInput{g}{.5};
    \drawInput{g}{1};
    \drawHLine[hline left = .6, hline right = .9]{g};
  \end{tikzpicture}
\end{displaymath}


\section{Basics}
\begin{chunk}
  Box diagrams are created and drawn using \texttt{\textbackslash
    boxdiagram} and
  \texttt{\textbackslash drawBd}, e.g.,\\
  \hfill
  \begin{minipage}{0.3\textwidth}
\begin{verbatim}
    \begin{tikzpicture}
      \boxdiagram{f}; \drawBd{f};
    \end{tikzpicture}
\end{verbatim}
  \end{minipage}
  \hfill
  \begin{minipage}{.6\linewidth}\mbox{}\\
    \begin{displaymath}
      \begin{tikzpicture}
        \boxdiagram{f};
        \drawBd{f};
      \end{tikzpicture}
      \quad \quad \quad \quad \quad \qquad
    \end{displaymath}
    \hfill
  \end{minipage}
\end{chunk}

\begin{chunk}
  Just as one can set the coordinate, label, etc. of a node,
  each box has many attributes. There are default values that can be
  changed when creating or drawing the box, by passing an optional
  list of key-value pairs. Two of the most basic attributes are
  \texttt{coord}, the coordinate of the bottom end of the output, with
  default value $(0,0),$ and \texttt{label}, the label printed inside the
  box (with default value the name of the diagram).
  \\\hfill
  \begin{minipage}{0.55\textwidth}
\begin{verbatim}
\begin{tikzpicture}
  \boxdiagram{f}; 
  \drawBd{f}; 
  \boxdiagram[coord = {(2,1)}, 
     label = box]{g};
  \drawBd{g};
\end{tikzpicture}
\end{verbatim}
  \end{minipage}
  \hfill
  \begin{minipage}{.35\linewidth}\mbox{}\\
    \begin{displaymath}
      \begin{tikzpicture}
        \draw[step=1cm,gray,very thin] (-1,0) grid (3,3); \boxdiagram{f};
        \drawBd{f}; \boxdiagram[coord = {(2,1)}, label = box]{g};
        \drawBd{g};
      \end{tikzpicture}
      \quad \quad \quad \quad \quad \qquad
    \end{displaymath}
    \hfill
  \end{minipage}
\end{chunk}

\begin{chunk}
  There are five size attributes: \texttt{width, box height, input
    height, input two height, output height:}\footnote{An explanation for the variable
    names is that box diagrams can be used to represent functions,
    with the top lines representing input values and the bottom line
    the value on the function on these inputs; more generally, the
    diagram can be used in the same way to represent a morphism from a
    tensor product of a module to another module.}  \makeatletter

  \begin{displaymath}
    \tikzset{every picture/.append style={scale=1.5}, every
      node/.style={transform shape, font = \tiny}}
    \begin{tikzpicture}
      \boxdiagram[box fill color = white, label={}, width = 1cm, input
      height =1cm, output height = .85cm]{f}; \drawBd{f};
      \node[shape=coordinate] (l@ft) at (0,0) {}; \f.coord bottom
      box(l@ft, 0); \node[shape=coordinate] (r@ght) at (0,0) {};
      \f.coord bottom box(r@ght, 1);
 
      \draw[decorate,decoration={brace,amplitude = 4},] (l@ft) --
      (r@ght) node[midway, above, ] {\tiny{width}};

      \f.coord bottom box(l@ft, -1); \f.coord top box(r@ght, -1);
      \draw[decorate,decoration={brace,amplitude = 4}] (l@ft) --
      (r@ght) node[midway, label={[align=left]left:box\\height}, ] {};

      \f.coord top box(l@ft, -1); \f.coord top input(r@ght, -1);
      \draw[decorate,decoration={brace,amplitude = 4}] (l@ft) --
      (r@ght) node[midway, label={[align=left]left:input\\height}, ]
      {};

      \f.coord top box(l@ft, 1); \f.coord top input(r@ght, 1);
      \draw[decorate,decoration={brace,amplitude = 4, mirror}] (l@ft) --
      ($ (l@ft) !.75! (r@ght) $) node[midway,
      label={[align=left]right:input two\\height}, ]
      {};

      \f.coord bottom box(l@ft, 0); \f.coord bottom output(r@ght, 0);
      \draw[decorate,decoration={brace,amplitude = 4, mirror}] (l@ft)
      -- (r@ght) node[midway, label={[align=left]left:output\\height},
      ] {};
    \end{tikzpicture}
  \end{displaymath}
  \makeatother The default values are: \texttt{width = .5cm, box
    height = .5cm, input height = .75cm, input two height = .75cm, output height = .5cm}. For
  example: \\
  \mbox{}\\\hfill
  \begin{minipage}{0.45\textwidth}
\begin{verbatim}
\begin{tikzpicture}
  \boxdiagram{f}; 
  \drawBd{f}; 
  \boxdiagram[coord = {(2.5,0)}]{g}; 
  \drawBd[width = 1cm, 
          box height = .75cm, 
          input height = 1cm, 
          input two height = 1.5cm,
          output height = .25cm]{g};
\end{tikzpicture}
\end{verbatim}
  \end{minipage}
  \hfill
  \begin{minipage}{.45\linewidth}\mbox{}\\
    \begin{displaymath}
      \begin{tikzpicture}
        \draw[step=1cm,gray,very thin] (-1,0) grid (4,3); \boxdiagram{f};
        \drawBd{f}; \boxdiagram[coord = {(2.5,0)}]{g}; \drawBd[width = 1cm,
        box height = .75cm, input height = 1cm, input two height =
        1.5cm, output height =
        .25cm]{g};
      \end{tikzpicture}
      \quad \quad \quad \quad \quad \qquad
    \end{displaymath}
    \hfill
  \end{minipage}
\end{chunk}

\begin{chunk}
  Colors can be changed with the attributes \texttt{input color, input
    two color, output color, box line color, box fill color, label
    color}, whose default values are all black, except for \texttt{box
  fill color}, which is black!20. For example:\\
  \mbox{}\\\hfill
  \begin{minipage}{0.45\textwidth}
\begin{verbatim}
\begin{tikzpicture}
  \boxdiagram{f}; 
  \drawBd{f}; 
  \boxdiagram[coord = {(1.5,0)}]{g}; 
  \drawBd[input color = red, 
          input two color = blue, 
          output color = green]{g};
  \boxdiagram[coord = {(3,0)}]{h}; 
  \drawBd[box line color = red, 
          box fill color = blue!40, 
          label color = green]{h};
\end{tikzpicture}
\end{verbatim}
  \end{minipage}
  \hfill
  \begin{minipage}{.45\linewidth}\mbox{}\\
    \begin{displaymath}
      \begin{tikzpicture}
         \draw[step=1cm,gray,very thin] (-1,0) grid (4,3);
  \boxdiagram{f}; 
  \drawBd{f}; 
  \boxdiagram[coord = {(1.5,0)}]{g}; 
  \drawBd[input color = red, 
          input two color = blue, 
          output color = green]{g};
            \boxdiagram[coord = {(3,0)}]{h}; 
  \drawBd[box line color = red, 
          box fill color = blue!40, 
          label color = green]{h};
\end{tikzpicture}
      \quad \quad \quad \quad \quad \qquad
    \end{displaymath}
    \hfill
  \end{minipage}
\end{chunk}

\begin{chunk}
  Instead of drawing the whole diagram, one can draw pieces with the
  functions \texttt{drawBox, drawInput, drawInputTwo, drawOutput}; the last three take
  as a second argument the
  relative horizontal position of the line to be drawn, with -1 the
  left side of the box and 1 the right side of the box. The relative
  position does not have to be between [-1,1]. For example:\\
  \mbox{}\\
    \begin{minipage}{0.45\textwidth}
\begin{verbatim}
\begin{tikzpicture}
  \boxdiagram[input color = red]{f}; 
  \drawBox{f};
  \drawInput{f}{-1};
  \drawInputTwo{f}{1};
  \drawOutput{f}{-1};
  \drawOutput{f}{1.5};
\end{tikzpicture}
\end{verbatim}
  \end{minipage}
  \hfill
  \begin{minipage}{.45\linewidth}\mbox{}\\
    \begin{displaymath}
      \begin{tikzpicture}
        \draw[step=1cm,gray,very thin] (-1,0) grid (2,2);
         \boxdiagram[input color = red]{f}; 
  \drawBox{f};
  \drawInput{f}{-1};
  \drawOutput{f}{1.5};
  \drawOutput{f}{-1};
  \drawInputTwo{f}{1};
      \end{tikzpicture}
      \quad \quad \quad \quad \quad \qquad
    \end{displaymath}
    \hfill
  \end{minipage}\\
  \mbox{}\\
  You can draw straight lines using the following:\\
    \mbox{}\\
    \begin{minipage}{0.45\textwidth}
\begin{verbatim}
\begin{tikzpicture}
    \boxdiagram[box height = 0pt, 
             output height = 0pt]{f};
    \drawInput{f}{-1};
    \drawInput{f}{0};
    \drawInput{f}{1};
\end{tikzpicture}
\end{verbatim}
  \end{minipage}
  \hfill
  \begin{minipage}{.45\linewidth}\mbox{}\\
    \begin{displaymath}
          \begin{tikzpicture}
    \boxdiagram[box height = 0pt, output height = 0pt]{f};
    \drawInput{f}{-1};
    \drawInput{f}{0};
    \drawInput{f}{1};
  \end{tikzpicture}
      \quad \quad \quad \quad \quad \qquad
    \end{displaymath}
    \hfill
  \end{minipage}\\
  \mbox{}\\
  You can draw lines the usual way in TikZ, but using a box diagram
  can help with spacing in a more complicated display.
\end{chunk}

\begin{chunk}
Each of the four line types: input, input two, output, and box line,
have six different style attributes: \texttt{dash pattern, line width, label,
  dec, dec amp, dec seg length}, where \texttt{dec} stands for
decoration, and uses the decoration library of TikZ (also there is no
label allowed on the box line). The default values are \texttt{dash
  pattern = \{\}, line
  width = .3mm, label = \{\}, dec = \{\}, dec amp = 2, dec seg length = .2cm}. For example:\\
\mbox{}\\
    \begin{minipage}{0.65\textwidth}
\begin{verbatim}
\begin{tikzpicture}
  \boxdiagram[width = 1cm,
           input two dash pattern = dotted,
           output label = \pi]{f}; 
  \drawBd[input line width = .6mm]{f};
  \drawInput[input dec = snake]{f}{-.5};
  \drawInput[input dec = snake, 
             input dec amp = 4, 
             input dec seg length = .1cm]{f}{.5};
  \boxdiagram[coord = {(2,0)},
           box line dec = coil,
           box line dec seg length = .1cm]{g};
  \drawBd{g};
\end{tikzpicture}
\end{verbatim}
  \end{minipage}
  \hfill
  \begin{minipage}{.25\linewidth}\mbox{}\\
    \begin{displaymath}
      \begin{tikzpicture}
        \draw[step=1cm,gray,very thin] (-1.5,0) grid (3,2);
        \boxdiagram[width = 1cm,
    input two dash pattern = dotted, output label = \pi]{f}; 
    \drawBd[input line width = .6mm]{f};
    \drawInput[input dec = snake]{f}{-.5};
    \drawInput[input dec = snake, input dec amp = 4, input dec seg
    length = .1cm]{f}{.5};
    \boxdiagram[coord = {(2,0)},
    box line dec = coil,
    box line dec seg length = .1cm]{g};
    \drawBd{g};
      \end{tikzpicture}
      \quad \quad \quad \quad \quad \qquad
    \end{displaymath}
    \hfill
  \end{minipage}\\
  \mbox{}\\
  
  Another common type of example is:\\
  \mbox{}\\
    \begin{minipage}{0.70\textwidth}
\begin{verbatim}
\begin{tikzpicture}
        \boxdiagram{f}; 
        \drawBd{f};
        \drawInput[input dec = brace, 
                   input color = gray, 
                   input label = \text{height}, 
                   input label position = left]{f}{-1.1};
\end{tikzpicture}
\end{verbatim}
  \end{minipage}
  \hfill
  \begin{minipage}{.2\linewidth}\mbox{}\\
    \begin{displaymath}
      \begin{tikzpicture}
        \boxdiagram{f}; 
        \drawBd{f};
        \drawInput[input dec = brace, input color = gray, input label
        = \text{height}, input label position = left]{f}{-1.1};
      \end{tikzpicture}
      \quad \quad \quad \quad \quad \qquad
    \end{displaymath}
    \hfill
  \end{minipage}\\
\end{chunk}

\begin{chunk}
To draw a horizontal line in the diagram one can use
\texttt{drawHLine}. Horizontal lines can be used to imply that there are
many inputs. The position attributes of an hline are \texttt{hline
  left, hline right} and
  \texttt{hline vert}. The left and right attributes give the relative starting and ending
 position of the horizontal line: -1 is the left end of the box and 1 is the right end of
 the box (parameters outside of [-1,1] are allowed). The default values are -.6 and .6; \texttt{hline vert} is
 the relative vertical position above the diagram: 0 is the top of the
 box and
 1 is the top of the input line. The
 default value is .5. For example:\\
\mbox{}\\
    \begin{minipage}{0.65\textwidth}
\begin{verbatim}
\begin{tikzpicture}
 \boxdiagram{f}; 
 \drawBd{f};
 \drawHLine{f};
 \boxdiagram[coord = {(1.5,0)}]{g};
 \drawBd{g};
 \drawInput{g}{-.3};
 \drawHLine[hline left = 0, 
            hline right = .75, 
            hline vert = .25]{g};
\end{tikzpicture}
\end{verbatim}
  \end{minipage}
  \hfill
  \begin{minipage}{.25\linewidth}\mbox{}\\
    \begin{displaymath}
      \begin{tikzpicture}
        \draw[step=1cm,gray,very thin] (-1.5,0) grid (3.5,2);
 \boxdiagram{f}; 
 \drawBd{f};
 \drawHLine{f};
 \boxdiagram[coord = {(1.5,0)}]{g};
 \drawBd{g};
 \drawInput{g}{-.3};
  \drawHLine[hline left = 0, hline right = .75, hline vert = .35]{g};
      \end{tikzpicture}
      \quad \quad \quad \quad \quad \qquad
    \end{displaymath}
    \hfill
  \end{minipage}\\
  \mbox{}\\
  The color of an hline is \texttt{hline color}, with default gray, and there is \texttt{hline
    dash pattern} with default value empty. Labels can be assigned and
  positioned on hlines with \texttt{hline label, hline label
    position}, with default value empty and above,
  respectively. Finally, we can decorate hlines analogously to other lines
  using \texttt{hline dec, hline dec amp, hline dec seg length.} For
  example:\\
  \mbox{}\\
    \begin{minipage}{0.65\textwidth}
\begin{verbatim}
\begin{tikzpicture}
 \boxdiagram{f}; 
 \drawBd{f};
 \drawHLine{f};
 \drawHLine[hline left = -1, 
            hline right = 1, 
            hline vert = 1.05, 
            hline dec = brace, 
            hline label = n \text{ inputs}]{f};
\end{tikzpicture}
\end{verbatim}
  \end{minipage}
  \hfill
  \begin{minipage}{.25\linewidth}\mbox{}\\
    \begin{displaymath}
      \begin{tikzpicture}
 %       \draw[step=1cm,gray,very thin] (-1.5,0) grid (3.5,2);
 \boxdiagram{f}; 
 \drawBd{f};
 \drawHLine{f};
 \drawHLine[hline left = -1, hline right = 1, hline vert = 1.05, hline
 dec = brace, hline label = n \text{ inputs}]{f};
      \end{tikzpicture}
      \quad \quad \quad \quad \quad \qquad
    \end{displaymath}
    \hfill
  \end{minipage}\\
  \mbox{}\\
\end{chunk}


\begin{chunk}
    We can use pgfkeys to set commonly used sets of key-values. For
    instance, the brace above the diagram in the above example is
    often used, so we set
\begin{verbatim}
\pgfkeys{braceDec/.style = {hline left = -1, hline right = 1, 
   hline vert = 1.05, hline  dec = brace}}.
\end{verbatim}
We can then do the following:\\
  \mbox{}\\
    \begin{minipage}{0.65\textwidth}
\begin{verbatim}
\begin{tikzpicture}
 \boxdiagram{f}; 
 \drawBd{f};
 \drawHLine{f};
 \drawHLine[/braceDec, 
            hline label = \text{n inputs}]{f};
\end{tikzpicture}
\end{verbatim}
  \end{minipage}
  \hfill
  \begin{minipage}{.25\linewidth}\mbox{}\\
    \begin{displaymath}
      \begin{tikzpicture}
         \boxdiagram{f}; 
 \drawBd{f};
 \drawHLine{f};
 \drawHLine[/braceDec, hline label = \text{n inputs}]{f};
      \end{tikzpicture}
      \quad \quad \quad \quad \quad \qquad
    \end{displaymath}
    \hfill
  \end{minipage}\\
  \end{chunk}

  \begin{chunk}
Coordinates make it easier to work with several diagrams. The
coordinate functions are \texttt{coordTopInput, coordTopBox,
  coordBottomBox, coordBottomOutput}. They each take three inputs: the
first is a box diagram, the second is the name of the coordinate to be
returned, and the third is a relative horizontal position, with -1 the
left end of the box and 1 the right end. We stress that you do not
need to create a coordinate node, just pass a name. For example:\\
  \mbox{}\\
    \begin{minipage}{0.65\textwidth}
\begin{verbatim}
\begin{tikzpicture}
 \boxdiagram{f}; 
 \drawBd{f};
 \coordTopInput{f}{coor}{-.5};
 \boxdiagram[coord = (coor)]{g};
 \drawBd{g};
 \coordTopBox{f}{coor1}{2.5};
 \coordBottomBox{f}{coor2}{2.5};
 \boxdiagram[coord = ($(coor1)!.5!(coor2)$)]{h};
 \drawBd{h};
\end{tikzpicture}
\end{verbatim}
  \end{minipage}
  \hfill
  \begin{minipage}{.25\linewidth}\mbox{}\\
    \begin{displaymath}
      \begin{tikzpicture}
         \draw[step=1cm,gray,very thin] (-1.5,0) grid (2,3.5);
         \boxdiagram{f}; 
 \drawBd{f};
 \coordTopInput{f}{coor}{-.5};
 \boxdiagram[coord = (coor)]{g};
 \drawBd{g};
 \coordTopBox{f}{coor1}{2.5};
 \coordBottomBox{f}{coor2}{2.5};
 \boxdiagram[coord = ($(coor1)!.5!(coor2)$)]{h};
 \drawBd{h};
      \end{tikzpicture}
      \quad \quad \quad \quad \quad \qquad
    \end{displaymath}
    \hfill
  \end{minipage}\\
  \end{chunk}

\section{Bugs}
\begin{enumerate}
\item The following won't compile:
\begin{verbatim}
\boxdiagram[label = \mu]{mu}
\end{verbatim}
  but, e.g., the following does:
  \begin{verbatim}
\boxdiagram[label = \mu]{m}.
\end{verbatim}
The following does not,
    \begin{verbatim}
\boxdiagram[label = \alpha]{a},
\end{verbatim}
but the following does
    \begin{verbatim}
\boxdiagram[label = \alpha]{ab}.
\end{verbatim}
\end{enumerate}

\end{document}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End:
