%%
%% This is file `etl.sty',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% etl.dtx  (with options: `pkg')
%% 
%% --------------------------------------------------------------
%% etl -- expandable token list operations
%% E-mail: jspratte@yahoo.de
%% Released under the LaTeX Project Public License v1.3c or later
%% See http://www.latex-project.org/lppl.txt
%% --------------------------------------------------------------
%% 
%% Copyright (C) 2020-2021 Jonathan P. Spratte
%% 
%% 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
%%   Jonathan P. Spratte.
%% 
%% This work consists of the file  etl.dtx
%% and the derived files           etl.pdf
%%                                 etl.sty
%% 
\ProvidesExplPackage{etl}
  {2021-11-07} {0.3}
  {expandable token list manipulation}
\cs_if_exist:NF \tex_expanded:D
  {
    \msg_new:nnn { etl } { expanded-missing }
      { The~ expanded~ primitive~ is~ required. }
    \msg_fatal:nn { etl } { expanded-missing }
  }
\cs_new_eq:NN \__etl_expanded:w \tex_expanded:D
\cs_new_eq:NN \__etl_unexpanded:w \tex_unexpanded:D
\cs_new_eq:NN \__etl_detokenize:w \tex_detokenize:D
\scan_new:N \s__etl_stop
\scan_new:N \s__etl_mark
\cs_new:Npn \__etl_split_first:w #1
  {
    { \__etl_unexpanded:w {#1} }
    \if_false: { \fi: \exp_after:wN } \exp_after:wN { \if_false: } \fi:
  }
\cs_new:Npn \__etl_turn_true:w \if_false: { \if_true: }
\cs_new:Npn \__etl_fi_turn_false:w \fi: \if_true: { \fi: \if_false: }
\use:n { \cs_new:Npn \__etl_rm_space:w } ~ {}
\cs_new:Npn \__etl_if_empty:nT #1
  {
    \__etl_if_empty:w
      \s__etl_stop #1 \s__etl_stop \__etl_if_empty_true:w
      \s__etl_stop \s__etl_stop \use_none:n
  }
\cs_new:Npn \__etl_if_empty:nTF #1
  {
    \__etl_if_empty:w
      \s__etl_stop #1 \s__etl_stop \__etl_if_empty_true_TF:w
      \s__etl_stop \s__etl_stop \use_ii:nn
  }
\cs_new:Npn \__etl_if_empty:w #1 \s__etl_stop \s__etl_stop {}
\cs_new:Npn \__etl_if_empty_true:w \s__etl_stop \s__etl_stop \use_none:n #1
  {#1}
\cs_new:Npn \__etl_if_empty_true_TF:w \s__etl_stop \s__etl_stop \use_ii:nn #1#2
  {#1}
\cs_new:Npn \__etl_if_head_is_group:nTF #1
  {
    \exp_after:wN \use_none:n \exp_after:wN
      {
        \exp_after:wN { \token_to_str:N #1 ? }
        \exp_after:wN \use_iii:nnnn \token_to_str:N
      }
    \use_ii:nn
  }
\cs_new:Npn \__etl_if_head_is_group:nT #1
  {
    \exp_after:wN \use_none:n \exp_after:wN
      {
        \exp_after:wN { \token_to_str:N #1 ? }
        \exp_after:wN \use_iii:nnn \token_to_str:N
      }
    \use_none:n
  }
\cs_new:Npn \etl_act:nnnnnnn #1#2#3#4#5#6#7
  {
    \__etl_unexpanded:w \__etl_expanded:w
      {{
        \__etl_act:w #7 {\s__etl_stop} . \s__etl_stop {#5} {#1} {#2} {#3}
        \__etl_act_result:n {#6} {#4}
      }}
  }
\exp_args:NNno \exp_args:Nno \use:n
  { \cs_new:Npn \__etl_act:nnnnnnn #1#2#3#4#5#6#7 }
  {
    \exp_after:wN \use_ii_iii:nnn
    \etl_act:nnnnnnn {#1} {#2} {#3} {#4} {#5} {#6} {#7}
  }
\exp_args:Nno \use:n { \cs_new:Npn \etl_act:nnnnnn #1#2#3#4#5#6 }
  { \etl_act:nnnnnnn {#1} {#2} {#3} {#4} {#5} {} {#6} }
\exp_args:Nno \use:n { \cs_new:Npn \etl_act:nnnnn #1#2#3#4#5 }
  { \etl_act:nnnnnnn {#1} {#2} {#3} \__etl_act_just_result:nn {#4} {} {#5} }
\cs_new:Npn \__etl_act_just_result:nn #1 { \__etl_unexpanded:w }
\group_begin:
  \cs_set:Npn \__etl_tmp:n #1
    {
      \cs_new:Npn \__etl_if_head_is_space:nTF ##1
        {
          \__etl_act_if_space:w
            \s__etl_stop ##1 \s__etl_stop \__etl_if_head_is_space_true:w
            \s__etl_stop #1  \s__etl_stop \use_ii:nn
        }
      \cs_new:Npn \__etl_if_head_is_space_true:w
          \s__etl_stop #1 \s__etl_stop \use_ii:nn ##1##2
        {##1}
      \cs_new:Npn \__etl_if_head_is_N_type:nTF ##1
        {
          \__etl_act_if_space:w
            \s__etl_stop ##1 \s__etl_stop \__etl_if_head_is_N_type_false:w
            \s__etl_stop #1  \s__etl_stop
          \__etl_if_head_is_group:nT {##1} \use_iii:nnn
          \use_i:nn
        }
      \cs_new:Npn \__etl_if_head_is_N_type_false:w
          \s__etl_stop #1 \s__etl_stop
          \__etl_if_head_is_group:nT ##1 \use_iii:nnn
          \use_i:nn
          ##2##3
        {##3}
      \cs_new:Npn \__etl_act:w ##1 \s__etl_stop ##2##3##4##5
        {
          \__etl_act_if_space:w
            \s__etl_stop ##1 \s__etl_stop \__etl_act_space:w {##4}
            \s__etl_stop #1  \s__etl_stop
          \__etl_if_head_is_group:nT {##1} \__etl_act_group:w
          \__etl_act_normal:w {##3} {##5}
          {##2} ##1 \s__etl_stop {##2} {##3} {##4} {##5}
        }
      \cs_new:Npn \__etl_act_if_space:w ##1 \s__etl_stop #1 ##2 \s__etl_stop {}
      \cs_new:Npn \__etl_act_space:w
          ##1 \s__etl_stop #1 \s__etl_stop
          \__etl_if_head_is_group:nT ##2 \__etl_act_group:w \__etl_act_normal:w ##3 ##4
          ##5 #1
        { ##1 {##5} \__etl_act:w }
    }
  \__etl_tmp:n { ~ }
\group_end:
\cs_new:Npn \__etl_act_normal:w #1#2#3#4 { #1 {#3} #4 \__etl_act:w }
\cs_new:Npn \__etl_act_group:w \__etl_act_normal:w #1#2#3#4
  {
    \__etl_act_if_end:w #4 \use_i:nn \etl_act_do_final: \s__etl_stop
    #2 {#3} {#4} \__etl_act:w
  }
\cs_new:Npn \__etl_act_if_end:w #1 \s__etl_stop {}
\cs_new:Npn \etl_act_output:n #1 #2 \__etl_act_result:n #3
  { #2 \__etl_act_result:n { #3 #1 } }
\cs_new:Npn \etl_act_output_pre:n #1 #2 \__etl_act_result:n #3
  { #2 \__etl_act_result:n { #1 #3 } }
\cs_new:Npn \etl_act_output_rest: #1 \s__etl_stop #2#3#4#5
  {
    #1 \s__etl_stop {#2}
    \__etl_act_output_normal:nN \__etl_act_output_space:n \__etl_act_output_group:nn
  }
\cs_new:Npn \etl_act_output_rest_pre: #1 \s__etl_stop #2#3#4#5
  {
    #1 \s__etl_stop {#2}
    \__etl_act_output_normal_pre:nN
    \__etl_act_output_space_pre:n
    \__etl_act_output_group_pre:nn
  }
\cs_new:Npn \__etl_act_output_normal:nN #1#2 #3 \__etl_act_result:n #4
  { #3 \__etl_act_result:n { #4 #2 } }
\cs_new:Npn \__etl_act_output_space:n #1 #2 \__etl_act_result:n #3
  { #2 \__etl_act_result:n { #3 ~ } }
\cs_new:Npn \__etl_act_output_group:nn #1#2 #3 \__etl_act_result:n #4
  { #3 \__etl_act_result:n { #4 {#2} } }
\cs_new:Npn \__etl_act_output_normal_pre:nN #1#2 #3 \__etl_act_result:n #4
  { #3 \__etl_act_result:n { #2 #4 } }
\cs_new:Npn \__etl_act_output_space_pre:n #1 #2 \__etl_act_result:n #3
  { #2 \__etl_act_result:n { ~ #3 } }
\cs_new:Npn \__etl_act_output_group_pre:nn #1#2 #3 \__etl_act_result:n #4
  { #3 \__etl_act_result:n { {#2} #4 } }
\cs_new:Npn \__etl_act_unexpanded_normal:nN #1 { \exp_not:N }
\cs_new:Npn \__etl_act_unexpanded_space:n #1 { ~ }
\cs_new:Npn \__etl_act_unexpanded_group:nn #1#2 { { \__etl_unexpanded:w {#2} } }
\cs_new:Npn \__etl_act_unexpanded_rest:w #1 \__etl_act:w #2#
  {
    \__etl_unexpanded:w {#2}
    \__etl_act_unexpanded_rest_aux:n
  }
\cs_new:Npn \__etl_act_unexpanded_rest_aux:w #1#
  {
    \__etl_unexpanded:w {#1}
    \__etl_act_unexpanded_rest_aux:n
  }
\cs_new:Npn \__etl_act_unexpanded_rest_aux:n #1
  {
    \__etl_act_if_end:w #1 \__etl_act_unexpanded_rest_done:w \s__etl_stop
    { \__etl_unexpanded:w {#1} }
    \__etl_act_unexpanded_rest_aux:w
  }
\cs_new:Npn \__etl_act_unexpanded_rest_done:w
    \s__etl_stop #1 \__etl_act_unexpanded_rest_aux:w
    . \s__etl_stop #2#3#4#5
    \__etl_act_result:n #6#7
  {}
\cs_new:Npn \etl_act_status:n #1 #2 \s__etl_stop #3
  { #2 \s__etl_stop {#1} }
\cs_new:Npn \etl_act_put_back:n #1 #2 \__etl_act:w { #2 \__etl_act:w #1 }
\cs_new:Npn \etl_act_switch:nnn #1#2#3 #4 \s__etl_stop #5#6#7#8
  { #4 \s__etl_stop {#5} {#1} {#2} {#3} }
\cs_new:Npn \etl_act_switch_normal:n #1 #2 \s__etl_stop #3#4
  { #2 \s__etl_stop {#3} {#1} }
\cs_new:Npn \etl_act_switch_space:n #1 #2 \s__etl_stop #3#4#5
  { #2 \s__etl_stop {#3} {#4} {#1} }
\cs_new:Npn \etl_act_switch_group:n #1 #2 \s__etl_stop #3#4#5#6
  { #2 \s__etl_stop {#3} {#4} {#5} {#1} }
\cs_new:Npn \etl_act_do_final: #1 \s__etl_stop #2#3 \__etl_act_result:n #4#5
  { #5 {#2} {#4} }
\cs_new:Npn \etl_act_break: #1 \__etl_act_result:n #2#3 { \__etl_unexpanded:w {#2} }
\cs_new:Npn \etl_act_break_discard: #1 \__etl_act_result:n #2#3 {}
\cs_new:Npn \etl_act_break:n #1 #2 \__etl_act_result:n #3#4
  { \__etl_unexpanded:w {#1} }
\cs_new:Npn \etl_act_break_pre:n #1 #2 \__etl_act_result:n #3#4
  { \__etl_unexpanded:w { #1 #3 } }
\cs_new:Npn \etl_act_break_post:n #1 #2 \__etl_act_result:n #3#4
  { \__etl_unexpanded:w { #3 #1 } }
\cs_new:Npn \etl_act_apply_to_rest:n #1
  {
    \__etl_expanded:w { \__etl_unexpanded:w {#1} { \if_false: }} \fi:
    \__etl_act_get_rest:w \prg_do_nothing:
  }
\cs_new:Npn \__etl_act_get_rest:w #1 \__etl_act:w #2#
  {
    \__etl_unexpanded:w {#2}
    \__etl_act_get_rest_aux:nn {#1}
  }
\cs_new:Npn \__etl_act_get_rest_aux:nw #1 #2#
  {
    \__etl_unexpanded:w {#2}
    \__etl_act_get_rest_aux:nn {#1}
  }
\cs_new:Npn \__etl_act_get_rest_aux:nn #1#2
  {
    \__etl_act_if_end:w #2 \__etl_act_get_rest_done:w \s__etl_stop
    { \__etl_unexpanded:w {#2} }
    \__etl_act_get_rest_aux:nw {#1}
  }
\cs_new:Npn \__etl_act_get_rest_done:w \s__etl_stop #1 \__etl_act_get_rest_aux:nw #2
  {
    \if_false: {{ \fi: } \exp_after:wN }
    #2
    \__etl_act:w { \s__etl_stop }
  }
\exp_args:Nno \use:n { \cs_new:Npn \etl_token_if_eq:NNTF #1#2 }
  {
    \token_if_eq_meaning:NNT {#1} {#2} { \str_if_eq:nnT #1#2 \use_ii:nnn }
    \use_ii:nn
  }
\exp_args:Nno
\use:n { \prg_new_conditional:Npnn \etl_token_if_eq:NN #1#2 { T , F , p } }
  {
    \token_if_eq_meaning:NNT {#1} {#2} { \str_if_eq:nnT #1#2 \__etl_turn_true:w }
    \if_false:
      \prg_return_true:
    \else:
      \prg_return_false:
    \fi:
  }
\exp_args:Nno
\use:n { \prg_new_conditional:Npnn \etl_token_if_in:nN #1#2 { TF , T , F , p } }
  {
    \__etl_act:nnnnnnn
        \__etl_token_if_in:NN \use_none:n \use_none:nn
        \__etl_act_just_result:nn
        {#2}
        \if_false:
        {#1}
      \prg_return_true:
    \else:
      \prg_return_false:
    \fi:
  }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_token_if_in:NN #1#2 }
  {
    \etl_token_if_eq:NNTF {#1} {#2} { \etl_act_break:n \if_true: } {}
  }
\exp_args:Nno \use:n
  { \prg_new_conditional:Npnn \etl_token_if_in_deep:nN #1#2 { TF , T , F , p } }
  {
    \__etl_act:nnnnnnn
        \__etl_token_if_in:NN \use_none:n \__etl_token_if_in_deep:Nn
        \__etl_act_just_result:nn
        {#2}
        \if_false:
        {#1}
      \prg_return_true:
    \else:
      \prg_return_false:
    \fi:
  }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_token_if_in_deep:Nn #1#2 }
  { \etl_token_if_in_deep:nNT {#2} {#1} { \etl_act_break:n \if_true: } }
\exp_args:Nno
\use:n { \prg_new_conditional:Npnn \etl_if_eq:nn #1#2 { TF , T , F , p } }
  {
    \__etl_act:nnnnnnn
        \__etl_if_eq_normal:nN
        \__etl_if_eq_space:n
        \__etl_if_eq_group:nn
        \__etl_if_eq_final:nn
        {#2}
        {}
        {#1}
      \prg_return_true:
    \else:
      \prg_return_false:
    \fi:
  }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_if_eq_normal:nN #1#2 }
  {
    \__etl_if_empty:nT {#1} { \etl_act_break:n \if_false: }
    \__etl_if_head_is_N_type:nTF {#1}
      {
        \exp_after:wN \__etl_if_eq_normal:NnN
          \__etl_expanded:w { \__etl_split_first:w #1 }
          #2
      }
      { \etl_act_break:n \if_false: }
  }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_if_eq_normal:NnN #1#2#3 }
  {
    \etl_token_if_eq:NNTF {#1} {#3}
      { \etl_act_status:n {#2} }
      { \etl_act_break:n \if_false: }
  }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_if_eq_space:n #1 }
  {
    \__etl_if_head_is_space:nTF {#1}
      { \exp_after:wN \etl_act_status:n \exp_after:wN { \__etl_rm_space:w #1 } }
      { \etl_act_break:n \if_false: }
  }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_if_eq_group:nn #1 }
  {
    \__etl_if_head_is_group:nTF {#1}
      {
        \exp_after:wN \__etl_if_eq_group:nnn
          \__etl_expanded:w { \__etl_split_first:w #1 }
      }
      { \etl_act_break:n \if_false: }
  }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_if_eq_group:nnn #1#2#3 }
  {
    \etl_if_eq:nnTF {#1} {#3}
      { \etl_act_status:n {#2} }
      { \etl_act_break:n \if_false: }
  }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_if_eq_final:nn #1#2 }
  {
    \exp_after:wN
    \__etl_unexpanded:w
    \__etl_if_empty:nT {#1} { { \if_true: } \use_none:n } { \if_false: }
  }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_if_in_put_back:n #1 }
  {
    \__etl_if_head_is_space:nTF {#1}
      { \exp_after:wN \etl_act_put_back:n \exp_after:wN { \__etl_rm_space:w #1 } }
      { \exp_after:wN \etl_act_put_back:n \exp_after:wN { \use_none:n #1 } }
  }
\exp_args:Nno
\use:n { \prg_new_conditional:Npnn \etl_if_in:nn #1#2 { TF , T , F , p } }
  {
    \__etl_act:nnnnnnn
        \__etl_if_in_normal:nN \__etl_if_in_space:n \__etl_if_in_group:nn
        \__etl_act_just_result:nn
        { { #2 } { #2 } {} }
        \if_false:
        { #1 ~ }
      \prg_return_true:
    \else:
      \prg_return_false:
    \fi:
  }
\cs_new:Npn \__etl_if_in_normal:nN #1 { \__etl_if_in_normal:nnnN #1 }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_if_in_normal:nnnN #1#2#3#4 }
  {
    \__etl_if_empty:nT {#1} { \etl_act_break:n \if_true: }
    \__etl_if_head_is_N_type:nTF {#1}
      {
        \exp_after:wN \__etl_if_in_normal:NnnnN
          \__etl_expanded:w { \__etl_split_first:w #1 } {#2} {#3} #4
      }
      {
        \etl_act_status:n { {#2} {#2} {} }
        \__etl_if_in_put_back:n { #3 #4 }
      }
  }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_if_in_normal:NnnnN #1#2#3#4#5 }
  {
    \etl_token_if_eq:NNTF {#1} {#5}
      { \etl_act_status:n { {#2} {#3} {#4#5} } }
      {
        \__etl_if_in_put_back:n { #4 #5 }
        \etl_act_status:n { {#3} {#3} {} }
      }
  }
\cs_new:Npn \__etl_if_in_space:n #1 { \__etl_if_in_space:nnn #1 }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_if_in_space:nnn #1#2#3 }
  {
    \__etl_if_empty:nT {#1} { \etl_act_break:n \if_true: }
    \__etl_if_head_is_space:nTF {#1}
      {
        \exp_after:wN \etl_act_status:n \exp_after:wN
          { \exp_after:wN { \__etl_rm_space:w #1 } {#2} { #3 ~ } }
      }
      {
        \__etl_if_in_put_back:n { #3 ~ }
        \etl_act_status:n { {#2} {#2} {} }
      }
  }
\cs_new:Npn \__etl_if_in_group:nn #1 { \__etl_if_in_group:nnnn #1 }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_if_in_group:nnnn #1 }
  {
    \__etl_if_empty:nT {#1} { \etl_act_break:n \if_true: }
    \__etl_if_head_is_group:nTF {#1}
      {
        \exp_after:wN \__etl_if_in_group:nnnnn
          \__etl_expanded:w { \__etl_split_first:w #1 }
      }
      { \__etl_if_in_group_false:nnn }
  }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_if_in_group:nnnnn #1#2#3#4#5 }
  {
    \etl_if_eq:nnTF {#1} {#5}
      { \etl_act_status:n { {#2} {#3} { #4 {#5} } } }
      {
        \__etl_if_in_put_back:n { #4 {#5} }
        \etl_act_status:n { {#3} {#3} {} }
      }
  }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_if_in_group_false:nnn #1#2#3 }
  {
    \__etl_if_in_put_back:n { #2 {#3} }
    \etl_act_status:n { {#1} {#1} {} }
  }
\exp_args:Nno
\use:n { \prg_new_conditional:Npnn \etl_if_in_deep:nn #1#2 { TF , T , F , p } }
  {
    \__etl_act:nnnnnnn
        \__etl_if_in_normal:nN \__etl_if_in_space:n \__etl_if_in_group_deep:nn
        \__etl_act_just_result:nn
        { { #2 } { #2 } {} }
        \if_false:
        { #1 ~ }
      \prg_return_true:
    \else:
      \prg_return_false:
    \fi:
  }
\cs_new:Npn \__etl_if_in_group_deep:nn #1 { \__etl_if_in_group_deep:nnnn #1 }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_if_in_group_deep:nnnn #1 }
  {
    \__etl_if_empty:nT {#1} { \etl_act_break:n \if_true: }
    \__etl_if_head_is_group:nTF {#1}
      {
        \exp_after:wN \__etl_if_in_group_deep:nnnnn
          \__etl_expanded:w { \__etl_split_first:w #1 }
      }
      { \__etl_if_in_group_deep_false:nnn }
  }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_if_in_group_deep:nnnnn #1#2#3#4#5 }
  {
    \etl_if_eq:nnTF {#1} {#5}
      { \etl_act_status:n { {#2} {#3} { #4 {#5} } } }
      {
        \etl_if_in_deep:nnT {#5} {#3} { \etl_act_break:n \if_true: }
        \__etl_if_in_put_back:n { #4 {#5} }
        \etl_act_status:n { {#3} {#3} {} }
      }
  }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_if_in_group_deep_false:nnn #1#2#3 }
  {
    \etl_if_in_deep:nnT {#3} {#1} { \etl_act_break:n \if_true: }
    \__etl_if_in_put_back:n { #2 {#3} }
    \etl_act_status:n { {#1} {#1} {} }
  }
\exp_args:Nno \use:n { \cs_new:Npn \etl_token_replace_all:nNn #1#2#3 }
  {
    \etl_act:nnnnnn
      { \__etl_token_replace:NnnN #2 {} }
      \__etl_act_unexpanded_space:n
      \__etl_act_unexpanded_group:nn
      \use_none:nn
      {#3}
      {#1}
  }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_token_replace:NnnN #1#2#3#4 }
  {
    \etl_token_if_eq:NNTF {#1} {#4}
      { \__etl_unexpanded:w {#3} #2 }
      { \__etl_unexpanded:w {#4} }
  }
\exp_args:Nno \use:n { \cs_new:Npn \etl_token_replace_all_deep:nNn #1#2#3 }
  {
    \etl_act:nnnnnn
      { \__etl_token_replace:NnnN #2 {} }
      \__etl_act_unexpanded_space:n
      { \__etl_token_replace_deep:Nnn #2 }
      \use_none:nn
      {#3}
      {#1}
  }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_token_replace_deep:Nnn #1#2#3 }
  { \exp_after:wN { \etl_token_replace_all_deep:nNn {#3} {#1} {#2} } }
\exp_args:Nno \use:n { \cs_new:Npn \etl_token_replace_once:nNn #1#2#3 }
  {
    \etl_act:nnnnnn
      { \__etl_token_replace:NnnN #2 \__etl_act_unexpanded_rest:w }
      \__etl_act_unexpanded_space:n
      \__etl_act_unexpanded_group:nn
      \use_none:nn
      {#3}
      {#1}
  }
\exp_args:Nno \use:n { \cs_new:Npn \etl_replace_all:nnn #1#2#3 }
  {
    \etl_act:nnnnnn
      \__etl_replace_normal:nN
      \__etl_replace_space:n
      \__etl_replace_group:nn
      \__etl_replace_final:nn
      { {#2} {#2} {} {#3} \prg_do_nothing: }
      {#1}
  }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_replace_put_back:nnnN #1#2#3#4 }
  {
    \__etl_if_head_is_space:nTF {#1}
      {
        \exp_after:wN \etl_act_put_back:n \exp_after:wN { \__etl_rm_space:w #1 } ~
      }
      {
        \__etl_if_head_is_group:nTF {#1}
          { \exp_after:wN \__etl_replace_put_back_group:nn }
          { \exp_after:wN \__etl_replace_put_back_normal:Nn }
          \__etl_expanded:w { \__etl_split_first:w #1 }
      }
    \etl_act_status:n { {#2} {#2} {} {#3} #4 }
  }
\cs_new:Npn \__etl_replace_put_back_group:nn #1
  {
    \__etl_unexpanded:w { {#1} }
    \etl_act_put_back:n
  }
\cs_new:Npn \__etl_replace_put_back_normal:Nn #1
  {
    \__etl_unexpanded:w {#1}
    \etl_act_put_back:n
  }
\cs_new:Npn \__etl_replace_normal:nN #1 { \__etl_replace_normal:nnnnNN #1 }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_replace_normal:nnnnNN #1 }
  {
    \__etl_if_head_is_N_type:nTF {#1}
      {
        \exp_after:wN \__etl_replace_normal:NnnnnNN
          \__etl_expanded:w { \__etl_split_first:w #1 }
      }
      { \__etl_replace_normal_false:nnnNN }
  }
\exp_args:Nno
\use:n { \cs_new:Npn \__etl_replace_normal:NnnnnNN #1#2#3#4#5#6#7 }
  {
    \etl_token_if_eq:NNTF {#1} {#7}
      {
        \__etl_if_empty:nTF {#2}
          {
            \__etl_unexpanded:w {#5}
            #6
            \etl_act_status:n { {#3} {#3} {} {#5} #6 }
          }
          { \etl_act_status:n { {#2} {#3} { #4 #7 } {#5} #6 } }
      }
      { \__etl_replace_put_back:nnnN { #4 #7 } {#3} {#5} #6 }
  }
\exp_args:Nno
\use:n { \cs_new:Npn \__etl_replace_normal_false:nnnNN #1#2#3#4#5 }
  { \__etl_replace_put_back:nnnN { #2 #5 } {#1} {#3} {#4} }
\cs_new:Npn \__etl_replace_space:n #1 { \__etl_replace_space:nnnnN #1 }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_replace_space:nnnnN #1 }
  {
    \__etl_if_head_is_space:nTF {#1}
      {
        \exp_after:wN \__etl_replace_space_aux:nnnnN \exp_after:wN
          { \__etl_rm_space:w #1 }
      }
      { \__etl_replace_space_false:nnnN }
  }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_replace_space_aux:nnnnN #1#2#3#4#5 }
  {
    \__etl_if_empty:nTF {#1}
      {
        \__etl_unexpanded:w {#4}
        #5
        \etl_act_status:n { {#2} {#2} {} {#4} #5 }
      }
      { \etl_act_status:n { {#1} {#2} { #3 ~ } {#4} #5 } }
  }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_replace_space_false:nnnN #1#2#3#4 }
  { \__etl_replace_put_back:nnnN { #2 ~ } {#1} {#3} {#4} }
\cs_new:Npn \__etl_replace_group:nn #1 { \__etl_replace_group:nnnnNn #1 }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_replace_group:nnnnNn #1 }
  {
    \__etl_if_head_is_group:nTF {#1}
      {
        \exp_after:wN \__etl_replace_group:nnnnnNn
          \__etl_expanded:w { \__etl_split_first:w #1 }
      }
      { \__etl_replace_group_false:nnnNn }
  }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_replace_group:nnnnnNn #1#2#3#4#5#6#7 }
  {
    \etl_if_eq:nnTF {#1} {#7}
      {
        \__etl_if_empty:nTF {#2}
          {
            \__etl_unexpanded:w {#5}
            #6
            \etl_act_status:n { {#3} {#3} {} {#5} #6 }
          }
          { \etl_act_status:n { {#2} {#3} { #4 {#7} } {#5} #6 } }
      }
      { \__etl_replace_put_back:nnnN { #4 {#7} } {#3} {#5} #6 }
  }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_replace_group_false:nnnNn #1#2#3#4#5 }
  { \__etl_replace_put_back:nnnN { #2 {#5} } {#1} {#3} {#4} }
\cs_new:Npn \__etl_replace_final:nn #1 { \__etl_replace_final:nnnnNn #1 }
\cs_new:Npn \__etl_replace_final:nnnnNn #1#2#3#4#5#6 { \__etl_unexpanded:w { #6#3 } }
\exp_args:Nno \use:n { \cs_new:Npn \etl_replace_all_deep:nnn #1#2#3 }
  {
    \etl_act:nnnnnn
      \__etl_replace_normal:nN
      \__etl_replace_space:n
      \__etl_replace_group_deep:nn
      \__etl_replace_final:nn
      { {#2} {#2} {} {#3} \prg_do_nothing: }
      {#1}
  }
\cs_new:Npn \__etl_replace_group_deep:nn #1
  { \__etl_replace_group_deep:nnnnNn #1 }
\exp_args:Nno \use:n { \cs_new:Npn \__etl_replace_group_deep:nnnnNn #1 }
  {
    \__etl_if_head_is_group:nTF {#1}
      {
        \exp_after:wN \__etl_replace_group_deep:nnnnnNn
          \__etl_expanded:w { \__etl_split_first:w #1 }
      }
      { \__etl_replace_group_deep_false:nnnNn }
  }
\exp_args:Nno
\use:n { \cs_new:Npn \__etl_replace_group_deep:nnnnnNn #1#2#3#4#5#6#7 }
  {
    \etl_if_eq:nnTF {#1} {#7}
      {
        \__etl_if_empty:nTF {#2}
          {
            \__etl_unexpanded:w {#5}
            \etl_act_status:n { {#3} {#3} {} {#5} #6 }
          }
          { \etl_act_status:n { {#2} {#3} { #4 {#7} } {#5} #6 } }
      }
      {
        \__etl_if_empty:nTF {#4}
          {
            { \etl_replace_all_deep:nnn {#7} {#3} {#5} }
            \etl_act_status:n { {#3} {#3} {} {#5} #6 }
          }
          { \__etl_replace_put_back:nnnN { #4 {#7} } {#3} {#5} #6 }
      }
  }
\exp_args:Nno
\use:n { \cs_new:Npn \__etl_replace_group_deep_false:nnnNn #1#2#3#4#5 }
  {
    \__etl_if_empty:nTF {#2}
      {
        { \etl_replace_all_deep:nnn {#5} {#1} {#3} }
        \etl_act_status:n { {#1} {#1} {} {#3} #4 }
      }
      { \__etl_replace_put_back:nnnN { #2 {#5} } {#1} {#3} #4 }
  }
\exp_args:Nno \use:n { \cs_new:Npn \etl_replace_once:nnn #1#2#3 }
  {
    \etl_act:nnnnnn
      \__etl_replace_normal:nN
      \__etl_replace_space:n
      \__etl_replace_group:nn
      \__etl_replace_final:nn
      { {#2} {#2} {} {#3} \__etl_act_unexpanded_rest:w }
      {#1}
  }
\exp_args:Nno \use:n { \cs_new_protected:Npn \etl_new_if_in:Nnn #1#2#3 }
  {
    \scan_stop:
    \if_false: { \fi:
    \exp_args:Nc \__etl_new_if_in:NnNnn
      { __etl_user_function ~ if_in ~ \tl_to_str:n {#2} :w }
      ?
      #1 {#2}
      {#3}
    \if_false: } \fi:
  }
\cs_new_protected:Npn \__etl_new_if_in:NnNnn #1#2#3#4
  {
    \cs_if_exist:NTF #1
      {
        \cs_set:Npn \__etl_tmp:w ##1 #4 {}
        \cs_if_eq:NNTF #1 \__etl_tmp:w
          { \__etl_new_if_in:NNnn #1 #3 {#4} }
          {
            \exp_args:Nc \__etl_new_if_in:NnNnn
              { __etl_user_function ~ if_in #2 ~ \tl_to_str:n {#4} :w }
              { #2? }
              #3 {#4}
          }
      }
      { \__etl_new_if_in:NNnn #1 #3 {#4} }
  }
\cs_new_protected:Npn \__etl_new_if_in:NNnn #1#2#3#4
  {
    \cs_gset:Npn #1 ##1 #3 {}
    \prg_new_conditional:Npnn #2 ##1 {#4}
      {
        \if:w
            \scan_stop:
            \__etl_detokenize:w \exp_after:wN { #1 ##1 {}{} #3 }
            \scan_stop:
          \__etl_fi_turn_false:w
        \fi:
        \if_true:
          \prg_return_true:
        \else:
          \prg_return_false:
        \fi:
      }
  }
\msg_new:nnn { etl } { empty-search-text }
  { The~ search~ text~ of~ #1 must~ not~ be~ empty. }
\cs_new_protected:Npn \__etl_new_replace_def:NNn #1#2#3
  {
    \tl_if_empty:nTF {#3}
      { \msg_error:nnn { etl } { empty-search-text } { #2 } }
      {
        \scan_stop:
        \if_false: { \fi:
        \exp_args:Nc \__etl_new_replace_def_aux:NnNnN
          { __etl_user_function ~ replace ~ \tl_to_str:n {#3} ~ :Nnw }
          ?
          #2 {#3}
          #1
        \if_false: } \fi:
      }
  }
\cs_new_protected:Npn \__etl_new_replace_def_aux:NnNnN #1#2#3#4#5
  {
    \cs_if_exist:NTF #1
      {
        \__etl_new_replace_def_aux:Nn \__etl_tmp:w {#4}
        \cs_if_eq:NNTF #1 \__etl_tmp:w
          { #5 #1#3 {#4} }
          {
            \exp_args:Nc \__etl_new_replace_def_aux:NnNnN
              { __etl_user_function ~ replace #2 ~ \tl_to_str:n {#4} ~ :Nnw }
              { #2? } #3 {#4} #5
          }
      }
      {
        \__etl_new_replace_def_aux:Nn #1 {#4}
        #5 #1#3 {#4}
      }
  }
\cs_new_protected:Npn \__etl_new_replace_def_aux:Nn #1#2
  {
    \cs_gset:Npn #1 ##1##2 ##3#2
      {
        \__etl_new_replace_wrap:w ##3 \s__etl_stop \__etl_unexpanded:w {##2}
        ##1 #1 {##2} {}{}
      }
  }
\cs_new:Npn \__etl_new_replace_wrap:w #1\s__etl_stop
  { \__etl_unexpanded:w \exp_after:wN { \use_none:nn #1 } }
\cs_new:Npn \__etl_new_replace_once:w #1#2 #3\s__etl_stop
  { \__etl_unexpanded:w \exp_after:wN { \use_none:nn #3 } }
\cs_new:Npn \__etl_new_replace_done:w
  { \exp_after:wN \use_none:n \exp_after:wN { \if_false: } \fi: }
\cs_new_protected:Npn \etl_new_replace_once:Nn
  { \__etl_new_replace_def:NNn \__etl_new_replace_once:NNn }
\cs_new_protected:Npn \__etl_new_replace_once:NNn #1#2#3
  {
    \cs_new:Npn #2 ##1##2
      {
        \__etl_unexpanded:w \__etl_expanded:w
          {{
            \if_false: { \fi:
              #1 \__etl_new_replace_once:w {##2} {}{} ##1 \s__etl_stop
              \__etl_new_replace_done:w #3
            }
          }}
      }
  }
\cs_new_protected:Npn \etl_new_replace_all:Nn
  { \__etl_new_replace_def:NNn \__etl_new_replace_all:NNn }
\cs_new_protected:Npn \__etl_new_replace_all:NNn #1#2#3
  {
    \cs_new:Npn #2 ##1##2
      {
        \__etl_unexpanded:w \__etl_expanded:w
          {{
            \if_false: { \fi:
              #1 #1 {##2} {}{} ##1 \s__etl_stop
              \__etl_new_replace_done:w #3
            }
          }}
      }
  }
\cs_undefine:N \__etl_act:nnnnnnn
%% 
%%
%% End of file `etl.sty'.
