[Dev-luatex] Assignments in TeX's mouth, or: "Dr. Zaius, it can talk!"

Jonathan Sauer Jonathan.Sauer at silverstroke.com
Tue Aug 14 09:04:00 CEST 2007


Hello,

normally, TeX cannot perform assignments in the mouth (except for
\let-ing a previously undefined control sequence to \relax when
using \csname...\endcsname). With LuaTeX, this has changed, albeit
in a slightly weird way: All assignments are \global.

Plain example (with some variations on a theme):

---------------------------------- CUT ------------------------------

\tracingassigns1

% Access internal control sequences:
\catcode`@=11

% For easier logging:
\def\log#1{\immediate\write\sixt@@n{#1}}
\let~\space


\count@=5
\log{Before:~~~~~~~~~~~~~~~~~~~\the\count@}


% We only define \test, we do not execute it:
\begingroup
\edef\test{%
	\directlua0{%
		% Note that `tex.count.count@' (syntactic sugar for the
code
		% below) cannot be used, since `@' is not a letter and
thus
		% not part of an identifier:
		tex.count["count@"]=42
		% We create some contents for \test:
		tex.print("Contents of test")
	}%
}

% Behold: We changed \count@ in the mouth!
\log{After:~~~~~~~~~~~~~~~~~~~~\the\count@}

% Note that \test only contains the string passed to tex.print above. 
% The rest of the Lua code has been executed completely:
\log{\string\test~is:~~~~~~~~~~~~~~~~~\meaning\test}

\endgroup


% Now that is weird: Assigning registers in Lua is automatically
% global:
\log{After \string\endgroup:~~~~~~~~~~\the\count@}


% We try again, without \edef:
\begingroup
\directlua0{tex.count["count@"]=23}
\log{In group, 2nd try:~~~~~~~~\the\count@}

\endgroup

% The assignment is global again:
\log{After \string\endgroup, 2nd try:~\the\count@}


% We try again, using accessor functions:
\begingroup
\directlua0{tex.setcount("count@",17)}
\log{In group, 3rd try:~~~~~~~~\the\count@}

\endgroup

% And global again:
\log{After \string\endgroup, 3rd try:~\the\count@}


% We try again, using accessor functions and \{b,e}group:
\bgroup
\directlua0{tex.setcount("count@",37)}
\log{In group, 3rd try:~~~~~~~~\the\count@}

\egroup

% And still global:
\log{After \string\endgroup, 3rd try:~\the\count@}


\bye

---------------------------------- CUT ------------------------------

Note: According to the Lua reference manual, section 2.1, the
definition of `letter' depends on the current locale. Would it be
possible/sensible to define the current locale not according to the
system TeX is run on (which would actually make LuaTeX code
locale-dependent, since some identifiers might not work on another
computer with a different locale) according to TeX's current catcode
table?

And while we're at it: Should string.uppercase and string.lowercase 
use the \lccode/\uccode tables?


When tracing assignments, the ones made from Lua are flagged as being
\global (BTW: What are these messages about `reassigning
[no_local_whatsits]'?):

---------------------------------- CUT ------------------------------

This is luaTeX, Version 3.141592-beta-0.10.2-2007081018 (Web2C 7.5.6)
(format=luatex 2007.8.10)  11 AUG 2007 08:50
**MouthSideeffect
(MouthSideeffect.tex{into \tracingassigns=1}
{changing \log=macro:->\mathop {\rm log}\nolimits }
{into \log=macro:#1->\immediate \write \sixt@@n {\ETC.}
{changing ~=macro:->\penalty \@M \ }
{into ~=macro:-> }
{changing \count255=92}
{into \count255=5}

Before:                   5
{reassigning [no_local_whatsits]=0}
{reassigning [no_local_dirs]=0}
{globally changing \count255=5}
{into \count255=42}
{changing \test=undefined}
{into \test=macro:->Contents of test}
After:                    42
\test is:                 macro:->Contents of test
After \endgroup:          42
{reassigning [no_local_whatsits]=0}
{reassigning [no_local_dirs]=0}
{globally changing \count255=42}
{into \count255=23}
In group, 2nd try:        23
After \endgroup, 2nd try: 23
{reassigning [no_local_whatsits]=0}
{reassigning [no_local_dirs]=0}
{globally changing \count255=23}
{into \count255=17}
In group, 3rd try:        17
After \endgroup, 3rd try: 17
{reassigning [no_local_whatsits]=0}
{reassigning [no_local_dirs]=0}
{globally changing \count255=17}
{into \count255=37}
In group, 3rd try:        37
After \endgroup, 3rd try: 37
 )
No pages of output.

---------------------------------- CUT ------------------------------

I do not think that assignments to TeX's registers done in Lua code
should be automatically \global, as it makes writing macros without
(intentioned) side-effects much harder. And those macros are the best,
since they can be used anywhere without having to remember that they
clobber register \foo, redefine macro \bar et cetera.

So, returning to this mail's subject, I can only say: "Take your hands
off my grouping, you damn dirty Lua code!" ;-)


Jonathan



More information about the dev-luatex mailing list