Difference between revisions of "Commands with optional arguments"

From Wiki
Jump to navigation Jump to search
m (typo)
(Added examples.)
Line 8: Line 8:
 
\MyCommand[Hans]{\scshape}
 
\MyCommand[Hans]{\scshape}
 
</texcode>
 
</texcode>
 +
 +
<context>
 +
{\bf Hello World!}
 +
{\sc Hello Hans!}
 +
</context>
  
 
In ConTeXt, the optional argument processing is handled as a two-step process.  First, we write the command for the end-user as a wrapper command, which calls <cmd>dodoubleempty</cmd> (from [http://source.contextgarden.net/tex/context/base/syst-gen.tex syst-gen.tex]) to handle the arguments properly -- including the optional ones -- and then calls a "private" command that contains the internals of the macro.  Note that this function call does not explicitly refer to the arguments at all.
 
In ConTeXt, the optional argument processing is handled as a two-step process.  First, we write the command for the end-user as a wrapper command, which calls <cmd>dodoubleempty</cmd> (from [http://source.contextgarden.net/tex/context/base/syst-gen.tex syst-gen.tex]) to handle the arguments properly -- including the optional ones -- and then calls a "private" command that contains the internals of the macro.  Note that this function call does not explicitly refer to the arguments at all.
Line 28: Line 33:
  
 
Note that this makes both arguments optional -- something that is much more difficult to do in LaTeX ([http://www.tex.ac.uk/cgi-bin/texfaq2html?label=twooptarg but can be done]).  This also means that we should reverse the order of arguments, since if the user specifies only one argument it will be treated as the first argument.
 
Note that this makes both arguments optional -- something that is much more difficult to do in LaTeX ([http://www.tex.ac.uk/cgi-bin/texfaq2html?label=twooptarg but can be done]).  This also means that we should reverse the order of arguments, since if the user specifies only one argument it will be treated as the first argument.
 +
 +
(Also, note that <tt>\MyCommand</tt> without the second argument ends up gobbling the following spaces, so we need to explicitly include one with "<tt>\ </tt>".)
 +
 +
<texcode>
 +
\MyCommand[\bf]\ %
 +
\MyCommand[\sc][Hans]
 +
</texcode>
 +
 +
<context>
 +
\def\MyCommand{\dodoubleempty\doMyCommand}
 +
\def\doMyCommand[#1][#2]{#1Hello
 +
    \ifsecondargument
 +
      #2%
 +
    \else
 +
      World%
 +
    \fi
 +
    !}
 +
\MyCommand[\bf]\ %
 +
\MyCommand[\sc][Hans]
 +
</context>
  
 
If you ''don't'' want any optional arguments, but still want your arguments enclosed in <tt>[]</tt> with appropriate handling for spaces (or line breaks) between the square brackets, use <cmd>dodoublearguments</cmd> instead of <cmd>dodoubleempty</cmd>.  There are of course versions for other numbers of arguments, found by replacing <tt>double</tt> with <tt>single</tt> through <tt>seventuple</tt>; see [http://source.contextgarden.net/tex/context/base/syst-gen.tex syst-gen.tex] for the exact names.
 
If you ''don't'' want any optional arguments, but still want your arguments enclosed in <tt>[]</tt> with appropriate handling for spaces (or line breaks) between the square brackets, use <cmd>dodoublearguments</cmd> instead of <cmd>dodoubleempty</cmd>.  There are of course versions for other numbers of arguments, found by replacing <tt>double</tt> with <tt>single</tt> through <tt>seventuple</tt>; see [http://source.contextgarden.net/tex/context/base/syst-gen.tex syst-gen.tex] for the exact names.

Revision as of 01:43, 4 August 2005

< Inside ConTeXt | Commands with KeyVal arguments >

In LaTeX you define a new command with an optional argument with "newcommand":

\newcommand{\MyCommand}[2][World]{{#2Hello #1!}}
\MyCommand{\bfseries}
\MyCommand[Hans]{\scshape}

In ConTeXt, the optional argument processing is handled as a two-step process. First, we write the command for the end-user as a wrapper command, which calls \dodoubleempty (from syst-gen.tex) to handle the arguments properly -- including the optional ones -- and then calls a "private" command that contains the internals of the macro. Note that this function call does not explicitly refer to the arguments at all.

\def\MyCommand{\dodoubleempty\doMyCommand}

We then create the "private" macro (\doMacroName is the traditional ConTeXt name for these), with all the arguments defined as nonoptional. Default values for the arguments need to be handled somewhat more explicitly than with LaTeX; macros such as \ifsecondargument are used to determine whether the given argument was specified, as follows:

 \def\doMyCommand[#1][#2]{#1Hello
    \ifsecondargument
       #2%
    \else
       World%
    \fi
    !}

Note that this makes both arguments optional -- something that is much more difficult to do in LaTeX (but can be done). This also means that we should reverse the order of arguments, since if the user specifies only one argument it will be treated as the first argument.

(Also, note that \MyCommand without the second argument ends up gobbling the following spaces, so we need to explicitly include one with "\ ".)

\MyCommand[\bf]\ %
\MyCommand[\sc][Hans]

If you don't want any optional arguments, but still want your arguments enclosed in [] with appropriate handling for spaces (or line breaks) between the square brackets, use \dodoublearguments instead of \dodoubleempty. There are of course versions for other numbers of arguments, found by replacing double with single through seventuple; see syst-gen.tex for the exact names.


To define \mycommand[.1.][.2.]{.3.}, i.e., with curly braces around a non-optional third argument, you just define

\def\mycommand{\dodoubleempty\doMycommand}
\def\doMycommand[#1][#2]#3{whatever}

Can someone test to see if \dosingleempty and \dodoubleargument can be chained, to get two square-bracketed arguments only one of which is optional? --Brooks