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 want to define macros within a personal package for a few variables (I don't even know if I should be calling them "variables") that may or may not be defined by the user. My approach so far is this:

\newcommand\@varname{}
\newcommand\varname[1]{\renewcommand\@varname{#1}}
\newcommand\printvarname{%
  \ifthenelse{\equal{\@varname}{}}{}{\@varname}}

The first command defines an empty \@<varname>; the second command provides a user level \<varname> that set \@<varname> to the value determined by the user; and the third command checks if \@<varname> is been defined by the user, and if so, prints it.

Since I have a lot of those "variables" to set, can I have a \NewResettableCommand{<varname>} (whose argument probably need to be set without the \) that does all of the above?

BTW: I used \newcommand (instead of \providecommand) because I'm running tests in a .tex file before create the packages.

share|improve this question

2 Answers 2

up vote 4 down vote accepted

This is it:

\newcommand{\NewResettableCommand}[1]{%
  \expandafter\newcommand\csname @#1\endcsname{}
  \expandafter\newcommand\csname #1\endcsname[1]{%
    \expandafter\renewcommand\csname @#1\endcsname{##1}}
  \expandafter\newcommand\csname print#1\endcsname{%
    \ifthenelse{\equal{\csname @#1\endcsname}{}}{}{\csname @#1\endcsname}}
}

\NewResettableCommand{varname}

Just do all the same operations with #1 in place of the name.

However, it's unclear why the "emptyness" test: if the contents is empty, expanding \@varname will do nothing the same.

However, using \renewcommand for redefining \@varname is just too much: you want to redefine it, so you don't care if it's already defined or not:

\makeatletter % not when the code is in a package
\newcommand{\NewResettableCommand}[1]{%
  \expandafter\newcommand\csname #1\endcsname[1]{\@namedef{@#1}{##1}}
  \@namedef{@#1}{}
  \expandafter\newcommand\csname print#1\endcsname{%
    \ifthenelse{\equal{\csname @#1\endcsname}{}}{}{\csname @#1\endcsname}}
}
\makeatother % not when the code is in a package

The compulsory LaTeX3 version:

\RequirePackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\NewResettableCommand}{ m }
  {
   \tl_new:c { l_nrc_#1_tl }
   \cs_new:cpn { #1 } ##1 { \tl_set:cn { l_nrc_#1_tl } { ##1 } }
   \cs_new:cpn { print #1 }
     {
      \tl_if_empty:cF { l_nrc_#1_tl } { \tl_use:c { l_nrc_#1_tl } }
     }
  }
\ExplSyntaxOff

Note that here nrc is just an arbitrary prefix that you can change at will (maybe uniformizing it to the prefix you're using for your package).

share|improve this answer

You can use the benefits of the package etoolbox to avoid handling with expandafter:

\documentclass{article}
\usepackage{etoolbox}
\newrobustcmd*\NewResettableCommand[1]{%
 \ifcsundef{#1}
  {%
    \csdef{#1}##1{\csdef{@#1}{##1}}%
    \csdef{print#1}{%
       \ifcsempty{@#1}%
         {\typeout{****#1 is empty****}}%
         {\csuse{@#1}}%
     }%
  }   
  {\typeout{****#1 is defined****}}%
}
\makeatother

\begin{document}
\NewResettableCommand{varname}

\varname{henrique}\printvarname

\varname{}\printvarname
\end{document}
share|improve this answer
    
You make expandafter sound like a disease;) –  Yiannis Lazarides Mar 9 '12 at 18:44
    
@YiannisLazarides: It is ;-) This based on expl3 which is more comfortable ;-) –  Marco Daniel Mar 9 '12 at 18:46
    
Expandafters and futurelets Gave me trouble for a very long time:) –  Yiannis Lazarides Mar 9 '12 at 18:49
    
@YiannisLazarides: just now futurlet is mysterious for me ;-) –  Marco Daniel Mar 9 '12 at 18:52

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.