%% %% This is file `tikzlibrarybraids.code.tex', %% generated with the docstrip utility. %% %% The original source files were: %% %% braids_code.dtx (with options: `library') %% ---------------------------------------------------------------- %% braids --- a TikZ library for drawing braid diagrams %% bundle version: v2.3 2024/01/09 %% E-mail: Andrew Stacey %% Released under the LaTeX Project Public License v1.3c or later %% See http://www.latex-project.org/lppl.txt %% ---------------------------------------------------------------- %% \ProvidesFile{tikzlibrarybraids.code.tex}[% 2024/01/09 v2.3 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_tmpb_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_crossing_start_int \int_new:N \l__braid_crossing_end_int \int_new:N \l__braid_crossing_width_int \int_new:N \l__braid_crossing_long_int \int_new:N \l__braid_crossing_start_factor_int \int_new:N \l__braid_crossing_end_factor_int \int_new:N \l__braid_anchor_level_int \int_new:N \l__braid_floor_int \seq_new:N \l__braid_tmpa_seq \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 \bool_new:N \l__braid_step_level_bool \bool_new:N \l__braid_swap_crossing_bool \bool_new:N \l__braid_default_crossing_bool \bool_new:N \l__braid_default_symbol_bool \bool_set_true:N \l__braid_default_crossing_bool \bool_set_true:N \l__braid_default_symbol_bool \bool_new:N \l__braid_floor_bool \bool_new:N \l__braid_height_bool \bool_new:N \l__braid_crossing_height_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 \msg_new:nnn {braids} {height} {The~ keys~ "height"~ and~ "crossing~ height"~ shouldn't~ be~ used~ together~ (the~ setting~ for~ "crossing~ height"~ will~ be~ used)} \cs_generate_variant:Nn \seq_set_split:Nnn {NVn} \cs_generate_variant:Nn \str_compare:nNnTF {VNnTF} \tikzset{ braid/.pic={ \begin{scope}[every~ braid/.try] \__braid_parse_word:n {#1} \__braid_count: \__braid_render: \end{scope} }, floor/.pic={ \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, crossing~ convention/.is~choice, crossing~ convention/over/.code={ \bool_set_true:N \l__braid_default_crossing_bool }, crossing~ convention/down/.code={ \bool_set_true:N \l__braid_default_crossing_bool }, crossing~ convention/under/.code={ \bool_set_false:N \l__braid_default_crossing_bool }, crossing~ convention/up/.code={ \bool_set_false:N \l__braid_default_crossing_bool }, crossing~ convention/.default=over, flip~ crossing~ convention/.code={ \bool_set_inverse:N \l__braid_default_crossing_bool }, set~ symbols/.is~choice, set~ symbols/over/.code={ \bool_set_true:N \l__braid_default_symbol_bool }, set~ symbols/down/.code={ \bool_set_true:N \l__braid_default_symbol_bool }, set~ symbols/under/.code={ \bool_set_false:N \l__braid_default_symbol_bool }, set~ symbols/up/.code={ \bool_set_false:N \l__braid_default_symbol_bool }, set~ symbols/.default=over, flip~ symbols/.code={ \bool_set_inverse:N \l__braid_default_symbol_bool }, height/.initial=-1cm, height/.code={ \bool_if:NTF \l__braid_crossing_height_bool { \msg_term:nn {braids} {height} } { \pgfkeyssetvalue{/tikz/braid/height}{#1} \bool_set_true:N \l__braid_height_bool } }, crossing~ height/.code={ \bool_if:NT \l__braid_height_bool { \msg_term:nn {braids} {height} } \exp_args:Nnx \pgfkeyssetvalue {/tikz/braid/height} {\dim_eval:n {-\dim_abs:n{#1}}} \bool_set_true:N \l__braid_crossing_height_bool }, 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_clear:N \l__braid_crossing_seq \clist_map_inline:nn {#1} { \tl_if_in:nnTF {##1} {-} { \seq_set_split:Nnn \l__braid_tmpa_seq {-} {##1} \int_compare:nTF {\seq_item:Nn \l__braid_tmpa_seq {1} < \seq_item:Nn \l__braid_tmpa_seq {2} } { \int_set:Nn \l__braid_tmpa_int {1} } { \int_set:Nn \l__braid_tmpa_int {-1} } \int_step_inline:nnnn {\seq_item:Nn \l__braid_tmpa_seq {1}} {\l__braid_tmpa_int} {\seq_item:Nn \l__braid_tmpa_seq {2}} { \seq_put_right:Nn \l__braid_crossing_seq {####1} } } { \seq_put_right: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_xor:nnT {\l__braid_swap_crossing_bool} {\l__braid_default_symbol_bool} { \seq_reverse:N \l__braid_crossing_seq } } \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 { \seq_map_inline:Nn \l__braid_crossing_seq { \int_set:Nn \l__braid_strands_int { \int_max:nn {\l__braid_strands_int} {####1} } } } } \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}} \tl_if_in:NnTF \l__braid_tmpa_tl {-} { \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_set:Nn \l__braid_anchor_level_int {-1} \tl_set:Nn \l__braid_anchor_strand_tl {-1} } \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 { \int_step_inline:nnn {2} {\seq_count:N \l__braid_crossing_seq} { \int_set:Nn \l__braid_tmpa_int {####1} \int_set:Nn \l__braid_tmpb_int {####1 - 1} \prop_get:NxN \l__braid_permutation_prop { \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int} } \l__braid_tmpa_tl \prop_get:NxN \l__braid_permutation_prop { \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int} } \l__braid_tmpb_tl \prop_put:NxV \l__braid_permutation_prop { \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int} } \l__braid_tmpa_tl \prop_put:NxV \l__braid_permutation_prop { \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int} } \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_if_eq:VnF \l__braid_anchor_strand_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: { \tl_if_eq:VnTF \l__braid_anchor_strand_tl {-1} { \tl_set:cn {pgf@sh@ns@temporary braid node}{rectangle} \tl_set:cx {pgf@sh@np@temporary braid node}{% \exp_not:N\def \exp_not:N\southwest { \exp_not:N\pgfqpoint {0pt} {0pt} } \exp_not:N\def \exp_not:N\northeast { \exp_not:N\pgfqpoint { \fp_to_dim:n { (\l__braid_strands_int - 1) * abs(\__braid_dim_value:n {width}) } } { \fp_to_dim:n { \l__braid_length_int * abs(\__braid_dim_value:n {height}) + 2 * \__braid_dim_value:n {border~ height} } } } }% \pgfgettransform\l__braid_tmpa_tl \tl_set:cV {pgf@sh@nt@temporary braid node} \l__braid_tmpa_tl \tl_set:cV {pgf@sh@pi@temporary braid node} \pgfpictureid \pgfpointanchor{temporary braid node} {\__braid_value:n {anchor}} \fp_set:Nn \l__braid_anchor_x_fp { - \dim_use:c {pgf@x} - (1 - sign(\__braid_dim_value:n {width})) / 2 * (\l__braid_strands_int - 1) * \__braid_dim_value:n {width} } \fp_set:Nn \l__braid_anchor_y_fp { - \dim_use:c {pgf@y} - (1 - sign(\__braid_dim_value:n {height})) / 2 * ( \l__braid_length_int * abs(\__braid_dim_value:n {height}) + 2 * \__braid_dim_value:n {border~ height} ) * sign(\__braid_dim_value:n {height}) } } { \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 { \int_set:Nn \l__braid_crossing_long_int { % \seq_item:Nn \l__braid_crossing_seq {\seq_count:N \l__braid_crossing_seq} \seq_item:Nn \l__braid_crossing_seq {1} } \int_set:Nn \l__braid_crossing_start_int { \int_min:nn { \seq_item:Nn \l__braid_crossing_seq {1} } { \seq_item:Nn \l__braid_crossing_seq {\seq_count:N \l__braid_crossing_seq} } } \int_set:Nn \l__braid_crossing_end_int { \int_max:nn { \seq_item:Nn \l__braid_crossing_seq {1} } { \seq_item:Nn \l__braid_crossing_seq {\seq_count:N \l__braid_crossing_seq} } } \int_set:Nn \l__braid_crossing_width_int { \l__braid_crossing_end_int - \l__braid_crossing_start_int } \int_step_inline:nnn {2} {\seq_count:N \l__braid_crossing_seq} { \bool_if:NTF \l__braid_default_crossing_bool { \int_set:Nn \l__braid_tmpa_int {####1} \int_set:Nn \l__braid_tmpb_int {####1 - 1} } { \int_set:Nn \l__braid_tmpa_int {####1 - 1} \int_set:Nn \l__braid_tmpb_int {####1} } \prop_get:NxN \l__braid_crossing_permutation_prop {\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int}} \l__braid_tmpa_tl \prop_get:NxN \l__braid_crossing_permutation_prop {\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int}} \l__braid_tmpb_tl \prop_put:NxV \l__braid_crossing_permutation_prop {\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int}} \l__braid_tmpa_tl \prop_put:NxV \l__braid_crossing_permutation_prop {\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int}} \l__braid_tmpb_tl \prop_get:NxN \l__braid_strands_prop {\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int}} \l__braid_tmpa_tl \prop_get:NxN \l__braid_strands_prop {\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int}} \l__braid_tmpb_tl \int_set:Nn \l__braid_crossing_start_factor_int {0} \int_set:Nn \l__braid_crossing_end_factor_int {0} \int_compare:nT { ####1 = \seq_count:N \l__braid_crossing_seq } { \int_set:Nn \l__braid_crossing_end_factor_int {1} } \int_compare:nT { ####1 = 2 } { \int_set:Nn \l__braid_crossing_start_factor_int {1} } \tl_put_right:Nx \l__braid_tmpa_tl { \exp_not:N \__braid_lineto:nn {\fp_eval:n { (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int} - 1) * \__braid_dim_value:n {width} } } {\fp_eval:n { \l__braid_height_fp + \l__braid_nudge_fp * \l__braid_crossing_start_factor_int + \__braid_dim_value:n {height} * (####1 - 2)/(\seq_count:N \l__braid_crossing_seq - 1) } } \exp_not:N \__braid_curveto:nnnnnn {0} {\fp_eval:n { \l__braid_control_fp * 1/(\seq_count:N \l__braid_crossing_seq - 1)}} {0} {\fp_eval:n {- \l__braid_control_fp * 1/(\seq_count:N \l__braid_crossing_seq - 1)}} {\fp_eval:n { (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int} - 1) * \__braid_dim_value:n {width} } } {\fp_eval:n { \l__braid_height_fp + \__braid_dim_value:n {height} * (####1 - 1)/(\seq_count:N \l__braid_crossing_seq - 1) - \l__braid_nudge_fp * \l__braid_crossing_end_factor_int } } } \int_set:Nn \l__braid_crossing_start_factor_int {0} \int_set:Nn \l__braid_crossing_end_factor_int {0} \int_compare:nT { ####1 = \seq_count:N \l__braid_crossing_seq } { \int_set:Nn \l__braid_crossing_end_factor_int {1} } \int_compare:nT { ####1 = 2 } { \int_set:Nn \l__braid_crossing_start_factor_int {1} } \tl_put_right:Nx \l__braid_tmpb_tl { \exp_not:N \__braid_lineto:nn {\fp_eval:n { (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int} - 1) * \__braid_dim_value:n {width} } } {\fp_eval:n { \l__braid_height_fp + \l__braid_nudge_fp * \l__braid_crossing_start_factor_int + \__braid_dim_value:n {height} * (####1 - 2)/(\seq_count:N \l__braid_crossing_seq - 1) } } \exp_not:N \__braid_curveto:nnnnnn {0} { \fp_eval:n { \l__braid_control_fp * (.5 - \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) ) * 1/(\seq_count:N \l__braid_crossing_seq - 1) } } { \fp_eval:n { - (.5 - \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) ) / 3 * \__braid_bezier_tangent:nnnnn {.5 - \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) } {0} {0} { (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int} - \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int}) * \__braid_dim_value:n {width} } { (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int} - \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int}) * \__braid_dim_value:n {width} } } } { \fp_eval:n { -(.5 - \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) ) / 3 * \__braid_bezier_tangent:nnnnn {.5 - \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) } {0} { \l__braid_control_fp * 1/(\seq_count:N \l__braid_crossing_seq - 1) } { \__braid_dim_value:n {height} * 1/(\seq_count:N \l__braid_crossing_seq - 1) - \l__braid_nudge_fp * \l__braid_crossing_start_factor_int - \l__braid_nudge_fp * \l__braid_crossing_end_factor_int - \l__braid_control_fp * 1/(\seq_count:N \l__braid_crossing_seq - 1) } { \__braid_dim_value:n {height} * 1/(\seq_count:N \l__braid_crossing_seq - 1) - \l__braid_nudge_fp * \l__braid_crossing_start_factor_int - \l__braid_nudge_fp * \l__braid_crossing_end_factor_int } } } { \fp_eval:n { (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int} - 1) * \__braid_dim_value:n {width} + \__braid_bezier_point:nnnnn {.5 - \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) } {0} {0} { (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int} - \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int}) * \__braid_dim_value:n {width} } { (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int} - \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int}) * \__braid_dim_value:n {width} } } } { \fp_eval:n { \l__braid_height_fp + \l__braid_nudge_fp * \l__braid_crossing_start_factor_int + \__braid_dim_value:n {height} * (####1 - 2)/(\seq_count:N \l__braid_crossing_seq - 1) + \__braid_bezier_point:nnnnn {.5 - \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) } {0} { \l__braid_control_fp * 1/(\seq_count:N \l__braid_crossing_seq - 1) } { \__braid_dim_value:n {height} * 1/(\seq_count:N \l__braid_crossing_seq - 1) - \l__braid_nudge_fp * \l__braid_crossing_start_factor_int - \l__braid_nudge_fp * \l__braid_crossing_end_factor_int - \l__braid_control_fp * 1/(\seq_count:N \l__braid_crossing_seq - 1) } {\__braid_dim_value:n {height} * 1/(\seq_count:N \l__braid_crossing_seq - 1) - \l__braid_nudge_fp * \l__braid_crossing_start_factor_int - \l__braid_nudge_fp * \l__braid_crossing_end_factor_int } } } \exp_not:N \__braid_moveto:nn { \fp_eval:n { (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int} - 1) * \__braid_dim_value:n {width} + \__braid_bezier_point:nnnnn {.5 + \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) } {0} {0} { (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int} - \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int}) * \__braid_dim_value:n {width} } { (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int} - \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int}) * \__braid_dim_value:n {width} } } } { \fp_eval:n { \l__braid_height_fp + \l__braid_nudge_fp * \l__braid_crossing_start_factor_int + \__braid_dim_value:n {height} * (####1 - 2)/(\seq_count:N \l__braid_crossing_seq - 1) + \__braid_bezier_point:nnnnn {.5 + \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) } {0} { \l__braid_control_fp * 1/(\seq_count:N \l__braid_crossing_seq - 1) } { \__braid_dim_value:n {height} * 1/(\seq_count:N \l__braid_crossing_seq - 1) - \l__braid_nudge_fp * \l__braid_crossing_start_factor_int - \l__braid_nudge_fp * \l__braid_crossing_end_factor_int - \l__braid_control_fp * 1/(\seq_count:N \l__braid_crossing_seq - 1) } {\__braid_dim_value:n {height} * 1/(\seq_count:N \l__braid_crossing_seq - 1) - \l__braid_nudge_fp * \l__braid_crossing_start_factor_int - \l__braid_nudge_fp * \l__braid_crossing_end_factor_int } } } \exp_not:N \__braid_curveto:nnnnnn { \fp_eval:n { (.5 - \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) ) / 3 * \__braid_bezier_tangent:nnnnn {.5 + \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) } {0} {0} { (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int} - \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int}) * \__braid_dim_value:n {width} } { (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int} - \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int}) * \__braid_dim_value:n {width} } } } { \fp_eval:n { (.5 - \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) ) / 3 * \__braid_bezier_tangent:nnnnn {.5 + \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) } {0} { \l__braid_control_fp * 1/(\seq_count:N \l__braid_crossing_seq - 1) } { \__braid_dim_value:n {height} * 1/(\seq_count:N \l__braid_crossing_seq - 1) - \l__braid_nudge_fp * \l__braid_crossing_start_factor_int - \l__braid_nudge_fp * \l__braid_crossing_end_factor_int - \l__braid_control_fp * 1/(\seq_count:N \l__braid_crossing_seq - 1) } {\__braid_dim_value:n {height} * 1/(\seq_count:N \l__braid_crossing_seq - 1) - \l__braid_nudge_fp * \l__braid_crossing_start_factor_int - \l__braid_nudge_fp * \l__braid_crossing_end_factor_int } } } {0} {\fp_eval:n { - \l__braid_control_fp * (.5 - \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) ) * 1/(\seq_count:N \l__braid_crossing_seq - 1)} } {\fp_eval:n { (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int} - 1) * \__braid_dim_value:n {width} } } {\fp_eval:n { \l__braid_height_fp + \__braid_dim_value:n {height} * (####1 - 1)/(\seq_count:N \l__braid_crossing_seq - 1) - \l__braid_nudge_fp * \l__braid_crossing_end_factor_int } } } \prop_put:NxV \l__braid_strands_prop {\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int}} \l__braid_tmpa_tl \prop_put:NxV \l__braid_strands_prop {\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int}} \l__braid_tmpb_tl \int_compare:nT { \int_max:nn { \seq_item:Nn \l__braid_crossing_seq {####1 - 1} } { \seq_item:Nn \l__braid_crossing_seq {####1} } - \int_min:nn { \seq_item:Nn \l__braid_crossing_seq {####1 - 1} } { \seq_item:Nn \l__braid_crossing_seq {####1} } > 1 } { \int_step_inline:nnnn { \int_min:nn { \seq_item:Nn \l__braid_crossing_seq {####1 - 1} } { \seq_item:Nn \l__braid_crossing_seq {####1} } + 1} {1} { \int_max:nn { \seq_item:Nn \l__braid_crossing_seq {####1 - 1} } { \seq_item:Nn \l__braid_crossing_seq {####1} } - 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 / (\seq_count:N \l__braid_crossing_seq - 1) + \__braid_dim_value:n {height} * (####1 - 2)/(\seq_count:N \l__braid_crossing_seq - 1) } } \exp_not:N \__braid_moveto: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 / (\seq_count:N \l__braid_crossing_seq - 1) + \__braid_dim_value:n {height} * (####1 - 1)/(\seq_count:N \l__braid_crossing_seq - 1) } } } \prop_put:NnV \l__braid_strands_prop {########1} \l__braid_tmpa_tl } } \int_compare:nTF { \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int} = \l__braid_crossing_long_int } { \int_set:Nn \l__braid_crossing_long_int {\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int}} } { \int_compare:nT { \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int} = \l__braid_crossing_long_int } { \int_set:Nn \l__braid_crossing_long_int {\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int}} } } } } \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 } \tl_if_empty:cF {tikz@fig@name} { \tl_gset:cn {pgf@sh@ns@ \tl_use:c{tikz@fig@name} }{rectangle} \tl_gset:cx {pgf@sh@np@ \tl_use:c{tikz@fig@name} }{% \exp_not:N\def \exp_not:N\southwest { \exp_not:N\pgfqpoint { \fp_to_dim:n { min(0, (\l__braid_strands_int - 1) * (\__braid_dim_value:n {width}) ) } } { \fp_to_dim:n { min(0, \l__braid_length_int * (\__braid_dim_value:n {height}) + 2 * sign(\__braid_dim_value:n {height}) * \__braid_dim_value:n {border~ height} ) } } } \exp_not:N\def \exp_not:N\northeast { \exp_not:N\pgfqpoint { \fp_to_dim:n { max(0, (\l__braid_strands_int - 1) * (\__braid_dim_value:n {width}) ) } } { \fp_to_dim:n { max(0, \l__braid_length_int * (\__braid_dim_value:n {height}) + 2 * sign(\__braid_dim_value:n {height}) * \__braid_dim_value:n {border~ height} ) } } } }% \pgfgettransform\l__braid_tmpa_tl \tl_gset:cV {pgf@sh@nt@ \tl_use:c{tikz@fig@name} } \l__braid_tmpa_tl \tl_gset:cV {pgf@sh@pi@ \tl_use:c{tikz@fig@name} } \pgfpictureid } \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-2024 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'.