2

I wish to give a default value to a series of arguments when they are empty. I could make a test prior the use of the argument and modify the value just before each of the usage. I could even make a macro to do so. I could build a macro that encapsulate the initial macro that would "process" the arguments. A more elegant way would be to modify the argument, right at the beginning of the macro. Is it possible ?

I wish I could change the value in #1, something like \def#1{...}:

\def\DisplayNumber#1{
\def#1{\ifx&#1& 0\else#1\fi} % if argument empty, make #1 equal to 0
Result is : #1}
  • Could you also provide the community with your use-case via a minimal example? Something tangible that highlights what you mean by "modify [a] macro argument"? – Werner Jun 15 '15 at 7:09
  • @egreg : Thanks for editing, I tried to do that with {} (code sample) but had not the result awaited (instead, I lost the carriage returns). – user1771398 Jun 15 '15 at 7:35
1

The simplest way is adding the conditional at the point of use:

\def\DisplayNumber#1{%
  Result is: \ifx&#1&0\else#1\fi
}

Instead of the \ifx&#1& test for emptyness, you can use

\if\relax\detokenize{#1}\relax

provided you have e-TeX extensions enabled.

You can also define a utility macro:

\def\printifempty#1#2{\ifx&#2&#1\else#2\fi}

and your macro can be

\def\DisplayNumber#1{%
  Result is: \printifempty{0}{#1}%
}

A “generic” strategy for changing arguments is to define an “external” and an “internal” macro. With the help of expl3 one can avoid cumbersome code with scores of \expandafter and \romannumeral.

\input expl3-generic

\ExplSyntaxOn

\cs_new:Nn \test_internal_macro:nnnnnn
 {
  \internalmacro{#1}{#2}{#3}{#4}{#5}{#6}
 }
\cs_generate_variant:Nn \test_internal_macro:nnnnnn { ffffff }

\cs_new:Nn \test_external_macro:nnnnnn
 {
  \test_internal_macro:ffffff
   { \tl_if_blank:nTF { #1 } { 0 } { #1 } }
   { \tl_if_blank:nTF { #2 } { 0 } { #2 } }
   { \tl_if_blank:nTF { #3 } { 0 } { #3 } }
   { \tl_if_blank:nTF { #4 } { 0 } { #4 } }
   { \tl_if_blank:nTF { #5 } { 0 } { #5 } }
   { \tl_if_blank:nTF { #6 } { 0 } { #6 } }
 }

\cs_new_eq:NN \externalmacro \test_external_macro:nnnnnn

\ExplSyntaxOff

\def\internalmacro#1#2#3#4#5#6{%
  \bigskip Calling {\tt\string\externalmacro}\par
  This is arg \#1: #1\par
  This is arg \#2: #2\par
  This is arg \#3: #3\par
  This is arg \#4: #4\par
  This is arg \#5: #5\par
  This is arg \#6: #6\par
}

\externalmacro{A}{B}{C}{D}{E}{F}

\externalmacro{A}{}{}{D}{E}{F}

\externalmacro{}{}{}{}{}{}

\bye

The \externalmacro command is defined to call \internalmacro with “normalized” arguments: if one of them is blank, 0 is substituted.

This calls \test_internal_macro:ffffff, which is a wrapper around \internalmacro that's the one you give the “real” definition.

enter image description here

  • Sure, as I mentioned in the question, these are ways to do it. But, that's the problem with the very minimal, I have several usage of the argument. I wish something more "elegant", more readable also at the point of usage of the argument. – user1771398 Jun 15 '15 at 7:39
  • @user1771398, store the value in a macro, and do the test at the storing stage. – daleif Jun 15 '15 at 7:45
  • @daleif interesting idea : it means in fact a transfer to another set of "variables", let say \a,\b... It is very near from the encapsulation alternative, but with other names than #1,#2 etc. – user1771398 Jun 15 '15 at 7:52
  • @user1771398 another benefit is that you can use these in the end part of a normal \newenvironment definition. There env args does not apply (can be done using xparse). Also see the etoolbox package for various useful macroing tools. – daleif Jun 15 '15 at 8:13
  • @user1771398 What's the problem with \printifempty? I'd avoid doing \def inside the replacement text of \DisplayNumber if expandable alternatives are available. – egreg Jun 15 '15 at 8:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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