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.

I have this code on my hard disk and now I would like to understand it. Firstly I would like to know if this code is correct and logic or if there is another way to do the same thing.

\documentclass{article}
\usepackage{fp}

\newcommand*\macro[2][]{%
  Option : #1\par % print the option in #1
  \let\y #2 % to keep 
\begingroup
  \catcode`\(=1
  \catcode`\)=2
  \macrobis
}
\newcommand*\macrobis[1]{%
\endgroup
\scantokens{\def\temp{#1}}}

\begin{document}

\def\fct{x*x}

\macro[op]{\fct}(exp(1))

\FPeval\x{\temp}%
\FPeval\img{\y}%
x = \x\ donne  y = \img

\end{document}

\begingroup and \endgroup are here, I suppose, because the code changes the catcodes but tha call of macrobis is very strange. Where is the argument ? Can someone explain this code?

share|improve this question
add comment

2 Answers 2

up vote 10 down vote accepted

Let's see one command at a time:

\newcommand*\macro[2][]{%
  Option : #1\par % print the option in #1
  \let\y #2 % to keep 
\begingroup
  \catcode`\(=1
  \catcode`\)=2
  \macrobis
}

\macro has one optional argument (default empty) and a mandatory one. It assumes that the mandatory argument is one token, as it does \let\y#2 (but will leave a space in the input stream). Then it opens a group where it sets ( and ) as delimiters just like { and }; after this it calls \macrobis.

\newcommand*\macrobis[1]{%
\endgroup
\scantokens{\def\temp{#1}}}

\macrobis gathers its argument considering ( and ) as braces. Then it ends the group, so ( and ) return to their previous status and defines \temp to expand to #1 but inside \scantokens so the possible ( and ) characters in #1 will be rescanned in this setting where they are not delimiters any more.

What appears to be a parenthesized second mandatory argument to \macro is actually the argument to \macrobis, but this is not relevant from a user's point of view.

The point is to hide possible parentheses in that argument: if one defined

\newcommand*\macro[2][]{%
  Option : #1\par % print the option in #1
  \let\y #2 % to keep 
  \macrobis}
\def\macrobis(#1){\def\temp{#1}}

then an input such as \macro[op]{\fct}(exp(1)) would interpret exp(1 as the argument to \macrobis, which would be wrong.

share|improve this answer
2  
This is magic ! –  Alain Matthes Dec 29 '11 at 17:31
    
@Altermundus A slick trick indeed! –  egreg Dec 29 '11 at 17:32
    
There is no problem with the first (but why it's the last ) that is used like a brace ? –  Alain Matthes Dec 29 '11 at 17:54
2  
@Altermundus In order to gather the argument! In the example, when \macrobis is called, this is equivalent to write {exp{1}} so everything is balanced and the argument is exp(1) (TeX considers those as delimiters, but after \scantokens they return to be as normal). –  egreg Dec 29 '11 at 17:58
add comment

As far as I interpret it, macros (or control sequences) could be considered "replacements" for larger constructs (here "larger constructs" refers to the macro contents). As such, \macro gobbles \macro[op]{\fct} since it requires 2 arguments, does some magic, and replaces it with \macrobis. Still left in the input steam is (exp(1)) with the category codes changed for ( and ) to group beginning and endings, respectively. So, effectively you're left with \macrobis{exp(1)}, which represents valid input for \macrobis, since it requires a single argument.

On a related note, consider the following. \FPeval is a macro that takes two arguments as is evident from \show\FPeval:

> \FPeval=macro:
#1#2->\FP@eval {#1}{#2}.

However, if you define

\newcommand{\myfunc}{\FPeval}

where \myfunc now takes no arguments, and use

\myfunc\x{\temp}%
\myfunc\img{\y}%
x = \x\ donne  y = \img

you'll get the same output, illustrating the idea behind replacement.

share|improve this answer
1  
Good remark with \newcommand{\myfunc}{\FPeval} –  Alain Matthes Dec 29 '11 at 17:48
add comment

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.