11

I'm currently in the process of writing my first document class file (a personalized resume class), and I want to get a better understanding of what exactly I'm doing. So, right now I'm setting up commands that allow for values to be assigned to variables (not sure if that's really the word I should be using), through a structure like this:

\newcommand{\institution}[1]{\def\@institution{#1}}
\newcommand{\datesattended}[1]{\def\@datesattended{#1}}
\newcommand{\degree}[1]{\def\@degree{#1}}

So, in the .tex file, the user can use the command \institution{University of Whatever} to save the string "University of Whatever" to \@institution, which is then later called within the class file by another command.

All of this works as I want it to, but now I'm hoping to create some conditional expressions to control the output. Like, I have a command \education that when called in the document will format an education section for a resume given the institution name, dates attended, degree info, etc. that the user had already entered. I want to be able to set it up in the class file to check if these \@variable variables have been defined, and then format the output differently based on which are defined and which are empty.

Primarily, I think a lot of my problem is that I don't actually understand what the \@variable definitions are or the scope of what I can do with them.

A full example of what I'm trying to achieve would be along the lines of (in LaTeX/pseudo):

\newcommand{\showeducation}{%
    \@institutionname -- \@degree
    if \@datesattended is defined:
        \newline \@datesattended
    clear \@institutionname, \@datesattended, \@degree
}

So, if \@datesattended were defined, the formatting would change to accommodate it. Otherwise, the command would just pass over it, printing the information that was given.

  • question's a bit vague to answer but note \def is just the primitive underlying \newcommand so there is no difference in the type of construct defined \degree and \@degree are both just control sequences referring to macros defined in your document, the @ is just a letter in this context, it does not denote a "variable". You could use \newcommand{\degree}[1]{\newcommand\@degree{#1}} or \def\degree#1{\def\@degree{#1}} – David Carlisle Apr 18 '15 at 18:31
  • The \@somename macros are 'considered' internal commands which are not to be applied by the 'ordinary' LaTeX user (thereby being kernel or somewhat critical commands controlling a lot of internal setups, which may be corrupted by an unexperienced user) – user31729 Apr 18 '15 at 18:36
  • Your are after \ifdefined\somecommand ... \else... \fi . It's a primitive – user31729 Apr 18 '15 at 18:40
  • For this sort of thing, you might find a key-value approach offers a lot more flexibility. Nesting conditions can quickly become a frustrating experience. – jon Apr 18 '15 at 20:27
11

There is nothing special about \@variable commands. They are just macros, for storing content rather than performing other operations. As such it's possible to test for being defined, by using \ifdefined, a (e-TeX) primitive.

\documentclass[11pt,a4paper]{article}


\makeatletter

\newcommand{\@institutionname}{Ministry of Silly Walks}
\newcommand{\@degree}{Minster of Silly Walks}

%\newcommand{\@datesattended}{1969}


\newcommand{\showeducation}{%
    \@institutionname\ -- \@degree
    \ifdefined\@datesattended 
        \newline \@datesattended  % Please use some 'better' setup here
        \else
     \let\@institutionname\relax
     \let\@datesattended\relax 
     \let\@degree\relax
     \fi
}

\makeatother


\begin{document}

\showeducation   % Date should not be printed

\makeatletter
\newcommand{\@datesattended}{1969}
\makeatother

\showeducation % Now it should be printed, but the rest is \relax`ed


\end{document}

Edit The same should be achievable using \ifdef from etoolbox package

  • Perfect! That is exactly what I wanted. Thank you! – Kevin Apr 18 '15 at 18:51
  • @Kevin: You're welcome ;-) – user31729 Apr 18 '15 at 19:04
  • @barbarabeeton: That's the original code by the OP, not mine.. It's not my intention to introduce whatever improvements, just to show how \ifdefined works. But thanks – user31729 Apr 18 '15 at 19:15
  • @barbarabeeton What improvements were you suggesting? I'm certainly open to constructive criticism regarding whatever things I've inevitably done wrong or poorly. – Kevin Apr 18 '15 at 19:32
  • @Kevin: She referred to the -- stuff. See my edited example, where I added a ` after \@institutionname` to provide the correct spacing – user31729 Apr 18 '15 at 19:33
8

Maybe better than \newcommand[1]... is usage of toks registers:

\newtoks\institution  \newtoks\datesattended  \newtoks\degree

If user says

\institution{Ministry of Silly Walks}

then you can use this value in your macros as:

\the\institution

If you need to test, if the value of the "variable" was already set, you can do:

\if\relax\the\degree\relax The degree isn't set.\else The degree is set.\fi

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.