![编辑:](https://linux22.com/image/282677/%E7%BC%96%E8%BE%91%EF%BC%9A.png)
在这个示例文档中,我想创建一个名为的数学关系R
,将其排版为R^X
,但作为数学关系。但我希望能够为其添加下标。\myRbad
没有下标,宏看起来没问题,但有下标,它看起来就不对了,因为下标出现在上标“之后”,而不是像应该的那样位于上标下方。\myRgood
无论哪种情况,宏看起来都是正确的。它的工作原理是检查下一个字符是否是_
,如果是,则吞噬_
并委托给另一个宏来排版下标版本。不过,我想知道是否有比这更直接的方法让 LaTeX 做我想做的事。
\documentclass[a4paper]{amsart}
\def\myRbad{\mathrel{R^X}}
\makeatletter
\def\@myRgood@#1{\mathrel{R^X_{#1}}}
\def\myRgood{\@ifnextchar_{\expandafter\@myRgood@\@gobble}{\mathrel{R^X}}}
\makeatother
\begin{document}
$a \myRbad b$
$a \myRbad_Y b$
$a \myRgood b$
$a \myRgood_Y b$
$a R^X_Y b$
$a \mathrel{R^X}_Y b$
$a \mathrel{R^X_Y} b$
\end{document}
编辑:
作为奖励,这里有一个宏,可以自动创建类似的宏\myRgood
(使用@egreg 的答案所示的改进方法)。 (你必须\usepackage{xstring}
。)
\makeatletter
\def\makeprocessedmathabsorbsubscript#1#2#3{
\edef\@themacroname{\string#1}%
\saveexpandmode%
\fullexpandarg%
\StrGobbleLeft{\@themacroname}{1}[\@themacroname]%
\restoreexpandmode%
\ifcsname\@themacroname\endcsname%
\errmessage{The macro "\@themacroname" already exists}%
\fi%
\ifcsname @\@themacroname @\endcsname%
\errmessage{Something strange is happening.
I want to create an internal macro for "\@themacroname",
but it exists already}%
\fi%
\expandafter\def\csname @\@themacroname @\endcsname##1##2{#2{#3_{##2}}}%
\edef#1{%
\unexpanded{\@ifnextchar_}%
{\unexpanded\expandafter{\csname @\@themacroname @\endcsname}}%
\unexpanded{{#2{#3}}}%
}
}
\makeatother
现在可以写类似这样的内容:
\makeprocessedmathabsorbsubscript{\myRbetter}{\mathrel}{R^X}
\myRbetter
并提供了宏。
答案1
只需定义\@myRgood
两个参数并使用第二个参数即可。当你\@myRgood
调用知道接下来_
。
\documentclass[a4paper]{amsart}
\makeatletter
\def\@myRgood@#1#2{\mathrel{R^X_{#2}}}
\def\myRgood{\@ifnextchar_{\@myRgood@}{\mathrel{R^X}}}
\makeatother
\begin{document}
$a \myRgood b$
$a \myRgood_Y b$
\end{document}
“抽象”版本;使用与带有可选参数的命令类似的技巧;与之相关的内部宏\myRgood
是\\myRgood
(名称中带有反斜杠)。
\documentclass[a4paper]{amsart}
\makeatletter
\newcommand{\newrelation}[2]{% #1 = control sequence, #2 = replacement text
\@ifdefinable{#1}{%
\def#1{%
\@ifnextchar_{\csname\string#1\endcsname}{\mathrel{#2}}%
}%
\@namedef{\string#1}##1##2{\mathrel{#2_{##2}}}%
}%
}
\makeatother
\newrelation{\myRgood}{R^X}
\begin{document}
$a \myRgood b$
$a \myRgood_Y b$
\end{document}
相同的 LaTeX3 版本
\documentclass[a4paper]{amsart}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\myRgood}{ }
{
\peek_catcode_remove:NTF \c_math_subscript_token
{ \hammerite_myR:n }
{ \hammerite_myR:n {} }
}
\cs_new_protected:Npn \hammerite_myR:n #1
{
\mathrel
{
R^X
\tl_if_empty:nF { #1 } { \c_math_subscript_token { #1 } }
}
}
\ExplSyntaxOff
\begin{document}
$a \myRgood b$
$a \myRgood_Y b$
\end{document}
这是“抽象”版本
\documentclass[a4paper]{amsart}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\newrelation}{mm}
{% #1 = control sequence, #2 = replacement text
\NewDocumentCommand{#1}{}
{
\peek_catcode_remove:NTF \c_math_subscript_token
{
\hammerite_relation:nn { #2 }
}
{
\hammerite_relation:nn { #2 } { }
}
}
}
\cs_new_protected:Npn \hammerite_relation:nn #1 #2
{
\mathrel
{
#1
\tl_if_empty:nF { #2 } { \c_math_subscript_token { #2 } }
}
}
\ExplSyntaxOff
\newrelation{\myRgood}{R^X}
\begin{document}
$a \myRgood b$
$a \myRgood_Y b$
\end{document}