我正在尝试进行设置,以便在数学模式下,如果出现 ,$$
则用 替换,否则用 替换。我的策略是使其处于活动状态,并根据以下标记是否也是 ,使其行为不同。但是,我似乎无法做到这一点。这是我的尝试:\]
\[
$
$
\documentclass{article}
\usepackage{lipsum}
\def\unactiveDollar{$}
\catcode`\$=\active
\def\activeDollar{$}
\def\executedollar{%
\if\isDollar\activeDollar%
\let\next=\executeDDollar%
\else%
\let\next=\unactiveDollar%
\fi%
\next%
}
\def\executeDDollar{%
\ifmmode%
\let\next=\]%
\else%
\let\next=\[%
\fi%
\next%
\let\absorbnext=
}
\def${\futurelet\isDollar\executedollar}
\begin{document}
\lipsum*[7]
$$\int x^2 \; dx = \frac{1}{3}x^3 + C$$
\lipsum[9]
%Make sure $ $ is not mistaken for $$:
It follows that $E = m c^2$ $\forall x \in X$.
\end{document}
产生的错误是
./doubledollar.tex:29: TeX capacity exceeded, sorry [input stack size=5000].
\isDollar ->\if \isDollar
\activeDollar \let \next =\executeDDollar \else \l...
l.29 $$
\int x^2 \; dx = \frac{1}{3}x^3 + C$$
./doubledollar.tex:29: ==> Fatal error occurred, no output PDF file produced!
其他变体(例如,替换\ifx
)\if
会产生不同的错误或只是不正确的输出,但都无法解决问题。据我所知,关键问题是我用于确定以下标记是否为 a $
(如果是,则吸收它)的方法根本不起作用。
我做错了什么?我该如何解决?
$$
附加说明:每当使用而不是其他宏/环境(必须能够在内部使用它)时都会引发错误的答案也是可以接受的,因为它回答了名义上的问题。
答案1
您应该使用\ifx
而不是\if
,它只比较字符代码并进行完全扩展。
\documentclass{article}
\usepackage{lipsum}
\let\unactiveDollar=$
\catcode`\$=\active
\def\executedollar{%
\ifx\isDollar$%
\let\next=\executeDDollar
\else
\let\next=\unactiveDollar
\fi
\next
}
\def\executeDDollar{%
\ifmmode
\let\next=\]%
\else
\let\next=\[%
\fi
\next
\let\absorbnext=
}
\def${\futurelet\isDollar\executedollar}
\begin{document}
\lipsum*[7]
$$\int x^2 \; dx = \frac{1}{3}x^3 + C$$
\lipsum[9]
%Make sure $ $ is not mistaken for $$:
It follows that $E = m c^2$ $\forall x \in X$.
\end{document}
当然输入如
It follows that $E = m c^2$$\forall x \in X$.
这会产生奇怪的错误,可能需要通过\ifinner
测试来解决。
这是一个类似的版本,用于检查是否合法(尽管有争议)$$
:
\documentclass{article}
\usepackage{lipsum}
\makeatletter
\let\staats@inactivedollar=$
\catcode`\$=\active
\def\staats@execdollar{%
\ifx\let@token$%
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
\staats@execddollar
\staats@inactivedollar
}
\def\staats@execddollar{%
\ifmmode
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{\ifinner
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{\staats@inactivedollar}%
{\]\let\staats@absorbnext= }}%
{\[\let\staats@absorbnext= }%
}
\protected\def${\futurelet\let@token\staats@execdollar}
\begin{document}
\lipsum*[7]
$$\int x^2 \; dx = \frac{1}{3}x^3 + C$$
\lipsum[9]
%Make sure $ $ is not mistaken for $$:
It follows that $E = m c^2$ $\forall x \in X$.
It follows that $E = m c^2$$\forall x \in X$.
\end{document}
我担心有几件事可能会导致事情出错。最好的办法就是坚持$$
永远不要使用暴力。身体胁迫可能会有效。;-)
答案2
我认为最简单的方法,虽然相当严厉,就是
\RequirePackage[l2tabu,orthodox]{nag}
在您的文档类中,或
\usepackage[l2tabu,orthodox]{nag}
无论您提供什么辅助包。
这将教会您的用户许多应避免的事情,包括$$...$$
。
答案3
基于egreg 的这个答案,结合包\new@nextchar
中的宏amsmath
,我有一个似乎可行的答案,至少对于这个例子来说:
\documentclass{article}
\usepackage{lipsum}
\RequirePackage{amsmath}
\makeatletter
\def\unactiveDollar{$}
\catcode`\$=\active
\def\@DDollar${%
\ifmmode%
\let\next=\]%
\else%
\let\next=\[%
\fi%
\next%
}
\protected\def${\new@ifnextchar$\@DDollar\unactiveDollar}
\makeatother
\begin{document}
\lipsum*[7]
$$\int x^2 \; dx = \frac{1}{3}x^3 + C$$
\lipsum[9]
%Make sure $ $ is not mistaken for $$:
It follows that $E = m c^2$ $\forall x \in X$.
\end{document}
问题:为什么定义受$
保护?我复制了此行为,因为我认为它有充分的理由,但是此示例即使没有它也可以正常工作。
答案4
这是另一个答案。无需测试很多东西,在决定是否开始内联或显示数学后,$
s 就会被吞噬。
\documentclass{scrartcl}
\usepackage{fixltx2e}
\usepackage{mathtools}
\makeatletter
\catcode`\$=\active
\protected\def${\new@ifnextchar$\staats@dmath\staats@math}
\def\staats@math#1${\(#1\)}
\def\staats@dmath$#1$${\[#1\]}
\makeatother
\begin{document}
Some math $x^2$
and a little more
$$ x^2 $$$x^2$$24$
\begin{figure}[h]
\rule{2cm}{2cm}
\caption{$x^2 +1$}
\end{figure}
\end{document}