如何在宏之后捕获上标和下标

如何在宏之后捕获上标和下标

这个问题的答案与通过宏捕获宏的下标/上标通过 egreg。

我正在尝试使用 xparser 包来创建一些宏,并且当我想要有下标和上标(或同时有两者)时我宁愿不必使用不同的宏!

我想要一个这样的宏:

\F
\F{m}
\F{m}_b
\F{m}^a
\F{m}_b^a
\F{m}^a_b

产生与此等同的输出:

在此处输入图片描述

$F$
$F[m]$
$F_b[m]$
$F^a[m]$
$F_b^a[m]$
$F^a_b[m]$

根据上述链接的问题,我可以捕捉到其中一个,但不能同时捕捉到两个。我尝试过几次,但现在的@ifnextchar作品中一定有一些非常基本(或微妙)的东西超出了我的理解范围。

此代码采用两个可选参数,而不是一个,但问题仍然存在:下标和上标总是出现在行末,而不是定义的第一个字符上。

\documentclass{article}
\usepackage{xparse}
\makeatletter
\newcommand{\DFcmd}{\ensuremath{F}}

\NewDocumentCommand\DFhelp{ g g g g }
{
    \IfValueT{#3}{ \def\@DFcmdsub{\DFcmd^{#3}} }{ \def\@DFcmdsub{\DFcmd} }
    \IfValueT{#4}{ \def\@DFcmdsuper{\@DFcmdsub_{#4}} }{ \def\@DFcmdsuper{\@DFcmdsub} }
    \@DFcmdsuper
    \IfNoValueF{#1}{#1}{}
    \IfNoValueF{#2}{#2}{}   
}    

\NewDocumentCommand\DF{ o o }
{%
    \def\firstarg{}%
    \def\secondarg{}%
    \IfNoValueF{#1}{ \def\firstarg{[#1]} }{ \def\firstarg{} }%
    \IfNoValueF{#2}{ \def\secondarg{#2} }{ \def\secondarg{} }%
    \def\superopt{}%
    \def\subopt{}%
    \@ifnextchar^%
    {%
        \assign@superopt%
        \@ifnextchar_%
        {%
            \assign@subopt%
        }%
        {%
            \def\subopt{}%
        }%
    }%
    {%
        \@ifnextchar_%
        {%
            \assign@subopt%
            \@ifnextchar^%
            {%
                \assign@superopt%
            }%
            {%
                \def\superopt{}%
            }%
        }
        {%
            \def\subopt{}%
        }%
    }
    \DFhelp{\firstarg}{\secondarg}{\superopt}{\subopt}%
}    

\def\assign@superopt^#1{ \def\superopt{#1} }
\def\assign@subopt_#1{ \def\subopt{#1} }
\makeatother

答案1

以下抓取多个下标和上标。

括号中的参数(显然是可选的)最好放在 中[ ]

代码

\documentclass{article}
\makeatletter
\def\F{%
  \let\f@sub\@empty
  \let\f@super\@empty
  \let\f@main\@empty
  \@ifnextchar\bgroup\f@catch@main\f@test
}
\def\f@catch@main#1{\def\f@main{#1}\f@test}
\def\f@test{%
  \@ifnextchar_\f@catch@sub{\@ifnextchar^\f@catch@super\f@finalize}%
}
\def\f@catch@sub_#1{\expandafter\def\expandafter\f@sub\expandafter{\f@sub#1}\f@test}
\def\f@catch@super^#1{\expandafter\def\expandafter\f@super\expandafter{\f@super#1}\f@test}
\def\f@finalize{%
      F
      \ifx\f@sub\@empty\else_{\f@sub}\fi
      \ifx\f@super\@empty\else^{\f@super}\fi
      \ifx\f@main\@empty\else[\f@main]\fi
}
\makeatother
\begin{document}
$ \F $ \par
$ \F{m} $ \par
$ \F{m}_b $ \par
$ \F{m}^a $ \par
$ \F{m}_b^a $ \par
$ \F{m}^a_b $ \par
$ \F{m}^a_b_a^b $ \par
\end{document}

输出

在此处输入图片描述

答案2

由于您只有一个强制参数(并且您正在寻找^and _),我认为不会xparse给您带来很多好处,所以我\@ifnextchar直接在这里使用。此外,由于您有m一个强制{}参数,因此应该始终给出它,因此我将其更改\F为并添加了一个测试,以确保该参数为空。(另一种方法是使参数可选,但随后应将其用not\F{}分隔。[]{}

在此处输入图片描述

\documentclass{article}

\makeatletter
\def\F#1{\def\F@{\ifx\relax#1\relax\else[#1]\fi}\def\F@@{F}\@ifnextchar^\@Fsp\@Fnsp}
\def\@Fsp^#1{\def\F@@{F^{#1}}\@ifnextchar_\@Fspsb{\F@@\F@}}
\def\@Fspsb_#1{\F@@_{#1}\F@}
\def\@Fnsp{\@ifnextchar_{\@Fsb}{\F@@\F@}}
\def\@Fsb_#1{\def\F@@{F_{#1}}\@ifnextchar^\@Fsbsp{\F@@\F@}}
\def\@Fsbsp^#1{\F@@^{#1}\F@}
\begin{document}



$\F{}$

$\F{m}$

$\F{m}_b$

$\F{m}^a$

$\F{m}_b^a$

$\F{m}^a_b$

\end{document}

答案3

下面的似乎运行得相当好,但(至少)有一个限制,即它需要在宏后有一个空格才能运行。

在此处输入图片描述

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn

\NewDocumentCommand{\F}{}{
    \peek_charcode:NTF \c_group_begin_token
        {\renstar_F:w}
        {$F$}
}

\cs_new:Npn \renstar_F:w #1#2~ {
    \ensuremath{F#2[#1]}~
}

\ExplSyntaxOff

\begin{document}

\F 

\F{m}

\F{m}_b

\F{m}^a

\F{m}_b^a

\F{m}^a_b

\end{document}

答案4

我会选择完全不同的方向。就你的情况而言,定义一个复杂的宏比更自然地打字没有任何好处

$F_{a}^{b}[m]$

如果这只是一个更复杂情况的例子,我建议你使用键值语法,这样可以避免追逐 token 和区分不同情况。这也更灵活。

这是示例。

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\DF}{O{}}
 {
  \group_begin:
  \keys_set:nn { renstar/DF } { #1 }
  \renstar_DF:
  \group_end:
 }
\keys_define:nn { renstar/DF }
 {
  arg .tl_set:N = \l_renstar_arg_tl,
  sub .tl_set:N = \l_renstar_sub_tl,
  sup .tl_set:N = \l_renstar_sup_tl,
  symbol .tl_set:N = \l_renstar_symbol_tl,
  symbol .initial:n = F,
 }
\cs_new:Npn \renstar_DF:
 {
  \l_renstar_symbol_tl
  \tl_if_empty:NF \l_renstar_sub_tl
   { \c_math_subscript_token { \l_renstar_sub_tl } }
  \tl_if_empty:NF \l_renstar_sup_tl
   { \c_math_superscript_token { \l_renstar_sup_tl } }
  \tl_if_empty:NF \l_renstar_arg_tl
   { [ \l_renstar_arg_tl ] }
 }
\ExplSyntaxOff

\begin{document}
$\DF$

$\DF[arg=m]$

$\DF[arg=m,sub=a]$

$\DF[sup=b,arg=m]$

$\DF[arg=m,sup=b,sub=a]$

$\DF[symbol=M,sup=x,arg=f]$
\end{document}

在此处输入图片描述

相关内容