From 658facdfe16a2d2b43c7312b9b15bebbf3c89d8e Mon Sep 17 00:00:00 2001
From: Karl Berry <karl@freefriends.org>
Date: Sat, 13 Apr 2013 22:56:07 +0000
Subject: hobby (13apr13)

git-svn-id: svn://tug.org/texlive/trunk@29895 c570f23f-e606-0410-a88d-b1316a301751
---
 Master/texmf-dist/tex/latex/hobby/hobby.code.tex | 419 ++++++++++++++++++-----
 1 file changed, 341 insertions(+), 78 deletions(-)

(limited to 'Master/texmf-dist/tex/latex/hobby/hobby.code.tex')

diff --git a/Master/texmf-dist/tex/latex/hobby/hobby.code.tex b/Master/texmf-dist/tex/latex/hobby/hobby.code.tex
index 70555c1973c..18c3409d5a3 100644
--- a/Master/texmf-dist/tex/latex/hobby/hobby.code.tex
+++ b/Master/texmf-dist/tex/latex/hobby/hobby.code.tex
@@ -18,6 +18,8 @@
 \RequirePackage{pml3array}
 \ExplSyntaxOn
 \cs_generate_variant:Nn \fp_set:Nn {Nx}
+\cs_generate_variant:Nn \tl_if_eq:nnTF {VnTF}
+\cs_generate_variant:Nn \tl_if_eq:nnTF {xnTF}
 \fp_new:N \g_hobby_parama_fp
 \fp_new:N \g_hobby_paramb_fp
 \fp_new:N \g_hobby_paramc_fp
@@ -32,6 +34,7 @@
 \array_new:N \l_hobby_points_array
 \array_new:N \l_hobby_points_x_array
 \array_new:N \l_hobby_points_y_array
+\array_new:N \l_hobby_actions_array
 \array_new:N \l_hobby_angles_array
 \array_new:N \l_hobby_distances_array
 \array_new:N \l_hobby_tension_out_array
@@ -64,34 +67,79 @@
 \fp_new:N \l_hobby_out_angle_fp
 \fp_set_eq:NN \l_hobby_out_angle_fp \c_undefined_fp
 \int_new:N \l_hobby_npoints_int
+\int_new:N \l_hobby_draw_int
 \keys_define:nn {hobby / read in all} {
   x .fp_set:N = \l_hobby_tempa_fp,
   y .fp_set:N = \l_hobby_tempb_fp,
   tension~out .fp_set:N = \l_hobby_tempc_fp,
   tension~in .fp_set:N = \l_hobby_tempd_fp,
   excess~angle .fp_set:N = \l_hobby_temps_fp,
+  break .tl_set:N = \l_tmpb_tl,
+  blank .tl_set:N = \l_tmpa_tl,
   tension .meta:n = { tension~out=#1, tension~in=#1 },
+  break .default:n = false,
+  blank .default:n = false,
+  invert~soft~blanks .choice:,
+  invert~soft~blanks / true .code:n = {
+    \int_gset:Nn \l_hobby_draw_int {0}
+  },
+  invert~soft~blanks / false .code:n = {
+    \int_gset:Nn \l_hobby_draw_int {1}
+  },
+  invert~soft~blanks .default:n = true,
   tension~out .default:n = 1,
   tension~in .default:n = 1,
   excess~angle .default:n = 0,
-  in~angle .fp_set:N = \l_hobby_in_angle_fp,
-  out~angle .fp_set:N = \l_hobby_out_angle_fp,
-  in~curl .fp_set:N = \l_hobby_in_curl_fp,
-  out~curl .fp_set:N = \l_hobby_out_curl_fp,
-  closed .bool_set:N = \l_hobby_closed_bool,
+  in~angle .fp_gset:N = \l_hobby_in_angle_fp,
+  out~angle .fp_gset:N = \l_hobby_out_angle_fp,
+  in~curl .fp_gset:N = \l_hobby_in_curl_fp,
+  out~curl .fp_gset:N = \l_hobby_out_curl_fp,
+  closed .bool_gset:N = \l_hobby_closed_bool,
   closed .default:n = true,
-  disjoint .bool_set:N = \l_hobby_disjoint_bool,
+  disjoint .bool_gset:N = \l_hobby_disjoint_bool,
   disjoint .default:n = true,
+  break~default .code:n = {
+    \keys_define:nn { hobby / read in all }
+    {
+      break .default:n = #1
+    }
+  },
+  blank~default .code:n = {
+    \keys_define:nn { hobby / read in all }
+    {
+      blank .default:n = #1
+    }
+  },
 }
 \keys_define:nn { hobby / read in params} {
-  in~angle .fp_set:N = \l_hobby_in_angle_fp,
-  out~angle .fp_set:N = \l_hobby_out_angle_fp,
-  in~curl .fp_set:N = \l_hobby_in_curl_fp,
-  out~curl .fp_set:N = \l_hobby_out_curl_fp,
-  closed .bool_set:N = \l_hobby_closed_bool,
+  in~angle .fp_gset:N = \l_hobby_in_angle_fp,
+  out~angle .fp_gset:N = \l_hobby_out_angle_fp,
+  in~curl .fp_gset:N = \l_hobby_in_curl_fp,
+  out~curl .fp_gset:N = \l_hobby_out_curl_fp,
+  closed .bool_gset:N = \l_hobby_closed_bool,
   closed .default:n = true,
-  disjoint .bool_set:N = \l_hobby_disjoint_bool,
+  disjoint .bool_gset:N = \l_hobby_disjoint_bool,
   disjoint .default:n = true,
+  break~default .code:n = {
+    \keys_define:nn { hobby / read in all }
+    {
+      break .default:n = #1
+    }
+  },
+  blank~default .code:n = {
+    \keys_define:nn { hobby / read in all }
+    {
+      blank .default:n = #1
+    }
+  },
+  invert~soft~blanks .choice:,
+  invert~soft~blanks / true .code:n = {
+    \int_gset:Nn \l_hobby_draw_int {0}
+  },
+  invert~soft~blanks / false .code:n = {
+    \int_gset:Nn \l_hobby_draw_int {1}
+  },
+  invert~soft~blanks .default:n = true,
 }
 \cs_set:Nn \hobby_distangle:n {
   \fp_set:Nn \l_hobby_tempa_fp {
@@ -132,10 +180,11 @@
     \hobby_append_point_copy_aux:Nn \l_hobby_tension_in_array {#1}
     \hobby_append_point_copy_aux:Nn \l_hobby_tension_out_array {#1}
     \hobby_append_point_copy_aux:Nn \l_hobby_excess_angle_array {#1}
+    \hobby_append_point_copy_aux:Nn \l_hobby_actions_array {#1}
   }
 \cs_new_protected:Npn \hobby_append_point_copy_aux:Nn #1#2
-  { \array_push:Nx #1 { \array_get:Nn #1 {#2} } }
-\cs_new:Nn \hobby_genpath:
+  { \array_gpush:Nx #1 { \array_get:Nn #1 {#2} } }
+\cs_new:Nn \hobby_gen_path:
 {
 \bool_if:NT \l_hobby_closed_bool {
   \fp_compare:nTF {(\array_get:Nn \l_hobby_points_x_array {0})
@@ -156,10 +205,69 @@
   }
     \hobby_append_point_copy:n {1}
 }
-\int_set:Nn \l_hobby_npoints_int {\array_length:N \l_hobby_points_y_array}
+\int_gset:Nn \l_hobby_npoints_int {\array_length:N \l_hobby_points_y_array}
+\int_compare:nNnTF {\l_hobby_npoints_int} = {0} {
+}
+{
+  \int_compare:nNnTF {\l_hobby_npoints_int} = {1} {
+\hobby_distangle:n {0}
+\fp_if_undefined:NF \l_hobby_out_angle_fp
+{
+  \fp_set:Nn \l_hobby_tempa_fp { \l_hobby_out_angle_fp
+    - \array_get:Nn \l_hobby_angles_array {0} }
+    \fp_compare:nT {\l_hobby_tempa_fp > \c_pi_fp }
+    {
+      \fp_sub:Nn \l_hobby_tempa_fp {2 * \c_pi_fp}
+    }
+    \fp_compare:nT {\l_hobby_tempa_fp < -\c_pi_fp }
+    {
+      \fp_add:Nn \l_hobby_tempa_fp {2 * \c_pi_fp}
+    }
+  \array_put:Nnx \l_hobby_theta_array {0} {\fp_to_tl:N \l_hobby_tempa_fp}
+    \fp_if_undefined:NT \l_hobby_in_angle_fp
+    {
+      \array_put:Nnx \l_hobby_phi_array {1}{ \fp_to_tl:N \l_hobby_tempa_fp}
+    }
+   }
+\fp_if_undefined:NTF \l_hobby_in_angle_fp
+{
+  \fp_if_undefined:NT \l_hobby_out_angle_fp
+  {
+    \array_put:Nnx \l_hobby_phi_array {1} {0}
+    \array_put:Nnx \l_hobby_theta_array {0} {0}
+  }
+}
+{
+  \fp_set:Nn \l_hobby_tempa_fp { - \l_hobby_in_angle_fp + \c_pi_fp
++ (\array_get:Nn \l_hobby_angles_array {0})}
+  \fp_compare:nT {\l_hobby_tempa_fp > \c_pi_fp }
+  {
+    \fp_sub:Nn \l_hobby_tempa_fp {2 * \c_pi_fp}
+  }
+  \fp_compare:nT {\l_hobby_tempa_fp < -\c_pi_fp }
+  {
+    \fp_add:Nn \l_hobby_tempa_fp {2 * \c_pi_fp}
+  }
 
-\prg_stepwise_function:nnnN {0} {1} {\l_hobby_npoints_int - 1} \hobby_distangle:n
-  \prg_stepwise_inline:nnnn {1} {1} {\l_hobby_npoints_int - 1} {
+  \array_put:Nnx \l_hobby_phi_array {1}
+  {\fp_to_tl:N \l_hobby_tempa_fp}
+  \fp_if_undefined:NT \l_hobby_out_angle_fp
+    {
+      \array_put:Nnx \l_hobby_theta_array {0}{ \fp_to_tl:N \l_hobby_tempa_fp}
+    }
+}
+
+  }
+  {
+    \hobby_compute_path:
+  }
+  \hobby_build_path:
+}
+}
+\cs_new:Nn \hobby_compute_path:
+{
+\int_step_function:nnnN {0} {1} {\l_hobby_npoints_int - 1} \hobby_distangle:n
+  \int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int - 1} {
     \fp_set:Nx \l_hobby_tempa_fp {
     \array_get:Nn \l_hobby_angles_array {##1}
     - \array_get:Nn \l_hobby_angles_array {##1 - 1}}
@@ -178,14 +286,14 @@
   }{}
     \array_put:Nnx \l_hobby_psi_array {##1}{\fp_to_tl:N \l_hobby_tempa_fp}
   }
-  \prg_stepwise_inline:nnnn {1} {1} {\l_hobby_npoints_int - 1} {
+  \int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int - 1} {
     \array_put:Nnx \l_hobby_matrix_a_array {##1} {\fp_to_tl:n {
        \array_get:Nn \l_hobby_tension_in_array {##1}^2
       * \array_get:Nn \l_hobby_distances_array {##1}
       * \array_get:Nn \l_hobby_tension_in_array {##1 + 1}
   }}
 }
-  \prg_stepwise_inline:nnnn {1} {1} {\l_hobby_npoints_int - 1} {
+  \int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int - 1} {
 
   \array_put:Nnx \l_hobby_matrix_b_array {##1} {\fp_to_tl:n
 {(3 * (\array_get:Nn \l_hobby_tension_in_array {##1 + 1}) - 1) *
@@ -199,7 +307,7 @@
 * (\array_get:Nn \l_hobby_distances_array {##1})}
 }
 }
-  \prg_stepwise_inline:nnnn {1} {1} {\l_hobby_npoints_int - 2} {
+  \int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int - 2} {
 
   \array_put:Nnx \l_hobby_matrix_c_array {##1} {\fp_to_tl:n
 {(\array_get:Nn \l_hobby_tension_in_array {##1})^2
@@ -208,7 +316,7 @@
 }}
 
 }
-  \prg_stepwise_inline:nnnn {1} {1} {\l_hobby_npoints_int - 2} {
+  \int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int - 2} {
 
   \array_put:Nnx \l_hobby_matrix_d_array {##1} {\fp_to_tl:n
 {
@@ -253,7 +361,7 @@
 }
   \array_put:Nnn \l_hobby_vector_u_array {0} {1}
 \array_put:Nnn \l_hobby_vector_u_array {\l_hobby_npoints_int - 1} {1}
-  \prg_stepwise_inline:nnnn {1} {1} {\l_hobby_npoints_int - 2} {
+  \int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int - 2} {
   \array_put:Nnn \l_hobby_vector_u_array {##1} {0}
   }
 \fp_set:Nn \l_hobby_matrix_v_fp {
@@ -365,7 +473,7 @@
 * (\array_get:Nn \l_hobby_distances_array  {\l_hobby_npoints_int - 1}) }}
 }
 }
-\prg_stepwise_inline:nnnn {1} {1} {\l_hobby_npoints_int - 1} {
+\int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int - 1} {
 
   \array_put:Nnx \l_hobby_matrix_b_array {##1} {\fp_to_tl:n {
   (\array_get:Nn \l_hobby_matrix_b_array {##1 - 1})
@@ -409,7 +517,7 @@
 / (\array_get:Nn \l_hobby_matrix_b_array  {\l_hobby_npoints_int - 1})
 }}
 }
-\prg_stepwise_inline:nnnn {\l_hobby_npoints_int - 2} {-1} {0} {
+\int_step_inline:nnnn {\l_hobby_npoints_int - 2} {-1} {0} {
 
   \array_put:Nnx \l_hobby_theta_array {##1} {\fp_to_tl:n {
 ( (\array_get:Nn \l_hobby_matrix_d_array {##1})
@@ -419,7 +527,7 @@
 }}
 }
 \bool_if:NT \l_hobby_closed_bool {
-\prg_stepwise_inline:nnnn {\l_hobby_npoints_int - 2} {-1} {0} {
+\int_step_inline:nnnn {\l_hobby_npoints_int - 2} {-1} {0} {
   \array_put:Nnx \l_hobby_vector_u_array {##1} {\fp_to_tl:n
 {
     ((\array_get:Nn \l_hobby_vector_u_array {##1})
@@ -440,7 +548,7 @@
 + 1
 )}
 
-\prg_stepwise_inline:nnnn {0} {1} {\l_hobby_npoints_int - 1} {
+\int_step_inline:nnnn {0} {1} {\l_hobby_npoints_int - 1} {
 
   \array_put:Nnx \l_hobby_theta_array {##1} {\fp_to_tl:n {
   (\array_get:Nn \l_hobby_theta_array {##1})
@@ -449,7 +557,7 @@
 }}
 }
 }
-\prg_stepwise_inline:nnnn {1} {1} {\l_hobby_npoints_int - 1} {
+\int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int - 1} {
 
     \array_put:Nnx \l_hobby_phi_array {##1} {\fp_to_tl:n {
       - (\array_get:Nn \l_hobby_psi_array {##1})
@@ -457,7 +565,7 @@
   }}
   }
 \bool_if:NTF \l_hobby_closed_bool {
-  \int_decr:N \l_hobby_npoints_int
+  \int_gdecr:N \l_hobby_npoints_int
 }{
 \fp_if_undefined:NT \l_hobby_in_angle_fp
 {
@@ -478,7 +586,10 @@
 }}
 }
 }
-\prg_stepwise_inline:nnnn {0} {1} {\l_hobby_npoints_int - 1} {
+}
+\cs_new:Nn \hobby_build_path:
+{
+\int_step_inline:nnnn {0} {1} {\l_hobby_npoints_int - 1} {
 
   \fp_set:Nn \l_hobby_tempa_fp {\array_get:Nn \l_hobby_theta_array {##1}}
 
@@ -493,9 +604,8 @@
    \array_put:Nnx \l_hobby_rho_array {##1} {\fp_to_tl:N \l_hobby_temps_fp}
 
   }
-\prg_stepwise_inline:nnnn {0} {1} {\l_hobby_npoints_int - 1} {
-
-\array_put:Nnx \l_hobby_controla_array  {##1 + 1} {x = \fp_eval:n  {
+\int_step_inline:nnnn {0} {1} {\l_hobby_npoints_int - 1} {
+\array_gput:Nnx \l_hobby_controla_array  {##1 + 1} {x = \fp_eval:n  {
 (\array_get:Nn \l_hobby_points_x_array {##1})
 +
   (\array_get:Nn \l_hobby_distances_array {##1}) *
@@ -515,9 +625,8 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1})
 }
 }
 }
-
-\prg_stepwise_inline:nnnn {1} {1} {\l_hobby_npoints_int} {
-  \array_put:Nnx \l_hobby_controlb_array {##1} {
+\int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int} {
+  \array_gput:Nnx \l_hobby_controlb_array {##1} {
     x = \fp_eval:n {\array_get:Nn \l_hobby_points_x_array {##1}
 - (\array_get:Nn \l_hobby_distances_array  {##1 - 1})
 * (\array_get:Nn \l_hobby_sigma_array {##1})
@@ -533,35 +642,8 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1})
  }
 }
 \NewDocumentCommand \hobbyinit {m m m} {
-\hobby_set_cmds:nnn#1#2#3
-\array_clear:N \l_hobby_points_array
-\array_clear:N \l_hobby_points_x_array
-\array_clear:N \l_hobby_points_y_array
-\array_clear:N \l_hobby_angles_array
-\array_clear:N \l_hobby_distances_array
-\array_clear:N \l_hobby_tension_out_array
-\array_clear:N \l_hobby_tension_in_array
-\array_clear:N \l_hobby_excess_angle_array
-\array_clear:N \l_hobby_matrix_a_array
-\array_clear:N \l_hobby_matrix_b_array
-\array_clear:N \l_hobby_matrix_c_array
-\array_clear:N \l_hobby_matrix_d_array
-\array_clear:N \l_hobby_vector_u_array
-\array_clear:N \l_hobby_psi_array
-\array_clear:N \l_hobby_theta_array
-\array_clear:N \l_hobby_phi_array
-\array_clear:N \l_hobby_sigma_array
-\array_clear:N \l_hobby_rho_array
-\array_clear:N \l_hobby_controla_array
-\array_clear:N \l_hobby_controlb_array
-\bool_set_false:N \l_hobby_closed_bool
-\bool_set_false:N \l_hobby_disjoint_bool
-
-  \int_set:Nn \l_hobby_npoints_int {-1}
-  \fp_set_eq:NN \l_hobby_in_angle_fp \c_undefined_fp
-  \fp_set_eq:NN \l_hobby_out_angle_fp \c_undefined_fp
-  \fp_set_eq:NN \l_hobby_in_curl_fp \c_one_fp
-  \fp_set_eq:NN \l_hobby_out_curl_fp \c_one_fp
+  \hobby_set_cmds:nnn#1#2#3
+  \hobby_clear_path:
 }
 \NewDocumentCommand \hobbyaddpoint { m } {
     \keys_set:nn { hobby/read in all }
@@ -569,16 +651,29 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1})
       tension~out,
       tension~in,
       excess~angle,
+      blank,
+      break,
       #1
     }
-    \array_push:Nx \l_hobby_tension_out_array {\fp_to_tl:N \l_hobby_tempc_fp}
-    \array_push:Nx \l_hobby_tension_in_array {\fp_to_tl:N \l_hobby_tempd_fp}
-    \array_push:Nx \l_hobby_excess_angle_array {\fp_to_tl:N \l_hobby_temps_fp}
-    \array_push:Nx \l_hobby_points_array {
+    \tl_if_eq:VnTF {\l_tmpa_tl} {true}
+     {\tl_set:Nn \l_tmpa_tl {2}}
+     {
+       \tl_if_eq:VnTF {\l_tmpa_tl} {soft}
+       {\tl_set:Nn \l_tmpa_tl {0}}
+       {\tl_set:Nn \l_tmpa_tl {1}}
+     }
+    \tl_if_eq:VnTF {\l_tmpb_tl} {true}
+     {\tl_put_right:Nn \l_tmpa_tl {1}}
+     {\tl_put_right:Nn \l_tmpa_tl {0}}
+    \array_gpush:Nx \l_hobby_actions_array {\l_tmpa_tl}
+    \array_gpush:Nx \l_hobby_tension_out_array {\fp_to_tl:N \l_hobby_tempc_fp}
+    \array_gpush:Nx \l_hobby_tension_in_array {\fp_to_tl:N \l_hobby_tempd_fp}
+    \array_gpush:Nx \l_hobby_excess_angle_array {\fp_to_tl:N \l_hobby_temps_fp}
+    \array_gpush:Nx \l_hobby_points_array {
       x = \fp_use:N \l_hobby_tempa_fp,
       y = \fp_use:N \l_hobby_tempb_fp }
-    \array_push:Nx \l_hobby_points_x_array {\fp_to_tl:N \l_hobby_tempa_fp}
-    \array_push:Nx \l_hobby_points_y_array {\fp_to_tl:N \l_hobby_tempb_fp}
+    \array_gpush:Nx \l_hobby_points_x_array {\fp_to_tl:N \l_hobby_tempa_fp}
+    \array_gpush:Nx \l_hobby_points_y_array {\fp_to_tl:N \l_hobby_tempb_fp}
 }
 \NewDocumentCommand \hobbysetparams { m } {
   \keys_set:nn { hobby / read in params }
@@ -587,28 +682,196 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1})
   }
 }
 \cs_new:Nn \hobby_set_cmds:nnn {
-  \cs_set_eq:NN \hobby_moveto:n #1
-  \cs_set_eq:NN \hobby_curveto:nnn #2
-  \cs_set_eq:NN \hobby_close:n #3
+  \cs_gset_eq:NN \hobby_moveto:n #1
+  \cs_gset_eq:NN \hobby_curveto:nnn #2
+  \cs_gset_eq:NN \hobby_close:n #3
 }
-\tl_new:N \l_tmpc_tl
 \NewDocumentCommand \hobbygenpath { } {
-  \hobby_genpath:
+  \array_if_empty:NF \l_hobby_points_array {
+    \hobby_gen_path:
+  }
+}
+\NewDocumentCommand \hobbygenifnecpath { m } {
+  \tl_if_exist:cTF {g_hobby_#1_path}
+  {
+    \tl_use:c {g_hobby_#1_path}
+  }
+  {
+    \hobby_gen_path:
+  }
+  \hobby_save_path:n {#1}
+  \hobby_save_path_to_aux:x {#1}
+}
+\NewDocumentCommand \hobbygenuseifnecpath { m } {
+  \tl_if_exist:cTF {g_hobby_#1_path}
+  {
+    \tl_use:c {g_hobby_#1_path}
+  }
+  {
+    \hobby_gen_path:
+  }
+  \hobby_save_path:n {#1}
+  \hobby_save_path_to_aux:x {#1}
+  \hobby_use_path:
+}
+\NewDocumentCommand \hobbyusepath { m } {
+  \hobbysetparams{#1}
+  \hobby_use_path:
+}
+\NewDocumentCommand \hobbysavepath { m } {
+  \hobby_save_path:n {#1}
+}
+\NewDocumentCommand \hobbyrestorepath { m } {
+  \tl_if_exist:cT {g_hobby_#1_path} {
+    \tl_use:c {g_hobby_#1_path}
+  }
+}
+\NewDocumentCommand \hobbyshowpath { m } {
+  \tl_if_exist:cT {g_hobby_#1_path} {
+    \tl_show:c {g_hobby_#1_path}
+  }
+}
+\NewDocumentCommand \hobbygenusepath { } {
+  \array_if_empty:NF \l_hobby_points_array {
+    \hobby_gen_path:
+    \hobby_use_path:
+  }
+}
+\NewDocumentCommand \hobbyclearpath { } {
+  \hobby_clear_path:
+}
+\tl_new:N \l_tmpc_tl
+\cs_new:Nn \hobby_use_path: {
   \bool_if:NT \l_hobby_disjoint_bool {
     \array_get:NnN \l_hobby_points_array {0} \l_tmpa_tl
     \exp_args:No \hobby_moveto:n {\l_tmpa_tl}
   }
-  \prg_stepwise_inline:nnnn {1} {1} {\l_hobby_npoints_int} {
+  \int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int} {
     \array_get:NnN \l_hobby_controla_array {##1} \l_tmpa_tl
     \array_get:NnN \l_hobby_controlb_array {##1} \l_tmpb_tl
     \array_get:NnN \l_hobby_points_array {##1} \l_tmpc_tl
-    \exp_args:Nooo \hobby_curveto:nnn {\l_tmpa_tl} {\l_tmpb_tl} {\l_tmpc_tl}
-}
+    \array_get:NnN \l_hobby_actions_array {##1} \l_tmpd_tl
+    \int_compare:nNnTF {\tl_item:Nn \l_tmpd_tl {1}} = {\l_hobby_draw_int} {
+      \exp_args:Nooo \hobby_curveto:nnn {\l_tmpa_tl} {\l_tmpb_tl} {\l_tmpc_tl}
+    }{
+      \bool_gset_false:N \l_hobby_closed_bool
+      \exp_args:No \hobby_moveto:n {\l_tmpc_tl}
+    }
+    \tl_if_eq:xnTF {\tl_item:Nn \l_tmpd_tl {2}} {1} {
+      \bool_gset_false:N \l_hobby_closed_bool
+      \exp_args:No \hobby_moveto:n {\l_tmpc_tl}
+    }{}
+  }
   \bool_if:NT \l_hobby_closed_bool {
     \array_get:NnN \l_hobby_points_array {0} \l_tmpa_tl
     \exp_args:No \hobby_close:n {\l_tmpa_tl}
     }
 }
+\cs_new:Nn \hobby_save_path:n {
+  \tl_clear:N \l_tmpa_tl
+  \tl_put_right:Nn \l_tmpa_tl {\int_gset:Nn \l_hobby_npoints_int}
+  \tl_put_right:Nx \l_tmpa_tl {{\int_use:N \l_hobby_npoints_int}}
+  \bool_if:NTF \l_hobby_disjoint_bool {
+    \tl_put_right:Nn \l_tmpa_tl {\bool_gset_true:N}
+  }{
+    \tl_put_right:Nn \l_tmpa_tl {\bool_gset_false:N}
+  }
+  \tl_put_right:Nn \l_tmpa_tl {\l_hobby_disjoint_bool}
+  \bool_if:NTF \l_hobby_closed_bool {
+    \tl_put_right:Nn \l_tmpa_tl {\bool_gset_true:N}
+  }{
+    \tl_put_right:Nn \l_tmpa_tl {\bool_gset_false:N}
+  }
+  \tl_put_right:Nn \l_tmpa_tl {\l_hobby_closed_bool}
+  \tl_put_right:Nn \l_tmpa_tl {\array_gclear:N \l_hobby_points_array}
+  \array_map_inline:Nn \l_hobby_points_array {
+    \tl_put_right:Nn \l_tmpa_tl {
+      \array_gput:Nnn \l_hobby_points_array {##1} {##2}
+    }
+  }
+  \tl_put_right:Nn \l_tmpa_tl {\array_gclear:N \l_hobby_actions_array}
+  \array_map_inline:Nn \l_hobby_actions_array {
+    \tl_put_right:Nn \l_tmpa_tl {
+      \array_gput:Nnn \l_hobby_actions_array {##1} {##2}
+    }
+  }
+  \tl_put_right:Nn \l_tmpa_tl {\array_gclear:N \l_hobby_controla_array}
+  \array_map_inline:Nn \l_hobby_controla_array {
+    \tl_put_right:Nn \l_tmpa_tl {
+      \array_gput:Nnn \l_hobby_controla_array {##1} {##2}
+    }
+  }
+  \tl_put_right:Nn \l_tmpa_tl {\array_gclear:N \l_hobby_controlb_array}
+  \array_map_inline:Nn \l_hobby_controlb_array {
+    \tl_put_right:Nn \l_tmpa_tl {
+      \array_gput:Nnn \l_hobby_controlb_array {##1} {##2}
+    }
+  }
+  \tl_gclear_new:c {g_hobby_#1_path}
+  \tl_gset_eq:cN {g_hobby_#1_path} \l_tmpa_tl
+}
+\int_set:Nn \l_tmpa_int {\char_value_catcode:n {`@}}
+\char_set_catcode_letter:N @
+\cs_new:Npn \hobby_save_path_to_aux:n #1 {
+  \bool_if:nT {
+    \tl_if_exist_p:c {g_hobby_#1_path}
+    &&
+    ! \tl_if_exist_p:c {g_hobby_#1_path_saved}
+  }
+  {
+    \tl_clear:N \l_tmpa_tl
+    \tl_put_right:Nn \l_tmpa_tl {
+      \ExplSyntaxOn
+      \tl_gclear_new:c {g_hobby_#1_path}
+      \tl_gput_right:cn {g_hobby_#1_path}
+    }
+    \tl_put_right:Nx \l_tmpa_tl {
+      {\tl_to_str:c {g_hobby_#1_path}}
+    }
+    \tl_put_right:Nn \l_tmpa_tl {
+      \ExplSyntaxOff
+    }
+    \protected@write\@auxout{}{
+      \tl_to_str:N \l_tmpa_tl
+    }
+    \tl_new:c {g_hobby_#1_path_saved}
+  }
+}
+\char_set_catcode:nn {`@} {\l_tmpa_int}
+\cs_generate_variant:Nn \hobby_save_path_to_aux:n {x}
+\cs_new:Nn \hobby_clear_path:
+{
+\array_gclear:N \l_hobby_points_array
+\array_gclear:N \l_hobby_points_x_array
+\array_gclear:N \l_hobby_points_y_array
+\array_gclear:N \l_hobby_angles_array
+\array_gclear:N \l_hobby_actions_array
+\array_gclear:N \l_hobby_distances_array
+\array_gclear:N \l_hobby_tension_out_array
+\array_gclear:N \l_hobby_tension_in_array
+\array_gclear:N \l_hobby_excess_angle_array
+\array_gclear:N \l_hobby_matrix_a_array
+\array_gclear:N \l_hobby_matrix_b_array
+\array_gclear:N \l_hobby_matrix_c_array
+\array_gclear:N \l_hobby_matrix_d_array
+\array_gclear:N \l_hobby_vector_u_array
+\array_gclear:N \l_hobby_psi_array
+\array_gclear:N \l_hobby_theta_array
+\array_gclear:N \l_hobby_phi_array
+\array_gclear:N \l_hobby_sigma_array
+\array_gclear:N \l_hobby_rho_array
+\array_gclear:N \l_hobby_controla_array
+\array_gclear:N \l_hobby_controlb_array
+\bool_gset_false:N \l_hobby_closed_bool
+\bool_gset_false:N \l_hobby_disjoint_bool
+
+  \int_gset:Nn \l_hobby_npoints_int {-1}
+  \int_gset:Nn \l_hobby_draw_int {1}
+  \fp_gset_eq:NN \l_hobby_in_angle_fp \c_undefined_fp
+  \fp_gset_eq:NN \l_hobby_out_angle_fp \c_undefined_fp
+  \fp_gset_eq:NN \l_hobby_in_curl_fp \c_one_fp
+  \fp_gset_eq:NN \l_hobby_out_curl_fp \c_one_fp
+}
 \ExplSyntaxOff
 %% 
 %% Copyright (C) 2012 by Andrew Stacey <stacey@math.ntnu.no>
-- 
cgit v1.2.3

