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 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.

share|improve this question

3 Answers 3

up vote 10 down vote accepted

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
share|improve this answer
    
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

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
share|improve this answer
    
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} 
share|improve this answer

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.