From fb65df85b540b77156e13d2cd358a376ec558055 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Wed, 13 Feb 2019 22:22:09 +0000 Subject: spath3 (13feb19) git-svn-id: svn://tug.org/texlive/trunk@50018 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/latex/spath3/README.txt | 9 + Master/texmf-dist/doc/latex/spath3/calligraphy.pdf | Bin 288184 -> 0 bytes .../doc/latex/spath3/calligraphy_doc.pdf | Bin 0 -> 288184 bytes Master/texmf-dist/doc/latex/spath3/knots.pdf | Bin 384979 -> 0 bytes Master/texmf-dist/doc/latex/spath3/knots_doc.pdf | Bin 0 -> 384979 bytes Master/texmf-dist/doc/latex/spath3/spath3_code.pdf | Bin 413476 -> 439282 bytes Master/texmf-dist/source/latex/spath3/spath3.dtx | 371 ++++++++++++++------- Master/texmf-dist/source/latex/spath3/spath3.ins | 91 +++++ Master/texmf-dist/tex/latex/spath3/spath3.sty | 62 ++-- .../latex/spath3/tikzlibrarycalligraphy.code.tex | 12 +- .../tex/latex/spath3/tikzlibraryknots.code.tex | 278 ++++++++++----- Master/tlpkg/libexec/ctan2tds | 1 + 12 files changed, 595 insertions(+), 229 deletions(-) create mode 100644 Master/texmf-dist/doc/latex/spath3/README.txt delete mode 100644 Master/texmf-dist/doc/latex/spath3/calligraphy.pdf create mode 100644 Master/texmf-dist/doc/latex/spath3/calligraphy_doc.pdf delete mode 100644 Master/texmf-dist/doc/latex/spath3/knots.pdf create mode 100644 Master/texmf-dist/doc/latex/spath3/knots_doc.pdf create mode 100644 Master/texmf-dist/source/latex/spath3/spath3.ins diff --git a/Master/texmf-dist/doc/latex/spath3/README.txt b/Master/texmf-dist/doc/latex/spath3/README.txt new file mode 100644 index 00000000000..a9d1fe62103 --- /dev/null +++ b/Master/texmf-dist/doc/latex/spath3/README.txt @@ -0,0 +1,9 @@ +---------------------------------------------------------------- +spath3 --- LaTeX3 functions for manipulating PGF soft paths +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 functions used to manipulate PGFs soft paths. +As applications of its use, included are a package for drawing calligraphic paths and a package for drawing knot diagrams. diff --git a/Master/texmf-dist/doc/latex/spath3/calligraphy.pdf b/Master/texmf-dist/doc/latex/spath3/calligraphy.pdf deleted file mode 100644 index 12a0313d8ad..00000000000 Binary files a/Master/texmf-dist/doc/latex/spath3/calligraphy.pdf and /dev/null differ diff --git a/Master/texmf-dist/doc/latex/spath3/calligraphy_doc.pdf b/Master/texmf-dist/doc/latex/spath3/calligraphy_doc.pdf new file mode 100644 index 00000000000..12a0313d8ad Binary files /dev/null and b/Master/texmf-dist/doc/latex/spath3/calligraphy_doc.pdf differ diff --git a/Master/texmf-dist/doc/latex/spath3/knots.pdf b/Master/texmf-dist/doc/latex/spath3/knots.pdf deleted file mode 100644 index d818161e21f..00000000000 Binary files a/Master/texmf-dist/doc/latex/spath3/knots.pdf and /dev/null differ diff --git a/Master/texmf-dist/doc/latex/spath3/knots_doc.pdf b/Master/texmf-dist/doc/latex/spath3/knots_doc.pdf new file mode 100644 index 00000000000..d818161e21f Binary files /dev/null and b/Master/texmf-dist/doc/latex/spath3/knots_doc.pdf differ diff --git a/Master/texmf-dist/doc/latex/spath3/spath3_code.pdf b/Master/texmf-dist/doc/latex/spath3/spath3_code.pdf index b1decee7719..be1f2941bd8 100644 Binary files a/Master/texmf-dist/doc/latex/spath3/spath3_code.pdf and b/Master/texmf-dist/doc/latex/spath3/spath3_code.pdf differ diff --git a/Master/texmf-dist/source/latex/spath3/spath3.dtx b/Master/texmf-dist/source/latex/spath3/spath3.dtx index 73d4a172377..9d6ae2825df 100644 --- a/Master/texmf-dist/source/latex/spath3/spath3.dtx +++ b/Master/texmf-dist/source/latex/spath3/spath3.dtx @@ -35,7 +35,7 @@ See http://www.latex-project.org/lppl.txt \endpreamble \postamble -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 @@ -49,15 +49,15 @@ Andrew Stacey. This work consists of the files spath3.dtx calligraphy_doc.tex - knot_doc.tex + knots_doc.tex and the derived files spath3.ins, - spath3.pdf, + spath3_code.pdf, spath3.sty, tikzlibrarycalligraphy.code.tex tikzlibraryknots.code.tex - calligraphy_doc.pdf - knots_doc.pdf - README.txt + calligraphy.pdf + knots.pdf + README \endpostamble \usedir{tex/latex/spath3} @@ -131,7 +131,7 @@ and the derived files spath3.ins, % % \fi % -% \CheckSum{4316} +% \CheckSum{4488} % % \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 @@ -152,6 +152,7 @@ and the derived files spath3.ins, % % \changes{1.0}{2011/05/03}{Converted to DTX file} % \changes{1.1}{2016/02/19}{Fixes due to changes in LaTeX3} +% \changes{1.2}{2019/02/12}{More fixes due to changes in LaTeX3} % % \DoNotIndex{\newcommand,\newenvironment} % @@ -194,7 +195,7 @@ and the derived files spath3.ins, \NeedsTeXFormat{LaTeX2e} \RequirePackage{expl3} \RequirePackage{pgf} -\ProvidesExplPackage {spath3} {2016/02/19} {1.1} {Functions for +\ProvidesExplPackage {spath3} {2019/02/12} {1.2} {Functions for manipulating PGF soft paths} \RequirePackage{xparse} % \end{macrocode} @@ -211,6 +212,7 @@ manipulating PGF soft paths} \fp_new:N \l__spath_tmpa_fp \fp_new:N \l__spath_tmpb_fp \int_new:N \l__spath_tmpa_int +\int_new:N \g__spath_map_int % \end{macrocode} % % We need to be able to compare against the macros that can occur in a soft path so these token lists contain them. @@ -496,7 +498,7 @@ manipulating PGF soft paths} } \__spath_get:nnN {#1} {#2} #3 } -\cs_generate_variant:Nn \spath_get:nnN {nnV,VnN,VnV} +\cs_generate_variant:Nn \spath_get:nnN {VnN} % \end{macrocode} % \end{macro} % @@ -1635,8 +1637,8 @@ manipulating PGF soft paths} % \begin{macrocode} \cs_new_nopar:Npn \spath_map_component:Nn #1#2 { - \int_gincr:N \g__prg_map_int - \cs_gset:cpn { __prg_map_ \int_use:N \g__prg_map_int :w } ##1 {#2} + \int_gincr:N \g__spath_map_int + \cs_gset:cpn { __spath_map_ \int_use:N \g__spath_map_int :w } ##1 {#2} \tl_set:NV \l__spath_tmpa_tl #1 \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} \tl_put_right:NV \l__spath_tmpa_tl \g__spath_moveto_tl @@ -1648,7 +1650,7 @@ manipulating PGF soft paths} \tl_set:Nx \l__spath_tmpc_tl {\tl_head:N \l__spath_tmpa_tl} \tl_if_eq:NNT \l__spath_tmpc_tl \g__spath_moveto_tl { - \exp_args:NnV \use:c { __prg_map_ \int_use:N \g__prg_map_int :w } \l__spath_tmpb_tl + \exp_args:NnV \use:c { __spath_map_ \int_use:N \g__spath_map_int :w } \l__spath_tmpb_tl \tl_clear:N \l__spath_tmpb_tl } \tl_if_single:NTF \l__spath_tmpc_tl @@ -1669,9 +1671,9 @@ manipulating PGF soft paths} % \begin{macrocode} \cs_new_nopar:Npn \spath_map_segment_inline:Nn #1#2 { - \int_gincr:N \g__prg_map_int - \cs_gset:cpn { __prg_map_ \int_use:N \g__prg_map_int :w } ##1 ##2 {#2} - \spath_map_segment_function:Nc #1 { __prg_map_ \int_use:N \g__prg_map_int :w } + \int_gincr:N \g__spath_map_int + \cs_gset:cpn { __spath_map_ \int_use:N \g__spath_map_int :w } ##1 ##2 {#2} + \spath_map_segment_function:Nc #1 { __spath_map_ \int_use:N \g__spath_map_int :w } } % \end{macrocode} % \end{macro} @@ -1681,10 +1683,10 @@ manipulating PGF soft paths} % \begin{macrocode} \cs_new_nopar:Npn \spath_map_segment_inline:nn #1#2 { - \int_gincr:N \g__prg_map_int - \cs_gset:cpn { __prg_map_ \int_use:N \g__prg_map_int :w } ##1 ##2 {#2} + \int_gincr:N \g__spath_map_int + \cs_gset:cpn { __spath_map_ \int_use:N \g__spath_map_int :w } ##1 ##2 {#2} \spath_get:nnN {#1} {path} \l__spath_tmpd_tl - \spath_map_segment_function:Nc \l__spath_tmpd_tl { __prg_map_ \int_use:N \g__prg_map_int :w } + \spath_map_segment_function:Nc \l__spath_tmpd_tl { __spath_map_ \int_use:N \g__spath_map_int :w } } % \end{macrocode} % \end{macro} @@ -1764,7 +1766,28 @@ manipulating PGF soft paths} \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} } - } + + \g__spath_closepath_tl + { + \tl_set_eq:NN \l__spath_tmpb_tl \g__spath_moveto_tl + \tl_put_right:Nx \l__spath_tmpb_tl + { + {\dim_use:N \l__spath_tmpa_dim} + {\dim_use:N \l__spath_tmpb_dim} + } + \tl_put_right:NV \l__spath_tmpb_tl \g__spath_lineto_tl + + \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} + \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl} + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} + + \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} + \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl} + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} + + } + + } { \tl_set_eq:NN \l__spath_tmpb_tl \l__spath_tmpc_tl @@ -1865,8 +1888,8 @@ manipulating PGF soft paths} % \begin{macrocode} \NewDocumentCommand \SPathInfoInto { m m m } { - \tl_set:Nn \l_tmpa_tl #3 - \spath_get:nnV {#1} {#2} \l_tmpa_tl + \tl_clear_new:N #3 + \spath_get:nnN {#1} {#2} #3 } % \end{macrocode} % \end{macro} @@ -1963,8 +1986,8 @@ manipulating PGF soft paths} \tl_gclear:N \l__spath_smuggle_tl \tl_set_eq:NN \l__spath_tmpa_tl \g__spath_moveto_tl \tl_put_right:Nx \l__spath_tmpa_tl { + {\tl_item:nn {#2} {2}} {\tl_item:nn {#2} {3}} - {\tl_item:nn {#2} {4}} } \tl_put_right:NV \l__spath_tmpa_tl \g__spath_curvetoa_tl \tl_put_right:Nx \l__spath_tmpa_tl @@ -2993,6 +3016,8 @@ manipulating PGF soft paths} \tl_new:N \l__knot_clip_width_tl \tl_new:N \l__knot_name_tl \tl_new:N \l__knot_node_tl +\tl_new:N \l__knot_aux_tl +\tl_new:N \l__knot_auxa_tl \int_new:N \l__knot_tmpa_int \int_new:N \l__knot_strands_int @@ -3004,7 +3029,8 @@ manipulating PGF soft paths} \dim_new:N \l__knot_tmpb_dim \dim_new:N \l__knot_tmpc_dim \dim_new:N \l__knot_tolerance_dim -\dim_new:N \l__knot_clip_radius_dim +\dim_new:N \l__knot_clip_bg_radius_dim +\dim_new:N \l__knot_clip_draw_radius_dim \bool_new:N \l__knot_draft_bool \bool_new:N \l__knot_ignore_ends_bool @@ -3015,6 +3041,9 @@ manipulating PGF soft paths} \bool_new:N \l__knot_prepend_prev_bool \bool_new:N \l__knot_append_next_bool \bool_new:N \l__knot_skip_bool +\bool_new:N \l__knot_save_bool + +\seq_new:N \l__knot_nodes_seq \bool_set_true:N \l__knot_ignore_ends_bool % \end{macrocode} @@ -3062,8 +3091,16 @@ manipulating PGF soft paths} }, background~ colour=white, knot~ diagram, - name/.store~in=\l__knot_name_tl, + name/.store~ in=\l__knot_name_tl, name={knot}, + save~ intersections/.is~ choice, + save~ intersections/.default=true, + save~ intersections/true/.code={ + \bool_set_true:N \l__knot_save_bool + }, + save~ intersections/false/.code={ + \bool_set_false:N \l__knot_save_bool + }, every~ strand/.style={draw}, ignore~ endpoint~ intersections/.code={ \tl_if_eq:nnTF {#1} {true} @@ -3090,13 +3127,26 @@ manipulating PGF soft paths} }, consider~ self~ intersections/.default={true}, clip~ radius/.code={ - \dim_set:Nn \l__knot_clip_radius_dim {#1} + \dim_set:Nn \l__knot_clip_bg_radius_dim {#1} + \dim_set:Nn \l__knot_clip_draw_radius_dim {#1+2pt} + }, + clip~ draw~ radius/.code={ + \dim_set:Nn \l__knot_clip_draw_radius_dim {#1} + }, + clip~ background~ radius/.code={ + \dim_set:Nn \l__knot_clip_bg_radius_dim {#1} }, clip~ radius=10pt, end~ tolerance/.code={ \dim_set:Nn \l__knot_tolerance_dim {#1} }, end~ tolerance=14pt, + clip/.style={ + clip + }, + background~ clip/.style={ + clip + }, clip~ width/.code={ \tl_set:Nn \l__knot_clip_width_tl {#1} }, @@ -3105,6 +3155,10 @@ manipulating PGF soft paths} \tl_clear_new:c {l__knot_crossing_#1} \tl_set:cn {l__knot_crossing_#1} {x} }, + ignore~ crossing/.code={% + \tl_clear_new:c {l__knot_ignore_crossing_#1} + \tl_set:cn {l__knot_ignore_crossing_#1} {x} + }, draft~ mode/.is~ choice, draft~ mode/off/.code={% \bool_set_false:N \l__knot_draft_bool @@ -3196,6 +3250,7 @@ manipulating PGF soft paths} \tikzset{knot~ diagram/.cd,every~ knot~ diagram/.try,#1} \int_zero:N \l__knot_strands_int \tl_clear:N \l__knot_redraws_tl + \seq_gclear:N \l__knot_nodes_seq } % \end{macrocode} % \end{macro} @@ -3245,11 +3300,14 @@ manipulating PGF soft paths} % \begin{macrocode} \bool_if:NTF \l__knot_draft_bool { - \tl_set:Nn \l__knot_node_tl - {\node[coordinate,pin={[knot~ diagram/draft/crossing~ label]{\int_use:N \l__knot_intersections_int}}]} + \tl_set:Nn \l__knot_node_tl { + \exp_not:N \node[coordinate, + pin={[node~ contents={\int_use:N \l__knot_intersections_int},knot~ diagram/draft/crossing~ label, knot~ diagram/draft/crossing~ \int_use:N \l__knot_intersections_int \c_space_tl label/.try] + }] + } } { - \tl_set:Nn \l__knot_node_tl {\node[coordinate]} + \tl_set:Nn \l__knot_node_tl {\exp_not:N \node[coordinate]} } % \end{macrocode} % This double loop steps through the pieces (strands or filaments) and computes the intersections and does stuff with those. @@ -3265,6 +3323,10 @@ manipulating PGF soft paths} % If any redraws were requested, do them here. % \begin{macrocode} \tl_use:N \l__knot_redraws_tl +% \end{macrocode} +% Draw the crossing nodes +% \begin{macrocode} + \seq_use:Nn \l__knot_nodes_seq {} } % \end{macrocode} % Close the scope @@ -3422,17 +3484,71 @@ manipulating PGF soft paths} \spath_get:nnN {knot \tl_use:N \l__knot_tmpa_tl} {path} \l__knot_tmpc_tl \spath_get:nnN {knot \tl_use:N \l__knot_tmpb_tl} {path} \l__knot_tmpd_tl - \pgfintersectionofpaths{\pgfsetpath\l__knot_tmpc_tl}{\pgfsetpath\l__knot_tmpd_tl} + \bool_if:nTF { + \l__knot_save_bool + && + \tl_if_exist_p:c {knot~ intersections~ \tl_use:N \l__knot_name_tl - \tl_use:N \l__knot_tmpa_tl - \tl_use:N \l__knot_tmpb_tl} + } + { + \tl_use:c {knot~ intersections~ \tl_use:N \l__knot_name_tl - \tl_use:N \l__knot_tmpa_tl - \tl_use:N \l__knot_tmpb_tl} + } + { +\pgfintersectionofpaths{\pgfsetpath\l__knot_tmpc_tl}{\pgfsetpath\l__knot_tmpd_tl} + } \int_compare:nT {\pgfintersectionsolutions > 0} { \int_step_function:nnnN {1} {1} {\pgfintersectionsolutions} \knot_do_intersection:n } + \knot_save_intersections:VV \l__knot_tmpa_tl \l__knot_tmpb_tl \group_end: } % \end{macrocode} % \end{macro} % +% \begin{macro}{\knot_save_intersections:nn} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \knot_save_intersections:nn #1#2 +{ + \bool_if:NT \l__knot_save_bool + { + \tl_clear:N \l__knot_aux_tl + \tl_put_right:Nn \l__knot_aux_tl + { + \def\pgfintersectionsolutions + } + \tl_put_right:Nx \l__knot_aux_tl + { + {\int_eval:n {\pgfintersectionsolutions}} + } + \int_compare:nT {\pgfintersectionsolutions > 0} + { + \int_step_inline:nnnn {1} {1} {\pgfintersectionsolutions} + { + \pgfpointintersectionsolution{##1} + \dim_set:Nn \l__knot_tmpa_dim {\pgf@x} + \dim_set:Nn \l__knot_tmpb_dim {\pgf@y} + \tl_put_right:Nn \l__knot_aux_tl + { + \expandafter\def\csname pgfpoint@intersect@solution@##1\endcsname + } + \tl_put_right:Nx \l__knot_aux_tl + { + {\exp_not:N \pgf@x=\dim_use:N \l__knot_tmpa_dim\exp_not:N\relax\exp_not:N \pgf@y =\dim_use:N \l__knot_tmpb_dim\relax} + } + } + \tl_set:Nn \l__knot_auxa_tl {\expandafter \gdef \csname knot~ intersections~} + \tl_put_right:Nx \l__knot_auxa_tl {\tl_use:N \l__knot_name_tl - #1 - #2} + \tl_put_right:Nn \l__knot_auxa_tl {\endcsname} + \tl_put_right:Nx \l__knot_auxa_tl {{\tl_to_str:N \l__knot_aux_tl}} + \protected@write\@auxout{}{\tl_to_str:N \l__knot_auxa_tl} + } + } +} +\cs_generate_variant:Nn \knot_save_intersections:nn {VV} +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\knot_do_intersection:n} % This handles a specific intersection. % \begin{macrocode} @@ -3476,7 +3592,7 @@ manipulating PGF soft paths} } } % \end{macrocode} -% The can also say that end points of filaments (or strands) should simply be ignored anyway. +% The user can also say that end points of filaments (or strands) should simply be ignored anyway. % \begin{macrocode} \bool_if:NT \l__knot_ignore_ends_bool { @@ -3505,135 +3621,152 @@ manipulating PGF soft paths} \int_gincr:N \l__knot_intersections_int % \end{macrocode} -% This is the flip test. -% We only render one of the paths. -% The ``flip'' swaps which one we render. +% This is the intersection test. +% If the intersection finder finds too many, it might be useful to ignore some. % \begin{macrocode} - \bool_if:nTF + \bool_if:nF { - \tl_if_exist_p:c {l__knot_crossing_ \int_use:N + \tl_if_exist_p:c {l__knot_ignore_crossing_ \int_use:N \l__knot_intersections_int} && - ! \tl_if_empty_p:c {l__knot_crossing_ \int_use:N + ! \tl_if_empty_p:c {l__knot_ignore_crossing_ \int_use:N \l__knot_intersections_int} } { - \tl_set_eq:NN \l__knot_tmpg_tl \l__knot_tmpb_tl - } - { - \tl_set_eq:NN \l__knot_tmpg_tl \l__knot_tmpa_tl - } % \end{macrocode} -% Now we know which one we're rendering, we test to see if we should also render its predecessor or successor to ensure that we render a path through the entire crossing region. -% \begin{macrocode} - \bool_if:NT \l__knot_self_intersections_bool - { - \knot_test_endpoint:VnT \l__knot_tmpg_tl {initial point} +% This is the flip test. +% We only render one of the paths. +% The ``flip'' swaps which one we render. +% \begin{macrocode} + \bool_if:nTF { - \bool_set_true:N \l__knot_prepend_prev_bool + \tl_if_exist_p:c {l__knot_crossing_ \int_use:N + \l__knot_intersections_int} + && + ! \tl_if_empty_p:c {l__knot_crossing_ \int_use:N + \l__knot_intersections_int} } { - \bool_set_false:N \l__knot_prepend_prev_bool + \tl_set_eq:NN \l__knot_tmpg_tl \l__knot_tmpb_tl } - - \knot_test_endpoint:VnT \l__knot_tmpg_tl {final point} { - \bool_set_true:N \l__knot_append_next_bool + \tl_set_eq:NN \l__knot_tmpg_tl \l__knot_tmpa_tl } +% \end{macrocode} +% Now we know which one we're rendering, we test to see if we should also render its predecessor or successor to ensure that we render a path through the entire crossing region. +% \begin{macrocode} + \bool_if:NT \l__knot_self_intersections_bool { - \bool_set_false:N \l__knot_append_next_bool - } + \knot_test_endpoint:VnT \l__knot_tmpg_tl {initial point} + { + \bool_set_true:N \l__knot_prepend_prev_bool + } + { + \bool_set_false:N \l__knot_prepend_prev_bool + } + \knot_test_endpoint:VnT \l__knot_tmpg_tl {final point} + { + \bool_set_true:N \l__knot_append_next_bool + } + { + \bool_set_false:N \l__knot_append_next_bool + } % \end{macrocode} % If either of those tests succeeded, do the appending or prepending. % \begin{macrocode} - \bool_if:nT - { - \l__knot_prepend_prev_bool || \l__knot_append_next_bool - } - { - \spath_clone:nn {knot \tl_use:N \l__knot_tmpg_tl} - {knot \tl_use:N \l__knot_prefix_tl -1} - - \tl_set_eq:cc {l__knot_options_ \tl_use:N \l__knot_prefix_tl -1} {l__knot_options_ \tl_use:N \l__knot_tmpg_tl} - \bool_if:nT { - \l__knot_prepend_prev_bool - && - \tl_if_exist_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} - && - !\tl_if_empty_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} + \l__knot_prepend_prev_bool || \l__knot_append_next_bool } { - \spath_prepend_no_move:nn {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot previous \tl_use:N \l__knot_tmpg_tl}} -% \end{macrocode} -% If we split potentially self intersecting curves, we test to see if we should prepend yet another segment. -% \begin{macrocode} + \spath_clone:nn {knot \tl_use:N \l__knot_tmpg_tl} + {knot \tl_use:N \l__knot_prefix_tl -1} + + \tl_set_eq:cc {l__knot_options_ \tl_use:N \l__knot_prefix_tl -1} {l__knot_options_ \tl_use:N \l__knot_tmpg_tl} + \bool_if:nT { - \l__knot_splits_bool + \l__knot_prepend_prev_bool && \tl_if_exist_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} && !\tl_if_empty_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} } { - \knot_test_endpoint:vnT {knot previous \tl_use:N \l__knot_tmpg_tl} {initial point} + \spath_prepend_no_move:nn {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot previous \tl_use:N \l__knot_tmpg_tl}} +% \end{macrocode} +% If we split potentially self intersecting curves, we test to see if we should prepend yet another segment. +% \begin{macrocode} + \bool_if:nT + { + \l__knot_splits_bool + && + \tl_if_exist_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} + && + !\tl_if_empty_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} + } { - \spath_get:nnN {knot \tl_use:N \l__knot_prefix_tl -1} {path} \l_tmpa_tl - \spath_prepend_no_move:nn {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot previous \tl_use:c {knot previous \tl_use:N \l__knot_tmpg_tl}}} - \spath_get:nnN {knot \tl_use:N \l__knot_prefix_tl -1} {path} \l_tmpa_tl + \knot_test_endpoint:vnT {knot previous \tl_use:N \l__knot_tmpg_tl} {initial point} + { + \spath_get:nnN {knot \tl_use:N \l__knot_prefix_tl -1} {path} \l_tmpa_tl + \spath_prepend_no_move:nn {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot previous \tl_use:c {knot previous \tl_use:N \l__knot_tmpg_tl}}} + \spath_get:nnN {knot \tl_use:N \l__knot_prefix_tl -1} {path} \l_tmpa_tl + } } } - } % \end{macrocode} % Now the same for appending. % \begin{macrocode} - \bool_if:nT - { - \l__knot_append_next_bool - && - \tl_if_exist_p:c {knot next \tl_use:N \l__knot_tmpg_tl} - && - !\tl_if_empty_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} - } - { - \spath_append_no_move:nn {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot next \tl_use:N \l__knot_tmpg_tl}} \bool_if:nT { - \l__knot_splits_bool + \l__knot_append_next_bool && - \tl_if_exist_p:c {knot previous \tl_use:N - \l__knot_tmpg_tl} + \tl_if_exist_p:c {knot next \tl_use:N \l__knot_tmpg_tl} && !\tl_if_empty_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} } { - \knot_test_endpoint:vnT {knot previous \tl_use:N \l__knot_tmpg_tl} {final point} + \spath_append_no_move:nn {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot next \tl_use:N \l__knot_tmpg_tl}} + \bool_if:nT { - \spath_append_no_move:nn {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot next \tl_use:c {knot next \tl_use:N \l__knot_tmpg_tl}}} - + \l__knot_splits_bool + && + \tl_if_exist_p:c {knot previous \tl_use:N + \l__knot_tmpg_tl} + && + !\tl_if_empty_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} + } + { + \knot_test_endpoint:vnT {knot previous \tl_use:N \l__knot_tmpg_tl} {final point} + { + \spath_append_no_move:nn {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot next \tl_use:c {knot next \tl_use:N \l__knot_tmpg_tl}}} + + } } } - } - \tl_set:Nn \l__knot_tmpg_tl {\tl_use:N \l__knot_prefix_tl -1} + \tl_set:Nn \l__knot_tmpg_tl {\tl_use:N \l__knot_prefix_tl -1} + } } - } % \end{macrocode} % Now we render the crossing. % \begin{macrocode} - \pgfscope - \group_begin: - \tikzset{knot~ diagram/every~ intersection/.try, every~ intersection/.try, knot~ diagram/intersection~ \int_use:N \l__knot_intersections_int/.try} - \knot_draw_crossing:nVV {\tl_use:N \l__knot_tmpg_tl} \l__knot_tmpa_dim \l__knot_tmpb_dim - \group_end: - \endpgfscope + \pgfscope + \group_begin: + \tikzset{knot~ diagram/every~ intersection/.try, every~ intersection/.try, knot~ diagram/intersection~ \int_use:N \l__knot_intersections_int/.try} + \knot_draw_crossing:nVV {\tl_use:N \l__knot_tmpg_tl} \l__knot_tmpa_dim \l__knot_tmpb_dim + \group_end: + \endpgfscope +% \end{macrocode} +% This ends the boolean as to whether to consider the intersection at all +% \begin{macrocode} + } % \end{macrocode} % And stick a coordinate possibly with a label at the crossing. % \begin{macrocode} - \tl_use:N \l__knot_node_tl (\l__knot_name_tl \c_space_tl \int_use:N \l__knot_intersections_int) at (\l__knot_tmpa_dim, \l__knot_tmpb_dim) {}; + \seq_gpush:Nx \l__knot_nodes_seq { \l__knot_node_tl (\l__knot_name_tl \c_space_tl \int_use:N \l__knot_intersections_int) at (\dim_use:N \l__knot_tmpa_dim, \dim_use:N \l__knot_tmpb_dim) {};} + } } @@ -3648,9 +3781,9 @@ manipulating PGF soft paths} { \dim_compare:nTF { - \dim_abs:n {\pgf@x - \tl_item:Nn #1 {1}} + \dim_abs:n { \l__knot_tmpa_dim - \tl_item:Nn #1 {1}} + - \dim_abs:n {\pgf@y - \tl_item:Nn #1 {2}} + \dim_abs:n { \l__knot_tmpb_dim - \tl_item:Nn #1 {2}} < \l__knot_tolerance_dim } @@ -3692,7 +3825,7 @@ manipulating PGF soft paths} { \group_begin: \pgfscope - \clip (#2, #3) circle[radius=\l__knot_clip_radius_dim]; + \path[knot~ diagram/background~ clip] (#2, #3) circle[radius=\l__knot_clip_bg_radius_dim]; \tl_set:Nn \l_tmpa_tl {knot~ diagram/every~ strand/.try,} \tl_if_exist:cT {l__knot_options_ #1} @@ -3705,7 +3838,7 @@ manipulating PGF soft paths} \endpgfscope \pgfscope - \clip (#2, #3) circle[radius=1.1\l__knot_clip_radius_dim]; + \path[knot~ diagram/clip] (#2, #3) circle[radius=\l__knot_clip_draw_radius_dim]; \tl_set:Nn \l_tmpa_tl {knot~ diagram/every~ strand/.try,} \tl_if_exist:cT {l__knot_options_ #1} @@ -3720,6 +3853,12 @@ manipulating PGF soft paths} } \cs_generate_variant:Nn \knot_draw_crossing:nnn {nVV} + +\cs_new_nopar:Npn \knot_draw_crossing:nn #1#2 +{ + \tikz@scan@one@point\pgfutil@firstofone #2 \relax + \knot_draw_crossing:nVV {#1} \pgf@x \pgf@y +} % \end{macrocode} % \end{macro} % @@ -3800,14 +3939,16 @@ manipulating PGF soft paths} \tl_set:cx {knot previous filament \int_use:N \l__knot_filaments_int} {filament \int_eval:n {\l__knot_filaments_int - 1}} } } - \g__spath_close_tl + \g__spath_closepath_tl { + \tl_show:N #2 \int_gincr:N \l__knot_filaments_int \spath_clear_new:n {knot filament \int_use:N \l__knot_filaments_int} - \tl_set_eq:NN \l_tmpa_tl #2 - \tl_set:Nx \l_tmpa_tl {\tl_item:Nn #2 {1}\tl_item:Nn #2 {2}\tl_item:Nn #2 {3}} + \tl_clear:N \l_tmpa_tl + \tl_put_right:Nx {\tl_item:Nn #2 {1}\tl_item:Nn #2 {2}\tl_item:Nn #2 {3}} \tl_put_right:NV \l_tmpa_tl \g__spath_lineto_tl - \tl_set:Nx \l_tmpa_tl {\tl_item:Nn #2 {5}\tl_item:Nn #2 {6}} + \tl_put_right:Nx {\tl_item:Nn #2 {5}\tl_item:Nn #2 {6}} + \tl_show:N \l_tmpa_tl \spath_put:nnV {knot filament \int_use:N \l__knot_filaments_int} {path} \l_tmpa_tl \tl_set_eq:cN {l__knot_options_filament \int_use:N \l__knot_filaments_int} \l__knot_tmpa_tl \tl_clear_new:c {knot previous filament \int_use:N \l__knot_filaments_int} @@ -3829,10 +3970,10 @@ manipulating PGF soft paths} % \begin{macrocode} \NewDocumentCommand \redraw { m m } { - \tikz@scan@one@point\pgfutil@firstofone #2 \relax - \tl_put_right:Nn \l__knot_redraws_tl {\knot_draw_crossing:nnn} +% \tikz@scan@one@point\pgfutil@firstofone #2 \relax + \tl_put_right:Nn \l__knot_redraws_tl {\knot_draw_crossing:nn} \tl_put_right:Nx \l__knot_redraws_tl { - {strand #1} {\dim_use:N \pgf@x} {\dim_use:N \pgf@y} + {strand #1} {#2}% {\dim_use:N \pgf@x} {\dim_use:N \pgf@y} } } % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/spath3/spath3.ins b/Master/texmf-dist/source/latex/spath3/spath3.ins new file mode 100644 index 00000000000..b49c85b6e71 --- /dev/null +++ b/Master/texmf-dist/source/latex/spath3/spath3.ins @@ -0,0 +1,91 @@ +%% +%% This is file `spath3.ins', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% spath3.dtx (with options: `install') +%% ---------------------------------------------------------------- +%% spath3 --- Functions for manipulating PGF soft paths +%% 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 +%% ---------------------------------------------------------------- +%% +\input docstrip.tex +\keepsilent +\askforoverwritefalse +\preamble +---------------------------------------------------------------- +spath3 --- Functions for manipulating PGF soft paths +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-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 spath3.dtx + calligraphy_doc.tex + knots_doc.tex +and the derived files spath3.ins, + spath3_code.pdf, + spath3.sty, + tikzlibrarycalligraphy.code.tex + tikzlibraryknots.code.tex + calligraphy.pdf + knots.pdf + README + +\endpostamble +\usedir{tex/latex/spath3} +\generate{ + \file{\jobname.sty}{\from{\jobname.dtx}{spath3}} +} +\generate{ + \file{tikzlibrarycalligraphy.code.tex}{\from{\jobname.dtx}{calligraphy}} +} +\generate{ + \file{tikzlibraryknots.code.tex}{\from{\jobname.dtx}{knots}} +} +\endbatchfile +%% +%% 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 spath3.dtx +%% calligraphy_doc.tex +%% knots_doc.tex +%% and the derived files spath3.ins, +%% spath3_code.pdf, +%% spath3.sty, +%% tikzlibrarycalligraphy.code.tex +%% tikzlibraryknots.code.tex +%% calligraphy.pdf +%% knots.pdf +%% README +%% +%% +%% End of file `spath3.ins'. diff --git a/Master/texmf-dist/tex/latex/spath3/spath3.sty b/Master/texmf-dist/tex/latex/spath3/spath3.sty index 876f5ca5841..43fd64cf5e2 100644 --- a/Master/texmf-dist/tex/latex/spath3/spath3.sty +++ b/Master/texmf-dist/tex/latex/spath3/spath3.sty @@ -15,7 +15,7 @@ \NeedsTeXFormat{LaTeX2e} \RequirePackage{expl3} \RequirePackage{pgf} -\ProvidesExplPackage {spath3} {2016/02/19} {1.1} {Functions for +\ProvidesExplPackage {spath3} {2019/02/12} {1.2} {Functions for manipulating PGF soft paths} \RequirePackage{xparse} \tl_new:N \l__spath_tmpa_tl @@ -28,6 +28,7 @@ manipulating PGF soft paths} \fp_new:N \l__spath_tmpa_fp \fp_new:N \l__spath_tmpb_fp \int_new:N \l__spath_tmpa_int +\int_new:N \g__spath_map_int \tl_new:N \g__spath_moveto_tl \tl_new:N \g__spath_lineto_tl \tl_new:N \g__spath_curveto_tl @@ -194,7 +195,7 @@ manipulating PGF soft paths} } \__spath_get:nnN {#1} {#2} #3 } -\cs_generate_variant:Nn \spath_get:nnN {nnV,VnN,VnV} +\cs_generate_variant:Nn \spath_get:nnN {VnN} \cs_new_nopar:Npn \spath_generate_length:n #1 { \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl @@ -1158,8 +1159,8 @@ manipulating PGF soft paths} } \cs_new_nopar:Npn \spath_map_component:Nn #1#2 { - \int_gincr:N \g__prg_map_int - \cs_gset:cpn { __prg_map_ \int_use:N \g__prg_map_int :w } ##1 {#2} + \int_gincr:N \g__spath_map_int + \cs_gset:cpn { __spath_map_ \int_use:N \g__spath_map_int :w } ##1 {#2} \tl_set:NV \l__spath_tmpa_tl #1 \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} \tl_put_right:NV \l__spath_tmpa_tl \g__spath_moveto_tl @@ -1171,7 +1172,7 @@ manipulating PGF soft paths} \tl_set:Nx \l__spath_tmpc_tl {\tl_head:N \l__spath_tmpa_tl} \tl_if_eq:NNT \l__spath_tmpc_tl \g__spath_moveto_tl { - \exp_args:NnV \use:c { __prg_map_ \int_use:N \g__prg_map_int :w } \l__spath_tmpb_tl + \exp_args:NnV \use:c { __spath_map_ \int_use:N \g__spath_map_int :w } \l__spath_tmpb_tl \tl_clear:N \l__spath_tmpb_tl } \tl_if_single:NTF \l__spath_tmpc_tl @@ -1186,16 +1187,16 @@ manipulating PGF soft paths} } \cs_new_nopar:Npn \spath_map_segment_inline:Nn #1#2 { - \int_gincr:N \g__prg_map_int - \cs_gset:cpn { __prg_map_ \int_use:N \g__prg_map_int :w } ##1 ##2 {#2} - \spath_map_segment_function:Nc #1 { __prg_map_ \int_use:N \g__prg_map_int :w } + \int_gincr:N \g__spath_map_int + \cs_gset:cpn { __spath_map_ \int_use:N \g__spath_map_int :w } ##1 ##2 {#2} + \spath_map_segment_function:Nc #1 { __spath_map_ \int_use:N \g__spath_map_int :w } } \cs_new_nopar:Npn \spath_map_segment_inline:nn #1#2 { - \int_gincr:N \g__prg_map_int - \cs_gset:cpn { __prg_map_ \int_use:N \g__prg_map_int :w } ##1 ##2 {#2} + \int_gincr:N \g__spath_map_int + \cs_gset:cpn { __spath_map_ \int_use:N \g__spath_map_int :w } ##1 ##2 {#2} \spath_get:nnN {#1} {path} \l__spath_tmpd_tl - \spath_map_segment_function:Nc \l__spath_tmpd_tl { __prg_map_ \int_use:N \g__prg_map_int :w } + \spath_map_segment_function:Nc \l__spath_tmpd_tl { __spath_map_ \int_use:N \g__spath_map_int :w } } \cs_new_nopar:Npn \spath_map_segment_function:nN #1#2 { @@ -1265,6 +1266,27 @@ manipulating PGF soft paths} \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} } + + \g__spath_closepath_tl + { + \tl_set_eq:NN \l__spath_tmpb_tl \g__spath_moveto_tl + \tl_put_right:Nx \l__spath_tmpb_tl + { + {\dim_use:N \l__spath_tmpa_dim} + {\dim_use:N \l__spath_tmpb_dim} + } + \tl_put_right:NV \l__spath_tmpb_tl \g__spath_lineto_tl + + \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} + \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl} + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} + + \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} + \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl} + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} + + } + } { @@ -1322,8 +1344,8 @@ manipulating PGF soft paths} } \NewDocumentCommand \SPathInfoInto { m m m } { - \tl_set:Nn \l_tmpa_tl #3 - \spath_get:nnV {#1} {#2} \l_tmpa_tl + \tl_clear_new:N #3 + \spath_get:nnN {#1} {#2} #3 } \NewDocumentCommand \SPathShow { m } { @@ -1372,8 +1394,8 @@ manipulating PGF soft paths} \tl_gclear:N \l__spath_smuggle_tl \tl_set_eq:NN \l__spath_tmpa_tl \g__spath_moveto_tl \tl_put_right:Nx \l__spath_tmpa_tl { + {\tl_item:nn {#2} {2}} {\tl_item:nn {#2} {3}} - {\tl_item:nn {#2} {4}} } \tl_put_right:NV \l__spath_tmpa_tl \g__spath_curvetoa_tl \tl_put_right:Nx \l__spath_tmpa_tl @@ -1463,7 +1485,7 @@ manipulating PGF soft paths} \cs_generate_variant:Nn \spath_split_curve:nnNN {nVNN, VVNN} %% -%% 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 @@ -1477,15 +1499,15 @@ manipulating PGF soft paths} %% %% This work consists of the files spath3.dtx %% calligraphy_doc.tex -%% knot_doc.tex +%% knots_doc.tex %% and the derived files spath3.ins, -%% spath3.pdf, +%% spath3_code.pdf, %% spath3.sty, %% tikzlibrarycalligraphy.code.tex %% tikzlibraryknots.code.tex -%% calligraphy_doc.pdf -%% knots_doc.pdf -%% README.txt +%% calligraphy.pdf +%% knots.pdf +%% README %% %% %% End of file `spath3.sty'. diff --git a/Master/texmf-dist/tex/latex/spath3/tikzlibrarycalligraphy.code.tex b/Master/texmf-dist/tex/latex/spath3/tikzlibrarycalligraphy.code.tex index f9530ffc9cb..9b0e082b144 100644 --- a/Master/texmf-dist/tex/latex/spath3/tikzlibrarycalligraphy.code.tex +++ b/Master/texmf-dist/tex/latex/spath3/tikzlibrarycalligraphy.code.tex @@ -806,7 +806,7 @@ } \fi %% -%% 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 @@ -820,15 +820,15 @@ %% %% This work consists of the files spath3.dtx %% calligraphy_doc.tex -%% knot_doc.tex +%% knots_doc.tex %% and the derived files spath3.ins, -%% spath3.pdf, +%% spath3_code.pdf, %% spath3.sty, %% tikzlibrarycalligraphy.code.tex %% tikzlibraryknots.code.tex -%% calligraphy_doc.pdf -%% knots_doc.pdf -%% README.txt +%% calligraphy.pdf +%% knots.pdf +%% README %% %% %% End of file `tikzlibrarycalligraphy.code.tex'. diff --git a/Master/texmf-dist/tex/latex/spath3/tikzlibraryknots.code.tex b/Master/texmf-dist/tex/latex/spath3/tikzlibraryknots.code.tex index e8a0872539c..0322a679410 100644 --- a/Master/texmf-dist/tex/latex/spath3/tikzlibraryknots.code.tex +++ b/Master/texmf-dist/tex/latex/spath3/tikzlibraryknots.code.tex @@ -29,6 +29,8 @@ \tl_new:N \l__knot_clip_width_tl \tl_new:N \l__knot_name_tl \tl_new:N \l__knot_node_tl +\tl_new:N \l__knot_aux_tl +\tl_new:N \l__knot_auxa_tl \int_new:N \l__knot_tmpa_int \int_new:N \l__knot_strands_int @@ -40,7 +42,8 @@ \dim_new:N \l__knot_tmpb_dim \dim_new:N \l__knot_tmpc_dim \dim_new:N \l__knot_tolerance_dim -\dim_new:N \l__knot_clip_radius_dim +\dim_new:N \l__knot_clip_bg_radius_dim +\dim_new:N \l__knot_clip_draw_radius_dim \bool_new:N \l__knot_draft_bool \bool_new:N \l__knot_ignore_ends_bool @@ -51,6 +54,9 @@ \bool_new:N \l__knot_prepend_prev_bool \bool_new:N \l__knot_append_next_bool \bool_new:N \l__knot_skip_bool +\bool_new:N \l__knot_save_bool + +\seq_new:N \l__knot_nodes_seq \bool_set_true:N \l__knot_ignore_ends_bool \tikzset{ @@ -94,8 +100,16 @@ }, background~ colour=white, knot~ diagram, - name/.store~in=\l__knot_name_tl, + name/.store~ in=\l__knot_name_tl, name={knot}, + save~ intersections/.is~ choice, + save~ intersections/.default=true, + save~ intersections/true/.code={ + \bool_set_true:N \l__knot_save_bool + }, + save~ intersections/false/.code={ + \bool_set_false:N \l__knot_save_bool + }, every~ strand/.style={draw}, ignore~ endpoint~ intersections/.code={ \tl_if_eq:nnTF {#1} {true} @@ -122,13 +136,26 @@ }, consider~ self~ intersections/.default={true}, clip~ radius/.code={ - \dim_set:Nn \l__knot_clip_radius_dim {#1} + \dim_set:Nn \l__knot_clip_bg_radius_dim {#1} + \dim_set:Nn \l__knot_clip_draw_radius_dim {#1+2pt} + }, + clip~ draw~ radius/.code={ + \dim_set:Nn \l__knot_clip_draw_radius_dim {#1} + }, + clip~ background~ radius/.code={ + \dim_set:Nn \l__knot_clip_bg_radius_dim {#1} }, clip~ radius=10pt, end~ tolerance/.code={ \dim_set:Nn \l__knot_tolerance_dim {#1} }, end~ tolerance=14pt, + clip/.style={ + clip + }, + background~ clip/.style={ + clip + }, clip~ width/.code={ \tl_set:Nn \l__knot_clip_width_tl {#1} }, @@ -137,6 +164,10 @@ \tl_clear_new:c {l__knot_crossing_#1} \tl_set:cn {l__knot_crossing_#1} {x} }, + ignore~ crossing/.code={% + \tl_clear_new:c {l__knot_ignore_crossing_#1} + \tl_set:cn {l__knot_ignore_crossing_#1} {x} + }, draft~ mode/.is~ choice, draft~ mode/off/.code={% \bool_set_false:N \l__knot_draft_bool @@ -201,6 +232,7 @@ \tikzset{knot~ diagram/.cd,every~ knot~ diagram/.try,#1} \int_zero:N \l__knot_strands_int \tl_clear:N \l__knot_redraws_tl + \seq_gclear:N \l__knot_nodes_seq } \cs_new_protected_nopar:Npn \knot_render: { @@ -223,11 +255,14 @@ \int_gzero:N \l__knot_intersections_int \bool_if:NTF \l__knot_draft_bool { - \tl_set:Nn \l__knot_node_tl - {\node[coordinate,pin={[knot~ diagram/draft/crossing~ label]{\int_use:N \l__knot_intersections_int}}]} + \tl_set:Nn \l__knot_node_tl { + \exp_not:N \node[coordinate, + pin={[node~ contents={\int_use:N \l__knot_intersections_int},knot~ diagram/draft/crossing~ label, knot~ diagram/draft/crossing~ \int_use:N \l__knot_intersections_int \c_space_tl label/.try] + }] + } } { - \tl_set:Nn \l__knot_node_tl {\node[coordinate]} + \tl_set:Nn \l__knot_node_tl {\exp_not:N \node[coordinate]} } \int_step_variable:nnnNn {1} {1} {\l__knot_tmpa_int - 1} \l__knot_tmpa_tl { @@ -237,6 +272,7 @@ } } \tl_use:N \l__knot_redraws_tl + \seq_use:Nn \l__knot_nodes_seq {} } \endpgfscope } @@ -363,14 +399,63 @@ \spath_get:nnN {knot \tl_use:N \l__knot_tmpa_tl} {path} \l__knot_tmpc_tl \spath_get:nnN {knot \tl_use:N \l__knot_tmpb_tl} {path} \l__knot_tmpd_tl - \pgfintersectionofpaths{\pgfsetpath\l__knot_tmpc_tl}{\pgfsetpath\l__knot_tmpd_tl} + \bool_if:nTF { + \l__knot_save_bool + && + \tl_if_exist_p:c {knot~ intersections~ \tl_use:N \l__knot_name_tl - \tl_use:N \l__knot_tmpa_tl - \tl_use:N \l__knot_tmpb_tl} + } + { + \tl_use:c {knot~ intersections~ \tl_use:N \l__knot_name_tl - \tl_use:N \l__knot_tmpa_tl - \tl_use:N \l__knot_tmpb_tl} + } + { +\pgfintersectionofpaths{\pgfsetpath\l__knot_tmpc_tl}{\pgfsetpath\l__knot_tmpd_tl} + } \int_compare:nT {\pgfintersectionsolutions > 0} { \int_step_function:nnnN {1} {1} {\pgfintersectionsolutions} \knot_do_intersection:n } + \knot_save_intersections:VV \l__knot_tmpa_tl \l__knot_tmpb_tl \group_end: } +\cs_new_protected_nopar:Npn \knot_save_intersections:nn #1#2 +{ + \bool_if:NT \l__knot_save_bool + { + \tl_clear:N \l__knot_aux_tl + \tl_put_right:Nn \l__knot_aux_tl + { + \def\pgfintersectionsolutions + } + \tl_put_right:Nx \l__knot_aux_tl + { + {\int_eval:n {\pgfintersectionsolutions}} + } + \int_compare:nT {\pgfintersectionsolutions > 0} + { + \int_step_inline:nnnn {1} {1} {\pgfintersectionsolutions} + { + \pgfpointintersectionsolution{##1} + \dim_set:Nn \l__knot_tmpa_dim {\pgf@x} + \dim_set:Nn \l__knot_tmpb_dim {\pgf@y} + \tl_put_right:Nn \l__knot_aux_tl + { + \expandafter\def\csname pgfpoint@intersect@solution@##1\endcsname + } + \tl_put_right:Nx \l__knot_aux_tl + { + {\exp_not:N \pgf@x=\dim_use:N \l__knot_tmpa_dim\exp_not:N\relax\exp_not:N \pgf@y =\dim_use:N \l__knot_tmpb_dim\relax} + } + } + \tl_set:Nn \l__knot_auxa_tl {\expandafter \gdef \csname knot~ intersections~} + \tl_put_right:Nx \l__knot_auxa_tl {\tl_use:N \l__knot_name_tl - #1 - #2} + \tl_put_right:Nn \l__knot_auxa_tl {\endcsname} + \tl_put_right:Nx \l__knot_auxa_tl {{\tl_to_str:N \l__knot_aux_tl}} + \protected@write\@auxout{}{\tl_to_str:N \l__knot_auxa_tl} + } + } +} +\cs_generate_variant:Nn \knot_save_intersections:nn {VV} \cs_new_protected_nopar:Npn \knot_do_intersection:n #1 { \pgfpointintersectionsolution{#1} @@ -424,113 +509,123 @@ { \int_gincr:N \l__knot_intersections_int - \bool_if:nTF + \bool_if:nF { - \tl_if_exist_p:c {l__knot_crossing_ \int_use:N + \tl_if_exist_p:c {l__knot_ignore_crossing_ \int_use:N \l__knot_intersections_int} && - ! \tl_if_empty_p:c {l__knot_crossing_ \int_use:N + ! \tl_if_empty_p:c {l__knot_ignore_crossing_ \int_use:N \l__knot_intersections_int} } { - \tl_set_eq:NN \l__knot_tmpg_tl \l__knot_tmpb_tl - } - { - \tl_set_eq:NN \l__knot_tmpg_tl \l__knot_tmpa_tl - } - \bool_if:NT \l__knot_self_intersections_bool - { - \knot_test_endpoint:VnT \l__knot_tmpg_tl {initial point} + \bool_if:nTF { - \bool_set_true:N \l__knot_prepend_prev_bool + \tl_if_exist_p:c {l__knot_crossing_ \int_use:N + \l__knot_intersections_int} + && + ! \tl_if_empty_p:c {l__knot_crossing_ \int_use:N + \l__knot_intersections_int} } { - \bool_set_false:N \l__knot_prepend_prev_bool + \tl_set_eq:NN \l__knot_tmpg_tl \l__knot_tmpb_tl } - - \knot_test_endpoint:VnT \l__knot_tmpg_tl {final point} - { - \bool_set_true:N \l__knot_append_next_bool - } - { - \bool_set_false:N \l__knot_append_next_bool - } - \bool_if:nT { - \l__knot_prepend_prev_bool || \l__knot_append_next_bool + \tl_set_eq:NN \l__knot_tmpg_tl \l__knot_tmpa_tl } + \bool_if:NT \l__knot_self_intersections_bool { - \spath_clone:nn {knot \tl_use:N \l__knot_tmpg_tl} - {knot \tl_use:N \l__knot_prefix_tl -1} - - \tl_set_eq:cc {l__knot_options_ \tl_use:N \l__knot_prefix_tl -1} {l__knot_options_ \tl_use:N \l__knot_tmpg_tl} - + \knot_test_endpoint:VnT \l__knot_tmpg_tl {initial point} + { + \bool_set_true:N \l__knot_prepend_prev_bool + } + { + \bool_set_false:N \l__knot_prepend_prev_bool + } + \knot_test_endpoint:VnT \l__knot_tmpg_tl {final point} + { + \bool_set_true:N \l__knot_append_next_bool + } + { + \bool_set_false:N \l__knot_append_next_bool + } \bool_if:nT { - \l__knot_prepend_prev_bool - && - \tl_if_exist_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} - && - !\tl_if_empty_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} + \l__knot_prepend_prev_bool || \l__knot_append_next_bool } { - \spath_prepend_no_move:nn {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot previous \tl_use:N \l__knot_tmpg_tl}} + \spath_clone:nn {knot \tl_use:N \l__knot_tmpg_tl} + {knot \tl_use:N \l__knot_prefix_tl -1} + + \tl_set_eq:cc {l__knot_options_ \tl_use:N \l__knot_prefix_tl -1} {l__knot_options_ \tl_use:N \l__knot_tmpg_tl} + \bool_if:nT { - \l__knot_splits_bool + \l__knot_prepend_prev_bool && \tl_if_exist_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} && !\tl_if_empty_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} } { - \knot_test_endpoint:vnT {knot previous \tl_use:N \l__knot_tmpg_tl} {initial point} + \spath_prepend_no_move:nn {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot previous \tl_use:N \l__knot_tmpg_tl}} + \bool_if:nT { - \spath_get:nnN {knot \tl_use:N \l__knot_prefix_tl -1} {path} \l_tmpa_tl - \spath_prepend_no_move:nn {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot previous \tl_use:c {knot previous \tl_use:N \l__knot_tmpg_tl}}} - \spath_get:nnN {knot \tl_use:N \l__knot_prefix_tl -1} {path} \l_tmpa_tl + \l__knot_splits_bool + && + \tl_if_exist_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} + && + !\tl_if_empty_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} + } + { + \knot_test_endpoint:vnT {knot previous \tl_use:N \l__knot_tmpg_tl} {initial point} + { + \spath_get:nnN {knot \tl_use:N \l__knot_prefix_tl -1} {path} \l_tmpa_tl + \spath_prepend_no_move:nn {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot previous \tl_use:c {knot previous \tl_use:N \l__knot_tmpg_tl}}} + \spath_get:nnN {knot \tl_use:N \l__knot_prefix_tl -1} {path} \l_tmpa_tl + } } } - } - \bool_if:nT - { - \l__knot_append_next_bool - && - \tl_if_exist_p:c {knot next \tl_use:N \l__knot_tmpg_tl} - && - !\tl_if_empty_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} - } - { - \spath_append_no_move:nn {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot next \tl_use:N \l__knot_tmpg_tl}} \bool_if:nT { - \l__knot_splits_bool + \l__knot_append_next_bool && - \tl_if_exist_p:c {knot previous \tl_use:N - \l__knot_tmpg_tl} + \tl_if_exist_p:c {knot next \tl_use:N \l__knot_tmpg_tl} && !\tl_if_empty_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} } { - \knot_test_endpoint:vnT {knot previous \tl_use:N \l__knot_tmpg_tl} {final point} + \spath_append_no_move:nn {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot next \tl_use:N \l__knot_tmpg_tl}} + \bool_if:nT + { + \l__knot_splits_bool + && + \tl_if_exist_p:c {knot previous \tl_use:N + \l__knot_tmpg_tl} + && + !\tl_if_empty_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} + } { - \spath_append_no_move:nn {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot next \tl_use:c {knot next \tl_use:N \l__knot_tmpg_tl}}} + \knot_test_endpoint:vnT {knot previous \tl_use:N \l__knot_tmpg_tl} {final point} + { + \spath_append_no_move:nn {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot next \tl_use:c {knot next \tl_use:N \l__knot_tmpg_tl}}} + } } } - } - \tl_set:Nn \l__knot_tmpg_tl {\tl_use:N \l__knot_prefix_tl -1} + \tl_set:Nn \l__knot_tmpg_tl {\tl_use:N \l__knot_prefix_tl -1} + } } + \pgfscope + \group_begin: + \tikzset{knot~ diagram/every~ intersection/.try, every~ intersection/.try, knot~ diagram/intersection~ \int_use:N \l__knot_intersections_int/.try} + \knot_draw_crossing:nVV {\tl_use:N \l__knot_tmpg_tl} \l__knot_tmpa_dim \l__knot_tmpb_dim + \group_end: + \endpgfscope } - \pgfscope - \group_begin: - \tikzset{knot~ diagram/every~ intersection/.try, every~ intersection/.try, knot~ diagram/intersection~ \int_use:N \l__knot_intersections_int/.try} - \knot_draw_crossing:nVV {\tl_use:N \l__knot_tmpg_tl} \l__knot_tmpa_dim \l__knot_tmpb_dim - \group_end: - \endpgfscope - \tl_use:N \l__knot_node_tl (\l__knot_name_tl \c_space_tl \int_use:N \l__knot_intersections_int) at (\l__knot_tmpa_dim, \l__knot_tmpb_dim) {}; + \seq_gpush:Nx \l__knot_nodes_seq { \l__knot_node_tl (\l__knot_name_tl \c_space_tl \int_use:N \l__knot_intersections_int) at (\dim_use:N \l__knot_tmpa_dim, \dim_use:N \l__knot_tmpb_dim) {};} + } } @@ -539,9 +634,9 @@ { \dim_compare:nTF { - \dim_abs:n {\pgf@x - \tl_item:Nn #1 {1}} + \dim_abs:n { \l__knot_tmpa_dim - \tl_item:Nn #1 {1}} + - \dim_abs:n {\pgf@y - \tl_item:Nn #1 {2}} + \dim_abs:n { \l__knot_tmpb_dim - \tl_item:Nn #1 {2}} < \l__knot_tolerance_dim } @@ -571,7 +666,7 @@ { \group_begin: \pgfscope - \clip (#2, #3) circle[radius=\l__knot_clip_radius_dim]; + \path[knot~ diagram/background~ clip] (#2, #3) circle[radius=\l__knot_clip_bg_radius_dim]; \tl_set:Nn \l_tmpa_tl {knot~ diagram/every~ strand/.try,} \tl_if_exist:cT {l__knot_options_ #1} @@ -584,7 +679,7 @@ \endpgfscope \pgfscope - \clip (#2, #3) circle[radius=1.1\l__knot_clip_radius_dim]; + \path[knot~ diagram/clip] (#2, #3) circle[radius=\l__knot_clip_draw_radius_dim]; \tl_set:Nn \l_tmpa_tl {knot~ diagram/every~ strand/.try,} \tl_if_exist:cT {l__knot_options_ #1} @@ -599,6 +694,12 @@ } \cs_generate_variant:Nn \knot_draw_crossing:nnn {nVV} + +\cs_new_nopar:Npn \knot_draw_crossing:nn #1#2 +{ + \tikz@scan@one@point\pgfutil@firstofone #2 \relax + \knot_draw_crossing:nVV {#1} \pgf@x \pgf@y +} \cs_new_protected_nopar:Npn \knot_split_strands: { \int_gzero:N \l__knot_filaments_int @@ -654,14 +755,16 @@ \tl_set:cx {knot previous filament \int_use:N \l__knot_filaments_int} {filament \int_eval:n {\l__knot_filaments_int - 1}} } } - \g__spath_close_tl + \g__spath_closepath_tl { + \tl_show:N #2 \int_gincr:N \l__knot_filaments_int \spath_clear_new:n {knot filament \int_use:N \l__knot_filaments_int} - \tl_set_eq:NN \l_tmpa_tl #2 - \tl_set:Nx \l_tmpa_tl {\tl_item:Nn #2 {1}\tl_item:Nn #2 {2}\tl_item:Nn #2 {3}} + \tl_clear:N \l_tmpa_tl + \tl_put_right:Nx {\tl_item:Nn #2 {1}\tl_item:Nn #2 {2}\tl_item:Nn #2 {3}} \tl_put_right:NV \l_tmpa_tl \g__spath_lineto_tl - \tl_set:Nx \l_tmpa_tl {\tl_item:Nn #2 {5}\tl_item:Nn #2 {6}} + \tl_put_right:Nx {\tl_item:Nn #2 {5}\tl_item:Nn #2 {6}} + \tl_show:N \l_tmpa_tl \spath_put:nnV {knot filament \int_use:N \l__knot_filaments_int} {path} \l_tmpa_tl \tl_set_eq:cN {l__knot_options_filament \int_use:N \l__knot_filaments_int} \l__knot_tmpa_tl \tl_clear_new:c {knot previous filament \int_use:N \l__knot_filaments_int} @@ -677,10 +780,9 @@ } \NewDocumentCommand \redraw { m m } { - \tikz@scan@one@point\pgfutil@firstofone #2 \relax - \tl_put_right:Nn \l__knot_redraws_tl {\knot_draw_crossing:nnn} + \tl_put_right:Nn \l__knot_redraws_tl {\knot_draw_crossing:nn} \tl_put_right:Nx \l__knot_redraws_tl { - {strand #1} {\dim_use:N \pgf@x} {\dim_use:N \pgf@y} + {strand #1} {#2}% {\dim_use:N \pgf@x} {\dim_use:N \pgf@y} } } \ExplSyntaxOff @@ -888,7 +990,7 @@ } } %% -%% 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 @@ -902,15 +1004,15 @@ %% %% This work consists of the files spath3.dtx %% calligraphy_doc.tex -%% knot_doc.tex +%% knots_doc.tex %% and the derived files spath3.ins, -%% spath3.pdf, +%% spath3_code.pdf, %% spath3.sty, %% tikzlibrarycalligraphy.code.tex %% tikzlibraryknots.code.tex -%% calligraphy_doc.pdf -%% knots_doc.pdf -%% README.txt +%% calligraphy.pdf +%% knots.pdf +%% README %% %% %% End of file `tikzlibraryknots.code.tex'. diff --git a/Master/tlpkg/libexec/ctan2tds b/Master/tlpkg/libexec/ctan2tds index 29a27c5b4a2..414be69330d 100755 --- a/Master/tlpkg/libexec/ctan2tds +++ b/Master/tlpkg/libexec/ctan2tds @@ -772,6 +772,7 @@ chomp ($Build = `cd $Master/../Build/source && pwd`); 'metauml', "&MAKEmetauml", 'metropolis', "die 'skipping, use beamertheme-metropolis'", 'mff', "die 'skipping, noinfo license'", + 'mflogo', "die 'skipping, must find logosl8.mf on CTAN'", # 11feb19 'mflogo-font', "&MAKEflatten", 'mfpic', "&MAKEcopy", 'mftoeps', "die 'skipping, bat-only (mirror.ctan.org/graphics/MF-PS)'", -- cgit v1.2.3