24

Is it possible put TeX into a "mute" mode in which all typesetting is suppressed?

\documentclass{article}
\pagestyle{empty}
\begin{document}
  \suppress
  This text will not be seen in the generated document.
  \enable
  But this text will.
  \suppress
  And this text won't again.
\end{document}

The input should be processed "as usual" (maintaining counters, etc.), just without outputting anything.

EDIT: The current application is the creation of a document, in PDF format, that contains only the figures contained in a given source. However, in the end I'm interested if it's possible to mute output in a generic fashion, just the way I asked. If I wanted just to solve the problem, I would simply open the PDF in Acrobat and extract the figures.

8
  • I once had the same question. I tried a comment environment, but unfortunately it didn't work inside document environment.
    – Thanos
    Feb 8, 2013 at 13:08
  • 3
    You can extract the figures directly if it's really what you want. This seems a bit like an XY problem to me...
    – yo'
    Feb 8, 2013 at 13:09
  • 3
    You can do it with the endfloat package, which writes out a file with extension .fff that contains the figure environments. If you don't number the figures by section, this should be enough. Please, try to better specify your aim.
    – egreg
    Feb 8, 2013 at 13:12
  • Deferred writes (the ones used for labels, for instance) require the page where they are to be shipped out. This is a big limitation for the "generic" problem.
    – egreg
    Feb 8, 2013 at 13:37
  • 1
    The answers to the following question might solve your problem: How to replace a large block of text by an empty block of the same size? (possible duplicate Feb 8, 2013 at 13:42

5 Answers 5

12

Taking inspiration from syntonly.sty:

\documentclass{article}
\makeatletter
\font\dummyft@=dummy \relax
\def\suppress{%
  \begingroup\par
  \parskip\z@
  \offinterlineskip
  \baselineskip=\z@skip
  \lineskip=\z@skip
  \lineskiplimit=\maxdimen
  \dummyft@
  \count@\sixt@@n
  \loop\ifnum\count@ >\z@
    \advance\count@\m@ne
    \textfont\count@\dummyft@
    \scriptfont\count@\dummyft@
    \scriptscriptfont\count@\dummyft@
  \repeat
  \let\selectfont\relax
  \let\mathversion\@gobble
  \let\getanddefine@fonts\@gobbletwo
  \tracinglostchars\z@
  \frenchspacing
  \hbadness\@M}
\def\endsuppress{\par\endgroup}
\makeatother

\begin{document}
Some text.
\suppress
This text \emph{will} not be seen in the generated document.
\endsuppress
But this text will.
\suppress
And this text won't again.
\endsuppress
This will show.
\end{document}

However rules, radical bars, fraction bars and some other things (mostly math) can escape.

1
  • Ah, yes, maths! I totally forgot about maths!
    – morbusg
    Feb 8, 2013 at 14:16
11
+50

One idea that occured to me was to use \nullfont:

\documentclass{article}
\long\def\suppress#1\endsuppress{%
  \begingroup%
    \tracinglostchars=0%
    \let\selectfont=\nullfont
    \nullfont #1\endgroup}
\pagestyle{empty}
\begin{document}
  \suppress
  This text will not be seen in the generated document.
  \endsuppress
  But this text will.
  \suppress
  And this text won't again.
  \endsuppress
\end{document}

Super-Caveats

  1. Maths are not hidden
  2. I don’t know LaTeX well enough to tell if I’m doing something really silly in the above.
7
  • 1
    haha just a few seconds late :)
    – percusse
    Feb 8, 2013 at 13:55
  • @percuße: Ouch, I know the feeling; I’m sorry O:-). But feel free to improve this answer!
    – morbusg
    Feb 8, 2013 at 13:57
  • 2
    At least add \tracinglostchars=0 in order not to fill the log file with Missing character messages.
    – egreg
    Feb 8, 2013 at 14:49
  • Nope much better than what I intended.
    – percusse
    Feb 8, 2013 at 14:51
  • 1
    @tohecz: absolutely! I just love to delete lines of code! Thanks! :-D
    – morbusg
    Feb 8, 2013 at 20:08
1

The comment package should do what you want:

...
\comment
This text will not be seen
\endcomment
But this text will!
...
1
  • 3
    Will the commented text be processed (counters, macro definitions, ...)?
    – krlmlr
    Mar 22, 2013 at 10:41
1

A different solution just for the figure problems.

Here's the main file, where some additions to endfloat are made; let's assume it's called main.tex:

\documentclass{book}
\usepackage{endfloat,etoolbox}
\makeatletter
\pretocmd{\@chapter}{\efloat@iwrite{fff}{\noexpand\fakestepcounter{chapter}}}{}{}
\AtBeginDocument{
  \efloat@openpost{fff}
  \efloat@iwrite{fff}{\noexpand\fakesetcounter{chapter}{0}}
}
\let\fakestepcounter\stepcounter
\let\fakesetcounter\setcounter
\makeatother

\begin{document}

\mainmatter
\chapter{A}
\section{SA1}

aaa

\begin{figure}
\caption{abc}\label{abc}
\end{figure}

aaa

\section{SA2}

aaa

\begin{figure}
\caption{def}\label{def}
\end{figure}

aaa

\chapter{B}
\section{SA1}

aaa

\begin{figure}
\caption{ghi}\label{ghi}
\end{figure}

aaa

\section{SA2}

aaa

\begin{figure}
\caption{jkl}\label{jkl}
\end{figure}

aaa

\end{document}

Now the auxiliary file, say doonlyfigures.tex

\documentclass{article}
\usepackage{xr,refcount,environ}

\externaldocument{main}

\makeatletter
\let\latexfigure\figure
\let\latexendfigure\endfigure
\let\figure\relax
\let\endfigure\relax
\NewEnviron{figure}{%
  \vbox{
    \def\label##1{\xdef\thefigure{\getrefnumber{##1}}}
    \def\caption{\@dblarg\fake@caption}
    \BODY
  }
  \let\label\@gobble
  \latexfigure
  \BODY
  \latexendfigure}
\def\fake@caption[#1]#2{}
\let\efloatseparator\relax
\let\fakesetcounter\@gobbletwo
\let\fakestepcounter\@gobble
\makeatother

\begin{document}
\input{main.fff}
\end{document}

Similar adjustments to main.tex should be made for supporting tables as well.

1

This answer does not answer the question perfectly because not all input is processed as usual, which is what most of the other answers focus on. However, it seems that none of the other answers is perfectly satisfying either, mentioning that in some cases (like math mode) they can not guarantee to suppress the output. This answer takes a different approach, compromising on processing everything as usual but guaranteeing that all undesired output is suppressed.

This approach ignores everything between two macros which is not explicitly excluded. I am not expanding not-excluded macros so if an excluded macro is hidden inside of a not-excluded macro it will not be executed.


I am looking ahead with \futurelet. If the next token is the end token (\enable, as you called it) I do nothing. Otherwise I gobble the next token and call \suppress again, which again checks and gobbles tokens until reaching \enable:

\documentclass{article}

\newcommand{\suppress}{\futurelet\nexttoken\doSuppress}

\newcommand{\doSuppress}{%
    \ifx \nexttoken \enable
        \let\do=\relax
    \else
        \let\do=\suppress
    \fi
    \GobbleOneTokenAndCall \do
}

% I am not using \expandafter\do\@gobble because that may cause trouble if
% the next token has catcode 1 (begin group), 2 (end group) or 10 (space).
\newcommand{\GobbleOneTokenAndCall}[1]{%
    \afterassignment#1%
    % The space after the equals is important if you want to gobble a space.
    % Without it the next token after the space would be gobbled, too.
    \let\gobbledToken= %
}

% The end token.
% This won't be expanded but the replacement text should be unique.
\newcommand*{\enable}{\PackageError{suppress}{\string\enable\space without \string\suppress}{}}


\begin{document}
    \suppress
    This text will not be seen in the generated document.
    \enable

    But this text will.
\end{document}

It is easy to extend this code to not suppress certain commands like \end{document} and \begin{figure}.

The following code does not suppress the content of the figure environment, independent of whether it is after a \suppress or not. Consequently the counter for figures is increased as usual. Other counters, like the section counter, are not implemented to be increased if a \section command is \suppressed.

\documentclass{article}

% Suppress code
% =============
\usepackage{etoolbox}

\newcommand{\suppress}{\futurelet\nexttoken\doSuppress}

\newcommand{\doSuppress}{%
    \ifx \nexttoken \enable
        \let\do=\relax
    \else\ifx \nexttoken \begin
        \let\do=\suppressCheckBegin
    \else\ifx \nexttoken \end
        \let\do=\suppressCheckEnd
    \else
        \let\do=\suppress
    \fi \fi \fi
    \GobbleOneTokenAndCall \do
}

\newcommand{\suppressCheckBegin}[1]{% #1: environment name
    \def\envName{#1}%
    \ifx \envName \envNameFigure
        \def\do{\beginAndSuppressAfterEnd{#1}}%
    \else
        \let\do=\suppress
    \fi
    \do
}

\newcommand{\beginAndSuppressAfterEnd}[1]{%
    \begin{#1}%
    \csappto{end#1}{\endgroup\suppress}%
}

\newcommand{\suppressCheckEnd}[1]{% #1: environment name
    \def\envName{#1}%
    \ifx \envName \envNameDocument
        \def\do{\end{document}}%
    \else
        \let\do=\suppress
    \fi
    \do
}

% Note the star, which means that this macro is not \long.
% Without this \ifx would always evaluate to false
% because it would compare a \long to a not \long macro.
\newcommand*{\envNameDocument}{document}
\newcommand*{\envNameFigure}{figure}

% I am not using \expandafter\do\@gobble because that may cause trouble if
% the next token has catcode 1 (begin group), 2 (end group) or 10 (space).
\newcommand{\GobbleOneTokenAndCall}[1]{%
    \afterassignment#1%
    % The space after the equals is important if you want to gobble a space.
    % Without it the next token after the space would be gobbled, too.
    \let\gobbledToken= %
}

% The end token.
% This won't be expanded but the replacement text should be unique.
\newcommand*{\enable}{\PackageError{suppress}{\string\enable\space without \string\suppress}{}}


% Test document
% =============
\usepackage{float}
\floatplacement{figure}{htbp}

% see https://www.ctan.org/pkg/latex2e-help-texinfo, section 5.6 "Floats"
\setcounter{topnumber}{10}
\setcounter{bottomnumber}{10}
\setcounter{totalnumber}{10}

\begin{document}
    \suppress
    suppressed~1.1

    \begin{figure}
        \centering
        ABC
        \caption{An example}
        \label{fig:abc}
    \end{figure}

    suppressed~1.2

    \enable

    \emph{not} suppressed~1.1

    \begin{figure}
        \centering
        DEF
        \caption{Another example}
        \label{fig:def}
    \end{figure}

    \emph{not} suppressed~1.2

    \suppress
    suppressed~2.1

    \begin{minipage}{.5\linewidth}
        Environments are not a problem.
    \end{minipage}

    suppressed~2.2

    \begin{figure}
        \centering
        GHI
        \caption{Yet another example}
        \label{fig:ghi}
    \end{figure}

    suppressed~2.3

\end{document}
2
  • The question says “The input should be processed "as usual" (maintaining counters, etc.)” — does this fit? Jul 14, 2019 at 17:39
  • @ShreevatsaR good point. I think I should have made that more explicit. Please see my updated answer.
    – jakun
    Jul 14, 2019 at 18:41

This site is temporarily in read-only mode and not accepting new answers.

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