[comp.text.tex] Testing for null arguments

rjohnson@vela.acs.oakland.edu (R o d Johnson) (03/14/91)

This is undoubtedly a question with a simple answer that I just can't
seem to get. I want to have a macro (for use in LaTeX documents) that
can have three arguments, two of which can be null.  It's invoked like
this:

  \prt{arg1}{arg2}{arg3}

but could also look like any of the following:

  \prt{}{arg2}{arg3}
  \prt{arg1}{arg2}{}
  \prt{}{arg2}{}

(arg2 will always be present).  I want to define an new \if (I guess)
that would allow me to define a macro like the following:

  \def\part#1#2#3{%           % or should there be braces around
   [some code]                % the arguments in the definition?
  %
  \ifnull{#1} \relax \else    % I guess it would be simpler to have
   [some more code]           % an \ifnotnull to do this
  \fi
  %
  \ifnull{#3} \relax \else
   [some more code]
  \fi
  }

I just can't figure out how to come up with an \ifnull or \ifnotnull.
Any suggestions?  Thanks in advance.

-- 
 Rod Johnson  *  rjohnson@vela.acs.oakland.edu  *  (313) 650 2315 

                "Life has a throat" --Peter Blegvad

gvr@cs.brown.edu (George V. Reilly) (03/14/91)

In article <5396@vela.acs.oakland.edu> rjohnson@vela.acs.oakland.edu (R o d Johnson) writes:
| 
| This is undoubtedly a question with a simple answer that I just can't
| seem to get. I want to have a macro (for use in LaTeX documents) that
| can have three arguments, two of which can be null.  It's invoked like
| this:
| 
|   \prt{arg1}{arg2}{arg3}
| 
| but could also look like any of the following:
| 
|   \prt{}{arg2}{arg3}
|   \prt{arg1}{arg2}{}
|   \prt{}{arg2}{}
| 
| (arg2 will always be present).  I want to define an new \if (I guess)
| that would allow me to define a macro like the following:
| 
|   \def\part#1#2#3{%           % or should there be braces around
|    [some code]                % the arguments in the definition?
|   %
|   \ifnull{#1} \relax \else    % I guess it would be simpler to have
|    [some more code]           % an \ifnotnull to do this
|   \fi
|   %
|   \ifnull{#3} \relax \else
|    [some more code]
|   \fi
|   }
| 
| I just can't figure out how to come up with an \ifnull or \ifnotnull.
| Any suggestions?  Thanks in advance.

Try this:

\def\part#1#2#3{%
    \def\first{#1}	% Or something with more mnemonic value
    \def\third{#1}
    [some code]
    %
    \ifx\first\empty
	% do nothing
    \else
	[some more code]
    \fi
    [etc.]
}

You might find it more convenient to define \part using
strings to delimit the three arguments, e.g.:
	\def\part #1:#2:#3!{%...
so you can say
	\part :arg2:!		or
	\part :arg2:arg3!	or
	\part arg1:arg2:!	or
	\part arg1:arg2:arg3!	or
you can use multicharacter strings instead of the `:'s and the `!',
of course.
________________
George V. Reilly   `LiveLong&Fester'	gvr@cs.brown.edu   +1 (401) 863-7684
uunet!brunix!gvr   gvr@browncs.bitnet	Box 1910, Brown U, Prov, RI 02912

em@dce.ie (Eamonn McManus) (03/15/91)

gvr@cs.brown.edu (George V. Reilly) writes:
>\def\part#1#2#3{%
>    \def\first{#1}	% Or something with more mnemonic value
>    \def\third{#1}
>    [some code]
>    %
>    \ifx\first\empty
>	% do nothing
>    \else
>	[some more code]
>    \fi

Another way of testing for null arguments is exemplified by this macro:
    \def\showempty#1{\message{\ifx\relax#1\relax empty\else not empty\fi}}

This has the advantage that it can be done entirely in TeX's mouth,
whereas the \def's in Geo's solution cannot.  It does however fail badly
if #1 begins with \relax (e.g., \showempty{\relax...}).

I have the feeling that there is a better solution.

,
Eamonn

rjohnson@vela.acs.oakland.edu (R o d Johnson) (03/15/91)

Thanks to everyone that sent help on this, especially Raymond Chen,
Richard Hughey (who contributed an idea unlike any other) and Bill
Mitchell, whose version I actually used.

Incidentally, Raymond's solution was

  \def\ifnull#1{\def\@tempa{#1}\ifx\@tempa\empty}

which doesn't work.  I'm still not sure why.  If instead we use

  \def\ifnull#1{\def\@tempa{#1}\def\@tempb{}\ifx\@tempa\@tempb}

it works fine.  Since \@tempb is defined the same way as \empty I'm
puzzled by this.  Can anyone confirm this (mis)behavior or explain it?

-- 
 Rod Johnson  *  rjohnson@vela.acs.oakland.edu  *  (313) 650 2315 

  "House, bridge, well, gate, jug, olive tree, window"  --Rilke

jeffrey@cs.chalmers.se (Alan Jeffrey) (03/15/91)

In article <5396@vela.acs.oakland.edu> rjohnson@vela.acs.oakland.edu (R o d Johnson) writes:
[...]
>I just can't figure out how to come up with an \ifnull or \ifnotnull.
>Any suggestions?  Thanks in advance.

One simple solution is to test

   \def\unlikely{This is rather unlikely}
   \def\ifnull#1{\ifx\unlikely#1\unlikely}

Then 

   \ifnull{}    A \else B \fi = \ifx\unlikely\unlikely A \else B \fi = A
   \ifnull{xyz} A \else B \fi = \ifx\unlikely xyz\unlikely A \else B \fi = B

Actually, this is true if #1 is empty, or #1 begins with \unlikely.
So as long as \unlikely is an unlikely control sequence to appear,
you're OK.

What a hack...

Alan.

Alan Jeffrey         Tel: +46 31 72 10 98         jeffrey@cs.chalmers.se
Department of Computer Sciences, Chalmers University, Gothenburg, Sweden