summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/braids
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2011-08-26 22:08:04 +0000
committerKarl Berry <karl@freefriends.org>2011-08-26 22:08:04 +0000
commit19102fcd457ba2a564f2e357a331ee95063a565e (patch)
treec2c142fbe2461f7bdd0476c5cc7f04dedbaac668 /Master/texmf-dist/source/latex/braids
parent94d8eec871be0ca8f1b658e064b3786333b288ef (diff)
new pgf package braids 1.0 (26aug11)
git-svn-id: svn://tug.org/texlive/trunk@23696 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/braids')
-rw-r--r--Master/texmf-dist/source/latex/braids/braids.dtx946
1 files changed, 946 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/braids/braids.dtx b/Master/texmf-dist/source/latex/braids/braids.dtx
new file mode 100644
index 00000000000..463da2c37cc
--- /dev/null
+++ b/Master/texmf-dist/source/latex/braids/braids.dtx
@@ -0,0 +1,946 @@
+% \iffalse meta-comment
+%<*internal>
+\iffalse
+%</internal>
+%<*readme>
+----------------------------------------------------------------
+braids --- a style file for drawing braid diagrams with TikZ/PGF
+E-mail: stacey@math.ntnu.no
+Released under the LaTeX Project Public License v1.3c or later
+See http://www.latex-project.org/lppl.txt
+----------------------------------------------------------------
+
+This package defines some commands for drawing braid diagrams with TikZ/PGF.
+It was designed and tested with PGF2.10.
+The initial idea of this package came from a question and answer on the site http://tex.stackexchange.com.
+%</readme>
+%<*internal>
+\fi
+\def\nameofplainTeX{plain}
+\ifx\fmtname\nameofplainTeX\else
+ \expandafter\begingroup
+\fi
+%</internal>
+%<*install>
+\input docstrip.tex
+\keepsilent
+\askforoverwritefalse
+\preamble
+----------------------------------------------------------------
+braids --- a style file for drawing braid diagrams with TikZ/PGF
+E-mail: stacey@math.ntnu.no
+Released under the LaTeX Project Public License v1.3c or later
+See http://www.latex-project.org/lppl.txt
+----------------------------------------------------------------
+
+\endpreamble
+\postamble
+
+Copyright (C) 2011 by Andrew Stacey <stacey@math.ntnu.no>
+
+This work may be distributed and/or modified under the
+conditions of the LaTeX Project Public License (LPPL), either
+version 1.3c of this license or (at your option) any later
+version. The latest version of this license is in the file:
+
+http://www.latex-project.org/lppl.txt
+
+This work is "maintained" (as per LPPL maintenance status) by
+Andrew Stacey.
+
+This work consists of the files braids.dtx
+ braids_doc.tex
+and the derived files README.txt,
+ braids.ins,
+ braids.pdf,
+ braids.sty,
+ braids_doc.pdf.
+
+\endpostamble
+\usedir{tex/latex/braids}
+\generate{
+ \file{\jobname.sty}{\from{\jobname.dtx}{package}}
+}
+%</install>
+%<install>\endbatchfile
+%<*internal>
+\usedir{source/latex/braids}
+\generate{
+ \file{\jobname.ins}{\from{\jobname.dtx}{install}}
+}
+\nopreamble\nopostamble
+\usedir{doc/latex/demopkg}
+\generate{
+ \file{README.txt}{\from{\jobname.dtx}{readme}}
+}
+\ifx\fmtname\nameofplainTeX
+ \expandafter\endbatchfile
+\else
+ \expandafter\endgroup
+\fi
+%</internal>
+%<*package>
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{braids}[2011/05/07 v1.0 Tikz/PGF commands for drawing braid diagrams]
+%</package>
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage[T1]{fontenc}
+\usepackage{lmodern}
+%\usepackage{morefloats}
+\usepackage{tikz}
+\usepackage{\jobname}
+\usepackage[numbered]{hypdoc}
+\definecolor{lstbgcolor}{rgb}{0.9,0.9,0.9}
+
+\usepackage{listings}
+\lstloadlanguages{[LaTeX]TeX}
+\lstset{breakatwhitespace=true,breaklines=true,language=TeX}
+
+\usepackage{fancyvrb}
+
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{815}
+%
+% \CharacterTable
+% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+%
+% \changes{1.0}{2011/05/03}{Converted to DTX file}
+%
+% \DoNotIndex{\newcommand,\newenvironment}
+%
+% \providecommand*{\url}{\texttt}
+% \GetFileInfo{braids.sty}
+% \title{The \textsf{braids} package: codebase}
+% \author{Andrew Stacey \\ \url{stacey@math.ntnu.no}}
+% \date{\fileversion~from \filedate}
+%
+% \maketitle
+%
+% \begin{center}
+% \begin{tikzpicture}
+% \braid[line width=3pt,line cap=round,style strands={1}{blue},number of strands=7] s_1 s_2 s_5^{-1};
+% \end{tikzpicture}
+% \end{center}
+%
+% \section{Introduction}
+%
+% This is a package for drawing braid diagrams using PGF/TikZ.
+% Its inspiration was a question and answer on the website \url{http://tex.stackexchange.com}.
+%
+% \StopEventually{}
+%
+% \section{Implementation}
+%
+% \iffalse
+%<*package>
+% \fi
+%
+% Test the version of PGF to see if it's what we expect.
+% If not, issue a warning (but continue anyway; after all, it \emph{might just work}).
+% \begin{macrocode}
+\def\braid@pgfversion{2.10}%
+\ifx\pgfversion\braid@pgfversion
+\else
+\PackageWarning{braids}{This package was designed using PGF2.10; you are using \pgfversion.}%
+\fi
+% \end{macrocode}
+% \begin{macro}{\ge@addto@macro}
+% This is an expanded version of \Verb+\g@addto@macro+.
+% Namely, it adds the \emph{expansion} of the second argument to the first.
+% \begin{macrocode}
+\long\def\ge@addto@macro#1#2{%
+ \begingroup
+ \toks@\expandafter\expandafter\expandafter{\expandafter#1#2}%
+ \xdef#1{\the\toks@}%
+ \endgroup}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\braid}
+% This is the user command.
+% We start a group to ensure that all our assignments are local, and then call our initialisation code.
+% The optional argument is for any keys to be set.
+% \begin{macrocode}
+\newcommand{\braid}[1][]{%
+ \begingroup
+ \braid@start{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\braid@process}
+% This is the token swallower.
+% This takes the next token on the braid specification and passes it to the handler command (in the macro \Verb+\braid@token+) which decides what to do next.
+% (Incidentally, the code here is heavily influenced by TikZ.
+% That's probably not very surprising.)
+% \begin{macrocode}
+\def\braid@process{%
+ \afterassignment\braid@handle\let\braid@token=%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\braid@process@start}
+% This is a variant of \Verb+\braid@process+ which is used at the start where we might have a few extra bits and pieces before the braid itself starts.
+% Specifically, we test for the \Verb+at+ and \Verb+(name)+ possibilities.
+% \begin{macrocode}
+\def\braid@process@start{%
+ \afterassignment\braid@handle@start\let\braid@token=%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\braid@handle@start}
+% This is the handler in use at the start.
+% It looks for the tokens \Verb+a+ or \Verb+(+ which (might) signal the start of an \Verb+at (coordinate)+ or \Verb+(name)+.
+% If we get anything else (modulo spaces) we decide that we've reached the end of the initialisation stuff and it is time to get started on the braid itself.
+% \begin{macrocode}
+\def\braid@handle@start{%
+ \let\braid@next=\braid@handle
+ \ifx\braid@token a
+% \end{macrocode}
+% We got an \Verb+a+ so we might have an \Verb+at (coordinate)+
+% \begin{macrocode}
+ \let\braid@next=\braid@maybe@locate
+ \else
+ \ifx\braid@token(%)
+% \end{macrocode}
+% We got an \Verb+(+ so we have a name
+% \begin{macrocode}
+ \iffalse)\fi %Indentation hack!
+ \let\braid@next=\braid@assign@name
+ \else
+ \ifx\braid@token\@sptoken
+% \end{macrocode}
+% Space; boring, redo from start
+% \begin{macrocode}
+ \let\braid@next=\braid@process@start
+ \fi
+ \fi
+ \fi
+ \braid@next%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\braid@handle}
+% This is the main handler for parsing the braid word.
+% It decides what action to take depending on what the token is.
+% We have to be a bit careful with catcodes, some packages set
+% \Verb+;+ and \Verb+|+ to be active.
+% We should probably also be careful with \Verb+^+ and \Verb+_+.
+% \begin{macrocode}
+\let\braid@semicolon=;
+\let\braid@bar=|
+\def\braid@handle{%
+ \let\braid@next=\braid@process
+% \end{macrocode}
+% Start by checking our catcodes to see what we should check against
+% \begin{macrocode}
+ \ifnum\the\catcode`\;=\active
+ \expandafter\let\expandafter\braid@semicolon\tikz@activesemicolon
+ \fi
+ \ifnum\the\catcode`\|=\active
+ \expandafter\let\expandafter\braid@bar\tikz@activebar
+ \fi
+ \ifx\braid@token\braid@semicolon
+% \end{macrocode}
+% Semicolon, means that we're done reading our braid.
+% It's time to render it.
+% \begin{macrocode}
+ \let\braid@next=\braid@render
+ \else
+ \ifx\braid@token^
+% \end{macrocode}
+% Superscript character, the next token tells us whether it's an over-crossing or an under-crossing.
+% \begin{macrocode}
+ \let\braid@next=\braid@sup
+ \else
+ \ifx\braid@token_
+% \end{macrocode}
+% Subscript character, the next token tells us which strands cross.
+% \begin{macrocode}
+ \let\braid@next=\braid@sub
+ \else
+ \ifx\braid@token-
+% \end{macrocode}
+% Hyphen, this is so that we can have more than one crossing on the same level.
+% \begin{macrocode}
+ \braid@increase@levelfalse
+ \else
+ \ifx\braid@token[
+% \end{macrocode}
+% Open bracket, this means we have some more options to process.
+% \begin{macrocode}
+ \let\braid@next=\braid@process@options
+ \else
+ \ifx\braid@token\braid@bar
+% \end{macrocode}
+% Bar, this tells us that we want a ``floor'' at this point.
+% \begin{macrocode}
+ \edef\braid@tmp{,\expandafter\the\value{braid@level}}%
+ \ge@addto@macro\braid@floors\braid@tmp%
+ \else
+ \ifx\braid@token\bgroup
+% \end{macrocode}
+% Begin group, which we reinterpret as begining a scope.
+% \begin{macrocode}
+ \braid@beginscope
+ \else
+ \ifx\braid@token\egroup
+% \end{macrocode}
+% End group, which ends the scope
+% \begin{macrocode}
+ \braid@endscope
+ \else
+% \end{macrocode}
+% Otherwise, we add the token to the braid label.
+% \begin{macrocode}
+ \ge@addto@macro\braid@label{\braid@token}%
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \braid@next%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\braid@maybe@locate}
+% If we got an \Verb+a+ token in the \Verb+\braid@handle@start+ then it \emph{might} mean we're looking at \Verb+at (coordinate)+ or it might mean that the user has decided to use \Verb+a+ as the braid parameter.
+% So we examine the next token for a \Verb+t+.
+% \begin{macrocode}
+\def\braid@maybe@locate{%
+ \afterassignment\braid@@maybe@locate\let\braid@token=%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\braid@@maybe@locate}
+% This is where we test for \Verb+t+ and act appropriately.
+% \begin{macrocode}
+\def\braid@@maybe@locate{%
+ \let\braid@next=\braid@handle
+ \ifx\braid@token t
+ \let\braid@next=\braid@find@location
+ \fi
+ \braid@next%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\braid@find@location}
+% This macro starts us looking for a coordinate.
+% \begin{macrocode}
+\def\braid@find@location{%
+ \afterassignment\braid@@find@location\let\braid@token=%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\braid@@find@location}
+% This is the test for the start of a coordinate.
+% If we get a \Verb+(+ that means we've reached the coordinate.
+% A space means ``carry on''.
+% Anything else is a (non-fatal) error.
+% \begin{macrocode}
+\def\braid@@find@location{%
+ \let\braid@next=\braid@location@error
+ \ifx\braid@token(%)
+ \let\braid@next=\braid@locate
+ \else
+ \ifx\braid@token\@sptoken
+ \let\braid@next=\braid@find@location
+ \fi
+ \fi
+ \braid@next%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\braid@location@error}
+% This is our error message for not getting a location.
+% \begin{macrocode}
+\def\braid@location@error{%
+ \PackageWarning{braids}{Could not figure out location for braid}%
+ \braid@process@start%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\braid@locate}
+% If we reached a \Verb+(+ when looking for a coordinate, everything up to the next \Verb+)+ is that coordinate.
+% Then we parse the coordinate and call the relocation macro.
+% \begin{macrocode}
+\def\braid@locate#1){%
+ \tikz@scan@one@point\braid@relocate(#1)%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\braid@relocate}
+% This is the macro that actually does the relocation.
+% \begin{macrocode}
+\def\braid@relocate#1{%
+ #1\relax
+ \advance\pgf@x by -\braid@width
+ \pgftransformshift{\pgfqpoint{\pgf@x}{\pgf@y}}
+ \braid@process@start%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\braid@assign@name}
+% This macro saves our name.
+% \begin{macrocode}
+\def\braid@assign@name#1){%
+ \def\braid@name{#1}%
+ \braid@process@start%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\braid@process@options}
+% The intention of this macro is to allow setting of style options mid-braid.
+% (At present, this wouldn't make a lot of sense.)
+% \begin{macrocode}
+\def\braid@process@options#1]{%
+ \tikzset{#1}%
+ \braid@process%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% The next macros handle the actual braid elements.
+% Everything has to have a subscript, but the superscript is optional and can come before or after the subscript.
+%
+% \begin{macro}{\braid@sup}
+% This handles braid elements of the form \Verb+a^{-1}_2+.
+% \begin{macrocode}
+\def\braid@sup#1_#2{\g@addto@macro\braid@label{_{#2}^{#1}}\braid@add@crossing{#2}{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\braid@sub}
+% \begin{macrocode}
+% This handles braid elements of the form \Verb+a_1+ or \Verb+a_1^{-1}+.
+\def\braid@sub#1{\@ifnextchar^{\braid@@sub{#1}}{\g@addto@macro\braid@label{_{#1}}\braid@add@crossing{#1}{1}}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\braid@@sub}
+% Helper macro for \Verb+\braid@sub+.
+% \begin{macrocode}
+\def\braid@@sub#1^#2{\g@addto@macro\braid@label{_{#1}^{#2}}\braid@add@crossing{#1}{#2}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\braid@ne}
+% Remember what \Verb+1+ looks like for testing against.
+% \begin{macrocode}
+\def\braid@ne{1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\braid@add@crossing}
+% This is the macro which adds the crossing to the current list of strands.
+% The strands are stored as \emph{soft paths} (see the TikZ/PGF documentation).
+% So this selects the right strands and then extends them according to the crossing type.
+% \begin{macrocode}
+\def\braid@add@crossing#1#2{%
+% \end{macrocode}
+% Our crossing type, which is \Verb+#2+, is one of \Verb+1+ or \Verb+-1+.
+% Our strands are \Verb+#1+ and \Verb-#1+1-.
+% \begin{macrocode}
+ \edef\braid@crossing@type{#2}%
+ \edef\braid@this@strand{#1}%
+ \pgfmathtruncatemacro{\braid@next@strand}{#1+1}
+% \end{macrocode}
+% Increment the level counter, if requested.
+% The controls whether the crossing is on the same level as the previous one or is one level further on.
+% \begin{macrocode}
+ \ifbraid@increase@level
+ \stepcounter{braid@level}
+ \fi
+% \end{macrocode}
+% Default is to request increment so we set it for next time.
+% \begin{macrocode}
+ \braid@increase@leveltrue
+% \end{macrocode}
+% Now we figure out the coordinates of the crossing.
+% \Verb+(\braid@tx,\braid@ty)+ is the top-left corner (assuming the braid flows down the page).
+% \Verb+(\braid@nx,\braid@ny)+ is the bottom-right corner (assuming the braid flows down the page).
+% We start by setting \Verb+(\braid@tx,\braid@ty)+ according to the level and strand number, then shift \Verb+\braid@ty+ by \Verb+\braid@eh+ which is the ``edge height'' (the little extra at the start and end of each strand).
+% Then from these values, we set \Verb+(\braid@nx,\braid@ny)+ by adding on the appropriate amount.
+% The heights \Verb+\braid@cy+ and \Verb+\braid@dy+ are for the control points for the strands as they cross.
+% They're actually the same height, but using two gives us the possibility of changing them independently in a later version of this package.
+% Lastly, we bring \Verb+\braid@ty+ and \Verb+\braid@ny+ towards each other just a little so that there is ``clear water'' between subsequent crossings (makes it look a bit better if the same strand is used in subsequent crossings).
+% \begin{macrocode}
+ \braid@tx=\braid@this@strand\braid@width
+ \braid@ty=\value{braid@level}\braid@height
+ \advance\braid@ty by \braid@eh
+ \braid@nx=\braid@tx
+ \braid@ny=\braid@ty
+ \advance\braid@nx by \braid@width
+ \advance\braid@ny by \braid@height
+ \braid@cy=\braid@ty
+ \braid@dy=\braid@ny
+ \advance\braid@cy by .5\braid@height
+ \advance\braid@dy by -.5\braid@height
+ \advance\braid@ty by .05\braid@height
+ \advance\braid@ny by -.05\braid@height
+% \end{macrocode}
+% Now we try to find a starting point for the strand ending here.
+% We might not have used this strand before, so it might not exist.
+% \begin{macrocode}
+ \expandafter\let\expandafter\braid@this@path@origin\csname braid@strand@\braid@this@strand @origin\endcsname
+% \end{macrocode}
+% If we haven't seen this strand before, that one will be \Verb+\relax+.
+% \begin{macrocode}
+\ifx\braid@this@path@origin\relax
+% \end{macrocode}
+% Haven't seen this strand before, so initialise it.
+% Record the initial position of the strand.
+% \begin{macrocode}
+ \let\braid@this@path@origin\braid@this@strand
+% \end{macrocode}
+% Start a new soft path.
+% \begin{macrocode}
+ \pgfsyssoftpath@setcurrentpath{\@empty}
+ \pgfpathmoveto{\pgfpoint{\braid@tx}{0pt}}
+% \end{macrocode}
+% Save the path as \Verb+\braid@this@path+.
+% \begin{macrocode}
+ \pgfsyssoftpath@getcurrentpath{\braid@this@path}
+ \else
+% \end{macrocode}
+% We have seen this before, so we simply copy the associated path in to \Verb+\braid@this@path+.
+% \begin{macrocode}
+ \expandafter\let\expandafter\braid@this@path\csname braid@strand@\braid@this@path@origin\endcsname
+ \fi
+% \end{macrocode}
+% Now we do the same again with the other strand in the crossing.
+% \begin{macrocode}
+ \expandafter\let\expandafter\braid@next@path@origin\csname braid@strand@\braid@next@strand @origin\endcsname
+ \ifx\braid@next@path@origin\relax
+ \let\braid@next@path@origin\braid@next@strand
+ \pgfsyssoftpath@setcurrentpath{\@empty}
+ \pgfpathmoveto{\pgfpoint{\braid@nx}{0pt}}
+ \pgfsyssoftpath@getcurrentpath{\braid@next@path}
+ \else
+ \expandafter\let\expandafter\braid@next@path\csname braid@strand@\braid@next@path@origin\endcsname
+ \fi
+% \end{macrocode}
+% Now that we have the paths for our two strands, we extend them to the next level.
+% We start by selecting the first path.
+% \begin{macrocode}
+ \pgfsyssoftpath@setcurrentpath{\braid@this@path}
+% \end{macrocode}
+% Draw a line down to the current level, note that this line is always non-trivial since we shifted the corners of the crossing in a little.
+% \begin{macrocode}
+ \pgfpathlineto{\pgfqpoint{\braid@tx}{\braid@ty}}
+% \end{macrocode}
+% Curve across to the next position.
+% Depending on the crossing type, we either have a single curve or we have to break it in two.
+% \begin{macrocode}
+\ifx\braid@crossing@type\braid@over@cross
+% \end{macrocode}
+% We're on the overpass, so just one curve needed.
+% \begin{macrocode}
+\pgfpathcurveto{\pgfqpoint{\braid@tx}{\braid@cy}}{\pgfqpoint{\braid@nx}{\braid@dy}}{\pgfqpoint{\braid@nx}{\braid@ny}}
+\else
+% \end{macrocode}
+% We're on the underpass, so we need to interrupt our path to allow the other curve to go past.
+% The choice of \Verb+.4+ and \Verb+.6+ should probably be configurable.
+% \begin{macrocode}
+\pgfpathcurvebetweentimecontinue{0}{.4}{\pgfqpoint{\braid@tx}{\braid@ty}}{\pgfqpoint{\braid@tx}{\braid@cy}}{\pgfqpoint{\braid@nx}{\braid@dy}}{\pgfqpoint{\braid@nx}{\braid@ny}}
+\pgfpathcurvebetweentime{.6}{1}{\pgfqpoint{\braid@tx}{\braid@ty}}{\pgfqpoint{\braid@tx}{\braid@cy}}{\pgfqpoint{\braid@nx}{\braid@dy}}{\pgfqpoint{\braid@nx}{\braid@ny}}
+\fi
+% \end{macrocode}
+% We're done with this path, so now we save it.
+% \begin{macrocode}
+ \pgfsyssoftpath@getcurrentpath{\braid@this@path}
+% \end{macrocode}
+% Now do the same with the second path.
+% \begin{macrocode}
+ \pgfsyssoftpath@setcurrentpath{\braid@next@path}
+ \pgfpathlineto{\pgfqpoint{\braid@nx}{\braid@ty}}
+\ifx\braid@crossing@type\braid@over@cross
+\pgfpathcurvebetweentimecontinue{0}{.4}{\pgfqpoint{\braid@nx}{\braid@ty}}{\pgfqpoint{\braid@nx}{\braid@cy}}{\pgfqpoint{\braid@tx}{\braid@dy}}{\pgfqpoint{\braid@tx}{\braid@ny}}
+\pgfpathcurvebetweentime{.6}{1}{\pgfqpoint{\braid@nx}{\braid@ty}}{\pgfqpoint{\braid@nx}{\braid@cy}}{\pgfqpoint{\braid@tx}{\braid@dy}}{\pgfqpoint{\braid@tx}{\braid@ny}}
+\else
+ \pgfpathcurveto{\pgfqpoint{\braid@nx}{\braid@cy}}{\pgfqpoint{\braid@tx}{\braid@dy}}{\pgfqpoint{\braid@tx}{\braid@ny}}
+\fi
+ \pgfsyssoftpath@getcurrentpath{\braid@next@path}
+% \end{macrocode}
+% Now save the paths to their proper macros again.
+% \begin{macrocode}
+ \expandafter\let\csname braid@strand@\braid@this@path@origin \endcsname\braid@this@path
+ \expandafter\let\csname braid@strand@\braid@next@path@origin \endcsname\braid@next@path
+% \end{macrocode}
+% Now update the origins
+% \begin{macrocode}
+ \expandafter\let\csname braid@strand@\braid@this@strand @origin\endcsname\braid@next@path@origin
+ \expandafter\let\csname braid@strand@\braid@next@strand @origin\endcsname\braid@this@path@origin
+% \end{macrocode}
+% increment the strand counter, if necessary
+% \begin{macrocode}
+ \pgfmathparse{\value{braid@strands} < \braid@next@strand ? "\noexpand\setcounter{braid@strands}{\braid@next@strand}" : ""}
+ \pgfmathresult
+% \end{macrocode}
+% And merrily go on our way with the next bit of the braid specification.
+% \begin{macrocode}
+ \braid@process%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\braid@floors@trim}
+% The list of floors, if given, will start with a superfluous comma.
+% This removes it.
+% \begin{macrocode}
+\def\braid@floors@trim,{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\braid@render@floor}
+% This is the default rendering for floors: it draws a rectangle.
+% \begin{macrocode}
+\def\braid@render@floor{%
+ \draw (\floorsx,\floorsy) rectangle (\floorex,\floorey);
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\braid@render}
+% This is called at the end of the braid and it renders the braids and floors according to whatever has been built up up to now.
+% \begin{macrocode}
+\def\braid@render{
+% \end{macrocode}
+% Check for floors since we do them first.
+% \begin{macrocode}
+ \ifx\braid@floors\@empty
+ \else
+% \end{macrocode}
+% Have some floors, start a scope and prepare to render them.
+% \begin{macrocode}
+ \pgfsys@beginscope
+% \end{macrocode}
+% Clear the path (just to be sure).
+% \begin{macrocode}
+ \pgfsyssoftpath@setcurrentpath{\empty}
+% \end{macrocode}
+% Trim the initial comma off the list of floors.
+% \begin{macrocode}
+ \edef\braid@floors{\expandafter\braid@floors@trim\braid@floors}
+% \end{macrocode}
+% Initialise our horizontal coordinates.
+% \begin{macrocode}
+ \braid@tx=\braid@width
+ \advance\braid@tx by \braid@eh
+ \braid@nx=\value{braid@strands}\braid@width
+ \advance\braid@nx by -\braid@eh
+% \end{macrocode}
+% Loop over the list of floors.
+% \begin{macrocode}
+ \foreach \braid@f in \braid@floors {
+ \pgfsys@beginscope
+% \end{macrocode}
+% Figure out the vertical coordinates for the current floor.
+% \begin{macrocode}
+ \braid@ty=\braid@f\braid@height
+ \advance\braid@ty by \braid@eh
+ \advance\braid@ty by \braid@height
+ \braid@ny=\braid@ty
+ \advance\braid@ny by \braid@height
+% \end{macrocode}
+% Save the coordinates for use in the floor rendering macro.
+% \begin{macrocode}
+ \edef\floorsx{\the\braid@tx}
+ \edef\floorsy{\the\braid@ty}
+ \edef\floorex{\the\braid@nx}
+ \edef\floorey{\the\braid@ny}
+ \let\tikz@options=\pgfutil@empty
+% \end{macrocode}
+% Load general floor style options.
+% \begin{macrocode}
+ \expandafter\tikzset\expandafter{\braid@floors@style}
+% \end{macrocode}
+% Load any style options specific to this floor.
+% We're actually offset by 2 from what the user thinks the floor level is.
+% \begin{macrocode}
+ \pgfmathtruncatemacro{\braid@ff}{\braid@f+2}
+% \end{macrocode}
+% Load the relevant floor style, if it exists.
+% \begin{macrocode}
+ \expandafter\let\expandafter\braid@floor@style\csname braid@options@floor@\braid@ff\endcsname
+ \ifx\braid@floor@style\relax
+ \else
+% \end{macrocode}
+% There is a floor style for this level, so process it.
+% \begin{macrocode}
+ \expandafter\tikzset\expandafter{\braid@floor@style}%
+ \fi
+% \end{macrocode}
+% The \Verb+\tikzset+ just parses the options, we need to call \Verb+\tikz@options+ to actually set them.
+% \begin{macrocode}
+\tikz@options
+% \end{macrocode}
+% Now we call the rendering code.
+% \begin{macrocode}
+\braid@render@floor
+% \end{macrocode}
+% Done!
+% End the scope for \emph{this} floor and go again.
+% \begin{macrocode}
+\pgfsys@endscope
+ }
+% \end{macrocode}
+% Done rendering floors, end the scope.
+% \begin{macrocode}
+ \pgfsys@endscope
+ \fi
+% \end{macrocode}
+% Finished with floors (if we had them), now get on with the strands.
+% \begin{macrocode}
+ \stepcounter{braid@level}
+ \foreach \braid@k in {1,...,\value{braid@strands}} {
+% \end{macrocode}
+% Start a local scope to ensure we don't mess with other braids
+% \begin{macrocode}
+ \pgfsys@beginscope
+% \end{macrocode}
+% Default is to draw each braid
+% \begin{macrocode}
+ \tikz@mode@drawtrue%
+ \let\tikz@mode=\pgfutil@empty
+ \let\tikz@options=\pgfutil@empty
+% \end{macrocode}
+% (x,y) coordinates of bottom of strand
+% \begin{macrocode}
+ \braid@tx=\braid@k\braid@width
+ \braid@ty=\value{braid@level}\braid@height
+ \advance\braid@ty by 2\braid@eh
+% \end{macrocode}
+% Try to find the starting point of this strand
+% \begin{macrocode}
+ \expandafter\let\expandafter\braid@path@origin\csname braid@strand@\braid@k @origin\endcsname
+ \ifx\braid@path@origin\relax
+% \end{macrocode}
+% If that doesn't exist, we'll just draw a straight line
+% so we move to the top of the current position
+% \begin{macrocode}
+ \pgfsyssoftpath@setcurrentpath{\@empty}
+ \pgfpathmoveto{\pgfqpoint{\braid@tx}{0pt}}
+ \let\braid@path@origin\braid@k
+ \else
+% \end{macrocode}
+% If the path does exist, we load it
+% \begin{macrocode}
+ \expandafter\let\expandafter\braid@path\csname braid@strand@\braid@path@origin\endcsname
+ \pgfsyssoftpath@setcurrentpath{\braid@path}
+ \fi
+% \end{macrocode}
+% Extend the path to the bottom
+% \begin{macrocode}
+ \pgflineto{\pgfqpoint{\braid@tx}{\braid@ty}}
+% \end{macrocode}
+% Load common style options
+% \begin{macrocode}
+ \expandafter\tikzset\expandafter{\braid@style}
+% \end{macrocode}
+% Load any style options specific to this strand
+% \begin{macrocode}
+ \expandafter\let\expandafter\braid@style\csname braid@options@strand@\braid@path@origin\endcsname
+ \ifx\braid@style\relax
+ \else
+ \expandafter\tikzset\expandafter{\braid@style}
+ \fi
+\braid@options
+ \tikz@mode
+ \tikz@options
+% \end{macrocode}
+% This is the command that actually draws the strand.
+% \begin{macrocode}
+ \edef\tikz@temp{\noexpand\pgfusepath{%
+ \iftikz@mode@draw draw\fi%
+ }}%
+ \tikz@temp
+% \end{macrocode}
+% If our braid has a name, we label the ends of the strand.
+% \begin{macrocode}
+\ifx\braid@name\pgfutil@empty
+\else
+% \end{macrocode}
+% Label the ends of the strand.
+% \begin{macrocode}
+\coordinate (\braid@name-\braid@path@origin-e) at (\braid@tx,\braid@ty);
+\coordinate (\braid@name-rev-\braid@k-e) at (\braid@tx,\braid@ty);
+\braid@nx=\braid@path@origin\braid@width
+\coordinate (\braid@name-\braid@path@origin-s) at (\braid@nx,0pt);
+\coordinate (\braid@name-rev-\braid@k-s) at (\braid@nx,0pt);
+\fi
+% \end{macrocode}
+% Done with this strand, close the scope and do the next one.
+% \begin{macrocode}
+ \pgfsys@endscope
+ }
+% \end{macrocode}
+% If our braid has a name, we also want to label the centre.
+% \begin{macrocode}
+ \ifx\braid@name\pgfutil@empty
+ \else
+ \braid@tx=\value{braid@strands}\braid@width
+ \braid@ty=\value{braid@level}\braid@height
+ \advance\braid@ty by 2\braid@eh
+ \advance\braid@tx by \braid@width
+ \braid@tx=.5\braid@tx
+ \braid@ty=.5\braid@ty
+ \coordinate (\braid@name) at (\braid@tx,\braid@ty);
+ \fi
+% \end{macrocode}
+% All done now, close the scope and end the group (which was opened right at the start).
+% \begin{macrocode}
+ \pgfsys@endscope
+ \endgroup}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\braid@start}
+% This starts off the braid, initialising a load of stuff.
+% We start a PGF scope, set the level to \(-1\), the label, floors, and name to empty, process any options we're given, and save certain lengths for later use..
+% \begin{macrocode}
+\def\braid@start#1{%
+ \pgfsys@beginscope
+ \setcounter{braid@level}{-1}%
+ \let\braid@label\@empty
+ \let\braid@floors\@empty
+ \let\braid@name\empty
+ \pgfkeys{/pgf/braid/.cd,#1}
+ \let\braid@options\tikz@options
+ \tikz@transform
+ \setcounter{braid@strands}{\pgfkeysvalueof{/pgf/braid/number of strands}}%
+ \braid@width=\pgfkeysvalueof{/pgf/braid/width}
+ \braid@height=\pgfkeysvalueof{/pgf/braid/height}
+ \braid@eh=\pgfkeysvalueof{/pgf/braid/border height}
+ \braid@height=-\braid@height
+ \braid@eh=-\braid@eh
+ \braid@increase@leveltrue
+ \braid@process@start
+}
+% \end{macrocode}
+% \end{macro}
+%
+% These are the lengths we'll use as we construct the braid
+% \begin{macrocode}
+\newdimen\braid@width
+\newdimen\braid@height
+\newdimen\braid@tx
+\newdimen\braid@ty
+\newdimen\braid@nx
+\newdimen\braid@ny
+\newdimen\braid@cy
+\newdimen\braid@dy
+\newdimen\braid@eh
+% \end{macrocode}
+%
+% An if to decide whether or not to step to the next level or not
+% \begin{macrocode}
+\newif\ifbraid@increase@level
+% \end{macrocode}
+%
+% Some initial values
+% \begin{macrocode}
+\let\braid@style\pgfutil@empty
+\let\braid@floors@style\pgfutil@empty
+\def\braid@over@cross{1}
+% \end{macrocode}
+%
+% Counters to track the strands and the levels.
+% \begin{macrocode}
+\newcounter{braid@level}
+\newcounter{braid@strands}
+% \end{macrocode}
+%
+% All the keys we'll use.
+% \begin{macrocode}
+\pgfkeys{
+% \end{macrocode}
+% Handle unknown keys by passing them to \Verb+pgf+ and \Verb+tikz+.
+% \begin{macrocode}
+ /tikz/braid/.search also={/pgf},
+ /pgf/braid/.search also={/pgf,/tikz},
+% \end{macrocode}
+% Our ``namespace'' is \Verb+/pgf/braid+.
+% \begin{macrocode}
+ /pgf/braid/.cd,
+ number of strands/.initial=0,
+ height/.initial=1cm,
+ width/.initial=1cm,
+ border height/.initial=.25cm,
+ name/.code={%
+ \def\braid@name{#1}%
+ },
+ at/.code={%
+ \braid@relocate{#1}%
+ },
+ floor command/.code={%
+ \def\braid@render@floor{#1}%
+ },
+ style strands/.code 2 args={%
+ \def\braid@temp{#2}%
+ \braidset{style each strand/.list={#1}}%
+ },
+ style each strand/.code={%
+ \expandafter\edef\csname braid@options@strand@#1\endcsname{\braid@temp}%
+ },
+ style floors/.code 2 args={%
+ \def\braid@temp{#2}%
+ \braidset{style each floor/.list={#1}}%
+ },
+ style each floor/.code={%
+ \expandafter\edef\csname braid@options@floor@#1\endcsname{\braid@temp}%
+ },
+ style all floors/.code={%
+ \def\braid@floors@style{#1}
+ }
+}
+% \end{macrocode}
+% \begin{macro}{\braidset}
+% Shorthand for setting braid-specific keys.
+% \begin{macrocode}
+\def\braidset#1{%
+ \pgfkeys{/pgf/braid/.cd,#1}}
+% \end{macrocode}
+% \end{macro}
+% \iffalse
+%</package>
+% \fi
+%
+% \Finale
+
+\endinput