% \iffalse meta-comment
%
% Written in 2009, 2010 by Manuel Pégourié-Gonnard and Élie Roux.
%     <mpg@elzevir.fr>
%     <elie.roux@telecom-bretagne.eu>
%
% 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 luatexbase.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
This is a generated file.

Written in 2009, 2010 by Manuel Pégourié-Gonnard and Élie Roux.
    <mpg@elzevir.fr>
    <elie.roux@telecom-bretagne.eu>

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 luatexbase.cctb.lua
   test-cctb-plain.tex test-cctb-latex.tex

\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{luatexbase.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         \~}
%
% \title{The \pk{luatexbase-cctb} package}
% \date{v0.1 2010-03-26}
% \author{%
%  Manuel P\'egouri\'e-Gonnard \\ \texttt{mpg@elzevir.fr} \and
%   \'Elie Roux \\ \texttt{elie.roux@telecom-bretagne.eu}}
%
% \maketitle
%
% \begin{abstract}
% \end{abstract}
%
% \section{Documentation}
%
%    \section{Implementation}
%
%    \subsection{\tex package}
%
%    \begin{macrocode}
%<*texpackage>
%    \end{macrocode}
%
%    \subsubsection{Preliminaries}
%
%    Reload protection, especially for \plaintex.
%
%    \begin{macrocode}
                \csname lltxb@cctb@loaded\endcsname
\expandafter\let\csname lltxb@cctb@loaded\endcsname\endinput
%    \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-attr}[2010/03/26 v0.1  Catcodetable allocation for LuaTeX  (mpg)]
%    \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 PackageWarningNoLine\endcsname\relax
      \def\x#1#2{\begingroup\newlinechar10
        \immediate\write16{Package #1 warning: #2}\endgroup}
    \else
      \let\x\PackageWarningNoLine
    \fi
  \expandafter\endgroup
  \x{luatexbase-cctb}{LuaTeX is required for this package.^^J
    Aborting package loading.}
  \expandafter\endinput
\fi
%    \end{macrocode}
%
%    Make sure the catcode of @ is correct, especially for \plaintex.
%
%    \begin{macrocode}
\expandafter\edef\csname lltxb@cctb@AtEnd\endcsname{%
  \catcode64 \the\catcode64\relax}
\catcode64 11
%    \end{macrocode}
%
%    \subsubsection{Main content}
%
%    Load the supporting Lua module.
%
%    \begin{macrocode}
\directlua{dofile(kpse.find_file('luatexbase.cctb.lua', 'lua'))}
%    \end{macrocode}
%
%    The allocation macro.
%
%    \begin{macrocode}
\newcount\luatexcatcodetabledefcounter
\luatexcatcodetabledefcounter = 1
\def\newluatexcatcodetable#1{%
  \ifnum\luatexcatcodetabledefcounter<1114110\relax % 0x10FFFF is maximal \chardef
    \global\advance\luatexcatcodetabledefcounter by 1\relax
    \allocationnumber=\luatexcatcodetabledefcounter
    \global\chardef#1=\allocationnumber
    \directlua{%
      luatextra.catcodetabledef_from_tex([[\noexpand#1]], '\number\allocationnumber')}%
    \wlog{\string#1=\string\catcodetable\the\allocationnumber}%
  \else
    \errmessage{No room for a new \string\catcodetable}%
  \fi}
%    \end{macrocode}
%
%    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}
%
%    A macro that sets the catcode of a range of characters. The first
%    parameter is the character number of the first character of the range,
%    the second parameter is one for the last character, and the third
%    parameter is the catcode we want them to have.
%
%    \begin{macrocode}
\def\luatexsetcatcoderange#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 by 1\relax
  \repeat
  \luaSCR@temp}
%    \end{macrocode}
%
%    Finally we create several catcodetables that may be used by the user.
%    These are:
%
%    \begin{itemize}
%    \item \texttt{\string\CatcodeTableIniTeX}: the base \TeX\ catcodes
%    \item \texttt{\string\CatcodeTableString}: almost all characters have
%    catcode 12
%    \item \texttt{\string\CatcodeTableOther}: all characters have catcode 12
%    (even space)
%    \item \texttt{\string\CatcodeTableLaTeX}: the \LaTeX\ classical catcodes
%    \item \texttt{\string\CatcodeTableLaTeXAtLetter}: the \LaTeX\ classical
%    catcodes and |@| letter
%    \item \texttt{\string\CatcodeTableExpl}: the expl3 catcodes
%    \end{itemize}
%
%    \begin{macrocode}
\newluatexcatcodetable\CatcodeTableIniTeX
\newluatexcatcodetable\CatcodeTableString
\newluatexcatcodetable\CatcodeTableOther
\newluatexcatcodetable\CatcodeTableLaTeX
\newluatexcatcodetable\CatcodeTableLaTeXAtLetter
\newluatexcatcodetable\CatcodeTableExpl
\luatexinitcatcodetable\CatcodeTableIniTeX

\expandafter\ifx\csname @firstofone\endcsname\relax
  \long\def\@firstofone#1{#1}%
\fi

\begingroup
  \def\@makeother#1{\catcode#1=12\relax}%
  \@firstofone{%
    \luatexcatcodetable\CatcodeTableIniTeX
    \begingroup
      \luatexsetcatcoderange{0}{8}{15}%
      \catcode9=10  % tab
      \catcode11=15 %
      \catcode12=13 % form feed
      \luatexsetcatcoderange{14}{31}{15}%
      \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 %
      \luatexsavecatcodetable\CatcodeTableLaTeX
      \catcode64=11 %
      \luatexsavecatcodetable\CatcodeTableLaTeXAtLetter
    \endgroup
    \begingroup
      \luatexsetcatcoderange{0}{8}{15}%
      \catcode9=9 % tab ignored
      \catcode11=15 %
      \catcode12=13 % form feed
      \luatexsetcatcoderange{14}{31}{15}%
      \catcode32=9 % space is ignored
      \catcode35=6 % hash mark is macro parameter character
      \catcode36=3 % dollar (not so sure about the catcode...)
      \catcode38=4 % ampersand
      \catcode58=11 % colon letter
      \catcode94=7 % circumflex is superscript character
      \catcode95=11 % underscore letter
      \catcode123=1 % left brace is begin-group character
      \catcode125=2 % right brace is end-group character
      \catcode126=10 % tilde is a space char.
      \catcode127=15 %
      \luatexsavecatcodetable\CatcodeTableExpl
    \endgroup
    \@makeother{0}% nul
    \@makeother{13}% carriage return
    \@makeother{37}% percent
    \@makeother{92}% backslash
    \@makeother{127}%
    \luatexsetcatcoderange{65}{90}{12}% A-Z
    \luatexsetcatcoderange{97}{122}{12}% a-z
    \luatexsavecatcodetable\CatcodeTableString
    \@makeother{32}% space
    \luatexsavecatcodetable\CatcodeTableOther
  \endgroup
}
\directlua{luatextra.catcodetable_do_shortcuts()}
%    \end{macrocode}
%
%    \begin{macrocode}
%</texpackage>
%    \end{macrocode}
%
%    \subsection{Lua module}
%
%    \begin{macrocode}
%<*luamodule>
%    \end{macrocode}
%
%    In the same way, the table \texttt{tex.catcodetablenumber} contains the
%    numbers of the catcodetables registered with
%    \texttt{\string\newluacatcodetable}.
%
%    \begin{macrocode}
luatextra = luatextra or {}
luatextra.catcodetables = {}
tex.catcodetablenumber = luatextra.catcodetables
function luatextra.catcodetabledef_from_tex(name, number)
    truename = name:gsub('[\\ ]', '')
    luatextra.catcodetables[truename] = tonumber(number)
end
%    \end{macrocode}
%
%    With this function we create some shortcuts for a
%    better readability in lua code. This makes
%    |tex.catcodetablenumber.latex| equivalent to 
%    |tex.catcodetablenumber['CatcodeTableLaTeX']|.
%
%    \begin{macrocode}
function luatextra.catcodetable_do_shortcuts()
    local cat = tex.catcodetablenumber
    local val = cat['CatcodeTableLaTeX']
    if val then
      cat['latex'] = val
    end
    val = cat['CatcodeTableLaTeXAtLetter']
    if val then
      cat['latex-package'] = val
      cat['latex-atletter'] = val
    end
    val = cat['CatcodeTableIniTeX']
    if val then
      cat['ini'] = val
    end
    val = cat['CatcodeTableExpl']
    if val then
      cat['expl3'] = val
      cat['expl'] = val
    end
    val = cat['CatcodeTableString']
    if val then
      cat['string'] = val
    end
    val = cat['CatcodeTableOther']
    if val then
      cat['other'] = val
    end
end
%    \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. We also check that the catcodetable's number is remembered well,
%    independently of the current value of |\escapechar|.
%
%    \begin{macrocode}
%<testplain>\input luatexbase-cctb.sty
%<testlatex>\RequirePackage{luatexbase-cctb}
%<*testplain,testlatex>
\newluatexcatcodetable\testcctb
\directlua{assert(luatextra.catcodetables.testcctb)}
\begingroup
\escapechar64
\newluatexcatcodetable\anothercctb
\endgroup
% \directlua{assert(luatextra.catcodetables.anothercctb)}
%</testplain,testlatex>
%<testplain>\bye
%<testlatex>\stop
%    \end{macrocode}
%
% \Finale
\endinput
