diff options
author | Karl Berry <karl@freefriends.org> | 2021-02-22 21:52:11 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2021-02-22 21:52:11 +0000 |
commit | eddf3073a8f4953603e7a5d21fcbba7d1104d502 (patch) | |
tree | 8bbd12381085e1d57c5684f733cd4e662b21e947 /Master/texmf-dist/source/latex | |
parent | d9e54ef03db8d244f5386fc89efffccb3d483a5e (diff) |
spath3 (22feb21)
git-svn-id: svn://tug.org/texlive/trunk@57842 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex')
-rw-r--r-- | Master/texmf-dist/source/latex/spath3/spath3_code.dtx | 1261 |
1 files changed, 972 insertions, 289 deletions
diff --git a/Master/texmf-dist/source/latex/spath3/spath3_code.dtx b/Master/texmf-dist/source/latex/spath3/spath3_code.dtx index 621ab942f7b..afd132938c7 100644 --- a/Master/texmf-dist/source/latex/spath3/spath3_code.dtx +++ b/Master/texmf-dist/source/latex/spath3/spath3_code.dtx @@ -143,7 +143,7 @@ and the derived files spath3.ins, %</driver> % \fi % -% \CheckSum{8404} +% \CheckSum{8929} % % \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 @@ -168,6 +168,7 @@ and the derived files spath3.ins, % \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.} +% \changes{2.4}{2021/02/21}{Rejigged how the routines for using paths were implemented, added some more routines for joining paths.} % % \DoNotIndex{\newcommand,\newenvironment} % @@ -256,7 +257,7 @@ and the derived files spath3.ins, \NeedsTeXFormat{LaTeX2e} \RequirePackage{expl3} \RequirePackage{pgf} -\ProvidesExplPackage {spath3} {2021/02/05} {2.2} {Functions for +\ProvidesExplPackage {spath3} {2021/02/21} {2.4} {Functions for manipulating PGF soft paths} \RequirePackage{xparse} % \end{macrocode} @@ -1756,7 +1757,7 @@ manipulating PGF soft paths} { \spath_splice_between:NVnn #1#1{#2}{#3} } -\cs_generate_variant:Nn \spath_splice_between:Nnn {NVV, cnn, cvv, Nvn} +\cs_generate_variant:Nn \spath_splice_between:Nnn {NVV, cnn, cvv, Nvn, NVn} \cs_new_protected_nopar:Npn \spath_gsplice_between:Nnnn #1#2#3#4 { \@@_splice_between:nnn {#2}{#3}{#4} @@ -1768,7 +1769,7 @@ manipulating PGF soft paths} { \spath_gsplice_between:NVnn #1#1{#2}{#3} } -\cs_generate_variant:Nn \spath_gsplice_between:Nnn {NVV, cnn, cvv} +\cs_generate_variant:Nn \spath_gsplice_between:Nnn {NVV, cnn, cvv, Nvn, NVn} % \end{macrocode} % \end{macro} % @@ -1919,7 +1920,7 @@ manipulating PGF soft paths} { \spath_append_no_move:NVn #1#1{#2} } -\cs_generate_variant:Nn \spath_append_no_move:Nn {NV, cv, Nv} +\cs_generate_variant:Nn \spath_append_no_move:Nn {NV, cv, Nv, cV} \cs_new_protected_nopar:Npn \spath_gappend_no_move:Nnn #1#2#3 { \@@_append_no_move:nn {#2}{#3} @@ -1931,7 +1932,7 @@ manipulating PGF soft paths} { \spath_gappend_no_move:NVn #1#1{#2} } -\cs_generate_variant:Nn \spath_gappend_no_move:Nn {NV, cv, Nv} +\cs_generate_variant:Nn \spath_gappend_no_move:Nn {NV, cv, Nv, cV} % \end{macrocode} % \end{macro} % @@ -1953,7 +1954,7 @@ manipulating PGF soft paths} { \spath_append:NVn #1#1{#2} } -\cs_generate_variant:Nn \spath_append:Nn {NV, Nv, cv} +\cs_generate_variant:Nn \spath_append:Nn {NV, Nv, cv, cV} \cs_new_protected_nopar:Npn \spath_gappend:Nnn #1#2#3 { \tl_gset:Nn #1 {#2} @@ -1964,7 +1965,7 @@ manipulating PGF soft paths} { \spath_gappend:NVn #1#1{#2} } -\cs_generate_variant:Nn \spath_gappend:Nn {NV, Nv, cv} +\cs_generate_variant:Nn \spath_gappend:Nn {NV, Nv, cv, cV} % \end{macrocode} % \end{macro} % @@ -2235,6 +2236,128 @@ manipulating PGF soft paths} % \end{macro} % % \begin{macro}[internal]{ +% \spath_replace_lines:Nn, +% \spath_replace_lines:Nn, +% \spath_replace_lines:Nn, +% \spath_replace_lines:Nn, +% } +% Replace any line segments by B\'ezier curves. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_replace_lines:n #1 +{ + \group_begin: + \tl_set:Nn \l_@@_tmpa_tl {#1} + \tl_clear:N \l_@@_tmpb_tl + \dim_set:Nn \l_@@_tmpa_dim {0pt} + \dim_set:Nn \l_@@_tmpb_dim {0pt} + + \bool_do_until:nn + { + \tl_if_empty_p:N \l_@@_tmpa_tl + } + { + \tl_set:Nx \l_@@_tmpc_tl {\tl_item:Nn \l_@@_tmpa_tl {1}} + \tl_set:Nx \l_@@_tmpd_tl {\tl_item:Nn \l_@@_tmpa_tl {2}} + \tl_set:Nx \l_@@_tmpe_tl {\tl_item:Nn \l_@@_tmpa_tl {3}} + + \tl_if_eq:NNTF \l_@@_tmpc_tl \c_spath_lineto_tl + { + \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curvetoa_tl + \tl_put_right:Nx \l_@@_tmpb_tl + { + { + \fp_to_dim:n + { + 2/3 * (\l_@@_tmpa_dim) + + + 1/3 * (\l_@@_tmpd_tl) + } + } + } + \tl_put_right:Nx \l_@@_tmpb_tl + { + { + \fp_to_dim:n + { + 2/3 * (\l_@@_tmpb_dim) + + + 1/3 * (\l_@@_tmpe_tl) + } + } + } + \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curvetob_tl + \tl_put_right:Nx \l_@@_tmpb_tl + { + { + \fp_to_dim:n + { + 1/3 * (\l_@@_tmpa_dim) + + + 2/3 * (\l_@@_tmpd_tl) + } + } + } + \tl_put_right:Nx \l_@@_tmpb_tl + { + { + \fp_to_dim:n + { + 1/3 * (\l_@@_tmpb_dim) + + + 2/3 * (\l_@@_tmpe_tl) + } + } + } + \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curveto_tl + \@@_tl_put_right_braced:NV \l_@@_tmpb_tl \l_@@_tmpd_tl + \@@_tl_put_right_braced:NV \l_@@_tmpb_tl \l_@@_tmpe_tl + } + { + \tl_put_right:NV \l_@@_tmpb_tl \l_@@_tmpc_tl + \@@_tl_put_right_braced:NV \l_@@_tmpb_tl \l_@@_tmpd_tl + \@@_tl_put_right_braced:NV \l_@@_tmpb_tl \l_@@_tmpe_tl + } + + \dim_set:Nn \l_@@_tmpa_dim {\l_@@_tmpd_tl} + \dim_set:Nn \l_@@_tmpb_dim {\l_@@_tmpe_tl} + + \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_generate_variant:Nn \@@_replace_lines:n {V} +\cs_new_protected_nopar:Npn \spath_replace_lines:Nn #1#2 +{ + \@@_replace_lines:n {#2} + \tl_set_eq:NN #1 \g_@@_output_tl + \tl_gclear:N \g_@@_output_tl +} +\cs_generate_variant:Nn \spath_replace_lines:Nn {NV, cV, cv, Nv} +\cs_new_protected_nopar:Npn \spath_replace_lines:N #1 +{ + \spath_replace_lines:NV #1#1 +} +\cs_generate_variant:Nn \spath_replace_lines:N {c} +\cs_new_protected_nopar:Npn \spath_greplace_lines:Nn #1#2 +{ + \@@_replace_lines:n {#2} + \tl_gset_eq:NN #1 \g_@@_output_tl + \tl_gclear:N \g_@@_output_tl +} +\cs_generate_variant:Nn \spath_greplace_lines:Nn {NV, cV, cv, Nv} +\cs_new_protected_nopar:Npn \spath_greplace_lines:N #1 +{ + \spath_greplace_lines:NV #1#1 +} +\cs_generate_variant:Nn \spath_greplace_lines:N {c} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{ % \spath_remove_empty_components:Nn, % \spath_remove_empty_components:N, % \spath_gremove_empty_components:Nn, @@ -4709,8 +4832,8 @@ manipulating PGF soft paths} \cs_generate_variant:Nn \spath_show:n {V, v} % \end{macrocode} % \end{macro} - -% \subsubsection{PGF and TikZ Interface Functions} +% +% \subsection{PGF and TikZ Interface Functions} % % Spaths come from PGF so we need some functions that get and set spaths from the pgf system. % @@ -4845,6 +4968,7 @@ manipulating PGF soft paths} \tl_clear_new:c {tikz@timer} \tl_set:cn {tikz@timer} { + \pgftransformreset \spath_reallength:Nn \l_@@_tmpa_int {#1} \tl_set_eq:Nc \l_@@_tmpb_tl {tikz@time} \tl_set:Nx \l_@@_tmpb_tl @@ -4927,7 +5051,10 @@ manipulating PGF soft paths} % % \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 } +\msg_new:nnnn { spath3 } { empty soft path } { Soft~ path~ #1~ is~ empty} +{If~ it~ was~ defined~ inside~ a~ group,~ try~ using~ "save~ global". } +\msg_new:nnn { spath3 } { load intersections } +{ You~ need~ to~ load~ the~ "intersections"~ library~ to~ work~ with~ intersections } % \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. @@ -4990,6 +5117,73 @@ manipulating PGF soft paths} % \end{macrocode} % \end{macro} % +% \begin{macro}[internal]{ +% \@@_tikzset:n +% } +% Wrapper around \Verb+\tikzset+ for expansion. +% \begin{macrocode} +\cs_set_eq:NN \@@_tikzset:n \tikzset +\cs_generate_variant:Nn \@@_tikzset:n {V, v} +% \end{macrocode} +% \end{macro} +% +% When joining two paths we provide a set of options for how to process the second path. +% +% \begin{macrocode} +\bool_new:N \l_@@_reverse_bool +\bool_new:N \l_@@_weld_bool +\bool_new:N \l_@@_move_bool +\bool_new:N \l_@@_global_bool +\tl_new:N \l_@@_joinpath_tl +\tl_new:N \l_@@_transformation_tl + +\cs_new_protected_nopar:Npn \@@_set_bool:Nn #1#2 +{ + \tl_if_eq:nnTF {#2}{false} + { + \bool_set_false:N #1 + } + { + \bool_set_true:N #1 + } +} +\tikzset { + spath/join/.is~ family, + spath/join/.cd, + reverse/.code = { + \@@_set_bool:Nn \l_@@_reverse_bool {#1} + }, + reverse/.default = true, + weld/.code = { + \@@_set_bool:Nn \l_@@_weld_bool {#1} + }, + weld/.default = true, + no~ weld/.code = { + \@@_set_bool:Nn \l_@@_weld_bool {#1} + \bool_set:Nn \l_@@_weld_bool {! \l_@@_weld_bool} + }, + no~ weld/.default = true, + move/.code = { + \@@_set_bool:Nn \l_@@_move_bool {#1} + }, + move/.default = true, + no~ move/.code = { + \@@_set_bool:Nn \l_@@_move_bool {#1} + \bool_set:Nn \l_@@_move_bool {! \l_@@_move_bool} + }, + no~ move/.default = true, + global/.code = { + \@@_set_bool:Nn \l_@@_global_bool {#1} + }, + global/.default = true, + transform/.store~in=\l_@@_transformation_tl, + .unknown/.code = { + \tl_set_eq:NN \l_@@_joinpath_tl \pgfkeyscurrentname + } +} +% \end{macrocode} +% +% % 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). % @@ -5042,6 +5236,15 @@ manipulating PGF soft paths} \l_@@_tmpa_tl } }, + save~ global/.code={ + \tikz@addmode{ + \spath_get_current_path:N \l_@@_tmpa_tl + \spath_bake_round:NV \l_@@_tmpa_tl \l_@@_tmpa_tl + \spath_gsave_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:cTF {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} @@ -5070,15 +5273,6 @@ manipulating PGF soft paths} \msg_warning:nnn { spath3 } { missing soft path } { #2 } } }, - save~ global/.code={ - \tikz@addmode{ - \spath_get_current_path:N \l_@@_tmpa_tl - \spath_bake_round:NV \l_@@_tmpa_tl \l_@@_tmpa_tl - \spath_gsave_path:cV - {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} - \l_@@_tmpa_tl - } - }, % \end{macrocode} % % Saves a soft path to the aux file. @@ -5097,77 +5291,152 @@ manipulating PGF soft paths} }, % \end{macrocode} % -% Restores a soft path to the current path. +% Exports the path as an SVG file. % % \begin{macrocode} - restore/.code={ + export~ to~ svg/.code={ \tl_if_exist:cTF {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { - \tl_if_empty:cTF + \spath_export_to_svg:nv {#1} {\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_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. +% Inserts the named path at the current point in the path, with options for how this is accomplished. +% The inserted path can be transformed, reversed, moved to the current point, and welded to the current path. +% If this is used before the path has been started then it becomes the start of the path (and the ``current point'' is taken as the origin). +% % % \begin{macrocode} - restore~ reverse/.code={ + use/.code={ + \bool_set_false:N \l_@@_reverse_bool + \bool_set_false:N \l_@@_weld_bool + \bool_set_false:N \l_@@_move_bool + \tl_clear:N \l_@@_joinpath_tl + \tl_clear:N \l_@@_transformation_tl + \tikzset{ + spath/join/.cd, + #1 + } + \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_use:N \l_@@_prefix_tl + \tl_use:N \l_@@_joinpath_tl + \tl_use:N \l_@@_suffix_tl + } + { + \tl_if_empty:cT + { + \tl_use:N \l_@@_prefix_tl + \tl_use:N \l_@@_joinpath_tl + \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 } } + \tl_set_eq:Nc \l_@@_joinpath_tl { - \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_use:N \l_@@_prefix_tl + \tl_use:N \l_@@_joinpath_tl + \tl_use:N \l_@@_suffix_tl + } + \spath_get_current_path:N \l_@@_current_tl + + \bool_if:NT \l_@@_reverse_bool + { + \spath_reverse:N \l_@@_joinpath_tl + } + + \tl_if_empty:NF \l_@@_transformation_tl + { + \group_begin: + \pgftransformreset + \@@_tikzset:V \l_@@_transformation_tl + \pgfgettransform \l_@@_tmpa_tl + \tl_gset:Nn \g_@@_smuggle_tl + { + \spath_transform:Nnnnnnn + \l_@@_joinpath_tl + } + \tl_gput_right:NV \g_@@_smuggle_tl \l_@@_tmpa_tl + \group_end: + \tl_use:N \g_@@_smuggle_tl + } + + \bool_if:NT \l_@@_move_bool + { + \tl_if_empty:NTF \l_@@_current_tl + { + \tl_set:Nn \l_@@_tmpc_tl { {0pt} {0pt} } + } + { + \spath_finalpoint:NV + \l_@@_tmpc_tl + \l_@@_current_tl + } + \spath_translate_to:NV \l_@@_joinpath_tl \l_@@_tmpc_tl + } + + \tl_if_empty:NTF \l_@@_current_tl + { + \tl_if_empty:NTF \l_@@_joinpath_tl + { + \tl_set_eq:NN \l_@@_current_tl \c_spath_moveto_tl + \tl_put_right:Nn \l_@@_current_tl {{0pt}{0pt}} + } + { + \tl_set_eq:NN \l_@@_current_tl \l_@@_joinpath_tl + } + } + { + + \tl_clear:N \l_@@_tmpa_tl + \tl_set:Nn \l_@@_tmpa_tl {spath_} + + \tl_put_right:Nn \l_@@_tmpa_tl {append} + + \bool_if:NT \l_@@_weld_bool + { + \tl_put_right:Nn \l_@@_tmpa_tl {_no_move} + } + \tl_put_right:Nn \l_@@_tmpa_tl {:NV} + + \use:c {\tl_use:N \l_@@_tmpa_tl } + \l_@@_current_tl + \l_@@_joinpath_tl } + + \spath_set_current_path:N \l_@@_current_tl + \spath_set_tikz_data:V \l_@@_joinpath_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 } + \msg_warning:nnx + { spath3 } + { missing soft path } + {\tl_use:N \l_@@_joinpath_tl } } }, % \end{macrocode} % +% Some aliases for the above. +% +% \begin{macrocode} + restore/.style={/tikz/spath/use={#1}}, + restore~ reverse/.style={/tikz/spath/use={reverse, #1}}, + append/.style={/tikz/spath/use={move, weld, #1}}, + append~ no~ move/.style={/tikz/spath/use={weld, #1}}, + append~ reverse/.style={/tikz/spath/use={move, weld, reverse, #1}}, + append~ reverse~ no~ move/.style={/tikz/spath/use={weld, reverse, #1}}, + insert/.style={/tikz/spath/use={#1}}, + insert~ reverse/.style={/tikz/spath/use={reverse, #1}}, +% \end{macrocode} +% % Diagnostic, show the current path in the terminal and log. % % \begin{macrocode} @@ -5204,45 +5473,99 @@ manipulating PGF soft paths} }, % \end{macrocode} % -% Appends the named path to the current path with a weld. -% -% \begin{macrocode} - append/.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_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_data:V \l_@@_tmpb_tl - } - { - \msg_warning:nnn { spath3 } { missing soft path } { #1 } - } - }, -% \end{macrocode} -% -% Joins the second named path to the first. +% This joins a path on to an existing path, possibly modifying it first. +% The possible options are the same as those for \Verb+use+. +% It is possible to specify the same path both for the initial and the joining path as a copy is made internally first. % % \begin{macrocode} join~ with/.code~ 2~ args={ \tl_if_exist:cTF {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { + \bool_set_false:N \l_@@_reverse_bool + \bool_set_false:N \l_@@_weld_bool + \bool_set_false:N \l_@@_move_bool + \bool_set_false:N \l_@@_global_bool + \tl_clear:N \l_@@_joinpath_tl + \tl_clear:N \l_@@_transformation_tl + \tikzset{ + spath/join/.cd, + #2 + } + \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 + \tl_use:N \l_@@_joinpath_tl + \tl_use:N \l_@@_suffix_tl + } + { + \tl_set_eq:Nc \l_@@_joinpath_tl + { + \tl_use:N \l_@@_prefix_tl + \tl_use:N \l_@@_joinpath_tl + \tl_use:N \l_@@_suffix_tl + } + + \bool_if:NT \l_@@_reverse_bool + { + \spath_reverse:N \l_@@_joinpath_tl + } + + \tl_if_empty:NF \l_@@_transformation_tl + { + \group_begin: + \pgftransformreset + \@@_tikzset:V \l_@@_transformation_tl + \pgfgettransform \l_@@_tmpa_tl + \tl_gset:Nn \g_@@_smuggle_tl + { + \spath_transform:Nnnnnnn + \l_@@_joinpath_tl + } + \tl_gput_right:NV \g_@@_smuggle_tl \l_@@_tmpa_tl + \group_end: + \tl_use:N \g_@@_smuggle_tl + } + + \bool_if:NT \l_@@_move_bool + { + \spath_finalpoint:Nv + \l_@@_tmpc_tl + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \spath_translate_to:NV \l_@@_joinpath_tl \l_@@_tmpc_tl + } + + \tl_clear:N \l_@@_tmpa_tl + \tl_set:Nn \l_@@_tmpa_tl {spath_} + + \bool_if:NT \l_@@_global_bool + { + \tl_put_right:Nn \l_@@_tmpa_tl {g} + } + + \tl_put_right:Nn \l_@@_tmpa_tl {append} + + \bool_if:NT \l_@@_weld_bool + { + \tl_put_right:Nn \l_@@_tmpa_tl {_no_move} + } + \tl_put_right:Nn \l_@@_tmpa_tl {:cV} + + \cs_if_exist:cF {\tl_use:N \l_@@_tmpa_tl} + { + \tl_show:N \l_@@_tmpa_tl + } + + \use:c {\tl_use:N \l_@@_tmpa_tl } {\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} + \l_@@_joinpath_tl } { - \msg_warning:nnn { spath3 } { missing soft path } { #2 } + \msg_warning:nnx + { spath3 } + { missing soft path } + {\tl_use:N \l_@@_joinpath_tl } } } { @@ -5305,113 +5628,6 @@ manipulating PGF soft paths} }, % \end{macrocode} % -% Appends the reversal of the path to the current path. -% -% \begin{macrocode} - append~ reverse/.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_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_data:V \l_@@_reverse_tl - } - { - \msg_warning:nnn { spath3 } { missing soft path } { #1 } - } - }, -% \end{macrocode} -% -% Inserts the named path into the current path as-is, meaning without transforming or welding it. -% -% \begin{macrocode} - insert/.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: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} -% -% Inserts the reverse of the named path. -% -% \begin{macrocode} - insert~ reverse/.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: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} -% -% 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} @@ -5519,36 +5735,99 @@ manipulating PGF soft paths} % \end{macrocode} % % Join the components of a path by splicing in the second path whenever the components are sufficiently far apart. +% The third argument is a list of components to splice after, if it is empty then all components are used and a spot weld is done first so that the splicing only happens if there is an actual gap. +% +% The \Verb+upright+ versions will join with the reflection of the splice path if it detects that the gap is ``upside-down''. +% % % \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_head_is_group:nTF {#2} + { + \tl_set:Nx \l_@@_tmpc_tl { \tl_item:nn {#2} {1} } + \tl_set:Nx \l_@@_tmpd_tl { \tl_item:nn {#2} {2} } + } + { + \tl_set:Nn \l_@@_tmpc_tl {#2} + \tl_clear:N \l_@@_tmpd_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} + \tl_use:N \l_@@_prefix_tl + \tl_use:N \l_@@_tmpc_tl + \tl_use:N \l_@@_suffix_tl + } + { + \tl_if_empty:NT \l_@@_tmpd_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_gclear:N \g_@@_tmpa_seq + + \tl_if_empty:NTF \l_@@_tmpd_tl + { + \int_step_inline:nnnn {1}{1} {\seq_count:N \l_@@_tmpa_seq} + { + \seq_gput_right:Nn \g_@@_tmpa_seq {##1} + } + } + { + \foreach \l_@@_tmpa_tl in \l_@@_tmpd_tl + { + \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_pop_left:NN \l_@@_tmpa_seq \l_@@_tmpa_tl - - \seq_map_inline:Nn \l_@@_tmpa_seq + \seq_gpop_left:NN \g_@@_tmpa_seq \l_@@_tmpb_tl + + \seq_map_indexed_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} + \int_compare:nTF + { + ##1 == \l_@@_tmpb_tl + } + { + \seq_gpop_left:NNF \g_@@_tmpa_seq \l_@@_tmpb_tl + { + \tl_set:Nn \l_@@_tmpb_tl {-1} + } + \spath_splice_between:Nvn \l_@@_tmpa_tl + { + \tl_use:N \l_@@_prefix_tl + \tl_use:N \l_@@_tmpc_tl + \tl_use:N \l_@@_suffix_tl + } + {##2} + } + { + \tl_put_right:Nn \l_@@_tmpa_tl {##2} + } } \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:nnx + { spath3 } + { missing soft path } + { \tl_use:N \l_@@_tmpc_tl } } } { @@ -5559,30 +5838,319 @@ manipulating PGF soft paths} \tl_if_exist:cTF {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { + \tl_if_head_is_group:nTF {#2} + { + \tl_set:Nx \l_@@_tmpc_tl { \tl_item:nn {#2} {1} } + \tl_set:Nx \l_@@_tmpd_tl { \tl_item:nn {#2} {2} } + } + { + \tl_set:Nn \l_@@_tmpc_tl {#2} + \tl_clear:N \l_@@_tmpd_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 + \tl_use:N \l_@@_tmpc_tl + \tl_use:N \l_@@_suffix_tl + } + { + \tl_if_empty:NT \l_@@_tmpd_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_gclear:N \g_@@_tmpa_seq + \tl_if_empty:NTF \l_@@_tmpd_tl + { + \int_step_inline:nnnn {1}{1} {\seq_count:N \l_@@_tmpa_seq} + { + \seq_gput_right:Nn \g_@@_tmpa_seq {##1} + } + } + { + \foreach \l_@@_tmpa_tl in \l_@@_tmpd_tl + { + \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_pop_left:NN \l_@@_tmpa_seq \l_@@_tmpa_tl + \seq_gpop_left:NN \g_@@_tmpa_seq \l_@@_tmpb_tl + + \seq_map_indexed_inline:Nn \l_@@_tmpa_seq + { + \int_compare:nTF + { + ##1 == \l_@@_tmpb_tl + } + { + \seq_gpop_left:NNF \g_@@_tmpa_seq \l_@@_tmpb_tl + { + \tl_set:Nn \l_@@_tmpb_tl {-1} + } + \spath_splice_between:Nvn \l_@@_tmpa_tl + { + \tl_use:N \l_@@_prefix_tl + \tl_use:N \l_@@_tmpc_tl + \tl_use:N \l_@@_suffix_tl + } + {##2} + } + { + \tl_put_right:Nn \l_@@_tmpa_tl {##2} + } + } + \tl_gset_eq:cN + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \l_@@_tmpa_tl + } + { + \msg_warning:nnx + { spath3 } + { missing soft path } + { \tl_use:N \l_@@_tmpc_tl } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + join~ components~ upright~ with/.code~2~args={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \tl_if_head_is_group:nTF {#2} + { + \tl_set:Nx \l_@@_tmpc_tl { \tl_item:nn {#2} {1} } + \tl_set:Nx \l_@@_tmpd_tl { \tl_item:nn {#2} {2} } + } + { + \tl_set:Nn \l_@@_tmpc_tl {#2} + \tl_clear:N \l_@@_tmpd_tl + } + \tl_if_exist:cTF + { + \tl_use:N \l_@@_prefix_tl + \tl_use:N \l_@@_tmpc_tl + \tl_use:N \l_@@_suffix_tl + } + { + \tl_if_empty:NT \l_@@_tmpd_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_gclear:N \g_@@_tmpa_seq + + \tl_if_empty:NTF \l_@@_tmpd_tl + { + \int_step_inline:nnnn {1}{1} {\seq_count:N \l_@@_tmpa_seq} + { + \seq_gput_right:Nn \g_@@_tmpa_seq {##1} + } + } + { + \foreach \l_@@_tmpa_tl in \l_@@_tmpd_tl + { + \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_pop_left:NN \l_@@_tmpa_seq \l_@@_tmpa_tl - - \seq_map_inline:Nn \l_@@_tmpa_seq + \seq_gpop_left:NN \g_@@_tmpa_seq \l_@@_tmpb_tl + + \tl_set_eq:Nc \l_@@_tmpc_tl { - \spath_gsplice_between:Nvn \l_@@_tmpa_tl - {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} - {##1} + \tl_use:N \l_@@_prefix_tl + \tl_use:N \l_@@_tmpc_tl + \tl_use:N \l_@@_suffix_tl + } + \spath_transform:NVnnnnnn \l_@@_tmpd_tl \l_@@_tmpc_tl {1}{0}{0}{-1}{0pt}{0pt} + + \seq_map_indexed_inline:Nn \l_@@_tmpa_seq + { + \int_compare:nTF + { + ##1 == \l_@@_tmpb_tl + } + { + \seq_gpop_left:NNF \g_@@_tmpa_seq \l_@@_tmpb_tl + { + \tl_set:Nn \l_@@_tmpb_tl {-1} + } + \spath_finalpoint:NV \l_@@_tmpe_tl \l_@@_tmpa_tl + \spath_initialpoint:Nn \l_@@_tmpf_tl {##2} + + \dim_compare:nTF + { + \tl_item:Nn \l_@@_tmpe_tl {1} + > + \tl_item:Nn \l_@@_tmpf_tl {1} + } + { + \spath_splice_between:NVn + \l_@@_tmpa_tl + \l_@@_tmpd_tl + {##2} + } + { + \spath_splice_between:NVn + \l_@@_tmpa_tl + \l_@@_tmpc_tl + {##2} + } + } + { + \tl_put_right:Nn \l_@@_tmpa_tl {##2} + } } \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:nnx + { spath3 } + { missing soft path } + { \tl_use:N \l_@@_tmpc_tl } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + join~ components~ globally~ upright~ with/.code~2~args={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \tl_if_head_is_group:nTF {#2} + { + \tl_set:Nx \l_@@_tmpc_tl { \tl_item:nn {#2} {1} } + \tl_set:Nx \l_@@_tmpd_tl { \tl_item:nn {#2} {2} } + } + { + \tl_set:Nn \l_@@_tmpc_tl {#2} + \tl_clear:N \l_@@_tmpd_tl + } + \tl_if_exist:cTF + { + \tl_use:N \l_@@_prefix_tl + \tl_use:N \l_@@_tmpc_tl + \tl_use:N \l_@@_suffix_tl + } + { + \tl_if_empty:NT \l_@@_tmpd_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_gclear:N \g_@@_tmpa_seq + + \tl_if_empty:NTF \l_@@_tmpd_tl + { + \int_step_inline:nnnn {1}{1} {\seq_count:N \l_@@_tmpa_seq} + { + \seq_gput_right:Nn \g_@@_tmpa_seq {##1} + } + } + { + \foreach \l_@@_tmpa_tl in \l_@@_tmpd_tl + { + \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_pop_left:NN \l_@@_tmpa_seq \l_@@_tmpa_tl + \seq_gpop_left:NN \g_@@_tmpa_seq \l_@@_tmpb_tl + + \tl_set_eq:Nc \l_@@_tmpc_tl + { + \tl_use:N \l_@@_prefix_tl + \tl_use:N \l_@@_tmpc_tl + \tl_use:N \l_@@_suffix_tl + } + \spath_transform:NVnnnnnn \l_@@_tmpd_tl \l_@@_tmpc_tl {1}{0}{0}{-1}{0pt}{0pt} + + \seq_map_indexed_inline:Nn \l_@@_tmpa_seq + { + \int_compare:nTF + { + ##1 == \l_@@_tmpb_tl + } + { + \seq_gpop_left:NNF \g_@@_tmpa_seq \l_@@_tmpb_tl + { + \tl_set:Nn \l_@@_tmpb_tl {-1} + } + \spath_finalpoint:NV \l_@@_tmpe_tl \l_@@_tmpa_tl + \spath_initialpoint:Nn \l_@@_tmpf_tl {##2} + + \dim_compare:nTF + { + \tl_item:Nn \l_@@_tmpe_tl {1} + > + \tl_item:Nn \l_@@_tmpf_tl {1} + } + { + \spath_splice_between:NVn + \l_@@_tmpa_tl + \l_@@_tmpd_tl + {##2} + } + { + \spath_splice_between:NVn + \l_@@_tmpa_tl + \l_@@_tmpc_tl + {##2} + } + } + { + \tl_put_right:Nn \l_@@_tmpa_tl {##2} + } + } + \tl_gset_eq:cN + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + \l_@@_tmpa_tl + } + { + \msg_warning:nnx + { spath3 } + { missing soft path } + { \tl_use:N \l_@@_tmpc_tl } } } { @@ -5790,22 +6358,6 @@ manipulating PGF soft paths} }, % \end{macrocode} % -% Exports the path as an SVG file. -% -% \begin{macrocode} - export~ to~ svg/.code={ - \tl_if_exist:cTF - {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} - { - \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} -% % Transforms the named path using TikZ transformation specifications. % % \begin{macrocode} @@ -5858,40 +6410,58 @@ manipulating PGF soft paths} % \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} + { + tikz@library@intersections@loaded + } { \tl_if_exist:cTF - {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + {\tl_use:N \l_@@_prefix_tl #1 \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_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 } { #2 } + \msg_warning:nnn { spath3 } { missing soft path } { #1 } } } { - \msg_warning:nnn { spath3 } { missing soft path } { #1 } + \msg_warning:nn { spath3 } { load intersections } } }, 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} + tikz@library@intersections@loaded + } + { + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \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_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 } { #2 } + \msg_warning:nnn { spath3 } { missing soft path } { #1 } } } { - \msg_warning:nnn { spath3 } { missing soft path } { #1 } + \msg_warning:nn { spath3 } { load intersections } } }, % \end{macrocode} @@ -5901,40 +6471,58 @@ manipulating PGF soft paths} % \begin{macrocode} split~ at~ intersections/.code~ n~ args={2}{ \tl_if_exist:cTF - {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + tikz@library@intersections@loaded + } { \tl_if_exist:cTF - {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + {\tl_use:N \l_@@_prefix_tl #1 \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_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 } { #2 } + \msg_warning:nnn { spath3 } { missing soft path } { #1 } } } { - \msg_warning:nnn { spath3 } { missing soft path } { #1 } + \msg_warning:nn { spath3 } { load intersections } } }, 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} + { + tikz@library@intersections@loaded + } { \tl_if_exist:cTF - {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl} + {\tl_use:N \l_@@_prefix_tl #1 \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_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 } { #2 } + \msg_warning:nnn { spath3 } { missing soft path } { #1 } } } { - \msg_warning:nnn { spath3 } { missing soft path } { #1 } + \msg_warning:nn { spath3 } { load intersections } } }, % \end{macrocode} @@ -5944,24 +6532,42 @@ manipulating PGF soft paths} % \begin{macrocode} split~ at~ self~ intersections/.code={ \tl_if_exist:cTF - {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { - \spath_split_at_self_intersections:c + tikz@library@intersections@loaded + } + { + \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 } + } } { - \msg_warning:nnn { spath3 } { missing soft path } { #1 } + \msg_warning:nn { spath3 } { load intersections } } }, 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 + tikz@library@intersections@loaded + } + { + \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 } + } } { - \msg_warning:nnn { spath3 } { missing soft path } { #1 } + \msg_warning:nn { spath3 } { load intersections } } }, % \end{macrocode} @@ -6069,40 +6675,64 @@ manipulating PGF soft paths} % The list of components is passed through a \Verb+\foreach+ loop so can use the shortcut syntax from those loops. % % \begin{macrocode} - insert~ gaps~ after~ components/.code~ n~ args={3}{ + insert~ gaps~ after~ components/.code~ 2~ args={ \tl_if_exist:cTF {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { \group_begin: + \tl_if_head_is_group:nTF {#2} + { + \tl_set:Nx \l_@@_tmpc_tl { \tl_item:nn {#2} {1} } + \tl_set:Nx \l_@@_tmpd_tl { \tl_item:nn {#2} {2} } + } + { + \tl_set:Nn \l_@@_tmpc_tl {#2} + \tl_clear:N \l_@@_tmpd_tl + } \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} + + \spath_components_to_seq:Nv + \l_@@_tmpa_seq + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + + \tl_if_empty:NTF \l_@@_tmpd_tl { - \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 + \int_step_inline:nnnn {1}{1} { \l_@@_tmpa_int - 1 } + { + \seq_gput_right:Nn \g_@@_tmpa_seq {##1} + \seq_gput_right:Nx + \g_@@_tmpb_seq + {\int_eval:n {##1 + 1}} + } + } + { + \foreach \l_@@_tmpa_tl in \l_@@_tmpd_tl + { + \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} + \spath_shorten_at_end:Nn \l_@@_tmpa_tl {\l_@@_tmpc_tl/2} } \seq_if_in:NnT \g_@@_tmpb_seq {##1} { - \spath_shorten_at_start:Nn \l_@@_tmpa_tl {#2/2} + \spath_shorten_at_start:Nn \l_@@_tmpa_tl {\l_@@_tmpc_tl/2} } \seq_put_right:NV \l_@@_tmpb_seq \l_@@_tmpa_tl } @@ -6117,41 +6747,64 @@ manipulating PGF soft paths} \msg_warning:nnn { spath3 } { missing soft path } { #1 } } }, - insert~ gaps~ globally~ after~ components/.code~ n~ args={3}{ + insert~ gaps~ globally~ after~ components/.code~ 2~ args={ \tl_if_exist:cTF {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} { \group_begin: + \tl_if_head_is_group:nTF {#2} + { + \tl_set:Nx \l_@@_tmpc_tl { \tl_item:nn {#2} {1} } + \tl_set:Nx \l_@@_tmpd_tl { \tl_item:nn {#2} {2} } + } + { + \tl_set:Nn \l_@@_tmpc_tl {#2} + \tl_clear:N \l_@@_tmpd_tl + } \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} + + \spath_components_to_seq:Nv + \l_@@_tmpa_seq + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + + \tl_if_empty:NTF \l_@@_tmpd_tl { - \seq_gput_right:NV \g_@@_tmpa_seq \l_@@_tmpa_tl - \seq_gput_right:Nx - \g_@@_tmpb_seq + \int_step_inline:nnnn {1}{1} { \l_@@_tmpa_int - 1 } { - \int_eval:n - { - \int_mod:nn { \l_@@_tmpa_tl }{ \l_@@_tmpa_int } + 1 + \seq_gput_right:Nn \g_@@_tmpa_seq {##1} + \seq_gput_right:Nx + \g_@@_tmpb_seq + {\int_eval:n {##1 + 1}} + } + } + { + \foreach \l_@@_tmpa_tl in \l_@@_tmpd_tl + { + \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} + \spath_shorten_at_end:Nn \l_@@_tmpa_tl {\l_@@_tmpc_tl/2} } \seq_if_in:NnT \g_@@_tmpb_seq {##1} { - \spath_shorten_at_start:Nn \l_@@_tmpa_tl {#2/2} + \spath_shorten_at_start:Nn \l_@@_tmpa_tl {\l_@@_tmpc_tl/2} } \seq_put_right:NV \l_@@_tmpb_seq \l_@@_tmpa_tl } @@ -6250,6 +6903,33 @@ manipulating PGF soft paths} }, % \end{macrocode} % +% Replace all line segments by B\'ezier curves. +% +% \begin{macrocode} + replace~ lines/.code={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \spath_replace_lines:c + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + replace~ lines~ globally/.code={ + \tl_if_exist:cTF + {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} + { + \spath_greplace_lines: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. % @@ -6547,7 +7227,10 @@ manipulating PGF soft paths} } } { - \msg_warning:nnx { spath3 } { missing soft path } { \tl_use:N \l_@@_tmpa_tl } + \msg_warning:nnx + { spath3 } + { missing soft path } + { \tl_use:N \l_@@_tmpa_tl } \tl_gset_eq:NN \g_@@_smuggle_tl \pgfpointorigin } \group_end: |