diff options
author | Karl Berry <karl@freefriends.org> | 2021-02-06 22:29:38 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2021-02-06 22:29:38 +0000 |
commit | a6cd75438fbcaade92377c09f1656838f98d34bd (patch) | |
tree | f7cad776e85704cc9b2df0d48f7a0e17f7d74a66 /Master/texmf-dist/source/latex/spath3 | |
parent | 1a26369eaf03943c7c533a207e4dea7922cd3336 (diff) |
spath3 (6feb21)
git-svn-id: svn://tug.org/texlive/trunk@57639 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/spath3')
-rw-r--r-- | Master/texmf-dist/source/latex/spath3/spath3_code.dtx | 4137 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/spath3/spath3_code.ins | 8 |
2 files changed, 3173 insertions, 972 deletions
diff --git a/Master/texmf-dist/source/latex/spath3/spath3_code.dtx b/Master/texmf-dist/source/latex/spath3/spath3_code.dtx index c5c584c4f81..621ab942f7b 100644 --- a/Master/texmf-dist/source/latex/spath3/spath3_code.dtx +++ b/Master/texmf-dist/source/latex/spath3/spath3_code.dtx @@ -35,7 +35,7 @@ See http://www.latex-project.org/lppl.txt \endpreamble \postamble -Copyright (C) 2011-2019 by Andrew Stacey <loopspace@mathforge.org> +Copyright (C) 2011-2021 by Andrew Stacey <loopspace@mathforge.org> This work may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either @@ -47,7 +47,7 @@ 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 +This work consists of the files spath3_code.dtx calligraphy_doc.tex knots_doc.tex spath3.tex @@ -143,7 +143,7 @@ and the derived files spath3.ins, %</driver> % \fi % -% \CheckSum{6848} +% \CheckSum{8404} % % \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 @@ -167,9 +167,15 @@ and the derived files spath3.ins, % \changes{1.2}{2019/02/12}{More fixes due to changes in LaTeX3} % \changes{1.4}{2020/12/18}{A fair amount of code reimplementation and reorganisation, together with defining TikZ keys to make functions available for use.} % \changes{2.0}{2021/01/19}{Refactored the code to remove the OO approach and make it functional, introduced the spath3 TikZ library to provide a user interface.} +% \changes{2.2}{2021/02/05}{Bugfixes and improvements, mainly with regard to the intersection and splitting routines.} % % \DoNotIndex{\newcommand,\newenvironment} % +% \pdfstringdefDisableCommands{% +% \def\\{}% +% \def\url#1{<#1>}% +% } +% % \providecommand*{\url}{\texttt} % \GetFileInfo{spath3.sty} % \title{The \textsf{spath3} package: code} @@ -250,12 +256,13 @@ and the derived files spath3.ins, \NeedsTeXFormat{LaTeX2e} \RequirePackage{expl3} \RequirePackage{pgf} -\ProvidesExplPackage {spath3} {2021/01/19} {2.0} {Functions for +\ProvidesExplPackage {spath3} {2021/02/05} {2.2} {Functions for manipulating PGF soft paths} \RequirePackage{xparse} % \end{macrocode} % % Utilities copied from \url{https://github.com/loopspace/LaTeX3-Utilities} for adding something in braces to a token list. +% I find I use this quite a lot in my packages. % \begin{macrocode} \cs_new_protected:Nn \@@_tl_put_right_braced:Nn { @@ -281,33 +288,77 @@ manipulating PGF soft paths} \cs_generate_variant:Nn \@@_tl_gput_left_braced:Nn { NV, cV, cv, Nx, cx } % \end{macrocode} % -% We need a slew of temporary variables. +% +% I had to think a bit about how to get \TeX\ to work the way I wanted. +% I'm really defining \emph{functions} but \TeX\ doesn't really have that concept, even with all the amazing \LaTeX3 stuff. +% The main issue I had was with scoping and return values. +% By default, \TeX\ functions aren't scoped -- they work on the same level as the calling functions. +% To protect the internals from being overwritten, each core function works inside a group. +% But then I have to work to get the answer out of it. +% So each of my core functions finishes by storing its return value in an appropriate \Verb+output+ variable. +% The core functions are then wrapped in a more user friendly interface that will take that output and assign it to a variable. +% This also means that I can deal with local and global versions without duplicating code. +% +% \begin{macrocode} +\tl_new:N \g_@@_output_tl +\int_new:N \g_@@_output_int +\seq_new:N \g_@@_output_seq +\bool_new:N \g_@@_output_bool +% \end{macrocode} +% +% To avoid creating vast numbers of variables, we provide ourselves with a few that we reuse frequently. +% For that reason, most of them don't have very exciting names. +% +% These are general purpose variables. % \begin{macrocode} \tl_new:N \l_@@_tmpa_tl \tl_new:N \l_@@_tmpb_tl \tl_new:N \l_@@_tmpc_tl \tl_new:N \l_@@_tmpd_tl \tl_new:N \l_@@_tmpe_tl +\tl_new:N \l_@@_tmpf_tl +\tl_new:N \l_@@_tmpg_tl +\tl_new:N \l_@@_tmph_tl +\tl_new:N \l_@@_tmpi_tl \seq_new:N \l_@@_tmpa_seq \seq_new:N \l_@@_tmpb_seq - -\tl_new:N \g_@@_output_tl -\int_new:N \g_@@_output_int -\seq_new:N \g_@@_output_seq +\seq_new:N \l_@@_tmpc_seq \dim_new:N \l_@@_tmpa_dim \dim_new:N \l_@@_tmpb_dim -\dim_new:N \l_@@_move_x_dim -\dim_new:N \l_@@_move_y_dim + \fp_new:N \l_@@_tmpa_fp \fp_new:N \l_@@_tmpb_fp +\fp_new:N \l_@@_tmpc_fp + \int_new:N \l_@@_tmpa_int +\int_new:N \l_@@_tmpb_int -\bool_new:N \g_@@_output_bool +\bool_new:N \l_@@_tmpa_bool +% \end{macrocode} +% +% Whenever I need more than two \Verb+dim+ variables it is because I need to remember the position of a move. +% +% \begin{macrocode} +\dim_new:N \l_@@_move_x_dim +\dim_new:N \l_@@_move_y_dim +% \end{macrocode} +% +% Closed paths often need special handling. +% When it's needed, this will say whether the path is closed or not. +% +% \begin{macrocode} \bool_new:N \l_@@_closed_bool % \end{macrocode} % +% The intersection routine can't happen inside a group so we need two token lists to hold the paths that we'll intersect. +% +% \begin{macrocode} +\tl_new:N \l_@@_intersecta_tl +\tl_new:N \l_@@_intersectb_tl +% \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. % These are global constants so that they can be used in other packages. % \begin{macrocode} @@ -319,28 +370,16 @@ manipulating PGF soft paths} \tl_const:Nn \c_spath_closepath_tl {\pgfsyssoftpath@closepathtoken} % \end{macrocode} % -% % We will want to be able to use anonymous spaths internally, so we create a global counter that we can use to refer to them. % \begin{macrocode} \int_new:N \g_@@_anon_int \int_gzero:N \g_@@_anon_int % \end{macrocode} % -% Groups and iterations don't mix well and I haven't got a good scheme for protecting local calculations when iterating, so we do our best with iteration-specific variables. -% \begin{macrocode} -\tl_new:N \l_@@_itera_tl -\tl_new:N \l_@@_iterb_tl -\tl_new:N \l_@@_iterc_tl -\tl_new:N \l_@@_iterd_tl -\tl_new:N \l_@@_iterp_tl -\dim_new:N \l_@@_itera_dim -\dim_new:N \l_@@_iterb_dim -\seq_new:N \l_@@_iter_seq -% \end{macrocode} -% % And some error messages % \begin{macrocode} -\msg_new:nnn { spath3 } { unknown path construction } { The~ path~ construction~ element~ #1~ is~ not~ currently~ supported.} +\msg_new:nnn { spath3 } { unknown path construction } +{ The~ path~ construction~ element~ #1~ is~ not~ currently~ supported.} % \end{macrocode} % % @@ -351,7 +390,7 @@ manipulating PGF soft paths} % The macro to store it in is the first argument. % These functions occur in two versions, the one with the \texttt{g} makes the assignment global. % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_segments_to_seq:Nn, % \spath_segments_gto_seq:Nn %} @@ -360,131 +399,131 @@ manipulating PGF soft paths} \cs_new_protected_nopar:Npn \@@_segments_to_seq:n #1 { \group_begin: - \tl_set:Nn \l_@@_itera_tl {#1} - \tl_clear:N \l_@@_iterb_tl - \seq_clear:N \l_@@_iter_seq - \dim_zero:N \l_@@_itera_dim - \dim_zero:N \l_@@_iterb_dim + \tl_set:Nn \l_@@_tmpa_tl {#1} + \tl_clear:N \l_@@_tmpb_tl + \seq_clear:N \l_@@_tmpa_seq + \dim_zero:N \l_@@_tmpa_dim + \dim_zero:N \l_@@_tmpb_dim \bool_until_do:nn { - \tl_if_empty_p:N \l_@@_itera_tl + \tl_if_empty_p:N \l_@@_tmpa_tl } { - \tl_set:Nx \l_@@_iterc_tl {\tl_head:N \l_@@_itera_tl} - \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl} - \tl_case:NnF \l_@@_iterc_tl + \tl_set:Nx \l_@@_tmpc_tl {\tl_head:N \l_@@_tmpa_tl} + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} + \tl_case:NnF \l_@@_tmpc_tl { \c_spath_moveto_tl { - \tl_set_eq:NN \l_@@_iterb_tl \c_spath_moveto_tl - \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}} - \dim_set:Nn \l_@@_itera_dim {\tl_head:N \l_@@_itera_tl} - \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl} + \tl_set_eq:NN \l_@@_tmpb_tl \c_spath_moveto_tl + \tl_put_right:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}} + \dim_set:Nn \l_@@_tmpa_dim {\tl_head:N \l_@@_tmpa_tl} + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} - \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}} - \dim_set:Nn \l_@@_iterb_dim {\tl_head:N \l_@@_itera_tl} - \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl} + \tl_put_right:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}} + \dim_set:Nn \l_@@_tmpb_dim {\tl_head:N \l_@@_tmpa_tl} + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} - \tl_set:Nx \l_@@_iterd_tl {\tl_head:N \l_@@_itera_tl} - \tl_if_eq:NNF \l_@@_iterd_tl \c_spath_moveto_tl + \tl_set:Nx \l_@@_tmpd_tl {\tl_head:N \l_@@_tmpa_tl} + \tl_if_eq:NNF \l_@@_tmpd_tl \c_spath_moveto_tl { - \tl_clear:N \l_@@_iterb_tl + \tl_clear:N \l_@@_tmpb_tl } } \c_spath_lineto_tl { - \tl_set_eq:NN \l_@@_iterb_tl \c_spath_moveto_tl - \tl_put_right:Nx \l_@@_iterb_tl + \tl_set_eq:NN \l_@@_tmpb_tl \c_spath_moveto_tl + \tl_put_right:Nx \l_@@_tmpb_tl { - {\dim_use:N \l_@@_itera_dim} - {\dim_use:N \l_@@_iterb_dim} + {\dim_use:N \l_@@_tmpa_dim} + {\dim_use:N \l_@@_tmpb_dim} } - \tl_put_right:NV \l_@@_iterb_tl \c_spath_lineto_tl + \tl_put_right:NV \l_@@_tmpb_tl \c_spath_lineto_tl - \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}} - \dim_set:Nn \l_@@_itera_dim {\tl_head:N \l_@@_itera_tl} - \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl} + \tl_put_right:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}} + \dim_set:Nn \l_@@_tmpa_dim {\tl_head:N \l_@@_tmpa_tl} + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} - \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}} - \dim_set:Nn \l_@@_iterb_dim {\tl_head:N \l_@@_itera_tl} - \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl} + \tl_put_right:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}} + \dim_set:Nn \l_@@_tmpb_dim {\tl_head:N \l_@@_tmpa_tl} + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} } \c_spath_curvetoa_tl { - \tl_set_eq:NN \l_@@_iterb_tl \c_spath_moveto_tl - \tl_put_right:Nx \l_@@_iterb_tl + \tl_set_eq:NN \l_@@_tmpb_tl \c_spath_moveto_tl + \tl_put_right:Nx \l_@@_tmpb_tl { - {\dim_use:N \l_@@_itera_dim} - {\dim_use:N \l_@@_iterb_dim} + {\dim_use:N \l_@@_tmpa_dim} + {\dim_use:N \l_@@_tmpb_dim} } - \tl_put_right:NV \l_@@_iterb_tl \c_spath_curvetoa_tl + \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curvetoa_tl \prg_replicate:nn {2} { - \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}} - \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl} - \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}} - \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl} - \tl_put_right:Nx \l_@@_iterb_tl {\tl_head:N \l_@@_itera_tl} - \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl} + \tl_put_right:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}} + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} + \tl_put_right:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}} + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} + \tl_put_right:Nx \l_@@_tmpb_tl {\tl_head:N \l_@@_tmpa_tl} + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} } - \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}} - \dim_set:Nn \l_@@_itera_dim {\tl_head:N \l_@@_itera_tl} - \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl} + \tl_put_right:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}} + \dim_set:Nn \l_@@_tmpa_dim {\tl_head:N \l_@@_tmpa_tl} + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} - \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}} - \dim_set:Nn \l_@@_iterb_dim {\tl_head:N \l_@@_itera_tl} - \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl} + \tl_put_right:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}} + \dim_set:Nn \l_@@_tmpb_dim {\tl_head:N \l_@@_tmpa_tl} + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} } \c_spath_closepath_tl { - \tl_set_eq:NN \l_@@_iterb_tl \c_spath_moveto_tl - \tl_put_right:Nx \l_@@_iterb_tl + \tl_set_eq:NN \l_@@_tmpb_tl \c_spath_moveto_tl + \tl_put_right:Nx \l_@@_tmpb_tl { - {\dim_use:N \l_@@_itera_dim} - {\dim_use:N \l_@@_iterb_dim} + {\dim_use:N \l_@@_tmpa_dim} + {\dim_use:N \l_@@_tmpb_dim} } - \tl_put_right:NV \l_@@_iterb_tl \c_spath_lineto_tl + \tl_put_right:NV \l_@@_tmpb_tl \c_spath_lineto_tl - \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}} - \dim_set:Nn \l_@@_itera_dim {\tl_head:N \l_@@_itera_tl} - \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl} + \tl_put_right:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}} + \dim_set:Nn \l_@@_tmpa_dim {\tl_head:N \l_@@_tmpa_tl} + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} - \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}} - \dim_set:Nn \l_@@_iterb_dim {\tl_head:N \l_@@_itera_tl} - \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl} + \tl_put_right:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}} + \dim_set:Nn \l_@@_tmpb_dim {\tl_head:N \l_@@_tmpa_tl} + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} } } { - \tl_set_eq:NN \l_@@_iterb_tl \l_@@_iterc_tl - \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}} - \dim_set:Nn \l_@@_itera_dim {\tl_head:N \l_@@_itera_tl} - \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl} + \tl_set_eq:NN \l_@@_tmpb_tl \l_@@_tmpc_tl + \tl_put_right:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}} + \dim_set:Nn \l_@@_tmpa_dim {\tl_head:N \l_@@_tmpa_tl} + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} - \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}} - \dim_set:Nn \l_@@_iterb_dim {\tl_head:N \l_@@_itera_tl} - \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl} + \tl_put_right:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}} + \dim_set:Nn \l_@@_tmpb_dim {\tl_head:N \l_@@_tmpa_tl} + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} } - \tl_if_empty:NF \l_@@_iterb_tl + \tl_if_empty:NF \l_@@_tmpb_tl { - \seq_put_right:NV \l_@@_iter_seq \l_@@_iterb_tl + \seq_put_right:NV \l_@@_tmpa_seq \l_@@_tmpb_tl } - \tl_clear:N \l_@@_iterb_tl + \tl_clear:N \l_@@_tmpb_tl } \seq_gclear:N \g_@@_output_seq - \seq_gset_eq:NN \g_@@_output_seq \l_@@_iter_seq + \seq_gset_eq:NN \g_@@_output_seq \l_@@_tmpa_seq \group_end: } \cs_new_protected_nopar:Npn \spath_segments_to_seq:Nn #1#2 @@ -506,7 +545,7 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_components_to_seq:Nn, % \spath_components_gto_seq:Nn, % \spath_components_to_clist:Nn, @@ -517,33 +556,33 @@ manipulating PGF soft paths} \cs_new_protected_nopar:Npn \@@_components_to_seq:n #1 { \group_begin: - \tl_set:Nn \l_@@_itera_tl {#1} - \seq_clear:N \l_@@_iter_seq - \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl} - \tl_put_right:NV \l_@@_itera_tl \c_spath_moveto_tl - \tl_set_eq:NN \l_@@_iterb_tl \c_spath_moveto_tl + \tl_set:Nn \l_@@_tmpa_tl {#1} + \seq_clear:N \l_@@_tmpa_seq + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} + \tl_put_right:NV \l_@@_tmpa_tl \c_spath_moveto_tl + \tl_set_eq:NN \l_@@_tmpb_tl \c_spath_moveto_tl \bool_do_until:nn { - \tl_if_empty_p:N \l_@@_itera_tl + \tl_if_empty_p:N \l_@@_tmpa_tl } { - \tl_set:Nx \l_@@_iterc_tl {\tl_head:N \l_@@_itera_tl} - \tl_if_eq:NNT \l_@@_iterc_tl \c_spath_moveto_tl + \tl_set:Nx \l_@@_tmpc_tl {\tl_head:N \l_@@_tmpa_tl} + \tl_if_eq:NNT \l_@@_tmpc_tl \c_spath_moveto_tl { - \seq_put_right:NV \l_@@_iter_seq \l_@@_iterb_tl - \tl_clear:N \l_@@_iterb_tl + \seq_put_right:NV \l_@@_tmpa_seq \l_@@_tmpb_tl + \tl_clear:N \l_@@_tmpb_tl } - \tl_if_single:NTF \l_@@_iterc_tl + \tl_if_single:NTF \l_@@_tmpc_tl { - \tl_put_right:NV \l_@@_iterb_tl \l_@@_iterc_tl + \tl_put_right:NV \l_@@_tmpb_tl \l_@@_tmpc_tl } { - \tl_put_right:Nx \l_@@_iterb_tl {{\l_@@_iterc_tl}} + \tl_put_right:Nx \l_@@_tmpb_tl {{\l_@@_tmpc_tl}} } - \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl} + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} } \seq_gclear:N \g_@@_output_seq - \seq_gset_eq:NN \g_@@_output_seq \l_@@_iter_seq + \seq_gset_eq:NN \g_@@_output_seq \l_@@_tmpa_seq \group_end: } \cs_new_protected_nopar:Npn \spath_components_to_seq:Nn #1#2 @@ -582,7 +621,7 @@ manipulating PGF soft paths} % \end{macro} % % -% \begin{macro}{\spath_length:n} +% \begin{macro}[internal]{\spath_length:n} % Counts the number of triples in the path. % \begin{macrocode} \cs_new_protected_nopar:Npn \spath_length:n #1 @@ -593,7 +632,7 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_reallength:Nn, % \spath_greallength:Nn % } @@ -604,8 +643,8 @@ manipulating PGF soft paths} \group_begin: \int_set:Nn \l_@@_tmpa_int {0} \tl_map_inline:nn {#1} { - \tl_set:Nn \l_@@_tmpc_tl {##1} - \tl_case:NnT \l_@@_tmpc_tl + \tl_set:Nn \l_@@_tmpa_tl {##1} + \tl_case:NnT \l_@@_tmpa_tl { \c_spath_lineto_tl {} \c_spath_curveto_tl {} @@ -636,7 +675,7 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_numberofcomponents:Nn, % \spath_gnumberofcomponents:Nn % } @@ -667,18 +706,18 @@ manipulating PGF soft paths} \int_set_eq:NN #1 \g_@@_output_int \int_gzero:N \g_@@_output_int } -\cs_generate_variant:Nn \spath_numberofcomponents:Nn {NV, cn, cV} +\cs_generate_variant:Nn \spath_numberofcomponents:Nn {NV, cn, cV, Nv} \cs_new_protected_nopar:Npn \spath_gnumberofcomponents:Nn #1#2 { \@@_numberofcomponents:n {#2} \int_gset_eq:NN #1 \g_@@_output_int \int_gzero:N \g_@@_output_int } -\cs_generate_variant:Nn \spath_gnumberofcomponents:Nn {NV, cn, cV} +\cs_generate_variant:Nn \spath_gnumberofcomponents:Nn {NV, cn, cV, Nv} % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_initialpoint:Nn, % \spath_ginitialpoint:Nn % } @@ -687,13 +726,13 @@ manipulating PGF soft paths} \cs_new_protected_nopar:Npn \@@_initialpoint:n #1 { \group_begin: - \tl_clear:N \l_@@_tmpb_tl - \tl_set:Nx \l_@@_tmpb_tl + \tl_clear:N \l_@@_tmpa_tl + \tl_set:Nx \l_@@_tmpa_tl { { \tl_item:nn {#1} {2} } { \tl_item:nn {#1} {3} } } - \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpb_tl + \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpa_tl \group_end: } \cs_new_protected_nopar:Npn \spath_initialpoint:Nn #1#2 @@ -713,7 +752,7 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_finalpoint:Nn, % \spath_gfinalpoint:Nn, % } @@ -750,7 +789,60 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[internal]{ +% \spath_finalmovepoint:Nn, +% \spath_gfinalmovepoint:Nn +% } +% Get the last move on the path. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_finalmovepoint:n #1 +{ + \group_begin: + \tl_set:Nn \l_@@_tmpc_tl { {0pt} {0pt} } + \tl_set:Nn \l_@@_tmpa_tl {#1} + \bool_do_until:nn + { + \tl_if_empty_p:N \l_@@_tmpa_tl + } + { + \tl_set:Nx \l_@@_tmpb_tl {\tl_head:N \l_@@_tmpa_tl} + \tl_case:Nn \l_@@_tmpb_tl + { + \c_spath_moveto_tl + { + \tl_set:Nx \l_@@_tmpc_tl + { + { \tl_item:Nn \l_@@_tmpa_tl {2} } + { \tl_item:Nn \l_@@_tmpa_tl {3} } + } + } + } + \prg_replicate:nn {3} + { + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} + } + } + \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpc_tl + \group_end: +} +\cs_new_protected_nopar:Npn \spath_finalmovepoint:Nn #1#2 +{ + \@@_finalmovepoint:n {#2} + \tl_set_eq:NN #1 \g_@@_output_tl + \tl_gclear:N \g_@@_output_tl +} +\cs_generate_variant:Nn \spath_finalmovepoint:Nn {NV, cn, cV} +\cs_new_protected_nopar:Npn \spath_gfinalmovepoint:Nn #1#2 +{ + \@@_finalmovepoint:n {#2} + \tl_gset_eq:NN #1 \g_@@_output_tl + \tl_gclear:N \g_@@_output_tl +} +\cs_generate_variant:Nn \spath_gfinalmovepoint:Nn {NV, cn, cV} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{ % \spath_reverse:Nn, % \spath_greverse:Nn % } @@ -836,7 +928,10 @@ manipulating PGF soft paths} \bool_set_true:N \l_@@_closed_bool } { - \msg_warning:nnx { spath3 } { unknown path construction } {\l_@@_tmpc_tl } + \msg_warning:nnx + { spath3 } + { unknown path construction } + {\l_@@_tmpc_tl } } \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} @@ -891,7 +986,7 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_initialaction:Nn, % \spath_ginitialaction:Nn, % } @@ -931,7 +1026,7 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_finalaction:Nn, % \spath_gfinalaction:Nn % } @@ -977,7 +1072,7 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_minbb:Nn, % \spath_gminbb:Nn % } @@ -997,9 +1092,11 @@ manipulating PGF soft paths} } { \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} - \dim_set:Nn \l_@@_tmpa_dim {\dim_min:nn {\tl_head:N \l_@@_tmpa_tl} {\l_@@_tmpa_dim}} + \dim_set:Nn \l_@@_tmpa_dim + {\dim_min:nn {\tl_head:N \l_@@_tmpa_tl} {\l_@@_tmpa_dim}} \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} - \dim_set:Nn \l_@@_tmpb_dim {\dim_min:nn {\tl_head:N \l_@@_tmpa_tl} {\l_@@_tmpb_dim}} + \dim_set:Nn \l_@@_tmpb_dim + {\dim_min:nn {\tl_head:N \l_@@_tmpa_tl} {\l_@@_tmpb_dim}} \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} } \tl_clear:N \l_@@_tmpb_tl @@ -1028,7 +1125,7 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_maxbb:Nn, % \spath_gmaxbb:Nn, % } @@ -1048,9 +1145,11 @@ manipulating PGF soft paths} } { \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} - \dim_set:Nn \l_@@_tmpa_dim {\dim_max:nn {\tl_head:N \l_@@_tmpa_tl} {\l_@@_tmpa_dim}} + \dim_set:Nn \l_@@_tmpa_dim + {\dim_max:nn {\tl_head:N \l_@@_tmpa_tl} {\l_@@_tmpa_dim}} \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} - \dim_set:Nn \l_@@_tmpb_dim {\dim_max:nn {\tl_head:N \l_@@_tmpa_tl} {\l_@@_tmpb_dim}} + \dim_set:Nn \l_@@_tmpb_dim + {\dim_max:nn {\tl_head:N \l_@@_tmpa_tl} {\l_@@_tmpb_dim}} \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} } \tl_clear:N \l_@@_tmpb_tl @@ -1079,7 +1178,7 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_save_to_aux:Nn, % \spath_save_to_aux:N % } @@ -1124,13 +1223,13 @@ manipulating PGF soft paths} % There is always a variant in which the path is specified by a macro and restored back in that same macro. % % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_translate:Nnnn, % \spath_translate:Nnn, % \spath_gtranslate:Nnnn, % \spath_gtranslate:Nnn % } -% Translates a path. +% Translates a path by an amount. % \begin{macrocode} \cs_new_protected_nopar:Npn \@@_translate:nnn #1#2#3 { @@ -1159,6 +1258,7 @@ manipulating PGF soft paths} \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpb_tl \group_end: } +\cs_generate_variant:Nn \@@_translate:nnn {nVV} \cs_new_protected_nopar:Npn \spath_translate:Nnnn #1#2#3#4 { \@@_translate:nnn {#2}{#3}{#4} @@ -1200,8 +1300,80 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % +% +% +% \begin{macro}[internal]{ +% \spath_translate_to:Nnnn, +% \spath_translate_to:Nnn, +% \spath_gtranslate_to:Nnnn, +% \spath_gtranslate_to:Nnn +% } +% Translates a path so that it starts at a point. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_translate_to:nnn #1#2#3 +{ + \group_begin: + \spath_initialpoint:Nn \l_@@_tmpa_tl {#1} + + \dim_set:Nn \l_@@_tmpa_dim + { + #2 + - + \tl_item:Nn \l_@@_tmpa_tl {1} + } + \dim_set:Nn \l_@@_tmpb_dim + { + #3 + - + \tl_item:Nn \l_@@_tmpa_tl {2} + } + + \@@_translate:nVV {#1} \l_@@_tmpa_dim \l_@@_tmpb_dim + \group_end: +} +\cs_new_protected_nopar:Npn \spath_translate_to:Nnnn #1#2#3#4 +{ + \@@_translate_to:nnn {#2}{#3}{#4} + \tl_set_eq:NN #1 \g_@@_output_tl + \tl_gclear:N \g_@@_output_tl +} +\cs_generate_variant:Nn \spath_translate_to:Nnnn {NVxx, NVVV, NVnn} +\cs_new_protected_nopar:Npn \spath_translate_to:Nnn #1#2#3 +{ + \spath_translate_to:NVnn #1#1{#2}{#3} +} +\cs_generate_variant:Nn \spath_translate_to:Nnn {NVV, cnn, cVV} +\cs_new_protected_nopar:Npn \spath_gtranslate_to:Nnnn #1#2#3#4 +{ + \@@_translate_to:nnn {#2}{#3}{#4} + \tl_gset_eq:NN #1 \g_@@_output_tl + \tl_gclear:N \g_@@_output_tl +} +\cs_generate_variant:Nn \spath_gtranslate_to:Nnnn {NVxx, NVVV, NVnn} +\cs_new_protected_nopar:Npn \spath_gtranslate_to:Nnn #1#2#3 +{ + \spath_gtranslate_to:NVnn #1#1{#2}{#3} +} +\cs_generate_variant:Nn \spath_gtranslate_to:Nnn {NVV, cnn, cVV} +% \end{macrocode} +% +% This variant allows for passing the coordinates as a single braced group as it strips off the outer braces of the second argument. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \spath_translate_to:Nn #1#2 +{ + \spath_translate_to:Nnn #1 #2 +} +\cs_generate_variant:Nn \spath_translate_to:Nn {NV} +\cs_new_protected_nopar:Npn \spath_gtranslate_to:Nn #1#2 +{ + \spath_gtranslate_to:Nnn #1 #2 +} +\cs_generate_variant:Nn \spath_gtranslate_to:Nn {NV} +% \end{macrocode} +% \end{macro} +% % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_scale:Nnnn, % \spath_scale:Nnn, % \spath_gscale:Nnnn, @@ -1279,7 +1451,7 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_transform:Nnnnnnnn, % \spath_transform:Nnnnnnn, % \spath_gtransform:Nnnnnnnn, @@ -1304,8 +1476,10 @@ manipulating PGF soft paths} \tl_set:Nx \l_@@_tmpd_tl {\tl_head:N \l_@@_tmpa_tl} \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} - \fp_set:Nn \l_@@_tmpa_fp {\l_@@_tmpc_tl * #2 + \l_@@_tmpd_tl * #4 + #6} - \fp_set:Nn \l_@@_tmpb_fp {\l_@@_tmpc_tl * #3 + \l_@@_tmpd_tl * #5 + #7} + \fp_set:Nn \l_@@_tmpa_fp + {\l_@@_tmpc_tl * #2 + \l_@@_tmpd_tl * #4 + #6} + \fp_set:Nn \l_@@_tmpb_fp + {\l_@@_tmpc_tl * #3 + \l_@@_tmpd_tl * #5 + #7} \tl_put_right:Nx \l_@@_tmpb_tl { {\fp_to_dim:N \l_@@_tmpa_fp} @@ -1322,7 +1496,8 @@ manipulating PGF soft paths} \tl_set_eq:NN #1 \g_@@_output_tl \tl_gclear:N \g_@@_output_tl } -\cs_generate_variant:Nn \spath_transform:Nnnnnnnn {NVnnnnnn, Nnxxxxxx, cnnnnnnn} +\cs_generate_variant:Nn \spath_transform:Nnnnnnnn +{NVnnnnnn, Nnxxxxxx, cnnnnnnn} \cs_new_protected_nopar:Npn \spath_transform:Nnnnnnn #1#2#3#4#5#6#7 { \spath_transform:NVnnnnnn #1#1{#2}{#3}{#4}{#5}{#6}{#7} @@ -1364,7 +1539,305 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[internal]{ +% \spath_span:Nnnn, +% \spath_span:Nnn, +% \spath_gspan:Nnnn, +% \spath_gspan:Nnn, +% \spath_normalise:Nn, +% \spath_normalise:N, +% \spath_gnormalise:Nn, +% \spath_gnormalise:N +% } +% The \Verb+span+ functions transform a path to start and end at specified points. +% The \Verb+normalise+ functions transform it to start at the origin and end at \((1\mathrm{pt},0\mathrm{pt})\). +% +% If the path starts and ends at the same point then it is translated to the specified point (or origin) but not otherwise changed. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_span:nnn #1#2#3 +{ + \group_begin: + \spath_initialpoint:Nn \l_@@_tmpa_tl {#1} + \spath_finalpoint:Nn \l_@@_tmpb_tl {#1} + + \fp_set:Nn \l_@@_tmpa_fp + { + (\tl_item:Nn \l_@@_tmpb_tl {1}) - + (\tl_item:Nn \l_@@_tmpa_tl {1}) + } + \fp_set:Nn \l_@@_tmpb_fp + { + (\tl_item:Nn \l_@@_tmpb_tl {2}) - + (\tl_item:Nn \l_@@_tmpa_tl {2}) + } + \fp_set:Nn \l_@@_tmpc_fp + { + (\l_@@_tmpa_fp) * (\l_@@_tmpa_fp) + + + (\l_@@_tmpb_fp * \l_@@_tmpb_fp) + } + + \fp_compare:nTF + { + \l_@@_tmpc_fp < 0.001 + } + { + \spath_translate_to:Nnnn \l_@@_tmpd_tl {#1} #2 + } + { + \fp_set:Nn \l_@@_tmpa_fp + { + ( + ((\tl_item:nn {#3} {1}) + - + (\tl_item:nn {#2} {1})) + * + ((\tl_item:Nn \l_@@_tmpb_tl {1}) + - + (\tl_item:Nn \l_@@_tmpa_tl {1})) + + + ((\tl_item:nn {#3} {2}) + - + (\tl_item:nn {#2} {2})) + * + ((\tl_item:Nn \l_@@_tmpb_tl {2}) + - + (\tl_item:Nn \l_@@_tmpa_tl {2})) + ) + / + \l_@@_tmpc_fp + } + \fp_set:Nn \l_@@_tmpb_fp + { + ( + ((\tl_item:nn {#3} {2}) + - + (\tl_item:nn {#2} {2})) + * + ((\tl_item:Nn \l_@@_tmpb_tl {1}) + - + (\tl_item:Nn \l_@@_tmpa_tl {1})) + - + ((\tl_item:nn {#3} {1}) + - + (\tl_item:nn {#2} {1})) + * + ((\tl_item:Nn \l_@@_tmpb_tl {2}) + - + (\tl_item:Nn \l_@@_tmpa_tl {2})) + ) + / + \l_@@_tmpc_fp + } + + \tl_set:Nx \l_@@_tmpc_tl + { + { + \fp_to_decimal:N \l_@@_tmpa_fp + } + { + \fp_to_decimal:N \l_@@_tmpb_fp + } + { + \fp_eval:n { - \l_@@_tmpb_fp } + } + { + \fp_to_decimal:N \l_@@_tmpa_fp + } + { + \fp_to_dim:n + { + \tl_item:nn {#2} {1} + - + \l_@@_tmpa_fp * (\tl_item:Nn \l_@@_tmpa_tl {1}) + + + \l_@@_tmpb_fp * (\tl_item:Nn \l_@@_tmpa_tl {2}) + } + } + { + \fp_to_dim:n + { + \tl_item:nn {#2} {2} + - + \l_@@_tmpb_fp * (\tl_item:Nn \l_@@_tmpa_tl {1}) + - + \l_@@_tmpa_fp * (\tl_item:Nn \l_@@_tmpa_tl {2}) + } + } + } + \spath_transform:NnV \l_@@_tmpd_tl {#1} \l_@@_tmpc_tl + } + \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpd_tl + \group_end: +} +\cs_new_protected_nopar:Npn \spath_span:Nnnn #1#2#3#4 +{ + \@@_span:nnn {#2}{#3}{#4} + \tl_set_eq:NN #1 \g_@@_output_tl + \tl_gclear:N \g_@@_output_tl +} +\cs_generate_variant:Nn \spath_span:Nnnn {NVnn, NVVV, NnVV} +\cs_new_protected_nopar:Npn \spath_span:Nnn #1#2#3 +{ + \spath_span:NVnn #1#1{#2}{#3} +} +\cs_generate_variant:Nn \spath_span:Nnn {NVV, cnn, cvv, cVV} +\cs_new_protected_nopar:Npn \spath_gspan:Nnnn #1#2#3#4 +{ + \@@_span:nnn {#2}{#3}{#4} + \tl_gset_eq:NN #1 \g_@@_output_tl + \tl_gclear:N \g_@@_output_tl +} +\cs_generate_variant:Nn \spath_gspan:Nnnn {NVnn, NVVV} +\cs_new_protected_nopar:Npn \spath_gspan:Nnn #1#2#3 +{ + \spath_gspan:NVnn #1#1{#2}{#3} +} +\cs_generate_variant:Nn \spath_gspan:Nnn {NVV, cnn, cvv, cVV} +\cs_new_protected_nopar:Npn \@@_normalise:n #1 +{ + \@@_span:nnn {#1}{{0pt}{0pt}}{{1pt}{0pt}} +} +\cs_new_protected_nopar:Npn \spath_normalise:Nn #1#2 +{ + \@@_normalise:n {#2} + \tl_set_eq:NN #1 \g_@@_output_tl + \tl_gclear:N \g_@@_output_tl +} +\cs_generate_variant:Nn \spath_normalise:Nn {cn,NV, cV, cv} +\cs_new_protected_nopar:Npn \spath_normalise:N #1 +{ + \spath_normalise:NV #1#1 +} +\cs_generate_variant:Nn \spath_normalise:N {c} +\cs_new_protected_nopar:Npn \spath_gnormalise:Nn #1#2 +{ + \@@_normalise:n {#2} + \tl_gset_eq:NN #1 \g_@@_output_tl + \tl_gclear:N \g_@@_output_tl +} +\cs_generate_variant:Nn \spath_gnormalise:Nn {cn,NV, cV, cv} +\cs_new_protected_nopar:Npn \spath_gnormalise:N #1 +{ + \spath_gnormalise:NV #1#1 +} +\cs_generate_variant:Nn \spath_gnormalise:N {c} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}[internal]{ +% \spath_splice_between:Nnnn, +% \spath_splice_between:Nnn, +% \spath_gsplice_between:Nnnn, +% \spath_gsplice_between:Nnn +% } +% This takes three paths and returns a single path in which the middle one is adjusted (and welded) so that it joins the first path to the third. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_splice_between:nnn #1#2#3 +{ + \group_begin: + \spath_finalpoint:NV \l_@@_tmpd_tl {#1} + \spath_initialpoint:NV \l_@@_tmpe_tl {#3} + \spath_span:NnVV \l_@@_tmpb_tl {#2} \l_@@_tmpd_tl \l_@@_tmpe_tl + \spath_append_no_move:NnV \l_@@_tmpa_tl {#1} \l_@@_tmpb_tl + \spath_append_no_move:Nn \l_@@_tmpa_tl {#3} + \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpa_tl + \group_end: +} +\cs_new_protected_nopar:Npn \spath_splice_between:Nnnn #1#2#3#4 +{ + \@@_splice_between:nnn {#2}{#3}{#4} + \tl_set_eq:NN #1 \g_@@_output_tl + \tl_gclear:N \g_@@_output_tl +} +\cs_generate_variant:Nn \spath_splice_between:Nnnn {NVnn, NVVV} +\cs_new_protected_nopar:Npn \spath_splice_between:Nnn #1#2#3 +{ + \spath_splice_between:NVnn #1#1{#2}{#3} +} +\cs_generate_variant:Nn \spath_splice_between:Nnn {NVV, cnn, cvv, Nvn} +\cs_new_protected_nopar:Npn \spath_gsplice_between:Nnnn #1#2#3#4 +{ + \@@_splice_between:nnn {#2}{#3}{#4} + \tl_gset_eq:NN #1 \g_@@_output_tl + \tl_gclear:N \g_@@_output_tl +} +\cs_generate_variant:Nn \spath_gsplice_between:Nnnn {NVnn, NVVV} +\cs_new_protected_nopar:Npn \spath_gsplice_between:Nnn #1#2#3 +{ + \spath_gsplice_between:NVnn #1#1{#2}{#3} +} +\cs_generate_variant:Nn \spath_gsplice_between:Nnn {NVV, cnn, cvv} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{ +% \spath_close_with:Nn, +% \spath_gclose_with:Nn +% } +% Closes the first path by splicing in the second. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_close_with:nn #1#2 +{ + \group_begin: + \spath_finalmovepoint:Nn \l_@@_tmpa_tl {#1} + \spath_finalpoint:Nn \l_@@_tmpb_tl {#1} + \dim_compare:nTF + { + \dim_abs:n + { + \tl_item:Nn \l_@@_tmpa_tl {1} + - + \tl_item:Nn \l_@@_tmpb_tl {1} + } + + + \dim_abs:n + { + \tl_item:Nn \l_@@_tmpa_tl {2} + - + \tl_item:Nn \l_@@_tmpb_tl {2} + } + < 0.01pt + } + { + \@@_close:n {#1} + } + { + \spath_span:NnVV \l_@@_tmpc_tl {#2} \l_@@_tmpb_tl \l_@@_tmpa_tl + \spath_append_no_move:NnV \l_@@_tmpd_tl {#1} \l_@@_tmpc_tl + \@@_close:V \l_@@_tmpd_tl + } + \group_end: +} +\cs_new_protected_nopar:Npn \spath_close_with:Nnn #1#2#3 +{ + \@@_close_with:nn {#2}{#3} + \tl_set_eq:NN #1 \g_@@_output_tl + \tl_gclear:N \g_@@_output_tl +} +\cs_generate_variant:Nn \spath_close_with:Nnn {cnn, cVV, cvv, NVn} +\cs_new_protected_nopar:Npn \spath_close_with:Nn #1#2 +{ + \spath_close_with:NVn #1#1{#2} +} +\cs_generate_variant:Nn \spath_close_with:Nn {cn, cV, cv, NV} +\cs_new_protected_nopar:Npn \spath_gclose_with:Nnn #1#2#3 +{ + \@@_close_with:nn {#2}{#3} + \tl_gset_eq:NN #1 \g_@@_output_tl + \tl_gclear:N \g_@@_output_tl +} +\cs_generate_variant:Nn \spath_gclose_with:Nnn {cnn, cVV, cvv, NVn} +\cs_new_protected_nopar:Npn \spath_gclose_with:Nn #1#2 +{ + \spath_gclose_with:NVn #1#1{#2} +} +\cs_generate_variant:Nn \spath_gclose_with:Nn {cn, cV, cv, NV} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{ % \spath_weld:Nnn, % \spath_weld:Nn, % \spath_gweld:Nnn, @@ -1378,32 +1851,10 @@ manipulating PGF soft paths} \group_begin: \tl_set:Nn \l_@@_tmpa_tl {#1} \tl_set:Nn \l_@@_tmpb_tl {#2} + \spath_finalpoint:Nn \l_@@_tmpc_tl {#1} + \spath_translate_to:NV \l_@@_tmpb_tl \l_@@_tmpc_tl - \spath_finalpoint:NV \l_@@_tmpc_tl \l_@@_tmpa_tl - \spath_initialpoint:NV \l_@@_tmpd_tl \l_@@_tmpb_tl - - \dim_set:Nn \l_@@_tmpa_dim - { - \tl_item:Nn \l_@@_tmpc_tl {1} - - - \tl_item:Nn \l_@@_tmpd_tl {1} - } - \dim_set:Nn \l_@@_tmpb_dim - { - \tl_item:Nn \l_@@_tmpc_tl {2} - - - \tl_item:Nn \l_@@_tmpd_tl {2} - } - - \spath_translate:NVV \l_@@_tmpb_tl \l_@@_tmpa_dim \l_@@_tmpb_dim - - \prg_replicate:nn {3} - { - \tl_set:Nx \l_@@_tmpb_tl {\tl_tail:N \l_@@_tmpb_tl} - } - - \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpb_tl - \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpa_tl + \@@_append_no_move:VV \l_@@_tmpa_tl \l_@@_tmpb_tl \group_end: } \cs_new_protected_nopar:Npn \spath_weld:Nnn #1#2#3 @@ -1434,7 +1885,7 @@ manipulating PGF soft paths} % \end{macro} % % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_append_no_move:Nnn, % \spath_append_no_move:Nn, % \spath_gappend_no_move:Nnn, @@ -1456,18 +1907,19 @@ manipulating PGF soft paths} \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpa_tl \group_end: } +\cs_generate_variant:Nn \@@_append_no_move:nn {VV} \cs_new_protected_nopar:Npn \spath_append_no_move:Nnn #1#2#3 { \@@_append_no_move:nn {#2}{#3} \tl_set_eq:NN #1 \g_@@_output_tl \tl_gclear:N \g_@@_output_tl } -\cs_generate_variant:Nn \spath_append_no_move:Nnn {NVV, NVn} +\cs_generate_variant:Nn \spath_append_no_move:Nnn {NVV, NVn, NnV} \cs_new_protected_nopar:Npn \spath_append_no_move:Nn #1#2 { \spath_append_no_move:NVn #1#1{#2} } -\cs_generate_variant:Nn \spath_append_no_move:Nn {NV, cv} +\cs_generate_variant:Nn \spath_append_no_move:Nn {NV, cv, Nv} \cs_new_protected_nopar:Npn \spath_gappend_no_move:Nnn #1#2#3 { \@@_append_no_move:nn {#2}{#3} @@ -1479,11 +1931,11 @@ manipulating PGF soft paths} { \spath_gappend_no_move:NVn #1#1{#2} } -\cs_generate_variant:Nn \spath_gappend_no_move:Nn {NV, cv} +\cs_generate_variant:Nn \spath_gappend_no_move:Nn {NV, cv, Nv} % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_append:Nnn, % \spath_append:Nn, % \spath_gappend:Nnn, @@ -1501,7 +1953,7 @@ manipulating PGF soft paths} { \spath_append:NVn #1#1{#2} } -\cs_generate_variant:Nn \spath_append:Nn {NV, Nv} +\cs_generate_variant:Nn \spath_append:Nn {NV, Nv, cv} \cs_new_protected_nopar:Npn \spath_gappend:Nnn #1#2#3 { \tl_gset:Nn #1 {#2} @@ -1512,12 +1964,12 @@ manipulating PGF soft paths} { \spath_gappend:NVn #1#1{#2} } -\cs_generate_variant:Nn \spath_gappend:Nn {NV, Nv} +\cs_generate_variant:Nn \spath_gappend:Nn {NV, Nv, cv} % \end{macrocode} % \end{macro} % % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_prepend_no_move:Nnn, % \spath_prepend_no_move:Nn, % \spath_gprepend_no_move:Nnn, @@ -1549,7 +2001,7 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_prepend:Nnn, % \spath_prepend:Nn, % \spath_gprepend:Nnn, @@ -1580,7 +2032,7 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_bake_round:Nn, % \spath_bake_round:N, % \spath_gbake_round:Nn, @@ -1625,26 +2077,25 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_close:Nn, % \spath_close:N, % \spath_gclose:Nn, % \spath_gclose:N % } % Appends a close path to the end of the path. -% For now, the point is the initial or final point (respectively). -% To be future proof, it ought to be the point of the adjacent move to. % \begin{macrocode} \cs_new_protected_nopar:Npn \@@_close:n #1 { \group_begin: \tl_set:Nn \l_@@_tmpa_tl {#1} - \spath_initialpoint:NV \l_@@_tmpb_tl \l_@@_tmpa_tl + \spath_finalmovepoint:NV \l_@@_tmpb_tl \l_@@_tmpa_tl \tl_put_right:NV \l_@@_tmpa_tl \c_spath_closepath_tl \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpb_tl \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpa_tl \group_end: } +\cs_generate_variant:Nn \@@_close:n {V} \cs_new_protected_nopar:Npn \spath_close:Nn #1#2 { \@@_close:n {#2} @@ -1673,7 +2124,7 @@ manipulating PGF soft paths} % \end{macro} % % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_open:Nn, % \spath_open:N, % \spath_gopen:Nn, @@ -1783,7 +2234,7 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_remove_empty_components:Nn, % \spath_remove_empty_components:N, % \spath_gremove_empty_components:Nn, @@ -1836,7 +2287,7 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{\spath_if_eq:nn} +% \begin{macro}[internal]{\spath_if_eq:nn} % Test if two soft paths are equal, we allow a little tolerance on the calculations. % \begin{macrocode} \prg_new_protected_conditional:Npnn \spath_if_eq:nn #1#2 { T, F, TF } @@ -1845,7 +2296,10 @@ manipulating PGF soft paths} \tl_set:Nn \l_@@_tmpa_tl {#1} \tl_set:Nn \l_@@_tmpb_tl {#2} \bool_gset_true:N \g_@@_tmpa_bool - \int_compare:nNnTF {\tl_count:N \l_@@_tmpa_tl} = {\tl_count:N \l_@@_tmpb_tl} + \int_compare:nNnTF + {\tl_count:N \l_@@_tmpa_tl} + = + {\tl_count:N \l_@@_tmpb_tl} { \int_step_inline:nnnn {1} {3} {\tl_count:N \l_@@_tmpa_tl} { @@ -1857,13 +2311,27 @@ manipulating PGF soft paths} } \dim_set:Nn \l_@@_tmpa_dim {\tl_item:Nn \l_@@_tmpa_tl {##1+1}} \dim_set:Nn \l_@@_tmpb_dim {\tl_item:Nn \l_@@_tmpb_tl {##1+1}} - \dim_compare:nF { \dim_abs:n { \l_@@_tmpa_dim - \l_@@_tmpb_dim} < 0.001pt } + \dim_compare:nF + { + \dim_abs:n + { + \l_@@_tmpa_dim - \l_@@_tmpb_dim + } + < 0.001pt + } { \bool_gset_false:N \g_@@_tmpa_bool } \dim_set:Nn \l_@@_tmpa_dim {\tl_item:Nn \l_@@_tmpa_tl {##1+2}} \dim_set:Nn \l_@@_tmpb_dim {\tl_item:Nn \l_@@_tmpb_tl {##1+2}} - \dim_compare:nF { \dim_abs:n { \l_@@_tmpa_dim - \l_@@_tmpb_dim} < 0.001pt } + \dim_compare:nF + { + \dim_abs:n + { + \l_@@_tmpa_dim - \l_@@_tmpb_dim + } + < 0.001pt + } { \bool_gset_false:N \g_@@_tmpa_bool } @@ -1887,7 +2355,7 @@ manipulating PGF soft paths} % % \subsection{Splitting Commands} % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_split_curve:NNnn, % \spath_gsplit_curve:NNnn % } @@ -1919,11 +2387,15 @@ manipulating PGF soft paths} { {\fp_to_dim:n { - (1 - #2)^2 * \tl_item:nn {#1} {2} + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {5} + (#2)^2 * \tl_item:nn {#1} {8} + (1 - #2)^2 * \tl_item:nn {#1} {2} + + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {5} + + (#2)^2 * \tl_item:nn {#1} {8} }} {\fp_to_dim:n { - (1 - #2)^2 * \tl_item:nn {#1} {3} + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {6} + (#2)^2 * \tl_item:nn {#1} {9} + (1 - #2)^2 * \tl_item:nn {#1} {3} + + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {6} + + (#2)^2 * \tl_item:nn {#1} {9} }} } @@ -1932,11 +2404,17 @@ manipulating PGF soft paths} { {\fp_to_dim:n { - (1 - #2)^3 * \tl_item:nn {#1} {2} + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {5} + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {8} + (#2)^3 * \tl_item:nn {#1} {11} + (1 - #2)^3 * \tl_item:nn {#1} {2} + + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {5} + + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {8} + + (#2)^3 * \tl_item:nn {#1} {11} }} {\fp_to_dim:n { - (1 - #2)^3 * \tl_item:nn {#1} {3} + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {6} + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {9} + (#2)^3 * \tl_item:nn {#1} {12} + (1 - #2)^3 * \tl_item:nn {#1} {3} + + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {6} + + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {9} + + (#2)^3 * \tl_item:nn {#1} {12} }} } @@ -1949,11 +2427,17 @@ manipulating PGF soft paths} { {\fp_to_dim:n { - (1 - #2)^3 * \tl_item:nn {#1} {2} + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {5} + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {8} + (#2)^3 * \tl_item:nn {#1} {11} + (1 - #2)^3 * \tl_item:nn {#1} {2} + + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {5} + + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {8} + + (#2)^3 * \tl_item:nn {#1} {11} }} {\fp_to_dim:n { - (1 - #2)^3 * \tl_item:nn {#1} {3} + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {6} + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {9} + (#2)^3 * \tl_item:nn {#1} {12} + (1 - #2)^3 * \tl_item:nn {#1} {3} + + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {6} + + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {9} + + (#2)^3 * \tl_item:nn {#1} {12} }} } @@ -1962,11 +2446,15 @@ manipulating PGF soft paths} { {\fp_to_dim:n { - (1 - #2)^2 * \tl_item:nn {#1} {5} + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {8} + (#2)^2 * \tl_item:nn {#1} {11} + (1 - #2)^2 * \tl_item:nn {#1} {5} + + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {8} + + (#2)^2 * \tl_item:nn {#1} {11} }} {\fp_to_dim:n { - (1 - #2)^2 * \tl_item:nn {#1} {6} + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {9} + (#2)^2 * \tl_item:nn {#1} {12} + (1 - #2)^2 * \tl_item:nn {#1} {6} + + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {9} + + (#2)^2 * \tl_item:nn {#1} {12} }} } \tl_put_right:NV \l_@@_tmpa_tl \c_spath_curvetob_tl @@ -1990,6 +2478,7 @@ manipulating PGF soft paths} \@@_tl_gput_right_braced:NV \g_@@_output_tl \l_@@_tmpa_tl \group_end: } +\cs_generate_variant:Nn \@@_split_curve:nn {nv, nV} \cs_new_protected_nopar:Npn \spath_split_curve:NNnn #1#2#3#4 { \@@_split_curve:nn {#3}{#4} @@ -2009,7 +2498,224 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% +% \begin{macro}[internal]{ +% \spath_maybe_split_curve:Nn, +% \spath_maybe_gsplit_curve:Nn, +% } +% Possibly splits a bezier curve to ensure that the pieces don't self-intersect. +% Figuring out whether a Bezier cubic self intersects is apparently a difficult problem so we don't bother. +% We compute a point such that if there is an intersection then it lies on either side of the point. +% I don't recall where the formula came from! +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_maybe_split_curve:n #1 +{ + \group_begin: + \fp_set:Nn \l_@@_tmpa_fp + { + ( + \tl_item:nn {#1} {3} + - 3 * \tl_item:nn {#1} {6} + + 3 * \tl_item:nn {#1} {9} + - \tl_item:nn {#1} {12} + ) + * + (3 * \tl_item:nn {#1} {8} - 3 * \tl_item:nn {#1} {11}) + - + ( + \tl_item:nn {#1} {2} + - 3 * \tl_item:nn {#1} {5} + + 3 * \tl_item:nn {#1} {8} + - \tl_item:nn {#1} {11} + ) + * + (3 * \tl_item:nn {#1} {9} - 3 * \tl_item:nn {#1} {12}) + } + \fp_set:Nn \l_@@_tmpb_fp + { + ( + \tl_item:nn {#1} {2} + - 3 * \tl_item:nn {#1} {5} + + 3 * \tl_item:nn {#1} {8} + - \tl_item:nn {#1} {11} + ) + * + ( + 3 * \tl_item:nn {#1} {6} + - 6 * \tl_item:nn {#1} {9} + + 3 * \tl_item:nn {#1} {12} + ) + - + ( + \tl_item:nn {#1} {3} + - 3 * \tl_item:nn {#1} {6} + + 3 * \tl_item:nn {#1} {9} + - \tl_item:nn {#1} {12} + ) + * + ( + 3 * \tl_item:nn {#1} {5} + - 6 * \tl_item:nn {#1} {8} + + 3 * \tl_item:nn {#1} {11} + ) + } + \fp_compare:nTF + { + \l_@@_tmpb_fp != 0 + } + { + \fp_set:Nn \l_@@_tmpa_fp {.5 * \l_@@_tmpa_fp / \l_@@_tmpb_fp} + \fp_compare:nTF + { + 0 < \l_@@_tmpa_fp && \l_@@_tmpa_fp < 1 + } + { + \@@_split_curve:nV {#1} \l_@@_tmpa_fp + } + { + \tl_gset:Nn \g_@@_output_tl { {#1} {} } + } + } + { + \tl_gset:Nn \g_@@_output_tl { {#1} {} } + } + \group_end: +} +\cs_new_protected_nopar:Npn \spath_maybe_split_curve:NNn #1#2#3 +{ + \@@_maybe_split_curve:n {#3} + \tl_set:Nx #1 {\tl_item:Nn \g_@@_output_tl {1}} + \tl_set:Nx #2 {\tl_item:Nn \g_@@_output_tl {2}} + \tl_gclear:N \g_@@_output_tl +} +\cs_generate_variant:Nn \spath_maybe_split_curve:NNn {NNn, NNV } +\cs_new_protected_nopar:Npn \spath_maybe_gsplit_curve:NNn #1#2#3 +{ + \@@_maybe_split_curve:n {#3} + \tl_gset:Nx #1 {\tl_item:Nn \g_@@_output_tl {1}} + \tl_gset:Nx #2 {\tl_item:Nn \g_@@_output_tl {2}} + \tl_gclear:N \g_@@_output_tl +} +\cs_generate_variant:Nn \spath_maybe_gsplit_curve:NNn {NNn, NNV} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{ +% \spath_split_curves:Nn, +% \spath_gsplit_curves:Nn, +% } +% Slurp through the path ensuring that beziers don't self-intersect. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_split_curves:n #1 +{ + \group_begin: + \tl_set:Nn \l_@@_tmpa_tl {#1} + \tl_clear:N \l_@@_tmpb_tl + \tl_clear:N \l_@@_tmpc_tl + \bool_do_until:nn + { + \tl_if_empty_p:N \l_@@_tmpa_tl + } + { + \tl_set:Nx \l_@@_tmpc_tl {\tl_head:N \l_@@_tmpa_tl} + \tl_case:NnF \l_@@_tmpc_tl + { + \c_spath_curvetoa_tl + { + \tl_clear:N \l_@@_tmpd_tl + \tl_set_eq:NN \l_@@_tmpd_tl \c_spath_moveto_tl + \tl_put_right:Nx \l_@@_tmpd_tl + { + { \dim_use:N \l_@@_tmpa_dim } + { \dim_use:N \l_@@_tmpb_dim } + } + \dim_set:Nn \l_@@_tmpa_dim + { + \tl_item:Nn \l_@@_tmpa_tl {8} + } + \dim_set:Nn \l_@@_tmpb_dim + { + \tl_item:Nn \l_@@_tmpa_tl {9} + } + \prg_replicate:nn {3} + { + \tl_put_right:Nx \l_@@_tmpd_tl + { + \tl_item:Nn \l_@@_tmpa_tl {1} + {\tl_item:Nn \l_@@_tmpa_tl {2}} + {\tl_item:Nn \l_@@_tmpa_tl {3}} + } + \prg_replicate:nn {3} + { + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} + } + } + + \spath_maybe_split_curve:NNV + \l_@@_tmpd_tl + \l_@@_tmpe_tl + \l_@@_tmpd_tl + \prg_replicate:nn {3} + { + \tl_set:Nx \l_@@_tmpd_tl {\tl_tail:N \l_@@_tmpd_tl} + \tl_set:Nx \l_@@_tmpe_tl {\tl_tail:N \l_@@_tmpe_tl} + } + \tl_put_right:NV \l_@@_tmpb_tl \l_@@_tmpd_tl + \tl_put_right:NV \l_@@_tmpb_tl \l_@@_tmpe_tl + } + } + { + \dim_set:Nn \l_@@_tmpa_dim + { + \tl_item:Nn \l_@@_tmpa_tl {2} + } + \dim_set:Nn \l_@@_tmpb_dim + { + \tl_item:Nn \l_@@_tmpa_tl {3} + } + \tl_put_right:Nx \l_@@_tmpb_tl + { + \tl_item:Nn \l_@@_tmpa_tl {1} + {\tl_item:Nn \l_@@_tmpa_tl {2}} + {\tl_item:Nn \l_@@_tmpa_tl {3}} + } + \prg_replicate:nn {3} + { + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} + } + } + } + \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpb_tl + \group_end: +} +\cs_new_protected_nopar:Npn \spath_split_curves:Nn #1#2 +{ + \@@_split_curves:n {#2} + \tl_set_eq:NN #1 \g_@@_output_tl + \tl_gclear:N \g_@@_output_tl +} +\cs_generate_variant:Nn \spath_split_curves:Nn {NV, cV, cn, cv } +\cs_new_protected_nopar:Npn \spath_split_curves:N #1 +{ + \spath_split_curves:NV #1#1 +} +\cs_generate_variant:Nn \spath_split_curves:N {c} +\cs_new_protected_nopar:Npn \spath_gsplit_curves:Nn #1#2 +{ + \@@_split_curves:n {#2} + \tl_gset_eq:NN #1 \g_@@_output_tl + \tl_gclear:N \g_@@_output_tl +} +\cs_generate_variant:Nn \spath_gsplit_curves:Nn {NV, cV, cn, cv } +\cs_new_protected_nopar:Npn \spath_gsplit_curves:N #1 +{ + \spath_gsplit_curves:NV #1#1 +} +\cs_generate_variant:Nn \spath_gsplit_curves:N {c} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{ % \spath_split_line:NNnn, % \spath_gsplit_line:NNnn % } @@ -2079,21 +2785,7 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macrocode} -\int_new:N \l_@@_split_int -\int_new:N \l_@@_splitat_int -\fp_new:N \l_@@_split_fp -\bool_new:N \l_@@_split_bool -\tl_new:N \l_@@_split_path_tl -\tl_new:N \l_@@_split_patha_tl -\tl_new:N \l_@@_split_pathb_tl -\tl_new:N \l_@@_split_intoa_tl -\tl_new:N \l_@@_split_intob_tl -\dim_new:N \l_@@_splitx_dim -\dim_new:N \l_@@_splity_dim -% \end{macrocode} -% -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_split_at:NNnn, % \spath_split_at:Nnn, % \spath_split_at:Nn, @@ -2107,165 +2799,165 @@ manipulating PGF soft paths} \cs_new_protected_nopar:Npn \@@_split_at:nn #1#2 { \group_begin: - \int_set:Nn \l_@@_splitat_int {\fp_to_int:n {floor(#2) + 1}} - \fp_set:Nn \l_@@_split_fp {#2 - floor(#2)} + \int_set:Nn \l_@@_tmpa_int {\fp_to_int:n {floor(#2) + 1}} + \fp_set:Nn \l_@@_tmpa_fp {#2 - floor(#2)} % Is split point near one end or other of a component? \fp_compare:nT { - \l_@@_split_fp < 0.01 + \l_@@_tmpa_fp < 0.01 } { % Near the start, so we'll place it at the start - \fp_set:Nn \l_@@_split_fp {0} + \fp_set:Nn \l_@@_tmpa_fp {0} } \fp_compare:nT { - \l_@@_split_fp > 0.99 + \l_@@_tmpa_fp > 0.99 } { % Near the end, so we'll place it at the end - \fp_set:Nn \l_@@_split_fp {0} - \int_incr:N \l_@@_splitat_int + \fp_set:Nn \l_@@_tmpa_fp {0} + \int_incr:N \l_@@_tmpa_int } - \int_zero:N \l_@@_split_int - \bool_set_true:N \l_@@_split_bool + \int_zero:N \l_@@_tmpb_int + \bool_set_true:N \l_@@_tmpa_bool - \tl_set:Nn \l_@@_split_path_tl {#1} - \tl_clear:N \l_@@_split_patha_tl + \tl_set:Nn \l_@@_tmpe_tl {#1} + \tl_clear:N \l_@@_tmpc_tl - \dim_zero:N \l_@@_splitx_dim - \dim_zero:N \l_@@_splity_dim + \dim_zero:N \l_@@_tmpa_dim + \dim_zero:N \l_@@_tmpb_dim \bool_until_do:nn { - \tl_if_empty_p:N \l_@@_split_path_tl + \tl_if_empty_p:N \l_@@_tmpe_tl || - \int_compare_p:n { \l_@@_splitat_int == \l_@@_split_int } + \int_compare_p:n { \l_@@_tmpa_int == \l_@@_tmpb_int } } { - \tl_set:Nx \l_@@_tmpc_tl {\tl_head:N \l_@@_split_path_tl} - \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl } - \tl_case:Nn \l_@@_tmpc_tl + \tl_set:Nx \l_@@_tmpf_tl {\tl_head:N \l_@@_tmpe_tl} + \tl_set:Nx \l_@@_tmpe_tl {\tl_tail:N \l_@@_tmpe_tl } + \tl_case:Nn \l_@@_tmpf_tl { \c_spath_lineto_tl { - \int_incr:N \l_@@_split_int + \int_incr:N \l_@@_tmpb_int } \c_spath_curvetoa_tl { - \int_incr:N \l_@@_split_int + \int_incr:N \l_@@_tmpb_int } } - \int_compare:nT { \l_@@_split_int < \l_@@_splitat_int } + \int_compare:nT { \l_@@_tmpb_int < \l_@@_tmpa_int } { - \tl_put_right:NV \l_@@_split_patha_tl \l_@@_tmpc_tl + \tl_put_right:NV \l_@@_tmpc_tl \l_@@_tmpf_tl - \tl_put_right:Nx \l_@@_split_patha_tl - {{ \tl_head:N \l_@@_split_path_tl }} - \dim_set:Nn \l_@@_splitx_dim {\tl_head:N \l_@@_split_path_tl} - \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl } + \tl_put_right:Nx \l_@@_tmpc_tl + {{ \tl_head:N \l_@@_tmpe_tl }} + \dim_set:Nn \l_@@_tmpa_dim {\tl_head:N \l_@@_tmpe_tl} + \tl_set:Nx \l_@@_tmpe_tl {\tl_tail:N \l_@@_tmpe_tl } - \tl_put_right:Nx \l_@@_split_patha_tl - {{ \tl_head:N \l_@@_split_path_tl }} - \dim_set:Nn \l_@@_splity_dim {\tl_head:N \l_@@_split_path_tl} - \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl } + \tl_put_right:Nx \l_@@_tmpc_tl + {{ \tl_head:N \l_@@_tmpe_tl }} + \dim_set:Nn \l_@@_tmpb_dim {\tl_head:N \l_@@_tmpe_tl} + \tl_set:Nx \l_@@_tmpe_tl {\tl_tail:N \l_@@_tmpe_tl } } } - \tl_clear:N \l_@@_split_pathb_tl - \tl_put_right:NV \l_@@_split_pathb_tl \c_spath_moveto_tl - \tl_put_right:Nx \l_@@_split_pathb_tl + \tl_clear:N \l_@@_tmpd_tl + \tl_put_right:NV \l_@@_tmpd_tl \c_spath_moveto_tl + \tl_put_right:Nx \l_@@_tmpd_tl { - {\dim_use:N \l_@@_splitx_dim} - {\dim_use:N \l_@@_splity_dim} + {\dim_use:N \l_@@_tmpa_dim} + {\dim_use:N \l_@@_tmpb_dim} } \fp_compare:nTF { - \l_@@_split_fp == 0 + \l_@@_tmpa_fp == 0 } { - \tl_set_eq:NN \l_@@_split_intob_tl \l_@@_split_pathb_tl - \tl_if_empty:NF \l_@@_split_path_tl + \tl_set_eq:NN \l_@@_tmpb_tl \l_@@_tmpd_tl + \tl_if_empty:NF \l_@@_tmpe_tl { - \tl_put_right:NV \l_@@_split_intob_tl \l_@@_tmpc_tl - \tl_put_right:NV \l_@@_split_intob_tl \l_@@_split_path_tl + \tl_put_right:NV \l_@@_tmpb_tl \l_@@_tmpf_tl + \tl_put_right:NV \l_@@_tmpb_tl \l_@@_tmpe_tl } } { - \tl_case:Nn \l_@@_tmpc_tl + \tl_case:Nn \l_@@_tmpf_tl { \c_spath_lineto_tl { - \tl_put_right:NV \l_@@_split_pathb_tl \l_@@_tmpc_tl - \tl_put_right:Nx \l_@@_split_pathb_tl - {{ \tl_head:N \l_@@_split_path_tl }} - \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl } + \tl_put_right:NV \l_@@_tmpd_tl \l_@@_tmpf_tl + \tl_put_right:Nx \l_@@_tmpd_tl + {{ \tl_head:N \l_@@_tmpe_tl }} + \tl_set:Nx \l_@@_tmpe_tl {\tl_tail:N \l_@@_tmpe_tl } - \tl_put_right:Nx \l_@@_split_pathb_tl - {{ \tl_head:N \l_@@_split_path_tl }} - \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl } + \tl_put_right:Nx \l_@@_tmpd_tl + {{ \tl_head:N \l_@@_tmpe_tl }} + \tl_set:Nx \l_@@_tmpe_tl {\tl_tail:N \l_@@_tmpe_tl } \spath_split_line:NNVV - \l_@@_split_intoa_tl - \l_@@_split_intob_tl - \l_@@_split_pathb_tl - \l_@@_split_fp + \l_@@_tmpa_tl + \l_@@_tmpb_tl + \l_@@_tmpd_tl + \l_@@_tmpa_fp \prg_replicate:nn {3} { - \tl_set:Nx \l_@@_split_intoa_tl {\tl_tail:N \l_@@_split_intoa_tl} + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} } - \tl_put_right:NV \l_@@_split_patha_tl \l_@@_split_intoa_tl - \tl_put_right:NV \l_@@_split_intob_tl \l_@@_split_path_tl + \tl_put_right:NV \l_@@_tmpc_tl \l_@@_tmpa_tl + \tl_put_right:NV \l_@@_tmpb_tl \l_@@_tmpe_tl } \c_spath_curvetoa_tl { - \tl_put_right:NV \l_@@_split_pathb_tl \l_@@_tmpc_tl - \tl_put_right:Nx \l_@@_split_pathb_tl - {{ \tl_head:N \l_@@_split_path_tl }} - \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl } + \tl_put_right:NV \l_@@_tmpd_tl \l_@@_tmpf_tl + \tl_put_right:Nx \l_@@_tmpd_tl + {{ \tl_head:N \l_@@_tmpe_tl }} + \tl_set:Nx \l_@@_tmpe_tl {\tl_tail:N \l_@@_tmpe_tl } - \tl_put_right:Nx \l_@@_split_pathb_tl - {{ \tl_head:N \l_@@_split_path_tl }} - \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl } + \tl_put_right:Nx \l_@@_tmpd_tl + {{ \tl_head:N \l_@@_tmpe_tl }} + \tl_set:Nx \l_@@_tmpe_tl {\tl_tail:N \l_@@_tmpe_tl } \prg_replicate:nn {2} { - \tl_put_right:Nx \l_@@_split_pathb_tl - { \tl_head:N \l_@@_split_path_tl } - \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl } + \tl_put_right:Nx \l_@@_tmpd_tl + { \tl_head:N \l_@@_tmpe_tl } + \tl_set:Nx \l_@@_tmpe_tl {\tl_tail:N \l_@@_tmpe_tl } - \tl_put_right:Nx \l_@@_split_pathb_tl - {{ \tl_head:N \l_@@_split_path_tl }} - \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl } + \tl_put_right:Nx \l_@@_tmpd_tl + {{ \tl_head:N \l_@@_tmpe_tl }} + \tl_set:Nx \l_@@_tmpe_tl {\tl_tail:N \l_@@_tmpe_tl } - \tl_put_right:Nx \l_@@_split_pathb_tl - {{ \tl_head:N \l_@@_split_path_tl }} - \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl } + \tl_put_right:Nx \l_@@_tmpd_tl + {{ \tl_head:N \l_@@_tmpe_tl }} + \tl_set:Nx \l_@@_tmpe_tl {\tl_tail:N \l_@@_tmpe_tl } } \spath_split_curve:NNVV - \l_@@_split_intoa_tl - \l_@@_split_intob_tl - \l_@@_split_pathb_tl \l_@@_split_fp + \l_@@_tmpa_tl + \l_@@_tmpb_tl + \l_@@_tmpd_tl \l_@@_tmpa_fp \prg_replicate:nn {3} { - \tl_set:Nx \l_@@_split_intoa_tl {\tl_tail:N \l_@@_split_intoa_tl} + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} } - \tl_put_right:NV \l_@@_split_patha_tl \l_@@_split_intoa_tl - \tl_put_right:NV \l_@@_split_intob_tl \l_@@_split_path_tl + \tl_put_right:NV \l_@@_tmpc_tl \l_@@_tmpa_tl + \tl_put_right:NV \l_@@_tmpb_tl \l_@@_tmpe_tl } } } \tl_gclear:N \g_@@_output_tl - \@@_tl_gput_right_braced:NV \g_@@_output_tl \l_@@_split_patha_tl - \@@_tl_gput_right_braced:NV \g_@@_output_tl \l_@@_split_intob_tl + \@@_tl_gput_right_braced:NV \g_@@_output_tl \l_@@_tmpc_tl + \@@_tl_gput_right_braced:NV \g_@@_output_tl \l_@@_tmpb_tl \group_end: } \cs_new_protected_nopar:Npn \spath_split_at:NNnn #1#2#3#4 @@ -2291,7 +2983,11 @@ manipulating PGF soft paths} \cs_new_protected_nopar:Npn \spath_split_at:Nnn #1#2#3 { \@@_split_at:nn {#2}{#3} - \tl_set:Nx #1 {\tl_item:Nn \g_@@_output_tl {1} \tl_item:Nn \g_@@_output_tl {2}} + \tl_set:Nx #1 + { + \tl_item:Nn \g_@@_output_tl {1} + \tl_item:Nn \g_@@_output_tl {2} + } \tl_gclear:N \g_@@_output_tl } \cs_generate_variant:Nn \spath_split_at:Nnn {NVn, NVV} @@ -2302,7 +2998,11 @@ manipulating PGF soft paths} \cs_new_protected_nopar:Npn \spath_gsplit_at:Nnn #1#2#3 { \@@_split_at:nn {#2}{#3} - \tl_gset:Nx #1 {\tl_item:Nn \g_@@_output_tl {1} \tl_item:Nn \g_@@_output_tl {2}} + \tl_gset:Nx #1 + { + \tl_item:Nn \g_@@_output_tl {1} + \tl_item:Nn \g_@@_output_tl {2} + } \tl_gclear:N \g_@@_output_tl } \cs_generate_variant:Nn \spath_gsplit_at:Nnn {NVn, NVV} @@ -2323,19 +3023,7 @@ manipulating PGF soft paths} % As in the previous section, there are various versions. % In particular, there are versions where the path can be specified by a macro and is saved back into that macro. % -% \begin{macrocode} -\tl_new:N \l_@@_shorten_fa_tl -\tl_new:N \l_@@_shorten_path_tl -\tl_new:N \l_@@_shorten_last_tl -\tl_new:N \l_@@_shorten_lasta_tl -\tl_new:N \l_@@_shorten_lastb_tl -\int_new:N \l_@@_shorten_int -\fp_new:N \l_@@_shorten_x_fp -\fp_new:N \l_@@_shorten_y_fp -\fp_new:N \l_@@_shorten_len_fp -% \end{macrocode} -% -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_shorten_at_end:Nnn % } % This macro shortens a path from the end by a dimension. @@ -2349,121 +3037,121 @@ manipulating PGF soft paths} } { \group_begin: - \tl_set:Nn \l_@@_shorten_path_tl {#1} - \tl_reverse:N \l_@@_shorten_path_tl + \tl_set:Nn \l_@@_tmpa_tl {#1} + \tl_reverse:N \l_@@_tmpa_tl - \tl_set:Nx \l_@@_shorten_fa_tl {\tl_item:Nn \l_@@_shorten_path_tl {3}} + \tl_set:Nx \l_@@_tmpb_tl {\tl_item:Nn \l_@@_tmpa_tl {3}} - \tl_clear:N \l_@@_shorten_last_tl - \tl_if_eq:NNTF \l_@@_shorten_fa_tl \c_spath_curveto_tl + \tl_clear:N \l_@@_tmpe_tl + \tl_if_eq:NNTF \l_@@_tmpb_tl \c_spath_curveto_tl { - \int_set:Nn \l_@@_shorten_int {3} + \int_set:Nn \l_@@_tmpa_int {3} } { - \int_set:Nn \l_@@_shorten_int {1} + \int_set:Nn \l_@@_tmpa_int {1} } - \prg_replicate:nn { \l_@@_shorten_int } + \prg_replicate:nn { \l_@@_tmpa_int } { - \tl_put_right:Nx \l_@@_shorten_last_tl + \tl_put_right:Nx \l_@@_tmpe_tl { - {\tl_head:N \l_@@_shorten_path_tl} + {\tl_head:N \l_@@_tmpa_tl} } - \tl_set:Nx \l_@@_shorten_path_tl {\tl_tail:N \l_@@_shorten_path_tl} - \tl_put_right:Nx \l_@@_shorten_last_tl + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} + \tl_put_right:Nx \l_@@_tmpe_tl { - {\tl_head:N \l_@@_shorten_path_tl} + {\tl_head:N \l_@@_tmpa_tl} } - \tl_set:Nx \l_@@_shorten_path_tl {\tl_tail:N \l_@@_shorten_path_tl} - \tl_put_right:Nx \l_@@_shorten_last_tl + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} + \tl_put_right:Nx \l_@@_tmpe_tl { - \tl_head:N \l_@@_shorten_path_tl + \tl_head:N \l_@@_tmpa_tl } - \tl_set:Nx \l_@@_shorten_path_tl {\tl_tail:N \l_@@_shorten_path_tl} + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} } - \tl_put_right:Nx \l_@@_shorten_last_tl + \tl_put_right:Nx \l_@@_tmpe_tl { - {\tl_item:Nn \l_@@_shorten_path_tl {1}} - {\tl_item:Nn \l_@@_shorten_path_tl {2}} + {\tl_item:Nn \l_@@_tmpa_tl {1}} + {\tl_item:Nn \l_@@_tmpa_tl {2}} } - \tl_put_right:NV \l_@@_shorten_last_tl \c_spath_moveto_tl + \tl_put_right:NV \l_@@_tmpe_tl \c_spath_moveto_tl - \tl_reverse:N \l_@@_shorten_path_tl + \tl_reverse:N \l_@@_tmpa_tl - \fp_set:Nn \l_@@_shorten_x_fp + \fp_set:Nn \l_@@_tmpa_fp { - \dim_to_fp:n {\tl_item:Nn \l_@@_shorten_last_tl {4}} + \dim_to_fp:n {\tl_item:Nn \l_@@_tmpe_tl {4}} - - \dim_to_fp:n {\tl_item:Nn \l_@@_shorten_last_tl {1}} + \dim_to_fp:n {\tl_item:Nn \l_@@_tmpe_tl {1}} } - \fp_set:Nn \l_@@_shorten_y_fp + \fp_set:Nn \l_@@_tmpb_fp { - \dim_to_fp:n {\tl_item:Nn \l_@@_shorten_last_tl {5}} + \dim_to_fp:n {\tl_item:Nn \l_@@_tmpe_tl {5}} - - \dim_to_fp:n {\tl_item:Nn \l_@@_shorten_last_tl {2}} + \dim_to_fp:n {\tl_item:Nn \l_@@_tmpe_tl {2}} } - \fp_set:Nn \l_@@_shorten_len_fp + \fp_set:Nn \l_@@_tmpc_fp { - sqrt( \l_@@_shorten_x_fp * \l_@@_shorten_x_fp + \l_@@_shorten_y_fp * \l_@@_shorten_y_fp ) + sqrt( + \l_@@_tmpa_fp * \l_@@_tmpa_fp + + + \l_@@_tmpb_fp * \l_@@_tmpb_fp + ) * \l_@@_tmpa_int } \fp_compare:nTF { - \l_@@_shorten_len_fp > #2 + \l_@@_tmpc_fp > #2 } { - \fp_set:Nn \l_@@_shorten_len_fp + \fp_set:Nn \l_@@_tmpc_fp { - (\l_@@_shorten_len_fp - #2)/ \l_@@_shorten_len_fp + (\l_@@_tmpc_fp - #2)/ \l_@@_tmpc_fp } - \tl_reverse:N \l_@@_shorten_last_tl + \tl_reverse:N \l_@@_tmpe_tl - \tl_if_eq:NNTF \l_@@_shorten_fa_tl \c_spath_curveto_tl + \tl_if_eq:NNTF \l_@@_tmpb_tl \c_spath_curveto_tl { - \fp_set:Nn \l_@@_shorten_len_fp - { - 1 - (1 -\l_@@_shorten_len_fp)/3 - } \spath_split_curve:NNVV - \l_@@_shorten_lasta_tl - \l_@@_shorten_lastb_tl - \l_@@_shorten_last_tl - \l_@@_shorten_len_fp + \l_@@_tmpc_tl + \l_@@_tmpd_tl + \l_@@_tmpe_tl + \l_@@_tmpc_fp } { \spath_split_line:NNVV - \l_@@_shorten_lasta_tl - \l_@@_shorten_lastb_tl - \l_@@_shorten_last_tl - \l_@@_shorten_len_fp + \l_@@_tmpc_tl + \l_@@_tmpd_tl + \l_@@_tmpe_tl + \l_@@_tmpc_fp } \prg_replicate:nn {3} { - \tl_set:Nx \l_@@_shorten_lasta_tl {\tl_tail:N \l_@@_shorten_lasta_tl} + \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpc_tl} } - \tl_put_right:NV \l_@@_shorten_path_tl \l_@@_shorten_lasta_tl + \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpc_tl } { \int_compare:nT { - \tl_count:N \l_@@_shorten_path_tl > 3 + \tl_count:N \l_@@_tmpa_tl > 3 } { - \dim_set:Nn \l_@@_tmpa_dim {\fp_to_dim:n {#2 - \l_@@_shorten_len_fp } } - \spath_shorten_at_end:NV \l_@@_shorten_path_tl \l_@@_tmpa_dim + \dim_set:Nn \l_@@_tmpa_dim {\fp_to_dim:n {#2 - \l_@@_tmpc_fp } } + \spath_shorten_at_end:NV \l_@@_tmpa_tl \l_@@_tmpa_dim } } - \tl_gset_eq:NN \g_@@_output_tl \l_@@_shorten_path_tl + \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpa_tl \group_end: } { @@ -2497,7 +3185,7 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_shorten_at_start:Nnn, % \spath_shorten_at_start:Nn, % \spath_gshorten_at_start:Nnn, @@ -2515,110 +3203,120 @@ manipulating PGF soft paths} } { \group_begin: - \tl_set:Nn \l_@@_shorten_path_tl {#1} + \tl_set:Nn \l_@@_tmpa_tl {#1} - \tl_set:Nx \l_@@_shorten_fa_tl {\tl_item:Nn \l_@@_shorten_path_tl {4}} + \tl_set:Nx \l_@@_tmpb_tl {\tl_item:Nn \l_@@_tmpa_tl {4}} - \tl_clear:N \l_@@_shorten_last_tl + \tl_clear:N \l_@@_tmpe_tl - \tl_if_eq:NNTF \l_@@_shorten_fa_tl \c_spath_curvetoa_tl + \tl_if_eq:NNTF \l_@@_tmpb_tl \c_spath_curvetoa_tl { - \int_set:Nn \l_@@_shorten_int {3} + \int_set:Nn \l_@@_tmpa_int {3} } { - \int_set:Nn \l_@@_shorten_int {1} + \int_set:Nn \l_@@_tmpa_int {1} } - \tl_set_eq:NN \l_@@_shorten_last_tl \c_spath_moveto_tl - \tl_set:Nx \l_@@_shorten_path_tl {\tl_tail:N \l_@@_shorten_path_tl } + \tl_set_eq:NN \l_@@_tmpe_tl \c_spath_moveto_tl + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl } - \prg_replicate:nn { \l_@@_shorten_int } + \prg_replicate:nn { \l_@@_tmpa_int } { - \@@_tl_put_right_braced:Nx \l_@@_shorten_last_tl {\tl_item:Nn \l_@@_shorten_path_tl {1}} - \@@_tl_put_right_braced:Nx \l_@@_shorten_last_tl {\tl_item:Nn \l_@@_shorten_path_tl {2}} - \tl_put_right:Nx \l_@@_shorten_last_tl {\tl_item:Nn \l_@@_shorten_path_tl {3}} + \@@_tl_put_right_braced:Nx + \l_@@_tmpe_tl + {\tl_item:Nn \l_@@_tmpa_tl {1}} + \@@_tl_put_right_braced:Nx + \l_@@_tmpe_tl + {\tl_item:Nn \l_@@_tmpa_tl {2}} + \tl_put_right:Nx \l_@@_tmpe_tl {\tl_item:Nn \l_@@_tmpa_tl {3}} \prg_replicate:nn {3} { - \tl_set:Nx \l_@@_shorten_path_tl {\tl_tail:N \l_@@_shorten_path_tl } + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl } } } - \@@_tl_put_right_braced:Nx \l_@@_shorten_last_tl {\tl_item:Nn \l_@@_shorten_path_tl {1}} - \@@_tl_put_right_braced:Nx \l_@@_shorten_last_tl {\tl_item:Nn \l_@@_shorten_path_tl {2}} + \@@_tl_put_right_braced:Nx + \l_@@_tmpe_tl + {\tl_item:Nn \l_@@_tmpa_tl {1}} + \@@_tl_put_right_braced:Nx + \l_@@_tmpe_tl + {\tl_item:Nn \l_@@_tmpa_tl {2}} - \fp_set:Nn \l_@@_shorten_x_fp + \fp_set:Nn \l_@@_tmpa_fp { - \dim_to_fp:n {\tl_item:Nn \l_@@_shorten_last_tl {5}} + \dim_to_fp:n {\tl_item:Nn \l_@@_tmpe_tl {5}} - - \dim_to_fp:n {\tl_item:Nn \l_@@_shorten_last_tl {2}} + \dim_to_fp:n {\tl_item:Nn \l_@@_tmpe_tl {2}} } - \fp_set:Nn \l_@@_shorten_y_fp + \fp_set:Nn \l_@@_tmpb_fp { - \dim_to_fp:n {\tl_item:Nn \l_@@_shorten_last_tl {6}} + \dim_to_fp:n {\tl_item:Nn \l_@@_tmpe_tl {6}} - - \dim_to_fp:n {\tl_item:Nn \l_@@_shorten_last_tl {3}} + \dim_to_fp:n {\tl_item:Nn \l_@@_tmpe_tl {3}} } - \fp_set:Nn \l_@@_shorten_len_fp + \fp_set:Nn \l_@@_tmpc_fp { - sqrt( \l_@@_shorten_x_fp * \l_@@_shorten_x_fp + \l_@@_shorten_y_fp * \l_@@_shorten_y_fp ) + sqrt( + \l_@@_tmpa_fp * \l_@@_tmpa_fp + + + \l_@@_tmpb_fp * \l_@@_tmpb_fp + ) + * + \l_@@_tmpa_int } \fp_compare:nTF { - \l_@@_shorten_len_fp > #2 + \l_@@_tmpc_fp > #2 } { - \fp_set:Nn \l_@@_shorten_len_fp + \fp_set:Nn \l_@@_tmpc_fp { - #2/ \l_@@_shorten_len_fp + #2/ \l_@@_tmpc_fp } - \tl_if_eq:NNTF \l_@@_shorten_fa_tl \c_spath_curvetoa_tl + \tl_if_eq:NNTF \l_@@_tmpb_tl \c_spath_curvetoa_tl { - \fp_set:Nn \l_@@_shorten_len_fp - { - \l_@@_shorten_len_fp/3 - } \spath_split_curve:NNVV - \l_@@_shorten_lasta_tl - \l_@@_shorten_lastb_tl - \l_@@_shorten_last_tl - \l_@@_shorten_len_fp + \l_@@_tmpc_tl + \l_@@_tmpd_tl + \l_@@_tmpe_tl + \l_@@_tmpc_fp } { \spath_split_line:NNVV - \l_@@_shorten_lasta_tl - \l_@@_shorten_lastb_tl - \l_@@_shorten_last_tl - \l_@@_shorten_len_fp + \l_@@_tmpc_tl + \l_@@_tmpd_tl + \l_@@_tmpe_tl + \l_@@_tmpc_fp } \prg_replicate:nn {2} { - \tl_set:Nx \l_@@_shorten_path_tl {\tl_tail:N \l_@@_shorten_path_tl} + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} } - \tl_put_left:NV \l_@@_shorten_path_tl \l_@@_shorten_lastb_tl + \tl_put_left:NV \l_@@_tmpa_tl \l_@@_tmpd_tl } { - \tl_put_left:NV \l_@@_shorten_path_tl \c_spath_moveto_tl + \tl_put_left:NV \l_@@_tmpa_tl \c_spath_moveto_tl \int_compare:nT { - \tl_count:N \l_@@_shorten_path_tl > 3 + \tl_count:N \l_@@_tmpa_tl > 3 } { - \dim_set:Nn \l_@@_tmpa_dim {\fp_to_dim:n {#2 - \l_@@_shorten_len_fp } } - \spath_shorten_at_start:NV \l_@@_shorten_path_tl \l_@@_tmpa_dim + \dim_set:Nn \l_@@_tmpa_dim {\fp_to_dim:n {#2 - \l_@@_tmpc_fp } } + \spath_shorten_at_start:NV \l_@@_tmpa_tl \l_@@_tmpa_dim } } - \tl_gset_eq:NN \g_@@_output_tl \l_@@_shorten_path_tl + \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpa_tl \group_end: } { @@ -2655,7 +3353,7 @@ manipulating PGF soft paths} % % \subsection{Points on a Path} % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_point_at:Nnn, % \spath_gpoint_at:Nnn, % } @@ -2687,7 +3385,9 @@ manipulating PGF soft paths} } { - \tl_set:Nx \l_@@_tmpa_tl {\seq_item:Nn \l_@@_tmpa_seq { \l_@@_tmpa_int} } + \tl_set:Nx + \l_@@_tmpa_tl + {\seq_item:Nn \l_@@_tmpa_seq { \l_@@_tmpa_int} } \int_compare:nTF { @@ -2765,11 +3465,21 @@ manipulating PGF soft paths} { {\fp_to_dim:n { - (1 - \l_@@_tmpa_fp)^3 * \tl_item:Nn \l_@@_tmpa_tl {2} + 3 * (1 - \l_@@_tmpa_fp)^2 * (\l_@@_tmpa_fp) * \tl_item:Nn \l_@@_tmpa_tl {5} + 3 * (1 - \l_@@_tmpa_fp) * (\l_@@_tmpa_fp)^2 * \tl_item:Nn \l_@@_tmpa_tl {8} + (\l_@@_tmpa_fp)^3 * \tl_item:Nn \l_@@_tmpa_tl {11} + (1 - \l_@@_tmpa_fp)^3 * \tl_item:Nn \l_@@_tmpa_tl {2} + + 3 * (1 - \l_@@_tmpa_fp)^2 * (\l_@@_tmpa_fp) + * \tl_item:Nn \l_@@_tmpa_tl {5} + + 3 * (1 - \l_@@_tmpa_fp) * (\l_@@_tmpa_fp)^2 + * \tl_item:Nn \l_@@_tmpa_tl {8} + + (\l_@@_tmpa_fp)^3 * \tl_item:Nn \l_@@_tmpa_tl {11} }} {\fp_to_dim:n { - (1 - \l_@@_tmpa_fp)^3 * \tl_item:Nn \l_@@_tmpa_tl {3} + 3 * (1 - \l_@@_tmpa_fp)^2 * (\l_@@_tmpa_fp) * \tl_item:Nn \l_@@_tmpa_tl {6} + 3 * (1 - \l_@@_tmpa_fp) * (\l_@@_tmpa_fp)^2 * \tl_item:Nn \l_@@_tmpa_tl {9} + (\l_@@_tmpa_fp)^3 * \tl_item:Nn \l_@@_tmpa_tl {12} + (1 - \l_@@_tmpa_fp)^3 * \tl_item:Nn \l_@@_tmpa_tl {3} + + 3 * (1 - \l_@@_tmpa_fp)^2 * (\l_@@_tmpa_fp) + * \tl_item:Nn \l_@@_tmpa_tl {6} + + 3 * (1 - \l_@@_tmpa_fp) * (\l_@@_tmpa_fp)^2 + * \tl_item:Nn \l_@@_tmpa_tl {9} + + (\l_@@_tmpa_fp)^3 * \tl_item:Nn \l_@@_tmpa_tl {12} }} } } @@ -2799,7 +3509,7 @@ manipulating PGF soft paths} % \end{macro} % % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_tangent_at:Nnn, % \spath_gtangent_at:Nnn, % } @@ -2831,7 +3541,9 @@ manipulating PGF soft paths} } { - \tl_set:Nx \l_@@_tmpa_tl {\seq_item:Nn \l_@@_tmpa_seq { \l_@@_tmpa_int} } + \tl_set:Nx + \l_@@_tmpa_tl + {\seq_item:Nn \l_@@_tmpa_seq { \l_@@_tmpa_int} } \int_compare:nTF { @@ -2909,16 +3621,24 @@ manipulating PGF soft paths} { {\fp_to_dim:n { - 3*(1 - \l_@@_tmpa_fp)^2 * (\tl_item:Nn \l_@@_tmpa_tl {5} - \tl_item:Nn \l_@@_tmpa_tl {2}) - + 6 * (1 - \l_@@_tmpa_fp) * (\l_@@_tmpa_fp) * (\tl_item:Nn \l_@@_tmpa_tl {8} - \tl_item:Nn \l_@@_tmpa_tl {5}) - + 3*(\l_@@_tmpa_fp)^2 * (\tl_item:Nn \l_@@_tmpa_tl {11} - \tl_item:Nn \l_@@_tmpa_tl {8}) + 3*(1 - \l_@@_tmpa_fp)^2 * (\tl_item:Nn \l_@@_tmpa_tl {5} + - \tl_item:Nn \l_@@_tmpa_tl {2}) + + 6 * (1 - \l_@@_tmpa_fp) * (\l_@@_tmpa_fp) * + (\tl_item:Nn \l_@@_tmpa_tl {8} + - \tl_item:Nn \l_@@_tmpa_tl {5}) + + 3*(\l_@@_tmpa_fp)^2 * (\tl_item:Nn \l_@@_tmpa_tl {11} + - \tl_item:Nn \l_@@_tmpa_tl {8}) } } {\fp_to_dim:n { - 3*(1 - \l_@@_tmpa_fp)^2 * (\tl_item:Nn \l_@@_tmpa_tl {6} - \tl_item:Nn \l_@@_tmpa_tl {3}) - + 6 * (1 - \l_@@_tmpa_fp) * (\l_@@_tmpa_fp) * (\tl_item:Nn \l_@@_tmpa_tl {9} - \tl_item:Nn \l_@@_tmpa_tl {6}) - + 3*(\l_@@_tmpa_fp)^2 * (\tl_item:Nn \l_@@_tmpa_tl {12} - \tl_item:Nn \l_@@_tmpa_tl {9}) + 3*(1 - \l_@@_tmpa_fp)^2 * (\tl_item:Nn \l_@@_tmpa_tl {6} + - \tl_item:Nn \l_@@_tmpa_tl {3}) + + 6 * (1 - \l_@@_tmpa_fp) * (\l_@@_tmpa_fp) * + (\tl_item:Nn \l_@@_tmpa_tl {9} + - \tl_item:Nn \l_@@_tmpa_tl {6}) + + 3*(\l_@@_tmpa_fp)^2 * (\tl_item:Nn \l_@@_tmpa_tl {12} + - \tl_item:Nn \l_@@_tmpa_tl {9}) }} } } @@ -2948,7 +3668,7 @@ manipulating PGF soft paths} % \end{macro} % % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_transformation_at:Nnn, % \spath_gtransformation_at:Nnn % } @@ -2960,15 +3680,24 @@ manipulating PGF soft paths} \tl_clear:N \l_@@_tmpa_tl \@@_tangent_at:nn {#1}{#2} \tl_set_eq:NN \l_@@_tmpb_tl \g_@@_output_tl - \fp_set:Nn \l_@@_tmpa_fp { sqrt( (\tl_item:Nn \l_@@_tmpb_tl {1})^2 + (\tl_item:Nn \l_@@_tmpb_tl {2})^2 ) } + \fp_set:Nn \l_@@_tmpa_fp + { + sqrt( + (\tl_item:Nn \l_@@_tmpb_tl {1})^2 + + + (\tl_item:Nn \l_@@_tmpb_tl {2})^2 + ) + } \fp_compare:nTF {\l_@@_tmpa_fp = 0} { \fp_set:Nn \l_@@_tmpa_fp {1} \fp_set:Nn \l_@@_tmpb_fp {0} } { - \fp_set:Nn \l_@@_tmpb_fp { (\tl_item:Nn \l_@@_tmpb_tl {2}) / \l_@@_tmpa_fp } - \fp_set:Nn \l_@@_tmpa_fp { (\tl_item:Nn \l_@@_tmpb_tl {1}) / \l_@@_tmpa_fp } + \fp_set:Nn \l_@@_tmpb_fp + { (\tl_item:Nn \l_@@_tmpb_tl {2}) / \l_@@_tmpa_fp } + \fp_set:Nn \l_@@_tmpa_fp + { (\tl_item:Nn \l_@@_tmpb_tl {1}) / \l_@@_tmpa_fp } } \tl_set:Nx \l_@@_tmpa_tl { @@ -3005,26 +3734,7 @@ manipulating PGF soft paths} % The intersection library is 0-based, but the user interface is 1-based (since if we ``count'' in a \Verb+\foreach+ then it starts at 1). % This should be more consistent. % -% \begin{macrocode} -\tl_new:N \l_@@_split_path_a_tl -\tl_new:N \l_@@_split_path_b_tl -\tl_new:N \l_@@_split_path_a_start_tl -\tl_new:N \l_@@_split_path_b_start_tl -\tl_new:N \l_@@_split_path_a_end_tl -\tl_new:N \l_@@_split_path_b_end_tl -\tl_new:N \l_@@_split_path_a_final_tl -\tl_new:N \l_@@_split_path_b_final_tl - -\tl_new:N \l_@@_split_prev_first_tl -\tl_new:N \l_@@_split_prev_second_tl - -\seq_new:N \l_@@_split_first_seq -\seq_new:N \l_@@_split_second_seq - -\int_new:N \l_@@_split_segment_int -% \end{macrocode} -% -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_intersect:NN, % \spath_intersect:nn, % } @@ -3039,8 +3749,6 @@ manipulating PGF soft paths} \pgfsetpath #2 } } -\tl_new:N \l_@@_intersecta_tl -\tl_new:N \l_@@_intersectb_tl \cs_new_protected_nopar:Npn \spath_intersect:nn #1#2 { \tl_set:Nn \l_@@_intersecta_tl {#1} @@ -3050,154 +3758,220 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{ -% \spath_split_at_intersections:NNnn, -% \spath_split_at_intersections:NN, -% \spath_gsplit_at_intersections:NNnn, -% \spath_gsplit_at_intersections:NN +% \begin{macro}[internal]{ +% \spath_split_component_at_intersections:Nnn % } -% Given two paths, split them at points where they intersect and store them in the macros. +% Split a component where it intersects a path. +% Key assumption is that the first path is a single component, so if it is closed then the end joins up to the beginning. +% The component is modified but the path is not. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_split_at_intersections:nn #1#2 +\cs_new_protected_nopar:Npn \@@_split_component_at_intersections:nn #1#2 { \group_begin: - - % Clear some token lists and sequences - \tl_clear:N \l_@@_split_path_a_final_tl - \tl_clear:N \l_@@_split_path_b_final_tl - \seq_clear:N \l_@@_split_first_seq - \seq_clear:N \l_@@_split_second_seq + \tl_clear:N \l_@@_tmpe_tl + \seq_clear:N \l_@@_tmpb_seq - \pgfintersectionsortbyfirstpath % Find the intersections of these segments - \tl_set:Nn \l_@@_split_path_a_tl {#1} - \tl_set:Nn \l_@@_split_path_b_tl {#2} - % Remove empty components -% \spath_path_remove_empty_components:N \l_@@_split_path_a_tl -% \spath_path_remove_empty_components:N \l_@@_split_path_b_tl + \tl_set:Nn \l_@@_tmpb_tl {#1} + \tl_set:Nn \l_@@_tmpc_tl {#2} - \spath_intersect:NN \l_@@_split_path_a_tl \l_@@_split_path_b_tl + \spath_reallength:Nn \l_@@_tmpa_int {#1} - % If we get intersections - \int_compare:nT {\pgfintersectionsolutions > 0} + % Remember if the component is closed + \spath_finalaction:NV \l_@@_tmpa_tl \l_@@_tmpb_tl + + \bool_set:Nn \l_@@_closed_bool { - % Find the times of the intersections on each path - \int_step_inline:nnnn {1} {1} {\pgfintersectionsolutions} - { - \pgfintersectiongetsolutiontimes{##1}{\l_@@_split_first_tl}{\l_@@_split_second_tl} - \seq_put_left:NV \l_@@_split_first_seq \l_@@_split_first_tl - } + \tl_if_eq_p:NN \l_@@_tmpa_tl \c_spath_closepath_tl } - \spath_intersect:NN \l_@@_split_path_b_tl \l_@@_split_path_a_tl + % Open it + \spath_open:N \l_@@_tmpb_tl + + % Sort intersections along the component + \pgfintersectionsortbyfirstpath + \spath_intersect:NN \l_@@_tmpb_tl \l_@@_tmpc_tl % If we get intersections \int_compare:nT {\pgfintersectionsolutions > 0} { - % Find the times of the intersections on each path + % Find the times of the intersections on the component \int_step_inline:nnnn {1} {1} {\pgfintersectionsolutions} { - \pgfintersectiongetsolutiontimes{##1}{\l_@@_split_first_tl}{\l_@@_split_second_tl} - \seq_put_left:NV \l_@@_split_second_seq \l_@@_split_first_tl + \pgfintersectiongetsolutiontimes{##1}{\l_@@_tmph_tl}{\l_@@_tmpi_tl} + \seq_put_left:NV \l_@@_tmpb_seq \l_@@_tmph_tl } - } - - \tl_set:Nn \l_@@_split_prev_first_tl {-1} - \seq_map_inline:Nn \l_@@_split_first_seq - { - \tl_set:Nn \l_@@_split_first_tl {##1} - - \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_split_first_tl - \int_compare:nT + \seq_get_left:NN \l_@@_tmpb_seq \l_@@_tmpa_tl + \fp_compare:nT { - \fp_to_int:n {floor( \l_@@_split_first_tl) } - = - \fp_to_int:n {floor( \l_@@_split_prev_first_tl) } + \l_@@_tmpa_tl > \l_@@_tmpa_int - .01 } { - \tl_set:Nx \l_@@_split_first_tl - { - \fp_eval:n { - floor( \l_@@_split_first_tl ) - + - ( \l_@@_split_first_tl - floor( \l_@@_split_first_tl) ) - / - ( \l_@@_split_prev_first_tl - floor( \l_@@_split_prev_first_tl) ) - } - } + \bool_set_false:N \l_@@_closed_bool } - \tl_set_eq:NN \l_@@_split_prev_first_tl \l_@@_tmpa_tl - - \spath_split_at:NNVV \l_@@_split_path_a_start_tl \l_@@_split_path_a_end_tl \l_@@_split_path_a_tl \l_@@_split_first_tl - - \tl_put_left:NV \l_@@_split_path_a_final_tl \l_@@_split_path_a_end_tl - \tl_set_eq:NN \l_@@_split_path_a_tl \l_@@_split_path_a_start_tl - - } - - \tl_set:Nn \l_@@_split_prev_second_tl {-1} - - \seq_map_inline:Nn \l_@@_split_second_seq - { - \tl_set:Nn \l_@@_split_second_tl {##1} - - \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_split_second_tl - \int_compare:nT + \seq_get_right:NN \l_@@_tmpb_seq \l_@@_tmpa_tl + \fp_compare:nT { - \fp_to_int:n {floor( \l_@@_split_second_tl) } - = - \fp_to_int:n {floor( \l_@@_split_prev_second_tl) } + \l_@@_tmpa_tl < .01 } { - \tl_set:Nx \l_@@_split_second_tl + \bool_set_false:N \l_@@_closed_bool + } + + + \tl_set:Nn \l_@@_tmpg_tl {-1} + + \seq_map_inline:Nn \l_@@_tmpb_seq + { + \tl_set:Nn \l_@@_tmph_tl {##1} + + \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_tmph_tl + \int_compare:nT { - \fp_eval:n { - floor( \l_@@_split_second_tl ) - + - ( \l_@@_split_second_tl - floor( \l_@@_split_second_tl) ) - / - ( \l_@@_split_prev_second_tl - floor( \l_@@_split_prev_second_tl) ) + \fp_to_int:n {floor( \l_@@_tmph_tl) } + = + \fp_to_int:n {floor( \l_@@_tmpg_tl) } + } + { + \tl_set:Nx \l_@@_tmph_tl + { + \fp_eval:n { + floor( \l_@@_tmph_tl ) + + + ( \l_@@_tmph_tl - floor( \l_@@_tmph_tl) ) + / + ( \l_@@_tmpg_tl - floor( \l_@@_tmpg_tl) ) + } } } + \tl_set_eq:NN \l_@@_tmpg_tl \l_@@_tmpa_tl + + \spath_split_at:NNVV + \l_@@_tmpd_tl + \l_@@_tmpf_tl + \l_@@_tmpb_tl + \l_@@_tmph_tl + + \tl_put_left:NV \l_@@_tmpe_tl \l_@@_tmpf_tl + \tl_set_eq:NN \l_@@_tmpb_tl \l_@@_tmpd_tl + } - \tl_set_eq:NN \l_@@_split_prev_second_tl \l_@@_tmpa_tl - \spath_split_at:NNVV \l_@@_split_path_b_start_tl \l_@@_split_path_b_end_tl \l_@@_split_path_b_tl\l_@@_split_second_tl - - \tl_put_left:NV \l_@@_split_path_b_final_tl \l_@@_split_path_b_end_tl - \tl_set_eq:NN \l_@@_split_path_b_tl \l_@@_split_path_b_start_tl - - } - \tl_put_left:NV \l_@@_split_path_a_final_tl \l_@@_split_path_a_tl - \tl_put_left:NV \l_@@_split_path_b_final_tl \l_@@_split_path_b_tl + \tl_put_left:NV \l_@@_tmpe_tl \l_@@_tmpb_tl + + \spath_remove_empty_components:N \l_@@_tmpe_tl - \tl_if_empty:NT \l_@@_split_path_a_final_tl - { - \tl_set_eq:NN \l_@@_split_path_a_final_tl \l_@@_split_path_a_tl + \tl_set_eq:NN \l_@@_tmpb_tl \l_@@_tmpe_tl } - \tl_if_empty:NT \l_@@_split_path_b_final_tl + + \bool_if:NT \l_@@_closed_bool { - \tl_set_eq:NN \l_@@_split_path_b_final_tl \l_@@_split_path_b_tl + \spath_join_component:Nn \l_@@_tmpb_tl {1} } + + \tl_gclear:N \g_@@_output_tl + \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpb_tl - \spath_remove_empty_components:N \l_@@_split_path_a_final_tl - \spath_remove_empty_components:N \l_@@_split_path_b_final_tl + \group_end: +} +\cs_new_protected_nopar:Npn \spath_split_component_at_intersections:Nnn #1#2#3 +{ + \@@_split_component_at_intersections:nn {#2}{#3} + \tl_set_eq:NN #1 \g_@@_output_tl + \tl_gclear:N \g_@@_output_tl +} +\cs_generate_variant:Nn \spath_split_component_at_intersections:Nnn {NVn, NVV} +\cs_new_protected_nopar:Npn \spath_split_component_at_intersections:Nn #1#2 +{ + \spath_split_component_at_intersections:NVn #1#1{#2} +} +\cs_generate_variant:Nn \spath_split_component_at_intersections:Nn {cn, cv} +\cs_new_protected_nopar:Npn \spath_gsplit_component_at_intersections:Nnn #1#2#3 +{ + \@@_split_component_at_intersections:nn {#2}{#3} + \tl_gset_eq:NN #1 \g_@@_output_tl + \tl_gclear:N \g_@@_output_tl +} +\cs_generate_variant:Nn \spath_gsplit_component_at_intersections:Nnn {NVn, NVV} +\cs_new_protected_nopar:Npn \spath_gsplit_component_at_intersections:Nn #1#2 +{ + \spath_gsplit_component_at_intersections:NVn #1#1{#2} +} +\cs_generate_variant:Nn \spath_gsplit_component_at_intersections:Nn {cn, cv} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}[internal]{ +% \spath_split_path_at_intersections:Nnn, +% \spath_split_path_at_intersections:Nn, +% \spath_gsplit_path_at_intersections:Nnn, +% \spath_gsplit_path_at_intersections:Nn, +% \spath_split_at_intersections:NNnn, +% \spath_split_at_intersections:NN, +% \spath_gsplit_at_intersections:NNnn, +% \spath_gsplit_at_intersections:NN, +% } +% Split paths at their intersections. +% The \Verb+path+ versions only split the first path. +% The others split both paths. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_split_path_at_intersections:nn #1#2 +{ + \group_begin: + + \seq_clear:N \l_@@_tmpa_seq + \seq_clear:N \l_@@_tmpb_seq + \spath_components_to_seq:Nn \l_@@_tmpa_seq {#1} + \seq_map_inline:Nn \l_@@_tmpa_seq + { + \spath_split_component_at_intersections:Nnn \l_@@_tmpa_tl {##1} {#2} + \seq_put_right:NV \l_@@_tmpb_seq \l_@@_tmpa_tl + } + \tl_gclear:N \g_@@_output_tl - \@@_tl_gput_right_braced:NV \g_@@_output_tl \l_@@_split_path_a_final_tl - \@@_tl_gput_right_braced:NV \g_@@_output_tl \l_@@_split_path_b_final_tl + \tl_gset:Nx \g_@@_output_tl {\seq_use:Nn \l_@@_tmpb_seq {} } \group_end: } +\cs_new_protected_nopar:Npn \spath_split_path_at_intersections:Nnn #1#2#3 +{ + \@@_split_path_at_intersections:nn {#2}{#3} + \tl_set_eq:NN #1 \g_@@_output_tl + \tl_gclear:N \g_@@_output_tl +} +\cs_generate_variant:Nn \spath_split_path_at_intersections:Nnn +{NVn, NVV, cVn, cVV, cvn, cvv} +\cs_new_protected_nopar:Npn \spath_split_path_at_intersections:Nn #1#2 +{ + \spath_split_path_at_intersections:NVn #1#1{#2} +} +\cs_generate_variant:Nn \spath_split_path_at_intersections:Nn {cv, NV} +\cs_new_protected_nopar:Npn \spath_gsplit_path_at_intersections:Nnn #1#2#3 +{ + \@@_split_path_at_intersections:nn {#2}{#3} + \tl_gset_eq:NN #1 \g_@@_output_tl + \tl_gclear:N \g_@@_output_tl +} +\cs_generate_variant:Nn \spath_gsplit_path_at_intersections:Nnn +{NVn, NVV, cVn, cVV, cvn, cvv} +\cs_new_protected_nopar:Npn \spath_gsplit_path_at_intersections:Nn #1#2 +{ + \spath_gsplit_path_at_intersections:NVn #1#1{#2} +} +\cs_generate_variant:Nn \spath_gsplit_path_at_intersections:Nn {cv, NV} \cs_new_protected_nopar:Npn \spath_split_at_intersections:NNnn #1#2#3#4 { - \@@_split_at_intersections:nn {#3}{#4} - \tl_set:Nx #1 {\tl_item:Nn \g_@@_output_tl {1}} - \tl_set:Nx #2 {\tl_item:Nn \g_@@_output_tl {2}} + \@@_split_path_at_intersections:nn {#3}{#4} + \tl_set_eq:NN #1 \g_@@_output_tl + \@@_split_path_at_intersections:nn {#4}{#3} + \tl_set_eq:NN #2 \g_@@_output_tl \tl_gclear:N \g_@@_output_tl } -\cs_generate_variant:Nn \spath_split_at_intersections:NNnn {NNVV, ccVV, ccvv} +\cs_generate_variant:Nn \spath_split_at_intersections:NNnn +{NNVn, NNVV, ccVn, ccVV, ccvn, ccvv} \cs_new_protected_nopar:Npn \spath_split_at_intersections:NN #1#2 { \spath_split_at_intersections:NNVV #1#2#1#2 @@ -3205,12 +3979,14 @@ manipulating PGF soft paths} \cs_generate_variant:Nn \spath_split_at_intersections:NN {cc} \cs_new_protected_nopar:Npn \spath_gsplit_at_intersections:NNnn #1#2#3#4 { - \@@_split_at_intersections:nn {#3}{#4} - \tl_gset:Nx #1 {\tl_item:Nn \g_@@_output_tl {1}} - \tl_gset:Nx #2 {\tl_item:Nn \g_@@_output_tl {2}} + \@@_split_path_at_intersections:nn {#3}{#4} + \tl_gset_eq:NN #1 \g_@@_output_tl + \@@_split_path_at_intersections:nn {#4}{#3} + \tl_gset_eq:NN #2 \g_@@_output_tl \tl_gclear:N \g_@@_output_tl } -\cs_generate_variant:Nn \spath_gsplit_at_intersections:NNnn {NNVV, ccVV, ccvv} +\cs_generate_variant:Nn \spath_gsplit_at_intersections:NNnn +{NNVn, NNVV, ccVn, ccVV, ccvn, ccvv} \cs_new_protected_nopar:Npn \spath_gsplit_at_intersections:NN #1#2 { \spath_gsplit_at_intersections:NNVV #1#2#1#2 @@ -3219,211 +3995,293 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{ -% \spath_split_at_self_intersections:Nn, -% \spath_split_at_self_intersections:N, -% \spath_gsplit_at_self_intersections:Nn, -% \spath_gsplit_at_self_intersections:N, +% +% \begin{macro}[internal]{ +% \spath_split_component_at_self_intersections:Nn, +% \spath_split_component_at_self_intersections:N, +% \spath_gsplit_component_at_self_intersections:Nn, +% \spath_gsplit_component_at_self_intersections:N, % } -% Given a path, split it at points where it self-intersects and store in the given macro. +% Given a component of a path, split it at points where it self-intersects. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_split_at_self_intersections:n #1 +\cs_new_protected_nopar:Npn \@@_split_component_at_self_intersections:n #1 { \group_begin: + \tl_set:Nn \l_@@_tmpe_tl {#1} + + % Remember if the component is closed + \spath_finalaction:NV \l_@@_tmpa_tl \l_@@_tmpe_tl + + \bool_set:Nn \l_@@_closed_bool + { + \tl_if_eq_p:NN \l_@@_tmpa_tl \c_spath_closepath_tl + } % Copy the path - \tl_set:Nn \l_@@_split_path_b_tl {#1} + \tl_set:Nn \l_@@_tmpe_tl {#1} % Open the path - \spath_open:N \l_@@_split_path_b_tl - % Remove empty components - \spath_remove_empty_components:N \l_@@_split_path_b_tl + \spath_open:N \l_@@_tmpe_tl + % Ensure beziers don't self-intersect + \spath_split_curves:N \l_@@_tmpe_tl + % Make a copy for later - \tl_set_eq:NN \l_@@_split_path_b_final_tl \l_@@_split_path_b_tl + \tl_set_eq:NN \l_@@_tmpg_tl \l_@@_tmpe_tl % Clear some token lists and sequences - \tl_clear:N \l_@@_split_path_a_tl - \seq_clear:N \l_@@_split_first_seq - \int_zero:N \l_@@_split_segment_int + \tl_clear:N \l_@@_tmpd_tl + \seq_clear:N \l_@@_tmpb_seq + \int_zero:N \l_@@_tmpa_int \pgfintersectionsortbyfirstpath - \bool_do_until:nn - { - \int_compare_p:n - { - \tl_count:N \l_@@_split_path_b_tl < 4 - } - } - { - \tl_clear:N \l_@@_split_path_a_tl - \tl_put_right:Nx \l_@@_split_path_a_tl - { - \tl_item:Nn \l_@@_split_path_b_tl {1} - {\tl_item:Nn \l_@@_split_path_b_tl {2}} - {\tl_item:Nn \l_@@_split_path_b_tl {3}} - } + % Split the path into a sequence of segments + \spath_segments_to_seq:NV \l_@@_tmpa_seq \l_@@_tmpe_tl - \tl_set:Nx \l_@@_tmpa_tl { \tl_item:Nn \l_@@_split_path_b_tl {4} } - - \tl_set:Nx \l_@@_split_path_b_tl {\tl_tail:N \l_@@_split_path_b_tl} - - \int_zero:N \l_@@_tmpa_int - - \tl_case:Nn \l_@@_tmpa_tl - { - \c_spath_moveto_tl - { - \tl_clear:N \l_@@_split_path_a_tl - \tl_set:Nx \l_@@_split_path_b_tl {\tl_tail:N \l_@@_split_path_b_tl} - \tl_set:Nx \l_@@_split_path_b_tl {\tl_tail:N \l_@@_split_path_b_tl} - \tl_set:Nx \l_@@_split_path_b_tl {\tl_tail:N \l_@@_split_path_b_tl} - } - \c_spath_lineto_tl - { - \int_set:Nn \l_@@_tmpa_int {1} - } - \c_spath_curvetoa_tl - { - \int_set:Nn \l_@@_tmpa_int {3} - } - } - - \prg_replicate:nn { \l_@@_tmpa_int } - { - \tl_set:Nx \l_@@_split_path_b_tl {\tl_tail:N \l_@@_split_path_b_tl} - \tl_set:Nx \l_@@_split_path_b_tl {\tl_tail:N \l_@@_split_path_b_tl} - - \tl_put_right:Nx \l_@@_split_path_a_tl - { - \tl_item:Nn \l_@@_split_path_b_tl {1} - {\tl_item:Nn \l_@@_split_path_b_tl {2}} - {\tl_item:Nn \l_@@_split_path_b_tl {3}} - } - - \tl_set:Nx \l_@@_split_path_b_tl {\tl_tail:N \l_@@_split_path_b_tl} - } - - \tl_put_left:NV \l_@@_split_path_b_tl \c_spath_moveto_tl - - \tl_if_empty:NF \l_@@_split_path_a_tl + \seq_map_indexed_inline:Nn \l_@@_tmpa_seq + { + \seq_map_indexed_inline:Nn \l_@@_tmpa_seq { - % Intersect the current segment with the rest of the path - \spath_intersect:NN \l_@@_split_path_a_tl \l_@@_split_path_b_tl - - - % If we get intersections - \int_compare:nT {\pgfintersectionsolutions > 0} + % Don't intersect a segment with itself + \int_compare:nF { - % Find the times of the intersections on each path - \int_step_inline:nnnn {1} {1} {\pgfintersectionsolutions} - { - \pgfintersectiongetsolutiontimes{##1}{\l_@@_split_first_tl}{\l_@@_split_second_tl} - \fp_compare:nT - { - \l_@@_split_first_tl < .99 - } - { - \tl_set:Nx \l_@@_tmpa_tl {\fp_to_decimal:n {\l_@@_split_first_tl + \l_@@_split_segment_int}} - \seq_put_right:NV \l_@@_split_first_seq \l_@@_tmpa_tl - } - } + ##1 == ####1 } - - \spath_intersect:NN \l_@@_split_path_b_tl \l_@@_split_path_a_tl - - % If we get intersections - \int_compare:nT {\pgfintersectionsolutions > 0} { - % Find the times of the intersections on each path - \int_step_inline:nnnn {1} {1} {\pgfintersectionsolutions} + \spath_intersect:nn {##2} {####2} + + \int_compare:nT {\pgfintersectionsolutions > 0} { - \pgfintersectiongetsolutiontimes{##1}{\l_@@_split_first_tl}{\l_@@_split_second_tl} - \fp_compare:nT - { - \l_@@_split_first_tl > .01 - } + % Find the times of the intersections on each path + \int_step_inline:nnnn {1} {1} {\pgfintersectionsolutions} { - \tl_set:Nx \l_@@_tmpa_tl {\fp_to_decimal:n {\l_@@_split_first_tl + \l_@@_split_segment_int + 1}} - \seq_put_right:NV \l_@@_split_first_seq \l_@@_tmpa_tl + \pgfintersectiongetsolutiontimes + {########1}{\l_@@_tmpb_tl}{\l_@@_tmpc_tl} + + \bool_if:nT + { + !( + \fp_compare_p:n { \l_@@_tmpb_tl > .99 } + && + \int_compare_p:n {##1 + 1 == ####1} + ) + && + !( + \fp_compare_p:n { \l_@@_tmpb_tl < .01 } + && + \int_compare_p:n {##1 - 1 == ####1} + ) + && + !( + \l_@@_closed_bool + && + \fp_compare_p:n { \l_@@_tmpb_tl < .01 } + && + \int_compare_p:n {##1 == 1} + && + \int_compare_p:n {\seq_count:N \l_@@_tmpa_seq == ####1} + ) + && + !( + \l_@@_closed_bool + && + \fp_compare_p:n { \l_@@_tmpb_tl > .99 } + && + \int_compare_p:n {####1 == 1} + && + \int_compare_p:n {\seq_count:N \l_@@_tmpa_seq == ##1} + ) + } + { + \tl_set:Nx \l_@@_tmpa_tl + {\fp_to_decimal:n {\l_@@_tmpb_tl + ##1 - 1}} + \seq_put_right:NV \l_@@_tmpb_seq \l_@@_tmpa_tl + } } } } - } - % Increment the segment counter - \int_incr:N \l_@@_split_segment_int } % Sort the sequence by reverse order along the path - \seq_sort:Nn \l_@@_split_first_seq + \seq_sort:Nn \l_@@_tmpb_seq { \fp_compare:nNnTF { ##1 } < { ##2 } { \sort_return_swapped: } { \sort_return_same: } } + \seq_get_left:NN \l_@@_tmpb_seq \l_@@_tmpa_tl + \fp_compare:nT + { + \l_@@_tmpa_tl > \seq_count:N \l_@@_tmpa_seq - .01 + } + { + \bool_set_false:N \l_@@_closed_bool + } + \seq_get_right:NN \l_@@_tmpb_seq \l_@@_tmpa_tl + \fp_compare:nT + { + \l_@@_tmpa_tl < .01 + } + { + \bool_set_false:N \l_@@_closed_bool + } + % Restore the original copy of the path - \tl_set_eq:NN \l_@@_split_path_b_tl \l_@@_split_path_b_final_tl + \tl_set_eq:NN \l_@@_tmpe_tl \l_@@_tmpg_tl % Clear the token lists - \tl_clear:N \l_@@_split_path_b_start_tl - \tl_clear:N \l_@@_split_path_b_end_tl - \tl_clear:N \l_@@_split_path_b_final_tl + \tl_clear:N \l_@@_tmpf_tl + \tl_clear:N \l_@@_tmph_tl + \tl_clear:N \l_@@_tmpg_tl - \tl_set:Nn \l_@@_split_prev_first_tl {-1} + \tl_set:Nn \l_@@_tmpi_tl {-1} - \seq_map_inline:Nn \l_@@_split_first_seq + \seq_map_inline:Nn \l_@@_tmpb_seq { - \tl_set:Nn \l_@@_split_first_tl {##1} - \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_split_first_tl + \tl_set:Nn \l_@@_tmpb_tl {##1} + \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_tmpb_tl \int_compare:nT { - \fp_to_int:n {floor( \l_@@_split_first_tl ) } + \fp_to_int:n {floor( \l_@@_tmpb_tl ) } = - \fp_to_int:n {floor( \l_@@_split_prev_first_tl) } + \fp_to_int:n {floor( \l_@@_tmpi_tl) } } { - \tl_set:Nx \l_@@_split_first_tl + \tl_set:Nx \l_@@_tmpb_tl { \fp_eval:n { - floor( \l_@@_split_first_tl ) + floor( \l_@@_tmpb_tl ) + - ( \l_@@_split_first_tl - floor( \l_@@_split_first_tl) ) + ( \l_@@_tmpb_tl - floor( \l_@@_tmpb_tl) ) / - ( \l_@@_split_prev_first_tl - floor( \l_@@_split_prev_first_tl) ) + ( \l_@@_tmpi_tl - floor( \l_@@_tmpi_tl) ) } } } - \tl_set_eq:NN \l_@@_split_prev_first_tl \l_@@_tmpa_tl + \tl_set_eq:NN \l_@@_tmpi_tl \l_@@_tmpa_tl - \spath_split_at:NNVV \l_@@_split_path_b_start_tl \l_@@_split_path_b_end_tl \l_@@_split_path_b_tl \l_@@_split_first_tl + \spath_split_at:NNVV + \l_@@_tmpf_tl + \l_@@_tmph_tl + \l_@@_tmpe_tl + \l_@@_tmpb_tl - \tl_put_left:NV \l_@@_split_path_b_final_tl \l_@@_split_path_b_end_tl - \tl_set_eq:NN \l_@@_split_path_b_tl \l_@@_split_path_b_start_tl + \tl_put_left:NV \l_@@_tmpg_tl \l_@@_tmph_tl + \tl_set_eq:NN \l_@@_tmpe_tl \l_@@_tmpf_tl } - \tl_put_left:NV \l_@@_split_path_b_final_tl \l_@@_split_path_b_tl + \tl_put_left:NV \l_@@_tmpg_tl \l_@@_tmpe_tl - \tl_if_empty:NT \l_@@_split_path_b_final_tl + \tl_if_empty:NT \l_@@_tmpg_tl { - \tl_set_eq:NN \l_@@_split_path_b_final_tl \l_@@_split_path_b_tl + \tl_set_eq:NN \l_@@_tmpg_tl \l_@@_tmpe_tl } - \spath_remove_empty_components:N \l_@@_split_path_b_final_tl + \spath_remove_empty_components:N \l_@@_tmpg_tl + + % Do something with closed + \bool_if:NT \l_@@_closed_bool + { + \spath_join_component:Nn \l_@@_tmpg_tl {1} + } \tl_gclear:N \g_@@_output_tl - \tl_gset_eq:NN \g_@@_output_tl \l_@@_split_path_b_final_tl + \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpg_tl + \group_end: +} +\cs_new_protected_nopar:Npn \spath_split_component_at_self_intersections:Nn #1#2 +{ + \@@_split_component_at_self_intersections:n {#2} + \tl_set_eq:NN #1 \g_@@_output_tl + \tl_gclear:N \g_@@_output_tl +} +\cs_generate_variant:Nn \spath_split_component_at_self_intersections:Nn {NV} +\cs_new_protected_nopar:Npn \spath_split_component_at_self_intersections:N #1 +{ + \spath_split_component_at_self_intersections:NV #1#1 +} +\cs_generate_variant:Nn \spath_split_component_at_self_intersections:N {c} +\cs_new_protected_nopar:Npn \spath_gsplit_component_at_self_intersections:Nn #1#2 +{ + \@@_split_component_at_self_intersections:n {#2} + \tl_gset_eq:NN #1 \g_@@_output_tl + \tl_gclear:N \g_@@_output_tl +} +\cs_generate_variant:Nn \spath_gsplit_component_at_self_intersections:Nn {NV} +\cs_new_protected_nopar:Npn \spath_gsplit_component_at_self_intersections:N #1 +{ + \spath_gsplit_component_at_self_intersections:NV #1#1 +} +\cs_generate_variant:Nn \spath_gsplit_component_at_self_intersections:N {c} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{ +% \spath_split_at_self_intersections:Nn, +% \spath_split_at_self_intersections:N, +% \spath_gsplit_at_self_intersections:Nn, +% \spath_gsplit_at_self_intersections:N, +% } +% Split a path at its self intersections. +% We iterate over the components, splitting each where it meets all the others and itself. +% To make this more efficient, we split against the components of the original path rather than updating each time. +% +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_split_at_self_intersections:n #1 +{ + \group_begin: + \spath_components_to_seq:Nn \l_@@_tmpa_seq {#1} + \seq_clear:N \l_@@_tmpb_seq + \seq_clear:N \l_@@_tmpc_seq + + % Iterate over the components of the original path. + \bool_do_until:nn + { + \seq_if_empty_p:N \l_@@_tmpa_seq + } + { + % Get the next component + \seq_pop_left:NN \l_@@_tmpa_seq \l_@@_tmpa_tl + % Copy for later + \tl_set_eq:NN \l_@@_tmpc_tl \l_@@_tmpa_tl + \int_compare:nT + { + \tl_count:N \l_@@_tmpa_tl > 3 + } + { + + % Split against itself + \spath_split_component_at_self_intersections:N \l_@@_tmpa_tl + % Grab the rest of the path + \tl_set:Nx \l_@@_tmpb_tl + { + \seq_use:Nn \l_@@_tmpb_seq {} + \seq_use:Nn \l_@@_tmpa_seq {} + } + % Split against the rest of the path + \spath_split_path_at_intersections:NV \l_@@_tmpa_tl \l_@@_tmpb_tl + } + % Save the split path + \seq_put_right:NV \l_@@_tmpc_seq \l_@@_tmpa_tl + % Add the original copy to the sequence of processed components + \seq_put_right:NV \l_@@_tmpb_seq \l_@@_tmpc_tl + } + + \tl_gclear:N \g_@@_output_tl + \tl_gset:Nx \g_@@_output_tl {\seq_use:Nn \l_@@_tmpc_seq {} } \group_end: } +\cs_generate_variant:Nn \@@_split_at_self_intersections:n {V, v} \cs_new_protected_nopar:Npn \spath_split_at_self_intersections:Nn #1#2 { \@@_split_at_self_intersections:n {#2} \tl_set_eq:NN #1 \g_@@_output_tl \tl_gclear:N \g_@@_output_tl } -\cs_generate_variant:Nn \spath_split_at_self_intersections:Nn {NV} +\cs_generate_variant:Nn \spath_split_at_self_intersections:Nn {NV, cn, cV, cv} \cs_new_protected_nopar:Npn \spath_split_at_self_intersections:N #1 { \spath_split_at_self_intersections:NV #1#1 @@ -3435,7 +4293,7 @@ manipulating PGF soft paths} \tl_gset_eq:NN #1 \g_@@_output_tl \tl_gclear:N \g_@@_output_tl } -\cs_generate_variant:Nn \spath_gsplit_at_self_intersections:Nn {NV} +\cs_generate_variant:Nn \spath_gsplit_at_self_intersections:Nn {NV, cn, cV, cv} \cs_new_protected_nopar:Npn \spath_gsplit_at_self_intersections:N #1 { \spath_gsplit_at_self_intersections:NV #1#1 @@ -3444,8 +4302,7 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_join_component:Nnn, % \spath_join_component:Nn, % \spath_gjoin_component:Nnn, @@ -3453,58 +4310,76 @@ manipulating PGF soft paths} % } % Join the specified component of the spath to its predecessor. % \begin{macrocode} -\tl_new:N \l_@@_tmpj_tl \cs_new_protected_nopar:Npn \@@_join_component:nn #1#2 { \group_begin: - \spath_components_to_seq:Nn \l_@@_tmpa_seq {#1} - \int_compare:nT - { - #2 == 1 - } - { - \tl_clear:N \l_@@_tmpj_tl - \seq_pop_left:NN \l_@@_tmpa_seq \l_@@_tmpj_tl - - \prg_replicate:nn {3} - { - \tl_set:Nx \l_@@_tmpj_tl {\tl_tail:N \l_@@_tmpj_tl} - } + \spath_numberofcomponents:Nn \l_@@_tmpa_int {#1} - \seq_put_right:NV \l_@@_tmpb_seq \l_@@_tmpj_tl - } - \bool_if:nT + \bool_if:nTF { - \int_compare_p:n - { - #2 > 1 - } + \int_compare_p:n { #2 >= 1 } && - \int_compare_p:n - { - #2 <= \seq_count:N \l_@@_tmpa_seq - } + \int_compare_p:n { #2 <= \l_@@_tmpa_int } } { - - \seq_clear:N \l_@@_tmpb_seq - \seq_map_indexed_inline:Nn \l_@@_tmpa_seq + \int_compare:nTF + { + #2 == 1 + } { - \tl_set:Nn \l_@@_tmpj_tl {##2} - \int_compare:nT {##1 = #2} + \int_compare:nTF + { + \l_@@_tmpa_int == 1 + } { + \tl_set:Nn \l_@@_tmpa_tl {#1} + \spath_initialpoint:Nn \l_@@_tmpb_tl {#1} + \tl_put_right:NV \l_@@_tmpa_tl \c_spath_closepath_tl + \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpb_tl + \tl_gclear:N \g_@@_output_tl + \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpa_tl + } + { + \spath_components_to_seq:Nn \l_@@_tmpa_seq {#1} + \seq_pop_left:NN \l_@@_tmpa_seq \l_@@_tmpa_tl + \prg_replicate:nn {3} { - \tl_set:Nx \l_@@_tmpj_tl {\tl_tail:N \l_@@_tmpj_tl} + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} } + + \seq_put_right:NV \l_@@_tmpa_seq \l_@@_tmpa_tl + + \tl_gclear:N \g_@@_output_tl + \tl_gset:Nx \g_@@_output_tl {\seq_use:Nn \l_@@_tmpa_seq {}} } - \seq_put_right:NV \l_@@_tmpb_seq \l_@@_tmpj_tl } + { + \spath_components_to_seq:Nn \l_@@_tmpa_seq {#1} + + \seq_clear:N \l_@@_tmpb_seq + \seq_map_indexed_inline:Nn \l_@@_tmpa_seq + { + \tl_set:Nn \l_@@_tmpa_tl {##2} + \int_compare:nT {##1 = #2} + { + \prg_replicate:nn {3} + { + \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl} + } + } + \seq_put_right:NV \l_@@_tmpb_seq \l_@@_tmpa_tl + } - \seq_set_eq:NN \l_@@_tmpa_seq \l_@@_tmpb_seq + \tl_gclear:N \g_@@_output_tl + \tl_gset:Nx \g_@@_output_tl {\seq_use:Nn \l_@@_tmpb_seq {}} + } + } + { + \tl_gclear:N \g_@@_output_tl + \tl_gset:Nn \g_@@_output_tl {#1} } - \tl_gset:Nx \g_@@_output_tl {\seq_use:Nn \l_@@_tmpa_seq {} } \group_end: } \cs_new_protected_nopar:Npn \spath_join_component:Nnn #1#2#3 @@ -3534,7 +4409,7 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_spot_weld_components:Nn, % \spath_spot_weld_components:N, % \spath_spot_gweld_components:Nn, @@ -3562,12 +4437,16 @@ manipulating PGF soft paths} { \dim_compare_p:n { - \dim_abs:n {\l_@@_move_x_dim - \tl_item:Nn \l_@@_tmpa_tl {2} } < 0.01pt + \dim_abs:n + {\l_@@_move_x_dim - \tl_item:Nn \l_@@_tmpa_tl {2} } + < 0.01pt } && \dim_compare_p:n { - \dim_abs:n {\l_@@_move_y_dim - \tl_item:Nn \l_@@_tmpa_tl {3} } < 0.01pt + \dim_abs:n + {\l_@@_move_y_dim - \tl_item:Nn \l_@@_tmpa_tl {3} } + < 0.01pt } } { @@ -3595,12 +4474,22 @@ manipulating PGF soft paths} { \dim_compare_p:n { - \dim_abs:n {\tl_item:Nn \l_@@_tmpa_tl {1} - \tl_item:Nn \l_@@_tmpb_tl {1} } < 0.01pt + \dim_abs:n + { + \tl_item:Nn \l_@@_tmpa_tl {1} - \tl_item:Nn \l_@@_tmpb_tl {1} + } + < + 0.01pt } && \dim_compare_p:n { - \dim_abs:n {\tl_item:Nn \l_@@_tmpa_tl {2} - \tl_item:Nn \l_@@_tmpb_tl {2} } < 0.01pt + \dim_abs:n + { + \tl_item:Nn \l_@@_tmpa_tl {2} - \tl_item:Nn \l_@@_tmpb_tl {2} + } + < + 0.01pt } } { @@ -3660,7 +4549,7 @@ manipulating PGF soft paths} % % \subsection{Exporting Commands} % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_convert_to_svg:Nn, % \spath_gconvert_to_svg:Nn, % } @@ -3679,7 +4568,7 @@ manipulating PGF soft paths} \iow_newline: <svg~ xmlns="http://www.w3.org/2000/svg"~ version="1.1"~viewBox=" } - + \spath_minbb:Nn \l_@@_tmpb_tl {#1} \spath_maxbb:Nn \l_@@_tmpc_tl {#1} \tl_put_right:Nx \l_@@_tmpa_tl @@ -3718,7 +4607,7 @@ manipulating PGF soft paths} <path~ d=" } \tl_set:Nn \l_@@_tmpc_tl {use:n} - \tl_map_inline:Nn #1 + \tl_map_inline:nn {#1} { \tl_set:Nn \l_@@_tmpb_tl {##1} \tl_case:NnF \l_@@_tmpb_tl @@ -3751,7 +4640,9 @@ manipulating PGF soft paths} } } { - \tl_put_right:Nx \l_@@_tmpa_tl {\use:c { \l_@@_tmpc_tl } {\dim_to_decimal:n {##1}} ~} + \tl_put_right:Nx + \l_@@_tmpa_tl + {\use:c { \l_@@_tmpc_tl } {\dim_to_decimal:n {##1}} ~} } } \tl_put_right:Nn \l_@@_tmpa_tl @@ -3779,7 +4670,7 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_export_to_svg:nn % } % Save a soft path to an SVG file. @@ -3787,18 +4678,21 @@ manipulating PGF soft paths} \iow_new:N \g_@@_stream \cs_new_protected_nopar:Npn \spath_export_to_svg:nn #1#2 { - \spath_convert_path_to_svg:Nn \l_@@_iterp_tl {#2} + \group_begin: + \spath_convert_to_svg:Nn \l_@@_tmpa_tl {#2} \iow_open:Nn \g_@@_stream {#1 .svg} \iow_now:Nx \g_@@_stream { - \tl_use:N \l_@@_iterp_tl + \tl_use:N \l_@@_tmpa_tl } \iow_close:N \g_@@_stream + \group_end: } +\cs_generate_variant:Nn \spath_export_to_svg:nn {nv, nV} % \end{macrocode} % \end{macro} % -% \begin{macro}{\spath_show:n} +% \begin{macro}[internal]{\spath_show:n} % Displays the soft path on the terminal. % \begin{macrocode} \cs_new_protected_nopar:Npn \spath_show:n #1 @@ -3806,9 +4700,9 @@ manipulating PGF soft paths} \int_step_inline:nnnn {1} {3} {\tl_count:n {#1}} { \iow_term:x { - \tl_item:Nn \l_@@_tmpa_tl {##1} - {\tl_item:Nn \l_@@_tmpa_tl {##1+1}} - {\tl_item:Nn \l_@@_tmpa_tl {##1+2}} + \tl_item:nn {#1} {##1} + {\tl_item:nn {#1} {##1+1}} + {\tl_item:nn {#1} {##1+2}} } } } @@ -3820,7 +4714,7 @@ manipulating PGF soft paths} % % Spaths come from PGF so we need some functions that get and set spaths from the pgf system. % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_get_current_path:N, % \spath_gget_current_path:N % } @@ -3841,7 +4735,7 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{\spath_protocol_path:n} +% \begin{macro}[internal]{\spath_protocol_path:n} % This feeds the bounding box of the soft path to PGF to ensure that its current bounding box contains the soft path. % \begin{macrocode} \cs_new_protected_nopar:Npn \spath_protocol_path:n #1 @@ -3856,7 +4750,7 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_set_current_path:n, % \spath_set_current_path:N % } @@ -3877,7 +4771,7 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[internal]{ % \spath_use_path:nn % } % Uses the given soft path at the PGF level. @@ -3890,7 +4784,7 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{\spath_tikz_path:nn} +% \begin{macro}[internal]{\spath_tikz_path:nn} % Uses the given soft path at the TikZ level. % \begin{macrocode} \cs_new_protected_nopar:Npn \spath_tikz_path:nn #1#2 @@ -3904,22 +4798,99 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % -% \begin{macro}{\spath_set_tikz_coords:n} +% \begin{macro}[internal]{\spath_set_tikz_data:n} % Sets the \Verb+\tikz@lastx+ and other coordinates from the soft path. % \begin{macrocode} -\cs_new_protected_nopar:Npn \spath_set_tikz_coords:n #1 +\cs_new_protected_nopar:Npn \spath_set_tikz_data:n #1 { \spath_finalpoint:Nn \l_@@_tmpa_tl {#1} \tl_set:Nx \l_@@_tmpa_tl { - \exp_not:c {tikz@lastx}=\tl_item:Nn \l_@@_tmpa_tl {1} - \exp_not:c {tikz@lasty}=\tl_item:Nn \l_@@_tmpa_tl {2} - \exp_not:c {tikz@lastxsaved}=\tl_item:Nn \l_@@_tmpa_tl {1} - \exp_not:c {tikz@lastysaved}=\tl_item:Nn \l_@@_tmpa_tl {2} + \exp_not:c {pgf@x}=\tl_item:Nn \l_@@_tmpa_tl {1} + \exp_not:c {pgf@y}=\tl_item:Nn \l_@@_tmpa_tl {2} + } + \use:c {pgf@process}{% + \tl_use:N \l_@@_tmpa_tl + \pgftransforminvert + \use:c {pgf@pos@transform@glob} + } + \tl_set:Nx \l_@@_tmpa_tl + { + \exp_not:c {tikz@lastx}=\exp_not:c {pgf@x} + \exp_not:c {tikz@lasty}=\exp_not:c {pgf@y} + \exp_not:c {tikz@lastxsaved}=\exp_not:c {pgf@x} + \exp_not:c {tikz@lastysaved}=\exp_not:c {pgf@y} } \tl_use:N \l_@@_tmpa_tl + \spath_finalmovepoint:Nn \l_@@_tmpa_tl {#1} + \ifpgfsyssoftpathmovetorelevant% + \tl_gset_eq:cN {pgfsyssoftpath@lastmoveto} \l_@@_tmpa_tl + \fi + \tl_set:Nx \l_@@_tmpa_tl + { + \exp_not:c {pgf@x}=\tl_item:Nn \l_@@_tmpa_tl {1} + \exp_not:c {pgf@y}=\tl_item:Nn \l_@@_tmpa_tl {2} + } + \use:c {pgf@process}{% + \tl_use:N \l_@@_tmpa_tl + \pgftransforminvert + \use:c {pgf@pos@transform@glob} + } + \tl_set:Nx \l_@@_tmpa_tl + { + \exp_not:c {tikz@lastmovetox}=\exp_not:c {pgf@x} + \exp_not:c {tikz@lastmovetoy}=\exp_not:c {pgf@y} + } + \tl_use:N \l_@@_tmpa_tl + \tl_clear_new:c {tikz@timer} + \tl_set:cn {tikz@timer} + { + \spath_reallength:Nn \l_@@_tmpa_int {#1} + \tl_set_eq:Nc \l_@@_tmpb_tl {tikz@time} + \tl_set:Nx \l_@@_tmpb_tl + {\fp_to_decimal:n {(\l_@@_tmpb_tl) * (\l_@@_tmpa_int)}} + \spath_transformation_at:NnV \l_@@_tmpc_tl {#1} \l_@@_tmpb_tl + + \tl_set:Nx \l_@@_tmpa_tl + { + \exp_not:N \pgfpoint + { \tl_item:Nn \l_@@_tmpc_tl {5} } + { \tl_item:Nn \l_@@_tmpc_tl {6} } + } + \exp_args:NV \pgftransformshift \l_@@_tmpa_tl + + \ifpgfresetnontranslationattime + \pgftransformresetnontranslations + \fi + + \ifpgfslopedattime + + \tl_set:Nx \l_@@_tmpa_tl + { + { \tl_item:Nn \l_@@_tmpc_tl {1} } + { \tl_item:Nn \l_@@_tmpc_tl {2} } + { \tl_item:Nn \l_@@_tmpc_tl {3} } + { \tl_item:Nn \l_@@_tmpc_tl {4} } + } + \ifpgfallowupsidedownattime + \else + \fp_compare:nT { \tl_item:Nn \l_@@_tmpc_tl {4} < 0} + { + \tl_set:Nx \l_@@_tmpa_tl + { + { \fp_eval:n { - (\tl_item:Nn \l_@@_tmpc_tl {1})} } + { \fp_eval:n { - (\tl_item:Nn \l_@@_tmpc_tl {2})} } + { \fp_eval:n { - (\tl_item:Nn \l_@@_tmpc_tl {3})} } + { \fp_eval:n { - (\tl_item:Nn \l_@@_tmpc_tl {4})} } + } + } + \fi + \tl_put_right:Nn \l_@@_tmpa_tl {{\pgfpointorigin}} + \exp_last_unbraced:NV \pgftransformcm \l_@@_tmpa_tl + \fi + } } -\cs_generate_variant:Nn \spath_set_tikz_coords:n {V, v} +\cs_generate_variant:Nn \spath_set_tikz_data:n {V, v} % \end{macrocode} % \end{macro} % @@ -3952,6 +4923,13 @@ manipulating PGF soft paths} \bool_new:N \l_@@_draft_bool % \end{macrocode} % +% We surround all the keys with checks to ensure that the soft path under consideration does actually exist, but if it doesn't we should warn the user. +% +% \begin{macrocode} +\msg_new:nnn { spath3 } { missing soft path } { Soft~ path~ #1~ doesn't~ exist } +\msg_new:nnn { spath3 } { empty soft path } { Soft~ path~ #1~ is~ empty } +% \end{macrocode} +% % When saving a soft path, by default we use a naming convention that is compatible with the intersections library so that paths saved here and paths saved by the \texttt{name path} facility of the intersections library are mutually exchangeable. % % \begin{macrocode} @@ -3991,6 +4969,34 @@ manipulating PGF soft paths} \cs_generate_variant:Nn \spath_gsave_path:Nn {cn, NV, cV} % \end{macrocode} % +% \begin{macro}[internal]{ +% \@@_process_tikz_point:Nn +% } +% Process a point via TikZ and store the resulting dimensions. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_process_tikz_point:Nn #1#2 +{ + \group_begin: + \use:c {tikz@scan@one@point} \use:n #2 \scan_stop: + \tl_gset:Nx \g_@@_output_tl + { + { \dim_use:c {pgf@x} } + { \dim_use:c {pgf@y} } + } + \group_end: + \tl_set_eq:NN #1 \g_@@_output_tl + \tl_gclear:N \g_@@_output_tl +} +% \end{macrocode} +% \end{macro} +% +% When we split a soft path into components, we make it a comma separated list so that it can be fed into a \Verb+\foreach+ loop. +% This can also make it possible to extract a single component, but to do this we need a wrapper around \Verb+\clist_item:Nn+ (there doesn't appear to be a PGF way of getting an item of a CS list). +% +% \begin{macrocode} +\cs_set_eq:NN \getComponentOf \clist_item:Nn +% \end{macrocode} +% % Now we define all of our keys. % % \begin{macrocode} @@ -4031,11 +5037,14 @@ manipulating PGF soft paths} \tikz@addmode{ \spath_get_current_path:N \l_@@_tmpa_tl \spath_bake_round:NV \l_@@_tmpa_tl \l_@@_tmpa_tl - \spath_save_path:cV {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} \l_@@_tmpa_tl + \spath_save_path:cV + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \l_@@_tmpa_tl } }, clone/.code~ 2~ args={ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} { \tl_clear_new:c {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} @@ -4043,9 +5052,13 @@ manipulating PGF soft paths} {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } }, clone~ global/.code~ 2~ args={ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} { \tl_gclear_new:c {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} @@ -4053,6 +5066,9 @@ manipulating PGF soft paths} {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } }, save~ global/.code={ \tikz@addmode{ @@ -4069,11 +5085,15 @@ manipulating PGF soft paths} % % \begin{macrocode} save~ to~ aux/.code={ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { \spath_save_to_aux:c {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, % \end{macrocode} % @@ -4081,12 +5101,69 @@ manipulating PGF soft paths} % % \begin{macrocode} restore/.code={ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { - \spath_set_current_path:c + \tl_if_empty:cTF {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} - \spath_set_tikz_coords:v + { + \tl_clear:N \l_@@_tmpa_tl + \tl_put_right:NV \l_@@_tmpa_tl \c_spath_moveto_tl + \tl_put_right:Nn \l_@@_tmpa_tl {{0pt}{0pt}} + \spath_set_current_path:V \l_@@_tmpa_tl + \spath_set_tikz_data:V \l_@@_tmpa_tl + \msg_warning:nnn { spath3 } { empty soft path } { #1 } + } + { + \spath_set_current_path:c + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \spath_set_tikz_data:v + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + } + } + { + \tl_clear:N \l_@@_tmpa_tl + \tl_put_right:NV \l_@@_tmpa_tl \c_spath_moveto_tl + \tl_put_right:Nn \l_@@_tmpa_tl {{0pt}{0pt}} + \spath_set_current_path:V \l_@@_tmpa_tl + \spath_set_tikz_data:V \l_@@_tmpa_tl + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, +% \end{macrocode} +% +% Restores the reverse of a soft path to the current path. +% +% \begin{macrocode} + restore~ reverse/.code={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \tl_if_empty:cTF {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \tl_clear:N \l_@@_tmpa_tl + \tl_put_right:NV \l_@@_tmpa_tl \c_spath_moveto_tl + \tl_put_right:Nn \l_@@_tmpa_tl {{0pt}{0pt}} + \spath_set_current_path:V \l_@@_tmpa_tl + \spath_set_tikz_data:V \l_@@_tmpa_tl + \msg_warning:nnn { spath3 } { empty soft path } { #1 } + } + { + \spath_reverse:Nv + \l_@@_reverse_tl + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \spath_set_current_path:N \l_@@_reverse_tl + \spath_set_tikz_data:V \l_@@_reverse_tl + } + } + { + \tl_clear:N \l_@@_tmpa_tl + \tl_put_right:NV \l_@@_tmpa_tl \c_spath_moveto_tl + \tl_put_right:Nn \l_@@_tmpa_tl {{0pt}{0pt}} + \spath_set_current_path:V \l_@@_tmpa_tl + \spath_set_tikz_data:V \l_@@_tmpa_tl + \msg_warning:nnn { spath3 } { missing soft path } { #1 } } }, % \end{macrocode} @@ -4107,10 +5184,22 @@ manipulating PGF soft paths} % % \begin{macrocode} show/.code={ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \tl_if_empty:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \msg_warning:nnn { spath3 } { empty soft path } { #1 } + } + { + \iow_term:n {---~ soft~ path~ #1~ ---} + \spath_show:v + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + } + } { - \iow_term:n {---~ soft~ path~ #1~ ---} - \spath_show:v {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \msg_warning:nnn { spath3 } { missing soft path } { #1 } } }, % \end{macrocode} @@ -4119,14 +5208,21 @@ manipulating PGF soft paths} % % \begin{macrocode} append/.code={ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { \spath_get_current_path:N \l_@@_current_tl - \spath_weld:Nv - \l_@@_current_tl + \spath_finalpoint:NV \l_@@_tmpa_tl \l_@@_current_tl + \tl_set_eq:Nc + \l_@@_tmpb_tl {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \spath_translate_to:NV \l_@@_tmpb_tl \l_@@_tmpa_tl + \spath_append_no_move:NV \l_@@_current_tl \l_@@_tmpb_tl \spath_set_current_path:N \l_@@_current_tl - \spath_set_tikz_coords:V \l_@@_current_tl + \spath_set_tikz_data:V \l_@@_tmpb_tl + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } } }, % \end{macrocode} @@ -4135,14 +5231,22 @@ manipulating PGF soft paths} % % \begin{macrocode} join~ with/.code~ 2~ args={ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} { \spath_append:cv {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } } }, % \end{macrocode} @@ -4151,11 +5255,26 @@ manipulating PGF soft paths} % % \begin{macrocode} spot~ weld/.code={ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { \spath_spot_weld_components:c {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + spot~ weld~ globally/.code={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \spath_spot_gweld_components:c + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, % \end{macrocode} % @@ -4163,11 +5282,26 @@ manipulating PGF soft paths} % % \begin{macrocode} reverse/.code={ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { \spath_reverse:c {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + reverse~ globally/.code={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \spath_reverse:c + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, % \end{macrocode} % @@ -4175,15 +5309,21 @@ manipulating PGF soft paths} % % \begin{macrocode} append~ reverse/.code={ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { \spath_reverse:Nv \l_@@_reverse_tl {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} \spath_get_current_path:N \l_@@_current_tl - \spath_weld:NV \l_@@_current_tl \l_@@_reverse_tl + \spath_finalpoint:NV \l_@@_tmpa_tl \l_@@_current_tl + \spath_translate_to:NV \l_@@_reverse_tl \l_@@_tmpa_tl + \spath_append_no_move:NV \l_@@_current_tl \l_@@_reverse_tl \spath_set_current_path:N \l_@@_current_tl - \spath_set_tikz_coords:V \l_@@_current_tl + \spath_set_tikz_data:V \l_@@_reverse_tl + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } } }, % \end{macrocode} @@ -4192,14 +5332,19 @@ manipulating PGF soft paths} % % \begin{macrocode} insert/.code={ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { \spath_get_current_path:N \l_@@_current_tl \spath_append:Nv \l_@@_current_tl {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} \spath_set_current_path:N \l_@@_current_tl - \spath_set_tikz_coords:V \l_@@_current_tl + \spath_set_tikz_data:v + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } } }, % \end{macrocode} @@ -4208,7 +5353,8 @@ manipulating PGF soft paths} % % \begin{macrocode} insert~ reverse/.code={ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { \spath_reverse:Nv \l_@@_reverse_tl @@ -4216,7 +5362,301 @@ manipulating PGF soft paths} \spath_get_current_path:N \l_@@_current_tl \spath_append:NV \l_@@_current_tl \l_@@_reverse_tl \spath_set_current_path:N \l_@@_current_tl - \spath_set_tikz_coords:V \l_@@_current_tl + \spath_set_tikz_data:V \l_@@_reverse_tl + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, +% \end{macrocode} +% +% Appends the named path to the current path without translating it. +% +% \begin{macrocode} + append~ no~ move/.code={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \spath_get_current_path:N \l_@@_current_tl + \spath_append_no_move:Nv + \l_@@_current_tl + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \spath_set_current_path:N \l_@@_current_tl + \spath_set_tikz_data:v + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, +% \end{macrocode} +% +% Appends the reverse of the named path without translating it. +% +% \begin{macrocode} + append~ reverse~ no~ move/.code={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \spath_reverse:Nv + \l_@@_reverse_tl + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \spath_get_current_path:N \l_@@_current_tl + \spath_append_no_move:NV \l_@@_current_tl \l_@@_reverse_tl + \spath_set_current_path:N \l_@@_current_tl + \spath_set_tikz_data:V \l_@@_reverse_tl + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, +% \end{macrocode} +% +% Adjust a path to span between two points. +% +% \begin{macrocode} + span/.code ~n~ args={3}{ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \@@_process_tikz_point:Nn \l_@@_tmpa_tl {#2} + \@@_process_tikz_point:Nn \l_@@_tmpb_tl {#3} + \spath_span:cVV + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \l_@@_tmpa_tl \l_@@_tmpb_tl + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + span~ global/.code ~n~ args={3}{ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \@@_process_tikz_point:Nn \l_@@_tmpa_tl {#2} + \@@_process_tikz_point:Nn \l_@@_tmpb_tl {#3} + \spath_gspan:cVV + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \l_@@_tmpa_tl \l_@@_tmpb_tl + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, +% \end{macrocode} +% +% Defines a to path +% +% \begin{macrocode} + to/.style={ + to~path={ + [ + spath/span={#1}{(\tikztostart)}{(\tikztotarget)}, + spath/append~no~move={#1}, + ] + \tikztonodes + } + }, +% \end{macrocode} +% +% Splice three paths together, transforming the middle one so that it exactly fits between the first and third. +% +% \begin{macrocode} + splice/.code ~n~ args={3}{ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + { + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #3 \tl_use:N \l_@@_suffix_tl} + { + \spath_splice_between:cvv + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + {\tl_use:N \l_@@_prefix_tl #3 \tl_use:N \l_@@_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #3 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + splice~ global/.code ~n~ args={3}{ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + { + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #3 \tl_use:N \l_@@_suffix_tl} + { + \spath_gsplice_between:cvv + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + {\tl_use:N \l_@@_prefix_tl #3 \tl_use:N \l_@@_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #3 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, +% \end{macrocode} +% +% Join the components of a path by splicing in the second path whenever the components are sufficiently far apart. +% +% \begin{macrocode} + join~ components~ with/.code~2~args={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + { + \spath_spot_weld_components:c + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + + \spath_components_to_seq:Nv + \l_@@_tmpa_seq + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + + \seq_pop_left:NN \l_@@_tmpa_seq \l_@@_tmpa_tl + + \seq_map_inline:Nn \l_@@_tmpa_seq + { + \spath_splice_between:Nvn \l_@@_tmpa_tl + {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + {##1} + } + \tl_set_eq:cN + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \l_@@_tmpa_tl + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + join~ components~ globally~ with/.code~2~args={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + { + \spath_spot_gweld_components:c + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + + \spath_components_to_seq:Nv + \l_@@_tmpa_seq + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + + \seq_pop_left:NN \l_@@_tmpa_seq \l_@@_tmpa_tl + + \seq_map_inline:Nn \l_@@_tmpa_seq + { + \spath_gsplice_between:Nvn \l_@@_tmpa_tl + {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + {##1} + } + \tl_set_eq:cN + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \l_@@_tmpa_tl + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, +% \end{macrocode} +% +% Close a path. +% +% \begin{macrocode} + close/.code={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \spath_close:c + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + close~ globally/.code={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \spath_gclose:c + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, +% \end{macrocode} +% +% Close a path with another path. +% +% \begin{macrocode} + close~ with/.code~ 2~ args={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + { + \spath_close_with:cv + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + close~ globally~ with/.code~ 2~ args={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + { + \spath_gclose_with:cv + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } } }, % \end{macrocode} @@ -4225,27 +5665,74 @@ manipulating PGF soft paths} % % \begin{macrocode} shorten~ at~ end/.code~ 2~ args={ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { \spath_shorten_at_end:cn {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} {#2} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, shorten~ at~ start/.code~ 2~ args ={ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { \spath_shorten_at_start:cn {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} {#2} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, shorten~ at~ both~ ends/.code~ 2~ args={ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { \spath_shorten_at_end:cn {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} {#2} \spath_shorten_at_start:cn {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} {#2} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + shorten~ globally~ at~ end/.code~ 2~ args={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \spath_gshorten_at_end:cn + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} {#2} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + shorten~ globally~ at~ start/.code~ 2~ args ={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \spath_gshorten_at_start:cn + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} {#2} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + shorten~ globally~ at~ both~ ends/.code~ 2~ args={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \spath_shorten_at_end:cn + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} {#2} + \spath_shorten_at_start:cn + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} {#2} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, % \end{macrocode} % @@ -4253,11 +5740,53 @@ manipulating PGF soft paths} % % \begin{macrocode} translate/.code~ n~ args={3}{ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { \spath_translate:cnn {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}{#2}{#3} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + translate~ globally/.code~ n~ args={3}{ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \spath_gtranslate:cnn + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}{#2}{#3} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, +% \end{macrocode} +% +% This normalises the named path. +% +% \begin{macrocode} + normalise/.code={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \spath_normalise:c + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + normalise~ globally/.code={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \spath_gnormalise:c + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, % \end{macrocode} % @@ -4265,11 +5794,15 @@ manipulating PGF soft paths} % % \begin{macrocode} export~ to~ svg/.code={ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { - \spath_export_to_svg:c + \spath_export_to_svg:nv {#1} {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, % \end{macrocode} % @@ -4277,7 +5810,8 @@ manipulating PGF soft paths} % % \begin{macrocode} transform/.code~ 2~ args={ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { \group_begin: \pgftransformreset @@ -4292,9 +5826,13 @@ manipulating PGF soft paths} \group_end: \tl_use:N \g_@@_smuggle_tl } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, - transform~global/.code~ 2~ args={ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + transform~globally/.code~ 2~ args={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { \group_begin: \pgftransformreset @@ -4309,6 +5847,52 @@ manipulating PGF soft paths} \group_end: \tl_use:N \g_@@_smuggle_tl } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, +% \end{macrocode} +% +% Splits first path where it intersects with the second. +% +% \begin{macrocode} + split~ at~ intersections~ with/.code~ n~ args={2}{ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + { + \spath_split_path_at_intersections:cv + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + split~ globally~ at~ intersections~ with/.code~ n~ args={2}{ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + { + \spath_gsplit_path_at_intersections:cv + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, % \end{macrocode} % @@ -4316,14 +5900,41 @@ manipulating PGF soft paths} % % \begin{macrocode} split~ at~ intersections/.code~ n~ args={2}{ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} { \spath_split_at_intersections:cc {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + split~ globally~ at~ intersections/.code~ n~ args={2}{ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + { + \spath_gsplit_at_intersections:cc + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } } }, % \end{macrocode} @@ -4332,11 +5943,26 @@ manipulating PGF soft paths} % % \begin{macrocode} split~ at~ self~ intersections/.code={ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { \spath_split_at_self_intersections:c {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + split~ globally~ at~ self~ intersections/.code={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \spath_gsplit_at_self_intersections:c + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, % \end{macrocode} % @@ -4344,7 +5970,8 @@ manipulating PGF soft paths} % % \begin{macrocode} get~ components~ of/.code~ 2~ args={ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { \clist_clear_new:N #2 \spath_components_to_seq:Nv @@ -4353,13 +5980,54 @@ manipulating PGF soft paths} \seq_map_inline:Nn \l_@@_tmpa_seq { \tl_new:c - {\tl_use:N \l_@@_prefix_tl anonymous_\int_use:N \g_@@_anon_int \tl_use:N \l_@@_suffix_tl} + { + \tl_use:N \l_@@_prefix_tl + anonymous_\int_use:N \g_@@_anon_int + \tl_use:N \l_@@_suffix_tl + } \tl_set:cn - {\tl_use:N \l_@@_prefix_tl anonymous_\int_use:N \g_@@_anon_int \tl_use:N \l_@@_suffix_tl} {##1} + { + \tl_use:N \l_@@_prefix_tl + anonymous_\int_use:N \g_@@_anon_int + \tl_use:N \l_@@_suffix_tl + } {##1} \clist_put_right:Nx #2 {anonymous_\int_use:N \g_@@_anon_int} \int_gincr:N \g_@@_anon_int } } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + get~ components~ of~ globally/.code~ 2~ args={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \clist_gclear_new:N #2 + \spath_components_to_seq:Nv + \l_@@_tmpa_seq + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \seq_map_inline:Nn \l_@@_tmpa_seq + { + \tl_new:c + { + \tl_use:N \l_@@_prefix_tl + anonymous_\int_use:N \g_@@_anon_int + \tl_use:N \l_@@_suffix_tl + } + \tl_gset:cn + { + \tl_use:N \l_@@_prefix_tl + anonymous_\int_use:N \g_@@_anon_int + \tl_use:N \l_@@_suffix_tl + } {##1} + \clist_gput_right:Nx #2 {anonymous_\int_use:N \g_@@_anon_int} + \int_gincr:N \g_@@_anon_int + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, % \end{macrocode} % @@ -4367,7 +6035,8 @@ manipulating PGF soft paths} % % \begin{macrocode} render~ components/.code={ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { \group_begin: \spath_components_to_seq:Nv @@ -4390,6 +6059,9 @@ manipulating PGF soft paths} } \group_end: } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, % \end{macrocode} % @@ -4398,15 +6070,24 @@ manipulating PGF soft paths} % % \begin{macrocode} insert~ gaps~ after~ components/.code~ n~ args={3}{ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { \group_begin: \seq_gclear:N \g_@@_tmpa_seq \seq_gclear:N \g_@@_tmpb_seq + \spath_numberofcomponents:Nv \l_@@_tmpa_int + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} \foreach \l_@@_tmpa_tl in {#3} { \seq_gput_right:NV \g_@@_tmpa_seq \l_@@_tmpa_tl - \seq_gput_right:Nx \g_@@_tmpb_seq {\int_eval:n { \l_@@_tmpa_tl + 1 }} + \seq_gput_right:Nx + \g_@@_tmpb_seq + {\int_eval:n + { + \int_mod:nn { \l_@@_tmpa_tl }{ \l_@@_tmpa_int } + 1 + } + } } \spath_components_to_seq:Nv \l_@@_tmpa_seq @@ -4432,6 +6113,58 @@ manipulating PGF soft paths} \g_@@_output_tl \tl_gclear:N \g_@@_output_tl } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + insert~ gaps~ globally~ after~ components/.code~ n~ args={3}{ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \group_begin: + \seq_gclear:N \g_@@_tmpa_seq + \seq_gclear:N \g_@@_tmpb_seq + \spath_numberofcomponents:Nv \l_@@_tmpa_int + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \foreach \l_@@_tmpa_tl in {#3} + { + \seq_gput_right:NV \g_@@_tmpa_seq \l_@@_tmpa_tl + \seq_gput_right:Nx + \g_@@_tmpb_seq + { + \int_eval:n + { + \int_mod:nn { \l_@@_tmpa_tl }{ \l_@@_tmpa_int } + 1 + } + } + } + \spath_components_to_seq:Nv + \l_@@_tmpa_seq + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \seq_clear:N \l_@@_tmpb_seq + \seq_map_indexed_inline:Nn \l_@@_tmpa_seq + { + \tl_set:Nn \l_@@_tmpa_tl {##2} + \seq_if_in:NnT \g_@@_tmpa_seq {##1} + { + \spath_shorten_at_end:Nn \l_@@_tmpa_tl {#2/2} + } + \seq_if_in:NnT \g_@@_tmpb_seq {##1} + { + \spath_shorten_at_start:Nn \l_@@_tmpa_tl {#2/2} + } + \seq_put_right:NV \l_@@_tmpb_seq \l_@@_tmpa_tl + } + \tl_gset:Nx \g_@@_output_tl {\seq_use:Nn \l_@@_tmpb_seq {} } + \group_end: + \tl_gset_eq:cN + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \g_@@_output_tl + \tl_gclear:N \g_@@_output_tl + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, % \end{macrocode} % @@ -4439,7 +6172,8 @@ manipulating PGF soft paths} % % \begin{macrocode} join~ components/.code~ 2~ args={ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { \seq_gclear:N \g_@@_tmpa_seq \foreach \l_@@_tmpa_tl in {#2} @@ -4458,6 +6192,34 @@ manipulating PGF soft paths} {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}{##1} } } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + join~ components~ globally/.code~ 2~ args={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \seq_gclear:N \g_@@_tmpa_seq + \foreach \l_@@_tmpa_tl in {#2} + { + \seq_gput_right:NV \g_@@_tmpa_seq \l_@@_tmpa_tl + } + \seq_gsort:Nn \g_@@_tmpa_seq + { + \int_compare:nNnTF {##1} > {##2} + { \sort_return_same: } + { \sort_return_swapped: } + } + \seq_map_inline:Nn \g_@@_tmpa_seq + { + \spath_gjoin_component:cn + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}{##1} + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, % \end{macrocode} % @@ -4465,14 +6227,123 @@ manipulating PGF soft paths} % % \begin{macrocode} remove~ empty~ components/.code={ - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { \spath_remove_empty_components:c {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + remove~ empty~ components~ globally/.code={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \spath_gremove_empty_components:c + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, % \end{macrocode} % +% +% Join the specified components together, joining each to its previous one. +% +% \begin{macrocode} + remove~ components/.code~ 2~ args={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \seq_gclear:N \g_@@_tmpa_seq + \foreach \l_@@_tmpa_tl in {#2} + { + \seq_gput_right:NV \g_@@_tmpa_seq \l_@@_tmpa_tl + } + \seq_gsort:Nn \g_@@_tmpa_seq + { + \int_compare:nNnTF {##1} < {##2} + { \sort_return_same: } + { \sort_return_swapped: } + } + \spath_components_to_seq:Nv + \l_@@_tmpa_seq + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \seq_gpop_left:NNF \g_@@_tmpa_seq \l_@@_tmpa_tl + { + \tl_clear:N \l_@@_tmpa_tl + } + \seq_clear:N \l_@@_tmpb_seq + \seq_map_indexed_inline:Nn \l_@@_tmpa_seq + { + \tl_set:Nn \l_@@_tmpb_tl {##1} + \tl_if_eq:NNTF \l_@@_tmpb_tl \l_@@_tmpa_tl + { + \seq_gpop_left:NNF \g_@@_tmpa_seq \l_@@_tmpa_tl + { + \tl_clear:N \l_@@_tmpa_tl + } + } + { + \seq_put_right:Nn \l_@@_tmpb_seq {##2} + } + } + \tl_set:cx {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + {\seq_use:Nn \l_@@_tmpb_seq {} } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + remove~ components~ globally/.code~ 2~ args={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \seq_gclear:N \g_@@_tmpa_seq + \foreach \l_@@_tmpa_tl in {#2} + { + \seq_gput_right:NV \g_@@_tmpa_seq \l_@@_tmpa_tl + } + \seq_gsort:Nn \g_@@_tmpa_seq + { + \int_compare:nNnTF {##1} < {##2} + { \sort_return_same: } + { \sort_return_swapped: } + } + \spath_components_to_seq:Nv + \l_@@_tmpa_seq + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \seq_gpop_left:NNF \g_@@_tmpa_seq \l_@@_tmpa_tl + { + \tl_clear:N \l_@@_tmpa_tl + } + \seq_clear:N \l_@@_tmpb_seq + \seq_map_indexed_inline:Nn \l_@@_tmpa_seq + { + \tl_set:Nn \l_@@_tmpb_tl {##1} + \tl_if_eq:NNTF \l_@@_tmpb_tl \l_@@_tmpa_tl + { + \seq_gpop_left:NNF \g_@@_tmpa_seq \l_@@_tmpa_tl + { + \tl_clear:N \l_@@_tmpa_tl + } + } + { + \seq_put_right:Nn \l_@@_tmpb_seq {##2} + } + } + \tl_gset:cx {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + {\seq_use:Nn \l_@@_tmpb_seq {} } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, +% \end{macrocode} +% % This puts a conditional around the \texttt{spot weld} key because when figuring out a knot drawing then we will initially want to render it without the spot weld to keep the number of components constant. % % \begin{macrocode} @@ -4486,11 +6357,29 @@ manipulating PGF soft paths} maybe~ spot~ weld/.code={ \bool_if:NF \l_@@_draft_bool { - \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { \spath_spot_weld_components:c {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + } + }, + maybe~ spot~ weld~ globally/.code={ + \bool_if:NF \l_@@_draft_bool + { + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \spath_spot_gweld_components:c + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } } }, % \end{macrocode} @@ -4527,6 +6416,7 @@ manipulating PGF soft paths} \tl_gset_eq:NN \g_@@_smuggle_tl \l_@@_tmpc_tl } { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } \tl_gset_eq:NN \g_@@_smuggle_tl { {1}{0}{0}{1}{0pt}{0pt} } } \group_end: @@ -4567,6 +6457,7 @@ manipulating PGF soft paths} \tl_gset_eq:NN \g_@@_smuggle_tl \l_@@_tmpc_tl } { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } \tl_gset_eq:NN \g_@@_smuggle_tl { {1}{0}{0}{1}{0pt}{0pt} } } \fp_compare:nT { \tl_item:Nn \g_@@_smuggle_tl {4} < 0} @@ -4591,11 +6482,18 @@ manipulating PGF soft paths} % % \begin{macrocode} knot/.style~ n~ args={3}{ - spath/.cd, - split~ at~ self~ intersections=#1, - insert~ gaps~ after~ components={#1}{#2}{#3}, - maybe~ spot~ weld=#1, - render~ components=#1 + spath/split~ at~ self~ intersections=#1, + spath/remove~ empty~ components=#1, + spath/insert~ gaps~ after~ components={#1}{#2}{#3}, + spath/maybe~ spot~ weld=#1, + spath/render~ components=#1 + }, + global~ knot/.style~ n~ args={3}{ + spath/split~ globally~ at~ self~ intersections=#1, + spath/remove~ empty~ components~ globally=#1, + spath/insert~ gaps~ globally ~after~ components={#1}{#2}{#3}, + spath/maybe~ spot~ weld~ globally=#1, + spath/render~ components=#1 }, } % \end{macrocode} @@ -4649,10 +6547,15 @@ manipulating PGF soft paths} } } { + \msg_warning:nnx { spath3 } { missing soft path } { \tl_use:N \l_@@_tmpa_tl } \tl_gset_eq:NN \g_@@_smuggle_tl \pgfpointorigin } - \group_end: + \group_end: + \use:c {pgf@process}{% \tl_use:N \g_@@_smuggle_tl + \pgftransforminvert + \use:c {pgf@pos@transform@glob} + } } \ExplSyntaxOff @@ -4733,7 +6636,8 @@ manipulating PGF soft paths} \pgfsyssoftpath@getcurrentpath\l_@@_tmpa_tl \spath_components_to_seq:NV \l_@@_tmpa_seq \l_@@_tmpa_tl \seq_gclear_new:c {g_@@_pen_\pgfkeysvalueof{/tikz/pen~name}_seq} - \seq_gset_eq:cN {g_@@_pen_\pgfkeysvalueof{/tikz/pen~name}_seq} \l_@@_tmpa_seq + \seq_gset_eq:cN + {g_@@_pen_\pgfkeysvalueof{/tikz/pen~name}_seq} \l_@@_tmpa_seq \pgfusepath{discard}% } }, @@ -4747,10 +6651,12 @@ manipulating PGF soft paths} \spath_components_to_seq:NV \l_@@_tmpa_seq \l_@@_tmpa_tl \tl_if_exist:cTF {g_@@_pen_\pgfkeysvalueof{/tikz/pen~name}_seq} { - \cal_path_create:Nc \l_@@_tmpa_seq {g_@@_pen_\pgfkeysvalueof{/tikz/pen~name}_seq} + \cal_path_create:Nc \l_@@_tmpa_seq + {g_@@_pen_\pgfkeysvalueof{/tikz/pen~name}_seq} } { - \msg_warning:nnx { calligraphy } { undefined pen } { \pgfkeysvalueof{/tikz/pen~name} } + \msg_warning:nnx { calligraphy } { undefined pen } + { \pgfkeysvalueof{/tikz/pen~name} } } } }, @@ -4823,8 +6729,10 @@ manipulating PGF soft paths} \tl_set:cn {l_@@_stroke_style_#1} {#2} }, this~stroke~style/.code={ - \tl_clear_new:c {l_@@_stroke_inline_style_ \int_use:N \g_@@_path_component_int} - \tl_set:cn {l_@@_stroke_inline_style_ \int_use:N \g_@@_path_component_int} {#1} + \tl_clear_new:c + {l_@@_stroke_inline_style_ \int_use:N \g_@@_path_component_int} + \tl_set:cn + {l_@@_stroke_inline_style_ \int_use:N \g_@@_path_component_int} {#1} }, annotate/.style={ annotate~if, @@ -4944,23 +6852,29 @@ manipulating PGF soft paths} \spath_weld:NV \l_@@_tmp_patha_tl \l_@@_tmp_rpathb_tl \tl_clear:N \l_@@_tmpa_tl - \tl_set:Nn \l_@@_tmpa_tl {fill=\pgfkeysvalueof{/tikz/pen~colour},draw=none} + \tl_set:Nn \l_@@_tmpa_tl + { + fill=\pgfkeysvalueof{/tikz/pen~colour}, + draw=none + } \tl_if_exist:cT {l_@@_stroke_style_ \int_use:N \l_@@_tmpa_int} { - \tl_put_right:Nv \l_@@_tmpa_tl {l_@@_stroke_style_ \int_use:N \l_@@_tmpa_int} + \tl_put_right:Nv \l_@@_tmpa_tl + {l_@@_stroke_style_ \int_use:N \l_@@_tmpa_int} } \tl_if_exist:cT {l_@@_stroke_inline_style_ \int_use:N \l_@@_tmpa_int} { \tl_put_right:Nn \l_@@_tmpa_tl {,} - \tl_put_right:Nv \l_@@_tmpa_tl {l_@@_stroke_inline_style_ \int_use:N \l_@@_tmpa_int} + \tl_put_right:Nv \l_@@_tmpa_tl + {l_@@_stroke_inline_style_ \int_use:N \l_@@_tmpa_int} } \tl_if_exist:cT {l_@@_nib_style_ \int_use:N \l_@@_tmpb_int} { \tl_put_right:Nn \l_@@_tmpa_tl {,} - \tl_put_right:Nv \l_@@_tmpa_tl {l_@@_nib_style_ \int_use:N \l_@@_tmpb_int} + \tl_put_right:Nv \l_@@_tmpa_tl + {l_@@_nib_style_ \int_use:N \l_@@_tmpb_int} } \spath_tikz_path:VV \l_@@_tmpa_tl \l_@@_tmp_patha_tl - } \pgfsys@endscope \group_end: @@ -4971,7 +6885,9 @@ manipulating PGF soft paths} \seq_get_right:NN #2 \l_@@_tmpa_tl \spath_finalpoint:NV \l_@@_tmpa_tl \l_@@_tmpa_tl \spath_translate:NV \l_@@_tmp_path_tl \l_@@_tmpa_tl - \tikz@scan@one@point\pgfutil@firstofone\pgfkeysvalueof{/tikz/annotation~shift} + \tikz@scan@one@point + \pgfutil@firstofone + \pgfkeysvalueof{/tikz/annotation~shift} \spath_translate:Nnn \l_@@_tmp_path_tl {\pgf@x} {\pgf@y} @@ -4982,7 +6898,10 @@ manipulating PGF soft paths} \exp_last_unbraced:NV \pgfqpoint \l_@@_tmpa_tl \begin{scope}[reset~ cm] - \node[every~annotation~node/.try,tl~use:c = {l_@@_annotation_style_ \int_use:N \l_@@_tmpa_int _tl}] at (\pgf@x,\pgf@y) {\int_use:N \l_@@_tmpa_int}; + \node[ + every~annotation~node/.try, + tl~use:c = {l_@@_annotation_style_ \int_use:N \l_@@_tmpa_int _tl} + ] at (\pgf@x,\pgf@y) {\int_use:N \l_@@_tmpa_int}; \end{scope} } } @@ -5191,8 +7110,18 @@ manipulating PGF soft paths} (\l_@@_tmpa_fp^2 + \l_@@_tmpb_fp^2)^.5 } - \fp_set:Nn \l_@@_tmpa_fp {.5*\l_@@_taper_width_dim * \l_@@_tmpa_fp / \l_@@_tmpe_fp} - \fp_set:Nn \l_@@_tmpb_fp {.5*\l_@@_taper_width_dim * \l_@@_tmpb_fp / \l_@@_tmpe_fp} + \fp_set:Nn \l_@@_tmpa_fp + { + .5*\l_@@_taper_width_dim + * + \l_@@_tmpa_fp / \l_@@_tmpe_fp + } + \fp_set:Nn \l_@@_tmpb_fp + { + .5*\l_@@_taper_width_dim + * + \l_@@_tmpb_fp / \l_@@_tmpe_fp + } \fp_set:Nn \l_@@_tmpc_fp { @@ -5207,13 +7136,23 @@ manipulating PGF soft paths} (\l_@@_tmpc_fp^2 + \l_@@_tmpd_fp^2)^.5 } - \fp_set:Nn \l_@@_tmpc_fp {.5*\l_@@_line_width_dim * \l_@@_tmpc_fp / \l_@@_tmpe_fp} - \fp_set:Nn \l_@@_tmpd_fp {.5*\l_@@_line_width_dim * \l_@@_tmpd_fp / \l_@@_tmpe_fp} + \fp_set:Nn \l_@@_tmpc_fp + { + .5*\l_@@_line_width_dim + * + \l_@@_tmpc_fp / \l_@@_tmpe_fp + } + \fp_set:Nn \l_@@_tmpd_fp + { + .5*\l_@@_line_width_dim + * + \l_@@_tmpd_fp / \l_@@_tmpe_fp + } \tl_put_right:Nx \l_@@_tmpb_tl { {\dim_eval:n { \fp_to_dim:N \l_@@_tmpa_fp + \l_@@_tmpa_dim}} - {\dim_eval:n { \fp_to_dim:N \l_@@_tmpb_fp + \l_@@_tmpb_dim}} + {\dim_eval:n { \fp_to_dim:N \l_@@_tmpb_fp + \l_@@_tmpb_dim}} } \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curvetoa_tl @@ -5244,16 +7183,44 @@ manipulating PGF soft paths} \tl_put_right:Nx \l_@@_tmpb_tl { - {\dim_eval:n { \fp_to_dim:N \l_@@_tmpc_fp + \l_@@_tmpg_dim - \fp_to_dim:n{ 1.32 * \l_@@_tmpd_fp}}} - {\dim_eval:n { \fp_to_dim:N \l_@@_tmpd_fp + \l_@@_tmph_dim + \fp_to_dim:n {1.32* \l_@@_tmpc_fp}}} + { + \dim_eval:n + { + \fp_to_dim:N \l_@@_tmpc_fp + \l_@@_tmpg_dim + - \fp_to_dim:n{ 1.32 * \l_@@_tmpd_fp + } + } + } + { + \dim_eval:n + { + \fp_to_dim:N \l_@@_tmpd_fp + \l_@@_tmph_dim + + \fp_to_dim:n {1.32* \l_@@_tmpc_fp + } + } + } } \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curvetob_tl \tl_put_right:Nx \l_@@_tmpb_tl { - {\dim_eval:n { -\fp_to_dim:N \l_@@_tmpc_fp + \l_@@_tmpg_dim - \fp_to_dim:n {1.32 * \l_@@_tmpd_fp}}} - {\dim_eval:n { -\fp_to_dim:N \l_@@_tmpd_fp + \l_@@_tmph_dim + \fp_to_dim:n {1.32 * \l_@@_tmpc_fp}}} + { + \dim_eval:n + { + -\fp_to_dim:N \l_@@_tmpc_fp + \l_@@_tmpg_dim + - \fp_to_dim:n {1.32 * \l_@@_tmpd_fp + } + } + } + { + \dim_eval:n + { + -\fp_to_dim:N \l_@@_tmpd_fp + \l_@@_tmph_dim + + \fp_to_dim:n {1.32 * \l_@@_tmpc_fp + } + } + } } \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curveto_tl @@ -5292,16 +7259,40 @@ manipulating PGF soft paths} \tl_put_right:Nx \l_@@_tmpb_tl { - {\dim_eval:n { -\fp_to_dim:N \l_@@_tmpa_fp + \l_@@_tmpa_dim + \fp_to_dim:n{ 1.32 * \l_@@_tmpb_fp}}} - {\dim_eval:n { -\fp_to_dim:N \l_@@_tmpb_fp + \l_@@_tmpb_dim - \fp_to_dim:n {1.32* \l_@@_tmpa_fp}}} + { + \dim_eval:n + { + -\fp_to_dim:N \l_@@_tmpa_fp + \l_@@_tmpa_dim + + \fp_to_dim:n{ 1.32 * \l_@@_tmpb_fp} + } + } + { + \dim_eval:n + { + -\fp_to_dim:N \l_@@_tmpb_fp + \l_@@_tmpb_dim + - \fp_to_dim:n {1.32* \l_@@_tmpa_fp} + } + } } \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curvetob_tl \tl_put_right:Nx \l_@@_tmpb_tl { - {\dim_eval:n { \fp_to_dim:N \l_@@_tmpa_fp + \l_@@_tmpa_dim + \fp_to_dim:n {1.32 * \l_@@_tmpb_fp}}} - {\dim_eval:n { \fp_to_dim:N \l_@@_tmpb_fp + \l_@@_tmpb_dim - \fp_to_dim:n {1.32 * \l_@@_tmpa_fp}}} + { + \dim_eval:n + { + \fp_to_dim:N \l_@@_tmpa_fp + \l_@@_tmpa_dim + + \fp_to_dim:n {1.32 * \l_@@_tmpb_fp} + } + } + { + \dim_eval:n + { + \fp_to_dim:N \l_@@_tmpb_fp + \l_@@_tmpb_dim + - \fp_to_dim:n {1.32 * \l_@@_tmpa_fp} + } + } } \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curveto_tl @@ -5309,7 +7300,7 @@ manipulating PGF soft paths} \tl_put_right:Nx \l_@@_tmpb_tl { {\dim_eval:n { \fp_to_dim:N \l_@@_tmpa_fp + \l_@@_tmpa_dim}} - {\dim_eval:n { \fp_to_dim:N \l_@@_tmpb_fp + \l_@@_tmpb_dim}} + {\dim_eval:n { \fp_to_dim:N \l_@@_tmpb_fp + \l_@@_tmpb_dim}} } \pgfsyssoftpath@setcurrentpath\l_@@_tmpb_tl @@ -5327,7 +7318,7 @@ manipulating PGF soft paths} \seq_gset_eq:NN \g_@@_pen_copperplate_seq \l_@@_tmpa_seq % \end{macrocode} % -% \begin{macro}{\CopperplatePath} +% \begin{macro}[internal]{\CopperplatePath} % This is used in the decorations section to convert a path to a copperplate path. % \begin{macrocode} \DeclareDocumentCommand \CopperplatePath { m } @@ -5350,75 +7341,160 @@ manipulating PGF soft paths} % \begin{macrocode} \expandafter\ifx\csname pgfdeclaredecoration\endcsname\relax \else -\pgfdeclaredecoration{calligraphic brace}{brace} -{ - \state{brace}[width=+\pgfdecoratedremainingdistance,next state=final] - { - \pgfsyssoftpath@setcurrentpath{\pgfutil@empty} - \pgfpathmoveto{\pgfpointorigin} - \pgfpathcurveto - {\pgfqpoint{.15\pgfdecorationsegmentamplitude}{.3\pgfdecorationsegmentamplitude}} - {\pgfqpoint{.5\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}} - {\pgfqpoint{\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}} - { - \pgftransformxshift{+\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance} - \pgfpathlineto{\pgfqpoint{-\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}} - \pgfpathcurveto - {\pgfqpoint{-.5\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}} - {\pgfqpoint{-.15\pgfdecorationsegmentamplitude}{.7\pgfdecorationsegmentamplitude}} - {\pgfqpoint{0\pgfdecorationsegmentamplitude}{1\pgfdecorationsegmentamplitude}} - \pgfpathmoveto{\pgfqpoint{0\pgfdecorationsegmentamplitude}{1\pgfdecorationsegmentamplitude}} - \pgfpathcurveto - {\pgfqpoint{.15\pgfdecorationsegmentamplitude}{.7\pgfdecorationsegmentamplitude}} - {\pgfqpoint{.5\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}} - {\pgfqpoint{\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}} - } - { - \pgftransformxshift{+\pgfdecoratedremainingdistance} - \pgfpathlineto{\pgfqpoint{-\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}} +\pgfdeclaredecoration{calligraphic brace}{brace}% +{% + \state{brace}[width=+\pgfdecoratedremainingdistance,next state=final]% + {% + \pgfsyssoftpath@setcurrentpath{\pgfutil@empty}% + \pgfpathmoveto{\pgfpointorigin}% + \pgfpathcurveto% + {% + \pgfqpoint% + {.15\pgfdecorationsegmentamplitude}% + {.3\pgfdecorationsegmentamplitude}% + }% + {% + \pgfqpoint% + {.5\pgfdecorationsegmentamplitude}% + {.5\pgfdecorationsegmentamplitude}% + }% + {% + \pgfqpoint% + {\pgfdecorationsegmentamplitude}% + {.5\pgfdecorationsegmentamplitude}% + }% + {% + \pgftransformxshift% + {+\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance}% + \pgfpathlineto% + {% + \pgfqpoint% + {-\pgfdecorationsegmentamplitude}% + {.5\pgfdecorationsegmentamplitude}% + }% \pgfpathcurveto - {\pgfqpoint{-.5\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}} - {\pgfqpoint{-.15\pgfdecorationsegmentamplitude}{.3\pgfdecorationsegmentamplitude}} - {\pgfqpoint{0pt}{0pt}} - } - \tikzset{ - taper width=.5\pgflinewidth, - taper + {% + \pgfqpoint% + {-.5\pgfdecorationsegmentamplitude}% + {.5\pgfdecorationsegmentamplitude}% + }% + {% + \pgfqpoint% + {-.15\pgfdecorationsegmentamplitude}% + {.7\pgfdecorationsegmentamplitude}% + }% + {% + \pgfqpoint% + {0\pgfdecorationsegmentamplitude}% + {1\pgfdecorationsegmentamplitude}% + }% + \pgfpathmoveto% + {% + \pgfqpoint% + {0\pgfdecorationsegmentamplitude}% + {1\pgfdecorationsegmentamplitude}% + }% + \pgfpathcurveto% + {% + \pgfqpoint% + {.15\pgfdecorationsegmentamplitude}% + {.7\pgfdecorationsegmentamplitude}% + }% + {% + \pgfqpoint% + {.5\pgfdecorationsegmentamplitude}% + {.5\pgfdecorationsegmentamplitude}% + }% + {% + \pgfqpoint% + {\pgfdecorationsegmentamplitude}% + {.5\pgfdecorationsegmentamplitude}% + }% }% - \pgfsyssoftpath@getcurrentpath\cal@tmp@path - \CopperplatePath{\cal@tmp@path} - } - \state{final}{} -} + {% + \pgftransformxshift{+\pgfdecoratedremainingdistance}% + \pgfpathlineto% + {% + \pgfqpoint% + {-\pgfdecorationsegmentamplitude}% + {.5\pgfdecorationsegmentamplitude}% + }% + \pgfpathcurveto% + {% + \pgfqpoint% + {-.5\pgfdecorationsegmentamplitude}% + {.5\pgfdecorationsegmentamplitude}% + }% + {% + \pgfqpoint% + {-.15\pgfdecorationsegmentamplitude}% + {.3\pgfdecorationsegmentamplitude}% + }% + {\pgfqpoint{0pt}{0pt}}% + }% + \tikzset{% + taper width=.5\pgflinewidth,% + taper% + }%% + \pgfsyssoftpath@getcurrentpath\cal@tmp@path% + \CopperplatePath{\cal@tmp@path}% + }% + \state{final}{}% +}% % \end{macrocode} % % The second is a straightened parenthesis (so that when very large it doesn't bow out too far). % \begin{macrocode} \pgfdeclaredecoration{calligraphic straight parenthesis}{brace} { - \state{brace}[width=+\pgfdecoratedremainingdistance,next state=final] - { - \pgfsyssoftpath@setcurrentpath{\pgfutil@empty} - \pgfpathmoveto{\pgfpointorigin} - \pgfpathcurveto - {\pgfqpoint{.76604\pgfdecorationsegmentamplitude}{.64279\pgfdecorationsegmentamplitude}} - {\pgfqpoint{2.3333\pgfdecorationsegmentamplitude}{\pgfdecorationsegmentamplitude}} - {\pgfqpoint{3.3333\pgfdecorationsegmentamplitude}{\pgfdecorationsegmentamplitude}} - { - \pgftransformxshift{+\pgfdecoratedremainingdistance} - \pgfpathlineto{\pgfqpoint{-3.3333\pgfdecorationsegmentamplitude}{\pgfdecorationsegmentamplitude}} - \pgfpathcurveto - {\pgfqpoint{-2.3333\pgfdecorationsegmentamplitude}{\pgfdecorationsegmentamplitude}} - {\pgfqpoint{-.76604\pgfdecorationsegmentamplitude}{.64279\pgfdecorationsegmentamplitude}} - {\pgfqpoint{0pt}{0pt}} - } - \tikzset{ - taper width=.5\pgflinewidth, - taper + \state{brace}[width=+\pgfdecoratedremainingdistance,next state=final]% + {% + \pgfsyssoftpath@setcurrentpath{\pgfutil@empty}% + \pgfpathmoveto{\pgfpointorigin}% + \pgfpathcurveto% + {% + \pgfqpoint% + {.76604\pgfdecorationsegmentamplitude}% + {.64279\pgfdecorationsegmentamplitude}% }% - \pgfsyssoftpath@getcurrentpath\cal@tmp@path - \CopperplatePath{\cal@tmp@path} - } + {% + \pgfqpoint% + {2.3333\pgfdecorationsegmentamplitude}% + {\pgfdecorationsegmentamplitude}% + }% + {% + \pgfqpoint% + {3.3333\pgfdecorationsegmentamplitude}% + {\pgfdecorationsegmentamplitude}% + }% + {% + \pgftransformxshift{+\pgfdecoratedremainingdistance}% + \pgfpathlineto% + {% + \pgfqpoint% + {-3.3333\pgfdecorationsegmentamplitude}% + {\pgfdecorationsegmentamplitude}% + }% + \pgfpathcurveto% + {% + \pgfqpoint% + {-2.3333\pgfdecorationsegmentamplitude}% + {\pgfdecorationsegmentamplitude}% + }% + {% + \pgfqpoint% + {-.76604\pgfdecorationsegmentamplitude}% + {.64279\pgfdecorationsegmentamplitude}% + }% + {\pgfqpoint{0pt}{0pt}}% + }% + \tikzset{% + taper width=.5\pgflinewidth,% + taper% + }% + \pgfsyssoftpath@getcurrentpath\cal@tmp@path% + \CopperplatePath{\cal@tmp@path}% + }% \state{final}{}% } % \end{macrocode} @@ -5427,24 +7503,28 @@ manipulating PGF soft paths} % \begin{macrocode} \pgfdeclaredecoration{calligraphic curved parenthesis}{brace} { - \state{brace}[width=+\pgfdecoratedremainingdistance,next state=final] - { - \pgfsyssoftpath@setcurrentpath{\pgfutil@empty} - \pgfpathmoveto{\pgfpointorigin} - \pgf@xa=\pgfdecoratedremainingdistance\relax - \advance\pgf@xa by -1.5890\pgfdecorationsegmentamplitude\relax - \edef\cgrphy@xa{\the\pgf@xa} - \pgfpathcurveto - {\pgfqpoint{1.5890\pgfdecorationsegmentamplitude}{1.3333\pgfdecorationsegmentamplitude}} - {\pgfqpoint{\cgrphy@xa}{1.3333\pgfdecorationsegmentamplitude}} - {\pgfqpoint{\pgfdecoratedremainingdistance}{0pt}} - \tikzset{ - taper width=.5\pgflinewidth, - taper + \state{brace}[width=+\pgfdecoratedremainingdistance,next state=final]% + {% + \pgfsyssoftpath@setcurrentpath{\pgfutil@empty}% + \pgfpathmoveto{\pgfpointorigin}% + \pgf@xa=\pgfdecoratedremainingdistance\relax% + \advance\pgf@xa by -1.5890\pgfdecorationsegmentamplitude\relax% + \edef\cgrphy@xa{\the\pgf@xa}% + \pgfpathcurveto% + {% + \pgfqpoint% + {1.5890\pgfdecorationsegmentamplitude}% + {1.3333\pgfdecorationsegmentamplitude}% }% - \pgfsyssoftpath@getcurrentpath\cal@tmp@path - \CopperplatePath{\cal@tmp@path} - } + {\pgfqpoint{\cgrphy@xa}{1.3333\pgfdecorationsegmentamplitude}}% + {\pgfqpoint{\pgfdecoratedremainingdistance}{0pt}}% + \tikzset{% + taper width=.5\pgflinewidth,% + taper% + }% + \pgfsyssoftpath@getcurrentpath\cal@tmp@path% + \CopperplatePath{\cal@tmp@path}% + }% \state{final}{}% } % \end{macrocode} @@ -5504,6 +7584,7 @@ manipulating PGF soft paths} \dim_new:N \l_@@_tmpa_dim \dim_new:N \l_@@_tmpb_dim \dim_new:N \l_@@_tolerance_dim +\dim_new:N \l_@@_redraw_tolerance_dim \dim_new:N \l_@@_clip_bg_radius_dim \dim_new:N \l_@@_clip_draw_radius_dim @@ -5747,6 +7828,14 @@ manipulating PGF soft paths} \pgfscope \pgftransformreset % \end{macrocode} +% Set the dimension for deciding when to include neighbouring strands +% \begin{macrocode} + \dim_set:Nn \l_@@_redraw_tolerance_dim {\fp_to_dim:n + { + sqrt(2) * max(\l_@@_clip_bg_radius_dim, \l_@@_clip_draw_radius_dim) + } + } +% \end{macrocode} % Loop through the strands drawing each one for the first time. % \begin{macrocode} \int_step_function:nnnN {1} {1} {\l_@@_strands_int} \knot_draw_strand:n @@ -5784,7 +7873,12 @@ manipulating PGF soft paths} { \tl_set:Nn \l_@@_node_tl { \exp_not:N \node[coordinate, - pin={[node~ contents={\int_use:N \g_@@_intersections_int},knot~ diagram/draft/crossing~ label, knot~ diagram/draft/crossing~ \int_use:N \g_@@_intersections_int \c_space_tl label/.try] + pin={[ + node~ contents={\int_use:N \g_@@_intersections_int}, + knot~ diagram/draft/crossing~ label, + knot~ diagram/draft/crossing~ + \int_use:N \g_@@_intersections_int \c_space_tl label/.try + ] }] } } @@ -5793,7 +7887,10 @@ manipulating PGF soft paths} % \begin{macrocode} \int_step_variable:nnnNn {1} {1} {\l_@@_tmpa_int - 1} \l_@@_tmpa_tl { - \int_step_variable:nnnNn {\tl_use:N \l_@@_tmpa_tl + 1} {1} {\l_@@_tmpa_int} \l_@@_tmpb_tl + \int_step_variable:nnnNn + {\tl_use:N \l_@@_tmpa_tl + 1} + {1} + {\l_@@_tmpa_int} \l_@@_tmpb_tl { \knot_intersections:VV \l_@@_tmpa_tl \l_@@_tmpb_tl } @@ -5825,7 +7922,12 @@ manipulating PGF soft paths} \spath_bake_round:c {knot strand #1} \tl_set:Nn \l_@@_tmpa_tl {knot~ diagram/every~ strand/.try,} \tl_put_right:Nv \l_@@_tmpa_tl {l_@@_options_strand #1} - \tl_put_right:Nn \l_@@_tmpa_tl {,knot~ diagram/only~ when~ rendering/.try,only~ when~ rendering/.try} + \tl_put_right:Nn \l_@@_tmpa_tl + { + , + knot~ diagram/only~ when~ rendering/.try, + only~ when~ rendering/.try + } \spath_tikz_path:Vv \l_@@_tmpa_tl {knot strand #1} \group_end: \endpgfscope @@ -5845,11 +7947,15 @@ manipulating PGF soft paths} \spath_finalpoint:Nv \l_@@_tmpb_tl {knot strand #1} \dim_set:Nn \l_@@_tmpa_dim {\tl_item:Nn \l_@@_tmpb_tl {1}} \dim_set:Nn \l_@@_tmpb_dim {\tl_item:Nn \l_@@_tmpb_tl {2}} - \node[knot~ diagram/draft/strand~label] at (\l_@@_tmpa_dim,\l_@@_tmpb_dim) {#1}; + \node[ + knot~ diagram/draft/strand~label + ] at (\l_@@_tmpa_dim,\l_@@_tmpb_dim) {#1}; \spath_initialpoint:Nv \l_@@_tmpb_tl {knot strand #1} \dim_set:Nn \l_@@_tmpa_dim {\tl_item:Nn \l_@@_tmpb_tl {1}} \dim_set:Nn \l_@@_tmpb_dim {\tl_item:Nn \l_@@_tmpb_tl {2}} - \node[knot~ diagram/draft/strand~label] at (\l_@@_tmpa_dim,\l_@@_tmpb_dim) {#1}; + \node[ + knot~ diagram/draft/strand~label + ] at (\l_@@_tmpa_dim,\l_@@_tmpb_dim) {#1}; } \bool_if:nT { \l_@@_self_intersections_bool @@ -5858,6 +7964,8 @@ manipulating PGF soft paths} } { \tl_clear:N \l_@@_tmpa_tl + \spath_initialpoint:Nv \l_@@_tmpa_tl {knot strand #1} + \tl_put_left:NV \l_@@_tmpa_tl \c_spath_moveto_tl \spath_segments_to_seq:Nv \l_@@_segments_seq {knot strand #1} \seq_map_function:NN \l_@@_segments_seq \knot_split_self_intersects:N \tl_set_eq:cN {knot strand #1} \l_@@_tmpa_tl @@ -5881,23 +7989,29 @@ manipulating PGF soft paths} { \fp_set:Nn \l_@@_tmpa_fp { - (\tl_item:nn {#1} {3} - 3 * \tl_item:nn {#1} {6} + 3 * \tl_item:nn {#1} {9} - \tl_item:nn {#1} {12}) + (\tl_item:nn {#1} {3} - 3 * \tl_item:nn {#1} {6} + + 3 * \tl_item:nn {#1} {9} - \tl_item:nn {#1} {12}) * (3 * \tl_item:nn {#1} {8} - 3 * \tl_item:nn {#1} {11}) - - (\tl_item:nn {#1} {2} - 3 * \tl_item:nn {#1} {5} + 3 * \tl_item:nn {#1} {8} - \tl_item:nn {#1} {11}) + (\tl_item:nn {#1} {2} - 3 * \tl_item:nn {#1} {5} + + 3 * \tl_item:nn {#1} {8} - \tl_item:nn {#1} {11}) * (3 * \tl_item:nn {#1} {9} - 3 * \tl_item:nn {#1} {12}) } \fp_set:Nn \l_@@_tmpb_fp { - (\tl_item:nn {#1} {2} - 3 * \tl_item:nn {#1} {5} + 3 * \tl_item:nn {#1} {8} - \tl_item:nn {#1} {11}) + (\tl_item:nn {#1} {2} - 3 * \tl_item:nn {#1} {5} + + 3 * \tl_item:nn {#1} {8} - \tl_item:nn {#1} {11}) * - (3 * \tl_item:nn {#1} {6} - 6 * \tl_item:nn {#1} {9} + 3 * \tl_item:nn {#1} {12}) + (3 * \tl_item:nn {#1} {6} - 6 * \tl_item:nn {#1} {9} + + 3 * \tl_item:nn {#1} {12}) - - (\tl_item:nn {#1} {3} - 3 * \tl_item:nn {#1} {6} + 3 * \tl_item:nn {#1} {9} - \tl_item:nn {#1} {12}) + (\tl_item:nn {#1} {3} - 3 * \tl_item:nn {#1} {6} + + 3 * \tl_item:nn {#1} {9} - \tl_item:nn {#1} {12}) * - (3 * \tl_item:nn {#1} {5} - 6 * \tl_item:nn {#1} {8} + 3 * \tl_item:nn {#1} {11}) + (3 * \tl_item:nn {#1} {5} - 6 * \tl_item:nn {#1} {8} + + 3 * \tl_item:nn {#1} {11}) } \fp_compare:nTF { @@ -5910,7 +8024,11 @@ manipulating PGF soft paths} 0 < \l_@@_tmpa_fp && \l_@@_tmpa_fp < 1 } { - \spath_split_curve:NNnV \l_@@_tmpc_tl \l_@@_tmpd_tl {#1} \l_@@_tmpa_fp + \spath_split_curve:NNnV + \l_@@_tmpc_tl + \l_@@_tmpd_tl + {#1} + \l_@@_tmpa_fp \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpc_tl} \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpc_tl} \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpc_tl} @@ -5968,19 +8086,33 @@ manipulating PGF soft paths} \bool_if:nTF { \l_@@_save_bool && - \tl_if_exist_p:c {knot~ intersections~ \tl_use:N \l_@@_name_tl - \tl_use:N \l_@@_tmpa_tl - \tl_use:N \l_@@_tmpb_tl} + \tl_if_exist_p:c { + knot~ intersections~ + \tl_use:N \l_@@_name_tl - + \tl_use:N \l_@@_tmpa_tl - + \tl_use:N \l_@@_tmpb_tl + } } { - \tl_use:c {knot~ intersections~ \tl_use:N \l_@@_name_tl - \tl_use:N \l_@@_tmpa_tl - \tl_use:N \l_@@_tmpb_tl} + \tl_use:c + { + knot~ intersections~ \tl_use:N \l_@@_name_tl - + \tl_use:N \l_@@_tmpa_tl - + \tl_use:N \l_@@_tmpb_tl + } } { -\pgfintersectionofpaths{\pgfsetpath\l_@@_tmpc_tl}{\pgfsetpath\l_@@_tmpd_tl} + \pgfintersectionofpaths{\pgfsetpath\l_@@_tmpc_tl}{\pgfsetpath\l_@@_tmpd_tl} } \int_compare:nT {\pgfintersectionsolutions > 0} { - \int_step_function:nnnN {1} {1} {\pgfintersectionsolutions} \knot_do_intersection:n + \int_step_function:nnnN + {1} + {1} + {\pgfintersectionsolutions} + \knot_do_intersection:n } \knot_save_intersections:VV \l_@@_tmpa_tl \l_@@_tmpb_tl @@ -6017,7 +8149,16 @@ manipulating PGF soft paths} } \tl_put_right:Nx \l_@@_aux_tl { - {\exp_not:N \pgf@x=\dim_use:N \l_@@_tmpa_dim\exp_not:N\relax\exp_not:N \pgf@y =\dim_use:N \l_@@_tmpb_dim\relax} + { + \exp_not:N \pgf@x + = + \dim_use:N \l_@@_tmpa_dim + \exp_not:N \relax + \exp_not:N \pgf@y + = + \dim_use:N \l_@@_tmpb_dim + \exp_not:N \relax + } } } \tl_set:Nn \l_@@_auxa_tl {\expandafter \gdef \csname knot~ intersections~} @@ -6057,7 +8198,7 @@ manipulating PGF soft paths} \tl_set:Nv \l_@@_tmpc_tl \l_@@_tmpc_tl \tl_if_eq:NNT \l_@@_tmpc_tl \l_@@_tmpb_tl { - \knot_test_endpoint:VnT \l_@@_tmpb_tl {final point} + \knot_test_endpoint:NVnT \l_@@_tolerance_dim \l_@@_tmpb_tl {final point} { \bool_set_true:N \l_@@_skip_bool } @@ -6068,7 +8209,7 @@ manipulating PGF soft paths} \tl_set:Nv \l_@@_tmpc_tl \l_@@_tmpc_tl \tl_if_eq:NNT \l_@@_tmpc_tl \l_@@_tmpa_tl { - \knot_test_endpoint:VnT \l_@@_tmpa_tl {final point} + \knot_test_endpoint:NVnT \l_@@_tolerance_dim \l_@@_tmpa_tl {final point} { \bool_set_true:N \l_@@_skip_bool } @@ -6079,19 +8220,19 @@ manipulating PGF soft paths} % \begin{macrocode} \bool_if:NT \l_@@_ignore_ends_bool { - \knot_test_endpoint:VnT \l_@@_tmpa_tl {initial point} + \knot_test_endpoint:NVnT \l_@@_tolerance_dim \l_@@_tmpa_tl {initial point} { \bool_set_true:N \l_@@_skip_bool } - \knot_test_endpoint:VnT \l_@@_tmpa_tl {final point} + \knot_test_endpoint:NVnT \l_@@_tolerance_dim \l_@@_tmpa_tl {final point} { \bool_set_true:N \l_@@_skip_bool } - \knot_test_endpoint:VnT \l_@@_tmpb_tl {initial point} + \knot_test_endpoint:NVnT \l_@@_tolerance_dim \l_@@_tmpb_tl {initial point} { \bool_set_true:N \l_@@_skip_bool } - \knot_test_endpoint:VnT \l_@@_tmpb_tl {final point} + \knot_test_endpoint:NVnT \l_@@_tolerance_dim \l_@@_tmpb_tl {final point} { \bool_set_true:N \l_@@_skip_bool } @@ -6140,14 +8281,16 @@ manipulating PGF soft paths} % \begin{macrocode} \bool_if:NT \l_@@_self_intersections_bool { - \knot_test_endpoint:VnT \l_@@_tmpg_tl {initial point} + \knot_test_endpoint:NVnT + \l_@@_redraw_tolerance_dim \l_@@_tmpg_tl {initial point} { \bool_set_true:N \l_@@_prepend_prev_bool } { \bool_set_false:N \l_@@_prepend_prev_bool } - \knot_test_endpoint:VnT \l_@@_tmpg_tl {final point} + \knot_test_endpoint:NVnT + \l_@@_redraw_tolerance_dim \l_@@_tmpg_tl {final point} { \bool_set_true:N \l_@@_append_next_bool } @@ -6163,10 +8306,14 @@ manipulating PGF soft paths} } { \tl_clear_new:c {knot \tl_use:N \l_@@_prefix_tl -1} - \tl_set_eq:cc {knot \tl_use:N \l_@@_prefix_tl -1} {knot \tl_use:N \l_@@_tmpg_tl} + \tl_set_eq:cc + {knot \tl_use:N \l_@@_prefix_tl -1} + {knot \tl_use:N \l_@@_tmpg_tl} \tl_clear_new:c {l_@@_options_ \tl_use:N \l_@@_prefix_tl -1} - \tl_set_eq:cc {l_@@_options_ \tl_use:N \l_@@_prefix_tl -1} {l_@@_options_ \tl_use:N \l_@@_tmpg_tl} + \tl_set_eq:cc + {l_@@_options_ \tl_use:N \l_@@_prefix_tl -1} + {l_@@_options_ \tl_use:N \l_@@_tmpg_tl} \bool_if:nT { @@ -6177,7 +8324,9 @@ manipulating PGF soft paths} !\tl_if_empty_p:c {knot previous \tl_use:N \l_@@_tmpg_tl} } { - \spath_prepend_no_move:cv {knot \tl_use:N \l_@@_prefix_tl -1} {knot \tl_use:c {knot previous \tl_use:N \l_@@_tmpg_tl}} + \spath_prepend_no_move:cv + {knot \tl_use:N \l_@@_prefix_tl -1} + {knot \tl_use:c {knot previous \tl_use:N \l_@@_tmpg_tl}} % \end{macrocode} % If we split potentially self intersecting curves, we test to see if we should prepend yet another segment. % \begin{macrocode} @@ -6190,10 +8339,18 @@ manipulating PGF soft paths} !\tl_if_empty_p:c {knot previous \tl_use:N \l_@@_tmpg_tl} } { - \knot_test_endpoint:vnT {knot previous \tl_use:N \l_@@_tmpg_tl} {initial point} + \knot_test_endpoint:NvnT + \l_@@_redraw_tolerance_dim + {knot previous \tl_use:N \l_@@_tmpg_tl} + {initial point} { - - \spath_prepend_no_move:cv {knot \tl_use:N \l_@@_prefix_tl -1} {knot \tl_use:c {knot previous \tl_use:c {knot previous \tl_use:N \l_@@_tmpg_tl}}} + \spath_prepend_no_move:cv + {knot \tl_use:N \l_@@_prefix_tl -1} + {knot \tl_use:c + {knot previous \tl_use:c + {knot previous \tl_use:N \l_@@_tmpg_tl} + } + } \tl_set_eq:Nc \l_@@_tmpa_tl {knot \tl_use:N \l_@@_prefix_tl -1} } } @@ -6210,7 +8367,9 @@ manipulating PGF soft paths} !\tl_if_empty_p:c {knot previous \tl_use:N \l_@@_tmpg_tl} } { - \spath_append_no_move:cv {knot \tl_use:N \l_@@_prefix_tl -1} {knot \tl_use:c {knot next \tl_use:N \l_@@_tmpg_tl}} + \spath_append_no_move:cv + {knot \tl_use:N \l_@@_prefix_tl -1} + {knot \tl_use:c {knot next \tl_use:N \l_@@_tmpg_tl}} \bool_if:nT { \l_@@_splits_bool @@ -6221,14 +8380,21 @@ manipulating PGF soft paths} !\tl_if_empty_p:c {knot previous \tl_use:N \l_@@_tmpg_tl} } { - \knot_test_endpoint:vnT {knot previous \tl_use:N \l_@@_tmpg_tl} {final point} + \knot_test_endpoint:NvnT + \l_@@_redraw_tolerance_dim + {knot previous \tl_use:N \l_@@_tmpg_tl} + {final point} { - \spath_append_no_move:cv {knot \tl_use:N \l_@@_prefix_tl -1} {knot \tl_use:c {knot next \tl_use:c {knot next \tl_use:N \l_@@_tmpg_tl}}} - + \spath_append_no_move:cv + {knot \tl_use:N \l_@@_prefix_tl -1} + {knot \tl_use:c + {knot next \tl_use:c + {knot next \tl_use:N \l_@@_tmpg_tl} + } + } } } } - \tl_set:Nn \l_@@_tmpg_tl {\tl_use:N \l_@@_prefix_tl -1} } } @@ -6237,9 +8403,15 @@ manipulating PGF soft paths} % \begin{macrocode} \pgfscope \group_begin: - \tikzset{knot~ diagram/every~ intersection/.try, every~ intersection/.try, knot~ diagram/intersection~ \int_use:N \g_@@_intersections_int/.try} + \tikzset{ + knot~ diagram/every~ intersection/.try, + every~ intersection/.try, + knot~ diagram/intersection~ \int_use:N \g_@@_intersections_int/.try + } \knot_draw_crossing:VVV \l_@@_tmpg_tl \l_@@_tmpa_dim \l_@@_tmpb_dim - \coordinate (\l_@@_name_tl \c_space_tl \int_use:N \g_@@_intersections_int) at (\dim_use:N \l_@@_tmpa_dim, \dim_use:N \l_@@_tmpb_dim); + \coordinate + (\l_@@_name_tl \c_space_tl \int_use:N \g_@@_intersections_int) + at (\dim_use:N \l_@@_tmpa_dim, \dim_use:N \l_@@_tmpb_dim); \group_end: \endpgfscope % \end{macrocode} @@ -6251,7 +8423,13 @@ manipulating PGF soft paths} % \begin{macrocode} \tl_if_empty:NF \l_@@_node_tl { - \seq_gpush:Nx \g_@@_nodes_seq { \l_@@_node_tl at (\dim_use:N \l_@@_tmpa_dim, \dim_use:N \l_@@_tmpb_dim) {};} + \seq_gpush:Nx + \g_@@_nodes_seq + { + \l_@@_node_tl + at + (\dim_use:N \l_@@_tmpa_dim, \dim_use:N \l_@@_tmpb_dim) {}; + } } } } @@ -6263,15 +8441,15 @@ manipulating PGF soft paths} % \begin{macro}[internal]{\knot_test_endpoint:N} % Test whether the point is near the intersection point. % \begin{macrocode} -\prg_new_conditional:Npnn \knot_test_endpoint:N #1 {p,T,F,TF} +\prg_new_conditional:Npnn \knot_test_endpoint:NN #1#2 {p,T,F,TF} { \dim_compare:nTF { - \dim_abs:n { \l_@@_tmpa_dim - \tl_item:Nn #1 {1}} + \dim_abs:n { \l_@@_tmpa_dim - \tl_item:Nn #2 {1}} + - \dim_abs:n { \l_@@_tmpb_dim - \tl_item:Nn #1 {2}} + \dim_abs:n { \l_@@_tmpb_dim - \tl_item:Nn #2 {2}} < - \l_@@_tolerance_dim + #1 } { \prg_return_true: @@ -6286,10 +8464,10 @@ manipulating PGF soft paths} % \begin{macro}[internal]{\knot_test_endpoint:nn} % Wrapper around the above. % \begin{macrocode} -\prg_new_protected_conditional:Npnn \knot_test_endpoint:nn #1#2 {T,F,TF} +\prg_new_protected_conditional:Npnn \knot_test_endpoint:Nnn #1#2#3 {T,F,TF} { - \use:c {spath_#2:Nv} \l_@@_tmpd_tl {knot #1} - \knot_test_endpoint:NTF \l_@@_tmpd_tl + \use:c {spath_#3:Nv} \l_@@_tmpd_tl {knot #2} + \knot_test_endpoint:NNTF #1 \l_@@_tmpd_tl { \prg_return_true: } @@ -6298,9 +8476,9 @@ manipulating PGF soft paths} } } -\cs_generate_variant:Nn \knot_test_endpoint:nnT {VnT,vnT} -\cs_generate_variant:Nn \knot_test_endpoint:nnF {VnF,vnF} -\cs_generate_variant:Nn \knot_test_endpoint:nnTF {VnTF,vnTF} +\cs_generate_variant:Nn \knot_test_endpoint:NnnT {NVnT,NvnT} +\cs_generate_variant:Nn \knot_test_endpoint:NnnF {NVnF,NvnF} +\cs_generate_variant:Nn \knot_test_endpoint:NnnTF {NVnTF,NvnTF} % \end{macrocode} % \end{macro} % @@ -6311,27 +8489,37 @@ manipulating PGF soft paths} { \group_begin: \pgfscope - \path[knot~ diagram/background~ clip] (#2, #3) circle[radius=\l_@@_clip_bg_radius_dim]; + \path[knot~ diagram/background~ clip] (#2, #3) + circle[radius=\l_@@_clip_bg_radius_dim]; \tl_set:Nn \l_@@_tmpa_tl {knot~ diagram/every~ strand/.try,} \tl_if_exist:cT {l_@@_options_ #1} { \tl_put_right:Nv \l_@@_tmpa_tl {l_@@_options_ #1} } - \tl_put_right:Nn \l_@@_tmpa_tl {,knotbg,line~ width= \tl_use:N \l_@@_clip_width_tl * \pgflinewidth} + \tl_put_right:Nn \l_@@_tmpa_tl + { + ,knotbg + ,line~ width= \tl_use:N \l_@@_clip_width_tl * \pgflinewidth + } \spath_tikz_path:Vv \l_@@_tmpa_tl {knot #1} \endpgfscope \pgfscope - \path[knot~ diagram/clip] (#2, #3) circle[radius=\l_@@_clip_draw_radius_dim]; + \path[knot~ diagram/clip] (#2, #3) + circle[radius=\l_@@_clip_draw_radius_dim]; \tl_set:Nn \l_@@_tmpa_tl {knot~ diagram/every~ strand/.try,} \tl_if_exist:cT {l_@@_options_ #1} { \tl_put_right:Nv \l_@@_tmpa_tl {l_@@_options_ #1} } - \tl_put_right:Nn \l_@@_tmpa_tl {,knot~ diagram/only~ when~ rendering/.try,only~ when~ rendering/.try} + \tl_put_right:Nn \l_@@_tmpa_tl + { + ,knot~ diagram/only~ when~ rendering/.try + ,only~ when~ rendering/.try + } \spath_tikz_path:Vv \l_@@_tmpa_tl {knot #1} \endpgfscope @@ -6408,12 +8596,14 @@ manipulating PGF soft paths} \tl_set:cn {knot filament \int_use:N \g_@@_filaments_int} {#1} \tl_clear_new:c {l_@@_options_filament \int_use:N \g_@@_filaments_int} - \tl_set_eq:cN {l_@@_options_filament \int_use:N \g_@@_filaments_int} \l_@@_tmpa_tl + \tl_set_eq:cN {l_@@_options_filament \int_use:N \g_@@_filaments_int} + \l_@@_tmpa_tl \tl_clear_new:c {knot previous filament \int_use:N \g_@@_filaments_int} \int_compare:nF {\l_@@_component_start_int == \g_@@_filaments_int} { - \tl_set:cx {knot previous filament \int_use:N \g_@@_filaments_int} {filament \int_eval:n {\g_@@_filaments_int - 1}} + \tl_set:cx {knot previous filament \int_use:N \g_@@_filaments_int} + {filament \int_eval:n {\g_@@_filaments_int - 1}} } } \c_spath_curvetoa_tl @@ -6422,12 +8612,15 @@ manipulating PGF soft paths} \tl_clear_new:c {knot filament \int_use:N \g_@@_filaments_int} \tl_set:cn {knot filament \int_use:N \g_@@_filaments_int} {#1} \tl_clear_new:c {l_@@_options_filament \int_use:N \g_@@_filaments_int} - \tl_set_eq:cN {l_@@_options_filament \int_use:N \g_@@_filaments_int} \l_@@_tmpa_tl + \tl_set_eq:cN {l_@@_options_filament \int_use:N \g_@@_filaments_int} + \l_@@_tmpa_tl \tl_clear_new:c {knot previous filament \int_use:N \g_@@_filaments_int} \int_compare:nF {\l_@@_component_start_int == \g_@@_filaments_int} { - \tl_set:cx {knot previous filament \int_use:N \g_@@_filaments_int} {filament \int_eval:n {\g_@@_filaments_int - 1}} + \tl_set:cx + {knot previous filament \int_use:N \g_@@_filaments_int} + {filament \int_eval:n {\g_@@_filaments_int - 1}} } } \c_spath_closepath_tl @@ -6435,18 +8628,26 @@ manipulating PGF soft paths} \int_gincr:N \g_@@_filaments_int \tl_clear_new:c {knot filament \int_use:N \g_@@_filaments_int} \tl_clear:N \l_@@_tmpa_tl - \tl_put_right:Nx {\tl_item:nn {#1} {1}\tl_item:nn {#1} {2}\tl_item:nn {#1} {3}} + \tl_put_right:Nx + { + \tl_item:nn {#1} {1}\tl_item:nn {#1} {2}\tl_item:nn {#1} {3} + } \tl_put_right:NV \l_@@_tmpa_tl \c_spath_lineto_tl \tl_put_right:Nx {\tl_item:nn {#1} {5}\tl_item:nn {#1} {6}} \tl_set:cV {knot filament \int_use:N \g_@@_filaments_int} \l_@@_tmpa_tl - \tl_set_eq:cN {l_@@_options_filament \int_use:N \g_@@_filaments_int} \l_@@_tmpa_tl + \tl_set_eq:cN {l_@@_options_filament \int_use:N \g_@@_filaments_int} + \l_@@_tmpa_tl \tl_clear_new:c {knot previous filament \int_use:N \g_@@_filaments_int} \int_compare:nF {\l_@@_component_start_int == \g_@@_filaments_int} { - \tl_set:cx {knot previous filament \int_use:N \g_@@_filaments_int} {filament \int_eval:n {\g_@@_filaments_int - 1}} + \tl_set:cx + {knot previous filament \int_use:N \g_@@_filaments_int} + {filament \int_eval:n {\g_@@_filaments_int - 1}} } - \tl_set:cx {knot previous filament \int_use:N \l_@@_component_start_int} {filament \int_use:N \g_@@_filaments_int} + \tl_set:cx + {knot previous filament \int_use:N \l_@@_component_start_int} + {filament \int_use:N \g_@@_filaments_int} } } { diff --git a/Master/texmf-dist/source/latex/spath3/spath3_code.ins b/Master/texmf-dist/source/latex/spath3/spath3_code.ins index 6c191765e5e..78ef5d1db8d 100644 --- a/Master/texmf-dist/source/latex/spath3/spath3_code.ins +++ b/Master/texmf-dist/source/latex/spath3/spath3_code.ins @@ -26,7 +26,7 @@ See http://www.latex-project.org/lppl.txt \endpreamble \postamble -Copyright (C) 2011-2019 by Andrew Stacey <loopspace@mathforge.org> +Copyright (C) 2011-2021 by Andrew Stacey <loopspace@mathforge.org> This work may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either @@ -38,7 +38,7 @@ 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 +This work consists of the files spath3_code.dtx calligraphy_doc.tex knots_doc.tex spath3.tex @@ -69,7 +69,7 @@ and the derived files spath3.ins, } \endbatchfile %% -%% Copyright (C) 2011-2019 by Andrew Stacey <loopspace@mathforge.org> +%% Copyright (C) 2011-2021 by Andrew Stacey <loopspace@mathforge.org> %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License (LPPL), either @@ -81,7 +81,7 @@ and the derived files spath3.ins, %% This work is "maintained" (as per LPPL maintenance status) by %% Andrew Stacey. %% -%% This work consists of the files spath3.dtx +%% This work consists of the files spath3_code.dtx %% calligraphy_doc.tex %% knots_doc.tex %% spath3.tex |