summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/tqft/tqft.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/tqft/tqft.dtx')
-rw-r--r--Master/texmf-dist/source/latex/tqft/tqft.dtx1212
1 files changed, 1212 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/tqft/tqft.dtx b/Master/texmf-dist/source/latex/tqft/tqft.dtx
new file mode 100644
index 00000000000..769cf8018a7
--- /dev/null
+++ b/Master/texmf-dist/source/latex/tqft/tqft.dtx
@@ -0,0 +1,1212 @@
+% \iffalse meta-comment
+%<*internal>
+\iffalse
+%</internal>
+%<*readme>
+----------------------------------------------------------------
+tqft --- a style file for drawing TQFT 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 node shapes useful for drawing TQFT diagrams with TikZ/PGF.
+%</readme>
+%<*internal>
+\fi
+\def\nameofplainTeX{plain}
+\ifx\fmtname\nameofplainTeX\else
+ \expandafter\begingroup
+\fi
+%</internal>
+%<*install>
+\input docstrip.tex
+\keepsilent
+\askforoverwritefalse
+\preamble
+----------------------------------------------------------------
+tqft --- a style file for drawing TQFT 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 file tqft.dtx
+and the derived files tqft.ins,
+ tqft.pdf, and
+ tqft.sty.
+
+\endpostamble
+\usedir{tex/latex/tqft}
+\generate{
+ \file{\jobname.sty}{\from{\jobname.dtx}{package}}
+}
+%</install>
+%<install>\endbatchfile
+%<*internal>
+\usedir{source/latex/tqft}
+\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{tqft}[2011/05/03 v1.0 Tikz/PGF commands for drawing TQFT 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{1595}
+%
+% \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{tqft.dtx}
+% \title{The \textsf{tqft} package: codebase}
+% \author{Andrew Stacey \\ \url{stacey@math.ntnu.no}}
+% \date{\fileversion~from \filedate}
+%
+% \maketitle
+%
+%
+% \begin{tikzpicture}[every node/.style={tqft/cobordism style={draw,thick,red}}]
+% \node[
+% tqft,
+% fill=orange,
+% fill opacity=.5,
+% boundary style={fill=purple},
+% cobordism style={draw,thick,red},
+% boundary lower style={draw,dashed,thick,blue},
+% boundary upper style={draw,green,thick},
+% incoming boundary components=4,
+% outgoing boundary components=6,
+% offset=-1.5,
+% ] (a) {};
+% \node[pin=north:1] at (a.incoming boundary 1) {};
+% \node[pin=north:3] at (a.incoming boundary 3) {};
+% \node[pin=south:1] at (a.outgoing boundary 1) {};
+% \node[pin=south:4] at (a.outgoing boundary 4) {};
+% \node[pin=south:6] at (a.outgoing boundary 6) {};
+% \end{tikzpicture}
+%
+% \section{Introduction}
+%
+% This is a package for drawing TQFT diagrams using PGF/TikZ.
+% Its inspiration was a question and answer on the website \url{http://tex.stackexchance.com}.
+%
+%
+% \StopEventually{}
+%
+% \section{Implementation}
+%
+% \iffalse
+%<*package>
+% \fi
+% \begin{macrocode}
+\RequirePackage{pgfkeys}
+\RequirePackage{pgf}
+% \end{macrocode}
+%
+% We can view the cobordisms from the \emph{input} or \emph{output} ends, the implementation of the choice is to draw an arc from 0 to 180 or from 0 to -180 so we just need to track minus signs.
+% These macros are for that.
+% \begin{macrocode}
+\def\pgf@tqft@minus{-}
+\let\pgf@tqft@upper\@empty
+\let\pgf@tqft@lower\pgf@tqft@minus
+% \end{macrocode}
+% Some helpful extra functions.
+%
+% \Verb+\tqftset+ is our equivalent of \Verb+\tikzset+.
+% \begin{macrocode}
+\def\tqftset#1{\pgfkeys{/pgf/tqft/.cd,#1}}
+% \end{macrocode}
+% \begin{macro}{\tqft@process}
+% This macro applies our flow transformation to the given coordinates, % with the result stored in \Verb+\pgf@x+ and \Verb+\pgf@y+.
+% \begin{macrocode}
+\def\tqft@process#1#2{%
+ \edef\tqft@px{#1}
+ \edef\tqft@py{#2}
+ \pgf@process{
+ \pgftransformreset
+ \let\tikz@transform=\pgfutil@empty
+ \expandafter\tikzset\expandafter{\tqft@transformation}
+ \tikz@transform
+ \pgfpointtransformed{\pgfqpoint{\tqft@px}{\tqft@py}}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% Declare some dimension registers to hold the specifications of the cobordism.
+% \begin{macrocode}
+\newdimen\tqft@xa
+\newdimen\tqft@xb
+\newdimen\tqft@c
+\newdimen\tqft@ch
+\newdimen\tqft@h
+\newdimen\tqft@s
+\newdimen\tqft@w
+\newif\iftqft@within@node
+% \end{macrocode}
+% Now we set up all the keys that we'll need in the course of this shape
+% \begin{macrocode}
+\pgfkeys{
+% \end{macrocode}
+% This key is our basic installer key, setting the shape and putting us in the right key family.
+% \begin{macrocode}
+ /tikz/tqft/.style={%
+ /tikz/shape=tqft cobordism,
+ /pgf/tqft,
+ /tikz/every tqft
+ },
+% \end{macrocode}
+% This deals with unknown keys, passing them on to TikZ.
+% \begin{macrocode}
+ /pgf/tqft/.unknown/.code={%
+ \let\tqft@searchname=\pgfkeyscurrentname%
+ \pgfkeysalso{%
+ /tikz/\tqft@searchname=#1
+ }
+ },
+% \end{macrocode}
+% Here we have the standard \Verb+every something+ style.
+% \begin{macrocode}
+ /tikz/every tqft/.style={},
+% \end{macrocode}
+% We might get called in \Verb+/tikz+ or \Verb+/pgf+, this passes off anything in \Verb+/tikz/tqft+ to \Verb+/pgf/tqft+.
+% \begin{macrocode}
+ /tikz/tqft/.unknown/.code={%
+ \let\tqft@searchname=\pgfkeyscurrentname%
+ \pgfkeysalso{%
+ /pgf/tqft/\tqft@searchname=#1
+ }
+ },
+% \end{macrocode}
+% Let's play happy families!
+% \begin{macrocode}
+ /pgf/tqft/.is family,
+ /pgf/tqft,
+% \end{macrocode}
+% This sets our shape to be the boundary circle
+% \begin{macrocode}
+ boundary circle/.style={
+ /tikz/shape=tqft boundary circle
+ },
+% \end{macrocode}
+% These set our number of boundary components
+% \begin{macrocode}
+ incoming boundary components/.initial=5,
+ outgoing boundary components/.initial=4,
+% \end{macrocode}
+% This is the ``horizontal'' offset of the first outgoing component from the first incoming one.
+% \begin{macrocode}
+ offset/.initial=0,
+% \end{macrocode}
+% This is the ``vertical'' separation between boundary components.
+% \begin{macrocode}
+ cobordism height/.initial=2cm,
+% \end{macrocode}
+% This is the ``horizontal'' separation between boundary components.
+% \begin{macrocode}
+ boundary separation/.initial=2cm,
+% \end{macrocode}
+% These are the ``horizontal'' and ``vertical'' radii, respectively, of the boundary components (perhaps poorly named!).
+% \begin{macrocode}
+ circle width/.initial=10pt,
+ circle depth/.initial=5pt,
+% \end{macrocode}
+% These control the separation between the node and its anchors.
+% \begin{macrocode}
+ outer xsep/.initial=0pt,
+ outer ysep/.initial=0pt,
+ outer sep/.style={
+ outer xsep=#1,
+ outer ysep=#1
+ },
+% \end{macrocode}
+% This is our flow control. The \Verb+flow+ key installs a transformation to be applied to our node shape.
+% The possible transformations are stored in the following keys.
+% They aren't just rotations so that the numbering is always ``top to bottom'' or ``left to right''.
+% \begin{macrocode}
+ flow/.code={%
+ \pgfkeys{/pgf/tqft/flow transformation/.expand twice/.expand once=\pgfkeysvalueof{/pgf/tqft/flow transformation #1}}
+ },
+ flow transformation south/.initial={},
+ flow transformation north/.initial={%
+ xscale=-1,rotate=180
+ },
+ flow transformation east/.initial={%
+ rotate=90,xscale=-1
+ },
+ flow transformation west/.initial={%
+ rotate=270
+ },
+ flow transformation/.initial={},
+% \end{macrocode}
+% These control the direction from which we view the cobordism.
+% \begin{macrocode}
+ view from/.is choice,
+ view from/incoming/.code={%
+ \let\pgf@tqft@upper\pgf@tqft@minus
+ \let\pgf@tqft@lower\@empty
+ },
+ view from/outgoing/.code={%
+ \let\pgf@tqft@lower\pgf@tqft@minus
+ \let\pgf@tqft@upper\@empty
+ },
+% \end{macrocode}
+% The next set of keys are for styling the different pieces of a cobordism.
+% \begin{macrocode}
+ boundary lower style contents/.initial={},
+ boundary lower style/.code={%
+ \pgfkeys{/pgf/tqft/boundary lower style contents/.style={%
+ /tikz/.cd,#1
+ }
+ }
+ },
+ boundary style contents/.initial={},
+ boundary style/.code={%
+ \pgfkeys{/pgf/tqft/boundary style contents/.style={%
+ /tikz/.cd,#1
+ }
+ }
+ },
+ boundary upper style contents/.initial={},
+ boundary upper style/.code={%
+ \pgfkeys{/pgf/tqft/boundary upper style contents/.style={%
+ /tikz/.cd,#1
+ }
+ }
+ },
+ cobordism style contents/.initial={},
+ cobordism style/.code={%
+ \pgfkeys{/pgf/tqft/cobordism style contents/.style={%
+ /tikz/.cd,#1%
+ }
+ }
+ },
+% \end{macrocode}
+% The next set of keys define some default shapes.
+% \begin{macrocode}
+ pair of pants/.style={
+ /tikz/tqft,
+ incoming boundary components=1,
+ outgoing boundary components=2,
+ offset=-.5
+ },
+ /tikz/tqft pair of pants/.style={
+ /pgf/tqft/pair of pants,
+ },
+ reverse pair of pants/.style={
+ /tikz/tqft,
+ incoming boundary components=2,
+ outgoing boundary components=1,
+ offset=.5
+ },
+ /tikz/tqft reverse pair of pants/.style={
+ /pgf/tqft/reverse pair of pants,
+ },
+ cylinder to prior/.style={
+ /tikz/tqft,
+ incoming boundary components=1,
+ outgoing boundary components=1,
+ offset=-.5
+ },
+ /tikz/tqft cylinder to prior/.style={
+ /pgf/tqft/cylinder to prior,
+ },
+ cylinder to next/.style={
+ /tikz/tqft,
+ incoming boundary components=1,
+ outgoing boundary components=1,
+ offset=.5
+ },
+ /tikz/tqft cylinder to next/.style={
+ /pgf/tqft/cylinder to next,
+ },
+ cylinder/.style={
+ /tikz/tqft,
+ incoming boundary components=1,
+ outgoing boundary components=1
+ },
+ /tikz/tqft cylinder/.style={
+ /pgf/tqft/cylinder,
+ },
+ cup/.style={
+ /tikz/tqft,
+ incoming boundary components=1,
+ outgoing boundary components=0
+ },
+ /tikz/tqft cup/.style={
+ /pgf/tqft/cup,
+ },
+ cap/.style={
+ /tikz/tqft,
+ incoming boundary components=0,
+ outgoing boundary components=1
+ },
+ /tikz/tqft cap/.style={
+ /pgf/tqft/cap,
+ },
+}
+% \end{macrocode}
+%
+% \begin{macro}{tqft shape}
+% This is a generic cobordism shape
+% \begin{macrocode}
+\pgfdeclareshape{tqft cobordism}{
+% \end{macrocode}
+% Save our specifications: incoming and outgoing boundary components
+% \begin{macrocode}
+ \savedmacro{\tqft@incoming}{\edef\tqft@incoming{\pgfkeysvalueof{/pgf/tqft/incoming boundary components}}}
+ \savedmacro{\tqft@outgoing}{\edef\tqft@outgoing{\pgfkeysvalueof{/pgf/tqft/outgoing boundary components}}}
+% \end{macrocode}
+% and the offset (in units of boundary components) between the leading incoming and outgoing components (regarded as a shift of the outgoing components relative to the incoming)
+% \begin{macrocode}
+ \savedmacro{\tqft@offset}{\edef\tqft@offset{\pgfkeysvalueof{/pgf/tqft/offset}}}
+% \end{macrocode}
+% Now we save our dimensions: height, separation, the radii of the boundary circles, and outer seps, and the heights of the control points.
+% \begin{macrocode}
+ \saveddimen{\tqft@height}{\pgf@x=\pgfkeysvalueof{/pgf/tqft/cobordism height}}
+ \saveddimen{\tqft@separation}{\pgf@x=\pgfkeysvalueof{/pgf/tqft/boundary separation}}
+ \saveddimen{\tqft@width}{\pgf@x=\pgfkeysvalueof{/pgf/tqft/circle width}}
+ \saveddimen{\tqft@depth}{\pgf@x=\pgfkeysvalueof{/pgf/tqft/circle depth}}
+ \saveddimen{\tqft@outerxsep}{\pgf@x=\pgfkeysvalueof{/pgf/tqft/outer xsep}}
+ \saveddimen{\tqft@outerysep}{\pgf@x=\pgfkeysvalueof{/pgf/tqft/outer ysep}}
+ \saveddimen{\tqft@control}{
+ \pgfkeysgetvalue{/pgf/tqft/cobordism height}{\tqft@tempa}
+ \pgfkeysgetvalue{/pgf/tqft/circle depth}{\tqft@tempb}
+ \pgfmathsetlength{\pgf@x}{.5 * \tqft@tempa - 4 * \tqft@tempb}
+}
+% \end{macrocode}
+% This is the internal transformation that is in place
+% \begin{macrocode}
+ \savedmacro{\tqft@transformation}{%
+ \pgfkeysgetvalue{/pgf/tqft/flow transformation}{\tqft@transformation}
+}
+% \end{macrocode}
+% For the externally available anchors, we need to save a few things as well.
+%
+% Position of first incoming boundary in internal coordinates
+% \begin{macrocode}
+ \savedanchor{\tqft@start@incoming}{%
+ \pgfmathsetlength{\pgf@x}{-(max(\pgfkeysvalueof{/pgf/tqft/incoming boundary components} - 1,\pgfkeysvalueof{/pgf/tqft/outgoing boundary components} - 1 + \pgfkeysvalueof{/pgf/tqft/offset}) + min(0,\pgfkeysvalueof{/pgf/tqft/offset}) )*\pgfkeysvalueof{/pgf/tqft/boundary separation}/2}
+ \pgfmathsetlength{\pgf@y}{.5 * \pgfkeysvalueof{/pgf/tqft/cobordism height}}
+}
+% \end{macrocode}
+% Position of first outgoing boundary in internal coordinates
+% \begin{macrocode}
+ \savedanchor{\tqft@start@outgoing}{%
+ \pgfmathsetlength{\pgf@x}{-(max(\pgfkeysvalueof{/pgf/tqft/incoming boundary components} - 1,\pgfkeysvalueof{/pgf/tqft/outgoing boundary components} - 1 + \pgfkeysvalueof{/pgf/tqft/offset}) + min(0,\pgfkeysvalueof{/pgf/tqft/offset})- 2*\pgfkeysvalueof{/pgf/tqft/offset})*\pgfkeysvalueof{/pgf/tqft/boundary separation}/2}
+ \pgfmathsetlength{\pgf@y}{-.5 * \pgfkeysvalueof{/pgf/tqft/cobordism height}}
+}
+% \end{macrocode}
+% For completeness, we record the size of the text box (not that we expect any text, but you never know)
+% \begin{macrocode}
+\savedanchor{\tqft@textsize}{%
+ \pgf@y=-.5\ht\pgfnodeparttextbox%
+ \pgf@x=-.5\wd\pgfnodeparttextbox%
+}
+% \end{macrocode}
+%
+% These are our externally available anchors
+% \begin{macrocode}
+ \anchor{centre}{\pgfpointorigin}
+ \anchor{center}{\pgfpointorigin}
+\anchor{text}{
+ \tqft@textsize
+}
+\anchor{north}{%
+ \pgf@ya=\tqft@height\relax
+ \pgf@yb=.5\pgf@ya
+ \advance\pgf@yb by \tqft@outerysep\relax
+ \tqft@process{0pt}{\the\pgf@yb}
+}
+\anchor{south}{%
+ \pgf@yb=\tqft@height\relax
+ \pgf@ya=.5\pgf@yb
+ \advance\pgf@ya by \tqft@outerysep\relax
+ \pgf@yb=-\pgf@ya
+ \tqft@process{0pt}{\the\pgf@yb}
+}
+\anchor{west}{%
+ \tqft@start@incoming
+ \pgf@xa=\pgf@x
+ \advance\pgf@xa by -\tqft@width
+ \pgf@ya=\pgf@y
+ \tqft@start@outgoing
+ \pgf@xb=\pgf@x
+ \advance\pgf@xb by -\tqft@width
+ \pgf@yb=\pgf@y
+ \pgf@xc=.5\pgf@xa
+ \advance\pgf@xc by .5\pgf@xb
+ \pgf@yc=.5\pgf@ya
+ \advance\pgf@yc by .5\pgf@yb
+ \advance\pgf@xc by -\tqft@outerxsep\relax
+ \tqft@process{\the\pgf@xc}{\the\pgf@yc}
+}
+\anchor{east}{%
+ \tqft@start@incoming
+ \pgf@xa=\pgf@x
+ \pgfmathsetlength{\pgf@xa}{\pgf@xa + (\tqft@incoming - 1) * \tqft@separation}
+ \advance\pgf@xa by \tqft@width\relax
+ \pgf@ya=\pgf@y
+ \tqft@start@outgoing
+ \pgf@xb=\pgf@x
+ \pgfmathsetlength{\pgf@xb}{\pgf@xb + (\tqft@outgoing - 1) * \tqft@separation}
+ \advance\pgf@xb by \tqft@width\relax
+ \pgf@yb=\pgf@y
+ \pgf@xc=.5\pgf@xa
+ \advance\pgf@xc by .5\pgf@xb
+ \pgf@yc=.5\pgf@ya
+ \advance\pgf@yc by .5\pgf@yb
+ \advance\pgf@xc by \tqft@outerxsep\relax
+ \tqft@process{\the\pgf@xc}{\the\pgf@yc}
+}
+\anchor{north west}{
+ \tqft@start@incoming
+ \pgf@xc=\pgf@x
+ \pgf@yc=\pgf@y
+ \advance\pgf@xc by -\tqft@width\relax
+ \advance\pgf@yc by \tqft@outerysep\relax
+ \advance\pgf@xc by -\tqft@outerxsep\relax
+ \tqft@process{\the\pgf@xc}{\the\pgf@yc}
+}
+\anchor{south west}{
+ \tqft@start@outgoing
+ \pgf@xc=\pgf@x
+ \pgf@yc=\pgf@y
+ \advance\pgf@xc by -\tqft@width\relax
+ \advance\pgf@yc by -\tqft@outerysep\relax
+ \advance\pgf@xc by -\tqft@outerxsep\relax
+ \tqft@process{\the\pgf@xc}{\the\pgf@yc}
+}
+\anchor{north east}{
+ \tqft@start@incoming
+ \pgf@xc=\pgf@x
+ \pgfmathsetlength{\pgf@xc}{\pgf@xc + (\tqft@incoming - 1)*\tqft@separation}
+ \pgf@yc=\pgf@y
+ \advance\pgf@xc by \tqft@width\relax
+ \advance\pgf@yc by \tqft@outerysep\relax
+ \advance\pgf@xc by \tqft@outerxsep\relax
+ \tqft@process{\the\pgf@xc}{\the\pgf@yc}
+}
+\anchor{south east}{
+ \tqft@start@outgoing
+ \pgf@xc=\pgf@x
+ \pgfmathsetlength{\pgf@xc}{\pgf@xc + (\tqft@outgoing - 1)*\tqft@separation}
+ \pgf@yc=\pgf@y
+ \advance\pgf@xc by \tqft@width\relax
+ \advance\pgf@yc by -\tqft@outerysep\relax
+ \advance\pgf@xc by \tqft@outerxsep\relax
+ \tqft@process{\the\pgf@xc}{\the\pgf@yc}
+}
+% \end{macrocode}
+% To define anchors at the boundary components requires a bit of trickery borrowed from the ``regular polygon'' shape.
+% \begin{macrocode}
+\expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@tqft cobordism\endcsname{%
+ \c@pgf@counta\tqft@incoming\relax%
+ \pgfmathloop%
+ \ifnum\c@pgf@counta>0\relax%
+ \pgfutil@ifundefined{pgf@anchor@tqft cobordism@incoming boundary\space\the\c@pgf@counta}{%
+ \expandafter\xdef\csname pgf@anchor@tqft cobordism@incoming boundary\space\the\c@pgf@counta\endcsname{%
+ \noexpand\tqft@start@incoming
+ \noexpand\pgfmathsetlength{\noexpand\pgf@y}{\noexpand\pgf@y + \noexpand\tqft@outerysep}
+ \noexpand\pgfmathsetlength{\noexpand\pgf@x}{\noexpand\pgf@x + (\the\c@pgf@counta - 1) * \noexpand\tqft@separation}
+ \noexpand\tqft@process{\noexpand\the\noexpand\pgf@x}{\noexpand\the\noexpand\pgf@y}
+ }
+ }{\c@pgf@counta0\relax}%
+ \advance\c@pgf@counta-1\relax%
+ \repeatpgfmathloop%
+}
+\expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@tqft cobordism\endcsname{%
+ \c@pgf@counta\tqft@outgoing\relax%
+ \pgfmathloop%
+ \ifnum\c@pgf@counta>0\relax%
+ \pgfutil@ifundefined{pgf@anchor@tqft cobordism@outgoing boundary\space\the\c@pgf@counta}{%
+ \expandafter\xdef\csname pgf@anchor@tqft cobordism@outgoing boundary\space\the\c@pgf@counta\endcsname{%
+ \noexpand\tqft@start@outgoing
+ \noexpand\pgfmathsetlength{\noexpand\pgf@y}{\noexpand\pgf@y - \noexpand\tqft@outerysep}
+ \noexpand\pgfmathsetlength{\noexpand\pgf@x}{\noexpand\pgf@x + (\the\c@pgf@counta - 1) * \noexpand\tqft@separation}
+ \noexpand\tqft@process{\noexpand\the\noexpand\pgf@x}{\noexpand\the\noexpand\pgf@y}
+ }
+ }{\c@pgf@counta0\relax}%
+ \advance\c@pgf@counta-1\relax%
+ \repeatpgfmathloop%
+}
+\expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@tqft cobordism\endcsname{%
+ \c@pgf@counta\tqft@incoming\relax%
+ \advance\c@pgf@counta-1\relax
+ \pgfmathloop%
+ \ifnum\c@pgf@counta>0\relax%
+ \pgfutil@ifundefined{pgf@anchor@tqft cobordism@after incoming boundary\space\the\c@pgf@counta}{%
+ \expandafter\xdef\csname pgf@anchor@tqft cobordism@after incoming boundary\space\the\c@pgf@counta\endcsname{%
+ \noexpand\tqft@start@incoming
+ \noexpand\pgfmathsetlength{\noexpand\pgf@y}{.25 * \noexpand\pgf@y +.75 * \noexpand\tqft@control + \noexpand\tqft@outerysep}
+ \noexpand\pgfmathsetlength{\noexpand\pgf@x}{\noexpand\pgf@x + (\the\c@pgf@counta - .5) * \noexpand\tqft@separation}
+ \noexpand\tqft@process{\noexpand\the\noexpand\pgf@x}{\noexpand\the\noexpand\pgf@y}
+ }
+ }{\c@pgf@counta0\relax}%
+ \advance\c@pgf@counta-1\relax%
+ \repeatpgfmathloop%
+}
+\expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@tqft cobordism\endcsname{%
+ \c@pgf@counta\tqft@outgoing\relax%
+ \advance\c@pgf@counta-1\relax
+ \pgfmathloop%
+ \ifnum\c@pgf@counta>0\relax%
+ \pgfutil@ifundefined{pgf@anchor@tqft cobordism@after outgoing boundary\space\the\c@pgf@counta}{%
+ \expandafter\xdef\csname pgf@anchor@tqft cobordism@after outgoing boundary\space\the\c@pgf@counta\endcsname{%
+ \noexpand\tqft@start@outgoing
+ \noexpand\pgfmathsetlength{\noexpand\pgf@y}{.25 * \noexpand\pgf@y -.75 * \noexpand\tqft@control - \noexpand\tqft@outerysep}
+ \noexpand\pgfmathsetlength{\noexpand\pgf@x}{\noexpand\pgf@x + (\the\c@pgf@counta - .5) * \noexpand\tqft@separation}
+ \noexpand\tqft@process{\noexpand\the\noexpand\pgf@x}{\noexpand\the\noexpand\pgf@y}
+ }
+ }{\c@pgf@counta0\relax}%
+ \advance\c@pgf@counta-1\relax%
+ \repeatpgfmathloop%
+}
+% \end{macrocode}
+% Now we define the background path.
+% This is the upper part of the cobordism.
+% \begin{macrocode}
+ \backgroundpath{
+% \end{macrocode}
+% Apply the internal transformation
+% \begin{macrocode}
+ \let\tikz@transform=\pgfutil@empty
+ \expandafter\tikzset\expandafter{\tqft@transformation}
+ \tikz@transform
+% \end{macrocode}
+% Convert the boundary separation and width to lengths
+% \begin{macrocode}
+ \pgfmathsetlength{\tqft@s}{\tqft@separation}
+ \pgfmathsetlength{\tqft@w}{2*\tqft@width}
+% \end{macrocode}
+% Compute the starting position of the incoming boundary components so that we get the centre anchor on the centre of the cobordism
+% \begin{macrocode}
+\tqft@start@incoming
+\tqft@xa=\pgf@x
+ \advance\tqft@xa by -.5\tqft@w\relax
+\tqft@h=\pgf@y
+ \tqft@xb=\tqft@xa
+ \advance\tqft@xb by \tqft@w\relax
+\tqft@c=\tqft@control\relax
+% \end{macrocode}
+% Do we have any incoming boundary components at all?
+% \begin{macrocode}
+ \ifnum\tqft@incoming>0
+% \end{macrocode}
+% Yes, so move to the position of the first and draw it
+% \begin{macrocode}
+ \pgfpathmoveto{\pgfqpoint{\tqft@xa}{\tqft@h}}
+ \pgfpatharc{\pgf@tqft@upper180}{0}{\tqft@width and \tqft@depth}
+% \end{macrocode}
+% Do we have any more incoming boundary components?
+% \begin{macrocode}
+ \ifnum\tqft@incoming>1
+% \end{macrocode}
+% Yes, so iterate over the remaining incoming boundary components
+% \begin{macrocode}
+ \foreach \tqft@k in {2,...,\tqft@incoming} {
+ \advance\tqft@xa by \tqft@k\tqft@s
+ \advance\tqft@xb by \tqft@k\tqft@s
+ \advance\tqft@xb by -2\tqft@s
+ \advance\tqft@xa by -\tqft@s
+ \pgfpathcurveto{\pgfqpoint{\tqft@xb}{\tqft@c}}{\pgfqpoint{\tqft@xa}{\tqft@c}}{\pgfqpoint{\tqft@xa}{\tqft@h}}
+ \pgfpatharc{\pgf@tqft@upper180}{0}{\tqft@width and \tqft@depth}
+ }
+ \fi
+% \end{macrocode}
+% If we don't have any outgoing boundary components, may as well close up now.
+% \begin{macrocode}
+ \ifnum\tqft@outgoing=0
+ \advance\tqft@xb by \tqft@incoming\tqft@s
+ \advance\tqft@xb by -\tqft@s
+ \pgfmathsetlength{\tqft@ch}{min(0,max(-\tqft@h,\tqft@h - (\tqft@h - \tqft@c) * ((abs(\tqft@xb - \tqft@xa) - \tqft@w)/\tqft@s + 1)))}
+ \pgfpathcurveto{\pgfqpoint{\tqft@xb}{\tqft@ch}}{\pgfqpoint{\tqft@xa}{\tqft@ch}}{\pgfqpoint{\tqft@xa}{\tqft@h}}
+ \fi
+ \fi
+% \end{macrocode}
+% Shift down to the outgoing components, if we have any
+% \begin{macrocode}
+ \ifnum\tqft@outgoing>0
+ \advance\tqft@xb by \tqft@incoming\tqft@s
+ \advance\tqft@xb by -\tqft@s
+ \pgfmathsetlength{\tqft@xa}{\tqft@xa + (\tqft@outgoing - 1 + \tqft@offset) * \tqft@separation + 2*\tqft@width}
+% \end{macrocode}
+% If we had incoming boundaries, this is a curveto, otherwise it's a moveto
+% \begin{macrocode}
+ \ifnum\tqft@incoming>0
+ \pgfmathsetlength{\tqft@ch}{min(0,max(-\tqft@h,\tqft@h - (\tqft@h - \tqft@c) * ((abs(\tqft@xb - \tqft@xa) - \tqft@w)/\tqft@s + 1)))}
+ \pgfpathcurveto{\pgfqpoint{\tqft@xb}{\tqft@ch}}{\pgfqpoint{\tqft@xa}{-\tqft@ch}}{\pgfqpoint{\tqft@xa}{-\tqft@h}}
+ \else
+ \pgfpathmoveto{\pgfqpoint{\tqft@xa}{-\tqft@h}}
+ \fi
+ \tqft@xb=\tqft@xa
+ \advance\tqft@xb by -\tqft@w
+% \end{macrocode}
+% Now draw the lower components
+% \begin{macrocode}
+ \pgfpatharc{0}{\pgf@tqft@upper180}{\tqft@width and \tqft@depth}
+% \end{macrocode}
+% Now iterate over the remaining outgoing boundary components
+% \begin{macrocode}
+ \ifnum\tqft@outgoing>1
+ \foreach \tqft@k in {2,...,\tqft@outgoing} {
+ \advance\tqft@xa by -\tqft@k\tqft@s
+ \advance\tqft@xb by -\tqft@k\tqft@s
+ \advance\tqft@xb by 2\tqft@s
+ \advance\tqft@xa by \tqft@s
+ \pgfpathcurveto{\pgfqpoint{\tqft@xb}{-\tqft@c}}{\pgfqpoint{\tqft@xa}{-\tqft@c}}{\pgfqpoint{\tqft@xa}{-\tqft@h}}
+ \pgfpatharc{0}{\pgf@tqft@upper180}{\tqft@width and \tqft@depth}
+ }
+ \fi
+% \end{macrocode}
+% Shift back up to the incoming components, if we had any, otherwise arc back to our starting point
+% \begin{macrocode}
+ \advance\tqft@xb by -\tqft@outgoing\tqft@s
+ \advance\tqft@xb by \tqft@s
+ \ifnum\tqft@incoming>0
+ \pgfmathsetlength{\tqft@xa}{\tqft@xa - (\tqft@outgoing -1 + \tqft@offset) * \tqft@separation - 2*\tqft@width}
+ \pgfmathsetlength{\tqft@ch}{min(0,max(-\tqft@h,\tqft@h - (\tqft@h - \tqft@c) * ((abs(\tqft@xb - \tqft@xa) - \tqft@w)/\tqft@s + 1)))}
+ \pgfpathcurveto{\pgfqpoint{\tqft@xb}{-\tqft@ch}}{\pgfqpoint{\tqft@xa}{\tqft@ch}}{\pgfqpoint{\tqft@xa}{\tqft@h}}
+ \else
+ \pgfmathsetlength{\tqft@ch}{min(0,max(-\tqft@h,\tqft@h - (\tqft@h - \tqft@c) * ((abs(\tqft@xb - \tqft@xa) - \tqft@w)/\tqft@s + 1)))}
+ \pgfpathcurveto{\pgfqpoint{\tqft@xb}{-\tqft@ch}}{\pgfqpoint{\tqft@xa}{-\tqft@ch}}{\pgfqpoint{\tqft@xa}{-\tqft@h}}
+ \fi
+ \fi
+% \end{macrocode}
+% Close the path
+% \begin{macrocode}
+ \pgfpathclose
+ }
+% \end{macrocode}
+% End of background path
+% Now we define the behind background path.
+% This is the lower part of the boundary circles.
+% \begin{macrocode}
+ \behindbackgroundpath{
+% \end{macrocode}
+% Apply the internal transformation
+% \begin{macrocode}
+ \let\tikz@transform=\pgfutil@empty
+ \expandafter\tikzset\expandafter{\tqft@transformation}
+ \tikz@transform
+% \end{macrocode}
+% Convert the boundary separation and width to lengths
+% \begin{macrocode}
+ \pgfmathsetlength{\tqft@s}{\tqft@separation}
+ \pgfmathsetlength{\tqft@w}{2*\tqft@width}
+% \end{macrocode}
+% Compute the starting position of the incoming boundary components so that we get the centre anchor on the centre of the cobordism
+% \begin{macrocode}
+ \pgfmathsetlength{\tqft@xa}{-(max(\tqft@incoming - 1,\tqft@outgoing - 1 + \tqft@offset) + min(0,\tqft@offset) + 2)*\tqft@separation/2}
+ \pgfmathsetlength{\tqft@h}{.5 * \tqft@height}
+% \end{macrocode}
+% This section draws the boundary circles
+% \begin{macrocode}
+ {
+% \end{macrocode}
+% Initialise the TikZ path settings and read in the style options for the boundary
+% \begin{macrocode}
+ \tikz@mode@fillfalse%
+ \tikz@mode@drawfalse%
+ \let\tikz@mode=\pgfutil@empty
+ \let\tikz@options=\pgfutil@empty
+ \tqftset{boundary style contents}
+ \tikz@mode
+ \tikz@options
+% \end{macrocode}
+% Do we have any incoming boundary components at all?
+% \begin{macrocode}
+ \ifnum\tqft@incoming>0
+% \end{macrocode}
+% Yes, so iterate over them
+% \begin{macrocode}
+ \foreach \tqft@k in {1,...,\tqft@incoming} {
+ \advance\tqft@xa by \tqft@k\tqft@s
+ \pgfpathellipse{\pgfqpoint{\tqft@xa}{\tqft@h}}{\pgfqpoint{\tqft@width}{0pt}}{\pgfqpoint{0pt}{\tqft@depth}}
+ }
+ \fi
+% \end{macrocode}
+% Now iterate over the outgoing boundary components, if we have any
+% \begin{macrocode}
+ \ifnum\tqft@outgoing>0
+ \pgfmathsetlength{\tqft@xa}{\tqft@xa + (\tqft@outgoing + \tqft@offset + 1) * \tqft@separation}
+ \foreach \tqft@k in {1,...,\tqft@outgoing} {
+ \advance\tqft@xa by -\tqft@k\tqft@s
+% \advance\tqft@xa by \tqft@s
+ \pgfpathellipse{\pgfqpoint{\tqft@xa}{-\tqft@h}}{\pgfqpoint{\tqft@width}{0pt}}{\pgfqpoint{0pt}{\tqft@depth}}
+ }
+ \fi
+% \end{macrocode}
+% \begin{macrocode}
+ \edef\tikz@temp{\noexpand\pgfusepath{%
+ \iftikz@mode@fill fill,\fi%
+ \iftikz@mode@draw draw\fi%
+ }}%
+ \tikz@temp
+ }
+% \end{macrocode}
+% This section draws the lower parts of the boundary circles
+% \begin{macrocode}
+ {
+% \end{macrocode}
+% Initialise the TikZ path settings and read in the style options for the boundary
+% \begin{macrocode}
+ \tikz@mode@fillfalse%
+ \tikz@mode@drawfalse%
+ \let\tikz@mode=\pgfutil@empty
+ \let\tikz@options=\pgfutil@empty
+ \tqftset{boundary lower style contents}
+ \tikz@mode
+ \tikz@options
+ \advance\tqft@xa by .5\tqft@w
+% \end{macrocode}
+% Do we have any incoming boundary components at all?
+% \begin{macrocode}
+ \ifnum\tqft@incoming>0
+% \end{macrocode}
+% Yes, so iterate over them
+% \begin{macrocode}
+ \foreach \tqft@k in {1,...,\tqft@incoming} {
+ \advance\tqft@xa by \tqft@k\tqft@s
+ \pgfpathmoveto{\pgfqpoint{\tqft@xa}{\tqft@h}}
+ \pgfpatharc{0}{\pgf@tqft@lower180}{\tqft@width and \tqft@depth}
+ }
+ \fi
+% \end{macrocode}
+% Now iterate over the outgoing boundary components, if we have any
+% \begin{macrocode}
+ \ifnum\tqft@outgoing>0
+ \pgfmathsetlength{\tqft@xa}{\tqft@xa + (\tqft@outgoing + \tqft@offset + 1) * \tqft@separation}
+ \foreach \tqft@k in {1,...,\tqft@outgoing} {
+ \advance\tqft@xa by -\tqft@k\tqft@s
+% \advance\tqft@xa by \tqft@s
+ \pgfpathmoveto{\pgfqpoint{\tqft@xa}{-\tqft@h}}
+ \pgfpatharc{0}{\pgf@tqft@lower180}{\tqft@width and \tqft@depth}
+ }
+ \fi
+% \end{macrocode}
+% \begin{macrocode}
+ \edef\tikz@temp{\noexpand\pgfusepath{%
+ \iftikz@mode@fill fill,\fi%
+ \iftikz@mode@draw draw\fi%
+ }}%
+ \tikz@temp
+ }
+ }
+% \end{macrocode}
+% End of behind background path.
+%
+% Now we define the before background path.
+% This is the upper part of the boundary circles and the cobordism edge.
+% \begin{macrocode}
+ \beforebackgroundpath{
+% \end{macrocode}
+% We \emph{don't} apply the internal transformation as it is already in place from the \Verb+\backgroundpath+.
+% Convert the boundary separation and width to lengths
+% \begin{macrocode}
+ \pgfmathsetlength{\tqft@s}{\tqft@separation}
+ \pgfmathsetlength{\tqft@w}{2*\tqft@width}
+% \end{macrocode}
+% Compute the starting position of the incoming boundary components so that we get the centre anchor on the centre of the cobordism
+% \begin{macrocode}
+ \pgfmathsetlength{\tqft@xa}{-(max(\tqft@incoming - 1,\tqft@outgoing - 1 + \tqft@offset) + min(0,\tqft@offset))*\tqft@s/2 - \tqft@width}
+ \tqft@xb=\tqft@xa
+ \advance\tqft@xb by \tqft@w
+\tqft@c=\tqft@control\relax
+ \pgfmathsetlength{\tqft@h}{.5 * \tqft@height}
+% \end{macrocode}
+% This section draws the non-boundary part of the cobordism.
+% \begin{macrocode}
+ {
+% \end{macrocode}
+% Initialise the TikZ path settings and read in the style options for the boundary
+% \begin{macrocode}
+ \tikz@mode@fillfalse%
+ \tikz@mode@drawfalse%
+ \let\tikz@mode=\pgfutil@empty
+ \let\tikz@options=\pgfutil@empty
+ \tqftset{cobordism style contents}
+ \tikz@mode
+ \tikz@options
+% Do we have any incoming boundary components at all?
+% \begin{macrocode}
+ \ifnum\tqft@incoming>0
+% \end{macrocode}
+% Do we have more than one?
+% \begin{macrocode}
+ \ifnum\tqft@incoming>1
+% \end{macrocode}
+% Yes, so iterate over the remaining incoming boundary components
+% \begin{macrocode}
+ \foreach \tqft@k in {2,...,\tqft@incoming} {
+ \advance\tqft@xa by \tqft@k\tqft@s
+ \advance\tqft@xb by \tqft@k\tqft@s
+ \advance\tqft@xb by -2\tqft@s
+ \advance\tqft@xa by -\tqft@s
+ \pgfpathmoveto{\pgfqpoint{\tqft@xb}{\tqft@h}}
+ \pgfpathcurveto{\pgfqpoint{\tqft@xb}{\tqft@c}}{\pgfqpoint{\tqft@xa}{\tqft@c}}{\pgfqpoint{\tqft@xa}{\tqft@h}}
+ }
+ \fi
+% \end{macrocode}
+% If we don't have any outgoing boundary components, may as well close up now.
+% \begin{macrocode}
+ \ifnum\tqft@outgoing=0
+ \advance\tqft@xb by \tqft@incoming\tqft@s
+ \advance\tqft@xb by -\tqft@s
+ \pgfmathsetlength{\tqft@ch}{min(0,max(-\tqft@h,\tqft@h - (\tqft@h - \tqft@c) * ((abs(\tqft@xb - \tqft@xa) - \tqft@w)/\tqft@s + 1)))}
+ \pgfpathmoveto{\pgfqpoint{\tqft@xb}{\tqft@h}}
+ \pgfpathcurveto{\pgfqpoint{\tqft@xb}{\tqft@ch}}{\pgfqpoint{\tqft@xa}{\tqft@ch}}{\pgfqpoint{\tqft@xa}{\tqft@h}}
+ \fi
+ \fi
+% \end{macrocode}
+% Shift down to the outgoing components, if we have any
+% \begin{macrocode}
+ \ifnum\tqft@outgoing>0
+ \advance\tqft@xb by \tqft@incoming\tqft@s
+ \advance\tqft@xb by -\tqft@s
+ \pgfmathsetlength{\tqft@xa}{\tqft@xa + (\tqft@outgoing - 1 + \tqft@offset) * \tqft@separation + 2*\tqft@width}
+% \end{macrocode}
+% If we had incoming boundaries, this is a curveto, otherwise it's a moveto
+% \begin{macrocode}
+ \ifnum\tqft@incoming>0
+ \pgfmathsetlength{\tqft@ch}{min(0,max(-\tqft@h,\tqft@h - (\tqft@h - \tqft@c) * ((abs(\tqft@xb - \tqft@xa) - \tqft@w)/\tqft@s + 1)))}
+ \pgfpathmoveto{\pgfqpoint{\tqft@xb}{\tqft@h}}
+ \pgfpathcurveto{\pgfqpoint{\tqft@xb}{\tqft@ch}}{\pgfqpoint{\tqft@xa}{-\tqft@ch}}{\pgfqpoint{\tqft@xa}{-\tqft@h}}
+ \else
+ \pgfpathmoveto{\pgfqpoint{\tqft@xa}{-\tqft@h}}
+ \fi
+ \tqft@xb=\tqft@xa
+ \advance\tqft@xb by -\tqft@w
+% \end{macrocode}
+% Now draw the lower components
+% \begin{macrocode}
+ \pgfpathmoveto{\pgfqpoint{\tqft@xb}{-\tqft@h}}
+% \end{macrocode}
+% Now iterate over the remaining outgoing boundary components
+% \begin{macrocode}
+ \ifnum\tqft@outgoing>1
+ \foreach \tqft@k in {2,...,\tqft@outgoing} {
+ \advance\tqft@xa by -\tqft@k\tqft@s
+ \advance\tqft@xb by -\tqft@k\tqft@s
+ \advance\tqft@xb by 2\tqft@s
+ \advance\tqft@xa by \tqft@s
+ \pgfpathcurveto{\pgfqpoint{\tqft@xb}{-\tqft@c}}{\pgfqpoint{\tqft@xa}{-\tqft@c}}{\pgfqpoint{\tqft@xa}{-\tqft@h}}
+ \advance\tqft@xa by -\tqft@w
+ \pgfpathmoveto{\pgfqpoint{\tqft@xa}{-\tqft@h}}
+ }
+ \fi
+% \end{macrocode}
+% Shift back up to the incoming components, if we had any, otherwise arc back to our starting point
+% \begin{macrocode}
+ \advance\tqft@xb by -\tqft@outgoing\tqft@s
+ \advance\tqft@xb by \tqft@s
+ \ifnum\tqft@incoming>0
+ \pgfmathsetlength{\tqft@xa}{\tqft@xa - (\tqft@outgoing -1 + \tqft@offset) * \tqft@separation - 2*\tqft@width}
+ \pgfmathsetlength{\tqft@ch}{min(0,max(-\tqft@h,\tqft@h - (\tqft@h - \tqft@c) * ((abs(\tqft@xb - \tqft@xa) - \tqft@w)/\tqft@s + 1)))}
+ \pgfpathcurveto{\pgfqpoint{\tqft@xb}{-\tqft@ch}}{\pgfqpoint{\tqft@xa}{\tqft@ch}}{\pgfqpoint{\tqft@xa}{\tqft@h}}
+ \else
+ \pgfmathsetlength{\tqft@ch}{min(0,max(-\tqft@h,\tqft@h - (\tqft@h - \tqft@c) * ((abs(\tqft@xb - \tqft@xa) - \tqft@w)/\tqft@s + 1)))}
+ \pgfpathcurveto{\pgfqpoint{\tqft@xb}{-\tqft@ch}}{\pgfqpoint{\tqft@xa}{-\tqft@ch}}{\pgfqpoint{\tqft@xa}{-\tqft@h}}
+ \fi
+ \fi
+ \edef\tikz@temp{\noexpand\pgfusepath{%
+ \iftikz@mode@fill fill,\fi%
+ \iftikz@mode@draw draw\fi%
+ }}%
+ \tikz@temp
+}
+% \end{macrocode}
+% This section draws the upper parts of the boundary circles
+% \begin{macrocode}
+ {
+% \end{macrocode}
+% Initialise the TikZ path settings and read in the style options for the boundary
+% \begin{macrocode}
+\let\tqft@bdry@path=\pgfutil@empty
+\let\tqft@bdry@node@path=\pgfutil@empty
+\pgfsyssoftpath@setcurrentpath{\tqft@bdry@path}
+ \tikz@mode@fillfalse%
+ \tikz@mode@drawfalse%
+ \let\tikz@mode=\pgfutil@empty
+ \let\tikz@options=\pgfutil@empty
+ \tqftset{boundary upper style contents}
+ \tikz@mode
+ \tikz@options
+ \advance\tqft@xa by -\tqft@s
+ \advance\tqft@xa by \tqft@w
+% \end{macrocode}
+% Do we have any incoming boundary components at all?
+% \begin{macrocode}
+ \ifnum\tqft@incoming>0
+% \end{macrocode}
+% Yes, so iterate over them
+% \begin{macrocode}
+ \foreach \tqft@k in {1,...,\tqft@incoming} {
+ \advance\tqft@xa by \tqft@k\tqft@s
+ \pgfpathmoveto{\pgfqpoint{\tqft@xa}{\tqft@h}}
+ \pgfpatharc{0}{\pgf@tqft@upper180}{\tqft@width and \tqft@depth}
+ \ifx\tikz@fig@name\pgfutil@empty
+ \else
+ {
+ \advance\tqft@xa by -\tqft@width
+ \pgftransformshift{\pgfqpoint{\tqft@xa}{\tqft@h}}
+ \tqft@within@nodetrue
+ \pgfsyssoftpath@getcurrentpath{\tqft@bdry@path}
+ \pgfsyssoftpath@setcurrentpath{\tqft@bdry@node@path}
+ \pgfnode{tqft boundary circle}{centre}{}{\tikz@fig@name\space incoming \tqft@k}{}
+ \pgfsyssoftpath@getcurrentpath{\tqft@bdry@node@path}
+ \pgfsyssoftpath@setcurrentpath{\tqft@bdry@path}
+ }
+ \fi
+ }
+ \fi
+% \end{macrocode}
+% Now iterate over the outgoing boundary components, if we have any
+% \begin{macrocode}
+ \ifnum\tqft@outgoing>0
+ \pgfmathsetlength{\tqft@xa}{\tqft@xa + (\tqft@outgoing + \tqft@offset + 1) * \tqft@separation}
+ \foreach \tqft@k in {1,...,\tqft@outgoing} {
+ \advance\tqft@xa by -\tqft@k\tqft@s
+% \advance\tqft@xa by \tqft@s
+ \pgfpathmoveto{\pgfqpoint{\tqft@xa}{-\tqft@h}}
+ \pgfpatharc{0}{\pgf@tqft@upper180}{\tqft@width and \tqft@depth}
+ \ifx\tikz@fig@name\pgfutil@empty
+ \else
+ {
+ \pgfmathtruncatemacro{\tqft@l}{\tqft@outgoing + 1 - \tqft@k}
+ \advance\tqft@xa by -\tqft@width
+ \pgftransformshift{\pgfqpoint{\tqft@xa}{-\tqft@h}}
+ \tqft@within@nodetrue
+ \pgfsyssoftpath@getcurrentpath{\tqft@bdry@path}
+ \pgfsyssoftpath@setcurrentpath{\tqft@bdry@node@path}
+ \pgfnode{tqft boundary circle}{centre}{}{\tikz@fig@name\space outgoing \tqft@l}{}
+ \pgfsyssoftpath@getcurrentpath{\tqft@bdry@node@path}
+ \pgfsyssoftpath@setcurrentpath{\tqft@bdry@path}
+ }
+ \fi
+ }
+ \fi
+% \end{macrocode}
+% \begin{macrocode}
+ \edef\tikz@temp{\noexpand\pgfusepath{%
+ \iftikz@mode@fill fill,\fi%
+ \iftikz@mode@draw draw\fi%
+ }}%
+ \tikz@temp
+ }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{boundary circle shape}
+% This is a the shape of the boundary circles
+% \begin{macrocode}
+\pgfdeclareshape{tqft boundary circle}{
+% \end{macrocode}
+% Now we save our dimensions: height, separation, and the radii of the boundary circles
+% \begin{macrocode}
+ \saveddimen{\tqft@height}{\pgf@x=\pgfkeysvalueof{/pgf/tqft/cobordism height}}
+ \saveddimen{\tqft@separation}{\pgf@x=\pgfkeysvalueof{/pgf/tqft/boundary separation}}
+ \saveddimen{\tqft@width}{\pgf@x=\pgfkeysvalueof{/pgf/tqft/circle width}}
+ \saveddimen{\tqft@depth}{\pgf@x=\pgfkeysvalueof{/pgf/tqft/circle depth}}
+% \end{macrocode}
+%
+% For the externally available anchors, we need to save the declared transformation; we save the actual transformation, not the macro that points to it.
+% If we're called within the main cobordism shape, the transformation is already applied so we ignore it.
+% \begin{macrocode}
+ \savedmacro{\tqft@transformation}{%
+ \iftqft@within@node
+ \let\tqft@transformation=\pgfutil@empty
+ \else
+ \pgfkeysgetvalue{/pgf/tqft/flow transformation}{\tqft@transformation}
+ \fi
+}
+% \end{macrocode}
+% \begin{macrocode}
+ \savedanchor{\tqft@centre}{%
+ \pgfpointorigin}
+% \end{macrocode}
+% For completeness, we record the size of the text box (not that we expect any text, but you never know)
+% \begin{macrocode}
+\savedanchor{\tqft@textsize}{%
+ \pgf@y=-.5\ht\pgfnodeparttextbox%
+ \pgf@x=-.5\wd\pgfnodeparttextbox%
+}
+% \end{macrocode}
+% These are our externally available anchors
+% \begin{macrocode}
+ \anchor{centre}{\tqft@centre}
+ \anchor{center}{\tqft@centre}
+\anchor{text}{
+ \tqft@textsize
+}
+ \anchor{next}{%
+ \tqft@process{\tqft@separation}{0pt}}%
+% \end{macrocode}
+% \begin{macrocode}
+ \anchor{prior}{%
+ \tqft@process{-\tqft@separation}{0pt}}%
+% \end{macrocode}
+% \begin{macrocode}
+ \anchor{above}{%
+ \tqft@process{0pt}{\tqft@height}}%
+% \end{macrocode}
+% \begin{macrocode}
+ \anchor{below}{%
+ \tqft@process{0pt}{-\tqft@height}}%
+% \end{macrocode}
+% The anchor border is the ellipse, but we need to take into account the possible transformation.
+% (This isn't right if the origin is shifted.)
+% At the moment, '0 degrees' is interpreted in the transformed coordinate system.
+% Should provide a system whereby that can be intepreted in the main coordinate system.
+% \begin{macrocode}
+ \anchorborder{
+% \end{macrocode}
+% This next \Verb+\pgf@process+ makes the angles absolute.
+% Comment it out to make the angles relative.
+% \begin{macrocode}
+ \tqft@process{\the\pgf@x}{\the\pgf@y}
+ \edef\tqft@marshal{%
+ \noexpand\pgfpointborderellipse
+ {\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}
+ {\noexpand\pgfqpoint{\tqft@width}{\tqft@depth}}
+ }%
+ \tqft@marshal
+ \tqft@process{\the\pgf@x}{\the\pgf@y}
+}
+% \end{macrocode}
+% Now we define the background path.
+% This is the upper part of the cobordism.
+% \begin{macrocode}
+ \backgroundpath{
+% \end{macrocode}
+% Apply the internal transformation if we're not within a node
+% \begin{macrocode}
+ \let\tikz@transform=\pgfutil@empty
+ \expandafter\tikzset\expandafter{\tqft@transformation}
+ \tikz@transform
+% \end{macrocode}
+% Draw the boundary circle
+% \begin{macrocode}
+ \pgfpathellipse{\pgfqpoint{0pt}{0pt}}{\pgfqpoint{\tqft@width}{0pt}}{\pgfqpoint{0pt}{\tqft@depth}}
+ }
+% \end{macrocode}
+% We draw the upper and lower arcs again with the appropriate styles
+% \begin{macrocode}
+ \beforebackgroundpath{
+ \iftqft@within@node
+ \else
+ \tikz@mode@fillfalse%
+ \tikz@mode@drawfalse%
+ \let\tikz@mode=\pgfutil@empty
+ \let\tikz@options=\pgfutil@empty
+ {
+ \pgfsys@beginscope
+ \tqftset{boundary lower style contents}
+ \tikz@mode
+ \tikz@options
+ \pgfpathmoveto{\pgfqpoint{\tqft@width}{0pt}}
+ \pgfpatharc{0}{\pgf@tqft@lower180}{\tqft@width and \tqft@depth}
+ \edef\tikz@temp{\noexpand\pgfusepath{%
+ \iftikz@mode@fill fill,\fi%
+ \iftikz@mode@draw draw\fi%
+ }}%
+ \tikz@temp
+ \pgfsys@endscope
+ }
+ {
+ \pgfsys@beginscope
+ \tqftset{boundary upper style contents}
+ \tikz@mode
+ \tikz@options
+ \pgfpathmoveto{\pgfqpoint{\tqft@width}{0pt}}
+ \pgfpatharc{0}{\pgf@tqft@upper180}{\tqft@width and \tqft@depth}
+ \edef\tikz@temp{\noexpand\pgfusepath{%
+ \iftikz@mode@fill fill,\fi%
+ \iftikz@mode@draw draw\fi%
+ }}%
+ \tikz@temp
+ \pgfsys@endscope
+ }
+ \fi
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \iffalse
+%</package>
+% \fi
+%
+% \Finale
+
+\endinput