%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
% This is file 'newenviron.sty', version 1.0, Match 2013.                  %
%                                                                          %
% This package and accompanying files may be distributed and/or            %
% modified under the conditions of the LaTeX Project Public License,       %
% either version 1.3 of this license or any later version. The latest      %
% version of this license is in http://www.latex-project.org/lppl.txt      %
% and version 1.3 or later is part of all distributions of LaTeX           %
% version 2005/12/01 or later.                                             %
%                                                                          %
% The LPPL maintenance status of this software is 'author-maintained'.     %
%                                                                          %
% This software is provided 'as it is', without warranty of any kind,      %
% either expressed or implied, including, but not limited to, the          %
% implied warranties of merchantability and fitness for a particular       %
% purpose.                                                                 %
%                                                                          %
% Copyright (c) 2013 Ahmed Musa (amusa22@gmail.com).                       %
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%

\@ifpackageloaded{catoptions}{}{\RequirePackage{catoptions}[2011/12/12]}
\UseNormalCatcodes
\StyleFilePurpose{Collect and execute environment body (AM)}
\StyleFileRCSInfo
$Id: newenviron.sty,v 1.0 2013/03/08 09:00:00 Ahmed Musa Exp $
\ProvidesPackage{newenviron}[\StyleFileInfo]
\NeedsTeXFormat{LaTeX2e}[2011/06/27]

% Collect environment body in macro \envbody and \<env name>body.
%
\cptnewvariables{toks}[nenv@]{temptoks}
\new@def\nenv@gobbletomarker#1\nenv@endmarker{}
\new@def*\nevn@quark{}
\new@def*\AlwaysTrimEnvEntries{\global\nenv@alwaystrimtrue}
\new@def*\nenv@trimspace{%
  \ifdefboolTF{nenv@alwaystrim}\cpttrimspace\unexpanded
}
\new@def*\nenv@everybegin@hook{}
\robust@def*\EveryBeginOfEnvironment#1{%
  \xifinsetTF
  {\detokenize{\nevn@quark#1\nevn@quark}}
  {\cptoxdetok\nenv@everybegin@hook}{}{%
    \edef\nenv@everybegin@hook{%
      \expandcsonce\nenv@everybegin@hook
      \noexpand\nevn@quark\unexpanded{#1}\noexpand\nevn@quark
    }%
  }%
}
\new@def*\nenv@everyend@hook{}
\robust@def*\EveryEndOfEnvironment#1{%
  \xifinsetTF
  {\detokenize{\nevn@quark#1\nevn@quark}}
  {\cptoxdetok\nenv@everyend@hook}{}{%
    \edef\nenv@everyend@hook{%
      \expandcsonce\nenv@everyend@hook
      \noexpand\nevn@quark\unexpanded{#1}\noexpand\nevn@quark
    }%
  }%
}
\EveryEndOfEnvironment{\@ignoretrue}
\robust@def*\nenv@appto#1#2{%
  \ifdefTF#1{%
    \edef#1{\expandcsonce#1\unexpanded{#2}}%
  }{%
    \edef#1{\unexpanded{#2}}%
  }%
}
%
% \newenviron<optional *>
%   {<name>}[<narg>][<default of 1st argument>]{<start-code>}{<end-code>}
%
% \renewenviron<optional *>
%   {<name>}[<narg>][<default of 1st argument>]{<start-code>}{<end-code>}
%
\robust@def*\newenviron{\cpt@starorlong\nenv@newenviron}
\robust@def*\nenv@newenviron#1{%
  \edef\cpt@tempa{\cpttrimspace{#1}}%
  \cptexpandarg\cpt@testopt
    {\nenv@newenviron@a{\expandcsonce\cpt@tempa}}{0}%
}
\robust@def*\nenv@newenviron@a#1[#2]{%
  \cpt@ifbrack{\nenv@newenviron@b#1[#2]}{\nenv@newenviron@c{#1}{[#2]}}%
}
\robust@def*\nenv@newenviron@b#1[#2][#3]{\nenv@newenviron@c{#1}{[#2][{#3}]}}
\robust@def\nenv@newenviron@c#1#2#3#4{%
  \ifcsndefTF{#1}{}{\letcsntocsn{#1}{end#1}}%
  \aftercsname\new@command{#1}#2{%
    \edef\nenv@beforebody{\nenv@trimspace{#3}}%
    \nenv@everybegin@hook
    \nenv@collectbody
  }%
  \l@ngrel@x\csn@edef{end#1}{%
    % We want any parameter characters in #4 to be doubled by
    % the user at environment definition time. The aim is that in both
    % <start code> and <end code>, the parameter characters should be
    % doubled for any new macro definition. For example,
    %
    % \newenviron{assertion}
    %   {\def\acmd##1{##1}}
    %   {\def\bcmd##1{##1}\assertionbody}
    %
    % Any #1, #2, etc. in <start code> refer to the parameters of
    % \assertion.
    %
    \def\noexpand\cpt@prova{\nenv@trimspace{#4}}\noexpand\cpt@prova
    \noexpand\nenv@everyend@hook
  }%
}
\robust@def*\nenv@collectbody{%
  \begingroup
  \toks@{}%
  \everyeof{\end{EOF}\relax}%
  \nenv@collectbody@a
}
\robust@def\nenv@collectbody@a#1\end#2{%
  \nenv@temptoks{%
    \cptexpanded{%
      \toks@{%
        \the\toks@\nenv@trimspace{#1}%
        \noexpand\end{\expandcsonce\cpt@argofend}%
      }%
    }%
    \nenv@collectbody@a
  }%
  \edef\cpt@argofend{\cpttrimspace{#2}}%
  \ifcseqTF\cpt@argofend\@currenvir{%
    \def\cpt@tempa{}%
    \nenv@pushbegin#1\begin\end\nenv@endmarker
    \ifcsemptyTF\cpt@tempa{%
      % Last end of \newenviron grabbed:
      \cptexpanded{\endgroup
        \csn@edef{\@currenvir body}{%
          \noexpand\unexpanded{\the\toks@\nenv@trimspace{#1}}%
        }%
        \letcstocsn\noexpand\envbody{\@currenvir body}%
        \unexpanded{%
          \nenv@beforebody\relax
          \ifdefboolTF{nenv@alwaystrim}\@ignoretrue\relax
        }%
        \noexpand\end{\cpt@argofend}%
      }%
    }{%
      % Nested \newenviron: add current #1 and continue:
      \the\nenv@temptoks
    }%
  }{%
    \oifstrcmpTF{\cpt@argofend}{document}{%
      \expandafter\endgroup\expandafter
        \@checkend\expandafter{\cpt@argofend}%
    }{%
      \oifstrcmpTF{\cpt@argofend}{EOF}{%
        \expandafter\endgroup\expandafter
          \@checkend\expandafter{\cpt@argofend}%
      }{%
        \the\nenv@temptoks
      }%
    }%
  }%
}
\new@def\nenv@pushbegin#1\begin#2{%
  \expandafter\ifx\cpt@car#2x\car@nil\end
    \expandafter\@gobble
  \else
    \edef\cpt@prova{\cpttrimspace{#2}}%
    \ifx\cpt@prova\cpt@argofend
      \def\cpt@tempa{x}%
      \expandafter\expandafter\expandafter\nenv@gobbletomarker
    \else
      \expandafter\expandafter\expandafter\nenv@pushbegin
    \fi
  \fi
}
\robust@def*\renewenviron{\cpt@starorlong\nenv@renewenviron}
\robust@def*\nenv@renewenviron#1{%
  \edef\cpt@tempa{\cpttrimspace{#1}}%
  \ifcsndefTF\cpt@tempa
    {}
    {\@latex@error{Environment #1 is undefined}\@ehd}%
  \letcsntocs\cpt@tempa\relax
  \letcsntocs{end\cpt@tempa}\relax
  \expandafter\nenv@newenviron\expandafter{\cpt@tempa}%
}
\XDeclareBooleanOption{alwaystrim}[true](nenv@){}{}
\XDeclareOption*{\@@warning{Unknown option '\CurrentOption' ignored}}
\XExecuteOptions{alwaystrim}
\XProcessOptions*\relax

\endinput
