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

%% The definition of formats was not part of the kernel, nor \MakeWord, but since the introduction of \TcodeLang, it has to be.

%Following the naming convention of the commands, this should be called \Format@kernel.
%But \Format@xxxx is already reserved for registered words. Furhter, "kernel" is misleading here.
\def\csFormat#1{\exP\noexpand\csname Format\TcodeLang #1\endcsname}
\unless\ifdefined\Format \let\Format\csFormat \fi %\Format is too generic. We never use it, but provide it for the user.

%Sets \FormatToApply to the given format. Uses \def, not \let, in agreement with all settings for \FormatToApply
\def\@FormatToApply#1{\exP\def\exP\FormatToApply\exP{\csname Format\TcodeLang #1\endcsname}}

%%%****               Definition of formats for categories               ****%%%

%Auxiliary macro for the next ones
\def\UpdateKernelFormat#1{\exP\let\csname Format#1\exP\endcsname\csname Format\TcodeLang#1\endcsname}
%Tell \UpdateKernelFormat what categories belong to the kernel
\def\UpdateKernelFormat@OtherWords{\UpdateKernelFormat{OtherWords}}
\def\UpdateKernelFormat@Number{\UpdateKernelFormat{Number}}
\def\UpdateKernelFormat@SpliceChar{\UpdateKernelFormat{SpliceChar}}
\def\UpdateKernelFormat@AtEsc{\UpdateKernelFormat{AtEsc}}

%To be used at the beginning of format definition files, to let all kernel formats to their defaults
\def\KernelFormatDefaults{
\let\FormatOtherWords\relax			\exP\let\csname Format\TcodeLang OtherWords\endcsname\FormatOtherWords
\let\FormatNumber\relax				\exP\let\csname Format\TcodeLang Number\endcsname\FormatNumber
\let\FormatSpliceChar\relax				\exP\let\csname Format\TcodeLang SpliceChar\endcsname\FormatSpliceChar
\let\formatAtEsc\FormatAtEsc@@Default	\exP\let\csname Format\TcodeLang AtEsc\endcsname\formatAtEsc
}

\def\TcodeDefineFormat#1{\ifx[#1\exP\T@DefFormat \else\def\next{\T@DefFormat@Lang{#1}}\exP\next \fi}
\def\TcodeEdefFormat#1{\ifx[#1\exP\T@EdefFormat \else\def\next{\T@EdefFormat@Lang{#1}}\exP\next \fi}
\def\TcodeCopyFormat#1{\ifx[#1\exP\T@CopyFormat \else\def\next{\T@CopyFormat@Lang{#1}}\exP\next \fi}
%
\def\T@DefFormat@Lang#1#2{\exP\protected\exP\def\csname Format\TcodeLang#1\endcsname{#2}		\condCsname UpdateKernelFormat@#1\endcsname}
\def\T@EdefFormat@Lang#1#2{\exP\protected\exP\edef\csname Format\TcodeLang#1\endcsname{#2}		\condCsname UpdateKernelFormat@#1\endcsname}
\def\T@CopyFormat@Lang#1#2{\exP\let\csname Format\TcodeLang#1\exP\endcsname\csname Format\TcodeLang#2\endcsname \condCsname UpdateKernelFormat@#1\endcsname}
%
\def\T@DefFormat#1]#2#3{\exP\protected\exP\def\csname Format#1#2\endcsname{#3}		\edef\temp{#1}\ifx\TcodeLang\temp\condCsname UpdateKernelFormat@#2\endcsname\fi}
\def\T@EdefFormat#1]#2#3{\exP\protected\exP\edef\csname Format#1#2\endcsname{#3}		\edef\temp{#1}\ifx\TcodeLang\temp\condCsname UpdateKernelFormat@#2\endcsname\fi}
\def\T@CopyFormat#1]#2#3{\exP\let\csname Format#1#2\exP\endcsname\csname Format#1#3\endcsname  \edef\temp{#1}\ifx\TcodeLang\temp\condCsname UpdateKernelFormat@#2\endcsname\fi}
%
\def\TCopyFormat#1#2{\exP\let\csname Format\TcodeLang#1\exP\endcsname\csname Format\TcodeLang#2\endcsname}

\def\TcodeDefineSubcategory#1{\ifx[#1\exP\T@DefFormat \else\def\next{\T@Def@Sub\TcodeLang]{#1}}\exP\next \fi}
\def\T@Def@Sub#1]#2#3{\exP\protected\exP\def\csname Format#1#2\exP\endcsname \exP{\csname Format#1#3\endcsname}}

% E.g., \TcodeRedirect[C]{TGFunction}{Function}, \TcodeRedirect{TGFunction}{Function}
\def\TcodeRedirect#1{\ifx[#1\exP\Tcode@Redirect \else\def\next{\Tcode@Redirect\TcodeLang]{#1}}\exP\next \fi}
\def\Tcode@Redirect#1]#2#3{\exP\def\csname Format#1#2\exP\endcsname\exP{\csname Format#1#3\endcsname}}

%The macro \TcodeRedirect uses \def instead of \let so that if you define the categories with "Slow" (the default), and in a
% PrePrintHook you write \edef\next{\FormatToApply}, say, (\HookOnlyKnownEE does that), you get the final category;
% i.e., after \TcodeRedirect{Aaa}{Bbb} you'd get \FormatLangBbb as the expansion of \next. If you just want Aaa identifiers
% formatted as Bbb, just use \TCopyFormat{AAA}{Bbb}.


%%%**** Making words of a particular category ****%%%

%on-the-spot formatting (no category). E.g., \FormatWordDirect{reset}{\color{yellow}}
\def\FormatWordDirect#1#2{\exP\def\csname Format\TcodeLang @#1\endcsname{#2}}

%Make one word of a particular category, or of none. E.g., \MakeWord{factorial}{Function}. \KillWord{countof}.
% The "Fast" and "Slow" refer to the subsequent use of the word, not the definition itself.
\def\MakeWordFast#1#2{\exP\let\csname Format\TcodeLang @#1\exP\endcsname\csname Format\TcodeLang#2\endcsname} %\let
\def\MakeWordSlow#1#2{\exP\def\csname Format\TcodeLang @#1\exP\endcsname\exP{\csname Format\TcodeLang#2\endcsname}} %\def
\def\MakeWordIndirect#1#2{\exP\let\csname Format\TcodeLang @#1\exP\endcsname\csname FormatAs\TcodeLang#2\endcsname} %Like Slow, but assumes \FormasAs#2 has been defined as if by Slow
\let\MakeWord\MakeWordSlow %Defaults to slow, so that a subsequent change in the Format is reflected in the words.
% \MakeWord should never be \let=\MakeWordIndirect by the end of a file, unless it is intended only for people who know this package well.

\def\DeclareWord#1{\ifx[#1\exP\Declare@Word \else\def\next{\Declare@Word\TcodeLang]{#1}}\exP\next \fi}
\def\Declare@Word#1]#2#3{\exP\def\csname Format#1@#2\exP\endcsname\exP{\csname Format#1#3\endcsname}} %\def

\def\KillWord#1{\ifx[#1\exP\Kill@Word \else\Kill@Word\TcodeLang]{#1}\fi}
\def\Kill@Word#1]#2{\exP\let\csname Format#1@#2\endcsname\undefined}
