我能重新定义美元吗

我能重新定义美元吗

我想通过重新定义来捕捉数学模式$。我想到了类似

\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}

amsldoc 提取

\[...\]这是重新定义和的示例\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

注意:即使立即关闭公式,仍然会有一个空的数学公式,这在显示模式下是一个较大的问题。

相关内容