我想设置一个宏,如果参数已经有一个上标,它可以添加括号。它类似于这个问题,遗憾的是以下 MWE 的编译并没有结束……
\documentclass[11pt]{article}
\usepackage{xparse}
\RequirePackage{unicode-math}
\usepackage{listofitems}
\NewDocumentCommand{\dans}{mG{\BbbR}e{^}}{%
\ensuremath{#1\in\IfValueTF{#3}{{\left(#2\right)}^{#3}}{#2}}%
}
\NewDocumentCommand{\Dans}{mG{\BbbR}e{^}}{%
\setsepchar{_||^}%
\readlist\mymat{#2}%
\ensuremath{#1\in\IfValueTF{#3}{\ifnum\mymatlen>1\left(#2\right)^{#3}\else#2^{#3}\fi}{#2}}%
}
\begin{document}
\dans{x}, \dans{(x, y)}{\BbbC^2}, \dans{(x, y)}{\BbbC}^2, \dans{(x, y)}{\BbbC^\star}^2
%\Dans{x}, \Dans{(x, y)}{\BbbC^2}, \Dans{(x, y)}{\BbbC}^2, \Dans{(x, y)}{\BbbC^\star}^2
\end{document}
取消注释该行时出现问题。
答案1
使用expl3
检查^
第二个参数的内部\tl_if_in:nnTF
,可以根据此测试添加括号:
\documentclass[11pt]{article}
\usepackage{unicode-math}
\usepackage{xparse}
\ExplSyntaxOn
\cs_new:Npn \NBur_superscript:n #1
{
\tl_if_in:nnTF { #1 } { ^ }
{ \left( #1 \right) }
{ #1 }
}
\NewDocumentCommand{\dans}{mG{\BbbC}e{^}}
{%
\ensuremath
{%
#1\in\IfValueTF{#3}{\NBur_superscript:n{#2}^{#3}}{#2}%
}%
}
\ExplSyntaxOff
\begin{document}
\dans{x}^2,
\dans{x}{A}^2,
\dans{x}{A^*}^2
\end{document}
如果将上标隐藏在上面的宏中,则测试将找不到它。一种可能的解决方案是完全展开参数,以便查找上标字符:
\documentclass[11pt]{article}
\usepackage{unicode-math}
\usepackage{xparse}
\newcommand\Test{A^*}
\ExplSyntaxOn
\cs_generate_variant:Nn \tl_if_in:nnTF { xnTF }
\cs_new:Npn \NBur_superscript:n #1
{
\tl_if_in:xnTF { #1 } { ^ }
{ \left( #1 \right) }
{ #1 }
}
\NewDocumentCommand{\dans}{mG{\BbbC}e{^}}
{%
\ensuremath
{%
#1\in\IfValueTF{#3}{\NBur_superscript:n{#2}^{#3}}{#2}%
}%
}
\ExplSyntaxOff
\begin{document}
\dans{x}^2,
\dans{x}{A}^2,
\dans{x}{A^*}^2
\dans{x}{\Test}^2
\end{document}
上述方法仍然可能失败,例如,如果上标隐藏在无法扩展的内容中,或者某些内容不应在那里扩展(前者会导致错误行为,后者可能会导致错误或非常糟糕的行为)。在正常用例中,后者应该很少见(我希望)。