[tex-eplain] optional arguments

Oleg Katsitadze olegkat at gmail.com
Sat Aug 29 05:31:29 CEST 2009


On Wed, Aug 26, 2009 at 06:17:17PM -0400, Russell Lyons wrote:
> -------------
>
> \let\nobibtex = t
> \let\noarrow = t
> \input eplain
> \enablehyperlinks[idxexact]
> \catcode`@=\letter
> \def\residx{\@getoptionalarg\finresidx}
> \def\finresidx#1{\ifx\@optionalarg\empty{\sidx{#1}}
>             \else{\sidx{#1}[\@optionalarg]}\fi}
>
> And a result later. \residx[sub]{result}
>
> \vfill\eject
>
> \readindexfile{i}
>
> \bye
>
> -------------
>
> However, what is produced in the index is the entry "result" with the
> subentry "optionalarg ". (Note it also has an extra space.)
>
> What am I doing wrong?

You are not expanding \@optionalarg.  Since \sidx doesn't expand the
optional argument, it gets written to the .idx file as is.  But if
\sidx would have tried to expand it, I suspect you would get infinite
recursion, because inside \sidx, \@optionalarg would be defined as a
call to a single macro, \@optionalarg.

Anyway, to do what you want you need the \edef trick (below), as
suggested by Karl.  We pass #1 and the expansion of \@optionalarg
through toks registers to avoid any further expansion.  And we don't
use \toks1 because by convention assignments to \toks1 should be
\global, to avoid save stack overflow.

HTH,
Oleg

\def\finresidx#1{%
  \ifx\@optionalarg\empty
    \sidx{#1}%
  \else
    \toks0={#1}%
    \toks2=\expandafter{\@optionalarg}%
    \edef\temp{\noexpand\sidx{\the\toks0}[\the\toks2]}%
    \temp
  \fi
}

Also note that this can be simpler, although slightly less efficient:

\def\finresidx#1{%
  \toks0={#1}%
  \toks2=\expandafter{\@optionalarg}%
  \edef\temp{\noexpand\sidx{\the\toks0}[\the\toks2]}%
  \temp
}


More information about the tex-eplain mailing list