%%
%% This is file `tikzlibraryceltic.code.tex',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% celtic.dtx  (with options: `library')
%% ----------------------------------------------------------------
%% celtic --- TikZ library for producing Celtic knots.
%% E-mail: [email protected]
%% Released under the LaTeX Project Public License v1.3c or later
%% See http://www.latex-project.org/lppl.txt
%% ----------------------------------------------------------------
%%
\usepackage{expl3}
\usepackage{xparse}
\ExplSyntaxOn
\cs_new_nopar:Npn \celtic_shift:n #1
{
 \use:c{tikz@scan@one@point}\pgftransformshift #1\relax
}
\int_new:N \l__celtic_max_steps_int
\int_new:N \l__celtic_int
\int_new:N \l__celtic_flip_int
\int_new:N \l__celtic_width_int
\int_new:N \l__celtic_height_int
\int_new:N \l__celtic_x
\int_new:N \l__celtic_y
\int_new:N \l__celtic_dx
\int_new:N \l__celtic_dy
\int_new:N \l__celtic_ox
\int_new:N \l__celtic_oy
\int_new:N \l__celtic_lout
\int_new:N \l__celtic_cross_int
\int_new:N \l__celtic_component_int
\fp_new:N \l__celtic_clip_fp
\fp_new:N \l__celtic_inner_clip_fp
\fp_new:N \l__celtic_inner_fp
\fp_new:N \l__celtic_outer_fp
\seq_new:N \l__celtic_path_seq
\seq_new:N \l__celtic_overpath_seq
\seq_new:N \l__celtic_component_seq
\seq_new:N \l__celtic_crossing_seq
\seq_new:N \l__celtic_tmpa_seq
\clist_new:N \l__celtic_tmpa_clist
\tl_new:N \l__celtic_tmpa_tl
\tl_new:N \l__celtic_path_tl
\tl_new:N \l__celtic_bar_tl
\tl_new:N \l__celtic_active_bar_tl
\tl_new:N \l__celtic_start_tl
\bool_new:N \l__celtic_bounce_bool
\bool_new:N \l__celtic_pbounce_bool

\cs_new_nopar:Npn \tl_split_after:Nnn #1#2#3
{
 \cs_set:Npn \tl_split_aux:nnn ##1#3##2 \q_stop: {#3##2}
 \tl_set:Nx #1 {\tl_split_aux:nnn #2 \q_stop:}
}
\cs_generate_variant:Nn \tl_split_after:Nnn {NVn}
\cs_new_nopar:Npn \tl_split_before:Nnn #1#2#3
{
 \cs_set:Npn \tl_split_aux:nnn ##1#3##2 \q_stop: {##1#3}
 \tl_set:Nx #1 {\tl_split_aux:nnn #2 \q_stop:}
}
\cs_generate_variant:Nn \tl_split_before:Nnn {NVn}
\msg_new:nnnn { celtic } { max~ steps } { Limit~ of~ number~ of~ steps~ exceeded~ \msg_line_context:.}
{ Paths~ may~ not~ be~ correctly~ constructed.~
Consider~ raising~ the~ limit~ from  \int_use:N \l__celtic_max_steps_int.}
\tl_const:Nx \c__celtic_colon_tl { \token_to_str:N : }
\tl_set:Nn \l__celtic_bar_tl {|}
\group_begin:
\char_set_catcode_active:N \|
\tl_gset:Nn \l__celtic_active_bar_tl {|}
\group_end:
\cs_generate_variant:Nn \tl_if_single_p:N {c}
\cs_generate_variant:Nn \tl_if_single:NTF {cTF}
\cs_generate_variant:Nn \tl_if_eq:nnTF {xnTF}
\cs_generate_variant:Nn \tl_head:N {c}
\cs_generate_variant:Nn \tl_tail:N {c}
\cs_generate_variant:Nn \tl_if_eq:nnTF {vnTF}
\cs_generate_variant:Nn \tl_if_in:nnTF {nVTF}
\int_set:Nn \l__celtic_max_steps_int {20}
\fp_set:Nn \l__celtic_inner_fp {1}
\fp_set:Nn \l__celtic_outer_fp {2}
\cs_new_nopar:Npn \celtic_do_crossing:nnn #1#2#3
{
 \tl_if_empty:nTF {#1}
 {
   \tl_clear:c {crossing used \int_eval:n {#2} - \int_eval:n {#3}}
 }
 {
   \tl_set:cn {crossing \int_eval:n {#2} - \int_eval:n{#3}}{#1}
 }
}
\cs_new_nopar:Npn \celtic_maybe_symmetric:nnnn #1#2#3#4
{
 \tl_if_empty:nTF {#1}
 {
   \celtic_do_crossing:nnn {#2}{#3}{#4}
 }
 {
   \celtic_do_crossing:nnn {#2}{#3}{#4}
   \celtic_do_crossing:nnn {#2}{\l__celtic_width_int - #3}{#4}
   \celtic_do_crossing:nnn {#2}{#3}{\l__celtic_height_int - #4}
   \celtic_do_crossing:nnn {#2}{\l__celtic_width_int - #3}{\l__celtic_height_int - #4}
 }
}
\cs_new_nopar:Npn \celtic_maybe_xrange:nnnn #1#2#3#4
{
 \tl_if_in:nVTF {#3} \c__celtic_colon_tl
 {
   \celtic_do_xrange:w {#1}{#2}#3\q_stop{#4}
 }
 {
   \celtic_maybe_yrange:nnnn {#1}{#2}{#3}{#4}
 }
}
\cs_new_nopar:Npn \celtic_maybe_yrange:nnnn #1#2#3#4
{
 \tl_if_in:nVTF {#4} \c__celtic_colon_tl
 {
   \celtic_do_yrange:w {#1}{#2}{#3}#4\q_stop
 }
 {
   \celtic_maybe_symmetric:nnnn {#1}{#2}{#3}{#4}
 }
}
\tl_set:Nx \l_tmpa_tl
{
 \exp_not:N \cs_new_nopar:Npn \exp_not:N \celtic_do_xrange:w ##1##2##3\tl_use:N \c__celtic_colon_tl ##4\exp_not:N \q_stop##5
 {
   \exp_not:N \int_step_inline:nnnn {##3} {2} {##4}
   {
     \exp_not:N \celtic_maybe_yrange:nnnn {##1}{##2} {####1}{##5}
   }
 }
 \exp_not:N \cs_new_nopar:Npn \exp_not:N \celtic_do_yrange:w ##1##2##3##4\tl_use:N \c__celtic_colon_tl ##5\exp_not:N \q_stop
 {
   \exp_not:N \int_step_inline:nnnn {##4} {2} {##5}
   {
     \exp_not:N \celtic_maybe_symmetric:nnnn {##1}{##2}{##3}{####1}
   }
 }
}
\tl_use:N \l_tmpa_tl
\cs_new_nopar:Npn \celtic_ignore_crossings:w #1,#2\q_stop
{
 \celtic_maybe_xrange:nnnn {}{}{#1}{#2}
}
\cs_new_nopar:Npn \celtic_ignore_symmetric_crossings:w #1,#2\q_stop
{
 \celtic_maybe_xrange:nnnn {s}{}{#1}{#2}
}
\cs_new_nopar:Npn \celtic_set_crossings:w #1,#2,#3\q_stop
{
 \celtic_maybe_xrange:nnnn {}{#3}{#1}{#2}
}
\cs_new_nopar:Npn \celtic_set_symmetric_crossings:w #1,#2,#3\q_stop
{
 \celtic_maybe_xrange:nnnn {s}{#3}{#1}{#2}
}
\cs_new_nopar:Npn \celtic_next_crossing:
{
 \int_zero:N \l__celtic_cross_int
 \tl_clear:N \l__celtic_crossing_tl
 \tl_clear:N \l__celtic_path_tl
 \tl_clear:N \l__celtic_overpath_tl
 \bool_set_false:N \l__celtic_bounce_tl
 \tl_set:Nx \l__celtic_start_tl {(\int_use:N \l__celtic_x, \int_use:N \l__celtic_y)}
 \tl_put_right:Nx \l__celtic_path_tl {(\int_use:N \l__celtic_x, \int_use:N \l__celtic_y)}
 \int_set:Nn \l__celtic_lout {(90 - \l__celtic_dx * 45) * \l__celtic_dy}
 \bool_do_until:nn {\int_compare_p:n {\l__celtic_cross_int > 1}}
 {
   \bool_set_eq:NN \l__celtic_pbounce_bool \l__celtic_bounce_bool
   \bool_set_false:N \l__celtic_bounce_bool
   \int_add:Nn \l__celtic_x {\l__celtic_dx}
   \int_add:Nn \l__celtic_y {\l__celtic_dy}
   \tl_if_exist:cT {crossing \int_use:N \l__celtic_x - \int_use:N       \l__celtic_y}
   {
     \tl_if_eq:cNTF {crossing \int_use:N \l__celtic_x - \int_use:N \l__celtic_y} \l__celtic_bar_tl
     {
       \bool_if:NTF \l__celtic_pbounce_bool
       {
         \tl_put_right:Nn \l__celtic_path_tl { -| }
       }
       {
         \tl_put_right:Nx \l__celtic_path_tl { to[out=\int_eval:n
{(90 - 45*\l__celtic_dx)*\l__celtic_dy}, in=\int_eval:n
{-90*\l__celtic_dy}] }
       }
       \int_set:Nn \l__celtic_lout {90*\l__celtic_dy}
       \int_set:Nn \l__celtic_dx {-\l__celtic_dx}
       \tl_put_right:Nx  \l__celtic_path_tl {(\fp_eval:n {\int_use:N \l__celtic_x + .5 * \int_use:N \l__celtic_dx}, \int_use:N \l__celtic_y)}
       \bool_set_true:N \l__celtic_bounce_bool
     }
     {
       \bool_if:NTF \l__celtic_pbounce_bool
       {
         \tl_put_right:Nn \l__celtic_path_tl { |- }
       }
       {
         \tl_put_right:Nx \l__celtic_path_tl { to[out=\int_eval:n {(90 - 45*\l__celtic_dx)*\l__celtic_dy}, in=\int_eval:n {90 + 90*\l__celtic_dx}] }
       }
       \int_set:Nn \l__celtic_lout {90-90*\l__celtic_dx}
       \int_set:Nn \l__celtic_dy {-\l__celtic_dy}
       \tl_put_right:Nx \l__celtic_path_tl {(\int_use:N \l__celtic_x, \fp_eval:n {\int_use:N \l__celtic_y + .5 * \int_use:N \l__celtic_dy})}
       \bool_set_true:N \l__celtic_bounce_bool
     }
   }
   \int_compare:nT {\l__celtic_x == 0}
   {
     \bool_if:NTF \l__celtic_pbounce_bool
     {
       \tl_put_right:Nn \l__celtic_path_tl { -| }
     }
     {
       \tl_put_right:Nx \l__celtic_path_tl { to[out=\int_eval:n {(90 - 45*\l__celtic_dx)*\l__celtic_dy}, in=\int_eval:n {-90*\l__celtic_dy}] }
     }
     \int_set:Nn \l__celtic_lout {90*\l__celtic_dy}
     \int_set:Nn \l__celtic_dx {-\l__celtic_dx}
     \tl_put_right:Nx  \l__celtic_path_tl {(\fp_eval:n {\int_use:N \l__celtic_x + .5 * \int_use:N \l__celtic_dx}, \int_use:N \l__celtic_y)}
     \bool_set_true:N \l__celtic_bounce_bool
   }
   \int_compare:nT {\l__celtic_x == \l__celtic_width_int}
   {
     \bool_if:NTF \l__celtic_pbounce_bool
     {
       \tl_put_right:Nn \l__celtic_path_tl { -| }
     }
     {
       \tl_put_right:Nx \l__celtic_path_tl { to[out=\int_eval:n {(90 - 45*\l__celtic_dx)*\l__celtic_dy}, in=\int_eval:n {-90*\l__celtic_dy}] }
     }
     \int_set:Nn \l__celtic_lout {90*\l__celtic_dy}
     \int_set:Nn \l__celtic_dx {-\l__celtic_dx}
     \tl_put_right:Nx \l__celtic_path_tl {(\fp_eval:n {\int_use:N \l__celtic_x + .5 * \int_use:N \l__celtic_dx}, \int_use:N \l__celtic_y)}
     \bool_set_true:N \l__celtic_bounce_bool
   }
   \int_compare:nT {\l__celtic_y == 0}
   {
     \bool_if:NTF \l__celtic_pbounce_bool
     {
       \tl_put_right:Nn \l__celtic_path_tl { |- }
     }
     {
       \tl_put_right:Nx \l__celtic_path_tl { to[out=\int_eval:n {(90 - 45*\l__celtic_dx)*\l__celtic_dy}, in=\int_eval:n {90 + 90*\l__celtic_dx}] }
     }
     \int_set:Nn \l__celtic_lout {90-90*\l__celtic_dx}
     \int_set:Nn \l__celtic_dy {-\l__celtic_dy}
     \tl_put_right:Nx \l__celtic_path_tl {(\int_use:N \l__celtic_x, \fp_eval:n {\int_use:N \l__celtic_y + .5 * \int_use:N \l__celtic_dy})}
     \bool_set_true:N \l__celtic_bounce_bool
   }
   \int_compare:nT {\l__celtic_y == \l__celtic_height_int}
   {
     \bool_if:NTF \l__celtic_pbounce_bool
     {
       \tl_put_right:Nn \l__celtic_path_tl { |- }
     }
     {
       \tl_put_right:Nx \l__celtic_path_tl { to[out=\int_eval:n {(90 - 45*\l__celtic_dx)*\l__celtic_dy}, in=\int_eval:n {90 + 90*\l__celtic_dx}] }
     }
     \int_set:Nn \l__celtic_lout {-90+90*\l__celtic_dx}
     \int_set:Nn \l__celtic_dy {-\l__celtic_dy}
     \tl_put_right:Nx \l__celtic_path_tl {(\int_use:N \l__celtic_x, \fp_eval:n {\int_use:N \l__celtic_y + .5 * \int_use:N \l__celtic_dy})}
     \bool_set_true:N \l__celtic_bounce_bool
   }
   \bool_if:NF \l__celtic_bounce_bool
   {
     \bool_if:NTF \l__celtic_pbounce_bool
     {
       \tl_put_right:Nx \l__celtic_path_tl { to[out=\int_use:N \l__celtic_lout,in=\int_eval:n {(-90 - 45 * \l__celtic_dx)*\l__celtic_dy}] }
     }
     {
       \tl_put_right:Nn \l__celtic_path_tl { -- }
     }
     \tl_put_right:Nx  \l__celtic_path_tl { (\int_use:N         \l__celtic_x, \int_use:N \l__celtic_y)}
     \tl_if_empty:NTF \l__celtic_crossing_tl
     {
       \tl_set:Nx \l__celtic_crossing_tl {(\int_use:N         \l__celtic_x, \int_use:N \l__celtic_y)}
     }
     {
       \tl_clear:c {crossing used \int_use:N \l__celtic_x - \int_use:N \l__celtic_y}
     }
     \int_incr:N \l__celtic_cross_int
     \int_set:Nn \l__celtic_lout {(90 - \l__celtic_dx * 45) * \l__celtic_dy}
   }
 }
 \tl_set_eq:NN \l__celtic_overpath_tl \l__celtic_path_tl
 \tl_set:Nx \l__celtic_tmpa_tl {(\int_use:N \l__celtic_x, \int_use:N
\l__celtic_y)}
 \tl_if_eq:NNT \l__celtic_crossing_tl \l__celtic_tmpa_tl
 {
   \tl_reverse:N \l__celtic_overpath_tl
   \tl_set:Nx \l__celtic_overpath_tl {\tl_tail:N \l__celtic_overpath_tl}
   \tl_split_after:NVn \l__celtic_overpath_tl \l__celtic_overpath_tl {)}
   \tl_reverse:N \l__celtic_overpath_tl
 }
 \tl_if_eq:NNT \l__celtic_crossing_tl \l__celtic_start_tl
 {
   \tl_set:Nx \l__celtic_overpath_tl {\tl_tail:N \l__celtic_overpath_tl}
   \tl_split_after:NVn \l__celtic_overpath_tl \l__celtic_overpath_tl {(}
 }
}
\keys_define:nn { celtic }
{
 max~ steps .int_set:N = \l__celtic_max_steps_int,
 flip .code:n = {
   \int_set:Nn \l__celtic_flip_int {-1}
 },
 width .int_set:N = \l__celtic_width_int,
 height .int_set:N = \l__celtic_height_int,
 size .code:n = {
   \clist_set:Nn \l__celtic_tmpa_clist {#1}
   \clist_pop:NN \l__celtic_tmpa_clist \l__celtic_tmpa_tl
   \int_set:Nn \l__celtic_width_int {\l__celtic_tmpa_tl}
   \clist_pop:NN \l__celtic_tmpa_clist \l__celtic_tmpa_tl
   \int_set:Nn \l__celtic_height_int {\l__celtic_tmpa_tl}
 },
 width  .groups:n = { size },
 height .groups:n = { size },
 size   .groups:n = { size },
 crossings .code:n = {
   \seq_set_split:Nnn \l__celtic_tmpa_seq {;} {#1}
   \seq_map_inline:Nn \l__celtic_tmpa_seq {
     \tl_if_empty:nF {##1}
     {
       \celtic_set_crossings:w ##1 \q_stop
     }
   }
 },
 symmetric~ crossings .code:n = {
   \seq_set_split:Nnn \l__celtic_tmpa_seq {;} {#1}
   \seq_map_inline:Nn \l__celtic_tmpa_seq {
     \tl_if_empty:nF {##1}
     {
       \celtic_set_symmetric_crossings:w ##1 \q_stop
     }
   }
 },
 ignore~ crossings .code:n ={
   \seq_set_split:Nnn \l__celtic_tmpa_seq {;} {#1}
   \seq_map_inline:Nn \l__celtic_tmpa_seq {
     \tl_if_empty:nF {##1}
     {
       \celtic_ignore_crossings:w ##1 \q_stop
     }
   }
 },
 ignore~ symmetric~ crossings .code:n ={
   \seq_set_split:Nnn \l__celtic_tmpa_seq {;} {#1}
   \seq_map_inline:Nn \l__celtic_tmpa_seq {
     \tl_if_empty:nF {##1}
     {
       \celtic_ignore_symmetric_crossings:w ##1 \q_stop
     }
   }
 },
 style .code:n = {
   \tikzset {#1}
 },
 at .code:n = {
   \celtic_shift:n {#1}
 },
 inner~ clip .fp_set:N = \l__celtic_inner_fp,
 outer~ clip .fp_set:N = \l__celtic_outer_fp,
}
\DeclareDocumentCommand \CelticDrawPath { m }
{
 \group_begin:
 \pgfscope
 \seq_clear:N \l__celtic_path_seq
 \seq_clear:N \l__celtic_overpath_seq
 \seq_clear:N \l__celtic_component_seq
 \seq_clear:N \l__celtic_crossing_seq
 \int_set:Nn \l__celtic_flip_int {1}
\int_compare:nT {\char_value_catcode:n {`\|} = 13}
{
 \tl_set_eq:NN \l__celtic_bar_tl \l__celtic_active_bar_tl
}
 \int_step_inline:nnnn {1} {1} {\l__celtic_height_int-1}
 {
   \int_step_inline:nnnn {1 + \int_mod:nn {##1}{2}} {2} {\l__celtic_width_int-1}
{
 \tl_clear_new:c {crossing used ####1 - ##1}
 \tl_set:cn {crossing used ####1 - ##1} {X}
}
 }
 \keys_set_groups:nnn { celtic } { size } {#1}
 \keys_set_filter:nnn { celtic } { size } {#1}
 \path[celtic~ bar/.try, celtic~ surround/.try] (0,0) rectangle (\int_use:N \l__celtic_width_int, \int_use:N \l__celtic_height_int);
 \int_step_inline:nnnn {1} {1} {\l__celtic_height_int-1}
 {
   \int_step_inline:nnnn {1 + \int_mod:nn {##1}{2}} {2} {\l__celtic_width_int-1}
{
 \tl_if_exist:cT {crossing ####1 - ##1}
 {
   \tl_if_eq:cNTF {crossing ####1 - ##1} \l__celtic_bar_tl
   {
     \path[celtic~ bar/.try] (####1,##1-1) -- (####1,##1+1);
   }
   {
     \path[celtic~ bar/.try] (####1-1,##1) -- (####1+1,##1);
   }
 }
}
 }
 \int_step_inline:nnnn {1} {1} {\l__celtic_height_int-1}
 {
   \int_step_inline:nnnn {1 + \int_mod:nn {##1}{2}} {2} {\l__celtic_width_int-1}
{
   \celtic_generate_path:nnx {####1}{##1}{\int_eval:n {\l__celtic_flip_int*(2*\int_mod:nn{####1}{2} - 1)}}
   }
 }
 \celtic_render_path:
 \endpgfscope
 \group_end:
}
\cs_new_nopar:Npn \celtic_generate_path:nnn #1#2#3
{
 \bool_if:nF {
   \tl_if_exist_p:c {crossing #1 - #2}
   ||
   \tl_if_empty_p:c {crossing used #1 - #2}
 }
 {
   \tl_clear:c {crossing used #1 - #2}
   \int_incr:N \l__celtic_component_int
   \int_set:Nn \l__celtic_x {#1}
   \int_set:Nn \l__celtic_y {#2}
   \int_set_eq:NN \l__celtic_ox \l__celtic_x
   \int_set_eq:NN \l__celtic_oy \l__celtic_y
   \int_set:Nn \l__celtic_dx {#3}
   \int_set:Nn \l__celtic_dy {1}
   \int_zero:N \l__celtic_int
   \bool_do_until:nn
   {
     (\int_compare_p:n {\l__celtic_x == \l__celtic_ox}
     &&
     \int_compare_p:n {\l__celtic_y == \l__celtic_oy}
     )
     || \int_compare_p:n {\l__celtic_int > \l__celtic_max_steps_int}
   }
   {
     \int_incr:N \l__celtic_int
     \celtic_next_crossing:
     \seq_put_left:NV \l__celtic_path_seq \l__celtic_path_tl
     \seq_put_left:NV \l__celtic_overpath_seq \l__celtic_overpath_tl
     \seq_put_left:NV \l__celtic_crossing_seq \l__celtic_crossing_tl
     \seq_put_left:NV \l__celtic_component_seq \l__celtic_component_int
   }
   \int_compare:nT {\l__celtic_int > \l__celtic_max_steps_int}
   {
     \msg_warning:nn {celtic} { max~ steps }
   }
 }
}
\cs_generate_variant:Nn \celtic_generate_path:nnn {nnx}
\cs_new_nopar:Npn \celtic_render_path:
{
 \seq_map_inline:Nn \l__celtic_path_seq
 {
   \seq_pop:NN \l__celtic_component_seq \l__celtic_tmpa_tl
   \seq_put_right:NV \l__celtic_component_seq \l__celtic_tmpa_tl
   \path[celtic~ path/.try, celtic~ path~ \tl_use:N \l__celtic_tmpa_tl/.try] ##1;
 }
 \group_begin:
 \pgfscope
 \tikzset{celtic~ path/.try}
 \tl_use:c {tikz@double@setup}
 \tl_set:Nn \l__celtic_tmpa_tl
 {
   \endpgfscope
   \group_end:
   \fp_set:Nn \l__celtic_clip_fp
 }
 \tl_put_right:Nx \l__celtic_tmpa_tl {{\dim_use:N \pgflinewidth}}
 \tl_use:N \l__celtic_tmpa_tl
 \fp_set:Nn \l__celtic_inner_clip_fp {sqrt(2) * (\l__celtic_clip_fp + \l__celtic_inner_fp)}
 \fp_set:Nn \l__celtic_clip_fp {sqrt(2) * (\l__celtic_clip_fp + \l__celtic_outer_fp)}
 \seq_map_inline:Nn \l__celtic_overpath_seq
 {
   \seq_pop:NN \l__celtic_crossing_seq \l__celtic_crossing_tl
   \seq_pop:NN \l__celtic_component_seq \l__celtic_tmpa_tl
   \seq_put_right:NV \l__celtic_component_seq \l__celtic_tmpa_tl
   \pgfscope
   \clip \l__celtic_crossing_tl +(-\fp_to_dim:N \l__celtic_inner_clip_fp,0) -- +(0,\fp_to_dim:N \l__celtic_inner_clip_fp) -- +(\fp_to_dim:N \l__celtic_inner_clip_fp,0) -- +(0,-\fp_to_dim:N \l__celtic_inner_clip_fp) --  +(-\fp_to_dim:N \l__celtic_inner_clip_fp,0);
   \path[celtic~ path/.try, celtic~ path~ \tl_use:N \l__celtic_tmpa_tl/.try, double~ background] ##1;
   \endpgfscope
   \pgfscope
   \clip \l__celtic_crossing_tl +(-\fp_to_dim:N \l__celtic_clip_fp,0) -- +(0,\fp_to_dim:N \l__celtic_clip_fp) -- +(\fp_to_dim:N \l__celtic_clip_fp,0) -- +(0,-\fp_to_dim:N \l__celtic_clip_fp) --  +(-\fp_to_dim:N \l__celtic_clip_fp,0);
   \path[celtic~ path/.try, celtic~ path~ \tl_use:N \l__celtic_tmpa_tl/.try,double~ foreground] ##1;
   \endpgfscope
 }
}
\ExplSyntaxOff
\tikzset{
 double background/.code={%
   \begingroup
   \tikz@double@setup
   \global\pgf@xa=\pgflinewidth
   \endgroup
   \expandafter\tikz@semiaddlinewidth\expandafter{\the\pgf@xa}%
   \tikz@addmode{\tikz@mode@doublefalse}%
 },
 double foreground/.code={%
   \begingroup
   \tikz@double@setup
   \global\pgf@xa=\pgfinnerlinewidth
   \endgroup
   \expandafter\tikz@semiaddlinewidth\expandafter{\the\pgf@xa}%
   \tikz@addmode{\tikz@mode@doublefalse}%
   \tikzset{color=\pgfinnerstrokecolor}%
 },
}
%%
%% Copyright (C) 2014 by Andrew Stacey <[email protected]>
%%
%% This work may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License (LPPL), either
%% version 1.3c of this license or (at your option) any later
%% version.  The latest version of this license is in the file:
%%
%% http://www.latex-project.org/lppl.txt
%%
%% This work is "maintained" (as per LPPL maintenance status) by
%% Andrew Stacey.
%%
%% This work consists of the files  celtic.dtx
%%                                  celtic_doc.tex
%% and the derived files            celtic.ins
%%                                  celtic_code.pdf
%%                                  tikzlibraryceltic.code.tex
%%                                  celtic.pdf
%%                                  README
%%
%%
%% End of file `tikzlibraryceltic.code.tex'.