Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Can someone explain to my why \foo and \bar are not the same (in the \ifx sense) in this example:

\documentclass{article}
\begingroup
  \catcode`|=3\relax
  \gdef\abc{|}
\endgroup
\makeatletter
\newcommand\foobar{
  \begingroup
    \catcode`|=3\relax
    \def\abc{|}
    \@foobar
}
\newcommand\@foobar[1]{
  \xdef\foo{#1}
  \endgroup
}
\edef\bar{\abc}
\foobar{\abc}

\begin{document}
foo means ``\meaning\foo'' and bar means ``\meaning\bar'', but the ``meanings'' are
\ifx\foo\bar
  same
\else
  different
\fi
\end{document}

I included the \@foobar because I read somewhere that the catcode had to be changed before reading the macro parameter (I don't think it applies here, but I have no idea what I am doing).

The global definition of \abc (the one defined with \gdef) is | with catcode 3. I would like the local definition of \abc (the one defined with \def) to also be | with catcode 3. In my example the local \abc is | with catcode 12. Ultimately I would like to have \foobar{\abc} expand to | with catcode 3 without having \abc defined golbally.

share|improve this question
    
You say you want to avoid the global definition of \abc but what do you want to define it to be? How do you want to use it? If you edit your question to give some higher level requirements, someone could suggest some code that would help –  David Carlisle Mar 8 '12 at 17:04
    
@DavidCarlisle I tried to clarify the question. I hope it helps. –  StrongBad Mar 8 '12 at 17:46
    
OK I added some code to my answer –  David Carlisle Mar 8 '12 at 17:55

3 Answers 3

up vote 7 down vote accepted

The problem lies here:

\newcommand\foobar{
  \begingroup
    \catcode`|=3\relax
    \def\abc{|}
    \@foobar
}

The \def\abc{|} is read by \newcommand and its catcodes are fixed then. The \catcode|=3\relaxis executed when the\foobar` macro is used not when it is defined.

You can use the following instead:

\begingroup
\newcommand\foobar{}% to get the name check 
\catcode`\|=3\relax
\gdef\foobar{%
  \begingroup
    \catcode`\|=3\relax
    \def\abc{|}%
    \@foobar
}
\endgroup

This changes the catcode of | to 3 also for the definition. You onlt need to use \@foobar if the user should be allowed to add | with catcode 3 inside the argument. Otherwise you simply let \foobar read the argument and use \xdef\foo{#1} inside \foobar directly. Then you don't need the second, inner\catcode\|=3\relax` line as well.

Also, you should place % at lines ending with { or } because otherwise the source code line breaks will be taken as a space which are inserted in the document.

share|improve this answer
    
I think there is an extra \begingroup in the definition of \foobar (left over from my awful example). I am not so confident to actually edit your answer. –  StrongBad Mar 8 '12 at 17:49
    
@DanielE.Shub: No, I don't think so. The closing \endgroup is inside \@foobar. Keep in mind that the outer grouping commands are executed during the definition but the inner ones during the usage of the macro. –  Martin Scharrer Mar 8 '12 at 18:22

I have no idea what you want to achieve. But the catcode of an input is assigned at the moment when TeX reads the input the first time. When the definition body of foobar is read the catcode of | is "other" and so your \foobar will always define "\abc = | with catcode other", regardless of the catcode value when you actually execute \foobar.

If you want to change the catcode of an input you can do it e.g. by writing it to an external file and then reinput it or by using \scantokens.

share|improve this answer

They are different because one holds a math-shift character and the other holds a punctuation character (catcodes 3 and 12) you can see this if you typeset

foo \foo 1*2*3 \foo

bar \bar 1*2*3 \bar

You can locally define \abc to be a \catcode 3 | with various idioms for example this one is used all over the place (usually with ~ to get an active character rather than $) for example the definition of \verb in latex.ltx.

\begingroup\lccode`$=`\|\lowercase{\endgroup\def\abc{$}}

defines \abc to be a math-shift | without any global definition.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.