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
  • 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
    Commented Jun 21, 2016 at 6:54

3 Answers 3

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

1
  • 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
    Commented Jun 21, 2016 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} 

You must log in to answer this question.

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