1

In this thread, @HenriMenke showed how to put a circle around a symbol. It's easy to modify his code to color the circle, see below, but I don't understand how to make the color an optional argument, i.e., with default black, and a color as an additional optional argument. This would be easy normally, but in this code, for some reason I don't understand the number of arguments passed to \mathcircled is different from the number passed to \@mathcircled

\usepackage{mathtools}
\usepackage{tikz}
\makeatletter
\newcommand\mathcircled[1]{%
  \mathpalette\@mathcircled{#1}%
}
\newcommand\@mathcircled[2]{%
  \tikz[baseline=(math.base)] \node[draw,color=red,circle,inner sep=1pt] (math) {$\m@th#1#2$};%
}
\makeatother

Another question is how to change the shape of the surrounding object. You'd think you could replace circle as the third argumnent of \node with square or oval or ellipse but none of these options work. I've also tried things like shape=ellipse but that doesn't work either. Thanks for any advice.

1
  • You can exchange circle with ellipse, but you have to \usetikzlibrary{shapes} in your preamble.
    – Skillmon
    Oct 18, 2018 at 19:18

1 Answer 1

4

You could wrap the two arguments in one:

\documentclass[]{article}

\usepackage{mathtools}
\usepackage{tikz}
\makeatletter
\newcommand\mathcircled[2][red]{%
  \mathpalette\@mathcircled{{#1}{#2}}%
}
\newcommand\@mathcircled[2]{%
  \@mathcircled@b{#1}#2%
}
\newcommand\@mathcircled@b[3]{%
  \tikz[baseline=(math.base)] \node[draw,color=#2,circle,inner sep=1pt] (math) {$\m@th#1#3$};%
}
\makeatother

\begin{document}
$\mathcircled[blue]{55}$
\end{document}

Without a second helper macro, you could as well put \@mathcircled and {#1} in one argument of \mathpalette:

\documentclass[]{article}

\usepackage{mathtools}
\usepackage{tikz}
\makeatletter
\newcommand\mathcircled[2][red]{%
  \mathpalette{\@mathcircled{#1}}{#2}%
}
\newcommand\@mathcircled[3]{%
  \tikz[baseline=(math.base)] \node[draw,color=#1,circle,inner sep=1pt] (math) {$\m@th#2#3$};%
}
\makeatother

\begin{document}
$\mathcircled[blue]{55}$
\end{document}

Both code blocks result in:

enter image description here

Edit: As requested a version taking more arguments (3 to be precise).

An approach taking two optional arguments in a row. If the first argument is empty it is set to red (which makes red the default, as it is empty by default). The second optional argument specifies the shape, defaulting to circle. I tried to explain the code a bit in comments:

\documentclass[border=2mm]{standalone}

\usepackage{mathtools}
\usepackage{tikz}
\usetikzlibrary{shapes}
\makeatletter
\newcommand\mathcircled[1][]
  {%
    % keeping stuff local
    \begingroup
    % check whether #1 is empty
    \if\relax\detokenize{#1}\relax
      % save red as the colour for later
      \def\mathcircled@color{red}%
    \else
      % save #1 as the colour for later
      \def\mathcircled@color{#1}%
    \fi
    % grab the next optional argument and the mandatory one
    \mathcircled@b
  }
\newcommand\mathcircled@b[2][circle]
  {%
    % expand the colour and read the expanded colour and the other two arguments
    \expandafter\mathcircled@c\expandafter{\mathcircled@color}{#1}{#2}%
  }
\newcommand\mathcircled@c[3]
  {%
    % putting the two optional arguments with \mathcircled@d into the first
    % argument of \mathpalette
    \mathpalette{\mathcircled@d{#1}{#2}}{#3}
    \endgroup
  }
\newcommand\mathcircled@d[4]
  {%
    \tikz[baseline=(math.base)]
      \node[draw,color=#1,#2,inner sep=1pt] (math) {$\m@th#3#4$};%
  }
\makeatother

\begin{document}
$\mathcircled[blue]{55}$
$\mathcircled[][ellipse]{69}$
$\mathcircled{5}$
\end{document}

Results:

enter image description here

A version of the edit using xparse:

\documentclass[border=2mm]{standalone}

\usepackage{mathtools}
\usepackage{tikz}
\usetikzlibrary{shapes}
\usepackage{xparse}
\makeatletter
% this will be used to parse the first optional argument of \mathcircled to
% set the default.
\newcommand \EmptyArgParse [2]
  {%
    \if\relax\detokenize{#2}\relax
      \def\ProcessedArgument{#1}%
    \else
      \def\ProcessedArgument{#2}%
    \fi
  }
\NewDocumentCommand \mathcircled { >{\EmptyArgParse{red}}O{} O{circle} m }
  {%
    \mathpalette{\mathcircled@b{#1}{#2}}{#3}%
  }
\newcommand\mathcircled@b[4]
  {%
    \tikz[baseline=(math.base)]
      \node[draw,color=#1,#2,inner sep=1pt] (math) {$\m@th#3#4$};%
  }
\makeatother

\begin{document}
$\mathcircled[blue]{55}$
$\mathcircled[][ellipse]{69}$
$\mathcircled{5}$
\end{document}
3
  • Thanks very much @Skillmon. I tried to generalize to \newcommand\mathShaped[3][black]{% \mathpalette\@mathShaped{{#1}{#2}{3}}% } \newcommand\@mathShaped[3]{% \@mathShaped@b{#1}{#2}#3% } \newcommand\@mathShaped@b[4]{% \tikz[baseline=(math.base)] \node[draw,color=#2,shape=#3,inner sep=1pt] (math) {$\m@th#1#4$};% } so I could let the shape be another optional argument, but my ability to generalize failed me again: The call $\mathShaped[red]{ellipse}{55}$ says I have an extra }. Could you extend your answer to this case, please?
    – Leo Simon
    Oct 19, 2018 at 8:40
  • @skillmon : what do you mean with "\node[draw,color=#1,#2,inner sep=1pt] (math) {$\m@th#3#4$};", how to writre \mathcircled with for parameters? I wonder #3 and #4 meanings.
    – pzorba75
    Oct 19, 2018 at 13:50
  • 1
    @pzorba75 #3 is given by \mathpalette and is one of \displaystyle, \textstyle, \scriptstyle and \scriptscriptstyle. #4 is the mandatory argument of \mathcircled. #1 is the colour and #2 is the shape (circle by default).
    – Skillmon
    Oct 19, 2018 at 15:23

You must log in to answer this question.

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