\RequirePackage{expkv-def}

\ExplSyntaxOn
\cs_new_eq:NN \enverb@count \tl_count:n
\cs_set:Npx \enverb@othercr { \char_generate:nn {13} {12} }
\ExplSyntaxOff
%% key setup
\ekvdefinekeys{enverb}
  {
     boolTF auto-ignore    = \enverb@ifautoignore
    ,initial auto-ignore
    ,protected code ignore = \let\enverb@ifautoignore\@secondoftwo
    ,eint more-ignore      = \enverb@moreignore
    ,initial more-ignore   = 2
    ,also eint ignore      = \enverb@ignore
    ,boolTF same-line = \enverb@ifsameline
    ,unknown-choice same-line =
      \let\enverb@ifsameline\@firstoftwo\edef\enverb@codeshare{\unexpanded{#1}}
    ,initial same-line = 0.75
    ,invboolTF other-line = \enverb@ifsameline
    ,nmeta below = {same-line=false, no-aboveskip, no-belowskip}
    ,nmeta undo-below = {same-line=true, aboveskip, belowskip}
    ,store same-line-lst = \enverb@options@lst@same
    ,store same-line-tcb = \enverb@options@tcb@same
    ,initial same-line-lst = {aboveskip=0pt,belowskip=0pt}
    ,initial same-line-tcb = {nobeforeafter,box align=center}
    ,store other-line-lst = \enverb@options@lst@other
    ,store other-line-tcb = \enverb@options@tcb@other
    ,meta slst = same-line-lst={#1}
    ,meta stcb = same-line-tcb={#1}
    ,meta olst = other-line-lst={#1}
    ,meta otcb = other-line-tcb={#1}
    ,store lst = \enverb@options@lst
    ,store tcb = \enverb@options@tcb
    ,long store bol = \enverb@bol@content
    ,long store eol = \enverb@eol@content
    ,einitial eol   = \enverb@othercr
    ,boolTF no-lst  = \enverb@ifno@lst
    ,also nmeta no-lst = below
    ,boolTF no-tcb  = \enverb@ifno@tcb
    ,also nmeta no-tcb = below
    ,nmeta undo-no-tcb = {no-tcb=false, undo-below}
    ,store inter   = \enverb@inter
    ,data  gappend = \enverb@append
    ,dataT pre-tcb = \enverb@pretcb
    ,store after   = \enverb@after
    ,nmeta store   = gappend=\enverb@store
    ,noval no-store = \let\enverb@append\@secondoftwo
    ,nmeta restore = {pre-tcb=\enverb@store,after=\enverb@clear@store}
    ,code aboveskip = \edef\enverb@aboveskip{\vskip\unexpanded{#1}\relax}
    ,code belowskip = \edef\enverb@belowskip{\vskip\unexpanded{#1}\relax}
    ,default aboveskip = \medskipamount
    ,default belowskip = \medskipamount
    ,initial aboveskip
    ,initial belowskip
    ,noval no-aboveskip = \let\enverb@aboveskip\@empty
    ,noval no-belowskip = \let\enverb@belowskip\@empty
  }
\protected\long\ekvsetdef\enverbsetup{enverb}
\protected\def\enverb@clear@store{\global\let\enverb@store\@empty}
\enverb@clear@store

%% start of nested environments
\newcommand\enverb@tcb
  {%
    \expanded
      {%
        \noexpand\begin{exresult}%
          [{%
            \enverb@options@tcb,%
            \enverb@ifsameline\enverb@options@tcb@same\enverb@options@tcb@other
          }]%
      }%
      {\linewidth\enverb@ifsameline{-\enverb@codeshare\linewidth}{}}%
  }
\newcommand\enverb@lst
  {%
    \expanded
      {%
        \noexpand\begin{lstlisting}%
          [{%
            \enverb@options@lst,%
            \enverb@ifsameline\enverb@options@lst@same\enverb@options@lst@other
          }]%
      }%
  }

%% auxiliary error function
\newcommand\enverb@error[1]
  {%
    \GenericError
      {(enverb)\@spaces\@spaces\@spaces\@spaces}%
      {Environment enverb error: #1}%
      {Just use it correctly!}%
      {Read the sources.}%
  }

%% setup for weird category code regime
\begingroup
\lccode`\~=`\^^M
\catcode`\:=13
\lccode`\:=`\ % <- space
\catcode`\;=13
\lccode`\;=`\^^I % <- tab
\lowercase{\endgroup
%% code for spaces and CR
\def\enverb@body@space{}%
\def\enverb@body@tab{}%
\def\enverb@body@newline#1~%
  {\enverb@ifnotend{#1}{\enverb@bol\unexpanded{#1}\enverb@eol~}}%
%% activate the category code regime of the body
\protected\def\enverb@body@setup
  {%
    \let\enverb@collected@body\@empty
    \let\do\@makeother\dospecials
    \catcode`\^^M=13 \let~\enverb@body@newline
    \catcode`\   =13 \let:\enverb@body@space
    \catcode`\^^I=13 \let;\enverb@body@tab
    \let\enverb@bol\relax
    \let\enverb@eol\relax
  }
%% check for optional argument
\newcommand\enverb@search@oarg@a
  {%
    \ifx:\next
      \ifenverb@firsteol
      \else
        \enverb@body@add{:}%
      \fi
      \let\next\enverb@search@oarg@b
    \else
      \ifx~\next
        \ifenverb@firsteol
          \enverb@firsteolfalse
        \else
          \enverb@body@add{~}%
        \fi
        \let\next\enverb@search@oarg@b
      \else
        \ifx[\next\@gobble]%
          \let\next\enverb@oarg
        \else
          \ifenverb@firsteol
            \let\next\enverb@body@after@begin
          \else
            \let\next\enverb@body
          \fi
        \fi
      \fi
    \fi
    \next
  }
%% start body collection
\newcommand\enverb@body
  {\edef\enverb@collected@body{\iffalse}\fi\expandafter~\enverb@collected@body}
%% check the line after an oarg
\def\enverb@body@after@oarg#1~%
  {\enverb@ensure@blank{#1}{closing bracket}\enverb@body}
%% check the line after the \begin statement
\def\enverb@body@after@begin#1~%
  {\enverb@ensure@blank{#1}{\string\begin}\enverb@body}
}
%% quick check for empty line
\newcommand\enverb@ensure@blank[2]
  {%
    \expandafter\enverb@ifempty\expanded{{#1}}{}%
      {%
        \expanded{%
        \noexpand\enverb@error
          {%
            Line after #2 not empty.\noexpand\MessageBreak
            Contains: \detokenize\expandafter{\romannumeral`\^^@#1}%
          }%
        }%
      }%
  }
%% quick check for empty argument
\newcommand\enverb@ifempty[1]
  {%
    \enverb@ifempty@\enverb@ifempty@A#1\enverb@ifempty@B.\enverb@ifempty@true
      \enverb@ifempty@A\enverb@ifempty@B
  }
\def\enverb@ifempty@#1\enverb@ifempty@A\enverb@ifempty@B#2#3{#3}
\def\enverb@ifempty@true\enverb@ifempty@A\enverb@ifempty@B#1#2{#1}
\newcommand\enverb@gadd[2]{\xdef#1{\unexpanded\expandafter{#1#2}}}
\newcommand\enverb@body@add[1]
  {%
    \edef\enverb@collected@body
      {\unexpanded\expandafter{\enverb@collected@body#1}}%
  }
% start of environment `enverb'
\newcommand\enverb
  {%
    \begingroup
      \def\tmp{enverb}%
      \expandafter
    \endgroup
    \expandafter\enverb@ifnotend@setup@perhaps\expanded
      {{\string{\@currenvir\string}}}%
    \begingroup
    \enverb@body@setup
    \enverb@firsteoltrue
    \let\enverb@collected@oarg\@empty
    \enverb@search@oarg
  }
\newif\ifenverb@firsteol
\newcommand\enverb@search@oarg{\futurelet\next\enverb@search@oarg@a}
\newcommand\enverb@search@oarg@b{\expandafter\enverb@search@oarg\@gobble}
\newcommand\enverb@oarg{\endgroup\enverb@oarg@}
\NewDocumentCommand\enverb@oarg@{O{}}
  {%
    \edef\enverb@collected@oarg{\unexpanded{#1}}%
    \begingroup
    \enverb@body@setup
    \enverb@body@after@oarg
  }
\def\enverb@ifnotend#1%
  {%
    \def\enverb@ifnotend##1%
      {%
        \enverb@ifnotend@
          ##1\enverb@mark\enverb@ifnotend@maybe
          #1\enverb@mark\@thirdofthree
          \enverb@stop
      }%
    \def\enverb@ifnotend@##1#1##2\enverb@mark##3##4\enverb@stop{##3{##1}{##2}}%
  }
\expandafter\enverb@ifnotend\expanded{{\expandafter\@gobble\string\\end}}
\newcommand\enverb@ifnotend@maybe[2]
  {\expandafter\enverb@ifnotend@perhaps\expandafter{\romannumeral`\^^@#2}{#1}}
\newcommand\enverb@ifnotend@setup@perhaps[1]
  {%
    \def\enverb@ifnotend@perhaps##1%
      {%
        \enverb@ifnotend@perhaps@\enverb@mark##1\enverb@mark\enverb@ifnotend@end
          \enverb@mark#1\enverb@mark\@thirdofthree
          \enverb@stop
      }%
    \def\enverb@ifnotend@perhaps@
        ##1\enverb@mark#1##2\enverb@mark##3##4\enverb@stop
      {##3{##2}}%
  }
\providecommand\@thirdofthree[3]{#3}
\outer\def\myabsolutestop{\stop}
\newcommand\enverb@ifnotend@end[3]
  {%
    \iffalse{\fi}%
    \enverb@ensure@blank{#1}{\string\end}%
    \expanded
      {%
        \endgroup
        \enverbsetup
          {\unexpanded\expandafter{\enverb@collected@oarg}}%
        \noexpand\enverb@output
          {\unexpanded\expandafter{\enverb@collected@body}}%
      }%
      {#2}%
    \expandafter\end\expandafter{\@currenvir}%
  }
\long\def\enverb@output#1#2%
  {%
    \enverb@ifautoignore
      {\enverb@setup@ignore{\enverb@count{#2}+\enverb@moreignore}}%
      {\enverb@setup@ignore\enverb@ignore}%
    \edef\enverb@line##1\enverb@eol
      {%
        \noexpand\detokenize{##1}%
        \noexpand\unexpanded{\unexpanded\expandafter{\enverb@eol@content}}%
      }%
    \edef\enverb@collected@body{#1}%
    \expanded
      {\unexpanded{\enverb@append\enverb@gadd\@gobble}\expandafter}%
      \expandafter{\enverb@collected@body}%
    \par
    \enverb@aboveskip
    \enverb@ifno@lst{}%
      {%
        \enverb@ifsameline
          {\noindent\begin{minipage}[c]{\enverb@codeshare\linewidth}}%
          {}%
        \begingroup
          \everyeof{\noexpand}%
          \expandafter
        \endgroup
        \scantokens\expanded
          {{%
            \noexpand\csname enverb@lst\endcsname
              \enverb@othercr
              \enverb@collected@body
            \string\end{lstlisting}\enverb@othercr
          }}%
        \enverb@ifsameline{\end{minipage}}{}%
      }%
    \enverb@inter
    \enverb@ifno@tcb{}%
      {%
        \begingroup
          \everyeof{\noexpand}%
          \newlinechar=\endlinechar
          \expandafter
        \endgroup
        \scantokens\expanded
          {{%
            \noexpand\csname enverb@tcb\endcsname
              \enverb@pretcb{\unexpanded\expandafter}%
              \enverb@collected@body
            \noexpand\end{exresult}%
          }}%
      }%
    \par
    \enverb@belowskip
    \enverb@after
    \@endpetrue
  }
\providecommand\@firstofnine[9]{#1}
\newcommand\enverb@setup@ignore[1]
  {\expandafter\enverb@setup@ignore@\the\numexpr#1\relax;\enverb@line}
\def\enverb@setup@ignore@#1;#2%
  {%
    \ifnum#1>9
      \expandafter\@firstoftwo
    \else
      \expandafter\@secondoftwo
    \fi
    {\expandafter\enverb@setup@ignore@\the\numexpr#1-8;{\@firstofnine{#2}}}%
    {%
      \let\enverb@bol@gobble\@empty % just so that renewcommand doesn't go nuts
      \expanded
        {%
          \unexpanded{\renewcommand\enverb@bol@gobble}\ifnum#1>\z@[#1]\fi
            {%
              \noexpand\unexpanded
                {\unexpanded\expandafter{\enverb@bol@content}}%
              \unexpanded{#2}%
            }%
          \unexpanded{\def\enverb@bol##1\enverb@eol}%
            {%
              \noexpand\unexpanded
                {\unexpanded\expandafter{\enverb@bol@content}}%
              \unexpanded{\expandafter\enverb@ifempty\expanded}{{##1}}%
                {\noexpand\enverb@line}%
                {\noexpand\enverb@bol@gobble}%
              ##1\unexpanded{\enverb@eol}%
            }%
        }%
    }%
  }
\let\endenverb\@empty
