我正在寻找一种将上标/下标(如果存在)与 LaTeX 命令参数分开的方法。例如,假设您想要定义一个命令,通过在集合名称上放置上划线来从集合构建多重集。该命令的简单实现如下所示:
\newcommand{\mset}[1]{\overline{#1}}
这对于没有下标/上标的集合非常有效;例如,对于集合R
,多重集\mset{R}
等于\overline{R}
,正如所需的那样。
但是,如果集合中有上标/下标,那么排版看起来会非常丑陋,因为上划线也会延伸到索引上。因此,我想要一个将\mset
上标/下标推到外面的命令版本\overline
;例如,\mset{R_1}
应该扩展为\overline{R}_1
。
为此,我认为我需要一种方法将下标/上标从 \mset 的参数中分离出来。理想情况下,无论 \mset 的参数没有索引、只有下标、只有上标,还是同时有下标和上标,这都可以正常工作。因此,\mset{R}
将给出\overline{R}
,\mset{R^1_2}
将给出\overline{R}^1_2
,等等。
只是为了立即取消显而易见的解决方案:我知道我可以将下标/上标作为\mset
附加参数传递。然而,这会很尴尬,因为我想将 \mset 命令嵌套在其他命令中,因此单独传递所有参数会非常笨拙。
答案1
你可以这样做,但我认为没有意义:如果上标和下标应该超出上划线的范围,则将它们放在参数之外。
请注意,我正在使用k
的功能xparse
被归类为实验性的,将来可能会消失(不太可能)。
\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}
答案2
即使有您的定义,您也可以使用\mset R_2^1
,它会按您想要的方式工作。无论如何,如果您确实想要,\mset{R_2^1}
您可以使用
\newcommand*\mset[1]{\overline#1}
它将按照您希望的方式工作,甚至可以与语法一起使用\mset R_2^1
。
答案3
这是一个基于 LuaLaTeX 的解决方案。它会扫描输入中的 实例\mset{...}
并“动态”重新排列参数,以便只有前导一个或多个字母才是 参数的一部分\mset
。左花括号前后允许有空格。
\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}