143
153
% \begin{tikzpicture}
144
% \braid[line width=3pt,line cap=round,style strands={1}{blue},number of strands=7] s_1 s_2 s_5^{-1};
154
% \braid[line width=3pt,line cap=round,style strand={1}{blue},number of strands=7] s_1 s_2 s_5^{-1};
145
155
% \end{tikzpicture}
148
158
% \section{Introduction}
150
160
% This is a package for drawing braid diagrams using PGF/TikZ.
151
% Its inspiration was a question and answer on the website \url{http://tex.stackexchange.com}.
156
% \item v1.0 First public release.
158
% \item v1.1 Added ability to configure the gap size, the control points, and the ``nudge''.
159
% Added ability to add labels to strands between crossings.
161
% An example follows.
165
% \begin{tikzpicture}[rotate=90]
166
% \braid[style strand={1}{red},style strand={2}{blue},style strand={3}{green}] s_1 s_2^{-1} s_1 s_2^{-1} s_1 s_2^{-1};
173
% \DescribeMacro{\braid}
174
% A braid is specified by the command \Verb+\braid+.
175
% The syntax for this command is as follows:
177
% \Verb+\braid[style options] (name) at (coordinate) braid-word;+
179
% The \Verb+braid-word+ is an expression in the braid group, such as \Verb+s_1 s_2^{-1}+.
180
% The generator labels are not significant.
181
% The exponent can be \Verb+1+, \Verb+{-1}+, or missing (in which case it defaults to \Verb+1+).
182
% Certain other symbols are allowed in the \Verb+braid-word+ which control the rendering of the braid.
183
% 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}).
184
% To draw a \emph{floor}, precede the braid element by a vertical line.
185
% 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.
186
% The intention is that this command draw something behind the braid.
187
% The command is configurable by a key (see \ref{sec:styleopts}).
189
% The (optional) \Verb+name+ acts a little like the \Verb+name+ of a TikZ node.
190
% When it is specified, the routine that renders the braid also saves certain coordinates as if they were node anchors.
191
% Specifically, \Verb+coordinate+ nodes are placed at the centre of the braid diagram and at the ends of each strand.
192
% 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.
193
% If the version with \Verb+rev+ is used then the numbers correspond to the \emph{final} positions of the braids.
194
% The name can also be specified with the \Verb+name+ key.
196
% The (options) \Verb+at (coordinate)+ syntax positions the braid at the \Verb+coordinate+ in the current picture.
197
% 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.
198
% Therefore, the braid is positioned so that the start of the first strand is at \Verb+(coordinate)+.
199
% This can also be specified using the \Verb+at+ key.
201
% The \Verb+style options+ set the style for the braid strands.
202
% 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.
203
% The options are as follows.
205
% \subsection{Style Options}
206
% \label{sec:styleopts}
208
% \DescribeMacro{number of strands} The key \Verb+number of strands+ sets the minimum number of strands for the braid.
209
% The number of strands will grow according to the terms in the braid word so this merely sets a lower bound.
210
% If not set, the number of strands will be determined by the terms in the braid word.
212
% \DescribeMacro{height}
213
% The key \Verb+height+ sets the height of the piece of the braid corresponding to an element in the group.
215
% \DescribeMacro{width}
216
% The key \Verb+width+ sets the separation of the strands in the braid.
218
% \DescribeMacro{border height}
219
% The key \Verb+border height+ adds a little extra length to the strands at the start and end of the braid.
221
% \DescribeMacro{style strand}
222
% The style of the strands are controlled by two types of option.
223
% Style options that are set on the \Verb+\braid+ command are passed to every strand.
224
% It is also possible to add style options to individual strands using the key \Verb+style strand+.
225
% This takes two options, a strand number and a list of options to be applied to that strand.
226
% Thus, the syntax is \Verb+style strand={n}{options}+.
227
% The strands are numbered by their starting position.
228
% Not all of the standard TikZ style options are possible due to the way that the strands are constructed.
229
% Basically, the options that are allowed are those that do not require changing the path or drawing it more than once.
231
% \DescribeMacro{floor command}
232
% When a floor is requested behind a crossing, the actual way to render it is determined by a command.
233
% This key allows the user to define that command.
234
% The argument to this key should be the code that should be executed for each floor.
235
% To avoid the hassle of getting the number of hashes right, the command should take no arguments.
236
% 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.
237
% The default is to draw a line at the top and at the bottom of the rectangle.
239
% \DescribeMacro{style floors}
240
% \DescribeMacro{style floor}
241
% 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).
242
% One advantage of this over building them in to the command is to allow them to be overridden for individual floors.
243
% The \Verb+style floors+ sets up options to be used for \emph{all} floors, whilst the \Verb+style floor={n}{options}+ sets up options to be used only for the \(n\)th floor.
244
% Anything specified in the \Verb+floor command+ will take precedence over both of these.
246
% 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).
251
% Here is a more detailed example.
252
% (Note that the floors are not drawn in the below.
253
% I have no idea why that is as they work when this example is put in a standalone file.
254
% It is presumably something to do with the documentation packages.)
259
% \begin{tikzpicture}
261
% style floors={fill=yellow},
262
% style floor={1}{dashed,fill=yellow!50!green},
264
% \message{drawing floor}
265
% \fill (\floorsx,\floorsy) rectangle (\floorex,\floorey);
266
% \draw (\floorsx,\floorsy) -- (\floorex,\floorsy);
269
% style strand={1}{red},
270
% style strand={2}{blue},
271
% style strand={3}{green}
272
% ] (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};
273
% \fill[yellow] (2,0) circle (4pt);
274
% \fill[purple] (braid) circle (4pt);
275
% \node[at=(braid-3-s),pin=north west:strand 3] {};
276
% \node[at=(braid-3-e),pin=south west:strand 3] {};
277
% \node[at=(braid-rev-3-s),pin=north east:strand 3 (from bottom)] {};
278
% \node[at=(braid-rev-3-e),pin=south east:strand 3 (from bottom)] {};
161
283
% \StopEventually{}
163
285
% \section{Implementation}
254
354
% \begin{macro}{\braid@handle}
255
355
% This is the main handler for parsing the braid word.
256
356
% It decides what action to take depending on what the token is.
257
% We have to be a bit careful with catcodes, some packages set
258
% \Verb+;+ and \Verb+|+ to be active.
259
% We should probably also be careful with \Verb+^+ and \Verb+_+.
260
357
% \begin{macrocode}
261
\let\braid@semicolon=;
263
358
\def\braid@handle{%
264
359
\let\braid@next=\braid@process
266
% Start by checking our catcodes to see what we should check against
268
\ifnum\the\catcode`\;=\active
269
\expandafter\let\expandafter\braid@semicolon\tikz@activesemicolon
271
\ifnum\the\catcode`\|=\active
272
\expandafter\let\expandafter\braid@bar\tikz@activebar
274
\ifx\braid@token\braid@semicolon
276
% Semicolon, means that we're done reading our braid.
277
% It's time to render it.
279
361
\let\braid@next=\braid@render
281
363
\ifx\braid@token^
283
% Superscript character, the next token tells us whether it's an over-crossing or an under-crossing.
285
364
\let\braid@next=\braid@sup
287
366
\ifx\braid@token_
289
% Subscript character, the next token tells us which strands cross.
291
367
\let\braid@next=\braid@sub
293
369
\ifx\braid@token-
295
% Hyphen, this is so that we can have more than one crossing on the same level.
297
370
\braid@increase@levelfalse
301
% 1: this means the ``identity'' crossing, so no crossing here.
302
% Increase the level, unless overriden, and add to the label.
304
\ifbraid@increase@level
305
\stepcounter{braid@level}
307
\braid@increase@leveltrue
308
\ge@addto@macro\braid@label{\braid@token}%
312
% Open bracket, this means we have some more options to process.
314
373
\let\braid@next=\braid@process@options
316
\ifx\braid@token\braid@bar
318
% Bar, this tells us that we want a ``floor'' at this point.
320
376
\edef\braid@tmp{,\expandafter\the\value{braid@level}}%
321
377
\ge@addto@macro\braid@floors\braid@tmp%
323
379
\ifx\braid@token\bgroup
325
% Begin group, which we reinterpret as begining a scope.
327
380
\braid@beginscope
329
382
\ifx\braid@token\egroup
331
% End group, which ends the scope
335
\ifx\braid@token\braid@olabel@strand
336
\let\braid@next=\braid@olabel@strand
338
\ifx\braid@token\braid@clabel@strand
339
\let\braid@next=\braid@clabel@strand
342
% Otherwise, we add the token to the braid label.
344
385
\ge@addto@macro\braid@label{\braid@token}%
497
535
% \begin{macro}{\braid@add@crossing}
498
% This is the macro which adds the crossing to the current list of strands.
536
% This is the macro which add the crossing to the current list of strands.
499
537
% The strands are stored as \emph{soft paths} (see the TikZ/PGF documentation).
500
538
% So this selects the right strands and then extends them according to the crossing type.
501
539
% \begin{macrocode}
502
540
\def\braid@add@crossing#1#2{%
504
% Our crossing type, which is \Verb+#2+, is one of \Verb+1+ or \Verb+-1+.
505
% Our strands are \Verb+#1+ and \Verb-#1+1-.
507
\edef\braid@crossing@type{#2}%
508
\edef\braid@this@strand{#1}%
541
\edef\braid@crossing@type{#2}
542
\edef\braid@this@strand{#1}
509
543
\pgfmathtruncatemacro{\braid@next@strand}{#1+1}
511
% Increment the level counter, if requested.
512
% The controls whether the crossing is on the same level as the previous one or is one level further on.
545
% increment the counter, if requested
514
546
\ifbraid@increase@level
515
547
\stepcounter{braid@level}
518
% Default is to request increment so we set it for next time.
549
% request increment next time
520
550
\braid@increase@leveltrue
522
% Now we figure out the coordinates of the crossing.
523
% \Verb+(\braid@tx,\braid@ty)+ is the top-left corner (assuming the braid flows down the page).
524
% \Verb+(\braid@nx,\braid@ny)+ is the bottom-right corner (assuming the braid flows down the page).
525
% 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).
526
% Then from these values, we set \Verb+(\braid@nx,\braid@ny)+ by adding on the appropriate amount.
527
% The heights \Verb+\braid@cy+ and \Verb+\braid@dy+ are for the control points for the strands as they cross.
528
% They're actually the same height, but using two gives us the possibility of changing them independently in a later version of this package.
529
% 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).
552
% Coordinates of crossing
531
553
\braid@tx=\braid@this@strand\braid@width
532
554
\braid@ty=\value{braid@level}\braid@height
533
555
\advance\braid@ty by \braid@eh
535
557
\braid@ny=\braid@ty
536
558
\advance\braid@nx by \braid@width
537
559
\advance\braid@ny by \braid@height
538
\advance\braid@ty by \braid@nf\braid@height
539
\advance\braid@ny by -\braid@nf\braid@height
540
560
\braid@cy=\braid@ty
541
561
\braid@dy=\braid@ny
542
\advance\braid@cy by \braid@cf\braid@height
543
\advance\braid@dy by -\braid@cf\braid@height
545
% Now we try to find a starting point for the strand ending here.
546
% We might not have used this strand before, so it might not exist.
562
\advance\braid@cy by .5\braid@height
563
\advance\braid@dy by -.5\braid@height
564
\advance\braid@ty by .05\braid@height
565
\advance\braid@ny by -.05\braid@height
567
% Try to find a starting point for the strand ending here
548
568
\expandafter\let\expandafter\braid@this@path@origin\csname braid@strand@\braid@this@strand @origin\endcsname
550
% If we haven't seen this strand before, that one will be \Verb+\relax+.
552
570
\ifx\braid@this@path@origin\relax
554
% Haven't seen this strand before, so initialise it.
555
% Record the initial position of the strand.
571
% Haven't seen this strand before, so initialise it
572
% Record the initial position of the strand
557
573
\let\braid@this@path@origin\braid@this@strand
559
% Start a new soft path.
574
% start a new soft path
561
575
\pgfsyssoftpath@setcurrentpath{\@empty}
562
576
\pgfpathmoveto{\pgfpoint{\braid@tx}{0pt}}
564
% Save the path as \Verb+\braid@this@path+.
566
578
\pgfsyssoftpath@getcurrentpath{\braid@this@path}
569
% We have seen this before, so we simply copy the associated path in to \Verb+\braid@this@path+.
571
580
\expandafter\let\expandafter\braid@this@path\csname braid@strand@\braid@this@path@origin\endcsname
574
% Now we do the same again with the other strand in the crossing.
583
% Try to find a starting point for the next strand ending here
576
584
\expandafter\let\expandafter\braid@next@path@origin\csname braid@strand@\braid@next@strand @origin\endcsname
577
586
\ifx\braid@next@path@origin\relax
587
% Haven't seen this strand before, so initialise it
588
% Record the initial position of the strand
578
589
\let\braid@next@path@origin\braid@next@strand
590
% start a new soft path
579
591
\pgfsyssoftpath@setcurrentpath{\@empty}
580
592
\pgfpathmoveto{\pgfpoint{\braid@nx}{0pt}}
581
594
\pgfsyssoftpath@getcurrentpath{\braid@next@path}
583
596
\expandafter\let\expandafter\braid@next@path\csname braid@strand@\braid@next@path@origin\endcsname
586
% Now that we have the paths for our two strands, we extend them to the next level.
587
% We start by selecting the first path.
599
% Start with the first path
589
600
\pgfsyssoftpath@setcurrentpath{\braid@this@path}
591
% 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.
601
% Draw a line down to the current level
593
602
\pgfpathlineto{\pgfqpoint{\braid@tx}{\braid@ty}}
595
% Curve across to the next position.
596
% Depending on the crossing type, we either have a single curve or we have to break it in two.
597
% Our gap is to interrupt at times determined by the gap key.
599
\pgfmathsetmacro{\braid@gst}{0.5 - \pgfkeysvalueof{/pgf/braid/gap}}%
600
\pgfmathsetmacro{\braid@gend}{0.5 + \pgfkeysvalueof{/pgf/braid/gap}}%
603
% Curve across to the next position
601
604
\ifx\braid@crossing@type\braid@over@cross
603
% We're on the overpass, so just one curve needed.
605
605
\pgfpathcurveto{\pgfqpoint{\braid@tx}{\braid@cy}}{\pgfqpoint{\braid@nx}{\braid@dy}}{\pgfqpoint{\braid@nx}{\braid@ny}}
608
% We're on the underpass, so we need to interrupt our path to allow the other curve to go past.
610
\pgfpathcurvebetweentimecontinue{0}{\braid@gst}{\pgfqpoint{\braid@tx}{\braid@ty}}{\pgfqpoint{\braid@tx}{\braid@cy}}{\pgfqpoint{\braid@nx}{\braid@dy}}{\pgfqpoint{\braid@nx}{\braid@ny}}
611
\pgfpathcurvebetweentime{\braid@gend}{1}{\pgfqpoint{\braid@tx}{\braid@ty}}{\pgfqpoint{\braid@tx}{\braid@cy}}{\pgfqpoint{\braid@nx}{\braid@dy}}{\pgfqpoint{\braid@nx}{\braid@ny}}
607
\pgfpathcurvebetweentimecontinue{0}{.4}{\pgfqpoint{\braid@tx}{\braid@ty}}{\pgfqpoint{\braid@tx}{\braid@cy}}{\pgfqpoint{\braid@nx}{\braid@dy}}{\pgfqpoint{\braid@nx}{\braid@ny}}
608
\pgfpathcurvebetweentime{.6}{1}{\pgfqpoint{\braid@tx}{\braid@ty}}{\pgfqpoint{\braid@tx}{\braid@cy}}{\pgfqpoint{\braid@nx}{\braid@dy}}{\pgfqpoint{\braid@nx}{\braid@ny}}
614
% We're done with this path, so now we save it.
616
611
\pgfsyssoftpath@getcurrentpath{\braid@this@path}
618
% Now do the same with the second path.
613
% Now do the same with the second path
620
614
\pgfsyssoftpath@setcurrentpath{\braid@next@path}
615
% Draw a line down to the current level
621
616
\pgfpathlineto{\pgfqpoint{\braid@nx}{\braid@ty}}
617
% Curve across to the previous position
622
618
\ifx\braid@crossing@type\braid@over@cross
623
\pgfpathcurvebetweentimecontinue{0}{\braid@gst}{\pgfqpoint{\braid@nx}{\braid@ty}}{\pgfqpoint{\braid@nx}{\braid@cy}}{\pgfqpoint{\braid@tx}{\braid@dy}}{\pgfqpoint{\braid@tx}{\braid@ny}}
624
\pgfpathcurvebetweentime{\braid@gend}{1}{\pgfqpoint{\braid@nx}{\braid@ty}}{\pgfqpoint{\braid@nx}{\braid@cy}}{\pgfqpoint{\braid@tx}{\braid@dy}}{\pgfqpoint{\braid@tx}{\braid@ny}}
619
\pgfpathcurvebetweentimecontinue{0}{.4}{\pgfqpoint{\braid@nx}{\braid@ty}}{\pgfqpoint{\braid@nx}{\braid@cy}}{\pgfqpoint{\braid@tx}{\braid@dy}}{\pgfqpoint{\braid@tx}{\braid@ny}}
620
\pgfpathcurvebetweentime{.6}{1}{\pgfqpoint{\braid@nx}{\braid@ty}}{\pgfqpoint{\braid@nx}{\braid@cy}}{\pgfqpoint{\braid@tx}{\braid@dy}}{\pgfqpoint{\braid@tx}{\braid@ny}}
626
622
\pgfpathcurveto{\pgfqpoint{\braid@nx}{\braid@cy}}{\pgfqpoint{\braid@tx}{\braid@dy}}{\pgfqpoint{\braid@tx}{\braid@ny}}
628
625
\pgfsyssoftpath@getcurrentpath{\braid@next@path}
630
% Now save the paths to their proper macros again.
627
% Now save the paths again
632
628
\expandafter\let\csname braid@strand@\braid@this@path@origin \endcsname\braid@this@path
633
629
\expandafter\let\csname braid@strand@\braid@next@path@origin \endcsname\braid@next@path
635
% Now update the origins
631
% Now update the origins
637
632
\expandafter\let\csname braid@strand@\braid@this@strand @origin\endcsname\braid@next@path@origin
638
633
\expandafter\let\csname braid@strand@\braid@next@strand @origin\endcsname\braid@this@path@origin
640
635
% increment the strand counter, if necessary
642
636
\pgfmathparse{\value{braid@strands} < \braid@next@strand ? "\noexpand\setcounter{braid@strands}{\braid@next@strand}" : ""}
645
% And merrily go on our way with the next bit of the braid specification.
652
% \begin{macro}{\braid@olabel@strand}
653
% This macro allows us to label a strand just before a crossing.
654
% The first argument is the strand number at that particular crossing and the second is the label.
655
% We also save the current height.
656
% This version takes the strand number as meaning the \emph{original} ordering.
658
\newcommand{\braid@olabel@strand}[3][]{%
659
\edef\braid@tmp{{\the\value{braid@level}}}%
660
\expandafter\ifx\csname braid@strand@#2@origin\endcsname\relax
661
\g@addto@macro\braid@tmp{{#2}}%
663
\edef\braid@tmpa{{\csname braid@strand@#2@origin\endcsname}}%
664
\ge@addto@macro\braid@tmp{\braid@tmpa}%
666
\g@addto@macro\braid@tmp{{#3}{#1}}%
667
\ge@addto@macro{\braid@strand@labels}{\braid@tmp}%
673
% \begin{macro}{\braid@clabel@strand}
674
% This macro allows us to label a strand just before a crossing.
675
% The first argument is the strand number at that particular crossing and the second is the label.
676
% We also save the current height.
677
% This version takes the strand number as meaning the \emph{current} ordering.
679
\newcommand{\braid@clabel@strand}[3][]{%
680
\edef\braid@tmp{{\the\value{braid@level}}}%
681
\g@addto@macro\braid@tmp{{#2}{#3}{#1}}%
682
\ge@addto@macro{\braid@strand@labels}{\braid@tmp}%
685
640
% \end{macrocode}
702
657
% \end{macrocode}
705
% \begin{macro}{\braid@render@strand@labels}
706
% This starts rendering the labels on the strands at the crossings.
708
\def\braid@render@strand@labels#1{%
710
\ifx\braid@tmp\pgfutil@empty
711
\let\braid@next=\pgfutil@gobble
713
\let\braid@next=\braid@@render@strand@labels
720
% \begin{macro}{\braid@@render@strand@labels}
721
% This is the actual renderer.
723
\def\braid@@render@strand@labels#1#2#3#4{%
726
\let\tikz@options=\pgfutil@empty
727
\let\tikz@mode=\pgfutil@empty
728
\let\tik@transform=\pgfutil@empty
729
\let\tikz@fig@name=\pgfutil@empty
730
\tikzset{/pgf/braid/strand label,#4}%
731
\braid@nx=#2\braid@width
732
\braid@ny=#1\braid@height
733
\advance\braid@ny by \braid@eh
734
\advance\braid@ny by \braid@height
735
\pgftransformshift{\pgfqpoint{\braid@nx}{\braid@ny}}%
737
\setbox\pgfnodeparttextbox=\hbox%
739
\tikzset{every text node part/.try}%
740
\ifx\tikz@textopacity\pgfutil@empty%
742
\pgfsetfillopacity{\tikz@textopacity}%
743
\pgfsetstrokeopacity{\tikz@textopacity}%
745
\pgfinterruptpicture%
747
\ifx\tikz@text@width\pgfutil@empty%
750
\pgfmathsetlength{\pgf@x}{\tikz@text@width}%
751
\pgfutil@minipage[t]{\pgf@x}\leavevmode\hbox{}%
757
\ifx\tikz@textcolor\pgfutil@empty%
759
\pgfutil@colorlet{.}{\tikz@textcolor}%
762
\setbox\tikz@figbox=\box\pgfutil@voidb@x%
763
\tikz@uninstallcommands%
769
\ifx\tikz@text@width\pgfutil@empty%
771
\pgfutil@endminipage%
774
\endpgfinterruptpicture%
776
\ifx\tikz@text@width\pgfutil@empty%
778
\pgfmathsetlength{\pgf@x}{\tikz@text@width}%
779
\wd\pgfnodeparttextbox=\pgf@x%
781
\ifx\tikz@text@height\pgfutil@empty%
783
\pgfmathsetlength{\pgf@x}{\tikz@text@height}%
784
\ht\pgfnodeparttextbox=\pgf@x%
786
\ifx\tikz@text@depth\pgfutil@empty%
788
\pgfmathsetlength{\pgf@x}{\tikz@text@depth}%
789
\dp\pgfnodeparttextbox=\pgf@x%
791
\pgfmultipartnode{\tikz@shape}{\tikz@anchor}{\tikz@fig@name}{%
792
{\begingroup\tikz@finish}%
796
\braid@render@strand@labels%
801
660
% \begin{macro}{\braid@render}
802
661
% 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.
803
662
% \begin{macrocode}
804
663
\def\braid@render{
806
% Check for floors since we do them first.
808
664
\ifx\braid@floors\@empty
811
% Have some floors, start a scope and prepare to render them.
813
666
\pgfsys@beginscope
815
% Clear the path (just to be sure).
817
667
\pgfsyssoftpath@setcurrentpath{\empty}
819
% Trim the initial comma off the list of floors.
821
668
\edef\braid@floors{\expandafter\braid@floors@trim\braid@floors}
823
% Initialise our horizontal coordinates.
825
669
\braid@tx=\braid@width
826
670
\advance\braid@tx by \braid@eh
827
671
\braid@nx=\value{braid@strands}\braid@width
828
672
\advance\braid@nx by -\braid@eh
830
% Loop over the list of floors.
832
673
\foreach \braid@f in \braid@floors {
833
674
\pgfsys@beginscope
835
% Figure out the vertical coordinates for the current floor.
837
675
\braid@ty=\braid@f\braid@height
838
676
\advance\braid@ty by \braid@eh
839
677
\advance\braid@ty by \braid@height
840
678
\braid@ny=\braid@ty
841
679
\advance\braid@ny by \braid@height
843
% Save the coordinates for use in the floor rendering macro.
845
680
\edef\floorsx{\the\braid@tx}
846
681
\edef\floorsy{\the\braid@ty}
847
682
\edef\floorex{\the\braid@nx}
848
683
\edef\floorey{\the\braid@ny}
849
684
\let\tikz@options=\pgfutil@empty
851
% Load general floor style options.
685
% Load general floor style options
853
686
\expandafter\tikzset\expandafter{\braid@floors@style}
855
% Load any style options specific to this floor.
856
% We're actually offset by 2 from what the user thinks the floor level is.
687
% Load any style options specific to this floor
858
688
\pgfmathtruncatemacro{\braid@ff}{\braid@f+2}
860
% Load the relevant floor style, if it exists.
862
689
\expandafter\let\expandafter\braid@floor@style\csname braid@options@floor@\braid@ff\endcsname
863
690
\ifx\braid@floor@style\relax
866
% There is a floor style for this level, so process it.
868
\expandafter\tikzset\expandafter{\braid@floor@style}%
692
\expandafter\tikzset\expandafter{\braid@floor@style}
871
% The \Verb+\tikzset+ just parses the options, we need to call \Verb+\tikz@options+ to actually set them.
875
% Now we call the rendering code.
880
% End the scope for \emph{this} floor and go again.
885
% Done rendering floors, end the scope.
890
% Finished with floors (if we had them), now get on with the strands.
892
700
\stepcounter{braid@level}
893
701
\foreach \braid@k in {1,...,\value{braid@strands}} {
895
702
% Start a local scope to ensure we don't mess with other braids
897
703
\pgfsys@beginscope
899
704
% Default is to draw each braid
901
705
\tikz@mode@drawtrue%
902
706
\let\tikz@mode=\pgfutil@empty
903
707
\let\tikz@options=\pgfutil@empty
905
708
% (x,y) coordinates of bottom of strand
907
709
\braid@tx=\braid@k\braid@width
908
710
\braid@ty=\value{braid@level}\braid@height
909
711
\advance\braid@ty by 2\braid@eh
911
712
% Try to find the starting point of this strand
913
713
\expandafter\let\expandafter\braid@path@origin\csname braid@strand@\braid@k @origin\endcsname
914
714
\ifx\braid@path@origin\relax
916
715
% If that doesn't exist, we'll just draw a straight line
917
716
% so we move to the top of the current position
919
717
\pgfsyssoftpath@setcurrentpath{\@empty}
920
718
\pgfpathmoveto{\pgfqpoint{\braid@tx}{0pt}}
921
719
\let\braid@path@origin\braid@k
924
721
% If the path does exist, we load it
926
722
\expandafter\let\expandafter\braid@path\csname braid@strand@\braid@path@origin\endcsname
927
723
\pgfsyssoftpath@setcurrentpath{\braid@path}
930
725
% Extend the path to the bottom
932
726
\pgflineto{\pgfqpoint{\braid@tx}{\braid@ty}}
934
727
% Load common style options
936
728
\expandafter\tikzset\expandafter{\braid@style}
938
729
% Load any style options specific to this strand
940
730
\expandafter\let\expandafter\braid@style\csname braid@options@strand@\braid@path@origin\endcsname
941
731
\ifx\braid@style\relax
1002
769
% \begin{macro}{\braid@start}
1003
770
% This starts off the braid, initialising a load of stuff.
1004
% 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..
1005
771
% \begin{macrocode}
1006
772
\def\braid@start#1{%
1008
\setcounter{braid@level}{-1}%
1009
\let\braid@label\@empty
1010
\let\braid@strand@labels\@empty
1011
\let\braid@floors\@empty
1012
\let\braid@name\empty
1013
\let\clabel=\braid@clabel@strand
1014
\let\olabel=\braid@olabel@strand
1015
\pgfkeys{/pgf/braid/.cd,#1}%
1016
\ifbraid@strand@labels@origin
1017
\let\label=\braid@olabel@strand
1019
\let\label=\braid@clabel@strand
1021
\let\braid@options\tikz@options
774
\setcounter{braid@level}{-1}%
775
\let\braid@label\@empty
776
\let\braid@floors\@empty
777
\let\braid@name\empty
778
\pgfkeys{/pgf/braid/.cd,#1}
779
\let\braid@options\tikz@options
1023
\setcounter{braid@strands}{\pgfkeysvalueof{/pgf/braid/number of strands}}%
1024
\braid@width=\pgfkeysvalueof{/pgf/braid/width}%
1025
\braid@height=\pgfkeysvalueof{/pgf/braid/height}%
1026
\braid@eh=\pgfkeysvalueof{/pgf/braid/border height}%
1027
\pgfkeysgetvalue{/pgf/braid/control factor}{\braid@cf}%
1028
\pgfkeysgetvalue{/pgf/braid/nudge factor}{\braid@nf}%
1029
\braid@height=-\braid@height
1030
\braid@eh=-\braid@eh
1031
\braid@increase@leveltrue
1032
\braid@process@start
781
\setcounter{braid@strands}{\pgfkeysvalueof{/pgf/braid/number of strands}}%
782
\braid@width=\pgfkeysvalueof{/pgf/braid/width}
783
\braid@height=\pgfkeysvalueof{/pgf/braid/height}
784
\braid@eh=\pgfkeysvalueof{/pgf/braid/border height}
785
\braid@height=-\braid@height
787
\braid@increase@leveltrue
1034
790
% \end{macrocode}