% \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-attr.dtx
% and the derived files
%    luatexbase-attr.sty luatexbase.attr.lua
%   test-regs-plain.tex test-regs-latex.tex
%
% Unpacking:
%    tex luatexbase-attr.dtx
% Documentation:
%    pdflatex luatexbase-attr.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-attr.dtx
and the derived files
   luatexbase-attr.sty luatexbase.attr.lua ...

\endpreamble

\let\MetaPrefix\DoubleperCent

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

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

\def\MetaPrefix{-- }

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

\def\currentpostamble{\luapostamble}%

\generate{%
  \usedir{tex/luatex/luatexbase}%
  \file{luatexbase.attr.lua}{\from{luatexbase-attr.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-attr.sty luatexbase.attr.lua ...}
\Msg{*}
\Msg{* Happy TeXing!}
\Msg{*}
\Msg{************************************************************************}

\endbatchfile
%</install>
%<*ignore>
\fi
%</ignore>
%<*driver>
\documentclass{ltxdoc}
\input lltxb-dtxstyle
\begin{document}
  \DocInput{luatexbase-attr.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-attr} package}
% \date{v0.1 2010-03-11}
% \author{%
%  Manuel P\'egouri\'e-Gonnard \\ \email{mpg@elzevir.fr} \and
%   \'Elie Roux \\ \email{elie.roux@telecom-bretagne.eu}}
%
% \maketitle
%
% \begin{abstract}
% In addition to the registers existing in \tex and \etex, \luatex introduces
% a new concept: attributes. This package takes care of attribute allocation
% just like Plain TeX and LaTeX do for other registers.
% \end{abstract}
%
% \section{Documentation}
%
% The main macro defined here is |\newluatexattribute|. It behaves in the same
% way as |\newcount|. There are also two helper macros: |\setluatexattibute|
% sets an attribute's value (locally, but you can use |\global| in front of
% it). |\unsetluatexattribute| unsets an atribute by giving it a special
% value, depending on \luatex's version; you should always use this macro
% in order to be sure the correct special value for your version of \luatex is
% used.
%
% Due to the intended use of attributes, it makes no sense to locally
% allocate an attribute the way you can locally allocate a counter using
% \file{etex.sty}'s |\loccount|, so no corresponding macro is defined.
%
% The various Lua functions for manipulating attributes use a number to
% designate the attribute. Hence, package writers need a way to know the
% number of the attribute associated to |\fooattr| assuming it was defined
% using |\newluatexattribute\fooattr|, something that \luatex currently
% doesn't support (you can get the current value of the associated attribute
% as |tex.atrribute.fooattr|, but not the attribute number).
%
% There are several ways to work around this. For example, it is possible to
% extract the number at any time from the |\meaning| of |\foobar|.
% Alternatively, one could look at |\the\allocationnumber| just after the
% definition of |\fooattr| and remember it in a Lua variable. For your
% convenience, this is automatically done by |\newluatexattribute|: the number
% is remembered in a dedicated Lua table so that you can get it as
% |luatextra.attributes.foobar| (mind the absence of backslash here) at any
% time.
%
%    \section{Implementation}
%
%    \subsection{\tex package}
%
%    \begin{macrocode}
%<*texpackage>
%    \end{macrocode}
%
%    \subsubsection{Preliminaries}
%
%    Reload protection, especially for \plaintex.
%
%    \begin{macrocode}
                \csname lltxb@attr@loaded\endcsname
\expandafter\let\csname lltxb@attr@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/11 v0.1  Attributes 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-attr}{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@attr@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.attr.lua', 'lua'))}
%    \end{macrocode}
%
%    The allocaton macro.
%
%    \begin{macrocode}
\newcount\lltxb@attribute@alloc
\lltxb@attribute@alloc\m@ne
\def\newluatexattribute#1{%
  \ifnum\lltxb@attribute@alloc<65535\relax
    \global\advance\lltxb@attribute@alloc\@ne
    \allocationnumber\lltxb@attribute@alloc
    \global\luatexattributedef#1=\allocationnumber
    \unsetluatexattribute#1%
    \begingroup\escapechar\m@ne \expandafter\endgroup
    \directlua{luatextra.attributedef_from_tex(
      '\luatexluaescapestring{\string#1}', '\number\allocationnumber')}%
    \wlog{\string#1=\string\luatexattribute\the\allocationnumber}%
  \else
    \errmessage{No room for a new \string\attribute}%
  \fi}
%    \end{macrocode}
%
%    Helper macro |\unsetluatexattribute|: depends on \luatex's version.
%
%    \begin{macrocode}
\def\unsetluatexattribute#1{%
  \ifnum\luatexversion<37\relax
    #1=-1\relax
  \else
    #1=-"7FFFFFFF\relax
  \fi}
%    \end{macrocode}
%
%    And now the trivial helper macro.
%
%    \begin{macrocode}
\def\setluatexattribute#1#2{%
  #1=\numexpr#2\relax}
%    \end{macrocode}
%
%    That's all folks!
%
%    \begin{macrocode}
\lltxb@attr@AtEnd
%</texpackage>
%    \end{macrocode}
%
%    \subsection{Lua module}
%
%    \begin{macrocode}
%<*luamodule>
module('luatextra', package.seeall)
%    \end{macrocode}
%
%    Record the allocation number in a Lua table.
%
%    \begin{macrocode}
attributes = {}
tex.attributenumber = attributes
function attributedef_from_tex(name, number)
    attributes[name] = tonumber(number)
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 attribute's number is remembered well,
%    independently of the current value of |\escapechar|.
%
%    \begin{macrocode}
%<testplain>\input luatexbase-attr.sty
%<testlatex>\RequirePackage{luatexbase-attr}
%<*testplain,testlatex>
\newluatexattribute\testattr
\setluatexattribute\testattr{1}
\unsetluatexattribute\testattr
\directlua{assert(luatextra.attributes.testattr)}
\begingroup
\escapechar64
\newluatexattribute\anotherattr
\endgroup
\setluatexattribute\anotherattr{1}
\directlua{assert(luatextra.attributes.anotherattr)}
%</testplain,testlatex>
%<testplain>\bye
%<testlatex>\stop
%    \end{macrocode}
%
%
% \Finale
\endinput
