summaryrefslogtreecommitdiff
path: root/luatexbase-attr.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'luatexbase-attr.dtx')
-rw-r--r--luatexbase-attr.dtx92
1 files changed, 67 insertions, 25 deletions
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