Search code examples
latextex

TeX edef macro blues


I spent some time trying to write a 'helper' macro to test a parameter for a new value, else use the existing value -- default values exist for all parameter positions.

I wanted to be able to write:

\foo{left}{nil}{}{20pt}

so that the second parameter would used its current value but the third value would be the value empty string. I wanted to use the notation:

\edef\pA{\isnil{#1}{\pA){#1}} % one for each parameter

I defined \isnil like so:

\def\nil{nil}
\def\isnil#1#2#3{%
  \edef\nilTest{#1}%
  \ifx\nilTest\nil#2\else#3\fi
}

but when I tried to run it, TeX complained that \nilTest is an undefined control sequence. That is true of course, but I want \pA to hold a value, not a recipe for a value, so it must be an \edef which means that all the macro test will be expanded but while will the \edef not protect the \nilTest -- is this a place to use \noexpand -- that did not seem to work for me.

EDIT: no digits in \cs names (yeah, I knew that.)


Solution

  • Why doesn't your solution work? \edef\pA{\isnil{#1}{\pA){#1}} expands \isnil and gets \edef\nilTest{.... Now \edef is not expandable and falls into a sequence of \pA as the first element. An attempt to expand the next macro \nilTest fails.

    Use \setpar from the following code to change your parameter.

    \def\nil{nil}
    \def\setpar#1#2{%
      \edef\nilTest{#2}%  
      \ifx\nilTest\nil\else\let#1\nilTest\fi}
    
    \def\first{old first}
    \def\second{old second}
    \setpar \first{nil}
    \setpar \second{new}
    
    first = ``\first'', second = ``\second''
    

    P.S. Do not use digits in your macro.