2

Edit: About bounty I am happy with the question below and this bounty is for that question. I don't think I can take a better

I searched a little bit about the usage of optional arguments in LaTeX but some things are not yet very clear for me.

When

My question is not specific for commands or for packages but for both.

Sometimes we need to specify one or more optional arguments for a package or for a command. We can find commands like:

\Foo[OptArg1,OptArg2]{Arg1}{Arg2}

and like:

\Foo[OptArg1][OptArg2]{Arg1}{Arg2}

For the first I see one family with two optional arguments separated with comma. For the second I have two families with one optional argument for each one.

I suppose something is different in these two ways, but haven't exactly understand when my command has to use the first and when has to use the second way.

For example let's say we need a command that will use our first optional argument to split the first non-optional argument in parts. Then I prefer the second way because in the first my comma as a separator will not be understood (it is already a separator). But I still could use a command like:

\Foo[separator={,},OptArg2]{Arg1}{Arg2}

to do the same thing.

Of course if I would like to separate the optional arguments of second family my way with \Foo[separator={//}][OptArg2//OptArg3] would be the only (or at least a better) choice because I have tt define the separator before reading the second family arguments.

How

Also, sometimes the command has to behave different if two families are given and deferent if one is given. For example in my above example if the first argument is not given, comma will be used to separate the second families optional arguments. But if is given, then it will be used as a separator and the command will behave different on reading the arguments.

In such situations I think \def is a more general option for writing the command than newcommand because we have more choices while reading the arguments. (\newcommand will break the second arguments before read the first or something like that. Consider also a ']' including in second families arguments...)

My questions are:

  1. When (standard LaTeX) do I have to use the first way and when the second?
  2. Is \def the only only or the better way to define our commands in general situations like in situations we don't already know the amount of arguments or in situations like the above with the separator or the ']' I already described?

PS: In the second question consider that I want my command to allow me by reading the next character handle much situations. (For example I want to read characters after the command one by one and stop only if i have found two ordinary arguments or the command \stop etc. Not asking for code of this, just asking if \newcommand can do it -and it is a good choice- or if \def is the only choice)

  • Let us continue this discussion in chat. – koleygr Jul 6 '17 at 3:33
  • Didn't knew what bounty is for... I thought I could just show my respect to the nice answer... I am fine with the one I have. – koleygr Aug 27 '17 at 2:42
  • You did not make any mistake with the bounty. Rewarding a current question is one of the reason of starting them. – CarLaTeX Aug 27 '17 at 3:03
  • @CarLaTeX and why I have to wait 24hours then? I already choose there to reward a current question, but cannot and didn't wanted to bring my question in first page... (No problem but why 24h?) – koleygr Aug 27 '17 at 3:05
  • It's a rule, to give someone else time to add another answer. When you start a bounty your question is automatically put on the first page. But don't worry, all this is ordinary behavior :) – CarLaTeX Aug 27 '17 at 3:11
4
+50

Your question mixes two separate things. LaTex2e has optional arguments in [] and mandatory arguments in {} so

\Foo[OptArg1,OptArg2]{Arg1}{Arg2}

has one optional argument and two mandatory arguments.

\Foo[OptArg1][OptArg2]{Arg1}{Arg2}

has two optional arguments and two mandatory arguments.

The second issue is the comma separated list, this may not be part of the syntax at all, just comma being treated as a character so for example after

 \newcommand\Foo[3][]{(#1)-(#2)(#3)}

then #1 would be OptArg1,OptArg2, #2 would be Arg1 and #3 would be Arg2 and the result would be to typeset

(OptArg1,OptArg2)-(Arg1)-(Arg2)

with the commas playing no special rule.

Of course a command can do what it likes with the arguments and this may include iterating over the commas. There are facilities in the latex format for that (\@for) or several packages offer macros to parse comma separated lists. This however is independent of the optional argument detection. In the (legal) syntax example

 \usepackage[foo,bar]{array,longtable}[2015/01/01 packages by you, me and someone]

there are two optional arguments and one mandatory argument, the first optional argument and the mandatory are later, as part of the processing of \usepackage, split up on commas. The second optional argument is not split on commas but is in fact split on / and space to extract the date from the start of the argument.

As for definition, if you only have one optional argument at the start, you can use \newcommand If you have two or more you can also use \newcommand but need to define the macro in stages, but it is probably easier to use xparse or similar packages to allow a simpler specification and automatically deal with defining the internal macros needed. It is however best not to have too many consecutive optional arguments as if you have

 \Foo[OptArg1][OptArg2]{Arg1}{Arg2}

then OptArg1 isn't really optional if you need to specify OptArg2. A syntax such as

\Foo[opt1=a,opt2=b]{Arg1}

allows each option to be independently omitted. But again such key=value parsing can be applied to any string of tokens, whether it is a mandatory or optional argument. For example graphicx uses the keyval package to parse the , and = in its optional argument

\includegraphics[width=10pt,height=8pt]{image}

and hyperref uses the same parsing to parse the same syntax in a mandatory argument

\hypersetup{colorlinks=false,plainpages=true}

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.