9

I am trying to set things up so that occurrences of $$ are replaced by \] if in math mode, \[ otherwise. My strategy is to make $ active and have it behave differently depending on whether the following token is also a $. However, I cannot seem to make this work. Here is my attempt:

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

The resulting error is

./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!

Other variations (e.g., substituting \ifx for \if) give different errors or simply incorrect output, but nothing gets it right. And as far as I can tell, the key problem is that my method for determining whether the following token is a $ (and absorbing it if so) simply does not work.

What am I doing wrong, and how can I fix it?

Additional note: An answer that throws an error whenever $$ is used instead of other macros/environments (which must be able to use it internally) would also be acceptable, since it answers the titular question.

10
  • Motivation: In a document class I'm writing, direct use of $$ changes the interline spacing of all subsequent text. So it's a much worse practice than usual. Jul 30, 2014 at 18:21
  • 7
    Just never use $$. That's how.
    – egreg
    Jul 30, 2014 at 18:21
  • 1
    looks a bit like Can I redefine the dollar
    – cgnieder
    Jul 30, 2014 at 18:29
  • 2
    @CharlesStaats just fail their thesis if they use $$:-) But if $$ affects spacing opf following text do you redefine equation and eqnarray etc which just expand to $$ ? Jul 30, 2014 at 20:18
  • 2
    I'm usually mean to the users and include \usepackage[all]{onlyamsmath} in my templates. Then $$ and eqnarray cause errors. Hard, but effective.
    – daleif
    Jul 31, 2014 at 11:06

4 Answers 4

6

You should use \ifx and not \if, that just compares character codes and does full expansion.

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

Of course input such as

It follows that $E = m c^2$$\forall x \in X$.

which will produce weird errors, which might be cured with an \ifinner test.

Here's a similar version that does the check for a legal (albeit disputable) $$:

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

I fear that there are several things that can make this go wrong. The best is simply insisting that $$ should never be used. Physical coercion might be fruitful. ;-)

1
  • Lovely, but wouldn't \usepackage[l2tabu]{nag} be simpler? Jul 30, 2014 at 22:41
6

I believe the easiest way, though fairly draconian, is to place

\RequirePackage[l2tabu,orthodox]{nag}

in your document class, or

\usepackage[l2tabu,orthodox]{nag}

in whatever auxiliary package you may be providing.

This will teach your users many things to be avoided, including $$...$$.

2

Based on this answer by egreg, together with the \new@nextchar macro from the amsmath package, I have an answer that seems to work, at least for this example:

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

Question: Why is the definition of $ protected? I copied this behavior because I assume there's a good reason for it, but this example works fine without it.

2
  • It's protected because \new@ifnextchar is not expandable, I guess. Also \@DDollar is not expandable. Place the unprotected version in an \edef and see what's happens...
    – cgnieder
    Jul 30, 2014 at 19:39
  • 1
    It needs to be protected otherwise it'll go very wrong at the start of table cells, or if you go \caption{ foo $x$} or ... Jul 30, 2014 at 20:20
0

Here it is another answer. Instead of testing many things, after deciding if it starts inline or display math the $s are gobbled.

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .