% \iffalse meta-comment
%
% Copyright 2009, 2010 by Élie Roux <elie.roux@telecom-bretagne.eu>
% Copyright 2010, 2011 by Manuel Pégourié-Gonnard <mpg@elzevir.fr>
%
% This work is under the CC0 license.
%
% This work consists of the main source file luatexbase-cctb.dtx
% and the derived files
%    luatexbase-cctb.sty cctb.lua
%    test-cctb-plain.tex test-cctb-latex.tex
%
% Unpacking:
%    tex luatexbase-cctb.dtx
% Documentation:
%    pdflatex luatexbase-cctb.dtx
%
%<*ignore>
\begingroup
  \def\x{LaTeX2e}%
\expandafter\endgroup
\ifcase 0\ifx\install y1\fi\expandafter
         \ifx\csname processbatchFile\endcsname\relax\else1\fi
         \ifx\fmtname\x\else 1\fi\relax
\else\csname fi\endcsname
%</ignore>
%<*install>
\input docstrip.tex

\keepsilent
\askforoverwritefalse

\let\MetaPrefix\relax

\preamble

See the aforementioned source file(s) for copyright and licensing information.

\endpreamble

\let\MetaPrefix\DoubleperCent

\generate{%
  \usedir{tex/luatex/luatexbase}%
  \file{luatexbase-cctb.sty}{\from{luatexbase-cctb.dtx}{texpackage}}%
}

\generate{%
  \usedir{doc/luatex/luatexbase}%
  \file{test-cctb-plain.tex}{\from{luatexbase-cctb.dtx}{testplain}}%
  \file{test-cctb-latex.tex}{\from{luatexbase-cctb.dtx}{testlatex}}%
}

\def\MetaPrefix{-- }

\def\luapostamble{%
  \MetaPrefix^^J%
  \MetaPrefix\space End of File `\outFileName'.%
}

\def\currentpostamble{\luapostamble}%

\generate{%
  \usedir{tex/luatex/luatexbase}%
  \file{cctb.lua}{\from{luatexbase-cctb.dtx}{luamodule}}%
}

\obeyspaces
\Msg{************************************************************************}
\Msg{*}
\Msg{* To finish the installation you have to move the following}
\Msg{* files into a directory searched by TeX:}
\Msg{*}
\Msg{*     luatexbase-cctb.sty cctb.lua}
\Msg{*}
\Msg{* Happy TeXing!}
\Msg{*}
\Msg{************************************************************************}

\endbatchfile
%</install>
%<*ignore>
\fi
%</ignore>
%<*driver>
\documentclass{ltxdoc}
\input{lltxb-dtxstyle}
\begin{document}
  \DocInput{luatexbase-cctb.dtx}%
\end{document}
%</driver>
% \fi
%
% \CheckSum{0}
%
% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
%
% \pkdate{luatexbase-cctb}{v0.6 2013-05-11}
%
% \maketitle
%
% \begin{abstract}
% In addition to the registers existing in \tex and \etex, \luatex introduces
% a new concept: catcode tables. This package takes care of catcode table
% allocation just like Plain TeX and LaTeX do for other registers. It also
% provides a few handy macros from common use cases.
% \end{abstract}
%
% \tableofcontents
%
% \section{Documentation}
%
% \subsection{Allocation and setting}
%
% The main macro defined here is |\newluatexcatcodetable|. It behaves the same
% as |\newbox|. Additionally, the newly allocated catcode table is initialised
% to the catcodes of Ini\tex.  In order to help you define the catcode tables
% (once they are allocated), two helper macros are available.
%
% \begin{quote}
% \cs{SetCatcodeRange}\marg{from}\marg{to}\marg{value}
% \end{quote}
% Set all characters code in the range \meta{from}--\meta{to} to the given
% catcode \meta{value}.
%
% \begin{quote}
% \cs{setluatexcatcodetable}\marg{table}\marg{catcode statements}
% \end{quote}
% Set a previously allocated \meta{table} to the catcodes given by executing
% \meta{catcode statements}. Note that \meta{table} must not be the current
% active catcode table. You may, however, load another catcode table in your
% \meta{catcode statements} (if you don't, then the current catcodes will be
% used as a basis).
%
% For your convenience, a few catcode tables are predefined:
% \begin{itemize}
% \item |\CatcodeTableIniTeX|: Ini\tex catcodes.
% \item |\CatcodeTableString|: the catcode regime used by |\string| and
% |\meaning|: everything has catcode 12, except space (U+0020) that has
% catcode 10.
% \item |\CatcodeTableOther|: everything (included space) has catcode 12.
% \item |\CatcodeTableLaTeX|: basic \LaTeXe\ catcodes.
% \item |\CatcodeTableLaTeXAtLetter|: same as above, but |@| is a letter.
% \item |\CatcodeTableExpl|: catcodes used by \latex{}3 with |\ExplSyntaxOn|.
% Be aware that this does not provide the exact same environment as
% |\ExplSyntaxOn|: most noticibly, some booleans are not set, and
% |\endlinechar| is not adjusted (it should be 32).
% \end{itemize}
%
% \subsection{Access from Lua}
%
% Various Lua functions, such as |tex.print| accept a catcode table number as
% argument. In order to use in Lua the catcode tables allocated in \tex, the
% package writer needs to know their number.  Since |\chardef| is used for the
% definition of the control sequence, this is rather easy to do. However, for
% extra ease of use, the numbers are also directly accessible from Lua as the
% value of the table |luatexbase.catcodetables|, whose keys is the name of the
% control sequence (without any leading backslash). For example, after
% \begin{quote}
% |\newluatexcatcodetable\mycatcodes|
% \end{quote}
% the variable |luatexbase.catcodetables.mycatcodes| will hold the number of
% the catcode table |\mycatcodes|. You will usually want to do
% \begin{quote}
% |local mycatcodes = luatexbase.catcodetables.mycatcodes|
% \end{quote}
% at the beginning of your Lua module (assuming it is loaded after the catcode
% table has been allocated) and then use |tex.print(mycatcodes, ...)| in the
% rest of your Lua code.
%
% Also, nicknames are available for the predefined catcode tables:
% \begin{itemize}
% \item |CatcodeTableIniTeX| = |ini|,
% \item |CatcodeTableString| = |string|,
% \item |CatcodeTableOther| = |other|,
% \item |CatcodeTableLaTeX| = |latex|,
% \item |CatcodeTableLaTeXAtLetter| = |latex-atletter| = |latex-package|,
% \item |CatcodeTableExpl| = |expl| = |expl3|,
% \end{itemize}
%
% \subsection{High-level stack interface}
%
% In many situations, you want to ensure a proper set of catcodes for some
% time, then go back to the previous catcodes without using a group. The
% obvious use case is a package, which may be loaded while unexpected
% catcodes are active. A pair of macros is provided to deal precisely with
% this situation.
% \begin{quote}
% \cs{BeginCatcodeRegime}\marg{catcode table}\\
% \meta{code}\\
% \cs{EndCatcodeRegime}
% \end{quote}
% \cs{BeginCatcodeRegime} remembers the current catcode table, then
% initializes a new one with a copy of the \meta{catcode table} given (so that
% this table is not changed by anything in \meta{code}), and makes it the
% active table. \cs{EndCatcodeRegime} restores the previous catcode table.
%
% For example, a \latex package might do:
% \begin{quote}
% |\BeginCatcodeRegime\CatcodeTableLaTeXAtLetter|\\
% |% package code|\\
% |\EndCatcodeRegime|
% \end{quote}
% Every catcode change made in the package code will be lost avec
% \cs{EndCatcodeRegime}; if you want them to survive, please use
% \cs{AtEndOfPackage} or \cs{AtBeginDocument}.
%
% By the way, you may add catcode statements in the argument of
% \cs{BeginCatcodeRegime} after the name of a catcode table. So the first line
% of the previous example is equivalent to
% \begin{quote}
% |\BeginCatcodeRegime{\CatcodeTableLaTeX \makeatletter}|
% \end{quote}
%
% \subsection{Low-level stack interface}
%
% The previous macros use internally two stacks : the first on holds the
% numbers of the active catcodes tables, so remembering the current table
% means pushing its number on the stack, and restoring the previously active
% table means popping it off the stack. This is done with:
% \begin{quote}
% \cs{PushCatcodeTableNumStack}\\
% \cs{PopCatcodeTableNumStack}
% \end{quote}
% Note that \cs{PushCatcodeTableNumStack} doesn't change current catcodes
% but \cs{PopCatcodeTableNumStack} does.
%
% The second stack consists of temporary tables, mainly used to hold copies of
% existing tables. A temporary table are allocated with
% \cs{IncCatcodeTableStack}, accessed with \cs{CatcodeTableStack} and the
% freed with \cs{DecCatcodeTableStack}, none of which changes the current
% table.
%
% As an illustration, \cs{BeginCatcodeRegime} does
% \begin{quote}
% |\PushCatcodeTableNumStack|\\
% |\IncCatcodeTableStack|\\
% |\setluatexcatcodetable\CatcodeTableStack{\luatexcatcodetable#1}%|\\
% |\luatexcatcodetable\CatcodeTableStack|
% \end{quote}
% and \cs{EndCatcodeRegime} is defined as
% \begin{quote}
% |\DecCatcodeTableStack|\\
% |\PopCatcodeTableNumStack|
% \end{quote}
%
% If you choose to use this low-level interface, it is your responsibility to
% ensure proper balancing of push-pop and inc-dec, as well as making sure that
% a temporary table is never used after it has been freed.
%
%    \section{Implementation}
%
%    \subsection{\tex package}
%
%    \begin{macrocode}
%<*texpackage>
%    \end{macrocode}
%
%    \subsubsection{Preliminaries}
%
%    Catcode defenses and reload protection.
%
%    \begin{macrocode}
\begingroup\catcode61\catcode48\catcode32=10\relax% = and space
  \catcode123 1 % {
  \catcode125 2 % }
  \catcode 35 6 % #
  \toks0\expandafter{\expandafter\endlinechar\the\endlinechar}%
  \edef\x{\endlinechar13}%
  \def\y#1 #2 {%
    \toks0\expandafter{\the\toks0 \catcode#1 \the\catcode#1}%
    \edef\x{\x \catcode#1 #2}}%
  \y  13  5 % carriage return
  \y  61 12 % =
  \y  32 10 % space
  \y 123  1 % {
  \y 125  2 % }
  \y  35  6 % #
  \y  64 11 % @ (letter)
  \y  10 12 % new line ^^J
  \y  39 12 % '
  \y  40 12 % (
  \y  41 12 % )
  \y  44 12 % ,
  \y  45 12 % -
  \y  46 12 % .
  \y  47 12 % /
  \y  58 12 % :
  \y  60 12 % <
  \y  62 12 % >
  \y  91 12 % [
  \y  93 12 % ]
  \y  94  7 % ^
  \y  95  8 % _
  \y  96 12 % `
  \toks0\expandafter{\the\toks0 \relax\noexpand\endinput}%
  \edef\y#1{\noexpand\expandafter\endgroup%
    \noexpand\ifx#1\relax \edef#1{\the\toks0}\x\relax%
    \noexpand\else \noexpand\expandafter\noexpand\endinput%
    \noexpand\fi}%
\expandafter\y\csname luatexbase@cctb@sty@endinput\endcsname%
%    \end{macrocode}
%
%    Package declaration.
%
%    \begin{macrocode}
\begingroup
  \expandafter\ifx\csname ProvidesPackage\endcsname\relax
    \def\x#1[#2]{\immediate\write16{Package: #1 #2}}
  \else
    \let\x\ProvidesPackage
  \fi
\expandafter\endgroup
\x{luatexbase-cctb}[2013/05/11 v0.6 Catcodetable allocation for LuaTeX]
%    \end{macrocode}
%
%    Make sure \luatex is used.
%
%    \begin{macrocode}
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname RequirePackage\endcsname\relax
  \input ifluatex.sty
\else
  \RequirePackage{ifluatex}
\fi
\ifluatex\else
  \begingroup
    \expandafter\ifx\csname PackageError\endcsname\relax
      \def\x#1#2#3{\begingroup \newlinechar10
        \errhelp{#3}\errmessage{Package #1 error: #2}\endgroup}
    \else
      \let\x\PackageError
    \fi
  \expandafter\endgroup
  \x{luatexbase-cctb}{LuaTeX is required for this package. Aborting.}{%
    This package can only be used with the LuaTeX engine^^J%
    (command `lualatex' or `luatex').^^J%
    Package loading has been stopped to prevent additional errors.}
  \expandafter\luatexbase@cctb@sty@endinput%
\fi
%    \end{macrocode}
%
%    \subsubsection{Load supporting Lua module}
%
%    First load \pk{luatexbase-modutils} (hence \pk{luatexbase-loader} 
%    and \pk{luatexbase-compat}), then the supporting Lua module.
%
%    \begin{macrocode}
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname RequirePackage\endcsname\relax
  \input luatexbase-modutils.sty
\else
  \RequirePackage{luatexbase-modutils}
\fi
\luatexbase@directlua{require('luatexbase.cctb')}
%    \end{macrocode}
%
%    \subsubsection{Primitives needed}
%
%    \pk{luatexbase-compat} is already loaded; just make sure the primitives
%    we need are available.
%
%    \begin{macrocode}
\luatexbase@ensure@primitive{luaescapestring}
\luatexbase@ensure@primitive{catcodetable}
\luatexbase@ensure@primitive{initcatcodetable}
\luatexbase@ensure@primitive{savecatcodetable}
%    \end{macrocode}
%
%    \subsubsection{Allocation and temporary tables}
%
%    Counters for the allocated and temporary tables.
%
%    \begin{macrocode}
\newcount\lltxb@catcodetable@alloc
\lltxb@catcodetable@alloc\m@ne
\newcount\CatcodeTableStack
\CatcodeTableStack\z@
%    \end{macrocode}
%
%    The allocation macro. Allocate only odd numbers to allow using even
%    numbers for temporary tables.
%
%    \begin{macrocode}
\def\newluatexcatcodetable#1{%
  \ifnum\lltxb@catcodetable@alloc<65535\relax
    \global\advance\lltxb@catcodetable@alloc\tw@
    \allocationnumber\lltxb@catcodetable@alloc
    \global\chardef#1\allocationnumber
    \luatexinitcatcodetable\allocationnumber
    \begingroup\escapechar\m@ne
    \luatexbase@directlua{luatexbase.catcodetabledef_from_tex(
      '\luatexluaescapestring{\string#1}', '\number\allocationnumber')}%
    \endgroup
    \wlog{\string#1=\string\luatexcatcodetable\the\allocationnumber}%
  \else
    \errmessage{No room for a new \string\luatexcatcodetable}%
  \fi}
%    \end{macrocode}
%
%    Allocate a new temporary table, using even numbers.
%
%    \begin{macrocode}
\def\IncCatcodeTableStack{%
  \ifnum\CatcodeTableStack<65534\relax
    \global\advance\CatcodeTableStack\tw@
  \else
    \errmessage{CatcodeTableStack overflow}%
  \fi}
%    \end{macrocode}
%
%    Free a temporary table.
%
%    \begin{macrocode}
\def\DecCatcodeTableStack{%
  \ifnum\CatcodeTableStack>\z@
    \global\advance\CatcodeTableStack-2\relax
  \else
    \errmessage{CatcodeTableStack underflow}%
  \fi}
%    \end{macrocode}
%
%    \subsubsection{Setting catcode tables}
%
%    A small patch to get two new counters in Plain too.
%
%    \begin{macrocode}
\expandafter\ifx\csname @tempcnta\endcsname\relax
  \csname newcount\endcsname\@tempcnta
\fi
\expandafter\ifx\csname @tempcntb\endcsname\relax
  \csname newcount\endcsname\@tempcntb
\fi
%    \end{macrocode}
%
%    Set the catcodes for a range of characters.
%
%    \begin{macrocode}
\def\SetCatcodeRange#1#2#3{%
  \edef\luaSCR@temp{%
    \noexpand\@tempcnta=\the\@tempcnta
    \noexpand\@tempcntb=\the\@tempcntb
    \noexpand\count@=\the\count@
    \relax}%
  \@tempcnta=#1\relax
  \@tempcntb=#2\relax
  \count@=#3\relax
  \loop\unless\ifnum\@tempcnta>\@tempcntb
    \catcode\@tempcnta=\count@
    \advance\@tempcnta\@ne
  \repeat
  \luaSCR@temp}
%    \end{macrocode}
%
%    Make \cs{SetCatcodeRange} available with its old name.
%
%    \begin{macrocode}
\def\lltxb@synonym#1#2{%
  \def#1{%
    \begingroup
    \ifdefined\PackageWarning
      \let\x\PackageWarning
    \else
      \def\x####1####2{%
        \begingroup \endlinechar10
        \message{Package ####1 warning: ####2}%
        \endgroup}
    \fi
    \expandafter\endgroup
    \x{luatex}{\string#1 is deprecated^^J%
      and will be removed in the next version of the package.^^J%
      Please use \string#2 instead.}
    \let#1#2%
    #1}}
\lltxb@synonym \setcatcoderange \SetCatcodeRange
%    \end{macrocode}
%
%    Set a catcode table.
%
%    \begin{macrocode}
\def\setluatexcatcodetable#1#2{%
  \begingroup
  #2%
  \luatexsavecatcodetable#1%
  \endgroup}
%    \end{macrocode}
%
%    \subsubsection{Predefined tables}
%
%    The |IniTeX| catcode table needs no extra initialisation.
%
%    \begin{macrocode}
\newluatexcatcodetable\CatcodeTableIniTeX
%    \end{macrocode}
%
%    The |String| and |Other| catcode tables.
%
%    \begin{macrocode}
\newluatexcatcodetable\CatcodeTableString
\setluatexcatcodetable\CatcodeTableString{%
  \luatexcatcodetable\CatcodeTableIniTeX
  \catcode0   12 % nul
  \catcode13  12 % carriage return
  \catcode37  12 % percent
  \SetCatcodeRange{65}{90}{12}% A-Z
  \SetCatcodeRange{97}{122}{12}% a-z
  \catcode92  12 % backslash
  \catcode127 12 }
%    \end{macrocode}
%
%    \begin{macrocode}
\newluatexcatcodetable\CatcodeTableOther
\setluatexcatcodetable\CatcodeTableOther{%
  \luatexcatcodetable\CatcodeTableString
  \catcode32 12 }
%    \end{macrocode}
%
%    Tables for \LaTeXe.
%
%    \begin{macrocode}
\newluatexcatcodetable\CatcodeTableLaTeX
\setluatexcatcodetable\CatcodeTableLaTeX{%
  \luatexcatcodetable\CatcodeTableIniTeX
  \SetCatcodeRange{0}{31}{15}%
  \catcode9   10 % tab
  \catcode10  12 % newline
  \catcode12  13 % form feed
  \catcode13  5  % carriage return
  \catcode35  6  % hash
  \catcode36  3  % dollar
  \catcode38  4  % ampersand
  \catcode94  7  % circumflex
  \catcode95  8  % underscore
  \catcode123 1  % brace left
  \catcode125 2  % brace right
  \catcode126 13 % tilde
  \catcode127 15 }
%    \end{macrocode}
%
%    \begin{macrocode}
\newluatexcatcodetable\CatcodeTableLaTeXAtLetter
\setluatexcatcodetable\CatcodeTableLaTeXAtLetter{%
  \luatexcatcodetable\CatcodeTableLaTeX
  \catcode64=11 }
%    \end{macrocode}
%
%    A table for \pk{expl3}.
%
%    \begin{macrocode}
\newluatexcatcodetable\CatcodeTableExpl
\setluatexcatcodetable\CatcodeTableExpl{%
  \luatexcatcodetable\CatcodeTableLaTeX
  \catcode126 10 % tilde is a space char
  \catcode32  9  % space is ignored
  \catcode9   9  % tab also ignored
  \catcode95  11 % underscore letter
  \catcode58  11 % colon letter
  }
%    \end{macrocode}
%
%    Now do the shortcuts.
%
%    \begin{macrocode}
\luatexbase@directlua{luatexbase.catcodetable_do_shortcuts()}
%    \end{macrocode}
%
%    \subsubsection{Catcode table number stack and regimes}
%
%    The stack is implemented as a list of (brace-enclosed) \tex arguments.
%    Initially, in contains only $0$, the number of the active table when
%    \luatex starts.
%
%    \begin{macrocode}
\def\lltxb@cctb@numstack{0}
%    \end{macrocode}
%
%    Pushing a number on the stack actually means adding it to the beginning
%    of the list (ie, unshifting it).
%
%    \begin{macrocode}
\def\PushCatcodeTableNumStack{%
  \xdef\lltxb@cctb@numstack{{\the\luatexcatcodetable}\lltxb@cctb@numstack}}
%    \end{macrocode}
%
%    Popping a number off the stack means shifting it.
%
%    \begin{macrocode}
\def\PopCatcodeTableNumStack{%
  \expandafter\lltxb@cctb@numstack@pop\lltxb@cctb@numstack\@nil}
\def\lltxb@cctb@numstack@pop#1#2\@nil{%
  \ifx\empty#2\empty
    \begingroup
    \ifdefined\PackageWarning
      \let\x\PackageWarning
    \else
      \def\x####1####2{%
        \begingroup \endlinechar10
        \message{Package ####1 warning: ####2}%
        \endgroup}%
    \fi
    \expandafter\endgroup
    \x{luatexbase-cctb}{Popping from an empty CatcodeTableNumStack}%
    \luatexcatcodetable\z@
  \else
    \gdef\lltxb@cctb@numstack{#2}%
    \luatexcatcodetable#1\relax
  \fi}
%    \end{macrocode}
%
%    Now the catcode regime pseudo-environment as presented in the
%    documentation.
%
%    \begin{macrocode}
\def\BeginCatcodeRegime#1{%
  \PushCatcodeTableNumStack
  \IncCatcodeTableStack
  \setluatexcatcodetable\CatcodeTableStack{\luatexcatcodetable#1}%
  \luatexcatcodetable\CatcodeTableStack}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\EndCatcodeRegime{%
  \DecCatcodeTableStack
  \PopCatcodeTableNumStack}
%    \end{macrocode}
%
%    That's all, folks!
%
%    \begin{macrocode}
\luatexbase@cctb@sty@endinput%
%</texpackage>
%    \end{macrocode}
%
%    \subsection{Lua module}
%
%    \begin{macrocode}
%<*luamodule>
luatexbase                  = luatexbase or { }
local luatexbase            = luatexbase
luatexbase.provides_module({
    name          = "luatexbase-cctb",
    version       = 0.6,
    date          = "2013/05/11",
    description   = "Catcodetable allocation for LuaTeX",
    author        = "Heiko Oberdiek, Elie Roux and Manuel Pegourie-Gonnard",
    copyright     = "Heiko Oberdiek, Elie Roux and Manuel Pegourie-Gonnard",
    license       = "CC0",
})
%    \end{macrocode}
%
%    The number associated to a CS name is remembered in the |catcodetables|
%    table.
%
%    \begin{macrocode}
luatexbase.catcodetables    = luatexbase.catcodetables or { }
local catcodetables         = luatexbase.catcodetables
local function catcodetabledef_from_tex(name, number)
    catcodetables[name] = tonumber(number)
end
luatexbase.catcodetabledef_from_tex = catcodetabledef_from_tex
%    \end{macrocode}
%
%    The next function creates some shortcuts for better readability in lua
%    code. This makes |luatexbase.catcodetables.latex| equivalent to
%    |luatexbase.catcodetables.CatcodeTableLaTeX|.
%
%    \begin{macrocode}
local function catcodetable_do_shortcuts()
    local cat = catcodetables
    cat['latex']                = cat.CatcodeTableLaTeX
    cat['latex-package']        = cat.CatcodeTableLaTeXAtLetter
    cat['latex-atletter']       = cat.CatcodeTableLaTeXAtLetter
    cat['ini']                  = cat.CatcodeTableIniTeX
    cat['expl3']                = cat.CatcodeTableExpl
    cat['expl']                 = cat.CatcodeTableExpl
    cat['string']               = cat.CatcodeTableString
    cat['other']                = cat.CatcodeTableOther
end
luatexbase.catcodetable_do_shortcuts = catcodetable_do_shortcuts
%    \end{macrocode}
%
%    \begin{macrocode}
%</luamodule>
%    \end{macrocode}
%
%    \section{Test files}
%
%    The tests done are very basic: we just make sure that the package loads
%    correctly and the macros don't generate any error, under both LaTeX en
%    Plain TeX.
%
%    \begin{macrocode}
%<testplain,testlatex>\catcode00 15
%<testplain>\input luatexbase-cctb.sty
%<testlatex>\RequirePackage{luatexbase-cctb}
%<*testplain,testlatex>
\begingroup \catcode64 11 \global\let\lua\luatexbase@directlua \endgroup
%    \end{macrocode}
%
%    Also check that the catcodetable's number is remembered well,
%    independently of the current value of |\escapechar|.

%    \begin{macrocode}
\newluatexcatcodetable\testcctb
\lua{assert(luatexbase.catcodetables.testcctb)}
\begingroup
\escapechar64
\newluatexcatcodetable\anothercctb
\endgroup
\lua{assert(luatexbase.catcodetables.anothercctb)}
%    \end{macrocode}
%
%    Now, play a little bit with predefined tables. Be careful to change
%    catcodes only inside a group to avoid chaos.
%
%    \begin{macrocode}
\def\test#1#2#3{%
  \begingroup
  \ifcsname CatcodeTable#1\endcsname \else \INTERR \fi
  \luatexcatcodetable\csname CatcodeTable#1\endcsname
  \ifnum\catcode#2=#3 \else \ERROR \fi
  \endgroup}
\test {IniTeX}        {00} {09}
\test {IniTeX}        {92} {00}
\test {IniTeX}        {64} {12}
\test {IniTeX}        {65} {11}
\test {String}        {92} {12}
\test {String}        {65} {12}
\test {String}        {32} {10}
\test {Other}         {92} {12}
\test {Other}         {65} {12}
\test {Other}         {32} {12}
\test {LaTeXAtLetter} {64} {11}
\test {LaTeX}         {64} {12}
\test {Expl}          {32} {09}
%<testlatex>\documentclass{minimal}
\lua{%
  tex.sprint('\string\\setbox0=\string\\hbox{')
  tex.sprint(luatexbase.catcodetables.string, "\string\\undef # _^&")
  tex.sprint('}')
  }
%    \end{macrocode}
%
%    \begin{macrocode}
%</testplain,testlatex>
%<testplain>\bye
%<testlatex>\stop
%    \end{macrocode}
%
% \Finale
\endinput
