From 07b3d5073208c7093319198b240e7c4bc1422ee4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Sun, 23 May 2010 16:23:10 +0200
Subject: Lua functions for attributes.

---
 luatexbase-attr.dtx | 92 ++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 67 insertions(+), 25 deletions(-)

(limited to 'luatexbase-attr.dtx')

diff --git a/luatexbase-attr.dtx b/luatexbase-attr.dtx
index dd01e01..c1ba696 100644
--- a/luatexbase-attr.dtx
+++ b/luatexbase-attr.dtx
@@ -124,17 +124,20 @@ See source file '\inFileName' for details.
 % \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.
+% just like Plain TeX and LaTeX do for other registers, and also provides a
+% Lua interface.
 % \end{abstract}
 %
 % \tableofcontents
 %
 % \section{Documentation}
 %
+% \subsection{\tex interface}
+%
 % 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
+% it). |\unsetluatexattribute| unsets an attribute 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.
@@ -143,6 +146,8 @@ See source file '\inFileName' for details.
 % allocate an attribute the way you can locally allocate a counter using
 % \file{etex.sty}'s |\loccount|, so no corresponding macro is defined.
 %
+% \subsection{Lua interface}
+%
 % 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
@@ -159,6 +164,16 @@ See source file '\inFileName' for details.
 % |luatexbase.attributes.foobar| (mind the absence of backslash here) at any
 % time.
 %
+% Also, two Lua functions are provided that are analogous to the above \tex
+% macros (actually, the macros are wrappers around the functions):
+% |luatexbase.new_attributes|\parg{name} allocates a new attribute, without
+% defining a corresponding \tex control sequence (only an entry in
+% |luatexbase.attributes| is created. It usually returns the number of the
+% allocated attribute. If room is missing, it raises an error, unless the
+% second argument (optional) is not false, in which case it returns -1.
+%
+% |luatexbase.unset_attribute|\parg{name} unsets an existing attribute.
+%
 %    \section{Implementation}
 %
 %    \subsection{\tex package}
@@ -288,39 +303,32 @@ See source file '\inFileName' for details.
 %
 %    \subsection{User macros}
 %
-%    The allocaton macro. Unlike other registers, allocate starting from 1.
-%    Some code (eg, font handling coming from Con\tex{}t) behaves strangely
-%    with \verb+\attribute0+ and since there is plenty of room here, it
-%    doesn't seem bad to ``loose'' one item in order to avoid this problem.
+%    The allocaton macro is merely a wrapper around the Lua function, but
+%    handles error and logging in \tex, for consistency with other allocation
+%    macros.
 %
 %    \begin{macrocode}
-\newcount\lltxb@attribute@alloc
-\lltxb@attribute@alloc\z@
 \def\newluatexattribute#1{%
-  \ifnum\lltxb@attribute@alloc<65535\relax
-    \global\advance\lltxb@attribute@alloc\@ne
-    \allocationnumber\lltxb@attribute@alloc
+  \begingroup\escapechar\m@ne \expandafter\expandafter\expandafter
+  \endgroup                   \expandafter\expandafter\expandafter
+  \allocationnumber           \luatexbase@directlua{tex.write(
+    luatexbase.new_attribute("\luatexluaescapestring{\string#1}", true))}%
+  \ifnum\allocationnumber>\m@ne
     \global\luatexattributedef#1=\allocationnumber
-    \unsetluatexattribute#1%
-    \begingroup\escapechar\m@ne
-    \luatexbase@directlua{luatexbase.attributedef_from_tex(
-      '\luatexluaescapestring{\string#1}', '\number\allocationnumber')}%
-    \endgroup
     \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.
+%    Helper macro |\unsetluatexattribute|: wrapper around the Lua function.
 %
 %    \begin{macrocode}
 \def\unsetluatexattribute#1{%
-  \ifnum\luatexversion<37\relax
-    #1=-1\relax
-  \else
-    #1=-"7FFFFFFF\relax
-  \fi}
+  \begingroup\escapechar\m@ne
+  \luatexbase@directlua{%
+    luatexbase.unset_attribute("\luatexluaescapestring{\string#1}")}%
+  \endgroup}
 %    \end{macrocode}
 %
 %    And now the trivial helper macro.
@@ -344,12 +352,44 @@ See source file '\inFileName' for details.
 module('luatexbase', package.seeall)
 %    \end{macrocode}
 %
-%    Record the allocation number in a Lua table.
+%    This table holds the values of the allocated attributes, indexed by name.
 %
 %    \begin{macrocode}
 attributes = {}
-function attributedef_from_tex(name, number)
-    attributes[name] = tonumber(number)
+%    \end{macrocode}
+%
+%    The allocaton function. Unlike other registers, allocate starting from 1.
+%    Some code (eg, font handling coming from Con\tex{}t) behaves strangely
+%    with \verb+\attribute0+ and since there is plenty of room here, it
+%    doesn't seem bad to ``loose'' one item in order to avoid this problem.
+%
+%    \begin{macrocode}
+local last_alloc = 0
+function new_attribute(name, silent)
+    if last_alloc >= 65535 then
+        if silent then
+            return -1
+        else
+            error("No room for a new \\attribute", 1)
+        end
+    end
+    last_alloc = last_alloc + 1
+    attributes[name] = last_alloc
+    unset_attribute(name)
+    if not silent then
+        texio.write_nl('log', string.format(
+            'luatexbase.attributes[%q] = %d', name, last_alloc))
+    end
+    return last_alloc
+end
+%    \end{macrocode}
+%
+%    Unset an attribute the correct way depending on \luatex's version.
+%
+%    \begin{macrocode}
+local unset_value = (luatexbase.luatexversion < 37) and -1 or -2147483647
+function unset_attribute(name)
+    tex.setattribute(attributes[name], unset_value)
 end
 %    \end{macrocode}
 %
@@ -373,6 +413,8 @@ end
 \unsetluatexattribute\testattr
 \catcode64 11
 \luatexbase@directlua{assert(luatexbase.attributes.testattr)}
+\luatexbase@directlua{luatexbase.new_attribute('luatestattr')}
+\luatexbase@directlua{assert(luatexbase.attributes.luatestattr)}
 \begingroup
 \escapechar64
 \newluatexattribute\anotherattr
-- 
cgit v1.2.3

