Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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.

share|improve this question
    
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. –  Charles Staats Jul 30 at 18:21
7  
Just never use $$. That's how. –  egreg Jul 30 at 18:21
1  
looks a bit like Can I redefine the dollar –  cgnieder Jul 30 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 $$ ? –  David Carlisle Jul 30 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 at 11:06

4 Answers 4

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. ;-)

share|improve this answer
    
Lovely, but wouldn't \usepackage[l2tabu]{nag} be simpler? –  Brent.Longborough Jul 30 at 22:41

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 $$...$$.

share|improve this answer

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.

share|improve this answer
    
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 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 ... –  David Carlisle Jul 30 at 20:20

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}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.