如何解析嵌套宏中的下标和上标?
我正在尝试根据此编写两个宏回答:
- underlinemacro:对输入参数加下划线(不包括下标和上标)。
- widehatmacro:在输入参数上放置一个 widehat,不包括下标和上标。
我不知道如何编写这些代码以用于重复或混合应用程序。我希望能够使用\underlinemacro{\underlinemacro{A^B_C}}
获得与 相同的行为,\underline{\underline{A}}\smash{^B_C}
并且 也是如此widehatmacro
。更重要的是,我希望能够使用\widehatmacro{\underlinemacro{A^B_C}}
获得与 相同的行为\widehat{\underline{A}}\smash{^B_C}
。
以下是 MWE 的尝试:
\documentclass{article}
\usepackage{xparse}
% Example Macro ---
\newcommand{\ABC}{A^B_C}
% Underline Macro ---
\newcommand{\underlinemacro}[1]{
\expandafter\makeunderlinemacroA\expandafter{#1}}
% Force expansion if input is a underlinemacro
% Pass expanded output to makeunderlinemacroA
\NewDocumentCommand{\makeunderlinemacroA}{
>{\SplitArgument{1}{_}}m}
{\makeunderlinemacroB#1}
% One Input -> Two Outputs
% A -> A x
% A^B -> A^B x
% A_B -> A B
% A^B_C -> A^B C
% A_B^C -> A B^C
% Pass outputs to makeunderlinemacroB
\NewDocumentCommand{\makeunderlinemacroB}{mm}{
\IfNoValueTF{#2}{% If no value then we had A^B x or A x
\makeunderlinemacroC{#1}{} % Pass A^B x or A x to makeunderlinemacroC
}{% Else, there were subscripts
\makeunderlinemacroC{#1}{#2} % Pass A B or A^B C or A B^C to makeunderlinemacroC
}%
}
\NewDocumentCommand{\makeunderlinemacroC}{
>{\SplitArgument{1}{^}}m
>{\SplitArgument{1}{^}}m}
{\makeunderlinemacroD#1#2}
% Two Input -> Four Output
% A x -> A x x x
% A^B x -> A B x x
% A B -> A x B x
% A^B C -> A B C x
% A B^C -> A x B C
% Pass outputs to makeunderlinemacroD
\NewDocumentCommand{\makeunderlinemacroD}{mmmm}{
\IfValueTF{#2}{
% If value for #2, we had A B C x or A B x x
\makeunderlinemacro{#1}{#3}{#2}
% Pass to makeunderlinemacro with #3 as subscript, #2 as superscript
}{% Else we had A x B x or A x B C or A x x x
\makeunderlinemacro{#1}{#3}{#4}
% Pass to makeunderlinemacro with #3 as subscript, #4 as superscript
}%
}
\NewDocumentCommand{\makeunderlinemacro}{mmm}{
\underline{#1}\smash{\IfValueT{#2}{_{#2}}\IfValueT{#3}{^{#3}}}}
% Widehat Macro ---
\newcommand{\widehatmacro}[1]{
\expandafter\makewidehatmacroA\expandafter{#1}}
% Force expansion if input is a widehatmacro
% Pass expanded output to makewidehatmacroA
\NewDocumentCommand{\makewidehatmacroA}{
>{\SplitArgument{1}{_}}m}
{\makewidehatmacroB#1}
% One Input -> Two Outputs
% A -> A x
% A^B -> A^B x
% A_B -> A B
% A^B_C -> A^B C
% A_B^C -> A B^C
% Pass outputs to makewidehatmacroB
\NewDocumentCommand{\makewidehatmacroB}{mm}{
\IfNoValueTF{#2}{% If no value then we had A^B x or A x
\makewidehatmacroC{#1}{} % Pass A^B x or A x to makewidehatmacroC
}{% Else, there were subscripts
\makewidehatmacroC{#1}{#2} % Pass A B or A^B C or A B^C to makewidehatmacroC
}%
}
\NewDocumentCommand{\makewidehatmacroC}{
>{\SplitArgument{1}{^}}m
>{\SplitArgument{1}{^}}m}
{\makewidehatmacroD#1#2}
% Two Input -> Four Output
% A x -> A x x x
% A^B x -> A B x x
% A B -> A x B x
% A^B C -> A B C x
% A B^C -> A x B C
% Pass outputs to makewidehatmacroD
\NewDocumentCommand{\makewidehatmacroD}{mmmm}{
\IfValueTF{#2}{
% If value for #2, we had A B C x or A B x x
\makewidehatmacro{#1}{#3}{#2}
% Pass to makewidehatmacro with #3 as subscript, #2 as superscript
}{% Else we had A x B x or A x B C or A x x x
\makewidehatmacro{#1}{#3}{#4}
% Pass to makewidehatmacro with #3 as subscript, #4 as superscript
}%
}
\NewDocumentCommand{\makewidehatmacro}{mmm}{
\widehat{#1}\smash{\IfValueT{#2}{_{#2}}\IfValueT{#3}{^{#3}}}}
% Document ---
\begin{document}
These should produce the same output: \(\underline{A}\smash{^B_C}\)
\[
\underlinemacro{A^B_C}
\underlinemacro{\ABC}
\underlinemacro{\underlinemacro\ABC}
\underlinemacro{\underlinemacro{\underlinemacro\ABC}}
\]
These should produce the same output: \(\widehat{A}\smash{^B_C}\)
\[
\widehatmacro{A^B_C}
\widehatmacro{\ABC}
\widehatmacro{\widehatmacro\ABC}
\widehatmacro{\widehatmacro{\widehatmacro\ABC}}
\]
These should produce the same output: \(\underline{\widehat{A}}\smash{^B_C}\)
\[
\underlinemacro{\widehatmacro{A^B_C}}
\widehatmacro{\underlinemacro{A^B_C}}
\underlinemacro{\widehatmacro\ABC}
\widehatmacro{\underlinemacro\ABC}
\]
\end{document}