% knitting.sty
%
% Provides commands useful for writing knitting patterns in LaTeX,
% including commands to typeset knit charts, and to switch to larger
% pages mid-document.
%
% author: Ariel Barton
%
% Copyright Ariel Barton, 2010
%
% 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 the license is in
%    http://www.latex-project.org/lppl.txt
% and version 1.3 or later is part of all distributions of
% LaTeX version 2003/06/01 or later.
%
% This work has the LPPL maintenance status "author-maintained".
%
% The complete list of files considered part of this work is in
% the file `knitting-doc.pdf' and its source code `knitting-doc.tex'.
%
% Version: 2

\ProvidesPackage{knitting}[2010/08/29]

%\pdfmapfile{+knitfont.map}

\newif \ifchartsonly \chartsonlyfalse
\newif \ifgrid
\newif \ifresetrn \resetrntrue
\newif \ifleftrn@knit
\newif \ifshowrn@knit \showrn@knittrue
\newif \ifpdf@knit
\newif \ifcountingout@knit
\pdf@knittrue
\ifx \pdfoutput \undefined \pdf@knitfalse \fi
\ifx \pdfoutput \relax     \pdf@knitfalse \fi

\RequirePackage{color}

\definecolor{purlgray}{gray}{0.65}
\definecolor{knitlinecolor}{rgb}{0.7,0,0}
\definecolor{gridcolor}{gray}{0.3}
\definecolor{rncolor}{rgb}{0.6,0,0}
\definecolor{rnarrowcolor}{rgb}{0.45,0,0}

\DeclareOption{chartsonly}{\chartsonlytrue}

\ProcessOptions

% Every dimension I could think of affecting the
% main page body. It's an environment instead of a command since I want
% a way to switch back to normal pages. Dimensions I don't change are
% \marginparsep,\marginparwidth,\marginparpush,\paperheight,\paperwidth

\newenvironment{fullpages}{
    \clearpage
    \pagestyle{plain}
    \setlength{\hoffset}{0pt}
    \setlength{\voffset}{0pt}
    \setlength{\oddsidemargin}{0pt}
    \setlength{\evensidemargin}{0pt}
    \setlength{\topmargin}{0pt}
    \setlength{\headheight}{0pt}
    \setlength{\headsep}{0pt}
    \setlength{\textheight}{\paperheight}
        \addtolength{\textheight}{-\footskip}
        \addtolength{\textheight}{-2in}
    \setlength{\textwidth}{\paperwidth}
        \addtolength{\textwidth}{-2in}
    % This bit is borrowed from Peter Wilson's chngpage.sty
    % package. I didn't want to just \usepackage{chngpage} because it
    % behaves like \addtolength and I wanted \setlength, and loading the
    % whole package for one eight-line snippet of code just seemed
    % needlessly complicated.
    \setlength{\@colht}{\textheight}\setlength{\@colroom}{\textheight}%
    \setlength{\vsize}{\textheight}\setlength{\columnwidth}{\textwidth}%
    \if@twocolumn%
        \advance\columnwidth-\columnsep \divide\columnwidth\tw@%
        \@firstcolumntrue%
    \fi%
    \setlength{\hsize}{\columnwidth}%
    \setlength{\linewidth}{\hsize}%
    }
    {\clearpage}

\newlength \leftgap@knit
\newlength \bgshift@knit
\newlength \chartwidth@knit
\newlength \stitchcountwidth@knit
\newlength \rnleftwd@knit
\newlength \rnrightwd@knit

\newbox\bgbox@knit
\newbox\fgbox@knit
\newbox\ggbox@knit

\newcounter{rownumber} 
\newcounter{tempcount@knit}
\newcounter{rownumberskip} \setcounter{rownumberskip}{1}
\newcounter{stitchcountin}
\newcounter{stitchcountinprev}
\newcounter{stitchcountout}

\newcommand \passnum@knit{2}
\newcommand \stitchwd{\fontdimen6\csname U/knit/\series@knit/n/\f@size\endcsname}
\newcommand \stitchdp{\fontdimen8\csname U/knit/\series@knit/n/\f@size\endcsname}
\newcommand \stitchht{\fontdimen9\csname U/knit/\series@knit/n/\f@size\endcsname}
\newcommand \gridwidth{\fontdimen10\csname U/knit/\series@knit/n/\f@size\endcsname}
\newcommand \knitlinewd{\fontdimen11\csname U/knit/\series@knit/n/\f@size\endcsname}
\newcommand \narrowincraise@knit{\fontdimen12\the\font}
\newcommand \fontvoffset@knit{\fontdimen13\the\font}
\newcommand \purlextend@knit{\fontdimen14\csname U/knit/\series@knit/n/\f@size\endcsname}
\newcommand \rownumberwd{\fontdimen6\csname U/knit/\series@knit/n/10\endcsname}
% The rest of them aren't \the\font because I want them to still work outside of a chart

\newcommand \ff@knit{\fontencoding{U}\fontfamily{knit}\fontseries{\series@knit}\fontshape{n}\selectfont}
\newcommand \gf@knit{\fontencoding{U}\fontfamily{knit}\fontseries{\series@knit}\fontshape{g}\selectfont}
\newcommand \pf@knit{\fontencoding{U}\fontfamily{knit}\fontseries{\series@knit}\fontshape{p}\selectfont}

\DeclareTextFontCommand {\knitsfsmall@knit}{\dimen0=\f@size pt\fontfamily{cmss}\fontseries{m}\fontshape{n}\fontsize{0.8\dimen0}{\f@baselineskip}\selectfont}
\DeclareTextFontCommand     {\cablesf@knit}{\dimen0=\f@size pt\fontfamily{cmss}\fontseries{m}\fontshape{n}\fontsize{0.8\dimen0}{\f@baselineskip}\selectfont}
\DeclareTextFontCommand{\cablesfsmall@knit}{\dimen0=\f@size pt\fontfamily{cmss}\fontseries{m}\fontshape{n}\fontsize{0.6\dimen0}{\f@baselineskip}\selectfont}

\newcommand \purlpass[2][]{\ifnum\passnum@knit = 0 #2\else #1\fi}
\newcommand \gridpass[2][]{\ifnum\passnum@knit = 1 #2\else #1\fi}
\newcommand \mainpass[2][]{\ifnum\passnum@knit = 2 #2\else #1\fi}
\newcommand \countpass[2][]{\ifnum\passnum@knit = 3 #2\else #1\fi}

% Some extra effort (the {\ff@knit}) is made to make sure that the fonts % actually exist.
% This is done so that the fonts are defined before they are used,
% which is necessary to make \gridwidth work
\newcommand \knitnogrid{\gridfalse\def\series@knit{n}{\ff@knit}}
\newcommand \knitgrid{\gridtrue \def\series@knit{g}{\ff@knit}}
\newcommand \knitwide{\gridtrue \def\series@knit{w}{\ff@knit}}

\knitgrid

\newcommand \textknit[1]{\mbox{\ff@knit
    \rlap{\pf@knit \color{purlgray}\def\passnum@knit{0}#1}%
    \ifgrid\rlap{\gf@knit \color{gridcolor}\def\passnum@knit{1}#1}\fi
    \def\passnum@knit{2}#1}}

\newcommand \do@endofpar@knit[1]{\def\par{#1\endgraf\let\par\endgraf}}

% Special symbols

\newcommand  \narrowdecrease[1]{\genbobble@knit{#1}{1}{-\narrowincraise@knit}\adjuststitchcount[#1]{0}\adjuststitchcount[-1]{0}}
\newcommand \pnarrowdecrease[1]{\genbobble@knit{#1}{2}{-\narrowincraise@knit}\adjuststitchcount[#1]{0}\adjuststitchcount[-1]{0}}
\newcommand  \narrowincrease[1]{\genbobble@knit{#1}{3}{\narrowincraise@knit}\adjuststitchcount[0]{#1}\adjuststitchcount[0]{-1}}
\newcommand \pnarrowincrease[1]{\genbobble@knit{#1}{4}{\narrowincraise@knit}\adjuststitchcount[0]{#1}\adjuststitchcount[0]{-1}}
\newcommand \bobble[1]{\genbobble@knit{#1}{0}{0pt}}

\newcommand \genbobble@knit[3]{\char#2 \ifnum \passnum@knit = 2
	\llap{\lower\stitchdp\vbox to\stitchht{\vss \vskip\fontvoffset@knit \hbox to \stitchwd{\hfil\knitsfsmall@knit{#1}\hfil}\vskip #3\vss}}\fi}


\newcommand \wideincrease[1]{\strut@knit
    \ifnum\passnum@knit = 3 \narrowincrease{#1}\else
    \hbox to #1\stitchwd{\char25
    	\hskip-0.1pt\leaders\hbox{\char22}\hfil\hskip-0.1pt
    	\char29
    	\hskip-0.1pt\leaders\hbox{\char22}\hfil\hskip-0.1pt
    	\char26}\fi}
\newcommand \widedecrease[1]{\strut@knit
    \ifnum #1 = 5 \char31 \else
    \ifnum\passnum@knit = 3 \narrowdecrease{#1}\else
    \hbox to #1\stitchwd{\char27 
    	\hskip-0.1pt\leaders\hbox{\char22}\hfil\hskip-0.1pt
    	\char30
    	\hskip-0.1pt\leaders\hbox{\char22}\hfil\hskip-0.1pt
    	\char28}\fi\fi}

% Standard chart commands

% \obeylines is normally defined with \let^^M\par, not \def^^M{\par};
% doing it this way makes it cooperate with \do@endofpar.

{\catcode`\^^M = \active \catcode`\| = \active
\global\def\commands@knit{%
	\setlength{\fboxsep}{0pt}%
    \let\[\pnarrowincrease
    \let\]\pnarrowdecrease
    \let\<\narrowincrease
    \let\>\narrowdecrease
    \let\@\bobble
    \let \! \barthin@knit
    \let \| \bar@knit
    \let |  \bar@knit
    \let \_ \horizline@knit
    \let \= \horizlinewide@knit
    \let \- \horizlinenarrow@knit
    \let\overline\overline@knit
    \let\underline\underline@knit
    \let\rn\rn@knit
    \let\rnbox\rnbox@knit
    \let\rnboxleft\rnboxleft@knit
    \let\rnboxright\rnboxright@knit
    \let\rnleft\rnleft@knit
    \let\rnright\rnright@knit
    \let\nonumber\relax
    \let\par\endgraf %Just in case someone's redefined it
    \leftgap@knit=0pt
    \def~{\ifnum\passnum@knit=3 \else \ifvmode \advance \leftgap@knit by \stitchwd
        \else \kern \stitchwd \fi \fi}%
    \def^^M{\par}%
    \def\\{\par}%
    }%
}

\newcommand \strut@knit{\rule[-\stitchdp]{0pt}{\stitchht}}

% Drawing lines on the chart

\newcommand \horizline@knit{\ifnum\passnum@knit<3 \ifvmode\nonumber\leavevmode\fi \dimen0 =   \stitchwd \advance \dimen0 \knitlinewd
    \ifnum\passnum@knit = 2
    \hskip -0.5\knitlinewd\smash{{\color{knitlinecolor}\vrule width \dimen0 height 0.5\knitlinewd depth 0.5\knitlinewd}}\hskip -0.5\knitlinewd
    \else\hskip \stitchwd \fi\fi}
\newcommand \horizlinenarrow@knit[1]{\ifnum\passnum@knit<3 \ifvmode\nonumber\leavevmode\fi \dimen0 = #1\stitchwd \advance \dimen0 \gridwidth
    \ifnum\passnum@knit = 2
    \hskip -0.5\gridwidth \smash{{\color{knitlinecolor}\vrule width \dimen0 height 0.5\knitlinewd depth 0.5\knitlinewd}}\hskip -0.5\gridwidth
    \else\hskip #1\stitchwd \fi\fi}
\newcommand \horizlinewide@knit[1]{\ifnum\passnum@knit<3 \ifvmode\nonumber\leavevmode\fi \dimen0 = #1\stitchwd \advance \dimen0 \knitlinewd
    \ifnum\passnum@knit = 2
                         \smash{{\color{knitlinecolor}\vrule width \dimen0 height 0.5\knitlinewd depth 0.5\knitlinewd}}
    \else\hskip \dimen0 \fi\fi}

\newcommand \bar@knit{\ifnum\passnum@knit < 3 \leavevmode
    \ifgrid
        \ifnum \passnum@knit = 0
        \hbox{\color{knitlinecolor}\rule[-\stitchdp]{\knitlinewd}{\stitchht}}%
        \else
        \kern \knitlinewd
        \fi
    \else
        \ifnum \passnum@knit = 2
        \hbox{\color{knitlinecolor}\rule[-\stitchdp]{\knitlinewd}{\stitchht}}%
        \else
        \kern \knitlinewd
        \fi
    \fi\fi}

\newcommand \barthintop@knit{0pt}
\newcommand \barthinbot@knit{0pt}

\newcommand \barthin@knit{\leavevmode\strut@knit
    \ifnum \passnum@knit = 2
    \dimen2 = \stitchht \advance \dimen2 \barthintop@knit \advance \dimen2 \barthinbot@knit
    \dimen3 = \stitchdp \advance \dimen3 \barthinbot@knit
    \smash{\hbox to 0pt{\hss \color{knitlinecolor}\rule[-\dimen3]{\knitlinewd}{\dimen2}\hss}}%
    \fi}

\newcommand \overline@knit{\@ifstar \overlinestar@knit \overlinenostar@knit}
\newcommand \underline@knit{\@ifstar \underlinestar@knit \underlinenostar@knit}

\newcommand \overlinenostar@knit[1]{\leavevmode{\def\barthintop@knit{\knitlinewd}%
    \setbox0 = \hbox{#1}%
    \ifgrid
    \ifnum \passnum@knit = 0
        \dimen1=\wd0 \advance\dimen1 by \gridwidth
        {\rlap{\hskip -0.5\gridwidth\color{knitlinecolor}\rule[\ht0]{\dimen1}{\knitlinewd}}}
    \else
        \rule[\ht0]{0pt}{\knitlinewd}
    \fi
    \else
    \ifnum \passnum@knit = 2
        \dimen1=\wd0 \advance\dimen1 by \gridwidth
        {\rlap{\hskip -0.5\gridwidth\color{knitlinecolor}\rule[\ht0]{\dimen1}{\knitlinewd}}}%
    \else
        \rule[\ht0]{0pt}{\knitlinewd}
    \fi \fi
    #1}}
    
\newcommand \overlinestar@knit[1]{\leavevmode{\def\barthintop@knit{0.5\knitlinewd}%
    \setbox0 = \hbox{#1}%
    \ifnum \passnum@knit = 2
        \dimen1=\wd0 \advance\dimen1 by \gridwidth
        \dimen2=\ht0 \advance\dimen2 by -0.5\knitlinewd
        \smash{\rlap{\hskip -0.5\gridwidth\color{knitlinecolor}\rule[\dimen2]{\dimen1}{\knitlinewd}}}%
    \fi
    #1}}

\newcommand \underlinenostar@knit[1]{\leavevmode{\def\barthinbot@knit{\knitlinewd}%
    \setbox0 = \hbox{#1}%
    \ifgrid
    \ifnum \passnum@knit = 0
		\dimen1=\wd0 \advance\dimen1 by \gridwidth
    	\rlap{\raisebox{-\dp0}{\hskip -0.5\gridwidth\color{knitlinecolor}\rule[-\knitlinewd]{\dimen1}{\knitlinewd}\hskip -0.5\gridwidth}}%
    \else
    	\rlap{\raisebox{-\dp0}{\vrule width 0pt height 0pt depth \knitlinewd}}%
    \fi
    \else
    \ifnum \passnum@knit = 2
		\dimen1=\wd0 \advance\dimen1 by \gridwidth
	    \rlap{\raisebox{-\dp0}{\hskip -0.5\gridwidth\color{knitlinecolor}\rule[-\knitlinewd]{\dimen1}{\knitlinewd}\hskip -0.5\gridwidth}}%
    \else
	    \rlap{\raisebox{-\dp0}{\vrule width 0pt height 0pt depth \knitlinewd}}%
    \fi \fi
    #1}}
    
\newcommand \underlinestar@knit[1]{\leavevmode{\def\barthinbot@knit{0.5\knitlinewd}%
    \setbox0 = \hbox{#1}%
    \ifnum \passnum@knit = 2
		\dimen1=\wd0 \advance\dimen1 by \gridwidth
	    \smash{\rlap{\raisebox{-\dp0}{\hskip -0.5\gridwidth\color{knitlinecolor}\rule[-0.5\knitlinewd]{\dimen1}{\knitlinewd}}\hskip -0.5\gridwidth}}%
    \fi
    #1}}

% Fancy cabling

\newcommand \overcableleft@knit[1]{%
    \setbox0=\hbox{#1}%
    \rlap{#1}%
    \hbox to \wd0{\leaders\hbox to \stitchwd{\hfil\char5}\hfil\hskip\stitchwd\char10}}
\newcommand \undercableleft@knit[1]{%
    \setbox0=\hbox{#1}%
    \rlap{#1}%
    \hbox to \wd0{\leaders\hbox to \stitchwd{\hfil\char6}\hfil\hskip\stitchwd\char9}}
\newcommand \undercableright@knit[1]{%
    \setbox0=\hbox{#1}%
    \rlap{#1}%
    \hbox to \wd0{\char13\char12\hskip\stitchwd\leaders\hbox to \stitchwd{\char8\hfil}\hfil}}
\newcommand \overcableright@knit[1]{%
    \setbox0=\hbox{#1}%
    \rlap{#1}%
    \hbox to \wd0{\char14\char11\hskip\stitchwd\leaders\hbox to \stitchwd{\char7\hfil}\hfil}}

\newcommand \cableleft[2]{\leavevmode{\knitnogrid
    \ifcase\passnum@knit
    \hbox{\pf@knit #1#2}
    \or
    \setbox0=\hbox{\pf@knit #1#2}
    \rule{\wd0}{0pt} \vrule width 0pt height \ht0 depth \dp0
    \or
    \hbox{\let \textsf \cablesf@knit \let \knitsfsmall@knit \cablesfsmall@knit {\ff@knit\fontshape{l}\selectfont \overcableleft@knit{#1}}{\ff@knit\fontshape{r}\selectfont \undercableright@knit{#2}}}
    \else
    #1#2\fi}}
\newcommand \cableright[2]{\leavevmode{\knitnogrid
    \ifcase\passnum@knit
    \hbox{\pf@knit #1#2}
    \or
    \setbox0=\hbox{\pf@knit #1#2} \rule{\wd0}{0pt} \vrule width 0pt height \ht0 depth \dp0
    \or
    \hbox{\let \textsf \cablesf@knit \let \knitsfsmall@knit \cablesfsmall@knit {\ff@knit\fontshape{r}\selectfont \undercableleft@knit{#1}}{\ff@knit\fontshape{l}\selectfont \overcableright@knit{#2}}}
    \else
    #1#2\fi}}

% Knit, purl, knitboxes

\newcommand \knit[1]{\strut@knit\hbox to #1\stitchwd{\leaders\hbox{-}\hfil}}
\newcommand \purl[1]{\strut@knit\hbox to #1\stitchwd{\leaders\hbox{=}\hfil}}

\newcommand \knitboxbackground{}
\newcommand \purlboxbackground{\color{purlgray}}
\newcommand \purlboxforeground{}
\newcommand \knitboxforeground{}

\newcommand \Knit[3][0]{\strut@knit%
    \setbox0 = \hbox{\fontseries{m}\fontshape{n}\textsf{#2}}%
    \ifcase \passnum@knit
        \ifx \empty@knit \knitboxbackground
        \rule{#3\stitchwd}{0pt}%
        \else
        {\knitboxbackground \purlbackground{\rule[-\stitchdp]{#3\stitchwd}{\stitchht}}}\fi
    \or
    \rlap{\hbox to #3\stitchwd{\leaders\hbox{\char5}\hfil}}%
    \hbox to #3\stitchwd{\leaders\hbox to \stitchwd{\char6\hfil\char6}\hskip #1\stitchwd plus 1fil \hskip\wd0\leaders\hbox to \stitchwd{\char6\hfil\char6}\hfil}%
    \or
    \hbox to #3\stitchwd{%
    	{\knitboxforeground\leaders\hbox{-}\hskip #1\stitchwd plus 1fil }%
    	\lower\stitchdp\vbox to\stitchht{\vss\vskip\fontvoffset@knit\hbox{\fontseries{m}\fontshape{n}\textsf{#2}}\vss}
    	{\knitboxforeground\leaders\hbox{-}\hfil}}%
    \or
    \hbox to #3\stitchwd{\hfil}
    \fi}
\newcommand \Purl[3][0]{\strut@knit%
    \setbox0 = \hbox{\fontseries{m}\fontshape{n}\textsf{#2}}%
    \ifcase \passnum@knit
        \ifx \empty@knit \purlboxbackground
        \rule{#3\stitchwd}{0pt}%
        \else
        {\purlboxbackground \purlbackground{\rule[-\stitchdp]{#3\stitchwd}{\stitchht}}}\fi
    \or
    \rlap{\hbox to #3\stitchwd{\leaders\hbox{\char5}\hfil}}%
    \hbox to #3\stitchwd{\leaders\hbox to \stitchwd{\char6\hfil\char6}\hskip #1\stitchwd plus 1fil \hskip\wd0\leaders\hbox to \stitchwd{\char6\hfil\char6}\hfil}%
    \or
    \hbox to #3\stitchwd{%
    	{\purlboxforeground\leaders\hbox{=}\hskip #1\stitchwd plus 1fil }%
    	\lower\stitchdp\vbox to\stitchht{\vss\vskip\fontvoffset@knit\hbox{\fontseries{m}\fontshape{n}\textsf{#2}}\vss}
    	{\purlboxforeground\leaders\hbox{=}\hfil}}%
    \or
    \hbox to #3\stitchwd{\hfil}
    \fi}

\newcommand \knitbox[3][0]{\strut@knit%
    \ifcase \passnum@knit
        \ifx \empty@knit \knitboxbackground
        \rule{#3\stitchwd}{0pt}%
        \else
        {\knitboxbackground \purlbackground{\rule[-\stitchdp]{#3\stitchwd}{\stitchht}}}\fi
    \or
    \hbox to #3\stitchwd{\char6\leaders\hbox{\char5}\hfil\char6}%
    \or
    \hbox to #3\stitchwd{\hskip #1\stitchwd plus 1fil \lower\stitchdp\vbox to\stitchht{\vss\vskip\fontvoffset@knit\hbox{\fontseries{m}\fontshape{n}\textsf{#2}}\vss}\hfil}%
    \or
    \hbox to #3\stitchwd{\hfil}
    \fi}
\newcommand \purlbox[3][0]{\strut@knit%
    \ifcase \passnum@knit
        \ifx \empty@knit \purlboxbackground
        \rule{#3\stitchwd}{0pt}%
        \else
        {\purlboxbackground \purlbackground{\rule[-\stitchdp]{#3\stitchwd}{\stitchht}}}\fi
    \or
    \hbox to #3\stitchwd{\char6\leaders\hbox{\char5}\hfil\char6}%
    \or
    \hbox to #3\stitchwd{\hskip #1\stitchwd plus 1fil \lower\stitchdp\vbox to\stitchht{\vss\vskip\fontvoffset@knit\hbox{\fontseries{m}\fontshape{n}\textsf{#2}}\vss}\hfil}%
    \or
    \hbox to #3\stitchwd{\hfil}%
    \fi}

\newcommand \purlbackground[1]{\leavevmode\setbox0=\hbox{#1}%
    \dimen0 = \wd0 \advance\dimen0 2\purlextend@knit
    \dimen1 = \stitchht \advance\dimen1 \purlextend@knit
    \dimen2 = \stitchdp \advance\dimen2 \purlextend@knit
    \ifnum \passnum@knit = 0  \kern-\purlextend@knit
        \vrule width 0pt height \ht0 depth \dp0
        \smash{\rule[-\dimen2]{\dimen0}{\dimen1}}%
        \kern-\purlextend@knit
        \else\box0\fi}

% Row number commands

\newcommand \numberrow[3]{\ifnum\passnum@knit=3 \ifvmode\vskip\stitchht\fi\else
	\ifvmode\nonumber\leavevmode\fi
    \strut@knit
    \count255=#1
    \hbox to \stitchwd{\hss\ifnum \passnum@knit = 2 \color{rncolor}\textnormal{#1}\fi\hss}%
    \ifnum #1 > #3
        \advance\count255 -1
        \loop \ifnum \count255>#3
        \c@tempcount@knit = \count255
        \divide\c@tempcount@knit #2
        \multiply \c@tempcount@knit #2
        \ifnum\c@tempcount@knit = \count255
        \hbox to \stitchwd{\hss\ifnum \passnum@knit = 2 \color{rncolor}\textnormal{\the\count255}\fi \hss}%
        \else
        \kern\stitchwd
        \fi
        \advance\count255 -1
        \repeat
    \else
        \advance\count255 1
        \loop \ifnum \count255<#3
        \c@tempcount@knit = \count255
        \divide\c@tempcount@knit #2
        \multiply \c@tempcount@knit #2
        \ifnum\c@tempcount@knit = \count255
        \hbox to \stitchwd{\hss\ifnum \passnum@knit = 2 \color{rncolor}\textnormal{\the\count255}\fi \hss}%
        \else
        \kern\stitchwd
        \fi
        \advance\count255 1
        \repeat
    \fi
    \hbox to \stitchwd{\hss\ifnum \passnum@knit = 2 \color{rncolor}\textnormal{#3}\fi \hss}%
    \fi}

\newcommand \rnoddonly{\def\rncore@knit##1{\ifshowrn@knit \ifodd\value{rownumber}\csname print##1rownumber\endcsname{\therownumber}\fi\fi}}
\newcommand \rnevenonly{\def\rncore@knit##1{\ifshowrn@knit \ifodd\value{rownumber}\else\csname print##1rownumber\endcsname{\therownumber}\fi\fi}}
\newcommand \rnnormal{\def\rncore@knit##1{\ifshowrn@knit \csname print##1rownumber\endcsname{\therownumber}\fi}}

\newcommand \rncore@knit[1]{\ifshowrn@knit \csname print#1rownumber\endcsname{\therownumber}\fi}
\newcommand \rnstep@knit{\ifshowrn@knit
                 \ifnum \passnum@knit = 2 \addtocounter{rownumber}{-\value{rownumberskip}}\fi
                 \ifnum \passnum@knit = 0 \addtocounter{rownumber}{-\value{rownumberskip}}\fi
            \else\global\showrn@knittrue\fi}

\newcommand \printrownumber[1]{{\color{rncolor}\textnormal{#1}}}
\newcommand \printrightrownumber[1]{\knitleftarrowhead{\color{rncolor}\textnormal{#1}}}
\newcommand \printleftrownumber[1]{{\color{rncolor}\textnormal{#1}}\knitrightarrowhead}
\newcommand \knitrightarrowhead{{\color{rnarrowcolor}\char125}}
\newcommand \knitleftarrowhead{{\color{rnarrowcolor}\char123}}

%\newcommand \therownumber{\arabic{rownumber}}
% \newcount automatically generates a \therownumber command

\newcommand \rn@knit{\ifnum \passnum@knit < 3 \leavevmode
    \hbox to \rownumberwd{\hss\ifnum \passnum@knit = 2 \rncore@knit{}\fi\rnstep@knit\hss}\fi}
\newcommand \rnleft@knit{\ifnum \passnum@knit < 3 \leavevmode
    \setbox0 = \hbox{\ifnum \passnum@knit = 2 \rncore@knit{left}\fi\rnstep@knit}
    \dimen0 = \wd0 %\advance \dimen0 -\rownumberwd
    \ifchartsonly\advance \dimen0 1pt\fi
    \ifdim \dimen0 > \rnleftwd@knit \global\rnleftwd@knit = \dimen0 \fi
    \hbox to 0pt{\hss\box0}\fi}
\newcommand \rnright@knit{\ifnum \passnum@knit < 3 \leavevmode
    \setbox0 = \hbox{\ifnum \passnum@knit = 2 \rncore@knit{right}\fi\rnstep@knit}
    \dimen0 = \wd0 %\advance \dimen0 -\rownumberwd
	\ifchartsonly\advance \dimen0 1pt\fi
    \ifdim \dimen0 > \rnrightwd@knit \global\rnrightwd@knit = \dimen0 \fi
    \hbox to 0pt{\box0\hss}\fi}

\newcommand \rnbox@knit[1]{\ifnum \passnum@knit < 3 \leavevmode
    \hbox to \rownumberwd{\hss\ifnum \passnum@knit = 2 {\printrownumber{#1}}\fi\hss}\fi}
\newcommand \rnboxleft@knit[1]{\ifnum \passnum@knit < 3 \leavevmode
    \setbox0 = \hbox{\ifnum \passnum@knit = 2 {\printleftrownumber{#1}}\fi}
    \dimen0 = \wd0 %\advance \dimen0 -\rownumberwd
    \ifchartsonly\advance \dimen0 1pt\fi
    \ifdim \dimen0 > \rnleftwd@knit \global\rnleftwd@knit = \dimen0 \fi
    \hbox to 0pt{\hss\box0}\fi}
\newcommand \rnboxright@knit[1]{\ifnum \passnum@knit < 3 \leavevmode
    \setbox0 = \hbox{\ifnum \passnum@knit = 2 {\printrightrownumber{#1}}\fi}
    \dimen0 = \wd0 %\advance \dimen0 -\rownumberwd
    \ifchartsonly \advance \dimen0 1pt \fi
    \ifdim \dimen0 > \rnrightwd@knit \global\rnrightwd@knit = \dimen0 \fi
    \hbox to 0pt{\box0\hss}\fi}

% The chart commands

\newcommand \chart[1][]{\smallpage@knit\obeylines \catcode`\|=\active \chart@knit{#1}}

% Some special stuff for chartsonly mode
\let\extracommands@knit\relax
\newcommand \smallpage@knit{\noindent\hbox\bgroup}
\let\endsmallpage@knit\egroup

% The chart command proper
\newcommand \chart@knit[2]{%
    \global \chartwidth@knit = 0pt
    \ifresetrn \setcounter{rownumber}{0}\else \setcounter{tempcount@knit}{\value{rownumber}}\fi
    \setbox\bgbox@knit=\vbox{\def\passnum@knit{0}\hsize=\maxdimen
        \ff@knit % This is kind of silly, but to make \stitchht work, we need to be sure that the foreground font exists.
        \pf@knit
        \lineskip=0pt
        \parskip=0pt
        \baselineskip=0pt
        \parindent=0pt
        \emergencystretch = \stitchwd
        \leftskip=0pt
        \rightskip=0pt
        \parfillskip=0pt plus 1fil
        \ifresetrn\else\let\rnstep@knit\relax\fi
        \commands@knit\extracommands@knit
        \def\nonumber{\global\showrn@knitfalse}%
        \csname auto#1@knit\endcsname #2\par}%
    \ifresetrn \setcounter{tempcount@knit}{-\value{rownumber}}\fi
    \ifgrid
    \setbox\ggbox@knit=\vbox{\def\passnum@knit{1}\hsize=\maxdimen
        \gf@knit
        \lineskip=0pt
        \parskip=0pt
        \baselineskip=0pt
        \parindent=0pt
        \emergencystretch = \stitchwd
        \leftskip=0pt
        \rightskip=0pt
        \parfillskip=0pt plus 1fil
        \commands@knit\extracommands@knit
        \def\nonumber{\global\showrn@knitfalse}%
        \csname auto#1@knit\endcsname #2\par}%
    \fi
    \setcounter{rownumber}{\value{tempcount@knit}}%
    \global \rnleftwd@knit = 0pt
    \global \rnrightwd@knit = 0pt
    \setbox\fgbox@knit=\vbox{\def\passnum@knit{2}\hsize=\maxdimen
        \ff@knit
        \lineskip=0pt
        \parskip=0pt
        \baselineskip=0pt
        \parindent=0pt
        \emergencystretch = \stitchwd
        \leftskip=0pt
        \rightskip=0pt
        \parfillskip=0pt plus 1fil
        \commands@knit\extracommands@knit
        \def\nonumber{\global\showrn@knitfalse}%
        \csname auto#1@knit\endcsname #2\par}%
    \global\advance \chartwidth@knit \rnleftwd@knit
    \global\advance \chartwidth@knit \rnrightwd@knit
    \hbox to \chartwidth@knit{\hskip \rnleftwd@knit
    \rlap{\color{purlgray}\box\bgbox@knit}%
    \ifgrid\rlap{\color{gridcolor}\box\ggbox@knit}\fi
    \ifchartsonly
    \dimen2 = \dp \fgbox@knit \dimen3 = \ht \fgbox@knit
    \advance\dimen2 0.5\gridwidth \advance\dimen3 0.5\gridwidth
    \vrule width 0pt height \dimen3 depth \dimen2
    \fi
    % If we are doing charts only, we want to enlarge things enough that
    % we can see the grid on all sides.
    % But if we aren't, we want adjacent charts to merge seamlessly
    % because using separate charts is the only way to allow charts to
    % break across pages.
    \box\fgbox@knit%
    \hss}%
    \endsmallpage@knit
    }

% Special charts only macros

\ifchartsonly
    \ifpdf@knit\else\errmessage{\chartsonly should only be used with pdfTeX.}\fi%
    \hoffset=-1in
    \voffset=-1in
        \oddsidemargin=0pt
        \evensidemargin=0pt
        \topmargin=0pt
        \headheight=0pt
        \headsep=0pt
        \footskip=0pt
        \textheight=120in
    \newenvironment{smallpage}{\clearpage
    	\hsize=\textwidth \columnwidth = \textwidth
        \global\chartwidth@knit=0pt
        \setbox0 = \vbox\bgroup
    	    \def\smallpage@knit{\let\endsmallpage@knit\egroup \noindent \hbox\bgroup}%
        }
    {\egroup%
        %
        \pdfpagewidth=\wd0
        %
        \dimen0=\ht0 \advance \dimen0 by \dp0
        \pdfpageheight=\dimen0
        %
        \ifdim\pdfpageheight>\textheight
        \typeout{}
        \typeout{You need to increase \string\textheight\space in the preamble.}
        \typeout{What do you want such a big chart for, anyway?}
        \typeout{}
        \fi
        %
        \box0
        \clearpage
        }
    \let\smallpage@knit\smallpage
    \let\endsmallpage@knit\endsmallpage
    \def\extracommands@knit{%
        \leftskip = 0.5\gridwidth
        \rightskip = 0.5\gridwidth
        }
\else
    \let\smallpage\begingroup
    \let\endsmallpage\endgroup
\fi

% Autonumbering macros

\newcommand \everypar@knit{\hskip\leftgap@knit \leftgap@knit=0pt \relax}

\newcommand         \auto@knit{\let\nonumber\relax \everypar={\everypar@knit\do@endofpar@knit{\adjustchartwidth@knit}}}
\newcommand     \autoleft@knit{\everypar={\everypar@knit\rnleft@knit\do@endofpar@knit{\adjustchartwidth@knit}}}
\newcommand    \autoright@knit{\everypar={\everypar@knit\do@endofpar@knit{\rnright@knit\adjustchartwidth@knit}}}
\newcommand  \autooddleft@knit{\everypar={\everypar@knit
    \ifodd \value{rownumber}\relax
    	\rnleft@knit\do@endofpar@knit{\adjustchartwidth@knit}%
    \else %\hskip\rownumberwd 
    	\do@endofpar@knit{\rnright@knit\adjustchartwidth@knit}\fi}}
\newcommand \autooddright@knit{\everypar={\everypar@knit
    \ifodd \value{rownumber}\relax %\hskip\rownumberwd
    	\do@endofpar@knit{\rnright@knit\adjustchartwidth@knit}%
    \else\rnleft@knit\do@endofpar@knit{\adjustchartwidth@knit}\fi}}
\newcommand     \autoboth@knit{\everypar={\everypar@knit\rnleft@knit\global\advance\rownumber 1 \do@endofpar@knit{\rnright@knit\adjustchartwidth@knit}}}
\let\autoevenleft@knit\autooddright@knit
\let\autoevenright@knit\autooddleft@knit

\newcommand \adjustchartwidth@knit{\endgraf
    \ifnum \passnum@knit = 2 \setbox0=\lastbox
    \setbox1=\hbox{\unhcopy0\unskip}%
    \box0
    \ifdim\wd1 >\chartwidth@knit \global\chartwidth@knit=\wd1\fi\fi}

% Stitch-counting macros

\newcommand \adjuststitchcount[2][\temp@knit]{\def\temp@knit{#2}%
	\leavevmode\ifnum\passnum@knit=3 \null
    \ifcountingout@knit \kern #2\stitchwd \else \kern #1\stitchwd \fi \null\fi}

\newcommand \stitchcountwarningbar{\ifnum \c@stitchcountinprev = \c@stitchcountout \else \vrule width \overfullrule \fi}

\newcommand \countstitches[1]{%
    \global\c@stitchcountinprev = \c@stitchcountin
    \setbox0 = \hbox{\def\passnum@knit{3}\countingout@knittrue \fontshape{out}\selectfont #1}%
    \c@stitchcountout = \wd0
    \dimen0 = 0.5\stitchwd \advance \c@stitchcountout \dimen0
    \global\divide \c@stitchcountout \stitchwd
    \setbox1 = \hbox{\def\passnum@knit{3}\countingout@knitfalse \fontshape{in}\selectfont #1}%
    \c@stitchcountin = \wd1
    \dimen1 = 0.5\stitchwd \advance \c@stitchcountin \dimen1
    \global\divide \c@stitchcountin \stitchwd
    \ifnum\c@stitchcountinprev < -99
        \global\c@stitchcountinprev = \c@stitchcountout
    \fi
    }

\newcommand \stitchcountchart[1][]{\begingroup \catcode`\|=\active \def\chartrn@knit{#1}\obeylines \afterassignment \printstitchcountchart@knit \toks0 =}

\newcommand \printstitchcountchart@knit{\smallpage@knit\hbox{%
    \ifx\relax\printleftstitchcount\else\ifx \empty@knit \printleftstitchcount\else
        \let\printstitchcount@knit\printleftstitchcount \def\stitchcountside@knit{0}\makestitchcounts@knit \fi\fi
    \chart[\chartrn@knit]{\the\toks0}%
    \ifx\relax\printrightstitchcount\else\ifx \empty@knit \printrightstitchcount\else
        \let\printstitchcount@knit\printrightstitchcount
        \def\stitchcountside@knit{1}\makestitchcounts@knit\fi\fi
    }\endsmallpage@knit
    \endgroup}

{\obeylines
\gdef\countstitcheseachrow@knit#1^^M{%
    \countstitches{#1}%
    \setbox0=\hbox{\def\passnum@knit{2}\strut@knit \printstitchcount@knit\stitchcountwarningbar}%
    \setbox1=\hbox{#1}%
    \ifdim \wd0 > \stitchcountwidth@knit \global\stitchcountwidth@knit = \wd0 \fi
    \hbox to 0pt{\ifnum\stitchcountside@knit = 0 \hss\fi
    	\vrule width 0pt height \ht1 depth \dp1 \smash{\box0}%
    	\ifnum\stitchcountside@knit = 1 \hss\fi}%
    \par}}

\def\makestitchcounts@knit{\hbox{\setbox1=\vbox{\c@stitchcountin = -1001 \global\stitchcountwidth@knit=0pt
    \parindent=0pt
    \def\passnum@knit{3}
    \ff@knit
    \commands@knit
    \everypar={\countstitcheseachrow@knit} \offinterlineskip
    \the\toks0
	}%
	\ifnum\stitchcountside@knit = 0
	\hskip \stitchcountwidth@knit\rlap{\box1}%
	\else
	\rlap{\box1}\hskip \stitchcountwidth@knit
	\fi
}}

\newcommand \empty@knit{} 
% This is needed because the plain TeX \empty is
% defined with \def and not \newcommand

\newcommand \printleftstitchcount{{\color{rncolor}\textnormal{(\thestitchcountout\ sts) }}}
\newcommand \printrightstitchcount{}