%%%==============================================================================
%% Copyright 2025-present by Alceu Frigeri
%%
%% This work may be distributed and/or modified under the conditions of
%%
%% * The [LaTeX Project Public License](http://www.latex-project.org/lppl.txt),
%%   version 1.3c (or later), and/or
%% * The [GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.html),
%%   version 3 (or later)
%%
%% This work has the LPPL maintenance status *maintained*.
%%
%% The Current Maintainer of this work is Alceu Frigeri
%%
%% This is version {1.3} {2025/10/23}
%%
%% The list of files that compose this work can be found in the README.md file at
%% https://ctan.org/pkg/xpeekahead
%%
%%%==============================================================================
\NeedsTeXFormat{LaTeX2e}[2022/06/01]

\ProvidesExplPackage
    {xpeekahead}
    {2025/10/23}
    {1.3}
    {A simplistic peek ahead set up}

%%%%%%%
%%%
%%% Just an attempt of having my packages info in a regular way
%%% \pkginfograb_set:nn {<pkg-name>} { props} for each and all.
%%%
%%%%%%%
\RequirePackage{pkginfograb}
\pkginfograb_set:nn { xpeekahead }
  {
     name        = {xpeekahead} ,
     prefix      = {xpeekahead} ,
     date        = {2025/10/23},
     version     = {1.3} ,
     description = {A simplistic peek ahead set up}
  }
%%%%%%%
%%% End of cut-n-paste
%%%%%%%

\msg_new:nnnn {xpeekahead} {deprecated}
  {
    (ID:#1)~#2 ~ is ~ deprecated.~ use~ '#3' ~ instead
  }
  {
    You~tried~to~use~a~deprecated~command:~#2. Use~'#3'~ instead.
    ~Error~Code~ ID:<#1>.
  }

\keys_define:nn { xpeekahead }
  {
    strict .usage:n    = load ,
    strict .code:n = 
      {
        \msg_redirect_module:nnn {xpeekahead} { warning } { error }
      } ,
  }
\ProcessKeyOptions [xpeekahead]

%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%

%%%
%%% Note that the TF endings
%%% are just for readability
%%% these commands aren't
%%% expl3 \prg_condicionals 
%%%

%%% This for the TF cases
%%%
\cs_new:Npn \__xpeekahead_set:NNnnnn #1#2#3#4#5#6
  {
    #1 #3
      {
        #2 { #4 }
          { #5 }
          { #6 }        
      }
  }

%%% This for the T or F cases
%%%
\cs_new:Npn \__xpeekahead_set:NNnnn #1#2#3#4#5
  {
    #1 #3
      {
        #2 { #4 }
          { #5 }
      }
  }
%%%
%%% bending the expl3 rules a bit...
%%% Those above expects 6(5) parameters, 
%%% whereas the following commands will insert 
%%% 2 parameters *before* the user given 4(3)...
%%%

\cs_new_protected:Npn \xpeekahead_set:NnTF 
  { \__xpeekahead_set:NNnnnn \cs_set_protected:Npn \peek_regex:nTF }
\cs_new_protected:Npn \xpeekahead_set:NnT
  { \__xpeekahead_set:NNnnn \cs_set_protected:Npn \peek_regex:nT }
\cs_new_protected:Npn \xpeekahead_set:NnF 
  { \__xpeekahead_set:NNnnn \cs_set_protected:Npn \peek_regex:nF }


\cs_new_protected:Npn \xpeekahead_gset:NnTF 
  { \__xpeekahead_set:NNnnnn \cs_gset_protected:Npn \peek_regex:nTF }
\cs_new_protected:Npn \xpeekahead_gset:NnT
  { \__xpeekahead_set:NNnnn \cs_gset_protected:Npn \peek_regex:nT }
\cs_new_protected:Npn \xpeekahead_gset:NnF 
  { \__xpeekahead_set:NNnnn \cs_gset_protected:Npn \peek_regex:nF }

\cs_new_protected:Npn \xpeekahead_set:NNTF 
  { \__xpeekahead_set:NNnnnn \cs_set_protected:Npn \peek_regex:NTF }
\cs_new_protected:Npn \xpeekahead_set:NNT
  { \__xpeekahead_set:NNnnn \cs_set_protected:Npn \peek_regex:NT }
\cs_new_protected:Npn \xpeekahead_set:NNF 
  { \__xpeekahead_set:NNnnn \cs_set_protected:Npn \peek_regex:NF }

\cs_new_protected:Npn \xpeekahead_gset:NNTF 
  { \__xpeekahead_set:NNnnnn \cs_gset_protected:Npn \peek_regex:NTF }
\cs_new_protected:Npn \xpeekahead_gset:NNT
  { \__xpeekahead_set:NNnnn \cs_gset_protected:Npn \peek_regex:NT }
\cs_new_protected:Npn \xpeekahead_gset:NNF 
  { \__xpeekahead_set:NNnnn \cs_gset_protected:Npn \peek_regex:NF }


\cs_new:Npn \__xpeekahead_cmd_peek:Nnnn #1#2#3#4
  {
    #1 
      \__xpeekahead_cmd_peek_aux: 
      { #2 } { #3 } { #4 }     
    \xpeekahead_cmd_peek:N \__xpeekahead_cmd_peek_aux:
  }
\cs_new:Npn \__xpeekahead_cmd_peek:Nnn #1#2#3
  {
    #1 
      \__xpeekahead_cmd_peek_aux: 
      { #2 } { #3 }
    \xpeekahead_cmd_peek:N \__xpeekahead_cmd_peek_aux:
  }
%%%
%%% same (regarding expl3 rules)
%%% the following commands will insert 
%%% 1 parameter *before* the user given 3(2)...
%%%

\cs_new_protected:Npn \xpeekahead_cmd_peek:nTF
  { \__xpeekahead_cmd_peek:Nnnn \xpeekahead_set:NnTF }
\cs_new_protected:Npn \xpeekahead_cmd_peek:nT
  { \__xpeekahead_cmd_peek:Nnn \xpeekahead_set:NnT }
\cs_new_protected:Npn \xpeekahead_cmd_peek:nF
  { \__xpeekahead_cmd_peek:Nnn \xpeekahead_set:NnF }

\cs_new_protected:Npn \xpeekahead_cmd_peek:NTF
  { \__xpeekahead_cmd_peek:Nnnn \xpeekahead_set:NNTF }
\cs_new_protected:Npn \xpeekahead_cmd_peek:NT
  { \__xpeekahead_cmd_peek:Nnn \xpeekahead_set:NNT }
\cs_new_protected:Npn \xpeekahead_cmd_peek:NF
  { \__xpeekahead_cmd_peek:Nnn \xpeekahead_set:NNF }

  
  
\cs_new_protected:Npn \xpeekahead_cmd_peek:N #1
  {
    \peek_remove_spaces:n
      {
        \peek_analysis_map_inline:n
          {
            \exp_args:No \token_if_eq_meaning:NNF { ##1 } \para_end:
              {
                \peek_analysis_map_break:n
                  {
                    \exp_after:wN
                      #1
                    ##1
                  }
              }
            ##1
          }
     }
  }

\cs_set_eq:NN \__xpeekahead_tmpi: \relax
  
\cs_new_protected:Npn \__xpeekahead_env_end:n #1
  {
    \tl_if_eq:nVTF { #1 } \l__xpeekahead_peekenv_tl
      {
        % Environment context closes when calling {end~} 
        % therefore the peek function has to be saved first (\group_insert_after:N doesn't work here)
        \cs_gset_eq:NN \__xpeekahead_tmpi: \__xpeekahead_env_peek_cmd:
        \__xpeekahead_org_end:n {#1} %% context closed !!!
        \xpeekahead_cmd_peek:N  \__xpeekahead_tmpi: 
      }
      {
        \__xpeekahead_org_end:n {#1}
      }
  }

\cs_new_protected:Npn \__xpeekahead_set_end:n 
  {
    %% WARNING: assuming end~ won't change thereafter.
    \cs_if_exist:NF \__xpeekahead_org_end:n
      { \cs_set_eq:Nc \__xpeekahead_org_end:n { end~ } }
    \cs_set_eq:cN { end~ } \__xpeekahead_env_end:n
    \tl_set:Nn \l__xpeekahead_peekenv_tl 
  }

\cs_new_protected:Npn \xpeekahead_env_set:nN #1#2
  {
    \__xpeekahead_set_end:n {#1}
    \cs_set_eq:NN \__xpeekahead_env_peek_cmd: #2
  }

%\cs_new_protected:Npn \__xpeekahead_env_set:Nnnnn #1#2#3#4#5
\cs_new_protected:Npn \__xpeekahead_env_set:Nnnnn #1#2
  {
    \__xpeekahead_set_end:n {#2}
    #1 
      \__xpeekahead_env_peek_cmd: 
  }
    % used to be {#3} {#4} {#5} %keeping the signature for readability (it expects 5 parameters)

%\cs_new_protected:Npn \__xpeekahead_env_set:Nnnn #1#2#3#4
\cs_new_protected:Npn \__xpeekahead_env_set:Nnnn #1#2
  {
    \__xpeekahead_set_end:n {#2}
    #1 
      \__xpeekahead_env_peek_cmd: 
  }
    % used to be {#3} {#4}  %keeping the signature for readability (it expects 4 parameters)

%%%
%%% same (regarding expl3 rules)
%%% the following commands will insert 
%%% 1 parameter *before* the user given 4(3)...
%%%

\cs_new_protected:Npn \xpeekahead_env_set:nnTF 
  { \__xpeekahead_env_set:Nnnnn \xpeekahead_set:NnTF }
\cs_new_protected:Npn \xpeekahead_env_set:nnT
  { \__xpeekahead_env_set:Nnnn \xpeekahead_set:NnT }
\cs_new_protected:Npn \xpeekahead_env_set:nnF 
  { \__xpeekahead_env_set:Nnnn \xpeekahead_set:NnF }

\cs_new_protected:Npn \xpeekahead_env_set:nNTF 
  { \__xpeekahead_env_set:Nnnnn \xpeekahead_set:NNTF }
\cs_new_protected:Npn \xpeekahead_env_set:nNT 
  { \__xpeekahead_env_set:Nnnn \xpeekahead_set:NNT }
\cs_new_protected:Npn \xpeekahead_env_set:nNF 
  { \__xpeekahead_env_set:Nnnn \xpeekahead_set:NNF }
  
%%%
%%%
%%% LaTeX2e alliases
%%%
%%%

\cs_new_eq:NN \xpeekSetCmd \xpeekahead_set:NnTF
\cs_new_eq:NN \xpeekSetCmdGlobal \xpeekahead_gset:NnTF

\cs_new_eq:NN \xpeekTok \xpeekahead_cmd_peek:nTF
\cs_new_eq:NN \xpeekTokCmd \xpeekahead_cmd_peek:N

\cs_new_eq:NN \xpeekEnv \xpeekahead_env_set:nnTF 
\cs_new_eq:NN \xpeekEnvCmd \xpeekahead_env_set:nN


%%%
%%%
%%% Deprecated ones (sorry)
%%%
%%%

\cs_new_protected:Npn \xpeekahead_set:Nnnn     { \msg_warning:nnnnn {xpeekahead} {deprecated} {\xpeekahead_set:Nnnn}     {\xpeekahead_set:NnTF} }
\cs_new_protected:Npn \xpeekahead_gset:Nnnn    { \msg_warning:nnnnn {xpeekahead} {deprecated} {\xpeekahead_gset:Nnnn}    {\xpeekahead_gset:NnTF} }
\cs_new_protected:Npn \xpeekahead_set:NNnn     { \msg_warning:nnnnn {xpeekahead} {deprecated} {\xpeekahead_set:NNnn}     {\xpeekahead_set:NNTF} } 
\cs_new_protected:Npn \xpeekahead_gset:NNnn    { \msg_warning:nnnnn {xpeekahead} {deprecated} {\xpeekahead_gset:NNnn}    {\xpeekahead_gset:NNTF} } 
\cs_new_protected:Npn \xpeekahead_cmd_peek:nnn { \msg_warning:nnnnn {xpeekahead} {deprecated} {\xpeekahead_cmd_peek:nnn} {\xpeekahead_cmd_peek:nTF} }
\cs_new_protected:Npn \xpeekahead_cmd_peek:Nnn { \msg_warning:nnnnn {xpeekahead} {deprecated} {\xpeekahead_cmd_peek:Nnn} {\xpeekahead_cmd_peek:NTF} }
\cs_new_protected:Npn \xpeekahead_env_set:nnnn { \msg_warning:nnnnn {xpeekahead} {deprecated} {\xpeekahead_env_set:nnnn} {\xpeekahead_env_set:nnTF} } 
\cs_new_protected:Npn \xpeekahead_env_set:nNnn { \msg_warning:nnnnn {xpeekahead} {deprecated} {\xpeekahead_env_set:nNnn} {\xpeekahead_env_set:nNTF} } 

