我有一些现有的宏,我想将它们包装到一些自定义处理中。下面是我想要做的事情的一个示例:
\makeatletter
\let\olddag\textdagger
\renewcommand\textdagger{\@inmatherr\textdagger \olddag}
\makeatother
然后如果尝试使用$\textdagger$
,我会得到一个错误,而不是现有的排版行为。然而,\textdagger
在常规文本模式下,它将遵循其现有的定义。
我的问题是,如何才能实现相同的效果,但不对中间命令进行分配\olddag
?我怀疑会有一些巫术使用\edef
和/或\expandafter
可以让我扩展:
{\@inmatherr\textdagger \textdagger}
也许:
{\noexpand\@inmatherr\noexpand\textdagger \textdagger}
在定义时,这样当我\textdagger
在文档主体中调用时,就不会出现 TeX 堆栈溢出。但我还无法找到它是什么。
以下其他问题(及答案)可能相关:
- 答:如何重复使用一个命令名称两次或更多次?
- 如何在 \edef 中使用 \noexpand?
- 何时使用 \edef、\noexpand 和 \expandafter?
- \let 和 \edef 之间有什么区别?
- 如何控制宏在另一个定义期间是否扩展以及何时扩展?
- 嵌套 \noexpand 和 \edef 的问题
但我还没能从中找出解决方案。我想 LaTeX 的求值顺序规则不是那么透明并不是什么新鲜事。
答案1
\documentclass{article}
\makeatletter
\expandafter
\renewcommand
\expandafter\textdagger
\expandafter{%
\expandafter\@inmatherr
\expandafter\textdagger
\textdagger}
\makeatoher
\begin{document}
\textdagger $\textdagger$
\end{document}
上面显示了一般的技术,但在这种情况下,你已经收到警告,\textdagger
默认情况下
LaTeX Warning: Command \textdagger invalid in math mode on input line 8.
因此,另一种方法是将警告命令重新定义为错误。
答案2
\textdagger
所有用 定义的命令都具有 的行为,因此,在数学模式下使用它们时出错的一种方法是在的定义中\OMS-cmd
更改。请参阅\@inmathwarn
\OMS-cmd
\@inmatherr
为什么 \textbackslash 在数学模式下呈现为“n”?了解有关此问题的更多信息。
\documentclass{article}
\usepackage{etoolbox}
\makeatletter
\expandafter\patchcmd\csname OMS-cmd\endcsname{\@inmathwarn}{\@inmatherr}{}{}
\makeatother
\begin{document}
$\textdagger$
\end{document}
这给出
! LaTeX Error: Command \textdagger invalid in math mode.
See the LaTeX manual or LaTeX Companion for explanation.
Type H <return> for immediate help.
...
l.7 $\textdagger
$