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/source/latex/braids | |
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/source/latex/braids')
-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 |
3 files changed, 2404 insertions, 946 deletions
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'. |