Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Active character let to a (non-active) character

10 views
Skip to first unread message

Bruno Le Floch

unread,
Feb 23, 2011, 7:20:17 PM2/23/11
to
I already asked the question on [tex.stackexchange.com][1], and I was
told to seek further opinions here.

Implicit characters have all sorts of nice properties. For example,

\let\dol$ \dol\dol x^2\dol$ text $\dol y^2\dol$

will typeset both equations in display mode. One advantage of using a
control sequence over a character with a special catcode is that this
control sequence can be redefined in case we have special needs. In
order to stilll use `$` in the input, rather than the cryptic `\dol`,
we can make `$` an active character, let to the math shift `$`:

\let\dol$ \catcode`\$=13\relax \let$\dol

A cleaner way of implementing that in general is the `\activate` macro
below, which uses a standard `\lccode` trick.

\def\activate#1{\begingroup
\lccode`\~=`#1%
\lowercase{\endgroup \let~#1}%
\catcode`#1=13\relax}

With that definition, it seems mostly harmless to `\activate &`, `
\activate $`, `\activate _`, `\activate ^`, `\activate #`. An example
at the bottom of this email shows that `$$`, the preamble and body of `
\halign`, and the macro parameters, are still recognized.

I could only find two cases where it breaks:
- ^^x is not recognized anymore as a single character
- in a `\csname ... \endcsname` construction, explicit characters
would be ok, but their active implicit counterpart needs `\string`.

I am particularly interested in knowing what the drawbacks of this
approach are for `&`, since it allows a nice fix for some `\futurelet`
accident in nested `\halign`s : redefining `&` before using `
\futurelet`, so that seeing it does not trigger the construction of a
cell, and restoring it `\afterassignment`.

--
Regards,
Bruno

% ======== Short example

\activate &
\halign{#&#\cr a&b\cr}

\activate $ \activate ^ \activate _
$$ x^2_2 + y^2_2 $$

\activate #
\def\myshow#1{\show#1}
\myshow #
\bye

[1]: http://tex.stackexchange.com/questions/11872/active-characters-let-to-a-non-active-character

GL

unread,
Feb 24, 2011, 6:54:31 AM2/24/11
to
Le 24/02/2011 01:20, Bruno Le Floch a écrit :
> I already asked the question on [tex.stackexchange.com][1], and I was
> told to seek further opinions here.
[...]

> I could only find two cases where it breaks:
> - ^^x is not recognized anymore as a single character

Yes, ^ must be a subscript character for this syntax:

\catcode`\*=7
**x

is then the same as ^^x


> I am particularly interested in knowing what the drawbacks of this
> approach are for `&`, since it allows a nice fix for some `\futurelet`
> accident in nested `\halign`s : redefining `&` before using `
> \futurelet`, so that seeing it does not trigger the construction of a
> cell, and restoring it `\afterassignment`.

This is absolutely not recommanded at all to change those category
codes. luaTeX provides \alignmark (#) and \aligntab (&).
see: http://www.luatex.org/svn/trunk/manual/luatexref-t.pdf

You shall not change the catcode of & inside \halign, but use the
so called "dirty trick" (which is, actually, clean for there is no
other solution) to increment/decrement the master counter used by
TeX inside \halign:

{\ifnum0=`}\fi
do some scanning with \futurelet until & (or whatever)
\ifnum0=`{\fi}

Or better (for in math mode, the construction above adds a math atom,
which is \hbox{}) :

\begingroup \iffalse{\fi \ifnum0=`}\fi
scan with \futurelet until & (or whatever)
\ifnum0=`{}\fi \endgroup

Yours sincerely.

Bruno Le Floch

unread,
Feb 24, 2011, 8:26:59 AM2/24/11
to
Hi GL,

thank you for your answer, but you don't provide any case where my
approach breaks. I know the usual problems brought by changing
catcodes mid-document. But here, I am setting the catcode at the very
beginning of the document. Since these characters are let to their non-
active counterparts (with the original catcode), most of their uses
are unchanged.

* \ifx or \ifcat will not differentiate between a true &4 and an
implicit &4
* \halign will not differentiate between the two either
* Math mode is happy with implicit $3
* Macro definitions work with implicit #6, even nested definitions
with ##.
* Sub- and superscripts work in math mode (expected since \sb and \sp
work)
* Neither \string nor \meaning can differentiate between true and
active implicit characters

OTOH, it is true that
* ^^X now fails
* \csname &\endcsname fails, but can be replaced by \csname \string&
\endcsname

> \catcode`\*=7
> **x
Indeed. It only works for two identical characters of catcode 7.

> This is absolutely not recommanded at all to change those category
> codes.

I'm avoiding the common problem of _changing_ catcodes by setting the
catcode at the start of the document.

> luaTeX provides \alignmark (#) and \aligntab (&).
> see:http://www.luatex.org/svn/trunk/manual/luatexref-t.pdf

Thanks for the luaTeX pointer.

> You shall not change the catcode of & inside \halign, but use the
> so called "dirty trick" (which is, actually, clean for there is no
> other solution) to increment/decrement the master counter used by
> TeX inside \halign:

Thank you. I know that trick already, but I heard that ther were still
issues with it (I'll post as soon as I can find out which precisely).
Thus, I'm trying to find alternative solutions. By the way, I am not
changin the catcode of & inside \halign only (which would break inside
macro arguments), but in the whole document.

--
Regards,
Bruno

GL

unread,
Feb 24, 2011, 8:48:03 AM2/24/11
to
Le 24/02/2011 14:26, Bruno Le Floch a écrit :
> Hi GL,
>
> thank you for your answer, but you don't provide any case where my
> approach breaks. I know the usual problems brought by changing
> catcodes mid-document. But here, I am setting the catcode at the very
> beginning of the document. Since these characters are let to their non-
> active counterparts (with the original catcode), most of their uses
> are unchanged.
>
> Thank you. I know that trick already, but I heard that ther were still
> issues with it (I'll post as soon as I can find out which precisely).
> Thus, I'm trying to find alternative solutions. By the way, I am not
> changin the catcode of& inside \halign only (which would break inside

> macro arguments), but in the whole document.

Well, I thought your purpose was to collect in a way or another (with
\futurelet you said) inside \halign.

For this purpose, the dirty trick is provided and works perfectly.
It does not change anything from plain TeX or LaTeX for it is local.
Then, changing the catcode is a bad choice as long as another
solution (for this purpose) exists.

Then ? What's your purpose ? Why do you really want or need to change
the catcode ?

Regards.

>
> --
> Regards,
> Bruno

Joseph Wright

unread,
Feb 24, 2011, 2:02:36 PM2/24/11
to
On 24/02/2011 13:48, GL wrote:
> Well, I thought your purpose was to collect in a way or another (with
> \futurelet you said) inside \halign.
>
> For this purpose, the dirty trick is provided and works perfectly.
> It does not change anything from plain TeX or LaTeX for it is local.
> Then, changing the catcode is a bad choice as long as another
> solution (for this purpose) exists.

Only if there is no danger of nesting from different sources (for
example, there is an outstanding problem in expl3 that both its
\peek_... functions and the 'robust' code in the LaTeX2e kernel try to
do the same thing).
--
Joseph Wright

Bruno Le Floch

unread,
Feb 25, 2011, 8:34:49 AM2/25/11
to
Let me rephrase my question: in what situations do a catcode 4 `&`,
and an active character & let to an alignment tab (result of \let
\temp& \catcode`\&=13 \let&\temp) behave differently?

>> Then ? What's your purpose ? Why do you really want or need to
>> change the catcode ?

My reason to change the catcode is that it seems to bring a different
way of fixing the problem of \futurelet (used e.g. to check for an
optional argument) in \halign. I had heard what Joseph mentionned
here:

> there is an outstanding problem in expl3 that both its
> \peek_... functions and the 'robust' code in the LaTeX2e kernel try to

> do the same thing.

Although I don't have a precise example of that problem, I think that
my different approach might solve the issue. But maybe it breaks
something else in an unforseen way, hence my question: what breaks?

GL

unread,
Feb 28, 2011, 12:21:18 PM2/28/11
to
Le 24/02/2011 01:20, Bruno Le Floch a écrit :
> I already asked the question on [tex.stackexchange.com][1], and I was
> told to seek further opinions here.

And what about a macro defined by:

\@ifnextchar &
\@ifnextchar $
\@ifnextchar ^
\@ifnextchar _
\@ifnextchar # may be ...

and so on ?


>
> Implicit characters have all sorts of nice properties. For example,
>
> \let\dol$ \dol\dol x^2\dol$ text $\dol y^2\dol$
>
> will typeset both equations in display mode. One advantage of using a
> control sequence over a character with a special catcode is that this
> control sequence can be redefined in case we have special needs. In
> order to stilll use `$` in the input, rather than the cryptic `\dol`,
> we can make `$` an active character, let to the math shift `$`:
>
> \let\dol$ \catcode`\$=13\relax \let$\dol
>
> A cleaner way of implementing that in general is the `\activate` macro
> below, which uses a standard `\lccode` trick.
>
> \def\activate#1{\begingroup
> \lccode`\~=`#1%
> \lowercase{\endgroup \let~#1}%
> \catcode`#1=13\relax}
>

> With that definition, it seems mostly harmless to `\activate&`, `

Bruno Le Floch

unread,
Mar 1, 2011, 4:04:13 AM3/1/11
to
> And what about a macro defined by:
>
> \@ifnextchar &
> \@ifnextchar $
> \@ifnextchar ^
> \@ifnextchar _
> \@ifnextchar #   may be ...
>
> and so on ?

`\@ifnextchar` will be fooled by an implict characters: it uses an `
\ifx` test. In fact, `\if`, `\ifcat`, and `\ifx` are all three fooled
by these active implicit characters.

\makeatletter
\def\foo{\@ifnextchar &{\message{yes}\@gobbletwo}{\message{no}
\@gobble}}
\foo{abc}
\foo&{abc}
\let\aligntab& \catcode`\&=13 \let&\aligntab
\foo{abc}
\foo&{abc}

shows `no yes no yes` on the terminal as expected. A macro delimited
by `&`, will not work though, except if we change & to be an active
implicit character before it is defined.

0 new messages