Monday, March 7, 2016

Define newcommand with multiple sorted mandatory arguments that can be empty – tex.stackexchange.com #JHedzWorlD



I’m trying to define a command that will take 3 arguments each one possibly empty. An empty argument will slightly modify the output. Let me give a non-working example :


newcommandfoo[3] textbfbar( ifthenelseisempty#1 #1, #2) ifthenelseisempty#3 cap #3 

And this is what I would like to get :


  • fooabc => foo1

  • foob => foo2

  • foobc => foo3

But obviously it doesn’t work. I’d like, as much as possible, to call this function with only one type of bracket (since I will always write the 3 pairs of bracket even if they are empty). As far as I’m concern, I consider that there’s no optional arguments in it, only mandatory arguments that are possibly empty. I pretty sure I’m not doing things right but I really don’t get the idea of this newcommand function.


Thanks for any help.




While xparse is one way to go, here’s another approach:


documentclassarticle newcommandfoo[3]%% textbfbar(%% expandafterifxexpandafterrelaxdetokenize#1relax else #1, fi #2) expandafterifxexpandafterrelaxdetokenize#3relax else cap#3 fi pagestyleempty begindocument $fooabc$ $foob$ $foobc$ enddocument 

enter image description here The expandafterifxexpandafterrelaxdetokenize#1relax is a nice way of testing for an empty argument to your macro. Essentially if #1 is empty, then the detokenize#1 essentially vanishes and the test becomes


ifxrelaxrelax 

which will test to true.


If #1 is not empty, then detokenize will result in a token that is not going to result in a true value when compared with relax.


To make your code a little more readable, you could define your own test commnad sequence:


newcommandaeifempty[3]%% expandafterifxexpandafterrelaxdetokenize#1relax #2%% else #3%% fi 

and then your foo could be written as


newcommandfoo[3]%% textbfbar(%% aeifempty#1#1,%% #2) aeifempty#3cap#3 



If you use xparse, you need not define your own test for emptyness:


documentclassarticle usepackageamsmath usepackagexparse ExplSyntaxOn NewDocumentCommandifnotblankmm tl_if_blank:nF #1 #2 ExplSyntaxOff NewDocumentCommandfoommm % operatornamemathbfbar(ifnotblank#1#1,#2)% ifnotblank#3cap #3% begindocument begintabular@ll@ verb|fooabc| & $fooabc$ verb|foob| & $foob$ verb|foobc| & $foobc$ verb|foo b | & $foob$ verb|foo bc| & $foobc$ endtabular enddocument 

The function tl_if_blank:nF returns the second argument if and only if the first argument is not blank (a sequence of zero or more blank spaces).


enter image description here


Of course, for the particular application just two arguments would be needed:


NewDocumentCommandfoomm% operatornamemathbfbar(#1)% notblank#2cap#2% 

and fooa,bc, foobc or foob would do.




With xparse and NewDocumentCommand it is possible to define a macro with two optional and one mandatory argument, where the latter is the middle one:


documentclassarticle usepackageamsmath usepackagexparse NewDocumentCommandfoo o m o % textbar(% IfValueT#1#1,% #2)% IfValueT#3cap #3% begindocument $foo[a]b[c]$ $foob$ $foo[a]b$ $foob[c]$ enddocument 

But this definition can be problematic if the command is followed by a literal [ the is part of the equation. In that case there must be a space between the mandatory argument and the opening bracket:


$foob [x,y,z]$ 



The OP didn’t say what packages, if any, were used.


The OP’s code works for me with usepackagexifthen.


It doesn’t work with usepackageifthen, which doesn’t implement isempty.


With usepackageifthen, you can do


newcommandfoo[3] textbfbar( ifthenelseequal#1 #1, #2) ifthenelseequal#3 cap #3 

but the xifthen version is more efficient because isempty doesn’t expand its argument, but equal does.



JHedzWorlD






Define newcommand with multiple sorted mandatory arguments that can be empty – tex.stackexchange.com #JHedzWorlD

No comments:

Post a Comment