Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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?

share|improve this question
2  
This is not how \title and \author work. You never use them without the brackets. Commands like \maketitle use \makeatletter\@title\makeatother etc. internally. –  qubyte Dec 10 '11 at 17:50
    
To push this point home, there is an error in your question. The passage "when they're used without parameter, they should print the corresponding variable" is incorrect. –  qubyte Dec 10 '11 at 17:59
add comment

3 Answers 3

up vote 6 down vote accepted

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.

share|improve this answer
add comment

With xparse:

\usepackage{xparse}
\makeatletter

\def\@tutor{\ClassError{myclass}{Undefined \string\tutor}
  {You need to say \string\tutor{<NAME>} before using \protect\tutor by itself}}

\NewDocumentCommand{\tutor}{g}{\IfNoValueTF{#1}{\@tutor}{\gdef\@tutor{#1}}}

\makeatother

I've also added an error message in case \tutor is used by itself before having defined its value (such definitions are used in class files, usually).

However, the usual strategy is to avoid having the user print explicitly the tutor's name; so only \tutor{<NAME>} should be at the user level and the class can use \@tutor to print the title page.

share|improve this answer
add comment

You can do it like this:

\makeatletter
\newcommand{\tutor}[1]{\newcommand{\@tutor}{#1}}
\makeatother

and then use it like this

\makeatletter\@tutor\makeatother

Which is not what you want. However, if you will be using the content a lot, then it is perhaps more usual to encapsulate the above in a newcommand

\makeatletter\newcommand{\thetutor}[0]{\@tutor}\makeatother

You can now use the content of \@tutor with \thetutor.

In short, it's simpler to just make two commands with a predictable difference between the names (in this case the).

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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