% This is part of the Tcode kernel. Only intended to by input by it.

%%%%%%%%%%%%%%%%****      The environment Code      ****%%%%%%%%%%%%%%%%

%At the begnning we need to put some space (3pt) below the frame line,
%but if there is no frame nor background, the space will not be put (see \let\N@abbe@cle\relax below)
%and some space above the bottom line at the end:
\def\CodeOpen{\NLhrule\no@break\N@abbe@cle\no@break}
\def\CodeClose{\no@break\N@abbe@cle\no@break\NLhrule}

%Each line will be placed in a box by itself. This makes possible the handling of page breaking in-between by this package.
%These macros open and close the \hbox containing each line, and place the 2pt clearance.
\def\openfirstline{\hbox\bgroup\kern\CodeLeftInd\setbox0 \hbox to\lineboxwd\bgroup\NLvrule\kern 2pt\strut}
\def\openlinebox{\no@break\vskip\CodeBreakglue\applyNLpenalty\vskip-\CodeBreakglue\relax
	\hbox\bgroup\kern\CodeLeftInd\setbox0 \hbox to\lineboxwd\bgroup\NLvrule\kern 2pt\strut
}
\def\closelineboxC{\hss\kern 2pt\NLvrule\egroup %Here ends the box with the contents. Now place a box with the bkg color
  \hbox to0pt{\ApplyBkgColor\vrule width\wd0 height\ht0 depth\dp0\hss}%filling the same space as the contents box
  \box0\kern\CodeRightInd\egroup %Place the contents box. \egroup closes the line box
}
\def\closelineboxN{\hss\kern 2pt\NLvrule\egroup \box0\kern\CodeRightInd\egroup}

\def\Code{\par
  \vskip\Codeskipbefore
  \begingroup\setlineboxwd
  \let\wordbox\relax %Used in inline mode to prevent hyphenation. Here, not needed. But is available as a hook
  \offinterlineskip
  \CodeLineZero %Will consume the ^^M and invoke \CodeAfterFisrtLine
}
%I'd rather not change the catcode of ^^M for this, so that the user could use a macro
%of his own also taking ^^M as delimiter. But TeX does not allow that (which also means the user cannot
%have any such macro).
\def\CodeLineZero{\SetCatcodesLineZero\CLineZero}
\def\SetCatcodesLineZero{%\We do not change %. Hence, its presence in line zero will omit the line after
\SpecialCharsInIdent\catcode`\^^M=\active %line zero. But this is useful for writing several lines of definitions
}
\def\CLineZero#1^^M{#1\CodeAfterLineZero} %Execute what the user has put there. Consumes the ^^M.

\def\CodeAfterLineZero{
  \ifx\ApplyBkgColor\empty
    \let\closelinebox\closelineboxN
    \ifdim\CodeFramewd=0pt \let\N@abbe@cle\relax\fi %If there is no frame nor background, we don't need the clearance.
  \else
    \let\closelinebox\closelineboxC
  \fi
  \let\break\CBreak \let\nobreak\CNobreak \let\goodbreak\CGoodbreak
  \SetCodeCatcodes		%Those of \ncode, plus ^^M and others
  \CodeDefineCommands%Hook for the language package
  \the\CodeHook\CodeOpen% A hook for the user and the top part of the frame
  \CodeLineCheck		%Start parsing the first line
}

{\catcode`\^^I=13
\gdef\SetCodeCatcodes{
  \SetNcodeCatcodes \catcode`\^^M=\active \catcode`\^^I=\active
  \let^^M\EOLMiddle %This is for ^^M not caught by the normal \@parsecode.
  \let\^^M\SlashMInCode %This is for \^^M not caught by the normal \@parsecode.
  \let^^I=\NcodeTab
  \catcode`\{=\cat@xii \catcode`\}=\cat@xii
  \let\MaybeSkipSpacesAfterCS\SkipSpacesAfterCS
  \SetEscapeChars \let\SetEscapeChars\relax %Not worth delaying it to every string. Further, \t, etc. may also be used in comments
}}
%This is the control seq. performing the last tasks *in* the environment
\def\CodeEnd{\CodeClose\endgroup}
\def\endCode{\vskip\Codeskipafter}% This will be executed *after* \CodeEnd

%Check if we have \end or \endCode right ahead of us
\def\IfCodeEnd#1{\ifcsname IfCodeEnd@\string#1\endcsname}
\exP\let\csname IfCodeEnd@\string\end\endcsname=\iftrue %or =\relax,
\exP\let\csname IfCodeEnd@\string\endCode\endcsname=\iftrue %or =\relax,
\let\fi\fi

%% This is the first code executed for the first line and for a line following a ^^M or \^^M caught by \@parsecode %%
%If we detect the end of the environment we need to perform the closing tasks before Latex
%attempts to pass us \endCode, because the latter needs the argument {Code} to be read by \end,
%but { and } do not have their usual catcodes inside the environment. We could instead restore these
%two catcodes immediately after reading \end.
%The c. s. which checks for the end of the environment is \CodeLineCheck
\def\CodeLineCheck#1{
  \IfCodeEnd#1\exP\CodeEnd
  \else\openlinebox\exP\CBeginLine\fi
  #1
}

%End of line caught by \@parsecode
\def\TcodeReloadC{
\def\splicechar{\SpliceCharTasks{\FormatSpliceChar\\}} %Two hooks for the user
\let\SpliceCharTasks\empty
\def\SlashMInCode{\splicechar^^M}

\TcodeDefineSpecial{^^M}{\closelinebox\CodeLineCheck}
\TcodeDefineSpecial{\^^M}{\splicechar\closelinebox\openlinebox\CBeginSplice}
\let\CBeginSplice\@parsecode %A hook for the user

\def\BeginLineBlanks{\let\parsecode\SkipInitialSpaces\parsecode}
\let\CBeginLine\BeginLineBlanks %A hook for the user. This default prints the blanks and then calls \CFirstNoBlank
\let\CFirstNoBlank\@parsecode %Another hook
}

%End of line (i.e., ^^M) or \^^M not caught by \@parsecode because it has entered the argument of a user macro.
\def\TcodeReloadD{
\def\EOLMiddle{\egroup\closelinebox\openlinebox\CBeginInTheMiddle}
\def\CBeginInTheMiddle{\bgroup\CContinueInTheMiddle} %A hook for the user
\let\CContinueInTheMiddle\relax  %Another hook
}
\TcodeReloadC \TcodeReloadD

%Another option for \CBeginInTheMiddle is \SkipSpacesInTheMiddle

%Space and tab are active in the environment. In the definitions that follow we
%need the tab, here, not to be treated like a space. This suffices
\catcode`\^^I=12

\def\SkipInitialSpaces#1{
  \if\noexpand#1^^I#1\else
  \if\noexpand#1 #1\else %If <space> is \space, or =any non-primitive
%  \ifx#1\ \ \else %If <space> is \ .
  \InitialSpacesFinished#1
   \fi\fi
  \parsecode
}
\def\InitialSpacesFinished#1{
  \ifx#1^^M\def\parsecode{\@parsecode#1}
  \else\ifx#1^^M\def\parsecode{\@parsecode#1}
  \else\def\parsecode{\CFirstNoBlank#1}
  \fi\fi
}

%Spaces at beginning of line InTheMiddle of something.
%The redefinition of itself is local to the group of the line, and will be restored when the line is closed
\def\SkipSpacesInTheMiddle#1{
  \if\noexpand#1^^I#1\else
  \if\noexpand#1 #1\else
  \def\SkipSpacesInTheMiddle{\bgroup\CContinueInTheMiddle #1}
  \fi\fi
  \SkipSpacesInTheMiddle
}

%Two commands for the user. it may be used also for the long inline macros.
%Ignore (printing them) blanks until something is found, at which point, execute #1.

%1st. If an end of line is reached we discard #1 and proceed normally.
\def\CSkipBlanks#1{
\let\CAfterSpaces#1
\let\parsecode\ParseSkipSpaces
}
\def\ParseSkipSpaces#1{
  \if\noexpand#1^^I#1\else
  \if\noexpand#1 #1\else
  \SkippedSpacesFinished#1
   \fi\fi
  \parsecode
}
\def\SkippedSpacesFinished#1{
  \ifx#1^^M\def\parsecode{\@parsecode#1}
  \else\ifx#1^^M\def\parsecode{\@parsecode#1}
  \else\def\parsecode{\CAfterSpaces#1}
  \fi\fi
}

%2nd. Like the previous one, but we let the user handle ^^M and \^^M
\def\CSkipBlanksPure#1{
\let\CAfterSpaces#1
\let\parsecode\ParseSkipSpacesPure
}
\def\ParseSkipSpacesPure#1{
  \if\noexpand#1^^I#1\else
  \if\noexpand#1 #1\else
  \def\parsecode{\CAfterSpaces#1}
   \fi\fi
  \parsecode
}

\catcode`\^^I=10 %
