% Package Tcode by Javier A. Múgica
%
% 2024-oct. - 2025-april: Developed for typeseting C code with a particular setup
% 2026-may - sep: The utility is made general and multilanguage.

%%%%%%%%%*******  Usage  *******%%%%%%%%%

\iffalse

\input Tcode.tex %and input also some language specific files: defs. for the language, syntax highl. and delaration of words
Or input a single \Tcode_<Lang>.tex file if you have it. E.g.,
\input Tcode_C.tex

Some text\ncode{int dp; 3*a + len;}. The function \ncode{print} is provided.

\Code %Or \begin{Code}, if you have \begin defined
	using matrices
	double atof(const char *nptr);
\endCode %Or \end{Code}

If you need control seq. that take arguments, you have to enclose them within « ». Also, for setting the formatting
	you want, overriding what the macro would do. But they are not needed for c.seq. that take no arguments:
	\ncode{«\FormatCMacro paste»(x,y)}. \def\paste{{\FormatCMacro paste}} \ncode{\paste(x,y)}.
\PrePrintHook is invoked before each word to be printed. By default it does nothing. You may redefine it.
\ident can be used instead of \ncode if the argument is a single identifier. The macro is much simpler.

More explanations in Tcode_users.html and Tcode_developers.html.
\fi

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

\def\ResetTcode{
  \def\TcodeLang{}
  \TcodeReloadA \TcodeReloadB
  \TcodeReloadW \TcodeReloadN
  \TcodeReloadC \TcodeReloadD
  \ResetKernelFormatsDefaults
}

\ifdefined\TcodeIncluded %multiple inclusion. Reset what *the language* (not farther users) may redefine
  \ResetTcode
  \exP\endinput
\fi

\catcode`@=11

%%%%%%******  General programming utilities  ******%%%%%%

\let\exP=\expandafter %Let's hope this is not used
\def\expandonce#1{\unexpanded\expandafter{#1}} %#1 must be a single token
\ifdefined\begincsname  \let\condCsname\begincsname
\else  \let\condCsname\csname
\fi
%e.g., \letcs\MyFormat{Format@Keyword}  --> \let\MyFormat\Format@Keyword
\def\letcs#1#2{\exP\let\exP#1\csname #2\endcsname}
%Use with care
\def\letcsrelax#1#2{\exP\let\exP#1\condCsname #2\endcsname\relax} %In luatex, Avoids creating an entry in TeX's tables

\unless\ifdefined\@gobble \def\@gobble#1{}\fi
\unless\ifdefined\quitvmode \let\quitvmode\leavevmode\fi

%\catcode =12 is very common, =11 too.
\newcount\cat@xii \cat@xii=12
\newcount\cat@xi \cat@xi=11
\ifx\@m\undefined \mathchardef\@m=1000 \fi %Latex's definition

%Disable some commands in pdf strings
\input Tkernel-hypdf.tex

%%%%%%******  Hooks for the user  ******%%%%%%

\newtoks\TcodeHook
\newtoks\ShortNcodeHook %For commands that format once: \ident,\IDENT,\Formatcode,\formatcode,\FastIdent,\Fastfid
\newtoks\LongNcodeHook %For the inline macros \Ncode, \ncode, \nscode
\newtoks\CodeHook %Called by \Code
\newtoks\StdioHook %Called by \stdin, \stdout

\TcodeHook={\SelectCodeFont}

\ifx\ttfamily\undefined
\let\SelectCodeFont=\tt
\else
\let\SelectCodeFont=\ttfamily
\fi
\ShortNcodeHook={\the\TcodeHook}
\LongNcodeHook={\the\TcodeHook}
\CodeHook={\the\TcodeHook}
\StdioHook={\the\TcodeHook}

\let\PrePrintDoNothing\empty %This is not for the user. This is a fixed command

%Hooks for the language package
\def\TcodeReloadA{
  \let\CodeDefineCommands\relax
  %#1 is the next token in the input. This may be needed for identifying prefixes. E.g., R"some string"
  \def\PrePrintLongHook##1{\PrePrintHook} %By default, we ignore the third argument
}
\TcodeReloadA
\let\StdioDefineCommands\relax

%\PrePrintHook. Document-wide
% It is invoked for any word before printing it. It is used by all macros except \formatcode, \Formatcode, \FastIdent, \Fastfid.
% It is supposed to modify or act upon \WordToPrint and \FormatToApply. The first is a token register, the latter expands to
% the category of the word, as \FormatFunction, for example, or equals (as by \ifx) \relax if the word is not recognised.
\let\PrePrintHook\PrePrintDoNothing

%This does not apply to \f(ormat)code, \F(ormat)code, \FastIdent and \Fastfid.
\def\IdentAllowHyphenation{\let\wordbox\relax \def\ifIdboxed{\ifmmode\exP\hbox\fi}}
\def\IdentNotAllowHyphenation{\let\wordbox\hbox \def\ifIdboxed{\quitvmode\wordbox}}
\IdentNotAllowHyphenation %The default

%%%%%%%%% Do not insert anything at end of line in this file
\endlinechar=-1
\catcode`\^^M=13 %
\def\TcodeLang{} %For the definitions in this file that use \TcodeLang

%%%%%%%%%*******  Macros common to all the environments, and the inline environments  *******%%%%%%%%%

\ifdefined\scantextokens \let\scantokensfixed\scantextokens \else
\def\scantokensfixed#1{\endlinechar=\m@ne\everyeof={}\scantokens{#1}} \fi
\newtoks\WordToPrint
\def\letFormatToApply{\let\FormatToApply}

\input Tkernel-setcatcodes.tex %Defines \TcodeReloadB
\input Tkernel-inline.tex %
\input Tkernel-parsecode.tex %Defines \TcodeReloadW \TcodeReloadN
\input Tkernel-noletter.tex %
\input Tkernel-ang.tex %The «» and ‹› environments

\TcodeLetSpecial\end=\relax %Finish all

%%%%%%%%%*******  Code for the displays: \Code, \stdin, \stdout  *******%%%%%%%%%

%Parameters defining the layout: dimensions and colours
\input Tkernel-layout.tex
%Define here how many spaces should a tab be. Obviously, this can be overriden.
\def\NcodeTab{\ \ \ \ \ \ }

% By default we place a penalty between lines. We provide hacks for the user for no penalty, no break and
%for forcing a line break.The setup of the environments make \goodbreak, \break and \nobreak equal to the ones here,
%so that these commands need not be used directly by the user.
\def\applyNLpenalty{\penalty\NLpenalty}
\def\CGoodbreak{\gdef\applyNLpenalty{\gdef\applyNLpenalty{\penalty\NLpenalty}}} %use \goodbreak for this
\def\CBreak{\gdef\applyNLpenalty{\penalty-\@M\gdef\applyNLpenalty{\penalty\NLpenalty}}} %use \break for this
\def\CNobreak{\gdef\applyNLpenalty{\penalty\@M\gdef\applyNLpenalty{\penalty\NLpenalty}}} %use \nobreak for this
\def\CNolinebreaks{\NLpenalty=\@M}
\def\no@break{\penalty\@M}

\input Tkernel-Code.tex %% The environment Code. Define \TcodeReloadC \TcodeReloadD
\input Tkernel-stdio.tex %% Environments stdout and stdin (not language dependent; hence, does not need to Reload anything)
\unless\ifdefined\Codeinput
  \input Tkernel-codeinput.tex %% Environment Codeinput
\fi
\input Tkernel-dollar.tex %% Setting up the character used as dollar

% Default definitions. Document-wide
\unless\ifdefined\DoDollar
  \ifdefined\itshape \let\DoDollar\itshape
  \else\let\DoDollar\it \fi
\fi
\unless\ifdefined\dollarchar
  \TcodeMarkerNone %By default, no dollar
\fi

%Definition of categories: \TcodeDefineFormat, etc. \MakeWord, \DeclareWord
\input Tkernel-categ-words.tex
\input Tkernel-lang.tex %
\UpdateTcodeLang %Set the defaults

\input Tkernel-utils.tex %Some utilities not really part of the core

\catcode`\^^M=5 %Back to normal
\endlinechar=`\^^M %

%For multiple inclusion
\let\TcodeIncluded\relax