# How to make new commands with alternative command definitions? i.e. NOT alternative arguments

I want something like this:

\newcommand{\MyCommand}{default definition}{definition}


The context for wanting this is as follows: I am making automated reports for different customers, and am defining all sorts of customer-specific text variables when making the report. So these text variables should be defined in my latex template files, for instance:

\newcommand{\CustomerName}{LackingCustomerName}{}%


should be compiled to " ...LackingCustmerName...." in the report

while

\newcommand{\CustomerName}{LackingCustomerName}{Coca Cole Inc.}%


should be compiled to " ...Coca Cola Inc...." in the report.

By including a default definitions on the form "Lacking...Name" it can easily be seen in the compiled text which of the text variables that has yet to be defined.

-

Define a generic interface

\newcommand{\newcustomer}[2]{%
\if\relax\detokenize{#2}\relax
% arg #2 is empty
\newcommand{#1}{No value for \texttt{\string#1} has been defined}%
\else
\newcommand{#1}{#2}%
\fi}


Then you can do

\newcustomer{\CustomerNameOne}{}
\newcustomer{\CustomerNameTwo}{ACME Inc.}


Change the "No value..." to what you prefer.

In order to disregard spaces in \newcustomer{\Xyz}{ } you have to "zap spaces". The easiest way, since your argument will only produce text is to measure the space it occupies:

\newcommand{\newcustomer}[2]{%
\sbox0{\ignorespaces#2\unskip}%
\ifdim\wd0=0pt
% arg #2 is empty or only spaces
\newcommand{#1}{No value for \texttt{\string#1} has been defined}%
\else
\newcommand{#1}{#2}%
\fi}


For getting only CustomerNameOne (without the backslash), you can say

\newcommand{\newcustomer}[2]{%
\sbox0{\ignorespaces#2\unskip}%
\ifdim\wd0=0pt
% arg #2 is empty or only spaces
\newcommand{#1}{No value for \getname{#1} has been defined}%
\else
\newcommand{#1}{#2}%
\fi}
\makeatletter
\newcommand\getname[1]{\expandafter\@gobble\string#1}
\makeatother

-
Thanks a lOt! That works fine. How can I make the code dissregard any open space in the definition of \CustomerNameOne? That is, if I by a misstake write: \newcustomer{\CustomerNameOne}{ }, then the open space in the last pair of curly braces will be used as the name of the customer. How to prevent that? –  Espen Donali May 18 '12 at 12:54
Another question regarding your code "..{\string#1}...", where #1 is "\CustomerNameOne". Can I somehow change this code in such a way that only "CustomerNameOne" will be used, i.e. only element 2...n of the string is used? How do I do that? Thanks in advance ! –  Espen Donali May 18 '12 at 14:07
Thanks again :) However, I get an errormessage when using your code for removing empty spaces: "...! Incomplete \ifdim; all text was ignored after line 18. <inserted text> \fi l.188 \input{../UserVariables.tex} ?" Is there any code lacking in your solution? –  Espen Donali May 18 '12 at 17:34
@EspenDonali Are you using the babel module for Turkish? That should be the reason. But the problem doesn't show if the code is before \begin{document} as such code always should. –  egreg May 18 '12 at 17:46
Hi egreg. Thanks som much for your help! Your second solution for removing "\" works fine ! However, when including code to delete open spaces I still get the afore mentioned error message. I am using Babel only for englis. And I have put the code in before the \begin{document} By the way, do you have a good learning source (book or websidt) for better understanding the code you made for me? I mean, where can I read about the functions \sbox, \ignorespace, \unskip,\relax, \detokenize, \expandafter, \string and how they can be combined? –  Espen Donali May 19 '12 at 15:47
show 1 more comment

You can define a value as default and then redefine it if required:

\newcommand{\CustomerName}{LackingCustomerName}

% ...
\renewcommand{\CustomerName}{Coca Cole Inc.}


However, the normal way this is done for variables like this (compare \title, \author etc.) is to use internal macros and let \CustomerName define it:

\newcommand{\CustomerName}[1]{\def\@CustomerName{#1}}
% Or maybe:
% \newcommand{\CustomerName}[1]{\def\theCustomerName{#1}}
\CustomerName{LackingCustomerName}%  default value

% ...
\CustomerName{Coca Cola Inc}


Then to typeset the customer name use:

Customer: \@CustomerName     % if only used internally in your package/class
% or
Customer: \theCustomerName   % if also used directly in the document

-
Thanks a lot, but I didn't succeed in making your code work for some reason. Should all the code you have written in the second block of code be together in the preamble?? Further, I want the default-value to be part of the definition of the \CustomerName code. Can that be accomplished? –  Espen Donali May 18 '12 at 12:14
@EspenDonali: Any code containing macros with an @ need to be either in a package or class file or be placed inside \makeatletter ... \makeatother. –  Martin Scharrer May 18 '12 at 15:16

For just the problem you described, you could leave you normal definitions like they are, but overwrite them later with \renewcommand. You would have e.g. a

\newcommand{\CustomerName}{LackingCustomerName}


in your preamble (maybe in a different file). In your report you could then 'overwrite' the variable using e.g.

\renewcommand{\CustomerName}{Coca Cola Inc.}


I would do it in a different way though: I would just not define a 'default' \CustomerName... This way the compiler would scream at you for forgetting to set a variable.

What you could also do is creating all commands you need, but setting them to commands like:

\PackageError{Customer Template}{forgot to redefine \CustomerName}{Please overwrite \\CustomerName by using \renewcommand}
\PackageWarning{Customer Template}{forgot to redefine \\CustomerName, boilerplate still in the file}
\PackageInfo{Customer Template}{forgot to redefine \\CustomerName, boilerplate still in the file}


This might greately reduce the risk of forgetting to redefine on of your commands and end up with a report that is sent to someone called 'LackingCustomerName'

MWE:

\documentclass[11pt]{article}

\newcommand{\CustomerName}{\PackageError{mypack}{blub}{blub}}
\renewcommand{\CustomerName}{Coca Cola Inc.}

\begin{document}
\CustomerName
\end{document}

-