3

I'm looking for a way of separating super-/subscripts (if they exist) from a LaTeX command argument. As an example, imagine you want to define a command that builds multisets from sets by placing an overline over the set name. A naive implementation of the command looks like this:

\newcommand{\mset}[1]{\overline{#1}}

This works well for sets that do not have sub-/superscripts; for example, for a set R, the multiset \mset{R} is equal to \overline{R}, as desired.

However, if the set has sub-/superscripts, then the typesetting looks really ugly as the overline stretches over the indexes as well. Thus, I would like a version of the \mset command that pushes sub-/superscripts outside \overline; for example, \mset{R_1} should expand to \overline{R}_1.

For this, it seems to me that I'd need a way to separate the sub-/superscripts out of the argument of \mset. Ideally, this would work regardless of whether the argument to \mset has no indexes, subscripts only, superscripts only, or both sub- and superscripts. Thus, \mset{R} would give \overline{R}, \mset{R^1_2} would give \overline{R}^1_2, and so on.

And just to immediately disqualify the obvious solution: I understand that I could pass sub-/superscripts to \mset as additional arguments. This, however, would be awkward as I want to nest the \mset command inside other commands so passing all the arguments separately would be quite clunky.

  • 1
    Simple solution for this: \newcommand*\mset[1]{\overline#1}. In any case, even simpler input would be \mset R^1_2, no need for braces. – Manuel Jun 21 '16 at 6:54
3

You can do it, but I see no point: if the superscripts and subscripts should be outside the scope of the overline, place them outside the argument.

Note that the k feature of xparse I'm using is classified as experimental and may disappear in the future (not really likely).

\documentclass{article}
\usepackage{xparse}

\newcommand{\mset}[1]{\makemset#1}
\NewDocumentCommand{\makemset}{mk_k^k_}{%
  \overline{#1}%
  \IfValueT{#2}{_{#2}}%
  \IfValueT{#3}{^{#3}}%
  \IfValueT{#4}{_{#4}}%
}

\begin{document}

$\mset{R}+\mset{R_1^2}+\mset{R^2_1}+\mset{R}_1^2$

\end{document}

enter image description here

  • Thank everyone for their answers -- they were all really helpful, but this one seems cleanest. Just a clarification as to the "why bother" question: I want to embed \mset into another command that accepts a set, converts it into a multiset, and does something with it. The set passed to this outer command can have sub-/superscripts, and it is more natural to pass it as, say, R_1^2, rather than requiring this outer command to accept several arguments. – Boris Jun 21 '16 at 8:50
3

Even with your definition, you can use \mset R_2^1 and it will work as you want. In any case, in case you definitely want \mset{R_2^1} you can use

\newcommand*\mset[1]{\overline#1}

Which will work as you want, and it will even work with the \mset R_2^1 syntax.

2

Here's a LuaLaTeX-based solution. It scans the input for instances of \mset{...} and rearranges the argument "on the fly", so that only leading single or multiple letters are part of the argument of \mset. Whitespace before or after the left-hand curly brace is allowed.

enter image description here

\documentclass{article}
\newcommand{\mset}[1]{\overline{#1}}

\usepackage{luacode}
\begin{luacode}
function mset_mod ( buff )
   return ( string.gsub ( buff, "\\mset[%s]-(%b{})",
              function ( x )
                 y = string.gsub ( x, "{[%s]-(%a+)(.*)}", "{%1}%2" )
                 return ("\\mset"..y )
              end ) )
end
luatexbase.add_to_callback("process_input_buffer", mset_mod, "mset_mod")
\end{luacode}

\begin{document}
$\mset{ R^{11}_{22}}$ $\mset {R_2^1}$ $\mset R$ $\mset{R}$

$\mset{  ABC }$ $\mset{ AB _1^{2}}$  
\end{document} 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.