23

The package comment.sty allows one to typeset

\begin{comment}
stuff that will be suppressed from output file
\end{comment}

or

\begin{myCustomEnv}
stuff that will be suppressed from output file
\end{myCustomEnv}

One can even suppress the contents of already defined environments, for instance {proof}.

In this spirit, I would like to suppress everything that is in math mode, whatever the way it starts: $, \(, $$, \begin{displaymath}, etc. The output should be as if the contents of everything that is in math mode was not in the source file.

Can this be done?

6
  • 1
    A script in python or perl or awk could preprocess the TeX source and remove all math. You'd have to be a little careful to detect escaped $ signs inside math mode. Commented Jan 6, 2013 at 18:16
  • 3
    @EthanBolker yes, but that would change the input; it sounds like the OP only wants to change the output with the flick of a switch in the preamble
    – cmhughes
    Commented Jan 6, 2013 at 18:59
  • @cmhughes The script output would go to nomath.tex for subsequent compilation, leaving the original input document whole. I'll upvote a wizardly answer that uses just TeX in the preamble. Commented Jan 6, 2013 at 21:45
  • 1
    How do you want to treat text material that appears in a math mode environment? Commented Jan 7, 2013 at 12:23
  • 1
    @jrouquie Why do you need this ?
    – projetmbc
    Commented Nov 27, 2020 at 12:34

4 Answers 4

19

There are a few very different ways to enter and to exit math mode:

  1. TeX math shift character, catcode 3, typically $
  2. LaTeX macros \(<math>\) and \[<math>\]
  3. LaTeX environments math and displaymath
  4. amsmath environments
  5. Not directly in the source: macros that were defined with the original catcode of $ cannot be hidden with the described methods.

1. TeX math shift

An easy redefintion of $ (catcode 13, active) solves this.

\catcode`$=\active
\makeatletter
\def${%                        % TeX math shift (not anymore)
    \@ifnextchar${\killB}{\killA}%
}
\makeatother
\def\killA#1${\ignorespaces}   % TeX inline math
\def\killB$#1$${\ignorespaces} % TeX display math

The macro \killA kills inline math ($<math>$) with removing any spaces that comes after the last $. Without \ignorespaces, something like Text $ f(x) $ text would be typset as Text␣␣text. (This would be disallowed by “The output should be as if the contents of everything that is in math mode was not in the source file.”)

2. LaTeX macros \(<math>\) and \[<math>\]

A TeX re-definition of those macros suffice:

\def\(#1\){\ignorespaces} % LaTeX inline math
\def\[#1\]{\ignorespaces} % LaTeX display math

Without the white-space problem (see above), the following would work too:

\let\[\iffalse
\let\]\fi
\let\(\iffalse
\let\)\fi

3. LaTeX environments math and displaymath

The LaTeX environments math and displaymath use internally $ and \[ and \], but the solutions above do not work here (they do more harm instead).

But with the help of the environ package we can simply redefine those environments:

\def\killMe#1{%                % for math environments
    \expandafter\let\csname #1\endcsname\relax
    \expandafter\let\csname end#1\endcsname\relax
    \NewEnviron{#1}{}%
    }

\killMe{displaymath}
\killMe{math}

The first two lines of the \killMe macro let \<environment> and \end<environment> to \relax so that \NewEnviron thinks they aren’t already defined. \NewEnviron automatically inserts a \ignorespaces in the \end part of the environment.

4. amsmath environments

The amsmath package provides a few environments that are “silenced” in the same way with the \killMe macro. For example:

\killMe{align}
\killMe{align*}

Code

\documentclass{article}
\usepackage{amsmath}
\usepackage{environ}

\def\killMe#1{%                      for math environments
    \expandafter\let\csname #1\endcsname\relax
    \expandafter\let\csname end#1\endcsname\relax
    \NewEnviron{#1}{}%
}

    \def\(#1\){\ignorespaces}%        LaTeX inline math
    \def\[#1\]{\ignorespaces}%        LaTeX display math

%   \let\[\iffalse
%   \let\]\fi
%   \let\(\iffalse
%   \let\)\fi

    \catcode`$=\active
    \makeatletter
    \def${%                            TeX math shift
        \@ifnextchar${\killB}{\killA}%
    }%
    \makeatother
    \def\killA#1${\ignorespaces}%     TeX inline math
    \def\killB$#1$${\ignorespaces}%   TeX display math

    \killMe{align}%
    \killMe{align*}%
    \killMe{displaymath}%              displaymath relies on \[ and \] and cannot live
    %                                  without the right definition of \[ and \]
    \killMe{math}%      %              math relies on $ as math shift character and would work
    %                                  although $ is active and redefined


\begin{document}
H%
$ i^n TeX $
e%
\( i^n LaTeX \)
l%
$$ o^ut TeX $$
l%
\[ o^ut LaTeX \]
o
\begin{align}
 f(x) & = x^2
\end{align}
W%
\begin{align*}
 f(x) & = x^2
\end{align*}
o%
\begin{displaymath}
 f(x) = x^2 (displaymath)
\end{displaymath}
r%
\begin{math}
    2^3 (math)
\end{math}
ld!

Text $ f(x) $ text
\end{document}

Output

enter image description here

2
  • In more complicated documents (e.g., if I use pgfplots) I get parameter stack overflow with the catcode definition. I fixed it by changing \@ifnextchar${\killB}{\killA}% to simply \killA but I assume there is a feature I am missing the original author intended.
    – ZaydH
    Commented Jan 10, 2022 at 15:48
  • @ZaydH I am pretty sure the point of the \@ifnextchar is so that it can handle displaymath that is delimited by $$ ... $$. Commented Mar 18 at 4:01
16

I would also suggest to go for some external solution that drops the math material from the file and writes a new one. One reason for it is that LaTeX internally uses math in many places which are not obvious at all (and not necessarily real math) the \LaTeXe logo for example.

Anyway just for the fun of it here is a solution within LaTeX (totally unsupported and not necessarily complete, perhaps one has to disable much more):

\documentclass{article}

\makeatletter
\def\nomath{%
\font\dummyft@=dummy \relax
   \count@\sixt@@n
   \loop
    \ifnum\count@ >\z@
     \advance\count@\m@ne
     \global\textfont\count@\dummyft@
     \global\scriptfont\count@\dummyft@
     \global\scriptscriptfont\count@\dummyft@
    \repeat
   \global\let\mathversion\@gobble
   \frozen@everymath={}
   \frozen@everydisplay={}
  \let\boldmath\relax
  \let\unboldmath\relax
  \let\mv@normal\@empty
  \let\mv@bold\@empty
}
\makeatother

\begin{document}
test1: $x$

test2:
\[ a=b\]

test3: \LaTeX{} and $a=b$ but see:  \LaTeXe

\begin{itemize} \item test4 $a=b$ \end{itemize}

test5:  \parbox[c]{1cm}{now what? $a=b$}

\bigskip

\nomath \ldots{} and again \ldots

test1: $x$

test2:
\[ a=b\]

test3: \LaTeX{} and $a=b$ but see:  \LaTeXe

\begin{itemize} \item test4 $a=b$ \end{itemize}

test5:  \parbox[c]{1cm}{now what? $a=b$}
\end{document}

But for the sample document it seems to do suppress all math successfully (more or less). Note, that I did really nasty stuff like changing \frozen@everymath, which is frozen for a reason, but there you go.

Also note the deficiencies in the resulting output:

enter image description here

3

(I know that the OP has said in the comments that they no longer need this, but it has found its way back to the front page of the site and I missed it first time round.)

Some time ago I wrote a program for grepping through maths bits in a LaTeX document. It's not perfect, but it goes a bit beyond a simple script.

You can find it (and its limitations) at https://github.com/loopspace/mathgrep

2

Here's an easy way to create math-free output from a LaTeX file by stripping all math code from that file. Don't forget to keep an unchanged copy of the original file!

Edit the LaTeX file using the replacement function with Regular Expressions in an editor such as Kate. The Regular Expression

\$((.|\n)(?!\$))*(.|\n)\$

finds inline math but compensates for greed, that is, it leaves the words and and implies untouched in the LaTeX code

$x=y$ and $y=z$ implies $x=z$.

(In other editors, the simpler Regular Expression \$.+?\$ may work.)

To find other math environments like equation*, just replace the first \$ with \\begin\{equation\*\}, and the second and third \$ with \\end\{equation\*\}.

5
  • 1
    Hmm, did the OP ask about how to suppress the output of all math material, or how to delete all math material from the *input file”?
    – Mico
    Commented Nov 27, 2020 at 11:41
  • Well, no one said that the original input file should be discarded. As soon as there is a math-free output, one forgets the edited input file.
    – user117833
    Commented Nov 27, 2020 at 12:21
  • I think it would be prudent to mention explicitly that if someone were to engage in a destructive edit along the lines suggested in your answer, they should save a copy of the unmodified tex file first. This may be blindingly obvious to many, but I suspect it's not obvious to everybody.
    – Mico
    Commented Nov 27, 2020 at 14:30
  • Regular expressions cannot correctly match nested delimiters such as \[ ... \] and \( ... \).
    – Davislor
    Commented Nov 28, 2020 at 8:27
  • It seems to me that there is no need to find nested delimiters here.
    – user117833
    Commented Dec 4, 2020 at 15:09

You must log in to answer this question.

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