32

I would like to define a new command which should determine (within a tikz plot) whether its argument is in math mode or not. If so, it should wrap the argument with $ $. I found \ifmode to do this, but it's not working. Here is my minimal example:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[american,ngerman]{babel}
\usepackage{tikz}

\newcommand*{\yellowemph}[1]{%
  \tikz[baseline=(text.base)]\node(text)[rectangle, fill=yellow, rounded
corners, inner sep=0.3mm]{\ifmmode $#1$\else #1\fi};%
}

\begin{document}
\yellowemph{word}% works
\yellowemph{$\frac{1}{2}$}% works
$\yellowemph{\frac{1}{2}}$% does not work
\end{document}

I am aware of \ensuremath, however, this always switches to math mode. I would like to keep text as is if not in math mode (see \yellowemph{word} for example).

SOLUTION

As posted below, this is a solution:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[american,ngerman]{babel}
\usepackage{tikz}

\newif\ifstartedinmathmode
\newcommand*{\yellowemph}[1]{%
  \relax\ifmmode\startedinmathmodetrue\else\startedinmathmodefalse\fi
  \tikz[baseline=(text.base)]\node(text)[rectangle, fill=yellow, rounded
corners, inner sep=0.3mm]
  {\ifstartedinmathmode$#1$\else#1\fi};%
}

\begin{document}
\yellowemph{word}
$\int_0^\infty f(\yellowemph{x})\,dx$
\yellowemph{$\displaystyle\frac{1}{2}$}
\end{document}
7
  • 3
    You could use \ensuremath{}
    – matth
    Commented Mar 2, 2012 at 11:15
  • 1
    Do you know about the \ensuremath command ? Commented Mar 2, 2012 at 11:16
  • 1
    There's always \ensuremath :D
    – qubyte
    Commented Mar 2, 2012 at 11:28
  • 1
    But \ensuremath always uses math mode right? that's not what I want for text such as in the first line, for example. Commented Mar 2, 2012 at 11:42
  • Incidentally, there's not just one mathmode. See tex.stackexchange.com/q/1223/86 for where I wanted a similar functionality. Commented Mar 2, 2012 at 12:13

3 Answers 3

27

The argument to a \node command is always processed in text mode, independently of whether the tikzpicture has been started in text or in math mode. So the best way out is to put the $ symbols in the argument.

\newcommand*{\yellowemph}[1]{%
  \tikz[baseline=(text.base)]\node(text)[rectangle, fill=yellow, rounded
corners, inner sep=0.3mm]{#1};%
}

\begin{document}
\yellowemph{word}
\yellowemph{$\frac{1}{2}$}

You might try a more complicated approach with a conditional:

\newif\ifstartedinmathmode
\newcommand*{\yellowemph}[1]{%
  \relax\ifmmode\startedinmathmodetrue\else\startedinmathmodefalse\fi
  \tikz[baseline=(text.base)]\node(text)[rectangle, fill=yellow, rounded
corners, inner sep=0.3mm]
  {\ifstartedinmathmode$#1$\else#1\fi};%
}
3
  • Thanks for your help. I am aware of this. I was just wondering if it is possible to let LaTeX include the $ $ if necessary (so if the argument #1 is something in math mode) Commented Mar 2, 2012 at 12:02
  • @MariusHofert That's what the second of egreg's solutions does (I was about to post exactly the same code ..., only I forgot the \relax at the start). Incidentally, I've given you a solution to the highlighter question which avoids this problem. Commented Mar 2, 2012 at 12:11
  • 1
    @egreg This will of course will still give an error if you use \frac in text leaving us with the first simpler solution;)
    – yannisl
    Commented Mar 2, 2012 at 12:37
10

You need to use \ensuremath or fix the error in your conditional:

\relax\ifmmode#1\else $#1$\fi
8
  • You might want to put a \relax before \ifmmode to ensure that it isn't expanded prematurely in some cases, like at the beginning of a tabular cell. Commented Mar 2, 2012 at 11:46
  • Thanks for helping, Yiannis. This does not work as expected. I want $ $ if I am in math mode, and just the argument otherwise. Your solution does it the other way around. The problem is that if I put the $ $ in the first part of the conditional, it does not work anymore. Also note that \ensuremath always switches to math mode, however, I would like to not do this for words (see the first line of my example after \begin{document}. Commented Mar 2, 2012 at 11:48
  • @MariusHofert Hm.. I see problem is you want to have more than two conditions. If you are sending text and you are in mathmode, you need to include it in a \text{#1}, problem will fail if you do send a \frac. Not too sure if it is feasible. Suggest define two commands \hltext` and \hlmath.
    – yannisl
    Commented Mar 2, 2012 at 12:12
  • @MartinScharrer --Thanks. Normally I would do this type of macro in a \DeclareRobustCommand omitting the relax. But your sugestion is good.
    – yannisl
    Commented Mar 2, 2012 at 12:13
  • @Marius: what you describe does not make sense; you are trying to get into math mode when you are in math mode (if in math mode, start math mode. See what I mean?), which ends up trying to start a display math mode as a result. ($$)
    – morbusg
    Commented Mar 2, 2012 at 12:15
1

Try this:

\newcommand*{\textyellowemph}[1]{\tikz[baseline=(text.base)]\node(text)[rectangle, fill=yellow, rounded, inner sep=0.3mm]{#1};}
\newcommand*{\mathyellowemph}[1]{\tikz[baseline=(text.base)]\node(text)[rectangle, fill=yellow, rounded, inner sep=0.3mm]{\ensuremath{#1}};}
\newcommand*{\yellowemph}[1]{\ifmmode\mathyellowemph{#1}\else\textyellowemph{#1}\fi}
1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .