diff options
author | Karl Berry <karl@freefriends.org> | 2019-05-08 21:15:00 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2019-05-08 21:15:00 +0000 |
commit | 78b1605f1f5a0899ce94e74a533fe20e7a2ae747 (patch) | |
tree | d0d7e9e8d1d7cb53860f975a5d564f8e0fcbe3bf /Master/texmf-dist | |
parent | 3de6683607c3042def19b77ca8a338814d0a1575 (diff) |
braids (8may19)
git-svn-id: svn://tug.org/texlive/trunk@51048 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist')
-rw-r--r-- | Master/texmf-dist/doc/latex/braids/README.txt (renamed from Master/texmf-dist/doc/latex/braids/README) | 3 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/braids/braids.pdf | bin | 0 -> 314455 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/latex/braids/braids.tex | 481 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/braids/braids_code.pdf | bin | 0 -> 410835 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/latex/braids/braids_doc.pdf | bin | 281058 -> 0 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/latex/braids/braids_doc.tex | 178 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/braids/braids.dtx | 946 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/braids/braids_code.dtx | 2321 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/braids/braids_code.ins | 83 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/braids/braids.sty | 296 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/braids/tikzlibrarybraids.code.tex | 916 |
11 files changed, 4044 insertions, 1180 deletions
diff --git a/Master/texmf-dist/doc/latex/braids/README b/Master/texmf-dist/doc/latex/braids/README.txt index 65583665cbb..84a8e7c0107 100644 --- a/Master/texmf-dist/doc/latex/braids/README +++ b/Master/texmf-dist/doc/latex/braids/README.txt @@ -1,11 +1,10 @@ ---------------------------------------------------------------- braids --- a style file for drawing braid diagrams with TikZ/PGF -E-mail: stacey@math.ntnu.no +E-mail: loopspace@mathforge.org 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. diff --git a/Master/texmf-dist/doc/latex/braids/braids.pdf b/Master/texmf-dist/doc/latex/braids/braids.pdf Binary files differnew file mode 100644 index 00000000000..5241cd38eec --- /dev/null +++ b/Master/texmf-dist/doc/latex/braids/braids.pdf diff --git a/Master/texmf-dist/doc/latex/braids/braids.tex b/Master/texmf-dist/doc/latex/braids/braids.tex new file mode 100644 index 00000000000..7dab9f08738 --- /dev/null +++ b/Master/texmf-dist/doc/latex/braids/braids.tex @@ -0,0 +1,481 @@ +\documentclass{ltxdoc} +\usepackage[T1]{fontenc} +\usepackage{lmodern} +\usepackage{morefloats} +\usepackage{tikz} +\usepackage{braids} +\usetikzlibrary{braids} +\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} + +\newenvironment{example} + {\VerbatimEnvironment + \begin{VerbatimOut}{example.out}} + {\end{VerbatimOut} + \begin{center} + \setlength{\parindent}{0pt} + \fbox{\begin{minipage}{.9\linewidth} + \lstset{breakatwhitespace=true,breaklines=true,language=TeX,basicstyle=\small} + \lstinputlisting[]{example.out} + \end{minipage}} + + \fbox{\begin{minipage}{.9\linewidth} + \input{example.out} + \end{minipage}} +\end{center} +} + +\providecommand*{\url}{\texttt} +\GetFileInfo{tikzlibrarybraids.code.tex} + +\title{The \textsf{braids} Package: Documentation} +\author{Andrew Stacey \\ \texttt{loopspace@mathforge.org}} +\date{\fileversion~from \filedate} + +\begin{document} + +\maketitle + +\begin{center} + \begin{tikzpicture} + \pic[ + line width=1.5pt, + red, + line cap=round, + braid/.cd, + width=.75cm, + height=.5cm, + strand 3/.style={gray,line width=1pt}, + strand 6/.style={gray,line width=1pt}, + strand 7/.style={gray,line width=1pt}, + strand 10/.style={gray,line width=1pt}, + strand 14/.style={gray,line width=1pt}, + strand 15/.style={gray,line width=1pt}, + strand 16/.style={gray,line width=1pt}, + strand 18/.style={gray,line width=1pt}, + ] {braid={s_1-s_4-s_8-s_{12}-s_{16} s_2-s_5-s_7-s_9-s_{13}-s_{15} s_2-s_5-s_7-s_9-s_{15} s_1-s_4-s_8-s_{16} s_1-s_4-s_7-s_9-s_{17} s_2-s_5-s_{17} s_2-s_{13}-s_{16} s_1-s_{12}-s_{15}}}; +\end{tikzpicture} +\end{center} + +\section{Introduction} + +This is a package for drawing braid diagrams using PGF/TikZ. +An example follows. + +\begin{example} +\begin{center} +\begin{tikzpicture} +\pic[ + rotate=90, + braid/.cd, + every strand/.style={ultra thick}, + strand 1/.style={red}, + strand 2/.style={green}, + strand 3/.style={blue}, +] {braid={s_1 s_2^{-1} s_1 s_2^{-1} s_1 s_2^{-1}}}; +\end{tikzpicture} +\end{center} +\end{example} + +\section{TikZ Library Usage} + +Version 2.0 changed the implementation to use the TikZ \Verb+pic+ syntax. +It also converted it to a TikZ library, so to use it put the following in the preamble. + +\begin{verbatim} +\usetikzlibrary{braids} +\end{verbatim} + +(Or add it to the copious list of TikZ libraries that you are already using.) + +\bigskip + +\DescribeMacro{braid} +A braid is specified by the pic name \Verb+braid+. +The usual syntax for this is as follows: + +\Verb+\pic[options] at (coordinate) {braid={braid-word}};+ + +\DescribeMacro{braid-word} +The \Verb+braid-word+ is an expression in the braid group, such as \Verb+s_1 s_2^{-1} s_{3,5}+. +The generator labels are not significant. +If the subscript is a single number, as in \Verb+s_2+, the crossing goes from that number over the next. +If the subscript is two numbers, as in \Verb+s_{2,4}+, the crossing goes from the first over the second, with both the crossing strands passing over all of the intervening strands. +The exponent can be \Verb+1+, \Verb+{-1}+, or missing (in which case it defaults to \Verb+1+, note also that the exponent is read as a \TeX-token so \Verb+{1}+ is also legal). +If the exponent is \(-1\) then the over and under strands swap. + +\begin{itemize} +\item \Verb+s_1+ is strand \(1\) over strand \(2\). +\item \Verb+s_1^{-1}+ is strand \(2\) over strand \(1\). +\item \Verb+s_{1,3}+ is strand \(1\) over strand \(3\), and both are over strand \(2\). +\end{itemize} + +Certain other symbols are allowed in the \Verb+braid-word+ which control the rendering of the braid. +These extras are as follows. + +\begin{enumerate} +\item To get crossings to render at the same height, separate them with a hyphen (note: no check is made to ensure that the crossings can legally be put at the same height; \emph{caveat emptor}). +For example, \Verb+s_1-s_3+. + +\item To draw a \emph{floor} -- which is a rectangle behind the braid occupying some number of levels (the default being one level) -- precede the braid element by a vertical line, as in \Verb+s_1 | s_2+. +The floor is itself a pic which, by default, consists of a rectangle and two horizontal lines. +The rectangle picks up any \Verb+fill+ options and the lines any \Verb+draw+ options that are set in the \Verb+braid/every floor+ and \Verb+braid/floor <n>+ styles. +The \Verb+n+ is the level number, starting at \(1\). + +More general floors can be drawn using the key \Verb+braid/add floor+. +This takes one argument which is a comma separated list of parameters that specifies the position and size floor: +% +\begin{verbatim} +braid/add floor={x,y,width,height,name} +\end{verbatim} +% +The units used are the ``natural'' units of the braid: strand separation and level height. +The \Verb+name+ is optional and if given can be used to style the floor in that the style \Verb+braid/floor <name>+ is applied to that floor. + +Replacing the floor pic will change how it is drawn. +The coordinate system is set up for the floor pic so that the floor is a unit square with lower left corner at the origin. + +\item The identity element can occur in the braid-word. +It is represented by \Verb+1+. +This inserts the identity which corresponds to no crossing. +However, it takes the same amount of space as if there were a crossing. + +\end{enumerate} + +\subsection{Style Options} +\label{sec:picstyleopts} + +There are various keys that change the behaviour or rendering of the braid. +All of these are in the \Verb+/tikz/braid/+ namespace. + +\DescribeMacro{number of strands} The key \Verb+number of strands+ sets the minimum number of strands for the braid. +The number of strands will grow according to the terms in the braid word so this merely sets a lower bound. +If not set, the number of strands will be determined by the terms in the braid word. + +\DescribeMacro{height} +The key \Verb+height+ sets the height of the piece of the braid corresponding to an element in the group. +This can be negative. + +\DescribeMacro{width} +The key \Verb+width+ sets the separation of the strands in the braid. +This can be negative. + +\DescribeMacro{border height} +The key \Verb+border height+ adds a little extra length to the strands at the start and end of the braid. + +\DescribeMacro{gap} +The key \Verb+gap+ is used to determine how much of a gap to leave in the under strand at a crossing. +This should be a number strictly between 0 and .5. +The curve is drawn using a cubic bezier and the gap is in terms of the time parameter, so the gap will not increase exactly proportionally to the value given by this key, though that is a reasonable approximation. + +\DescribeMacro{control factor} +As just said, the parts of the strands involved in a crossing are drawn using a cubic bezier curve. +The control points are vertically above or below their respective end point. +This key determines that vertical separation. +It is multiplied by the \Verb+height+ so that it scales properly. +It can be set to 0 whereupon the strands in the crossing are straight lines. +The default is 0.5. + +\DescribeMacro{nudge factor} +The crossings are not quite placed one after another. +There is a small ``nudge'' between the end of one crossing and the start of another. +Due to the way that the strands are lengthened, if there is no ``nudge'' then some PDF renderers produce slightly strange results at certain magnifications. +This key controls how much that ``nudge'' is, as a factor of the \Verb+height+. +For the aforementioned reason, it should not be set to 0 (the default is 0.05). +Note that this does not change the height of a crossing. +Rather, it nudges the height at which the strands start to cross over. + +\DescribeMacro{every strand, strand <n>} +The style of the strands are controlled by two types of option. +Style options that are set on the \Verb+pic+ are passed to every strand. +It is also possible to add style options to individual strands using the keys \Verb+every strand+ and \Verb+strand <n>+. +The strands are numbered by their starting position. + +\DescribeMacro{every floor, floor <n>} +When a floor is requested behind a crossing, it is rendered as a pic. +These keys control how the floor is styled. + +\subsection{Coordinates and Anchors} + +The braid is littered with coordinates. +Each strand gets a coordinate at each end, and at every level between crossings. +These are labelled and numbered by the initial strand position and the crossing level. +They are also labelled and numbered by the final strand position with the prefix \Verb+rev+. +With a \Verb+name prefix+, the coordinate names look like the following: +% +\begin{verbatim} +<name prefix>-<strand number>-<crossing number> +<name prefix>-rev-<strand number>-<crossing number> +\end{verbatim} +% +The crossing number can also be either \Verb+s+ or \Verb+e+ for the start and end of the strand. +Note that \Verb+-1-0+ and \Verb+-1-s+ are slightly different in that \Verb+s+ includes the border height. + +\DescribeMacro{anchor} +The key \Verb+anchor+ (in the \Verb+braid+ name space) can be used to shift the braid so that a different part of it is at the specified location. +It uses the same syntax as the coordinates, except without the \Verb+<name prefix>-+. +In the following example, the braid is shifted so that where the third strand starts the second level is at the position \Verb+(1,1)+ + +\begin{example} +\begin{center} +\begin{tikzpicture} +\fill[purple] (1,1) circle[radius=3mm]; +\pic[braid/anchor=3-2,rotate=90] at (1,1) {braid={s_2 s_1 s_2 s_1}}; +\end{tikzpicture} +\end{center} +\end{example} + + +\section{Examples} + +Here are more detailed examples. + +\begin{example} +\begin{center} +\begin{tikzpicture} +\pic[ + braid/every floor/.style={fill=yellow}, + braid/floor 1/.style={draw=black,dashed,fill=yellow!50!green}, + line width=2pt, + braid/strand 1/.style={red}, + braid/strand 2/.style={blue}, + braid/strand 3/.style={green}, + braid/add floor={2,4,3,2,a}, + braid/floor a/.style={fill=pink}, + name prefix=braid, +] at (2,0) {braid={| s_1-s_3-s_5 | s_2^{-1}-s_4| s_1-s_4 s_2^{-1} s_1-s_3 s_2^{-1}-s_4^{-1}}}; +\fill[yellow] (2,0) circle (4pt); +\node[at=(braid-3-s),pin=north west:strand 3 start] {}; +\node[at=(braid-3-e),pin=south west:strand 3 end] {}; +\node[at=(braid-rev-3-s),pin=north east:strand 3 (from bottom) start] {}; +\node[at=(braid-rev-3-e),pin=south east:strand 3 (from bottom) end] {}; +\end{tikzpicture} +\end{center} +\end{example} + +\begin{example} +\begin{center} +\begin{tikzpicture} +\pic[ + braid/.cd, + number of strands=3, + line width=8pt, + strand 1/.style={red}, + strand 2/.style={green}, + strand 3/.style={blue}, + gap=0.1, + control factor=0, + nudge factor=0, + name prefix=braid, +] {braid={a_2 a_1 a_2^{-1} a_1}}; +\node[circle,draw,fill=white,inner sep=0pt] at (braid-2-1) {\(+\)}; +\node[circle,draw,fill=white,inner sep=0pt] at (braid-3-1) {\(-\)}; +\node[circle,draw,fill=white,inner sep=0pt] at (braid-2-3) {\(+\)}; +\end{tikzpicture} +\end{center} + +\end{example} + +\newpage + +\section{Original Package Usage (Depreciated)} + +The original version was as a separate package. +This is still included for backwards compatibility. +To use this package, you need to put the following in the preamble. + +\begin{verbatim} +\usepackage{braids} +\end{verbatim} + +\DescribeMacro{\braid} +A braid is specified by the command \Verb+\braid+. +The syntax for this command is as follows: + +\Verb+\braid[style options] (name) at (coordinate) braid-word;+ + +\DescribeMacro{braid-word} +The \Verb+braid-word+ is an expression in the braid group, such as \Verb+s_1 s_2^{-1}+. +The generator labels are not significant. +The exponent can be \Verb+1+, \Verb+{-1}+, or missing (in which case it defaults to \Verb+1+, note also that the exponent is read as a \TeX-token so \Verb+{1}+ is also legal). +Certain other symbols are allowed in the \Verb+braid-word+ which control the rendering of the braid. +These extras are as follows. + +\begin{enumerate} +\item To get crossings to render at the same height, separate them with a hyphen (note: no check is made to ensure that the crossings can legally be put at the same height; \emph{caveat emptor}). + +\item To draw a \emph{floor}, precede the braid element by a vertical line. +What happens then is that when the braid is rendered, the coordinates of the rectangle behind that crossing (wide enough to encompass all the strands) is passed to a command. +The intention is that this command draw something behind the braid. +The command is configurable by a key (see \ref{sec:styleopts}). + +\item The identity element can occur in the braid-word. +It is represented by \Verb+1+. +This inserts the identity which corresponds to no crossing. +However, it takes the same amount of space as if there were a crossing. + +\item Strands can be labelled between crossings. +To do this, the commands \Verb+\label+, \Verb+\olabel+, and \Verb+\clabel+ are provided. +These take three arguments, the first is optional. +The result of this command is to place a node on top of a particular strand between the crossings where the command is given. +The first (optional) argument can be used to pass style options to this node. +The second argument is the strand number. +The third argument is the label text. + +The three commands differ as to how they interpret the strand number. +For \Verb+\olabel+, the strand number is taken to mean the strand that starts at that position. +For \Verb+\clabel+, the strand number is taken to mean the strand that is currently at that position. +The behaviour of \Verb+\label+ is to choose one or other of these depending on whether the key \Verb+strand label by origin+ is true or false. +This key only has an effect at the start of the braid-word; it cannot be reset in the middle. + +\item Style options can be given in the middle of a braid-word by enclosing them in square brackets. +There are not many style options that it makes sense to change in the middle of the braid-word, since the strands are rendered all in one go at the end. + +\item Scoping is handled by using braces. +Thus to change a style only briefly, enclose the desired scope in braces. +\end{enumerate} + +\DescribeMacro{name} +The (optional) \Verb+name+ acts a little like the \Verb+name+ of a TikZ node. +When it is specified, the routine that renders the braid also saves certain coordinates as if they were node anchors. +Specifically, \Verb+coordinate+ nodes are placed at the centre of the braid diagram and at the ends of each strand. +The centre has the label \Verb+name+, the strands are labelled \Verb+name-number-end+ and \Verb+name-rev-number-end+, where \Verb+name+ is the name given to the braid, \Verb+number+ is the number of the strand counting from the left, and \Verb+end+ is either \Verb+s+ for the start or \Verb+e+ for the end. +If the version with \Verb+rev+ is used then the numbers correspond to the \emph{final} positions of the braids. +The name can also be specified with the \Verb+name+ key. + +\DescribeMacro{at} +The (optional) \Verb+at (coordinate)+ syntax positions the braid at the \Verb+coordinate+ in the current picture. +Due to the implementation, the coordinate has to be known at the start, but the width and height of the braid are only known at the end. +Therefore, the braid is positioned so that the start of the first strand is at \Verb+(coordinate)+. +This can also be specified using the \Verb+at+ key. + +\DescribeMacro{style options} +The \Verb+style options+ set the style for the braid strands. +They can be grouped into three types: options that set up the main parameters for the braid, options that set the default style for the strands, and options that set up styles for individual strands. +The options are as follows. + +\subsection{Style Options} +\label{sec:styleopts} + +\DescribeMacro{number of strands} The key \Verb+number of strands+ sets the minimum number of strands for the braid. +The number of strands will grow according to the terms in the braid word so this merely sets a lower bound. +If not set, the number of strands will be determined by the terms in the braid word. + +\DescribeMacro{height} +The key \Verb+height+ sets the height of the piece of the braid corresponding to an element in the group. + +\DescribeMacro{width} +The key \Verb+width+ sets the separation of the strands in the braid. + +\DescribeMacro{border height} +The key \Verb+border height+ adds a little extra length to the strands at the start and end of the braid. + +\DescribeMacro{gap} +The key \Verb+gap+ is used to determine how much of a gap to leave in the under strand at a crossing. +This should be a number strictly between 0 and .5. +The curve is drawn using a cubic bezier and the gap is in terms of the time parameter, so the gap will not increase exactly proportionally to the value given by this key, though that is a reasonable approximation. + +\DescribeMacro{control factor} +As just said, the parts of the strands involved in a crossing are drawn using a cubic bezier curve. +The control points are vertically above or below their respective end point. +This key determines that vertical separation. +It is multiplied by the \Verb+height+ so that it scales properly. +It can be set to 0 whereupon the strands in the crossing are straight lines. +The default is 0.5. + +\DescribeMacro{nudge factor} +The crossings are not quite placed one after another. +There is a small ``nudge'' between the end of one crossing and the start of another. +Due to the way that the strands are lengthened, if there is no ``nudge'' then some PDF renderers produce slightly strange results at certain magnifications. +This key controls how much that ``nudge'' is, as a factor of the \Verb+height+. +For the aforementioned reason, it should not be set to 0 (the default is 0.05). +Note that this does not change the height of a crossing. +Rather, it nudges the height at which the strands start to cross over. + +\DescribeMacro{style strands} +The style of the strands are controlled by two types of option. +Style options that are set on the \Verb+\braid+ command are passed to every strand. +It is also possible to add style options to individual strands using the key \Verb+style strands+. +This takes two options, a comma-delimited list of strand numbers (which could be just a single number) and a list of options to be applied to that strand. +Thus, the syntax is \Verb+style strands={n,m,...}{options}+. +The strands are numbered by their starting position. +Not all of the standard TikZ style options are possible due to the way that the strands are constructed. +Basically, the options that are allowed are those that do not require changing the path or drawing it more than once. + +\DescribeMacro{floor command} +When a floor is requested behind a crossing, the actual way to render it is determined by a command. +This key allows the user to define that command. +The argument to this key should be the code that should be executed for each floor. +To avoid the hassle of getting the number of hashes right, the command should take no arguments. +Rather, the coordinates of the rectangle are saved in to macros \Verb+\floorsx+, \Verb+\floorsy+, \Verb+\floorex+, \Verb+\floorey+ (these macros will expand to something like \Verb+10pt+) and the command should use these to position the drawing. +The default is to draw a line at the top and at the bottom of the rectangle. + +\DescribeMacro{style floors} +\DescribeMacro{style all floors} +In the spirit of separating \emph{style} and \emph{content}, the style options for the floors can be specified separately to the command (of course, they could be built in to the command). +One advantage of this over building them in to the command is to allow them to be overridden for individual floors. +The \Verb+style all floors+ sets up options to be used for \emph{all} floors, whilst the \Verb+style floors={n,m,...}{options}+ sets up options to be used only for the listed floor. +Anything specified in the \Verb+floor command+ will take precedence over both of these. + +Any other style options are passed to the underlying TikZ/PGF system and so may influence how the braid is drawn (but note that not all keys make sense due to the implementation). + + +\section{Examples} + +Here are more detailed examples. + +\begin{example} +\begin{center} +\begin{tikzpicture} +\braid[ + style all floors={fill=yellow}, + style floors={1}{dashed,fill=yellow!50!green}, + floor command={% + \fill (\floorsx,\floorsy) rectangle (\floorex,\floorey); + \draw (\floorsx,\floorsy) -- (\floorex,\floorsy); + }, + line width=2pt, + style strands={1}{red}, + style strands={2}{blue}, + style strands={3}{green} +] (braid) at (2,0) | s_1-s_3-s_5 | s_2^{-1}-s_4| s_1-s_4 s_2^{-1} s_1-s_3 s_2^{-1}-s_4^{-1}; +\fill[yellow] (2,0) circle (4pt); +\fill[purple] (braid) circle (4pt); +\node[at=(braid-3-s),pin=north west:strand 3] {}; +\node[at=(braid-3-e),pin=south west:strand 3] {}; +\node[at=(braid-rev-3-s),pin=north east:strand 3 (from bottom)] {}; +\node[at=(braid-rev-3-e),pin=south east:strand 3 (from bottom)] {}; +\end{tikzpicture} +\end{center} +\end{example} + +\begin{example} +\begin{center} +\begin{tikzpicture} +\braid[ + number of strands=3, + line width=8pt, + style strands={1}{red}, + style strands={2}{green}, + style strands={3}{blue}, + gap=0.1, + control factor=0, + nudge factor=0, + strand label by origin=true, + strand label/.style={circle,draw,fill=white,inner sep=0pt}, + yscale=1] (braid_1) a_2 \label{2}{\(+\)} \clabel{2}{\(-\)} a_1 a_2^{-1} \olabel{2}{\(+\)} a_1; +\end{tikzpicture} +\end{center} + +\end{example} + +\end{document} +% Local Variables: +% tex-output-type: "pdf18" +% End: diff --git a/Master/texmf-dist/doc/latex/braids/braids_code.pdf b/Master/texmf-dist/doc/latex/braids/braids_code.pdf Binary files differnew file mode 100644 index 00000000000..d60b9b6f399 --- /dev/null +++ b/Master/texmf-dist/doc/latex/braids/braids_code.pdf diff --git a/Master/texmf-dist/doc/latex/braids/braids_doc.pdf b/Master/texmf-dist/doc/latex/braids/braids_doc.pdf Binary files differdeleted file mode 100644 index 444fcba185d..00000000000 --- a/Master/texmf-dist/doc/latex/braids/braids_doc.pdf +++ /dev/null diff --git a/Master/texmf-dist/doc/latex/braids/braids_doc.tex b/Master/texmf-dist/doc/latex/braids/braids_doc.tex deleted file mode 100644 index 43a58064a1c..00000000000 --- a/Master/texmf-dist/doc/latex/braids/braids_doc.tex +++ /dev/null @@ -1,178 +0,0 @@ -\documentclass{ltxdoc} -\usepackage[T1]{fontenc} -\usepackage{lmodern} -\usepackage{morefloats} -\usepackage{tikz} -\usepackage{braids} -\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} - -\newenvironment{example} - {\VerbatimEnvironment - \begin{VerbatimOut}{example.out}} - {\end{VerbatimOut} - \begin{center} - \setlength{\parindent}{0pt} - \fbox{\begin{minipage}{.9\linewidth} - \lstset{breakatwhitespace=true,breaklines=true,language=TeX,basicstyle=\small} - \lstinputlisting[]{example.out} - \end{minipage}} - - \fbox{\begin{minipage}{.9\linewidth} - \input{example.out} - \end{minipage}} -\end{center} -} - -\providecommand*{\url}{\texttt} -\GetFileInfo{braids.sty} - -\title{The \textsf{braids} Package: Documentation} -\author{Andrew Stacey \\ \url{stacey@math.ntnu.no}} -\date{\fileversion~from \filedate} - -\begin{document} - -\maketitle - -\begin{center} -\begin{tikzpicture} -\braid[width=.75cm,height=.5cm,line width=1.5pt,red,line cap=round,style strands={3,6,7,10,14,15,16,18}{gray,line width=1pt}] s_1-s_4-s_8-s_{12}-s_{16} s_2-s_5-s_7-s_9-s_{13}-s_{15} s_2-s_5-s_7-s_9-s_{15} s_1-s_4-s_8-s_{16} s_1-s_4-s_7-s_9-s_{17} s_2-s_5-s_{17} s_2-s_{13}-s_{16} s_1-s_{12}-s_{15}; -\end{tikzpicture} -\end{center} - -\section{Introduction} - -This is a package for drawing braid diagrams using PGF/TikZ. -An example follows. - -\begin{example} -\begin{center} -\begin{tikzpicture} -\braid[rotate=90,style strands={1}{red},style strands={2}{blue},style strands={3}{green}] s_1 s_2^{-1} s_1 s_2^{-1} s_1 s_2^{-1}; -\end{tikzpicture} -\end{center} -\end{example} - -\section{Usage} - -\DescribeMacro{\braid} -A braid is specified by the command \Verb+\braid+. -The syntax for this command is as follows: - -\Verb+\braid[style options] (name) at (coordinate) braid-word;+ - -\DescribeMacro{braid-word} -The \Verb+braid-word+ is an expression in the braid group, such as \Verb+s_1 s_2^{-1}+. -The generator labels are not significant. -The exponent can be \Verb+1+, \Verb+{-1}+, or missing (in which case it defaults to \Verb+1+, note also that the exponent is read as a \TeX-token so \Verb+{1}+ is also legal). -Certain other symbols are allowed in the \Verb+braid-word+ which control the rendering of the braid. -To get crossings to render at the same height, separate them with a hyphen (note: no check is made to ensure that the crossings can legally be put at the same height; \emph{caveat emptor}). -To draw a \emph{floor}, precede the braid element by a vertical line. -What happens then is that when the braid is rendered, the coordinates of the rectangle behind that crossing (wide enough to encompass all the strands) is passed to a command. -The intention is that this command draw something behind the braid. -The command is configurable by a key (see \ref{sec:styleopts}). - -\DescribeMacro{name} -The (optional) \Verb+name+ acts a little like the \Verb+name+ of a TikZ node. -When it is specified, the routine that renders the braid also saves certain coordinates as if they were node anchors. -Specifically, \Verb+coordinate+ nodes are placed at the centre of the braid diagram and at the ends of each strand. -The centre has the label \Verb+name+, the strands are labelled \Verb+name-number-end+ and \Verb+name-rev-number-end+, where \Verb+name+ is the name given to the braid, \Verb+number+ is the number of the strand counting from the left, and \Verb+end+ is either \Verb+s+ for the start or \Verb+e+ for the end. -If the version with \Verb+rev+ is used then the numbers correspond to the \emph{final} positions of the braids. -The name can also be specified with the \Verb+name+ key. - -\DescribeMacro{at} -The (optional) \Verb+at (coordinate)+ syntax positions the braid at the \Verb+coordinate+ in the current picture. -Due to the implementation, the coordinate has to be known at the start, but the width and height of the braid are only known at the end. -Therefore, the braid is positioned so that the start of the first strand is at \Verb+(coordinate)+. -This can also be specified using the \Verb+at+ key. - -\DescribeMacro{style options} -The \Verb+style options+ set the style for the braid strands. -They can be grouped into three types: options that set up the main parameters for the braid, options that set the default style for the strands, and options that set up styles for individual strands. -The options are as follows. - -\subsection{Style Options} -\label{sec:styleopts} - -\DescribeMacro{number of strands} The key \Verb+number of strands+ sets the minimum number of strands for the braid. -The number of strands will grow according to the terms in the braid word so this merely sets a lower bound. -If not set, the number of strands will be determined by the terms in the braid word. - -\DescribeMacro{height} -The key \Verb+height+ sets the height of the piece of the braid corresponding to an element in the group. - -\DescribeMacro{width} -The key \Verb+width+ sets the separation of the strands in the braid. - -\DescribeMacro{border height} -The key \Verb+border height+ adds a little extra length to the strands at the start and end of the braid. - -\DescribeMacro{style strands} -The style of the strands are controlled by two types of option. -Style options that are set on the \Verb+\braid+ command are passed to every strand. -It is also possible to add style options to individual strands using the key \Verb+style strands+. -This takes two options, a comma-delimited list of strand numbers (which could be just a single number) and a list of options to be applied to that strand. -Thus, the syntax is \Verb+style strands={n,m,...}{options}+. -The strands are numbered by their starting position. -Not all of the standard TikZ style options are possible due to the way that the strands are constructed. -Basically, the options that are allowed are those that do not require changing the path or drawing it more than once. - -\DescribeMacro{floor command} -When a floor is requested behind a crossing, the actual way to render it is determined by a command. -This key allows the user to define that command. -The argument to this key should be the code that should be executed for each floor. -To avoid the hassle of getting the number of hashes right, the command should take no arguments. -Rather, the coordinates of the rectangle are saved in to macros \Verb+\floorsx+, \Verb+\floorsy+, \Verb+\floorex+, \Verb+\floorey+ (these macros will expand to something like \Verb+10pt+) and the command should use these to position the drawing. -The default is to draw a line at the top and at the bottom of the rectangle. - -\DescribeMacro{style floors} -\DescribeMacro{style all floors} -In the spirit of separating \emph{style} and \emph{content}, the style options for the floors can be specified separately to the command (of course, they could be built in to the command). -One advantage of this over building them in to the command is to allow them to be overridden for individual floors. -The \Verb+style all floors+ sets up options to be used for \emph{all} floors, whilst the \Verb+style floors={n,m,...}{options}+ sets up options to be used only for the listed floor. -Anything specified in the \Verb+floor command+ will take precedence over both of these. - -Any other style options are passed to the underlying TikZ/PGF system and so may influence how the braid is drawn (but note that not all keys make sense due to the implementation). - - -\section{Example} - -Here is a more detailed example. - - -\begin{example} -\begin{center} -\begin{tikzpicture} -\braid[ - style all floors={fill=yellow}, - style floors={1}{dashed,fill=yellow!50!green}, - floor command={% - \fill (\floorsx,\floorsy) rectangle (\floorex,\floorey); - \draw (\floorsx,\floorsy) -- (\floorex,\floorsy); - }, - line width=2pt, - style strands={1}{red}, - style strands={2}{blue}, - style strands={3}{green} -] (braid) at (2,0) | s_1-s_3-s_5 | s_2^{-1}-s_4| s_1-s_4 s_2^{-1} s_1-s_3 s_2^{-1}-s_4^{-1}; -\fill[yellow] (2,0) circle (4pt); -\fill[purple] (braid) circle (4pt); -\node[at=(braid-3-s),pin=north west:strand 3] {}; -\node[at=(braid-3-e),pin=south west:strand 3] {}; -\node[at=(braid-rev-3-s),pin=north east:strand 3 (from bottom)] {}; -\node[at=(braid-rev-3-e),pin=south east:strand 3 (from bottom)] {}; -\end{tikzpicture} -\end{center} -\end{example} -\end{document} - -% Local Variables: -% tex-output-type: "pdf18" -% End: diff --git a/Master/texmf-dist/source/latex/braids/braids.dtx b/Master/texmf-dist/source/latex/braids/braids.dtx deleted file mode 100644 index 463da2c37cc..00000000000 --- a/Master/texmf-dist/source/latex/braids/braids.dtx +++ /dev/null @@ -1,946 +0,0 @@ -% \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 diff --git a/Master/texmf-dist/source/latex/braids/braids_code.dtx b/Master/texmf-dist/source/latex/braids/braids_code.dtx new file mode 100644 index 00000000000..51a4ee2c600 --- /dev/null +++ b/Master/texmf-dist/source/latex/braids/braids_code.dtx @@ -0,0 +1,2321 @@ +% \iffalse meta-comment +%<*internal> +\iffalse +%</internal> +%<*readme> +---------------------------------------------------------------- +braids --- a style file for drawing braid diagrams with TikZ/PGF +E-mail: loopspace@mathforge.org +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. +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 l3docstrip.tex +\keepsilent +\askforoverwritefalse +\preamble +---------------------------------------------------------------- +braids --- a style file for drawing braid diagrams with TikZ/PGF +E-mail: loopspace@mathforge.org +Released under the LaTeX Project Public License v1.3c or later +See http://www.latex-project.org/lppl.txt +---------------------------------------------------------------- + +\endpreamble +\postamble + +Copyright (C) 2011-2019 by Andrew Stacey <loopspace@mathforge.org> + +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, + tikzlibrarybraids.code.tex, + braids_doc.pdf. + +\endpostamble +\usedir{tex/latex/braids} +\generate{ + \file{braids.sty}{\from{\jobname.dtx}{package}} +} +\generate{ + \file{tikzlibrarybraids.code.tex}{\from{\jobname.dtx}{library}} +} +%</install> +%<install>\endbatchfile +%<*internal> +\usedir{source/latex/braids} +\generate{ + \file{\jobname.ins}{\from{\jobname.dtx}{install}} +} +\nopreamble\nopostamble +\usedir{doc/latex/braids} +\generate{ + \file{README.txt}{\from{\jobname.dtx}{readme}} +} +\ifx\fmtname\nameofplainTeX + \expandafter\endbatchfile +\else + \expandafter\endgroup +\fi +%</internal> +%<*package> +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{braids}[2011/10/18 v1.1 Tikz/PGF commands for drawing braid diagrams] +%</package> +%<*driver> +\documentclass{l3doc} +\usepackage[T1]{fontenc} +\usepackage{lmodern} +\usepackage{tikz} +\usepackage{braids} +\usetikzlibrary{braids} + +\EnableCrossrefs +\CodelineIndex +\RecordChanges +\begin{document} + \DocInput{\jobname.dtx} +\end{document} +%</driver> +% \fi +% +% \CheckSum{1949} +% +% \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} +% \changes{1.1}{2011/05/03}{Extended syntax} +% \changes{2.0}{2019/03/20}{Converted TikZ library} +% +% \DoNotIndex{\newcommand,\newenvironment} +% +% \GetFileInfo{tikzlibrarybraids.code.tex} +% \title{The \textsf{braids} package: codebase} +% \author{Andrew Stacey \\ \texttt{loopspace@mathforge.org}} +% \date{\fileversion~from \filedate} +% +% \maketitle +% +% \section{Introduction} +% +% This is a package for drawing braid diagrams using PGF/TikZ. +% Its inspiration was a question and answer on the website \texttt{http://tex.stackexchange.com}. +% +% \section{History} +% +% \begin{itemize} +% \item v1.0 First public release. +% +% \item v1.1 Added ability to configure the gap size, the control points, and the ``nudge''. +% Added ability to add labels to strands between crossings. +% +% \item v2 Reimplemented as TikZ library rather than a standalone package. +% \end{itemize} +% \StopEventually{} +% +% \section{Implementation} +% +% \iffalse +%<*package> +% \fi +% +% Issue a notice that this is a depreciated version of the braids package. +% \begin{macrocode} +\PackageWarning{braids}{% + This package has been reimplemented as a TikZ library; if starting with a fresh document, please consider using that instead.% +}% +% \end{macrocode} +% +% \begin{macro}[internal]{\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}[internal]{\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}[internal]{\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}[internal]{\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}[internal]{\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@token1% +% \end{macrocode} +% 1: this means the ``identity'' crossing, so no crossing here. +% Increase the level, unless overriden, and add to the label. +% \begin{macrocode} + \ifbraid@increase@level + \stepcounter{braid@level} + \fi + \braid@increase@leveltrue + \ge@addto@macro\braid@label{\braid@token}% + \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 + \ifx\braid@token\braid@olabel@strand + \let\braid@next=\braid@olabel@strand + \else + \ifx\braid@token\braid@clabel@strand + \let\braid@next=\braid@clabel@strand + \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 + \fi + \fi + \fi + \braid@next% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\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}[internal]{\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}[internal]{\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}[internal]{\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}[internal]{\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}[internal]{\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}[internal]{\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}[internal]{\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}[internal]{\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}[internal]{\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}[internal]{\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}[internal]{\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}[internal]{\braid@ne} +% Remember what \Verb+1+ looks like for testing against. +% \begin{macrocode} +\def\braid@ne{1} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\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 + \advance\braid@ty by \braid@nf\braid@height + \advance\braid@ny by -\braid@nf\braid@height + \braid@cy=\braid@ty + \braid@dy=\braid@ny + \advance\braid@cy by \braid@cf\braid@height + \advance\braid@dy by -\braid@cf\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. +% Our gap is to interrupt at times determined by the gap key. +% \begin{macrocode} +\pgfmathsetmacro{\braid@gst}{0.5 - \pgfkeysvalueof{/pgf/braid/gap}}% +\pgfmathsetmacro{\braid@gend}{0.5 + \pgfkeysvalueof{/pgf/braid/gap}}% +\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. +% \begin{macrocode} + \pgfpathcurvebetweentimecontinue{0}{\braid@gst}% + {\pgfqpoint{\braid@tx}{\braid@ty}}% + {\pgfqpoint{\braid@tx}{\braid@cy}}% + {\pgfqpoint{\braid@nx}{\braid@dy}}% + {\pgfqpoint{\braid@nx}{\braid@ny}}% + \pgfpathcurvebetweentime{\braid@gend}{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}{\braid@gst}% + {\pgfqpoint{\braid@nx}{\braid@ty}}% + {\pgfqpoint{\braid@nx}{\braid@cy}}% + {\pgfqpoint{\braid@tx}{\braid@dy}}% + {\pgfqpoint{\braid@tx}{\braid@ny}} + \pgfpathcurvebetweentime{\braid@gend}{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}[internal]{\braid@olabel@strand} +% This macro allows us to label a strand just before a crossing. +% The first argument is the strand number at that particular crossing and the second is the label. +% We also save the current height. +% This version takes the strand number as meaning the \emph{original} ordering. +% \begin{macrocode} +\newcommand{\braid@olabel@strand}[3][]{% + \edef\braid@tmp{{\the\value{braid@level}}}% + \expandafter\ifx\csname braid@strand@#2@origin\endcsname\relax + \g@addto@macro\braid@tmp{{#2}}% + \else + \edef\braid@tmpa{{\csname braid@strand@#2@origin\endcsname}}% + \ge@addto@macro\braid@tmp{\braid@tmpa}% + \fi + \g@addto@macro\braid@tmp{{#3}{#1}}% + \ge@addto@macro{\braid@strand@labels}{\braid@tmp}% + \braid@process% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\braid@clabel@strand} +% This macro allows us to label a strand just before a crossing. +% The first argument is the strand number at that particular crossing and the second is the label. +% We also save the current height. +% This version takes the strand number as meaning the \emph{current} ordering. +% \begin{macrocode} +\newcommand{\braid@clabel@strand}[3][]{% + \edef\braid@tmp{{\the\value{braid@level}}}% + \g@addto@macro\braid@tmp{{#2}{#3}{#1}}% + \ge@addto@macro{\braid@strand@labels}{\braid@tmp}% + \braid@process% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\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}[internal]{\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}[internal]{\braid@render@strand@labels} +% This starts rendering the labels on the strands at the crossings. +% \begin{macrocode} +\def\braid@render@strand@labels#1{% + \def\braid@tmp{#1}% + \ifx\braid@tmp\pgfutil@empty + \let\braid@next=\pgfutil@gobble + \else + \let\braid@next=\braid@@render@strand@labels + \fi + \braid@next{#1}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\braid@@render@strand@labels} +% This is the actual renderer. +% \begin{macrocode} +\def\braid@@render@strand@labels#1#2#3#4{% + \begingroup + \pgfscope + \let\tikz@options=\pgfutil@empty + \let\tikz@mode=\pgfutil@empty + \let\tik@transform=\pgfutil@empty + \let\tikz@fig@name=\pgfutil@empty + \tikzset{/pgf/braid/strand label,#4}% + \braid@nx=#2\braid@width + \braid@ny=#1\braid@height + \advance\braid@ny by \braid@eh + \advance\braid@ny by \braid@height + \pgftransformshift{\pgfqpoint{\braid@nx}{\braid@ny}}% + \tikz@options + \setbox\pgfnodeparttextbox=\hbox% + \bgroup% + \tikzset{every text node part/.try}% + \ifx\tikz@textopacity\pgfutil@empty% + \else% + \pgfsetfillopacity{\tikz@textopacity}% + \pgfsetstrokeopacity{\tikz@textopacity}% + \fi% + \pgfinterruptpicture% + \tikz@textfont% + \ifx\tikz@text@width\pgfutil@empty% + \else% + \begingroup% + \pgfmathsetlength{\pgf@x}{\tikz@text@width}% + \pgfutil@minipage[t]{\pgf@x}\leavevmode\hbox{}% + \tikz@text@action% + \fi% + \tikz@atbegin@node% + \bgroup% + \aftergroup\unskip% + \ifx\tikz@textcolor\pgfutil@empty% + \else% + \pgfutil@colorlet{.}{\tikz@textcolor}% + \fi% + \pgfsetcolor{.}% + \setbox\tikz@figbox=\box\pgfutil@voidb@x% + \tikz@uninstallcommands% + \tikz@halign@check% + \ignorespaces% + #3 + \egroup + \tikz@atend@node% + \ifx\tikz@text@width\pgfutil@empty% + \else% + \pgfutil@endminipage% + \endgroup% + \fi% + \endpgfinterruptpicture% + \egroup% + \ifx\tikz@text@width\pgfutil@empty% + \else% + \pgfmathsetlength{\pgf@x}{\tikz@text@width}% + \wd\pgfnodeparttextbox=\pgf@x% + \fi% + \ifx\tikz@text@height\pgfutil@empty% + \else% + \pgfmathsetlength{\pgf@x}{\tikz@text@height}% + \ht\pgfnodeparttextbox=\pgf@x% + \fi% + \ifx\tikz@text@depth\pgfutil@empty% + \else% + \pgfmathsetlength{\pgf@x}{\tikz@text@depth}% + \dp\pgfnodeparttextbox=\pgf@x% + \fi% + \pgfmultipartnode{\tikz@shape}{\tikz@anchor}{\tikz@fig@name}{% + {\begingroup\tikz@finish}% + }% + \endpgfscope + \endgroup + \braid@render@strand@labels% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\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} +% Now we label the strands if needed. +% \begin{macrocode} + \ifx\braid@strand@labels\pgfutil@empty + \else + \expandafter\braid@render@strand@labels\braid@strand@labels{}% + \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}[internal]{\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@strand@labels\@empty + \let\braid@floors\@empty + \let\braid@name\empty + \let\clabel=\braid@clabel@strand + \let\olabel=\braid@olabel@strand + \pgfkeys{/pgf/braid/.cd,#1}% + \ifbraid@strand@labels@origin + \let\label=\braid@olabel@strand + \else + \let\label=\braid@clabel@strand + \fi + \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}% + \pgfkeysgetvalue{/pgf/braid/control factor}{\braid@cf}% + \pgfkeysgetvalue{/pgf/braid/nudge factor}{\braid@nf}% + \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} +% An if to decide whether label indices should be absolute or not +% \begin{macrocode} +\newif\ifbraid@strand@labels@origin +% \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, + gap/.initial=.1, + border height/.initial=.25cm, + control factor/.initial=.5, + nudge factor/.initial=.05, + 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} + }, + strand label/.style={}, + strand label by origin/.is if=braid@strand@labels@origin, +} +% \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 +% \begin{macrocode} +%<*library> +%<@@=braid> +% \end{macrocode} +% +% \section{Reimplementation as a TikZ Library} +% +% Life is so much easier with \LaTeX3. +% \begin{macrocode} +\ProvidesFile{tikzlibrarybraids.code.tex}[% + 2019/03/20 v2.0 Tikz/PGF library for drawing braid diagrams% +] +\RequirePackage{expl3} +\ExplSyntaxOn +% \end{macrocode} +% Define all the variables we'll be using. +% \begin{macrocode} +\tl_new:N \l_@@_tmpa_tl +\tl_new:N \l_@@_tmpb_tl +\tl_new:N \l_@@_tmpc_tl +\tl_new:N \l_@@_tmpd_tl +\tl_new:N \l_@@_anchor_strand_tl +\tl_new:N \l_@@_anchor_level_tl +\fp_new:N \l_@@_height_fp +\fp_new:N \l_@@_width_fp +\fp_new:N \l_@@_nudge_fp +\fp_new:N \l_@@_control_fp +\fp_new:N \l_@@_ctrlax_fp +\fp_new:N \l_@@_ctrlay_fp +\fp_new:N \l_@@_ctrlbx_fp +\fp_new:N \l_@@_ctrlby_fp +\fp_new:N \l_@@_endx_fp +\fp_new:N \l_@@_endy_fp +\fp_new:N \l_@@_anchor_x_fp +\fp_new:N \l_@@_anchor_y_fp +\int_new:N \l_@@_tmpa_int +\int_new:N \l_@@_length_int +\int_new:N \l_@@_strands_int +\int_new:N \l_@@_crossing_int +\int_new:N \l_@@_anchor_level_int +\int_new:N \l_@@_floor_int +\seq_new:N \l_@@_word_seq +\seq_new:N \l_@@_crossing_seq +\seq_new:N \l_@@_anchor_seq +\seq_new:N \l_@@_floors_seq +\str_new:N \l_@@_tmpa_str +\str_new:N \l_@@_sup_str +\str_set:Nn \l_@@_sup_str {^} +\str_new:N \l_@@_sub_str +\str_set:Nn \l_@@_sub_str {_} +\str_new:N \l_@@_hyphen_str +\str_set:Nn \l_@@_hyphen_str {-} +\str_new:N \l_@@_bar_str +\str_set:Nn \l_@@_bar_str {|} +\str_new:N \l_@@_one_str +\str_set:Nn \l_@@_one_str {1} +\bool_new:N \l_@@_step_level_bool +\bool_new:N \l_@@_swap_crossing_bool +\bool_new:N \l_@@_floor_bool +\prop_new:N \l_@@_strands_prop +\prop_new:N \l_@@_permutation_prop +\prop_new:N \l_@@_crossing_permutation_prop +\prop_new:N \l_@@_inverse_prop +\prop_new:N \l_@@_anchor_prop +% \end{macrocode} +% Our interface is through a TikZ pic. +% \begin{macrocode} +\tikzset{ + braid/.pic={ + code={ + \@@_parse_word:n {#1} + \@@_count: + \@@_render: + } + }, + floor/.pic={ + code={ + \path[pic~ actions, draw=none] (0,0) rectangle (1,1); + \path[pic~ actions, fill=none] (0,0) -- (1,0) (0,1) -- (1,1); + } + }, + /tikz/braid/.search~ also={/tikz}, + braid/.cd, +% \end{macrocode} +% The various TikZ parameters for the braid. +% +% The anchor determines which part of the braid is located at the position specified by the pic. +% It can be of the form \Verb+n-m+ where \Verb+n+ is a strand number and +m+ is a crossing level. +% The strand number can be either a number or \Verb+rev-n+ to use the ending numbering of the strands. +% The crossing level can also be \Verb+s+ or \Verb+e+ which means the actual start or end of the strand (including the border). +% +% \begin{macrocode} + anchor/.initial=1-s, +% \end{macrocode} +% \Verb+number of strands+ sets a minimum for the number of strands in the braid (otherwise, it is set by the strands used in the specified crossings). +% \begin{macrocode} + number~ of~ strands/.initial=0, +% \end{macrocode} +% \Verb+height+ is the distance between crossings (can be negative). +% \begin{macrocode} + height/.initial=-1cm, +% \end{macrocode} +% \Verb+width+ is the distance between strands (can be negative). +% \begin{macrocode} + width/.initial=1cm, +% \end{macrocode} +% \Verb+gap+ is for determining the gap in the under-strand of a crossing. +% \begin{macrocode} + gap/.initial=.05, +% \end{macrocode} +% \Verb+border height+ is a length added at the start and end of each strand. +% \begin{macrocode} + border~ height/.initial=.25cm, +% \end{macrocode} +% \Verb+floor border+ is added to the width of any floors +% \begin{macrocode} + floor~ border/.initial=.25cm, +% \end{macrocode} +% \Verb+floors+ is a list of floors to draw, specified as a cslist of coordinates as (x,y,w,h,a) in which the units are numbers of strands and crossing levels. +% The parameters are: coordinates of lower left corner, width, height, (optional) name for styling. +% \begin{macrocode} + add~ floor/.code={ + \seq_push:Nn \l_@@_floors_seq {#1} + }, +% \end{macrocode} +% \Verb+control factor+ determines the proportion of the \Verb+height+ used for the control points. +% \begin{macrocode} + control~ factor/.initial=.5, +% \end{macrocode} +% \Verb+nudge factor+ is used to compress each crossing slightly within its rectangle. +% \begin{macrocode} + nudge~ factor/.initial=.05 +} +% \end{macrocode} +% +% \begin{macro}[internal]{\@@_parse_word:Nn} +% Parse the braid word as a token list and convert it into a sequence. +% \begin{macrocode} +\cs_new_nopar:Npn \@@_parse_word:n #1 +{ + \seq_clear:N \l_@@_word_seq + \tl_clear:N \l_@@_tmpa_tl + \tl_set:Nn \l_@@_tmpb_tl {#1} + + \bool_until_do:nn { \tl_if_empty_p:N \l_@@_tmpb_tl } + { +% \end{macrocode} +% We step through the braid specification, looking for special characters. +% To avoid catcode issues, the comparison is as strings. +% Some actions may involve consuming more tokens from the list so we can't do a simple \Verb+map_inline+ but have to keep stripping off the head token. +% +% The idea is to store information about the current crossing in a token list (noting that it may be specified in a variety of orders) and then when we're sure we have all the information we add it to our sequence of crossings. +% \begin{macrocode} + \str_set:Nx \l_@@_tmpa_str {\tl_head:N \l_@@_tmpb_tl} + \tl_set:Nx \l_@@_tmpb_tl {\tl_tail:N \l_@@_tmpb_tl} +% \end{macrocode} +% +% \begin{macrocode} + \str_case_e:nnTF {\l_@@_tmpa_str} + { +% \end{macrocode} +% Underscore introduces the crossing numbers +% \begin{macrocode} + {_} + { + \tl_put_right:Nx \l_@@_tmpa_tl + { + \exp_not:N \@@_parse_index:n {\tl_head:N \l_@@_tmpb_tl} + } + \tl_set:Nx \l_@@_tmpb_tl {\tl_tail:N \l_@@_tmpb_tl} + } +% \end{macrocode} +% Power is used to indicate inverse. +% \begin{macrocode} + {^} + { + \tl_put_left:Nx \l_@@_tmpa_tl + { + \exp_not:N \@@_parse_exponent:n {\tl_head:N \l_@@_tmpb_tl} + } + \tl_set:Nx \l_@@_tmpb_tl {\tl_tail:N \l_@@_tmpb_tl} + } +% \end{macrocode} +% Bar is for floors. +% \begin{macrocode} + {|} + { + \tl_if_empty:NF \l_@@_tmpa_tl + { + \seq_put_right:NV \l_@@_word_seq \l_@@_tmpa_tl + \tl_clear:N \l_@@_tmpa_tl + } + + \tl_set:Nn \l_@@_tmpa_tl { + \bool_set_false:N \l_@@_step_level_bool + \bool_set_true:N \l_@@_floor_bool + } + \seq_put_right:NV \l_@@_word_seq \l_@@_tmpa_tl + \tl_clear:N \l_@@_tmpa_tl + } +% \end{macrocode} +% Hyphen says the next crossing is on the same level as the current one. +% \begin{macrocode} + {-} + { + \tl_put_right:Nn \l_@@_tmpa_tl + { + \bool_set_false:N \l_@@_step_level_bool + } + } +% \end{macrocode} +% \(1\) is for the identity (i.e., no crossing but still have a level). +% We put a nop token on the list so that it is no longer empty. +% \begin{macrocode} + {1} + { + \tl_if_empty:NF \l_@@_tmpa_tl + { + \seq_put_right:NV \l_@@_word_seq \l_@@_tmpa_tl + \tl_clear:N \l_@@_tmpa_tl + } + \tl_put_right:Nn \l_@@_tmpa_tl {\@@_do_identity:} + } +% \end{macrocode} +% Ignore spaces. +% \begin{macrocode} + {~} + { + } + } + { + } + { +% \end{macrocode} +% If we get an unrecognised token, it's our trigger to start accumulating information for the next crossing. +% \begin{macrocode} + \tl_if_empty:NF \l_@@_tmpa_tl + { + \seq_put_right:NV \l_@@_word_seq \l_@@_tmpa_tl + \tl_clear:N \l_@@_tmpa_tl + } + } + } +% \end{macrocode} +% At the end, we also put our current token list on the word sequence. +% \begin{macrocode} + \tl_if_empty:NF \l_@@_tmpa_tl + { + \seq_put_right:NV \l_@@_word_seq \l_@@_tmpa_tl + \tl_clear:N \l_@@_tmpa_tl + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_parse_index:n} +% Parse an index, saving it in a sequence with the two indices such that the first goes over the second. +% \begin{macrocode} +\cs_new_nopar:Npn \@@_parse_index:n #1 +{ + \seq_set_from_clist:Nn \l_@@_crossing_seq {#1} + \int_compare:nT {\seq_count:N \l_@@_crossing_seq == 1} + { + \seq_put_right:Nx \l_@@_crossing_seq {\int_eval:n {#1 + 1} } + } + \bool_if:NT \l_@@_swap_crossing_bool + { + \seq_pop_left:NN \l_@@_crossing_seq \l_@@_tmpa_tl + \seq_put_right:NV \l_@@_crossing_seq \l_@@_tmpa_tl + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_parse_exponent:n} +% Parse an exponent, basically testing to see if it is \(-1\) in which case our crossing numbers should be reversed.. +% \begin{macrocode} +\cs_new_nopar:Npn \@@_parse_exponent:n #1 +{ + \int_compare:nTF {#1 == -1} + { + \bool_set_true:N \l_@@_swap_crossing_bool + } + { + \bool_set_false:N \l_@@_swap_crossing_bool + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_do_identity:} +% \begin{macrocode} +\cs_new_nopar:Npn \@@_do_identity: +{ +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_count:NNN} +% Work out how big the braid is by counting strands and levels. +% We also figure out the permutation from the start to end of the strands. +% This is useful for labelling various parts of the braid. +% \begin{macrocode} +\cs_new_nopar:Npn \@@_count: +{ + \int_zero:N \l_@@_length_int + \int_set:Nn \l_@@_strands_int {\@@_value:n {number~of~strands}} + \prop_clear:N \l_@@_permutation_prop + \prop_clear:N \l_@@_crossing_permutation_prop + \prop_clear:N \l_@@_anchor_prop + \prop_clear:N \l_@@_inverse_prop + + \seq_map_inline:Nn \l_@@_word_seq + { +% \end{macrocode} +% Clear the crossing sequence and assume we're going to step the level. +% \begin{macrocode} + \seq_clear:N \l_@@_crossing_seq + \bool_set_true:N \l_@@_step_level_bool + \bool_set_false:N \l_@@_swap_crossing_bool +% \end{macrocode} +% Run the details of this crossing. +% \begin{macrocode} + ##1 +% \end{macrocode} +% If we're increasing the level (no hyphen), do so. +% \begin{macrocode} + \bool_if:NT \l_@@_step_level_bool + { + \int_incr:N \l_@@_length_int + } +% \end{macrocode} +% If we have a crossing, check we have enough strands to cover it. +% \begin{macrocode} + \seq_if_empty:NF \l_@@_crossing_seq + { + \int_set:Nn \l_@@_strands_int + { + \int_max:nn + { + \int_max:nn {\l_@@_strands_int} + { \seq_item:Nn \l_@@_crossing_seq {1}} + } + { + \seq_item:Nn \l_@@_crossing_seq {2} + } + } + } + } +% \end{macrocode} +% Now that we know how many strands we have, we can initialise our permutation props. +% One will hold the overall permutation, the other will keep track of our current permutation. +% \begin{macrocode} + \int_step_inline:nnnn {1} {1} {\l_@@_strands_int} + { + \prop_put:Nnn \l_@@_permutation_prop {##1} {##1} + \prop_put:Nnn \l_@@_anchor_prop {##1} {##1} + \prop_put:Nnn \l_@@_crossing_permutation_prop {##1} {##1} + } +% \end{macrocode} +% Now we step through the braid word again and record the permutations so that we can calculate the overall permutation defined by the braid. +% +% We will also figure out our shift from the anchor, so first we need to get some information about the anchor. +% \begin{macrocode} + \tl_set:Nx \l_@@_tmpa_tl {\@@_value:n {anchor}} + \seq_set_split:NnV \l_@@_anchor_seq {-} \l_@@_tmpa_tl + + \tl_set:Nx \l_@@_tmpa_tl {\seq_item:Nn \l_@@_anchor_seq {1}} + \tl_if_eq:VnTF \l_@@_tmpa_tl {rev} + { + \tl_set:Nx \l_@@_anchor_strand_tl {\seq_item:Nn \l_@@_anchor_seq {2}} + \tl_set:Nx \l_@@_anchor_level_tl {\seq_item:Nn \l_@@_anchor_seq {3}} + } + { + \tl_set:Nx \l_@@_anchor_strand_tl {\seq_item:Nn \l_@@_anchor_seq {1}} + \tl_set:Nx \l_@@_anchor_level_tl {\seq_item:Nn \l_@@_anchor_seq {2}} + } +% \end{macrocode} +% The important information is as to the level at which the requested anchor resides. +% If it is at the end or start of a strand, we set the level to \(-1\) so that it never matches a level number. +% \begin{macrocode} + \tl_if_eq:VnTF \l_@@_anchor_level_tl {s} + { + \int_set:Nn \l_@@_anchor_level_int {-1} + } + { + \tl_if_eq:VnTF \l_@@_anchor_level_tl {e} + { + \int_set:Nn \l_@@_anchor_level_int {-1} + } + { + \int_set:Nn \l_@@_anchor_level_int + {\tl_use:N \l_@@_anchor_level_tl} + } + } + + \int_zero:N \l_@@_crossing_int + \int_incr:N \l_@@_crossing_int +% \end{macrocode} +% +% \begin{macrocode} + \seq_map_inline:Nn \l_@@_word_seq + { + \bool_set_true:N \l_@@_step_level_bool + \seq_clear:N \l_@@_crossing_seq + \bool_set_false:N \l_@@_swap_crossing_bool + ##1 + \seq_if_empty:NF \l_@@_crossing_seq + { + \prop_get:NxN \l_@@_permutation_prop + { + \seq_item:Nn \l_@@_crossing_seq {1} + } \l_@@_tmpa_tl + \prop_get:NxN \l_@@_permutation_prop + { + \seq_item:Nn \l_@@_crossing_seq {2} + } \l_@@_tmpb_tl + + \prop_put:NxV \l_@@_permutation_prop + { + \seq_item:Nn \l_@@_crossing_seq {2} + } \l_@@_tmpa_tl + \prop_put:NxV \l_@@_permutation_prop + { + \seq_item:Nn \l_@@_crossing_seq {1} + } \l_@@_tmpb_tl + } +% \end{macrocode} +% See if the current level is what was requested by the anchor. +% \begin{macrocode} + \int_compare:nT {\l_@@_crossing_int = \l_@@_anchor_level_int} + { + \prop_set_eq:NN \l_@@_anchor_prop \l_@@_permutation_prop + } + \bool_if:NT \l_@@_step_level_bool + { + \int_incr:N \l_@@_crossing_int + } + } +% \end{macrocode} +% This inverts the anchor permutation. +% \begin{macrocode} + \int_step_inline:nnnn {1} {1} {\l_@@_strands_int} + { + \prop_get:NnN \l_@@_anchor_prop {##1} \l_@@_tmpa_tl + \prop_put:NVn \l_@@_inverse_prop \l_@@_tmpa_tl {##1} + } + \prop_set_eq:NN \l_@@_anchor_prop \l_@@_inverse_prop +% \end{macrocode} +% This inverts the full permutation. +% \begin{macrocode} + \int_step_inline:nnnn {1} {1} {\l_@@_strands_int} + { + \prop_get:NnN \l_@@_permutation_prop {##1} \l_@@_tmpa_tl + \prop_put:NVn \l_@@_inverse_prop \l_@@_tmpa_tl {##1} + } +% \end{macrocode} +% Now that we have the inverse, we can figure out our anchor. +% First, see if we requested a strand by its position at the end of the braid. +% \begin{macrocode} + \tl_set:Nx \l_@@_tmpa_tl {\seq_item:Nn \l_@@_anchor_seq {1}} + \tl_if_eq:VnT \l_@@_tmpa_tl {rev} + { + \prop_get:NVN \l_@@_permutation_prop + \l_@@_anchor_strand_tl \l_@@_anchor_strand_tl + } + \tl_if_eq:VnF \l_@@_anchor_level_tl {s} + { + \tl_if_eq:VnTF \l_@@_anchor_level_tl {e} + { + \prop_get:NVN \l_@@_inverse_prop + \l_@@_anchor_strand_tl \l_@@_anchor_strand_tl + } + { + \prop_get:NVN \l_@@_anchor_prop + \l_@@_anchor_strand_tl \l_@@_anchor_strand_tl + } + } +% \end{macrocode} +% \begin{macrocode} +} +% \end{macrocode} +% +% +% \end{macro} +% +% +% \begin{macro}{\@@_dim_value:n, \@@_value:n} +% Extract a length or a value from a PGF key. +% \begin{macrocode} +\cs_new_nopar:Npn \@@_dim_value:n #1 +{ + \dim_to_fp:n {\pgfkeysvalueof{/tikz/braid/#1}} +} +\cs_new_nopar:Npn \@@_value:n #1 +{ + \pgfkeysvalueof{/tikz/braid/#1} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_render:} +% This is the macro that converts the braid word into TikZ paths. +% \begin{macrocode} +\cs_generate_variant:Nn \prop_get:NnN {NxN} +\cs_generate_variant:Nn \prop_put:Nnn {NxV} +\cs_generate_variant:Nn \tl_if_eq:nnTF {VnTF} +\cs_generate_variant:Nn \tl_if_eq:nnF {VnF} +\cs_generate_variant:Nn \tl_if_eq:nnT {VnT} + +\cs_new_nopar:Npn \@@_render: +{ +% \end{macrocode} +% +% \begin{macrocode} + \fp_set:Nn \l_@@_anchor_x_fp { - 1 * (\tl_use:N \l_@@_anchor_strand_tl - 1) * \@@_dim_value:n {width} } + + \tl_if_eq:VnTF \l_@@_anchor_level_tl {s} + { + \fp_set:Nn \l_@@_anchor_y_fp {0} + } + { + \tl_if_eq:VnTF \l_@@_anchor_level_tl {e} + { + \fp_set:Nn \l_@@_anchor_y_fp { + -1 * \l_@@_length_int * \@@_dim_value:n {height} + - sign(\@@_dim_value:n {height}) + * 2 * \@@_dim_value:n {border~ height} + } + } + { + \fp_set:Nn \l_@@_anchor_y_fp { + -1 * \l_@@_anchor_level_tl * \@@_dim_value:n {height} + - sign(\@@_dim_value:n {height}) + * \@@_dim_value:n {border~ height} + } + } + } + + \begin{scope}[ + shift={ + (\fp_to_decimal:N \l_@@_anchor_x_fp pt, + \fp_to_decimal:N \l_@@_anchor_y_fp pt + ) + } + ] +% \end{macrocode} +% Initialise a prop for the individual strands. +% \begin{macrocode} + \prop_clear:N \l_@@_strands_prop +% \end{macrocode} +% Initialise some lengths. +% \begin{macrocode} + \fp_zero:N \l_@@_height_fp + \fp_zero:N \l_@@_nudge_fp + \fp_zero:N \l_@@_control_fp +% \end{macrocode} +% This holds our current \Verb+height+ of our strands. +% \begin{macrocode} + \fp_set:Nn \l_@@_height_fp + { + sign(\@@_dim_value:n {height}) + * \@@_dim_value:n {border~ height} + } +% \end{macrocode} +% This holds the total \Verb+width+ of our strands. +% \begin{macrocode} + \fp_set:Nn \l_@@_width_fp + { + (\l_@@_strands_int - 1) * \@@_dim_value:n {width} + + 2 * sign(\@@_dim_value:n{width}) + * \@@_dim_value:n {floor~ border} + } +% \end{macrocode} +% Each crossing actually starts a little bit into the crossing space, as defined by the \Verb+nudge factor+. +% \begin{macrocode} + \fp_set:Nn \l_@@_nudge_fp + { + \@@_value:n {nudge~ factor} * \@@_dim_value:n {height} + } +% \end{macrocode} +% This sets where the control points for the crossing curves will be. +% \begin{macrocode} + \fp_set:Nn \l_@@_control_fp + { + \@@_value:n {control~ factor} * \@@_dim_value:n {height} + } + \fp_sub:Nn \l_@@_control_fp {\l_@@_nudge_fp} +% \end{macrocode} +% Initialise our strand paths with a \Verb+\draw+. +% \begin{macrocode} + \int_step_inline:nnnn {1} {1} {\l_@@_strands_int} + { + \prop_get:NnN \l_@@_inverse_prop {##1} \l_@@_tmpa_tl + \prop_put:Nnx \l_@@_strands_prop {##1} + { + \exp_not:N \draw[ + braid/every~ strand/.try, + braid/strand~ ##1/.try + ] + \exp_not:N \@@_moveto:nn { + \fp_eval:n {(##1 - 1) * \@@_dim_value:n {width} } + } {0} + \exp_not:N \@@_lineto:nn { + \fp_eval:n {(##1 - 1) * \@@_dim_value:n {width} } + } { \fp_to_decimal:N \l_@@_height_fp} + } +% \end{macrocode} +% Add a load of coordinates at the start of each strand, indexed by both forward and backward strand numbers. +% \begin{macrocode} + \@@_coordinate:xxxx {-##1-s} {-rev-\l_@@_tmpa_tl-s} + {\fp_eval:n {(##1 - 1) * \@@_dim_value:n {width} }} {0} + + \@@_coordinate:xxxx {-##1-0} {-rev-\l_@@_tmpa_tl-0} + {\fp_eval:n {(##1 - 1) * \@@_dim_value:n {width} }} + { \fp_to_decimal:N \l_@@_height_fp} + } +% \end{macrocode} +% +% Run through any extra floors requested. +% \begin{macrocode} + \seq_map_inline:Nn \l_@@_floors_seq + { + \tl_set:Nx \l_@@_tmpa_tl {\clist_item:nn {##1} {5}} + \@@_do_floor:Vxxxx \l_@@_tmpa_tl + {\fp_eval:n + { + -1*sign(\@@_dim_value:n{width}) + * \@@_dim_value:n {floor~ border} + + (\@@_dim_value:n {width}) * (\clist_item:nn {##1} {1} - 1) + } + pt + } + {\fp_eval:n + { + \l_@@_height_fp + ( \@@_dim_value:n {height} ) * (\clist_item:nn {##1} {2}) + } + pt + } + {\fp_eval:n { + ( (\clist_item:nn {##1} {3}) * \@@_dim_value:n {width} + + 2 * sign(\@@_dim_value:n{width}) + * \@@_dim_value:n {floor~ border} ) / \dim_to_fp:n {1cm} + } + } + {\fp_eval:n { + (\clist_item:nn {##1} {4}) * ( \@@_dim_value:n {height} ) / \dim_to_fp:n {1cm} + } + } + } +% \end{macrocode} +% +% Keep track of the crossing level for the floor. +% \begin{macrocode} + \int_zero:N \l_@@_crossing_int + \int_incr:N \l_@@_crossing_int + + \seq_map_inline:Nn \l_@@_word_seq + { +% \end{macrocode} +% Clear the flags for this segment of the braid word +% \begin{macrocode} + \seq_clear:N \l_@@_crossing_seq + \bool_set_true:N \l_@@_step_level_bool + \bool_set_false:N \l_@@_floor_bool + \bool_set_false:N \l_@@_swap_crossing_bool + ##1 +% \end{macrocode} +% If we're drawing a floor, do so straightaway. +% \begin{macrocode} + \bool_if:NT \l_@@_floor_bool + { + \@@_do_floor:Vxxxx \l_@@_crossing_int + {\fp_eval:n + { + -1*sign(\@@_dim_value:n{width}) + * \@@_dim_value:n {floor~ border} + } + pt + } + {\fp_to_decimal:N \l_@@_height_fp pt} + {\fp_eval:n { \l_@@_width_fp / \dim_to_fp:n {1cm} }} + {\fp_eval:n { ( \@@_dim_value:n {height} ) / \dim_to_fp:n {1cm}}} + } +% \end{macrocode} +% If we have a crossing, process it. +% \begin{macrocode} + \seq_if_empty:NF \l_@@_crossing_seq + { +% \end{macrocode} +% Keep track of the current permutation. +% \begin{macrocode} + \prop_get:NxN \l_@@_crossing_permutation_prop + {\seq_item:Nn \l_@@_crossing_seq {1}} \l_@@_tmpa_tl + \prop_get:NxN \l_@@_crossing_permutation_prop + {\seq_item:Nn \l_@@_crossing_seq {2}} \l_@@_tmpb_tl + + \prop_put:NxV \l_@@_crossing_permutation_prop + {\seq_item:Nn \l_@@_crossing_seq {2}} \l_@@_tmpa_tl + \prop_put:NxV \l_@@_crossing_permutation_prop + {\seq_item:Nn \l_@@_crossing_seq {1}} \l_@@_tmpb_tl +% \end{macrocode} +% Now get the strands corresponding to the ones involved in the crossing. +% \begin{macrocode} + \prop_get:NxN \l_@@_strands_prop + {\seq_item:Nn \l_@@_crossing_seq {1}} \l_@@_tmpa_tl + \prop_get:NxN \l_@@_strands_prop + {\seq_item:Nn \l_@@_crossing_seq {2}} \l_@@_tmpb_tl +% \end{macrocode} +% The over-strand is easy as that's a single curve. +% \begin{macrocode} + \tl_put_right:Nx \l_@@_tmpa_tl + { + \exp_not:N \@@_lineto:nn + + {\fp_eval:n + { + (\seq_item:Nn \l_@@_crossing_seq {1} - 1) + * \@@_dim_value:n {width} + } + } + {\fp_eval:n { \l_@@_height_fp + \l_@@_nudge_fp } } + + \exp_not:N \@@_curveto:nnnnnn + + {0} + {\fp_eval:n { \l_@@_control_fp}} + + {0} + {\fp_eval:n {- \l_@@_control_fp}} + + {\fp_eval:n + { + (\seq_item:Nn \l_@@_crossing_seq {2} - 1) + * \@@_dim_value:n {width} + } + } + {\fp_eval:n + { + \l_@@_height_fp + + \@@_dim_value:n {height} + - \l_@@_nudge_fp + } + } + } +% \end{macrocode} +% The under-strand is a bit more complicated as we need to break it in the middle. +% \begin{macrocode} + \tl_put_right:Nx \l_@@_tmpb_tl + { + \exp_not:N \@@_lineto:nn + + {\fp_eval:n + { + (\seq_item:Nn \l_@@_crossing_seq {2} - 1) + * \@@_dim_value:n {width} + } + } + {\fp_eval:n { \l_@@_height_fp + \l_@@_nudge_fp } } + + \exp_not:N \@@_curveto:nnnnnn + + {0} + { + \fp_eval:n { + \l_@@_control_fp * (.5 - \@@_value:n {gap} ) + } + } + + { + \fp_eval:n { + - (.5 - \@@_value:n {gap} ) / 3 * + \@@_bezier_tangent:nnnnn + {.5 - \@@_value:n {gap} } + {0} + {0} + { + (\seq_item:Nn \l_@@_crossing_seq {1} + - \seq_item:Nn \l_@@_crossing_seq {2}) + * \@@_dim_value:n {width} + } + { + (\seq_item:Nn \l_@@_crossing_seq {1} + - \seq_item:Nn \l_@@_crossing_seq {2}) + * \@@_dim_value:n {width} + } + } + } + { + \fp_eval:n { + -(.5 - \@@_value:n {gap} ) / 3 * + \@@_bezier_tangent:nnnnn + {.5 - \@@_value:n {gap} } + {0} + {\l_@@_control_fp} + { + \@@_dim_value:n {height} + - 2* \l_@@_nudge_fp + - \l_@@_control_fp + } + {\@@_dim_value:n {height} - 2* \l_@@_nudge_fp} + } + } + + { + \fp_eval:n { + (\seq_item:Nn \l_@@_crossing_seq {2} - 1) + * \@@_dim_value:n {width} + + \@@_bezier_point:nnnnn + {.5 - \@@_value:n {gap} } + {0} + {0} + { + (\seq_item:Nn \l_@@_crossing_seq {1} + - \seq_item:Nn \l_@@_crossing_seq {2}) + * \@@_dim_value:n {width} + } + { + (\seq_item:Nn \l_@@_crossing_seq {1} + - \seq_item:Nn \l_@@_crossing_seq {2}) + * \@@_dim_value:n {width} + } + } + } + { + \fp_eval:n { + \l_@@_height_fp + \l_@@_nudge_fp + + \@@_bezier_point:nnnnn + {.5 - \@@_value:n {gap} } + {0} + {\l_@@_control_fp} + { + \@@_dim_value:n {height} + - 2* \l_@@_nudge_fp + - \l_@@_control_fp + } + {\@@_dim_value:n {height} - 2* \l_@@_nudge_fp} + } + } + + \exp_not:N \@@_moveto:nn + { + \fp_eval:n { + (\seq_item:Nn \l_@@_crossing_seq {2} - 1) + * \@@_dim_value:n {width} + + \@@_bezier_point:nnnnn + {.5 + \@@_value:n {gap} } + {0} + {0} + { + (\seq_item:Nn \l_@@_crossing_seq {1} + - \seq_item:Nn \l_@@_crossing_seq {2}) + * \@@_dim_value:n {width} + } + { + (\seq_item:Nn \l_@@_crossing_seq {1} + - \seq_item:Nn \l_@@_crossing_seq {2}) + * \@@_dim_value:n {width} + } + } + } + { + \fp_eval:n { + \l_@@_height_fp + \l_@@_nudge_fp + + \@@_bezier_point:nnnnn + {.5 + \@@_value:n {gap} } + {0} + {\l_@@_control_fp} + { + \@@_dim_value:n {height} - 2* \l_@@_nudge_fp + - \l_@@_control_fp + } + {\@@_dim_value:n {height} - 2* \l_@@_nudge_fp} + } + } + + \exp_not:N \@@_curveto:nnnnnn + + { + \fp_eval:n { + (.5 - \@@_value:n {gap} ) / 3 * + \@@_bezier_tangent:nnnnn + {.5 + \@@_value:n {gap} } + {0} + {0} + { + (\seq_item:Nn \l_@@_crossing_seq {1} + - \seq_item:Nn \l_@@_crossing_seq {2}) + * \@@_dim_value:n {width} + } + { + (\seq_item:Nn \l_@@_crossing_seq {1} + - \seq_item:Nn \l_@@_crossing_seq {2}) + * \@@_dim_value:n {width} + } + } + } + { + \fp_eval:n { + (.5 - \@@_value:n {gap} ) / 3 * + \@@_bezier_tangent:nnnnn + {.5 + \@@_value:n {gap} } + {0} + {\l_@@_control_fp} + { + \@@_dim_value:n {height} - 2* \l_@@_nudge_fp + - \l_@@_control_fp + } + {\@@_dim_value:n {height} - 2* \l_@@_nudge_fp} + } + } + + {0} + { \fp_eval:n { + -\l_@@_control_fp * (.5 - \@@_value:n {gap} ) + } + } + + + {\fp_eval:n + { + (\seq_item:Nn \l_@@_crossing_seq {1} - 1) + * \@@_dim_value:n {width} + } + } + {\fp_eval:n + { + \l_@@_height_fp + \@@_dim_value:n {height} + - \l_@@_nudge_fp + } + } + + } +% \end{macrocode} +% Now put those new strands back in the prop. +% \begin{macrocode} + \prop_put:NxV \l_@@_strands_prop + {\seq_item:Nn \l_@@_crossing_seq {2}} \l_@@_tmpa_tl + \prop_put:NxV \l_@@_strands_prop + {\seq_item:Nn \l_@@_crossing_seq {1}} \l_@@_tmpb_tl +% \end{macrocode} +% If the strands are more than one apart, the intermediate strands need to be broken as well. +% \begin{macrocode} + \int_compare:nT + { + \int_max:nn + { + \seq_item:Nn \l_@@_crossing_seq {1} + } + { + \seq_item:Nn \l_@@_crossing_seq {2} + } + - + \int_min:nn + { + \seq_item:Nn \l_@@_crossing_seq {1} + } + { + \seq_item:Nn \l_@@_crossing_seq {2} + } + > 1 + } + { + \int_step_inline:nnnn + { + \int_min:nn + { + \seq_item:Nn \l_@@_crossing_seq {1} + } + { + \seq_item:Nn \l_@@_crossing_seq {2} + } + + 1} + {1} + { + \int_max:nn + { + \seq_item:Nn \l_@@_crossing_seq {1} + } + { + \seq_item:Nn \l_@@_crossing_seq {2} + } + - 1 + } + { + + \prop_get:NnN \l_@@_strands_prop {####1} \l_@@_tmpa_tl + \tl_put_right:Nx \l_@@_tmpa_tl + { + \exp_not:N \@@_lineto:nn + {\fp_eval:n {(####1 - 1) * \@@_dim_value:n {width} }} + {\fp_eval:n + { + \l_@@_height_fp + \l_@@_nudge_fp + + .5 * \l_@@_control_fp + } + } + \exp_not:N \@@_moveto:nn + {\fp_eval:n {(####1 - 1) * \@@_dim_value:n {width} }} + {\fp_eval:n + { + \l_@@_height_fp + \@@_dim_value:n {height} + - \l_@@_nudge_fp - .5 * \l_@@_control_fp + } + } + } + + \prop_put:NnV \l_@@_strands_prop {####1} \l_@@_tmpa_tl + } + } + } +% \end{macrocode} +% If we're to step the level, increase the height and add a load of coordinates. +% \begin{macrocode} + \bool_if:NT \l_@@_step_level_bool + { + \fp_add:Nn \l_@@_height_fp { \@@_dim_value:n {height} } + + \int_step_inline:nnnn {1} {1} {\l_@@_strands_int} + { + \prop_get:NnN \l_@@_crossing_permutation_prop + {####1} \l_@@_tmpb_tl + \prop_get:NVN \l_@@_inverse_prop + \l_@@_tmpb_tl \l_@@_tmpa_tl + + \@@_coordinate:xxxx + {-\l_@@_tmpb_tl-\int_use:N \l_@@_crossing_int} + {-rev-\l_@@_tmpa_tl-\int_use:N \l_@@_crossing_int } + {\fp_eval:n { (####1 - 1) * \@@_dim_value:n {width} }} + {\fp_to_decimal:N \l_@@_height_fp} + } + + \int_incr:N \l_@@_crossing_int + } + } + + \fp_add:Nn \l_@@_height_fp + { + sign(\@@_dim_value:n {height}) + * \@@_dim_value:n {border~ height} + } +% \end{macrocode} +% Add a little bit to the end of each strand, together with some coordinates. +% \begin{macrocode} + \int_step_inline:nnnn {1} {1} {\l_@@_strands_int} + { + \prop_get:NxN \l_@@_strands_prop {##1} \l_@@_tmpa_tl + \prop_get:NxN \l_@@_permutation_prop {##1} \l_@@_tmpb_tl + + \tl_put_right:Nx \l_@@_tmpa_tl { + \exp_not:N \@@_lineto:nn + {\fp_eval:n { (##1 - 1) * \@@_dim_value:n {width} }} + {\fp_to_decimal:N \l_@@_height_fp} + coordinate (-rev-##1-e) + coordinate (-\l_@@_tmpb_tl-e) + ; + } + + \prop_put:NnV \l_@@_strands_prop {##1} \l_@@_tmpa_tl + } +% \end{macrocode} +% This is where we actually carry out the drawing commands. +% \begin{macrocode} + \int_step_inline:nnnn {1} {1} {\l_@@_strands_int} + { + \prop_get:NnN \l_@@_strands_prop {##1} \l_@@_tmpa_tl + \tl_use:N \l_@@_tmpa_tl + } + \end{scope} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_moveto:nn, \@@_lineto:nn, \@@_curveto:nnnnnn, \@@_coordinate:nnnn} +% These are our interfaces to the TikZ code. +% \begin{macrocode} +\cs_new_nopar:Npn \@@_moveto:nn #1#2 +{ + (#1 pt, #2 pt) +} +\cs_new_nopar:Npn \@@_lineto:nn #1#2 +{ + -- (#1 pt, #2 pt) +} +\cs_new_nopar:Npn \@@_curveto:nnnnnn #1#2#3#4#5#6 +{ + .. controls +(#1 pt, #2 pt) and +(#3 pt, #4 pt) + .. (#5 pt, #6 pt) +} +\cs_new_nopar:Npn \@@_coordinate:nnnn #1#2#3#4 +{ + \coordinate[alias=#2] (#1) at (#3 pt,#4 pt); +} +\cs_generate_variant:Nn \@@_coordinate:nnnn {xxxx} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\@@_bezier_point:nnnnn, \@@_bezier_tangent:nnnnn} +% Used to calculate intermediate points and tangents on a bezier curve. +% \begin{macrocode} +\cs_new_nopar:Npn \@@_bezier_point:nnnnn #1#2#3#4#5 +{ + \fp_eval:n + { + (1 - (#1)) * (1 - (#1)) * (1 - (#1)) * (#2) + + + 3 * (1 - (#1)) * (1 - (#1)) * (#1) * (#3) + + + 3 * (1 - (#1)) * (#1) * (#1) * (#4) + + + (#1) * (#1) * (#1) * (#5) + } +} +\cs_new_nopar:Npn \@@_bezier_tangent:nnnnn #1#2#3#4#5 +{ + \fp_eval:n + { + 3 * (1 - (#1)) * (1 - (#1)) * (#3 - (#2)) + + + 6 * (1 - (#1)) * (#1) * (#4 - (#3)) + + + 3 * (#1) * (#1) * (#5 - (#4)) + } +} +\cs_new_nopar:Npn \@@_do_floor:nnnnn #1#2#3#4#5 +{ + \pic[pic~ type=floor, + xscale=#4, + yscale=#5, + at={(#2,#3)}, + braid/every~ floor/.try, + braid/floor~#1/.try, + ]; +} +\cs_generate_variant:Nn \@@_do_floor:nnnnn {Vxxxx} +% \end{macrocode} +% \end{macro} +% \begin{macrocode} +\ExplSyntaxOff +% \end{macrocode} +% +% \iffalse +%</library> +% \fi +% +% \Finale + +\endinput diff --git a/Master/texmf-dist/source/latex/braids/braids_code.ins b/Master/texmf-dist/source/latex/braids/braids_code.ins new file mode 100644 index 00000000000..4e3678839fd --- /dev/null +++ b/Master/texmf-dist/source/latex/braids/braids_code.ins @@ -0,0 +1,83 @@ +%% +%% This is file `braids_code.ins', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% braids_code.dtx (with options: `install') +%% ---------------------------------------------------------------- +%% braids --- a style file for drawing braid diagrams with TikZ/PGF +%% E-mail: loopspace@mathforge.org +%% Released under the LaTeX Project Public License v1.3c or later +%% See http://www.latex-project.org/lppl.txt +%% ---------------------------------------------------------------- +%% +\input l3docstrip.tex +\keepsilent +\askforoverwritefalse +\preamble +---------------------------------------------------------------- +braids --- a style file for drawing braid diagrams with TikZ/PGF +E-mail: loopspace@mathforge.org +Released under the LaTeX Project Public License v1.3c or later +See http://www.latex-project.org/lppl.txt +---------------------------------------------------------------- + +\endpreamble +\postamble + +Copyright (C) 2011-2019 by Andrew Stacey <loopspace@mathforge.org> + +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, + tikzlibrarybraids.code.tex, + braids_doc.pdf. + +\endpostamble +\usedir{tex/latex/braids} +\generate{ + \file{braids.sty}{\from{\jobname.dtx}{package}} +} +\generate{ + \file{tikzlibrarybraids.code.tex}{\from{\jobname.dtx}{library}} +} +\endbatchfile + +%% +%% Copyright (C) 2011-2019 by Andrew Stacey <loopspace@mathforge.org> +%% +%% 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, +%% tikzlibrarybraids.code.tex, +%% braids_doc.pdf. +%% +%% +%% End of file `braids_code.ins'. diff --git a/Master/texmf-dist/tex/latex/braids/braids.sty b/Master/texmf-dist/tex/latex/braids/braids.sty index f7edd15f724..d9976eec067 100644 --- a/Master/texmf-dist/tex/latex/braids/braids.sty +++ b/Master/texmf-dist/tex/latex/braids/braids.sty @@ -4,21 +4,19 @@ %% %% The original source files were: %% -%% braids.dtx (with options: `package') +%% braids_code.dtx (with options: `package') %% ---------------------------------------------------------------- %% braids --- a style file for drawing braid diagrams with TikZ/PGF -%% E-mail: stacey@math.ntnu.no +%% E-mail: loopspace@mathforge.org %% Released under the LaTeX Project Public License v1.3c or later %% See http://www.latex-project.org/lppl.txt %% ---------------------------------------------------------------- %% \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{braids}[2011/05/07 v1.0 Tikz/PGF commands for drawing braid diagrams] -\def\braid@pgfversion{2.10}% -\ifx\pgfversion\braid@pgfversion -\else -\PackageWarning{braids}{This package was designed using PGF2.10; you are using \pgfversion.}% -\fi +\ProvidesPackage{braids}[2011/10/18 v1.1 Tikz/PGF commands for drawing braid diagrams] +\PackageWarning{braids}{% + This package has been reimplemented as a TikZ library; if starting with a fresh document, please consider using that instead.% +}% \long\def\ge@addto@macro#1#2{% \begingroup \toks@\expandafter\expandafter\expandafter{\expandafter#1#2}% @@ -71,7 +69,14 @@ \ifx\braid@token- \braid@increase@levelfalse \else - \ifx\braid@token[ + \ifx\braid@token1% + \ifbraid@increase@level + \stepcounter{braid@level} + \fi + \braid@increase@leveltrue + \ge@addto@macro\braid@label{\braid@token}% + \else + \ifx\braid@token[% \let\braid@next=\braid@process@options \else \ifx\braid@token\braid@bar @@ -84,6 +89,12 @@ \ifx\braid@token\egroup \braid@endscope \else + \ifx\braid@token\braid@olabel@strand + \let\braid@next=\braid@olabel@strand + \else + \ifx\braid@token\braid@clabel@strand + \let\braid@next=\braid@clabel@strand + \else \ge@addto@macro\braid@label{\braid@token}% \fi \fi @@ -93,6 +104,9 @@ \fi \fi \fi + \fi + \fi + \fi \braid@next% } \def\braid@maybe@locate{% @@ -140,9 +154,18 @@ \tikzset{#1}% \braid@process% } -\def\braid@sup#1_#2{\g@addto@macro\braid@label{_{#2}^{#1}}\braid@add@crossing{#2}{#1}} -\def\braid@sub#1{\@ifnextchar^{\braid@@sub{#1}}{\g@addto@macro\braid@label{_{#1}}\braid@add@crossing{#1}{1}}} -\def\braid@@sub#1^#2{\g@addto@macro\braid@label{_{#1}^{#2}}\braid@add@crossing{#1}{#2}} +\def\braid@sup#1_#2{% + \g@addto@macro\braid@label{_{#2}^{#1}}% + \braid@add@crossing{#2}{#1}% +} +\def\braid@sub#1{% + \@ifnextchar^{\braid@@sub{#1}}% + {\g@addto@macro\braid@label{_{#1}}\braid@add@crossing{#1}{1}}% +} +\def\braid@@sub#1^#2{% + \g@addto@macro\braid@label{_{#1}^{#2}}% + \braid@add@crossing{#1}{#2}% +} \def\braid@ne{1} \def\braid@add@crossing#1#2{% \edef\braid@crossing@type{#2}% @@ -159,60 +182,197 @@ \braid@ny=\braid@ty \advance\braid@nx by \braid@width \advance\braid@ny by \braid@height + \advance\braid@ty by \braid@nf\braid@height + \advance\braid@ny by -\braid@nf\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 - \expandafter\let\expandafter\braid@this@path@origin\csname braid@strand@\braid@this@strand @origin\endcsname + \advance\braid@cy by \braid@cf\braid@height + \advance\braid@dy by -\braid@cf\braid@height + \expandafter\let\expandafter\braid@this@path@origin% + \csname braid@strand@\braid@this@strand @origin\endcsname \ifx\braid@this@path@origin\relax \let\braid@this@path@origin\braid@this@strand \pgfsyssoftpath@setcurrentpath{\@empty} \pgfpathmoveto{\pgfpoint{\braid@tx}{0pt}} \pgfsyssoftpath@getcurrentpath{\braid@this@path} \else - \expandafter\let\expandafter\braid@this@path\csname braid@strand@\braid@this@path@origin\endcsname + \expandafter\let\expandafter\braid@this@path% + \csname braid@strand@\braid@this@path@origin\endcsname \fi - \expandafter\let\expandafter\braid@next@path@origin\csname braid@strand@\braid@next@strand @origin\endcsname + \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 + \expandafter\let\expandafter\braid@next@path% + \csname braid@strand@\braid@next@path@origin\endcsname \fi \pgfsyssoftpath@setcurrentpath{\braid@this@path} \pgfpathlineto{\pgfqpoint{\braid@tx}{\braid@ty}} +\pgfmathsetmacro{\braid@gst}{0.5 - \pgfkeysvalueof{/pgf/braid/gap}}% +\pgfmathsetmacro{\braid@gend}{0.5 + \pgfkeysvalueof{/pgf/braid/gap}}% \ifx\braid@crossing@type\braid@over@cross -\pgfpathcurveto{\pgfqpoint{\braid@tx}{\braid@cy}}{\pgfqpoint{\braid@nx}{\braid@dy}}{\pgfqpoint{\braid@nx}{\braid@ny}} + \pgfpathcurveto{\pgfqpoint{\braid@tx}{\braid@cy}}% + {\pgfqpoint{\braid@nx}{\braid@dy}}% + {\pgfqpoint{\braid@nx}{\braid@ny}} \else -\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}} + \pgfpathcurvebetweentimecontinue{0}{\braid@gst}% + {\pgfqpoint{\braid@tx}{\braid@ty}}% + {\pgfqpoint{\braid@tx}{\braid@cy}}% + {\pgfqpoint{\braid@nx}{\braid@dy}}% + {\pgfqpoint{\braid@nx}{\braid@ny}}% + \pgfpathcurvebetweentime{\braid@gend}{1}% + {\pgfqpoint{\braid@tx}{\braid@ty}}% + {\pgfqpoint{\braid@tx}{\braid@cy}}% + {\pgfqpoint{\braid@nx}{\braid@dy}}% + {\pgfqpoint{\braid@nx}{\braid@ny}} \fi \pgfsyssoftpath@getcurrentpath{\braid@this@path} \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}} + \pgfpathcurvebetweentimecontinue{0}{\braid@gst}% + {\pgfqpoint{\braid@nx}{\braid@ty}}% + {\pgfqpoint{\braid@nx}{\braid@cy}}% + {\pgfqpoint{\braid@tx}{\braid@dy}}% + {\pgfqpoint{\braid@tx}{\braid@ny}} + \pgfpathcurvebetweentime{\braid@gend}{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}} + \pgfpathcurveto{\pgfqpoint{\braid@nx}{\braid@cy}}% + {\pgfqpoint{\braid@tx}{\braid@dy}}% + {\pgfqpoint{\braid@tx}{\braid@ny}} \fi \pgfsyssoftpath@getcurrentpath{\braid@next@path} - \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 - \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 - \pgfmathparse{\value{braid@strands} < \braid@next@strand ? "\noexpand\setcounter{braid@strands}{\braid@next@strand}" : ""} + \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 + \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 + \pgfmathparse{\value{braid@strands} < \braid@next@strand ? + "\noexpand\setcounter{braid@strands}{\braid@next@strand}" : ""} \pgfmathresult \braid@process% } +\newcommand{\braid@olabel@strand}[3][]{% + \edef\braid@tmp{{\the\value{braid@level}}}% + \expandafter\ifx\csname braid@strand@#2@origin\endcsname\relax + \g@addto@macro\braid@tmp{{#2}}% + \else + \edef\braid@tmpa{{\csname braid@strand@#2@origin\endcsname}}% + \ge@addto@macro\braid@tmp{\braid@tmpa}% + \fi + \g@addto@macro\braid@tmp{{#3}{#1}}% + \ge@addto@macro{\braid@strand@labels}{\braid@tmp}% + \braid@process% +} +\newcommand{\braid@clabel@strand}[3][]{% + \edef\braid@tmp{{\the\value{braid@level}}}% + \g@addto@macro\braid@tmp{{#2}{#3}{#1}}% + \ge@addto@macro{\braid@strand@labels}{\braid@tmp}% + \braid@process% +} \def\braid@floors@trim,{} \def\braid@render@floor{% \draw (\floorsx,\floorsy) rectangle (\floorex,\floorey); } +\def\braid@render@strand@labels#1{% + \def\braid@tmp{#1}% + \ifx\braid@tmp\pgfutil@empty + \let\braid@next=\pgfutil@gobble + \else + \let\braid@next=\braid@@render@strand@labels + \fi + \braid@next{#1}% +} +\def\braid@@render@strand@labels#1#2#3#4{% + \begingroup + \pgfscope + \let\tikz@options=\pgfutil@empty + \let\tikz@mode=\pgfutil@empty + \let\tik@transform=\pgfutil@empty + \let\tikz@fig@name=\pgfutil@empty + \tikzset{/pgf/braid/strand label,#4}% + \braid@nx=#2\braid@width + \braid@ny=#1\braid@height + \advance\braid@ny by \braid@eh + \advance\braid@ny by \braid@height + \pgftransformshift{\pgfqpoint{\braid@nx}{\braid@ny}}% + \tikz@options + \setbox\pgfnodeparttextbox=\hbox% + \bgroup% + \tikzset{every text node part/.try}% + \ifx\tikz@textopacity\pgfutil@empty% + \else% + \pgfsetfillopacity{\tikz@textopacity}% + \pgfsetstrokeopacity{\tikz@textopacity}% + \fi% + \pgfinterruptpicture% + \tikz@textfont% + \ifx\tikz@text@width\pgfutil@empty% + \else% + \begingroup% + \pgfmathsetlength{\pgf@x}{\tikz@text@width}% + \pgfutil@minipage[t]{\pgf@x}\leavevmode\hbox{}% + \tikz@text@action% + \fi% + \tikz@atbegin@node% + \bgroup% + \aftergroup\unskip% + \ifx\tikz@textcolor\pgfutil@empty% + \else% + \pgfutil@colorlet{.}{\tikz@textcolor}% + \fi% + \pgfsetcolor{.}% + \setbox\tikz@figbox=\box\pgfutil@voidb@x% + \tikz@uninstallcommands% + \tikz@halign@check% + \ignorespaces% + #3 + \egroup + \tikz@atend@node% + \ifx\tikz@text@width\pgfutil@empty% + \else% + \pgfutil@endminipage% + \endgroup% + \fi% + \endpgfinterruptpicture% + \egroup% + \ifx\tikz@text@width\pgfutil@empty% + \else% + \pgfmathsetlength{\pgf@x}{\tikz@text@width}% + \wd\pgfnodeparttextbox=\pgf@x% + \fi% + \ifx\tikz@text@height\pgfutil@empty% + \else% + \pgfmathsetlength{\pgf@x}{\tikz@text@height}% + \ht\pgfnodeparttextbox=\pgf@x% + \fi% + \ifx\tikz@text@depth\pgfutil@empty% + \else% + \pgfmathsetlength{\pgf@x}{\tikz@text@depth}% + \dp\pgfnodeparttextbox=\pgf@x% + \fi% + \pgfmultipartnode{\tikz@shape}{\tikz@anchor}{\tikz@fig@name}{% + {\begingroup\tikz@finish}% + }% + \endpgfscope + \endgroup + \braid@render@strand@labels% +} \def\braid@render{ \ifx\braid@floors\@empty \else @@ -237,7 +397,8 @@ \let\tikz@options=\pgfutil@empty \expandafter\tikzset\expandafter{\braid@floors@style} \pgfmathtruncatemacro{\braid@ff}{\braid@f+2} - \expandafter\let\expandafter\braid@floor@style\csname braid@options@floor@\braid@ff\endcsname + \expandafter\let\expandafter\braid@floor@style% + \csname braid@options@floor@\braid@ff\endcsname \ifx\braid@floor@style\relax \else \expandafter\tikzset\expandafter{\braid@floor@style}% @@ -257,18 +418,21 @@ \braid@tx=\braid@k\braid@width \braid@ty=\value{braid@level}\braid@height \advance\braid@ty by 2\braid@eh - \expandafter\let\expandafter\braid@path@origin\csname braid@strand@\braid@k @origin\endcsname + \expandafter\let\expandafter\braid@path@origin% + \csname braid@strand@\braid@k @origin\endcsname \ifx\braid@path@origin\relax \pgfsyssoftpath@setcurrentpath{\@empty} \pgfpathmoveto{\pgfqpoint{\braid@tx}{0pt}} \let\braid@path@origin\braid@k \else - \expandafter\let\expandafter\braid@path\csname braid@strand@\braid@path@origin\endcsname + \expandafter\let\expandafter\braid@path% + \csname braid@strand@\braid@path@origin\endcsname \pgfsyssoftpath@setcurrentpath{\braid@path} \fi \pgflineto{\pgfqpoint{\braid@tx}{\braid@ty}} \expandafter\tikzset\expandafter{\braid@style} - \expandafter\let\expandafter\braid@style\csname braid@options@strand@\braid@path@origin\endcsname + \expandafter\let\expandafter\braid@style% + \csname braid@options@strand@\braid@path@origin\endcsname \ifx\braid@style\relax \else \expandafter\tikzset\expandafter{\braid@style} @@ -300,25 +464,40 @@ \braid@ty=.5\braid@ty \coordinate (\braid@name) at (\braid@tx,\braid@ty); \fi + \ifx\braid@strand@labels\pgfutil@empty + \else + \expandafter\braid@render@strand@labels\braid@strand@labels{}% + \fi \pgfsys@endscope \endgroup} \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 + \pgfsys@beginscope + \setcounter{braid@level}{-1}% + \let\braid@label\@empty + \let\braid@strand@labels\@empty + \let\braid@floors\@empty + \let\braid@name\empty + \let\clabel=\braid@clabel@strand + \let\olabel=\braid@olabel@strand + \pgfkeys{/pgf/braid/.cd,#1}% + \ifbraid@strand@labels@origin + \let\label=\braid@olabel@strand + \else + \let\label=\braid@clabel@strand + \fi + \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 + \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}% + \pgfkeysgetvalue{/pgf/braid/control factor}{\braid@cf}% + \pgfkeysgetvalue{/pgf/braid/nudge factor}{\braid@nf}% + \braid@height=-\braid@height + \braid@eh=-\braid@eh + \braid@increase@leveltrue + \braid@process@start } \newdimen\braid@width \newdimen\braid@height @@ -330,6 +509,7 @@ \newdimen\braid@dy \newdimen\braid@eh \newif\ifbraid@increase@level +\newif\ifbraid@strand@labels@origin \let\braid@style\pgfutil@empty \let\braid@floors@style\pgfutil@empty \def\braid@over@cross{1} @@ -342,7 +522,10 @@ number of strands/.initial=0, height/.initial=1cm, width/.initial=1cm, + gap/.initial=.1, border height/.initial=.25cm, + control factor/.initial=.5, + nudge factor/.initial=.05, name/.code={% \def\braid@name{#1}% }, @@ -357,24 +540,28 @@ \braidset{style each strand/.list={#1}}% }, style each strand/.code={% - \expandafter\edef\csname braid@options@strand@#1\endcsname{\braid@temp}% + \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}% + \expandafter\edef% + \csname braid@options@floor@#1\endcsname{\braid@temp}% }, style all floors/.code={% \def\braid@floors@style{#1} - } + }, + strand label/.style={}, + strand label by origin/.is if=braid@strand@labels@origin, } \def\braidset#1{% \pgfkeys{/pgf/braid/.cd,#1}} %% -%% Copyright (C) 2011 by Andrew Stacey <stacey@math.ntnu.no> +%% Copyright (C) 2011-2019 by Andrew Stacey <loopspace@mathforge.org> %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License (LPPL), either @@ -392,6 +579,7 @@ %% braids.ins, %% braids.pdf, %% braids.sty, +%% tikzlibrarybraids.code.tex, %% braids_doc.pdf. %% %% diff --git a/Master/texmf-dist/tex/latex/braids/tikzlibrarybraids.code.tex b/Master/texmf-dist/tex/latex/braids/tikzlibrarybraids.code.tex new file mode 100644 index 00000000000..6bef1d8b8ce --- /dev/null +++ b/Master/texmf-dist/tex/latex/braids/tikzlibrarybraids.code.tex @@ -0,0 +1,916 @@ +%% +%% This is file `tikzlibrarybraids.code.tex', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% braids_code.dtx (with options: `library') +%% ---------------------------------------------------------------- +%% braids --- a style file for drawing braid diagrams with TikZ/PGF +%% E-mail: loopspace@mathforge.org +%% Released under the LaTeX Project Public License v1.3c or later +%% See http://www.latex-project.org/lppl.txt +%% ---------------------------------------------------------------- +%% +\ProvidesFile{tikzlibrarybraids.code.tex}[% + 2019/03/20 v2.0 Tikz/PGF library for drawing braid diagrams% +] +\RequirePackage{expl3} +\ExplSyntaxOn +\tl_new:N \l__braid_tmpa_tl +\tl_new:N \l__braid_tmpb_tl +\tl_new:N \l__braid_tmpc_tl +\tl_new:N \l__braid_tmpd_tl +\tl_new:N \l__braid_anchor_strand_tl +\tl_new:N \l__braid_anchor_level_tl +\fp_new:N \l__braid_height_fp +\fp_new:N \l__braid_width_fp +\fp_new:N \l__braid_nudge_fp +\fp_new:N \l__braid_control_fp +\fp_new:N \l__braid_ctrlax_fp +\fp_new:N \l__braid_ctrlay_fp +\fp_new:N \l__braid_ctrlbx_fp +\fp_new:N \l__braid_ctrlby_fp +\fp_new:N \l__braid_endx_fp +\fp_new:N \l__braid_endy_fp +\fp_new:N \l__braid_anchor_x_fp +\fp_new:N \l__braid_anchor_y_fp +\int_new:N \l__braid_tmpa_int +\int_new:N \l__braid_length_int +\int_new:N \l__braid_strands_int +\int_new:N \l__braid_crossing_int +\int_new:N \l__braid_anchor_level_int +\int_new:N \l__braid_floor_int +\seq_new:N \l__braid_word_seq +\seq_new:N \l__braid_crossing_seq +\seq_new:N \l__braid_anchor_seq +\seq_new:N \l__braid_floors_seq +\str_new:N \l__braid_tmpa_str +\str_new:N \l__braid_sup_str +\str_set:Nn \l__braid_sup_str {^} +\str_new:N \l__braid_sub_str +\str_set:Nn \l__braid_sub_str {_} +\str_new:N \l__braid_hyphen_str +\str_set:Nn \l__braid_hyphen_str {-} +\str_new:N \l__braid_bar_str +\str_set:Nn \l__braid_bar_str {|} +\str_new:N \l__braid_one_str +\str_set:Nn \l__braid_one_str {1} +\bool_new:N \l__braid_step_level_bool +\bool_new:N \l__braid_swap_crossing_bool +\bool_new:N \l__braid_floor_bool +\prop_new:N \l__braid_strands_prop +\prop_new:N \l__braid_permutation_prop +\prop_new:N \l__braid_crossing_permutation_prop +\prop_new:N \l__braid_inverse_prop +\prop_new:N \l__braid_anchor_prop +\tikzset{ + braid/.pic={ + code={ + \__braid_parse_word:n {#1} + \__braid_count: + \__braid_render: + } + }, + floor/.pic={ + code={ + \path[pic~ actions, draw=none] (0,0) rectangle (1,1); + \path[pic~ actions, fill=none] (0,0) -- (1,0) (0,1) -- (1,1); + } + }, + /tikz/braid/.search~ also={/tikz}, + braid/.cd, + anchor/.initial=1-s, + number~ of~ strands/.initial=0, + height/.initial=-1cm, + width/.initial=1cm, + gap/.initial=.05, + border~ height/.initial=.25cm, + floor~ border/.initial=.25cm, + add~ floor/.code={ + \seq_push:Nn \l__braid_floors_seq {#1} + }, + control~ factor/.initial=.5, + nudge~ factor/.initial=.05 +} +\cs_new_nopar:Npn \__braid_parse_word:n #1 +{ + \seq_clear:N \l__braid_word_seq + \tl_clear:N \l__braid_tmpa_tl + \tl_set:Nn \l__braid_tmpb_tl {#1} + + \bool_until_do:nn { \tl_if_empty_p:N \l__braid_tmpb_tl } + { + \str_set:Nx \l__braid_tmpa_str {\tl_head:N \l__braid_tmpb_tl} + \tl_set:Nx \l__braid_tmpb_tl {\tl_tail:N \l__braid_tmpb_tl} + \str_case_e:nnTF {\l__braid_tmpa_str} + { + {_} + { + \tl_put_right:Nx \l__braid_tmpa_tl + { + \exp_not:N \__braid_parse_index:n {\tl_head:N \l__braid_tmpb_tl} + } + \tl_set:Nx \l__braid_tmpb_tl {\tl_tail:N \l__braid_tmpb_tl} + } + {^} + { + \tl_put_left:Nx \l__braid_tmpa_tl + { + \exp_not:N \__braid_parse_exponent:n {\tl_head:N \l__braid_tmpb_tl} + } + \tl_set:Nx \l__braid_tmpb_tl {\tl_tail:N \l__braid_tmpb_tl} + } + {|} + { + \tl_if_empty:NF \l__braid_tmpa_tl + { + \seq_put_right:NV \l__braid_word_seq \l__braid_tmpa_tl + \tl_clear:N \l__braid_tmpa_tl + } + + \tl_set:Nn \l__braid_tmpa_tl { + \bool_set_false:N \l__braid_step_level_bool + \bool_set_true:N \l__braid_floor_bool + } + \seq_put_right:NV \l__braid_word_seq \l__braid_tmpa_tl + \tl_clear:N \l__braid_tmpa_tl + } + {-} + { + \tl_put_right:Nn \l__braid_tmpa_tl + { + \bool_set_false:N \l__braid_step_level_bool + } + } + {1} + { + \tl_if_empty:NF \l__braid_tmpa_tl + { + \seq_put_right:NV \l__braid_word_seq \l__braid_tmpa_tl + \tl_clear:N \l__braid_tmpa_tl + } + \tl_put_right:Nn \l__braid_tmpa_tl {\__braid_do_identity:} + } + {~} + { + } + } + { + } + { + \tl_if_empty:NF \l__braid_tmpa_tl + { + \seq_put_right:NV \l__braid_word_seq \l__braid_tmpa_tl + \tl_clear:N \l__braid_tmpa_tl + } + } + } + \tl_if_empty:NF \l__braid_tmpa_tl + { + \seq_put_right:NV \l__braid_word_seq \l__braid_tmpa_tl + \tl_clear:N \l__braid_tmpa_tl + } +} +\cs_new_nopar:Npn \__braid_parse_index:n #1 +{ + \seq_set_from_clist:Nn \l__braid_crossing_seq {#1} + \int_compare:nT {\seq_count:N \l__braid_crossing_seq == 1} + { + \seq_put_right:Nx \l__braid_crossing_seq {\int_eval:n {#1 + 1} } + } + \bool_if:NT \l__braid_swap_crossing_bool + { + \seq_pop_left:NN \l__braid_crossing_seq \l__braid_tmpa_tl + \seq_put_right:NV \l__braid_crossing_seq \l__braid_tmpa_tl + } +} +\cs_new_nopar:Npn \__braid_parse_exponent:n #1 +{ + \int_compare:nTF {#1 == -1} + { + \bool_set_true:N \l__braid_swap_crossing_bool + } + { + \bool_set_false:N \l__braid_swap_crossing_bool + } +} +\cs_new_nopar:Npn \__braid_do_identity: +{ +} +\cs_new_nopar:Npn \__braid_count: +{ + \int_zero:N \l__braid_length_int + \int_set:Nn \l__braid_strands_int {\__braid_value:n {number~of~strands}} + \prop_clear:N \l__braid_permutation_prop + \prop_clear:N \l__braid_crossing_permutation_prop + \prop_clear:N \l__braid_anchor_prop + \prop_clear:N \l__braid_inverse_prop + + \seq_map_inline:Nn \l__braid_word_seq + { + \seq_clear:N \l__braid_crossing_seq + \bool_set_true:N \l__braid_step_level_bool + \bool_set_false:N \l__braid_swap_crossing_bool + ##1 + \bool_if:NT \l__braid_step_level_bool + { + \int_incr:N \l__braid_length_int + } + \seq_if_empty:NF \l__braid_crossing_seq + { + \int_set:Nn \l__braid_strands_int + { + \int_max:nn + { + \int_max:nn {\l__braid_strands_int} + { \seq_item:Nn \l__braid_crossing_seq {1}} + } + { + \seq_item:Nn \l__braid_crossing_seq {2} + } + } + } + } + \int_step_inline:nnnn {1} {1} {\l__braid_strands_int} + { + \prop_put:Nnn \l__braid_permutation_prop {##1} {##1} + \prop_put:Nnn \l__braid_anchor_prop {##1} {##1} + \prop_put:Nnn \l__braid_crossing_permutation_prop {##1} {##1} + } + \tl_set:Nx \l__braid_tmpa_tl {\__braid_value:n {anchor}} + \seq_set_split:NnV \l__braid_anchor_seq {-} \l__braid_tmpa_tl + + \tl_set:Nx \l__braid_tmpa_tl {\seq_item:Nn \l__braid_anchor_seq {1}} + \tl_if_eq:VnTF \l__braid_tmpa_tl {rev} + { + \tl_set:Nx \l__braid_anchor_strand_tl {\seq_item:Nn \l__braid_anchor_seq {2}} + \tl_set:Nx \l__braid_anchor_level_tl {\seq_item:Nn \l__braid_anchor_seq {3}} + } + { + \tl_set:Nx \l__braid_anchor_strand_tl {\seq_item:Nn \l__braid_anchor_seq {1}} + \tl_set:Nx \l__braid_anchor_level_tl {\seq_item:Nn \l__braid_anchor_seq {2}} + } + \tl_if_eq:VnTF \l__braid_anchor_level_tl {s} + { + \int_set:Nn \l__braid_anchor_level_int {-1} + } + { + \tl_if_eq:VnTF \l__braid_anchor_level_tl {e} + { + \int_set:Nn \l__braid_anchor_level_int {-1} + } + { + \int_set:Nn \l__braid_anchor_level_int + {\tl_use:N \l__braid_anchor_level_tl} + } + } + + \int_zero:N \l__braid_crossing_int + \int_incr:N \l__braid_crossing_int + \seq_map_inline:Nn \l__braid_word_seq + { + \bool_set_true:N \l__braid_step_level_bool + \seq_clear:N \l__braid_crossing_seq + \bool_set_false:N \l__braid_swap_crossing_bool + ##1 + \seq_if_empty:NF \l__braid_crossing_seq + { + \prop_get:NxN \l__braid_permutation_prop + { + \seq_item:Nn \l__braid_crossing_seq {1} + } \l__braid_tmpa_tl + \prop_get:NxN \l__braid_permutation_prop + { + \seq_item:Nn \l__braid_crossing_seq {2} + } \l__braid_tmpb_tl + + \prop_put:NxV \l__braid_permutation_prop + { + \seq_item:Nn \l__braid_crossing_seq {2} + } \l__braid_tmpa_tl + \prop_put:NxV \l__braid_permutation_prop + { + \seq_item:Nn \l__braid_crossing_seq {1} + } \l__braid_tmpb_tl + } + \int_compare:nT {\l__braid_crossing_int = \l__braid_anchor_level_int} + { + \prop_set_eq:NN \l__braid_anchor_prop \l__braid_permutation_prop + } + \bool_if:NT \l__braid_step_level_bool + { + \int_incr:N \l__braid_crossing_int + } + } + \int_step_inline:nnnn {1} {1} {\l__braid_strands_int} + { + \prop_get:NnN \l__braid_anchor_prop {##1} \l__braid_tmpa_tl + \prop_put:NVn \l__braid_inverse_prop \l__braid_tmpa_tl {##1} + } + \prop_set_eq:NN \l__braid_anchor_prop \l__braid_inverse_prop + \int_step_inline:nnnn {1} {1} {\l__braid_strands_int} + { + \prop_get:NnN \l__braid_permutation_prop {##1} \l__braid_tmpa_tl + \prop_put:NVn \l__braid_inverse_prop \l__braid_tmpa_tl {##1} + } + \tl_set:Nx \l__braid_tmpa_tl {\seq_item:Nn \l__braid_anchor_seq {1}} + \tl_if_eq:VnT \l__braid_tmpa_tl {rev} + { + \prop_get:NVN \l__braid_permutation_prop + \l__braid_anchor_strand_tl \l__braid_anchor_strand_tl + } + \tl_if_eq:VnF \l__braid_anchor_level_tl {s} + { + \tl_if_eq:VnTF \l__braid_anchor_level_tl {e} + { + \prop_get:NVN \l__braid_inverse_prop + \l__braid_anchor_strand_tl \l__braid_anchor_strand_tl + } + { + \prop_get:NVN \l__braid_anchor_prop + \l__braid_anchor_strand_tl \l__braid_anchor_strand_tl + } + } +} +\cs_new_nopar:Npn \__braid_dim_value:n #1 +{ + \dim_to_fp:n {\pgfkeysvalueof{/tikz/braid/#1}} +} +\cs_new_nopar:Npn \__braid_value:n #1 +{ + \pgfkeysvalueof{/tikz/braid/#1} +} +\cs_generate_variant:Nn \prop_get:NnN {NxN} +\cs_generate_variant:Nn \prop_put:Nnn {NxV} +\cs_generate_variant:Nn \tl_if_eq:nnTF {VnTF} +\cs_generate_variant:Nn \tl_if_eq:nnF {VnF} +\cs_generate_variant:Nn \tl_if_eq:nnT {VnT} + +\cs_new_nopar:Npn \__braid_render: +{ + \fp_set:Nn \l__braid_anchor_x_fp { - 1 * (\tl_use:N \l__braid_anchor_strand_tl - 1) * \__braid_dim_value:n {width} } + + \tl_if_eq:VnTF \l__braid_anchor_level_tl {s} + { + \fp_set:Nn \l__braid_anchor_y_fp {0} + } + { + \tl_if_eq:VnTF \l__braid_anchor_level_tl {e} + { + \fp_set:Nn \l__braid_anchor_y_fp { + -1 * \l__braid_length_int * \__braid_dim_value:n {height} + - sign(\__braid_dim_value:n {height}) + * 2 * \__braid_dim_value:n {border~ height} + } + } + { + \fp_set:Nn \l__braid_anchor_y_fp { + -1 * \l__braid_anchor_level_tl * \__braid_dim_value:n {height} + - sign(\__braid_dim_value:n {height}) + * \__braid_dim_value:n {border~ height} + } + } + } + + \begin{scope}[ + shift={ + (\fp_to_decimal:N \l__braid_anchor_x_fp pt, + \fp_to_decimal:N \l__braid_anchor_y_fp pt + ) + } + ] + \prop_clear:N \l__braid_strands_prop + \fp_zero:N \l__braid_height_fp + \fp_zero:N \l__braid_nudge_fp + \fp_zero:N \l__braid_control_fp + \fp_set:Nn \l__braid_height_fp + { + sign(\__braid_dim_value:n {height}) + * \__braid_dim_value:n {border~ height} + } + \fp_set:Nn \l__braid_width_fp + { + (\l__braid_strands_int - 1) * \__braid_dim_value:n {width} + + 2 * sign(\__braid_dim_value:n{width}) + * \__braid_dim_value:n {floor~ border} + } + \fp_set:Nn \l__braid_nudge_fp + { + \__braid_value:n {nudge~ factor} * \__braid_dim_value:n {height} + } + \fp_set:Nn \l__braid_control_fp + { + \__braid_value:n {control~ factor} * \__braid_dim_value:n {height} + } + \fp_sub:Nn \l__braid_control_fp {\l__braid_nudge_fp} + \int_step_inline:nnnn {1} {1} {\l__braid_strands_int} + { + \prop_get:NnN \l__braid_inverse_prop {##1} \l__braid_tmpa_tl + \prop_put:Nnx \l__braid_strands_prop {##1} + { + \exp_not:N \draw[ + braid/every~ strand/.try, + braid/strand~ ##1/.try + ] + \exp_not:N \__braid_moveto:nn { + \fp_eval:n {(##1 - 1) * \__braid_dim_value:n {width} } + } {0} + \exp_not:N \__braid_lineto:nn { + \fp_eval:n {(##1 - 1) * \__braid_dim_value:n {width} } + } { \fp_to_decimal:N \l__braid_height_fp} + } + \__braid_coordinate:xxxx {-##1-s} {-rev-\l__braid_tmpa_tl-s} + {\fp_eval:n {(##1 - 1) * \__braid_dim_value:n {width} }} {0} + + \__braid_coordinate:xxxx {-##1-0} {-rev-\l__braid_tmpa_tl-0} + {\fp_eval:n {(##1 - 1) * \__braid_dim_value:n {width} }} + { \fp_to_decimal:N \l__braid_height_fp} + } + \seq_map_inline:Nn \l__braid_floors_seq + { + \tl_set:Nx \l__braid_tmpa_tl {\clist_item:nn {##1} {5}} + \__braid_do_floor:Vxxxx \l__braid_tmpa_tl + {\fp_eval:n + { + -1*sign(\__braid_dim_value:n{width}) + * \__braid_dim_value:n {floor~ border} + + (\__braid_dim_value:n {width}) * (\clist_item:nn {##1} {1} - 1) + } + pt + } + {\fp_eval:n + { + \l__braid_height_fp + ( \__braid_dim_value:n {height} ) * (\clist_item:nn {##1} {2}) + } + pt + } + {\fp_eval:n { + ( (\clist_item:nn {##1} {3}) * \__braid_dim_value:n {width} + + 2 * sign(\__braid_dim_value:n{width}) + * \__braid_dim_value:n {floor~ border} ) / \dim_to_fp:n {1cm} + } + } + {\fp_eval:n { + (\clist_item:nn {##1} {4}) * ( \__braid_dim_value:n {height} ) / \dim_to_fp:n {1cm} + } + } + } + \int_zero:N \l__braid_crossing_int + \int_incr:N \l__braid_crossing_int + + \seq_map_inline:Nn \l__braid_word_seq + { + \seq_clear:N \l__braid_crossing_seq + \bool_set_true:N \l__braid_step_level_bool + \bool_set_false:N \l__braid_floor_bool + \bool_set_false:N \l__braid_swap_crossing_bool + ##1 + \bool_if:NT \l__braid_floor_bool + { + \__braid_do_floor:Vxxxx \l__braid_crossing_int + {\fp_eval:n + { + -1*sign(\__braid_dim_value:n{width}) + * \__braid_dim_value:n {floor~ border} + } + pt + } + {\fp_to_decimal:N \l__braid_height_fp pt} + {\fp_eval:n { \l__braid_width_fp / \dim_to_fp:n {1cm} }} + {\fp_eval:n { ( \__braid_dim_value:n {height} ) / \dim_to_fp:n {1cm}}} + } + \seq_if_empty:NF \l__braid_crossing_seq + { + \prop_get:NxN \l__braid_crossing_permutation_prop + {\seq_item:Nn \l__braid_crossing_seq {1}} \l__braid_tmpa_tl + \prop_get:NxN \l__braid_crossing_permutation_prop + {\seq_item:Nn \l__braid_crossing_seq {2}} \l__braid_tmpb_tl + + \prop_put:NxV \l__braid_crossing_permutation_prop + {\seq_item:Nn \l__braid_crossing_seq {2}} \l__braid_tmpa_tl + \prop_put:NxV \l__braid_crossing_permutation_prop + {\seq_item:Nn \l__braid_crossing_seq {1}} \l__braid_tmpb_tl + \prop_get:NxN \l__braid_strands_prop + {\seq_item:Nn \l__braid_crossing_seq {1}} \l__braid_tmpa_tl + \prop_get:NxN \l__braid_strands_prop + {\seq_item:Nn \l__braid_crossing_seq {2}} \l__braid_tmpb_tl + \tl_put_right:Nx \l__braid_tmpa_tl + { + \exp_not:N \__braid_lineto:nn + + {\fp_eval:n + { + (\seq_item:Nn \l__braid_crossing_seq {1} - 1) + * \__braid_dim_value:n {width} + } + } + {\fp_eval:n { \l__braid_height_fp + \l__braid_nudge_fp } } + + \exp_not:N \__braid_curveto:nnnnnn + + {0} + {\fp_eval:n { \l__braid_control_fp}} + + {0} + {\fp_eval:n {- \l__braid_control_fp}} + + {\fp_eval:n + { + (\seq_item:Nn \l__braid_crossing_seq {2} - 1) + * \__braid_dim_value:n {width} + } + } + {\fp_eval:n + { + \l__braid_height_fp + + \__braid_dim_value:n {height} + - \l__braid_nudge_fp + } + } + } + \tl_put_right:Nx \l__braid_tmpb_tl + { + \exp_not:N \__braid_lineto:nn + + {\fp_eval:n + { + (\seq_item:Nn \l__braid_crossing_seq {2} - 1) + * \__braid_dim_value:n {width} + } + } + {\fp_eval:n { \l__braid_height_fp + \l__braid_nudge_fp } } + + \exp_not:N \__braid_curveto:nnnnnn + + {0} + { + \fp_eval:n { + \l__braid_control_fp * (.5 - \__braid_value:n {gap} ) + } + } + + { + \fp_eval:n { + - (.5 - \__braid_value:n {gap} ) / 3 * + \__braid_bezier_tangent:nnnnn + {.5 - \__braid_value:n {gap} } + {0} + {0} + { + (\seq_item:Nn \l__braid_crossing_seq {1} + - \seq_item:Nn \l__braid_crossing_seq {2}) + * \__braid_dim_value:n {width} + } + { + (\seq_item:Nn \l__braid_crossing_seq {1} + - \seq_item:Nn \l__braid_crossing_seq {2}) + * \__braid_dim_value:n {width} + } + } + } + { + \fp_eval:n { + -(.5 - \__braid_value:n {gap} ) / 3 * + \__braid_bezier_tangent:nnnnn + {.5 - \__braid_value:n {gap} } + {0} + {\l__braid_control_fp} + { + \__braid_dim_value:n {height} + - 2* \l__braid_nudge_fp + - \l__braid_control_fp + } + {\__braid_dim_value:n {height} - 2* \l__braid_nudge_fp} + } + } + + { + \fp_eval:n { + (\seq_item:Nn \l__braid_crossing_seq {2} - 1) + * \__braid_dim_value:n {width} + + \__braid_bezier_point:nnnnn + {.5 - \__braid_value:n {gap} } + {0} + {0} + { + (\seq_item:Nn \l__braid_crossing_seq {1} + - \seq_item:Nn \l__braid_crossing_seq {2}) + * \__braid_dim_value:n {width} + } + { + (\seq_item:Nn \l__braid_crossing_seq {1} + - \seq_item:Nn \l__braid_crossing_seq {2}) + * \__braid_dim_value:n {width} + } + } + } + { + \fp_eval:n { + \l__braid_height_fp + \l__braid_nudge_fp + + \__braid_bezier_point:nnnnn + {.5 - \__braid_value:n {gap} } + {0} + {\l__braid_control_fp} + { + \__braid_dim_value:n {height} + - 2* \l__braid_nudge_fp + - \l__braid_control_fp + } + {\__braid_dim_value:n {height} - 2* \l__braid_nudge_fp} + } + } + + \exp_not:N \__braid_moveto:nn + { + \fp_eval:n { + (\seq_item:Nn \l__braid_crossing_seq {2} - 1) + * \__braid_dim_value:n {width} + + \__braid_bezier_point:nnnnn + {.5 + \__braid_value:n {gap} } + {0} + {0} + { + (\seq_item:Nn \l__braid_crossing_seq {1} + - \seq_item:Nn \l__braid_crossing_seq {2}) + * \__braid_dim_value:n {width} + } + { + (\seq_item:Nn \l__braid_crossing_seq {1} + - \seq_item:Nn \l__braid_crossing_seq {2}) + * \__braid_dim_value:n {width} + } + } + } + { + \fp_eval:n { + \l__braid_height_fp + \l__braid_nudge_fp + + \__braid_bezier_point:nnnnn + {.5 + \__braid_value:n {gap} } + {0} + {\l__braid_control_fp} + { + \__braid_dim_value:n {height} - 2* \l__braid_nudge_fp + - \l__braid_control_fp + } + {\__braid_dim_value:n {height} - 2* \l__braid_nudge_fp} + } + } + + \exp_not:N \__braid_curveto:nnnnnn + + { + \fp_eval:n { + (.5 - \__braid_value:n {gap} ) / 3 * + \__braid_bezier_tangent:nnnnn + {.5 + \__braid_value:n {gap} } + {0} + {0} + { + (\seq_item:Nn \l__braid_crossing_seq {1} + - \seq_item:Nn \l__braid_crossing_seq {2}) + * \__braid_dim_value:n {width} + } + { + (\seq_item:Nn \l__braid_crossing_seq {1} + - \seq_item:Nn \l__braid_crossing_seq {2}) + * \__braid_dim_value:n {width} + } + } + } + { + \fp_eval:n { + (.5 - \__braid_value:n {gap} ) / 3 * + \__braid_bezier_tangent:nnnnn + {.5 + \__braid_value:n {gap} } + {0} + {\l__braid_control_fp} + { + \__braid_dim_value:n {height} - 2* \l__braid_nudge_fp + - \l__braid_control_fp + } + {\__braid_dim_value:n {height} - 2* \l__braid_nudge_fp} + } + } + + {0} + { \fp_eval:n { + -\l__braid_control_fp * (.5 - \__braid_value:n {gap} ) + } + } + + {\fp_eval:n + { + (\seq_item:Nn \l__braid_crossing_seq {1} - 1) + * \__braid_dim_value:n {width} + } + } + {\fp_eval:n + { + \l__braid_height_fp + \__braid_dim_value:n {height} + - \l__braid_nudge_fp + } + } + + } + \prop_put:NxV \l__braid_strands_prop + {\seq_item:Nn \l__braid_crossing_seq {2}} \l__braid_tmpa_tl + \prop_put:NxV \l__braid_strands_prop + {\seq_item:Nn \l__braid_crossing_seq {1}} \l__braid_tmpb_tl + \int_compare:nT + { + \int_max:nn + { + \seq_item:Nn \l__braid_crossing_seq {1} + } + { + \seq_item:Nn \l__braid_crossing_seq {2} + } + - + \int_min:nn + { + \seq_item:Nn \l__braid_crossing_seq {1} + } + { + \seq_item:Nn \l__braid_crossing_seq {2} + } + > 1 + } + { + \int_step_inline:nnnn + { + \int_min:nn + { + \seq_item:Nn \l__braid_crossing_seq {1} + } + { + \seq_item:Nn \l__braid_crossing_seq {2} + } + + 1} + {1} + { + \int_max:nn + { + \seq_item:Nn \l__braid_crossing_seq {1} + } + { + \seq_item:Nn \l__braid_crossing_seq {2} + } + - 1 + } + { + + \prop_get:NnN \l__braid_strands_prop {####1} \l__braid_tmpa_tl + \tl_put_right:Nx \l__braid_tmpa_tl + { + \exp_not:N \__braid_lineto:nn + {\fp_eval:n {(####1 - 1) * \__braid_dim_value:n {width} }} + {\fp_eval:n + { + \l__braid_height_fp + \l__braid_nudge_fp + + .5 * \l__braid_control_fp + } + } + \exp_not:N \__braid_moveto:nn + {\fp_eval:n {(####1 - 1) * \__braid_dim_value:n {width} }} + {\fp_eval:n + { + \l__braid_height_fp + \__braid_dim_value:n {height} + - \l__braid_nudge_fp - .5 * \l__braid_control_fp + } + } + } + + \prop_put:NnV \l__braid_strands_prop {####1} \l__braid_tmpa_tl + } + } + } + \bool_if:NT \l__braid_step_level_bool + { + \fp_add:Nn \l__braid_height_fp { \__braid_dim_value:n {height} } + + \int_step_inline:nnnn {1} {1} {\l__braid_strands_int} + { + \prop_get:NnN \l__braid_crossing_permutation_prop + {####1} \l__braid_tmpb_tl + \prop_get:NVN \l__braid_inverse_prop + \l__braid_tmpb_tl \l__braid_tmpa_tl + + \__braid_coordinate:xxxx + {-\l__braid_tmpb_tl-\int_use:N \l__braid_crossing_int} + {-rev-\l__braid_tmpa_tl-\int_use:N \l__braid_crossing_int } + {\fp_eval:n { (####1 - 1) * \__braid_dim_value:n {width} }} + {\fp_to_decimal:N \l__braid_height_fp} + } + + \int_incr:N \l__braid_crossing_int + } + } + + \fp_add:Nn \l__braid_height_fp + { + sign(\__braid_dim_value:n {height}) + * \__braid_dim_value:n {border~ height} + } + \int_step_inline:nnnn {1} {1} {\l__braid_strands_int} + { + \prop_get:NxN \l__braid_strands_prop {##1} \l__braid_tmpa_tl + \prop_get:NxN \l__braid_permutation_prop {##1} \l__braid_tmpb_tl + + \tl_put_right:Nx \l__braid_tmpa_tl { + \exp_not:N \__braid_lineto:nn + {\fp_eval:n { (##1 - 1) * \__braid_dim_value:n {width} }} + {\fp_to_decimal:N \l__braid_height_fp} + coordinate (-rev-##1-e) + coordinate (-\l__braid_tmpb_tl-e) + ; + } + + \prop_put:NnV \l__braid_strands_prop {##1} \l__braid_tmpa_tl + } + \int_step_inline:nnnn {1} {1} {\l__braid_strands_int} + { + \prop_get:NnN \l__braid_strands_prop {##1} \l__braid_tmpa_tl + \tl_use:N \l__braid_tmpa_tl + } + \end{scope} +} +\cs_new_nopar:Npn \__braid_moveto:nn #1#2 +{ + (#1 pt, #2 pt) +} +\cs_new_nopar:Npn \__braid_lineto:nn #1#2 +{ + -- (#1 pt, #2 pt) +} +\cs_new_nopar:Npn \__braid_curveto:nnnnnn #1#2#3#4#5#6 +{ + .. controls +(#1 pt, #2 pt) and +(#3 pt, #4 pt) + .. (#5 pt, #6 pt) +} +\cs_new_nopar:Npn \__braid_coordinate:nnnn #1#2#3#4 +{ + \coordinate[alias=#2] (#1) at (#3 pt,#4 pt); +} +\cs_generate_variant:Nn \__braid_coordinate:nnnn {xxxx} +\cs_new_nopar:Npn \__braid_bezier_point:nnnnn #1#2#3#4#5 +{ + \fp_eval:n + { + (1 - (#1)) * (1 - (#1)) * (1 - (#1)) * (#2) + + + 3 * (1 - (#1)) * (1 - (#1)) * (#1) * (#3) + + + 3 * (1 - (#1)) * (#1) * (#1) * (#4) + + + (#1) * (#1) * (#1) * (#5) + } +} +\cs_new_nopar:Npn \__braid_bezier_tangent:nnnnn #1#2#3#4#5 +{ + \fp_eval:n + { + 3 * (1 - (#1)) * (1 - (#1)) * (#3 - (#2)) + + + 6 * (1 - (#1)) * (#1) * (#4 - (#3)) + + + 3 * (#1) * (#1) * (#5 - (#4)) + } +} +\cs_new_nopar:Npn \__braid_do_floor:nnnnn #1#2#3#4#5 +{ + \pic[pic~ type=floor, + xscale=#4, + yscale=#5, + at={(#2,#3)}, + braid/every~ floor/.try, + braid/floor~#1/.try, + ]; +} +\cs_generate_variant:Nn \__braid_do_floor:nnnnn {Vxxxx} +\ExplSyntaxOff + +%% +%% Copyright (C) 2011-2019 by Andrew Stacey <loopspace@mathforge.org> +%% +%% 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, +%% tikzlibrarybraids.code.tex, +%% braids_doc.pdf. +%% +%% +%% End of file `tikzlibrarybraids.code.tex'. |