如何定义一个新角色同时避免与现有的角色定义发生冲突?

如何定义一个新角色同时避免与现有的角色定义发生冲突?

我想定义一个新的特点。具体来说,对于上下文,我的新字符的作用类似于^上标字符,但会在上标上下文周围加上括号。

我知道我可以写一篇正常命令, 喜欢

\newcommand{\superscriptWithParentheses}[2]{{#1}^{({#2})}}

产生所需的结果。例如,\superscriptWithParentheses{x}{i}将成功创建x^{(i)}。但我希望定义一个字符而不是普通命令。为什么?出于同样的原因,人们更喜欢写x_i而不是。(基本上,我的动机与(1)当参数变得复杂时源代码的可读性和(2)与类似运算符和x\sp{i}的语法一致性有关。如果需要额外的动机,我可以提供一个具体的例子。)_^

现在关注此链接,如果我想重新定义 ^, 我可以

\catcode`\^=\active
\newcommand{^}[1]{\sp{({#1})}}

不过,我想保留该^字符以供正常上标使用。

所以看起来我需要定义一个新字符。但是哪一个呢?我想不出一个没有含义而我不应该覆盖的字符。有人有什么建议吗?有没有我没有考虑到的字符可以使用?有没有办法为双字符提供特殊含义,比如^^?有没有办法将其定义\^为与具有不同含义的字符^?有没有我没有想到的其他方法?

答案1

我不推荐这样做,但你可以^激活数学。在数学模式下,^将检查紧随其后的^;在这种情况下,它会将上标括起来,否则它只会发出一个普通的上标标记。

\documentclass{article}
\usepackage{amsmath}

\ExplSyntaxOn

\cs_new_protected:Npn \__ashman_hat:w
 {
  \peek_charcode_remove:NTF ^
   {% there is ^, remove it and do
    \__ashman_hat_double:n
   }
   {% else, just normal ^
    \c_math_superscript_token
   }
 }

\cs_new_protected:Nn \__ashman_hat_double:n
 {
  \c_math_superscript_token { (#1) }
 }

\char_set_active_eq:NN ^ \__ashman_hat:w

\ExplSyntaxOn

\AtBeginDocument{\mathcode`^="8000 \catcode`^=12 }

\begin{document}

$a^b+a^^b$

\end{document}

在此处输入图片描述

这对文本模式重音没有影响\^

“经典”代码如下

\documentclass{article}
\usepackage{amsmath}

\makeatletter
\newcommand{\ashman@hat}{\futurelet\ashman@next\ashman@@hat}
\newcommand{\ashman@@hat}{%
  \if\noexpand\ashman@next\string^%
    \expandafter\ashman@hathat
  \else
    \expandafter\sp
  \fi
}
\newcommand{\ashman@hathat}[2]{\sp{(#2)}}

\begingroup
\catcode`^=\active
\global\let^\ashman@hat
\endgroup

\AtBeginDocument{\mathcode`^="8000 \catcode`^=12 }
\makeatother

\begin{document}

$a^b+a^^b$

\end{document}

并非更短或更隐秘。

如果你找到一种轻松输入的方法,那么你可以这样做

\documentclass{article}
\usepackage{amsmath}
\usepackage{newunicodechar}

\newunicodechar{↑}{\ashmanparens}
\newcommand{\ashmanparens}[1]{^{(#1)}}

\begin{document}

$a^b+a↑b$

\end{document}

所有方法都适用于任何 TeX 引擎(Knuth TeX 除外,对于它只有“经典”方法有效)。

答案2

当然,你可以定义

\def\^#1{^{(#1)}}

并使用a\^{b+c}将其扩展为a^{(a+c)}。但是旧的 8 位 LaTeX 及其 LICR(LaTeX 内部字符表示)存在问题,其中\^预期为重音宏:\^o扩展为ô。更确切地说,如果您重新定义\^并使用旧的 8 位 LaTeX,那么:如果用户ô在输入文件中写入,它会在内部扩展为\^o并且如果 被重新定义,则以下扩展会崩溃\^。所以,你必须使用新的 LaTeX,即 LuaLaTeX 或 XeLaTeX。或者你可以完全离开 LaTeX 并使用 OpTeX,例如。

Egreg 展示了经典解决方案,^^并尝试将其与 Expl3 宏进行比较。我认为 Expl3 代码更加神秘,但这是基于个人看法。如果您使用的是 OpTeX,那么您可以使用以下代码进行^^比较:

\adef^{\ea\isnextchar \string^{\spb}{\sp}}
\def\spb#1#2{\sp{(#2)}}
\mathcode`\^="8000 \catcode`\^=12

$ a^^b, \quad c^d $

\bye

相关内容