[Tex/LaTex] Own document variables with and without arguments

conditionalsmacrosoptional arguments

I use the following to introduce new document variables to my document. They should behave like \author or \title. So when they're used without parameter, they should print the corresponding variable. If they're called with parameter, they should set the corresponding variable to this value.

\newcommand*{\tutor}[1]{\gdef\@tutor{#1}}

Works ok, but I have to use

\tutor{new defined name}

to define the value and

\@tutor

to get the name printed instead of just using

\tutor

What's the simplest way to introduce \tutor as desired?

Best Answer

This usage is very uncommon with LaTeX (it's not the way \author etc. works), but it is possible to make the macro look ahead with \@ifnextchar to see if the next character is a brace (which needs to be written as \bgroup because you need a matching pair of braces in the macro).

\newcommand*\tutor{%
   \@ifnextchar\bgroup
      {\gdef\@tutor}%
      {\@tutor}%
}

This will expand to \gdef\@tutor if there is an argument (which will then be taken by it) or to \@tutor if not.


There is also the xparse package which allows to define macros with optional brace arguments and a way to test if the argument was there or not. See the package manual for the details. For this case it is IMHO a little overkill.


You could also define \tutor in the form you have in your post and redefine it at the begin of the document to be equal to \@tutor.

\newcommand*{\tutor}[1]{\gdef\@tutor{#1}}
% or
% \newcommand*{\tutor}{\gdef\@tutor}

\AtBeginDocument{\let\tutor\@tutor}

Then you can use \tutor{<argument>} only in the preamble and \tutor only in the document body.


Macros with an @ in the name need to be wrapped in \makeatletter ... \makeatother, except in package or class files, which do this automatically.

Related Question