我想通过重新定义来捕捉数学模式$
。我想到了类似
\def$#1${here was a formula}
% to test
$x+y=z$
我希望输出“这里有一个公式”。这可能吗?
编辑:egreg 的解决方案对我有用:
\documentclass{article}
\catcode`\$=\active
\gdef$#1${Formula(\detokenize{#1})}
\begin{document}
voila le calcul $3+4=5$
\end{document}
但我还想重新定义双美元$$ ...$$
。如果我再定义一下:
\gdef$$#1$${centered-Formula(\detokenize{#1})}
然后进行以下工作:
voila un calcul centré $$x+y=z$$
但我不能再使用单一美元了:$3+4=5$
现在无法编译。
问题: 我怎样才能同时拥有$...$
和$$...$$
可用?
答案1
你可以,但不能保证它在所有情况下都有效:
\begingroup
\catcode`\$=\active
\protected\gdef$#1${...}
\endgroup
\AtBeginDocument{\catcode`\$=\active}
对于$$...$$
,保证更少:
\documentclass{article}
\usepackage[T1]{fontenc}
\catcode`$=\active
\makeatletter
\protected\def${\@ifnextchar$\@doubledollar\@singledollar}
\def\@doubledollar$#1$${centeredFormula(\detokenize{#1})}
\def\@singledollar#1${Formula(\detokenize{#1})}
\makeatother
\begin{document}
$a+b=b+a$
$$a-b\ne b-a$$
\end{document}
答案2
这与其他答案的解决方案相同,但在 expl3 中实现:
\documentclass{article}
\ExplSyntaxOn
\char_set_catcode_active:N $
\cs_new:Npn $ { \peek_charcode:NTF $ {\loic_doubledollar:w} {\loic_singledollar:w} }
\cs_new:Npn \loic_doubledollar:w $ #1 $ $ {
Formula(\detokenize{#1}):
\c_math_toggle_token \c_math_toggle_token #1
\c_math_toggle_token \c_math_toggle_token
}
\cs_new:Npn \loic_singledollar:w #1 $ {
Formula(\detokenize{#1}):
\c_math_toggle_token #1 \c_math_toggle_token
}
\char_set_catcode_math_toggle:N $
\AtBeginDocument{
\char_set_catcode_active:N $
}
\ExplSyntaxOff
\begin{document}
$a+b=b+a$
$$a-b\ne b-a$$
\end{document}
额外:手柄\[
等\begin{align*}
。
不幸的是,align*
环境align
在后台使用,因此重新定义是危险的align
。
相似地,重新定义equation*
休息\[... \]
。
尽管如此,不建议$$...$$
在 LaTeX 中使用,\[...\]
更建议参考为什么 \[ ... \] 比 $$ ... $$ 更可取?。
此外,可能还需要重新定义其他几个数学环境,如\begin{tikzcd}..\end{tikzcd}
、\begin{align*}..\end{align*}
等。
完整列表可以在以下位置找到texdoc amsldoc
(加上已弃用的eqnarray
、和环境\begin{math}
)\begin{displaymath}
:
\[...\]
这是重新定义和的示例\begin{align*}...\end{align*}
:(\(...\)
未处理)
\documentclass{article}
\usepackage{amsmath}
\ExplSyntaxOn
% ======== redefine $...$
\char_set_catcode_active:N $
\cs_new:Npn $ #1 $ {
Formula(\detokenize{#1}):
\c_math_toggle_token #1 \c_math_toggle_token
}
\char_set_catcode_other:N $
\AtBeginDocument{ \char_set_catcode_active:N \$ }
% ======== redefine \[...\]
\cs_new_eq:NN \lois__old_open_square_bracket: \[
\cs_gset:Npn \[ #1 \] {
Formula(\detokenize{#1}):
\lois__old_open_square_bracket: #1 \]
}
% ======== redefine align*
\ProvideDocumentCommand \NewEnvironmentCopy {mm} { % lines taken from https://tex.stackexchange.com/a/680717/250119, can be deleted if LaTeX version is new enough
\expandafter \NewCommandCopy \csname#1\expandafter\endcsname \csname#2\endcsname
\expandafter \NewCommandCopy \csname end#1\expandafter\endcsname \csname end#2\endcsname }
\ProvideDocumentCommand \RenewEnvironmentCopy {mm} {
\expandafter \RenewCommandCopy \csname#1\expandafter\endcsname \csname#2\endcsname
\expandafter \RenewCommandCopy \csname end#1\expandafter\endcsname \csname end#2\endcsname }
\NewEnvironmentCopy{old-align*}{align*} % backup the old definition
%do nothing: fine -- \RenewDocumentEnvironment{align*}{}{\csname old-align*\endcsname}{\csname endold-align*\endcsname}
%insert something at the start of the environment: fine -- \RenewDocumentEnvironment{align*}{}{\csname old-align*\endcsname xxx}{\csname endold-align*\endcsname}
% this may appear to work well, but will silently use wrong spacing! -- \RenewDocumentEnvironment{align*}{}{\csname old-align*\endcsname}{xxx\csname endold-align*\endcsname}
\RenewDocumentEnvironment{align*}{b}{Formula: \begin{old-align*}#1\end{old-align*}}{}
% ======== done
\ExplSyntaxOff
\begin{document}
123
$a+b=b+a$
\[a-b\ne b-a\]
and
\begin{align*}
123 &=456 \\
456 &=123
\end{align*}
\begin{old-align*}
xxx123 &=456 \\
456 &=123
\end{old-align*}
\end{document}
替代解决方案不太可靠,不推荐
您可能会想到使用\everymath
自动插入命令$
。然而,这会破坏很多使用数学模式的东西,例如,,,\textsuperscript
等等。\underline
\(...\)
\ExplSyntaxOn
\quark_new:N \qmymathpreserve % variable name does not conform to expl3 recommendation!
\cs_set:Npn \my_token_if_eq_meaning:nNTF #1 {\token_if_eq_meaning:NNTF #1} % (remove braces around #1.) (note that this will not work properly when #1 is empty.)
\cs_generate_variant:Nn \my_token_if_eq_meaning:nNTF {xNTF}
\cs_new:Npn \mymathprocessor #1 $ {
\my_token_if_eq_meaning:xNTF {\tl_head:n {#1}} \qmymathpreserve {
\tl_tail:n {#1} $ % preserve the old behavior
} {
$ % close the math environment first...
#1 ~ % then print as text (put ~ here because space at the start of a line doesn't work)
$\qmymathpreserve a^2$ % add another math formula for demonstration
}
}
\everymath{\mymathprocessor}
\ExplSyntaxOff
$this is actually text$
$\qmymathpreserve a^2+b^2$
正如你所见,以下代码
$\qmymathpreserve formula$
将呈现为“正常”数学公式,而以下代码
$formula$
将使用处理器对公式进行预处理。在这种情况下,处理器是可扩展的。
您甚至可以在数学环境之外添加额外的文本,如上面的示例所示(但您仍然是一个空的数学公式)。
请注意,\tl_head:n
如果输入为空,则会返回空,从而中断\my_token_if_eq_meaning:nNTF
。
用来。$$...$$
\everydisplay
注意:即使立即关闭公式,仍然会有一个空的数学公式,这在显示模式下是一个较大的问题。