From 78b1605f1f5a0899ce94e74a533fe20e7a2ae747 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Wed, 8 May 2019 21:15:00 +0000 Subject: braids (8may19) git-svn-id: svn://tug.org/texlive/trunk@51048 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/tex/latex/braids/braids.sty | 296 +++++-- .../tex/latex/braids/tikzlibrarybraids.code.tex | 916 +++++++++++++++++++++ 2 files changed, 1158 insertions(+), 54 deletions(-) create mode 100644 Master/texmf-dist/tex/latex/braids/tikzlibrarybraids.code.tex (limited to 'Master/texmf-dist/tex/latex/braids') diff --git a/Master/texmf-dist/tex/latex/braids/braids.sty b/Master/texmf-dist/tex/latex/braids/braids.sty index f7edd15f724..d9976eec067 100644 --- a/Master/texmf-dist/tex/latex/braids/braids.sty +++ b/Master/texmf-dist/tex/latex/braids/braids.sty @@ -4,21 +4,19 @@ %% %% The original source files were: %% -%% braids.dtx (with options: `package') +%% braids_code.dtx (with options: `package') %% ---------------------------------------------------------------- %% braids --- a style file for drawing braid diagrams with TikZ/PGF -%% E-mail: stacey@math.ntnu.no +%% E-mail: loopspace@mathforge.org %% Released under the LaTeX Project Public License v1.3c or later %% See http://www.latex-project.org/lppl.txt %% ---------------------------------------------------------------- %% \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{braids}[2011/05/07 v1.0 Tikz/PGF commands for drawing braid diagrams] -\def\braid@pgfversion{2.10}% -\ifx\pgfversion\braid@pgfversion -\else -\PackageWarning{braids}{This package was designed using PGF2.10; you are using \pgfversion.}% -\fi +\ProvidesPackage{braids}[2011/10/18 v1.1 Tikz/PGF commands for drawing braid diagrams] +\PackageWarning{braids}{% + This package has been reimplemented as a TikZ library; if starting with a fresh document, please consider using that instead.% +}% \long\def\ge@addto@macro#1#2{% \begingroup \toks@\expandafter\expandafter\expandafter{\expandafter#1#2}% @@ -71,7 +69,14 @@ \ifx\braid@token- \braid@increase@levelfalse \else - \ifx\braid@token[ + \ifx\braid@token1% + \ifbraid@increase@level + \stepcounter{braid@level} + \fi + \braid@increase@leveltrue + \ge@addto@macro\braid@label{\braid@token}% + \else + \ifx\braid@token[% \let\braid@next=\braid@process@options \else \ifx\braid@token\braid@bar @@ -84,6 +89,12 @@ \ifx\braid@token\egroup \braid@endscope \else + \ifx\braid@token\braid@olabel@strand + \let\braid@next=\braid@olabel@strand + \else + \ifx\braid@token\braid@clabel@strand + \let\braid@next=\braid@clabel@strand + \else \ge@addto@macro\braid@label{\braid@token}% \fi \fi @@ -93,6 +104,9 @@ \fi \fi \fi + \fi + \fi + \fi \braid@next% } \def\braid@maybe@locate{% @@ -140,9 +154,18 @@ \tikzset{#1}% \braid@process% } -\def\braid@sup#1_#2{\g@addto@macro\braid@label{_{#2}^{#1}}\braid@add@crossing{#2}{#1}} -\def\braid@sub#1{\@ifnextchar^{\braid@@sub{#1}}{\g@addto@macro\braid@label{_{#1}}\braid@add@crossing{#1}{1}}} -\def\braid@@sub#1^#2{\g@addto@macro\braid@label{_{#1}^{#2}}\braid@add@crossing{#1}{#2}} +\def\braid@sup#1_#2{% + \g@addto@macro\braid@label{_{#2}^{#1}}% + \braid@add@crossing{#2}{#1}% +} +\def\braid@sub#1{% + \@ifnextchar^{\braid@@sub{#1}}% + {\g@addto@macro\braid@label{_{#1}}\braid@add@crossing{#1}{1}}% +} +\def\braid@@sub#1^#2{% + \g@addto@macro\braid@label{_{#1}^{#2}}% + \braid@add@crossing{#1}{#2}% +} \def\braid@ne{1} \def\braid@add@crossing#1#2{% \edef\braid@crossing@type{#2}% @@ -159,60 +182,197 @@ \braid@ny=\braid@ty \advance\braid@nx by \braid@width \advance\braid@ny by \braid@height + \advance\braid@ty by \braid@nf\braid@height + \advance\braid@ny by -\braid@nf\braid@height \braid@cy=\braid@ty \braid@dy=\braid@ny - \advance\braid@cy by .5\braid@height - \advance\braid@dy by -.5\braid@height - \advance\braid@ty by .05\braid@height - \advance\braid@ny by -.05\braid@height - \expandafter\let\expandafter\braid@this@path@origin\csname braid@strand@\braid@this@strand @origin\endcsname + \advance\braid@cy by \braid@cf\braid@height + \advance\braid@dy by -\braid@cf\braid@height + \expandafter\let\expandafter\braid@this@path@origin% + \csname braid@strand@\braid@this@strand @origin\endcsname \ifx\braid@this@path@origin\relax \let\braid@this@path@origin\braid@this@strand \pgfsyssoftpath@setcurrentpath{\@empty} \pgfpathmoveto{\pgfpoint{\braid@tx}{0pt}} \pgfsyssoftpath@getcurrentpath{\braid@this@path} \else - \expandafter\let\expandafter\braid@this@path\csname braid@strand@\braid@this@path@origin\endcsname + \expandafter\let\expandafter\braid@this@path% + \csname braid@strand@\braid@this@path@origin\endcsname \fi - \expandafter\let\expandafter\braid@next@path@origin\csname braid@strand@\braid@next@strand @origin\endcsname + \expandafter\let\expandafter\braid@next@path@origin% + \csname braid@strand@\braid@next@strand @origin\endcsname \ifx\braid@next@path@origin\relax \let\braid@next@path@origin\braid@next@strand \pgfsyssoftpath@setcurrentpath{\@empty} \pgfpathmoveto{\pgfpoint{\braid@nx}{0pt}} \pgfsyssoftpath@getcurrentpath{\braid@next@path} \else - \expandafter\let\expandafter\braid@next@path\csname braid@strand@\braid@next@path@origin\endcsname + \expandafter\let\expandafter\braid@next@path% + \csname braid@strand@\braid@next@path@origin\endcsname \fi \pgfsyssoftpath@setcurrentpath{\braid@this@path} \pgfpathlineto{\pgfqpoint{\braid@tx}{\braid@ty}} +\pgfmathsetmacro{\braid@gst}{0.5 - \pgfkeysvalueof{/pgf/braid/gap}}% +\pgfmathsetmacro{\braid@gend}{0.5 + \pgfkeysvalueof{/pgf/braid/gap}}% \ifx\braid@crossing@type\braid@over@cross -\pgfpathcurveto{\pgfqpoint{\braid@tx}{\braid@cy}}{\pgfqpoint{\braid@nx}{\braid@dy}}{\pgfqpoint{\braid@nx}{\braid@ny}} + \pgfpathcurveto{\pgfqpoint{\braid@tx}{\braid@cy}}% + {\pgfqpoint{\braid@nx}{\braid@dy}}% + {\pgfqpoint{\braid@nx}{\braid@ny}} \else -\pgfpathcurvebetweentimecontinue{0}{.4}{\pgfqpoint{\braid@tx}{\braid@ty}}{\pgfqpoint{\braid@tx}{\braid@cy}}{\pgfqpoint{\braid@nx}{\braid@dy}}{\pgfqpoint{\braid@nx}{\braid@ny}} -\pgfpathcurvebetweentime{.6}{1}{\pgfqpoint{\braid@tx}{\braid@ty}}{\pgfqpoint{\braid@tx}{\braid@cy}}{\pgfqpoint{\braid@nx}{\braid@dy}}{\pgfqpoint{\braid@nx}{\braid@ny}} + \pgfpathcurvebetweentimecontinue{0}{\braid@gst}% + {\pgfqpoint{\braid@tx}{\braid@ty}}% + {\pgfqpoint{\braid@tx}{\braid@cy}}% + {\pgfqpoint{\braid@nx}{\braid@dy}}% + {\pgfqpoint{\braid@nx}{\braid@ny}}% + \pgfpathcurvebetweentime{\braid@gend}{1}% + {\pgfqpoint{\braid@tx}{\braid@ty}}% + {\pgfqpoint{\braid@tx}{\braid@cy}}% + {\pgfqpoint{\braid@nx}{\braid@dy}}% + {\pgfqpoint{\braid@nx}{\braid@ny}} \fi \pgfsyssoftpath@getcurrentpath{\braid@this@path} \pgfsyssoftpath@setcurrentpath{\braid@next@path} \pgfpathlineto{\pgfqpoint{\braid@nx}{\braid@ty}} \ifx\braid@crossing@type\braid@over@cross -\pgfpathcurvebetweentimecontinue{0}{.4}{\pgfqpoint{\braid@nx}{\braid@ty}}{\pgfqpoint{\braid@nx}{\braid@cy}}{\pgfqpoint{\braid@tx}{\braid@dy}}{\pgfqpoint{\braid@tx}{\braid@ny}} -\pgfpathcurvebetweentime{.6}{1}{\pgfqpoint{\braid@nx}{\braid@ty}}{\pgfqpoint{\braid@nx}{\braid@cy}}{\pgfqpoint{\braid@tx}{\braid@dy}}{\pgfqpoint{\braid@tx}{\braid@ny}} + \pgfpathcurvebetweentimecontinue{0}{\braid@gst}% + {\pgfqpoint{\braid@nx}{\braid@ty}}% + {\pgfqpoint{\braid@nx}{\braid@cy}}% + {\pgfqpoint{\braid@tx}{\braid@dy}}% + {\pgfqpoint{\braid@tx}{\braid@ny}} + \pgfpathcurvebetweentime{\braid@gend}{1}% + {\pgfqpoint{\braid@nx}{\braid@ty}}% + {\pgfqpoint{\braid@nx}{\braid@cy}}% + {\pgfqpoint{\braid@tx}{\braid@dy}}% + {\pgfqpoint{\braid@tx}{\braid@ny}} \else - \pgfpathcurveto{\pgfqpoint{\braid@nx}{\braid@cy}}{\pgfqpoint{\braid@tx}{\braid@dy}}{\pgfqpoint{\braid@tx}{\braid@ny}} + \pgfpathcurveto{\pgfqpoint{\braid@nx}{\braid@cy}}% + {\pgfqpoint{\braid@tx}{\braid@dy}}% + {\pgfqpoint{\braid@tx}{\braid@ny}} \fi \pgfsyssoftpath@getcurrentpath{\braid@next@path} - \expandafter\let\csname braid@strand@\braid@this@path@origin \endcsname\braid@this@path - \expandafter\let\csname braid@strand@\braid@next@path@origin \endcsname\braid@next@path - \expandafter\let\csname braid@strand@\braid@this@strand @origin\endcsname\braid@next@path@origin - \expandafter\let\csname braid@strand@\braid@next@strand @origin\endcsname\braid@this@path@origin - \pgfmathparse{\value{braid@strands} < \braid@next@strand ? "\noexpand\setcounter{braid@strands}{\braid@next@strand}" : ""} + \expandafter\let% + \csname braid@strand@\braid@this@path@origin \endcsname% + \braid@this@path + \expandafter\let% + \csname braid@strand@\braid@next@path@origin \endcsname% + \braid@next@path + \expandafter\let% + \csname braid@strand@\braid@this@strand @origin\endcsname% + \braid@next@path@origin + \expandafter\let% + \csname braid@strand@\braid@next@strand @origin\endcsname% + \braid@this@path@origin + \pgfmathparse{\value{braid@strands} < \braid@next@strand ? + "\noexpand\setcounter{braid@strands}{\braid@next@strand}" : ""} \pgfmathresult \braid@process% } +\newcommand{\braid@olabel@strand}[3][]{% + \edef\braid@tmp{{\the\value{braid@level}}}% + \expandafter\ifx\csname braid@strand@#2@origin\endcsname\relax + \g@addto@macro\braid@tmp{{#2}}% + \else + \edef\braid@tmpa{{\csname braid@strand@#2@origin\endcsname}}% + \ge@addto@macro\braid@tmp{\braid@tmpa}% + \fi + \g@addto@macro\braid@tmp{{#3}{#1}}% + \ge@addto@macro{\braid@strand@labels}{\braid@tmp}% + \braid@process% +} +\newcommand{\braid@clabel@strand}[3][]{% + \edef\braid@tmp{{\the\value{braid@level}}}% + \g@addto@macro\braid@tmp{{#2}{#3}{#1}}% + \ge@addto@macro{\braid@strand@labels}{\braid@tmp}% + \braid@process% +} \def\braid@floors@trim,{} \def\braid@render@floor{% \draw (\floorsx,\floorsy) rectangle (\floorex,\floorey); } +\def\braid@render@strand@labels#1{% + \def\braid@tmp{#1}% + \ifx\braid@tmp\pgfutil@empty + \let\braid@next=\pgfutil@gobble + \else + \let\braid@next=\braid@@render@strand@labels + \fi + \braid@next{#1}% +} +\def\braid@@render@strand@labels#1#2#3#4{% + \begingroup + \pgfscope + \let\tikz@options=\pgfutil@empty + \let\tikz@mode=\pgfutil@empty + \let\tik@transform=\pgfutil@empty + \let\tikz@fig@name=\pgfutil@empty + \tikzset{/pgf/braid/strand label,#4}% + \braid@nx=#2\braid@width + \braid@ny=#1\braid@height + \advance\braid@ny by \braid@eh + \advance\braid@ny by \braid@height + \pgftransformshift{\pgfqpoint{\braid@nx}{\braid@ny}}% + \tikz@options + \setbox\pgfnodeparttextbox=\hbox% + \bgroup% + \tikzset{every text node part/.try}% + \ifx\tikz@textopacity\pgfutil@empty% + \else% + \pgfsetfillopacity{\tikz@textopacity}% + \pgfsetstrokeopacity{\tikz@textopacity}% + \fi% + \pgfinterruptpicture% + \tikz@textfont% + \ifx\tikz@text@width\pgfutil@empty% + \else% + \begingroup% + \pgfmathsetlength{\pgf@x}{\tikz@text@width}% + \pgfutil@minipage[t]{\pgf@x}\leavevmode\hbox{}% + \tikz@text@action% + \fi% + \tikz@atbegin@node% + \bgroup% + \aftergroup\unskip% + \ifx\tikz@textcolor\pgfutil@empty% + \else% + \pgfutil@colorlet{.}{\tikz@textcolor}% + \fi% + \pgfsetcolor{.}% + \setbox\tikz@figbox=\box\pgfutil@voidb@x% + \tikz@uninstallcommands% + \tikz@halign@check% + \ignorespaces% + #3 + \egroup + \tikz@atend@node% + \ifx\tikz@text@width\pgfutil@empty% + \else% + \pgfutil@endminipage% + \endgroup% + \fi% + \endpgfinterruptpicture% + \egroup% + \ifx\tikz@text@width\pgfutil@empty% + \else% + \pgfmathsetlength{\pgf@x}{\tikz@text@width}% + \wd\pgfnodeparttextbox=\pgf@x% + \fi% + \ifx\tikz@text@height\pgfutil@empty% + \else% + \pgfmathsetlength{\pgf@x}{\tikz@text@height}% + \ht\pgfnodeparttextbox=\pgf@x% + \fi% + \ifx\tikz@text@depth\pgfutil@empty% + \else% + \pgfmathsetlength{\pgf@x}{\tikz@text@depth}% + \dp\pgfnodeparttextbox=\pgf@x% + \fi% + \pgfmultipartnode{\tikz@shape}{\tikz@anchor}{\tikz@fig@name}{% + {\begingroup\tikz@finish}% + }% + \endpgfscope + \endgroup + \braid@render@strand@labels% +} \def\braid@render{ \ifx\braid@floors\@empty \else @@ -237,7 +397,8 @@ \let\tikz@options=\pgfutil@empty \expandafter\tikzset\expandafter{\braid@floors@style} \pgfmathtruncatemacro{\braid@ff}{\braid@f+2} - \expandafter\let\expandafter\braid@floor@style\csname braid@options@floor@\braid@ff\endcsname + \expandafter\let\expandafter\braid@floor@style% + \csname braid@options@floor@\braid@ff\endcsname \ifx\braid@floor@style\relax \else \expandafter\tikzset\expandafter{\braid@floor@style}% @@ -257,18 +418,21 @@ \braid@tx=\braid@k\braid@width \braid@ty=\value{braid@level}\braid@height \advance\braid@ty by 2\braid@eh - \expandafter\let\expandafter\braid@path@origin\csname braid@strand@\braid@k @origin\endcsname + \expandafter\let\expandafter\braid@path@origin% + \csname braid@strand@\braid@k @origin\endcsname \ifx\braid@path@origin\relax \pgfsyssoftpath@setcurrentpath{\@empty} \pgfpathmoveto{\pgfqpoint{\braid@tx}{0pt}} \let\braid@path@origin\braid@k \else - \expandafter\let\expandafter\braid@path\csname braid@strand@\braid@path@origin\endcsname + \expandafter\let\expandafter\braid@path% + \csname braid@strand@\braid@path@origin\endcsname \pgfsyssoftpath@setcurrentpath{\braid@path} \fi \pgflineto{\pgfqpoint{\braid@tx}{\braid@ty}} \expandafter\tikzset\expandafter{\braid@style} - \expandafter\let\expandafter\braid@style\csname braid@options@strand@\braid@path@origin\endcsname + \expandafter\let\expandafter\braid@style% + \csname braid@options@strand@\braid@path@origin\endcsname \ifx\braid@style\relax \else \expandafter\tikzset\expandafter{\braid@style} @@ -300,25 +464,40 @@ \braid@ty=.5\braid@ty \coordinate (\braid@name) at (\braid@tx,\braid@ty); \fi + \ifx\braid@strand@labels\pgfutil@empty + \else + \expandafter\braid@render@strand@labels\braid@strand@labels{}% + \fi \pgfsys@endscope \endgroup} \def\braid@start#1{% - \pgfsys@beginscope - \setcounter{braid@level}{-1}% - \let\braid@label\@empty - \let\braid@floors\@empty - \let\braid@name\empty - \pgfkeys{/pgf/braid/.cd,#1} - \let\braid@options\tikz@options + \pgfsys@beginscope + \setcounter{braid@level}{-1}% + \let\braid@label\@empty + \let\braid@strand@labels\@empty + \let\braid@floors\@empty + \let\braid@name\empty + \let\clabel=\braid@clabel@strand + \let\olabel=\braid@olabel@strand + \pgfkeys{/pgf/braid/.cd,#1}% + \ifbraid@strand@labels@origin + \let\label=\braid@olabel@strand + \else + \let\label=\braid@clabel@strand + \fi + \let\braid@options\tikz@options \tikz@transform - \setcounter{braid@strands}{\pgfkeysvalueof{/pgf/braid/number of strands}}% - \braid@width=\pgfkeysvalueof{/pgf/braid/width} - \braid@height=\pgfkeysvalueof{/pgf/braid/height} - \braid@eh=\pgfkeysvalueof{/pgf/braid/border height} - \braid@height=-\braid@height - \braid@eh=-\braid@eh - \braid@increase@leveltrue - \braid@process@start + \setcounter{braid@strands}{% + \pgfkeysvalueof{/pgf/braid/number of strands}}% + \braid@width=\pgfkeysvalueof{/pgf/braid/width}% + \braid@height=\pgfkeysvalueof{/pgf/braid/height}% + \braid@eh=\pgfkeysvalueof{/pgf/braid/border height}% + \pgfkeysgetvalue{/pgf/braid/control factor}{\braid@cf}% + \pgfkeysgetvalue{/pgf/braid/nudge factor}{\braid@nf}% + \braid@height=-\braid@height + \braid@eh=-\braid@eh + \braid@increase@leveltrue + \braid@process@start } \newdimen\braid@width \newdimen\braid@height @@ -330,6 +509,7 @@ \newdimen\braid@dy \newdimen\braid@eh \newif\ifbraid@increase@level +\newif\ifbraid@strand@labels@origin \let\braid@style\pgfutil@empty \let\braid@floors@style\pgfutil@empty \def\braid@over@cross{1} @@ -342,7 +522,10 @@ number of strands/.initial=0, height/.initial=1cm, width/.initial=1cm, + gap/.initial=.1, border height/.initial=.25cm, + control factor/.initial=.5, + nudge factor/.initial=.05, name/.code={% \def\braid@name{#1}% }, @@ -357,24 +540,28 @@ \braidset{style each strand/.list={#1}}% }, style each strand/.code={% - \expandafter\edef\csname braid@options@strand@#1\endcsname{\braid@temp}% + \expandafter\edef% + \csname braid@options@strand@#1\endcsname{\braid@temp}% }, style floors/.code 2 args={% \def\braid@temp{#2}% \braidset{style each floor/.list={#1}}% }, style each floor/.code={% - \expandafter\edef\csname braid@options@floor@#1\endcsname{\braid@temp}% + \expandafter\edef% + \csname braid@options@floor@#1\endcsname{\braid@temp}% }, style all floors/.code={% \def\braid@floors@style{#1} - } + }, + strand label/.style={}, + strand label by origin/.is if=braid@strand@labels@origin, } \def\braidset#1{% \pgfkeys{/pgf/braid/.cd,#1}} %% -%% Copyright (C) 2011 by Andrew Stacey +%% Copyright (C) 2011-2019 by Andrew Stacey %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License (LPPL), either @@ -392,6 +579,7 @@ %% braids.ins, %% braids.pdf, %% braids.sty, +%% tikzlibrarybraids.code.tex, %% braids_doc.pdf. %% %% diff --git a/Master/texmf-dist/tex/latex/braids/tikzlibrarybraids.code.tex b/Master/texmf-dist/tex/latex/braids/tikzlibrarybraids.code.tex new file mode 100644 index 00000000000..6bef1d8b8ce --- /dev/null +++ b/Master/texmf-dist/tex/latex/braids/tikzlibrarybraids.code.tex @@ -0,0 +1,916 @@ +%% +%% This is file `tikzlibrarybraids.code.tex', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% braids_code.dtx (with options: `library') +%% ---------------------------------------------------------------- +%% braids --- a style file for drawing braid diagrams with TikZ/PGF +%% E-mail: loopspace@mathforge.org +%% Released under the LaTeX Project Public License v1.3c or later +%% See http://www.latex-project.org/lppl.txt +%% ---------------------------------------------------------------- +%% +\ProvidesFile{tikzlibrarybraids.code.tex}[% + 2019/03/20 v2.0 Tikz/PGF library for drawing braid diagrams% +] +\RequirePackage{expl3} +\ExplSyntaxOn +\tl_new:N \l__braid_tmpa_tl +\tl_new:N \l__braid_tmpb_tl +\tl_new:N \l__braid_tmpc_tl +\tl_new:N \l__braid_tmpd_tl +\tl_new:N \l__braid_anchor_strand_tl +\tl_new:N \l__braid_anchor_level_tl +\fp_new:N \l__braid_height_fp +\fp_new:N \l__braid_width_fp +\fp_new:N \l__braid_nudge_fp +\fp_new:N \l__braid_control_fp +\fp_new:N \l__braid_ctrlax_fp +\fp_new:N \l__braid_ctrlay_fp +\fp_new:N \l__braid_ctrlbx_fp +\fp_new:N \l__braid_ctrlby_fp +\fp_new:N \l__braid_endx_fp +\fp_new:N \l__braid_endy_fp +\fp_new:N \l__braid_anchor_x_fp +\fp_new:N \l__braid_anchor_y_fp +\int_new:N \l__braid_tmpa_int +\int_new:N \l__braid_length_int +\int_new:N \l__braid_strands_int +\int_new:N \l__braid_crossing_int +\int_new:N \l__braid_anchor_level_int +\int_new:N \l__braid_floor_int +\seq_new:N \l__braid_word_seq +\seq_new:N \l__braid_crossing_seq +\seq_new:N \l__braid_anchor_seq +\seq_new:N \l__braid_floors_seq +\str_new:N \l__braid_tmpa_str +\str_new:N \l__braid_sup_str +\str_set:Nn \l__braid_sup_str {^} +\str_new:N \l__braid_sub_str +\str_set:Nn \l__braid_sub_str {_} +\str_new:N \l__braid_hyphen_str +\str_set:Nn \l__braid_hyphen_str {-} +\str_new:N \l__braid_bar_str +\str_set:Nn \l__braid_bar_str {|} +\str_new:N \l__braid_one_str +\str_set:Nn \l__braid_one_str {1} +\bool_new:N \l__braid_step_level_bool +\bool_new:N \l__braid_swap_crossing_bool +\bool_new:N \l__braid_floor_bool +\prop_new:N \l__braid_strands_prop +\prop_new:N \l__braid_permutation_prop +\prop_new:N \l__braid_crossing_permutation_prop +\prop_new:N \l__braid_inverse_prop +\prop_new:N \l__braid_anchor_prop +\tikzset{ + braid/.pic={ + code={ + \__braid_parse_word:n {#1} + \__braid_count: + \__braid_render: + } + }, + floor/.pic={ + code={ + \path[pic~ actions, draw=none] (0,0) rectangle (1,1); + \path[pic~ actions, fill=none] (0,0) -- (1,0) (0,1) -- (1,1); + } + }, + /tikz/braid/.search~ also={/tikz}, + braid/.cd, + anchor/.initial=1-s, + number~ of~ strands/.initial=0, + height/.initial=-1cm, + width/.initial=1cm, + gap/.initial=.05, + border~ height/.initial=.25cm, + floor~ border/.initial=.25cm, + add~ floor/.code={ + \seq_push:Nn \l__braid_floors_seq {#1} + }, + control~ factor/.initial=.5, + nudge~ factor/.initial=.05 +} +\cs_new_nopar:Npn \__braid_parse_word:n #1 +{ + \seq_clear:N \l__braid_word_seq + \tl_clear:N \l__braid_tmpa_tl + \tl_set:Nn \l__braid_tmpb_tl {#1} + + \bool_until_do:nn { \tl_if_empty_p:N \l__braid_tmpb_tl } + { + \str_set:Nx \l__braid_tmpa_str {\tl_head:N \l__braid_tmpb_tl} + \tl_set:Nx \l__braid_tmpb_tl {\tl_tail:N \l__braid_tmpb_tl} + \str_case_e:nnTF {\l__braid_tmpa_str} + { + {_} + { + \tl_put_right:Nx \l__braid_tmpa_tl + { + \exp_not:N \__braid_parse_index:n {\tl_head:N \l__braid_tmpb_tl} + } + \tl_set:Nx \l__braid_tmpb_tl {\tl_tail:N \l__braid_tmpb_tl} + } + {^} + { + \tl_put_left:Nx \l__braid_tmpa_tl + { + \exp_not:N \__braid_parse_exponent:n {\tl_head:N \l__braid_tmpb_tl} + } + \tl_set:Nx \l__braid_tmpb_tl {\tl_tail:N \l__braid_tmpb_tl} + } + {|} + { + \tl_if_empty:NF \l__braid_tmpa_tl + { + \seq_put_right:NV \l__braid_word_seq \l__braid_tmpa_tl + \tl_clear:N \l__braid_tmpa_tl + } + + \tl_set:Nn \l__braid_tmpa_tl { + \bool_set_false:N \l__braid_step_level_bool + \bool_set_true:N \l__braid_floor_bool + } + \seq_put_right:NV \l__braid_word_seq \l__braid_tmpa_tl + \tl_clear:N \l__braid_tmpa_tl + } + {-} + { + \tl_put_right:Nn \l__braid_tmpa_tl + { + \bool_set_false:N \l__braid_step_level_bool + } + } + {1} + { + \tl_if_empty:NF \l__braid_tmpa_tl + { + \seq_put_right:NV \l__braid_word_seq \l__braid_tmpa_tl + \tl_clear:N \l__braid_tmpa_tl + } + \tl_put_right:Nn \l__braid_tmpa_tl {\__braid_do_identity:} + } + {~} + { + } + } + { + } + { + \tl_if_empty:NF \l__braid_tmpa_tl + { + \seq_put_right:NV \l__braid_word_seq \l__braid_tmpa_tl + \tl_clear:N \l__braid_tmpa_tl + } + } + } + \tl_if_empty:NF \l__braid_tmpa_tl + { + \seq_put_right:NV \l__braid_word_seq \l__braid_tmpa_tl + \tl_clear:N \l__braid_tmpa_tl + } +} +\cs_new_nopar:Npn \__braid_parse_index:n #1 +{ + \seq_set_from_clist:Nn \l__braid_crossing_seq {#1} + \int_compare:nT {\seq_count:N \l__braid_crossing_seq == 1} + { + \seq_put_right:Nx \l__braid_crossing_seq {\int_eval:n {#1 + 1} } + } + \bool_if:NT \l__braid_swap_crossing_bool + { + \seq_pop_left:NN \l__braid_crossing_seq \l__braid_tmpa_tl + \seq_put_right:NV \l__braid_crossing_seq \l__braid_tmpa_tl + } +} +\cs_new_nopar:Npn \__braid_parse_exponent:n #1 +{ + \int_compare:nTF {#1 == -1} + { + \bool_set_true:N \l__braid_swap_crossing_bool + } + { + \bool_set_false:N \l__braid_swap_crossing_bool + } +} +\cs_new_nopar:Npn \__braid_do_identity: +{ +} +\cs_new_nopar:Npn \__braid_count: +{ + \int_zero:N \l__braid_length_int + \int_set:Nn \l__braid_strands_int {\__braid_value:n {number~of~strands}} + \prop_clear:N \l__braid_permutation_prop + \prop_clear:N \l__braid_crossing_permutation_prop + \prop_clear:N \l__braid_anchor_prop + \prop_clear:N \l__braid_inverse_prop + + \seq_map_inline:Nn \l__braid_word_seq + { + \seq_clear:N \l__braid_crossing_seq + \bool_set_true:N \l__braid_step_level_bool + \bool_set_false:N \l__braid_swap_crossing_bool + ##1 + \bool_if:NT \l__braid_step_level_bool + { + \int_incr:N \l__braid_length_int + } + \seq_if_empty:NF \l__braid_crossing_seq + { + \int_set:Nn \l__braid_strands_int + { + \int_max:nn + { + \int_max:nn {\l__braid_strands_int} + { \seq_item:Nn \l__braid_crossing_seq {1}} + } + { + \seq_item:Nn \l__braid_crossing_seq {2} + } + } + } + } + \int_step_inline:nnnn {1} {1} {\l__braid_strands_int} + { + \prop_put:Nnn \l__braid_permutation_prop {##1} {##1} + \prop_put:Nnn \l__braid_anchor_prop {##1} {##1} + \prop_put:Nnn \l__braid_crossing_permutation_prop {##1} {##1} + } + \tl_set:Nx \l__braid_tmpa_tl {\__braid_value:n {anchor}} + \seq_set_split:NnV \l__braid_anchor_seq {-} \l__braid_tmpa_tl + + \tl_set:Nx \l__braid_tmpa_tl {\seq_item:Nn \l__braid_anchor_seq {1}} + \tl_if_eq:VnTF \l__braid_tmpa_tl {rev} + { + \tl_set:Nx \l__braid_anchor_strand_tl {\seq_item:Nn \l__braid_anchor_seq {2}} + \tl_set:Nx \l__braid_anchor_level_tl {\seq_item:Nn \l__braid_anchor_seq {3}} + } + { + \tl_set:Nx \l__braid_anchor_strand_tl {\seq_item:Nn \l__braid_anchor_seq {1}} + \tl_set:Nx \l__braid_anchor_level_tl {\seq_item:Nn \l__braid_anchor_seq {2}} + } + \tl_if_eq:VnTF \l__braid_anchor_level_tl {s} + { + \int_set:Nn \l__braid_anchor_level_int {-1} + } + { + \tl_if_eq:VnTF \l__braid_anchor_level_tl {e} + { + \int_set:Nn \l__braid_anchor_level_int {-1} + } + { + \int_set:Nn \l__braid_anchor_level_int + {\tl_use:N \l__braid_anchor_level_tl} + } + } + + \int_zero:N \l__braid_crossing_int + \int_incr:N \l__braid_crossing_int + \seq_map_inline:Nn \l__braid_word_seq + { + \bool_set_true:N \l__braid_step_level_bool + \seq_clear:N \l__braid_crossing_seq + \bool_set_false:N \l__braid_swap_crossing_bool + ##1 + \seq_if_empty:NF \l__braid_crossing_seq + { + \prop_get:NxN \l__braid_permutation_prop + { + \seq_item:Nn \l__braid_crossing_seq {1} + } \l__braid_tmpa_tl + \prop_get:NxN \l__braid_permutation_prop + { + \seq_item:Nn \l__braid_crossing_seq {2} + } \l__braid_tmpb_tl + + \prop_put:NxV \l__braid_permutation_prop + { + \seq_item:Nn \l__braid_crossing_seq {2} + } \l__braid_tmpa_tl + \prop_put:NxV \l__braid_permutation_prop + { + \seq_item:Nn \l__braid_crossing_seq {1} + } \l__braid_tmpb_tl + } + \int_compare:nT {\l__braid_crossing_int = \l__braid_anchor_level_int} + { + \prop_set_eq:NN \l__braid_anchor_prop \l__braid_permutation_prop + } + \bool_if:NT \l__braid_step_level_bool + { + \int_incr:N \l__braid_crossing_int + } + } + \int_step_inline:nnnn {1} {1} {\l__braid_strands_int} + { + \prop_get:NnN \l__braid_anchor_prop {##1} \l__braid_tmpa_tl + \prop_put:NVn \l__braid_inverse_prop \l__braid_tmpa_tl {##1} + } + \prop_set_eq:NN \l__braid_anchor_prop \l__braid_inverse_prop + \int_step_inline:nnnn {1} {1} {\l__braid_strands_int} + { + \prop_get:NnN \l__braid_permutation_prop {##1} \l__braid_tmpa_tl + \prop_put:NVn \l__braid_inverse_prop \l__braid_tmpa_tl {##1} + } + \tl_set:Nx \l__braid_tmpa_tl {\seq_item:Nn \l__braid_anchor_seq {1}} + \tl_if_eq:VnT \l__braid_tmpa_tl {rev} + { + \prop_get:NVN \l__braid_permutation_prop + \l__braid_anchor_strand_tl \l__braid_anchor_strand_tl + } + \tl_if_eq:VnF \l__braid_anchor_level_tl {s} + { + \tl_if_eq:VnTF \l__braid_anchor_level_tl {e} + { + \prop_get:NVN \l__braid_inverse_prop + \l__braid_anchor_strand_tl \l__braid_anchor_strand_tl + } + { + \prop_get:NVN \l__braid_anchor_prop + \l__braid_anchor_strand_tl \l__braid_anchor_strand_tl + } + } +} +\cs_new_nopar:Npn \__braid_dim_value:n #1 +{ + \dim_to_fp:n {\pgfkeysvalueof{/tikz/braid/#1}} +} +\cs_new_nopar:Npn \__braid_value:n #1 +{ + \pgfkeysvalueof{/tikz/braid/#1} +} +\cs_generate_variant:Nn \prop_get:NnN {NxN} +\cs_generate_variant:Nn \prop_put:Nnn {NxV} +\cs_generate_variant:Nn \tl_if_eq:nnTF {VnTF} +\cs_generate_variant:Nn \tl_if_eq:nnF {VnF} +\cs_generate_variant:Nn \tl_if_eq:nnT {VnT} + +\cs_new_nopar:Npn \__braid_render: +{ + \fp_set:Nn \l__braid_anchor_x_fp { - 1 * (\tl_use:N \l__braid_anchor_strand_tl - 1) * \__braid_dim_value:n {width} } + + \tl_if_eq:VnTF \l__braid_anchor_level_tl {s} + { + \fp_set:Nn \l__braid_anchor_y_fp {0} + } + { + \tl_if_eq:VnTF \l__braid_anchor_level_tl {e} + { + \fp_set:Nn \l__braid_anchor_y_fp { + -1 * \l__braid_length_int * \__braid_dim_value:n {height} + - sign(\__braid_dim_value:n {height}) + * 2 * \__braid_dim_value:n {border~ height} + } + } + { + \fp_set:Nn \l__braid_anchor_y_fp { + -1 * \l__braid_anchor_level_tl * \__braid_dim_value:n {height} + - sign(\__braid_dim_value:n {height}) + * \__braid_dim_value:n {border~ height} + } + } + } + + \begin{scope}[ + shift={ + (\fp_to_decimal:N \l__braid_anchor_x_fp pt, + \fp_to_decimal:N \l__braid_anchor_y_fp pt + ) + } + ] + \prop_clear:N \l__braid_strands_prop + \fp_zero:N \l__braid_height_fp + \fp_zero:N \l__braid_nudge_fp + \fp_zero:N \l__braid_control_fp + \fp_set:Nn \l__braid_height_fp + { + sign(\__braid_dim_value:n {height}) + * \__braid_dim_value:n {border~ height} + } + \fp_set:Nn \l__braid_width_fp + { + (\l__braid_strands_int - 1) * \__braid_dim_value:n {width} + + 2 * sign(\__braid_dim_value:n{width}) + * \__braid_dim_value:n {floor~ border} + } + \fp_set:Nn \l__braid_nudge_fp + { + \__braid_value:n {nudge~ factor} * \__braid_dim_value:n {height} + } + \fp_set:Nn \l__braid_control_fp + { + \__braid_value:n {control~ factor} * \__braid_dim_value:n {height} + } + \fp_sub:Nn \l__braid_control_fp {\l__braid_nudge_fp} + \int_step_inline:nnnn {1} {1} {\l__braid_strands_int} + { + \prop_get:NnN \l__braid_inverse_prop {##1} \l__braid_tmpa_tl + \prop_put:Nnx \l__braid_strands_prop {##1} + { + \exp_not:N \draw[ + braid/every~ strand/.try, + braid/strand~ ##1/.try + ] + \exp_not:N \__braid_moveto:nn { + \fp_eval:n {(##1 - 1) * \__braid_dim_value:n {width} } + } {0} + \exp_not:N \__braid_lineto:nn { + \fp_eval:n {(##1 - 1) * \__braid_dim_value:n {width} } + } { \fp_to_decimal:N \l__braid_height_fp} + } + \__braid_coordinate:xxxx {-##1-s} {-rev-\l__braid_tmpa_tl-s} + {\fp_eval:n {(##1 - 1) * \__braid_dim_value:n {width} }} {0} + + \__braid_coordinate:xxxx {-##1-0} {-rev-\l__braid_tmpa_tl-0} + {\fp_eval:n {(##1 - 1) * \__braid_dim_value:n {width} }} + { \fp_to_decimal:N \l__braid_height_fp} + } + \seq_map_inline:Nn \l__braid_floors_seq + { + \tl_set:Nx \l__braid_tmpa_tl {\clist_item:nn {##1} {5}} + \__braid_do_floor:Vxxxx \l__braid_tmpa_tl + {\fp_eval:n + { + -1*sign(\__braid_dim_value:n{width}) + * \__braid_dim_value:n {floor~ border} + + (\__braid_dim_value:n {width}) * (\clist_item:nn {##1} {1} - 1) + } + pt + } + {\fp_eval:n + { + \l__braid_height_fp + ( \__braid_dim_value:n {height} ) * (\clist_item:nn {##1} {2}) + } + pt + } + {\fp_eval:n { + ( (\clist_item:nn {##1} {3}) * \__braid_dim_value:n {width} + + 2 * sign(\__braid_dim_value:n{width}) + * \__braid_dim_value:n {floor~ border} ) / \dim_to_fp:n {1cm} + } + } + {\fp_eval:n { + (\clist_item:nn {##1} {4}) * ( \__braid_dim_value:n {height} ) / \dim_to_fp:n {1cm} + } + } + } + \int_zero:N \l__braid_crossing_int + \int_incr:N \l__braid_crossing_int + + \seq_map_inline:Nn \l__braid_word_seq + { + \seq_clear:N \l__braid_crossing_seq + \bool_set_true:N \l__braid_step_level_bool + \bool_set_false:N \l__braid_floor_bool + \bool_set_false:N \l__braid_swap_crossing_bool + ##1 + \bool_if:NT \l__braid_floor_bool + { + \__braid_do_floor:Vxxxx \l__braid_crossing_int + {\fp_eval:n + { + -1*sign(\__braid_dim_value:n{width}) + * \__braid_dim_value:n {floor~ border} + } + pt + } + {\fp_to_decimal:N \l__braid_height_fp pt} + {\fp_eval:n { \l__braid_width_fp / \dim_to_fp:n {1cm} }} + {\fp_eval:n { ( \__braid_dim_value:n {height} ) / \dim_to_fp:n {1cm}}} + } + \seq_if_empty:NF \l__braid_crossing_seq + { + \prop_get:NxN \l__braid_crossing_permutation_prop + {\seq_item:Nn \l__braid_crossing_seq {1}} \l__braid_tmpa_tl + \prop_get:NxN \l__braid_crossing_permutation_prop + {\seq_item:Nn \l__braid_crossing_seq {2}} \l__braid_tmpb_tl + + \prop_put:NxV \l__braid_crossing_permutation_prop + {\seq_item:Nn \l__braid_crossing_seq {2}} \l__braid_tmpa_tl + \prop_put:NxV \l__braid_crossing_permutation_prop + {\seq_item:Nn \l__braid_crossing_seq {1}} \l__braid_tmpb_tl + \prop_get:NxN \l__braid_strands_prop + {\seq_item:Nn \l__braid_crossing_seq {1}} \l__braid_tmpa_tl + \prop_get:NxN \l__braid_strands_prop + {\seq_item:Nn \l__braid_crossing_seq {2}} \l__braid_tmpb_tl + \tl_put_right:Nx \l__braid_tmpa_tl + { + \exp_not:N \__braid_lineto:nn + + {\fp_eval:n + { + (\seq_item:Nn \l__braid_crossing_seq {1} - 1) + * \__braid_dim_value:n {width} + } + } + {\fp_eval:n { \l__braid_height_fp + \l__braid_nudge_fp } } + + \exp_not:N \__braid_curveto:nnnnnn + + {0} + {\fp_eval:n { \l__braid_control_fp}} + + {0} + {\fp_eval:n {- \l__braid_control_fp}} + + {\fp_eval:n + { + (\seq_item:Nn \l__braid_crossing_seq {2} - 1) + * \__braid_dim_value:n {width} + } + } + {\fp_eval:n + { + \l__braid_height_fp + + \__braid_dim_value:n {height} + - \l__braid_nudge_fp + } + } + } + \tl_put_right:Nx \l__braid_tmpb_tl + { + \exp_not:N \__braid_lineto:nn + + {\fp_eval:n + { + (\seq_item:Nn \l__braid_crossing_seq {2} - 1) + * \__braid_dim_value:n {width} + } + } + {\fp_eval:n { \l__braid_height_fp + \l__braid_nudge_fp } } + + \exp_not:N \__braid_curveto:nnnnnn + + {0} + { + \fp_eval:n { + \l__braid_control_fp * (.5 - \__braid_value:n {gap} ) + } + } + + { + \fp_eval:n { + - (.5 - \__braid_value:n {gap} ) / 3 * + \__braid_bezier_tangent:nnnnn + {.5 - \__braid_value:n {gap} } + {0} + {0} + { + (\seq_item:Nn \l__braid_crossing_seq {1} + - \seq_item:Nn \l__braid_crossing_seq {2}) + * \__braid_dim_value:n {width} + } + { + (\seq_item:Nn \l__braid_crossing_seq {1} + - \seq_item:Nn \l__braid_crossing_seq {2}) + * \__braid_dim_value:n {width} + } + } + } + { + \fp_eval:n { + -(.5 - \__braid_value:n {gap} ) / 3 * + \__braid_bezier_tangent:nnnnn + {.5 - \__braid_value:n {gap} } + {0} + {\l__braid_control_fp} + { + \__braid_dim_value:n {height} + - 2* \l__braid_nudge_fp + - \l__braid_control_fp + } + {\__braid_dim_value:n {height} - 2* \l__braid_nudge_fp} + } + } + + { + \fp_eval:n { + (\seq_item:Nn \l__braid_crossing_seq {2} - 1) + * \__braid_dim_value:n {width} + + \__braid_bezier_point:nnnnn + {.5 - \__braid_value:n {gap} } + {0} + {0} + { + (\seq_item:Nn \l__braid_crossing_seq {1} + - \seq_item:Nn \l__braid_crossing_seq {2}) + * \__braid_dim_value:n {width} + } + { + (\seq_item:Nn \l__braid_crossing_seq {1} + - \seq_item:Nn \l__braid_crossing_seq {2}) + * \__braid_dim_value:n {width} + } + } + } + { + \fp_eval:n { + \l__braid_height_fp + \l__braid_nudge_fp + + \__braid_bezier_point:nnnnn + {.5 - \__braid_value:n {gap} } + {0} + {\l__braid_control_fp} + { + \__braid_dim_value:n {height} + - 2* \l__braid_nudge_fp + - \l__braid_control_fp + } + {\__braid_dim_value:n {height} - 2* \l__braid_nudge_fp} + } + } + + \exp_not:N \__braid_moveto:nn + { + \fp_eval:n { + (\seq_item:Nn \l__braid_crossing_seq {2} - 1) + * \__braid_dim_value:n {width} + + \__braid_bezier_point:nnnnn + {.5 + \__braid_value:n {gap} } + {0} + {0} + { + (\seq_item:Nn \l__braid_crossing_seq {1} + - \seq_item:Nn \l__braid_crossing_seq {2}) + * \__braid_dim_value:n {width} + } + { + (\seq_item:Nn \l__braid_crossing_seq {1} + - \seq_item:Nn \l__braid_crossing_seq {2}) + * \__braid_dim_value:n {width} + } + } + } + { + \fp_eval:n { + \l__braid_height_fp + \l__braid_nudge_fp + + \__braid_bezier_point:nnnnn + {.5 + \__braid_value:n {gap} } + {0} + {\l__braid_control_fp} + { + \__braid_dim_value:n {height} - 2* \l__braid_nudge_fp + - \l__braid_control_fp + } + {\__braid_dim_value:n {height} - 2* \l__braid_nudge_fp} + } + } + + \exp_not:N \__braid_curveto:nnnnnn + + { + \fp_eval:n { + (.5 - \__braid_value:n {gap} ) / 3 * + \__braid_bezier_tangent:nnnnn + {.5 + \__braid_value:n {gap} } + {0} + {0} + { + (\seq_item:Nn \l__braid_crossing_seq {1} + - \seq_item:Nn \l__braid_crossing_seq {2}) + * \__braid_dim_value:n {width} + } + { + (\seq_item:Nn \l__braid_crossing_seq {1} + - \seq_item:Nn \l__braid_crossing_seq {2}) + * \__braid_dim_value:n {width} + } + } + } + { + \fp_eval:n { + (.5 - \__braid_value:n {gap} ) / 3 * + \__braid_bezier_tangent:nnnnn + {.5 + \__braid_value:n {gap} } + {0} + {\l__braid_control_fp} + { + \__braid_dim_value:n {height} - 2* \l__braid_nudge_fp + - \l__braid_control_fp + } + {\__braid_dim_value:n {height} - 2* \l__braid_nudge_fp} + } + } + + {0} + { \fp_eval:n { + -\l__braid_control_fp * (.5 - \__braid_value:n {gap} ) + } + } + + {\fp_eval:n + { + (\seq_item:Nn \l__braid_crossing_seq {1} - 1) + * \__braid_dim_value:n {width} + } + } + {\fp_eval:n + { + \l__braid_height_fp + \__braid_dim_value:n {height} + - \l__braid_nudge_fp + } + } + + } + \prop_put:NxV \l__braid_strands_prop + {\seq_item:Nn \l__braid_crossing_seq {2}} \l__braid_tmpa_tl + \prop_put:NxV \l__braid_strands_prop + {\seq_item:Nn \l__braid_crossing_seq {1}} \l__braid_tmpb_tl + \int_compare:nT + { + \int_max:nn + { + \seq_item:Nn \l__braid_crossing_seq {1} + } + { + \seq_item:Nn \l__braid_crossing_seq {2} + } + - + \int_min:nn + { + \seq_item:Nn \l__braid_crossing_seq {1} + } + { + \seq_item:Nn \l__braid_crossing_seq {2} + } + > 1 + } + { + \int_step_inline:nnnn + { + \int_min:nn + { + \seq_item:Nn \l__braid_crossing_seq {1} + } + { + \seq_item:Nn \l__braid_crossing_seq {2} + } + + 1} + {1} + { + \int_max:nn + { + \seq_item:Nn \l__braid_crossing_seq {1} + } + { + \seq_item:Nn \l__braid_crossing_seq {2} + } + - 1 + } + { + + \prop_get:NnN \l__braid_strands_prop {####1} \l__braid_tmpa_tl + \tl_put_right:Nx \l__braid_tmpa_tl + { + \exp_not:N \__braid_lineto:nn + {\fp_eval:n {(####1 - 1) * \__braid_dim_value:n {width} }} + {\fp_eval:n + { + \l__braid_height_fp + \l__braid_nudge_fp + + .5 * \l__braid_control_fp + } + } + \exp_not:N \__braid_moveto:nn + {\fp_eval:n {(####1 - 1) * \__braid_dim_value:n {width} }} + {\fp_eval:n + { + \l__braid_height_fp + \__braid_dim_value:n {height} + - \l__braid_nudge_fp - .5 * \l__braid_control_fp + } + } + } + + \prop_put:NnV \l__braid_strands_prop {####1} \l__braid_tmpa_tl + } + } + } + \bool_if:NT \l__braid_step_level_bool + { + \fp_add:Nn \l__braid_height_fp { \__braid_dim_value:n {height} } + + \int_step_inline:nnnn {1} {1} {\l__braid_strands_int} + { + \prop_get:NnN \l__braid_crossing_permutation_prop + {####1} \l__braid_tmpb_tl + \prop_get:NVN \l__braid_inverse_prop + \l__braid_tmpb_tl \l__braid_tmpa_tl + + \__braid_coordinate:xxxx + {-\l__braid_tmpb_tl-\int_use:N \l__braid_crossing_int} + {-rev-\l__braid_tmpa_tl-\int_use:N \l__braid_crossing_int } + {\fp_eval:n { (####1 - 1) * \__braid_dim_value:n {width} }} + {\fp_to_decimal:N \l__braid_height_fp} + } + + \int_incr:N \l__braid_crossing_int + } + } + + \fp_add:Nn \l__braid_height_fp + { + sign(\__braid_dim_value:n {height}) + * \__braid_dim_value:n {border~ height} + } + \int_step_inline:nnnn {1} {1} {\l__braid_strands_int} + { + \prop_get:NxN \l__braid_strands_prop {##1} \l__braid_tmpa_tl + \prop_get:NxN \l__braid_permutation_prop {##1} \l__braid_tmpb_tl + + \tl_put_right:Nx \l__braid_tmpa_tl { + \exp_not:N \__braid_lineto:nn + {\fp_eval:n { (##1 - 1) * \__braid_dim_value:n {width} }} + {\fp_to_decimal:N \l__braid_height_fp} + coordinate (-rev-##1-e) + coordinate (-\l__braid_tmpb_tl-e) + ; + } + + \prop_put:NnV \l__braid_strands_prop {##1} \l__braid_tmpa_tl + } + \int_step_inline:nnnn {1} {1} {\l__braid_strands_int} + { + \prop_get:NnN \l__braid_strands_prop {##1} \l__braid_tmpa_tl + \tl_use:N \l__braid_tmpa_tl + } + \end{scope} +} +\cs_new_nopar:Npn \__braid_moveto:nn #1#2 +{ + (#1 pt, #2 pt) +} +\cs_new_nopar:Npn \__braid_lineto:nn #1#2 +{ + -- (#1 pt, #2 pt) +} +\cs_new_nopar:Npn \__braid_curveto:nnnnnn #1#2#3#4#5#6 +{ + .. controls +(#1 pt, #2 pt) and +(#3 pt, #4 pt) + .. (#5 pt, #6 pt) +} +\cs_new_nopar:Npn \__braid_coordinate:nnnn #1#2#3#4 +{ + \coordinate[alias=#2] (#1) at (#3 pt,#4 pt); +} +\cs_generate_variant:Nn \__braid_coordinate:nnnn {xxxx} +\cs_new_nopar:Npn \__braid_bezier_point:nnnnn #1#2#3#4#5 +{ + \fp_eval:n + { + (1 - (#1)) * (1 - (#1)) * (1 - (#1)) * (#2) + + + 3 * (1 - (#1)) * (1 - (#1)) * (#1) * (#3) + + + 3 * (1 - (#1)) * (#1) * (#1) * (#4) + + + (#1) * (#1) * (#1) * (#5) + } +} +\cs_new_nopar:Npn \__braid_bezier_tangent:nnnnn #1#2#3#4#5 +{ + \fp_eval:n + { + 3 * (1 - (#1)) * (1 - (#1)) * (#3 - (#2)) + + + 6 * (1 - (#1)) * (#1) * (#4 - (#3)) + + + 3 * (#1) * (#1) * (#5 - (#4)) + } +} +\cs_new_nopar:Npn \__braid_do_floor:nnnnn #1#2#3#4#5 +{ + \pic[pic~ type=floor, + xscale=#4, + yscale=#5, + at={(#2,#3)}, + braid/every~ floor/.try, + braid/floor~#1/.try, + ]; +} +\cs_generate_variant:Nn \__braid_do_floor:nnnnn {Vxxxx} +\ExplSyntaxOff + +%% +%% Copyright (C) 2011-2019 by Andrew Stacey +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License (LPPL), either +%% version 1.3c of this license or (at your option) any later +%% version. The latest version of this license is in the file: +%% +%% http://www.latex-project.org/lppl.txt +%% +%% This work is "maintained" (as per LPPL maintenance status) by +%% Andrew Stacey. +%% +%% This work consists of the files braids.dtx +%% braids_doc.tex +%% and the derived files README.txt, +%% braids.ins, +%% braids.pdf, +%% braids.sty, +%% tikzlibrarybraids.code.tex, +%% braids_doc.pdf. +%% +%% +%% End of file `tikzlibrarybraids.code.tex'. -- cgit v1.2.3