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.

Based on this solution related to defining a macro I came up with this macro to help me define a macro that I can use either in or outside of math mode.

The example as is functions as I want. However, this solution requires me to NOT put $$ around the second parameter to to the \DefineNamedFunction macro. I would like to be able to include the $$, or not include it.

One solution is to modify \DefineNamedFunction to strip out the $$ if it is included in the macro call using the xstring pacakge, but this to me feels like a hack, and am thinking that there is probably a cleaner TeX way to do this.

So to summarize: How do I change \DefineNamedFunction such that I can use both the commented and uncommented calls to this macro, and still be able to use the definition inside and outside of math mode?

\documentclass{article}

\usepackage{amsmath}
\usepackage{xcolor}

\newcommand{\DefineNamedFunction}[2]{% {FunctionName}{FunctionExpression}
    \expandafter\providecommand\expandafter{\csname#1\endcsname}{\textcolor{red}{\ensuremath{#2}}}%
}

\begin{document}

\DefineNamedFunction{FunctionF}{y = 2 \sin x}
%\DefineNamedFunction{FunctionF}{$y = 2 \sin x$}

I can use FunctionF inside math mode as $\FunctionF$,
but can also use this outside of math mode as \FunctionF.

\end{document}
share|improve this question
add comment

2 Answers

up vote 3 down vote accepted

Probably

\ensuremath{\textcolor{red}{#2}}

is what you need, since \textcolor can be used in text and in math. The complete definition is

\newcommand{\DefineNamedFunction}[2]{% {FunctionName}{FunctionExpression}
    \expandafter\providecommand\csname#1\endcsname
      {\ensuremath{\textcolor{red}{#2}}}%
}
...
\DefineNamedFunction{FunctionF}{y=2\sin x}
$\FunctionF$ and \FunctionF

Sample

I've also deleted the braces that require another \expandafter, but that's not the problem.

Of course, you can't call

\DefinedNamedFunction{FunctionFF}{$y=x$}

and I wouldn't know why you'd want it. But in any case there's a simple solution

\newcommand{\DefineNamedFunction}[2]{%
  \expandafter\providecommand\csname#1\endcsname
    {\ensuremath{\begingroup\color{red}\DNFnorm#2\endgroup}}}
\makeatletter
\def\DNFnorm{\@ifnextchar$\DNFnormi{}}
\def\DNFnormi$#1${#1}
\makeatother

The input is "normalized" by removing the $ tokens before and after, if present.

With \begingroup\color{red}...\endgroup the spaces in the subformula participate to the stretching and shrinking of the spaces in the line.

share|improve this answer
    
That does not seem to behave any differently. Yes, in the MWE I should have switched it to \newcommand, but I need \providecommand in my real usage. –  Peter Grill Jun 6 '11 at 18:22
    
@Peter: really? To me it does exactly what you want. I'll edit the answer with the complete definition. –  egreg Jun 6 '11 at 19:57
    
Only reason I would want to be able to call \DefinedNamedFunction{FunctionFF}{$y=x$} (with the dollar signs) as it is more natural to do so. I didn't want to have to remember that when I use this macro I do not put the $$, but for all the other macros where I have math, I do put the $$. –  Peter Grill Jun 6 '11 at 20:16
    
This solution using DNFnorm looks simpler. –  Peter Grill Jun 6 '11 at 20:45
    
@Peter: it's just a command defined for the purpose. It checks whether #2 starts with $; in this case it is substituted by \DNFnormi that throws away the two $, otherwise it does nothing. –  egreg Jun 6 '11 at 20:51
show 1 more comment
\documentclass{article}
\usepackage{amsmath}
\usepackage{xcolor}
\makeatletter
\def\DefineNamedFunction#1#2{\expandafter\DefineNamedFunction@i#1\@nil#2\@nil}
\def\DefineNamedFunction@i#1\@nil{%
  \@ifnextchar${\DefineNamedFunction@ii{#1}}{\DefineNamedFunction@iii{#1}}}
\def\DefineNamedFunction@ii#1$#2$\@nil{%
  \@namedef{#1}{\ifmmode\textcolor{red}{#2}\else\textcolor{red}{$#2$}\fi}}
\def\DefineNamedFunction@iii#1#2\@nil{%
  \@namedef{#1}{\ifmmode\textcolor{red}{#2}\else\textcolor{red}{$#2$}\fi}}
\makeatother

\DefineNamedFunction{FunctionF}{y = 2 \sin x}
\DefineNamedFunction{FunctionFF}{$y = 2 \sin x$}
\begin{document}    
I can use \FunctionF\ inside math mode as $\FunctionF$,
but can also use this outside of math mode as 
$\FunctionFF$ and \FunctionFF.

\end{document}
share|improve this answer
    
This works great. Thanks. So, is this basically doing the job of \ensuremath manually? –  Peter Grill Jun 6 '11 at 18:27
    
more or less ... the problem is \textcolor when it is used in math mode with a math argument –  Herbert Jun 6 '11 at 18:30
    
@Herbert: apart from making the + an ordinary atom, $\textcolor{blue}{a}\textcolor{red}{+}\textcolor{green}{b}$ works perfectly. –  egreg Jun 6 '11 at 20:08
    
@egreg: I was talking about $\textcolor{blue}{$a$}$ ... –  Herbert Jun 7 '11 at 4:25
    
@Herbert: I see; \textcolor is smart enough to know when it's called in math mode: maybe a pair \textcolor and \mathcolor would have been better. –  egreg Jun 7 '11 at 8:16
show 3 more comments

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.