4

I already searched for comparable questions, but found none with this problem.

I have the following LaTeX formatting section to define inline and multiline comments that can be "in-commented" at one stroke by replacing iffalse with iftrue:

\providecommand{\comment}[1]{}
\let\commentstart=\iffalse
\let\commentend=\fi
\iffalse
\renewcommand{\comment}[1]{#1}
%\let\commentstart=\iftrue
\fi

However, I had to outcomment the line that sets commentstart to iftrue because otherwise it produces the following error:

pdflatex.exe> ! Incomplete \iffalse; all text was ignored after line 12.
pdflatex.exe> <inserted text> 
pdflatex.exe>                 \fi 
pdflatex.exe> <*> document.tex
pdflatex.exe>                 
pdflatex.exe> ! Emergency stop.
pdflatex.exe> <*> document.tex
pdflatex.exe>                 
pdflatex.exe> !  ==> Fatal error occurred, no output PDF file produced!
pdflatex.exe> Transcript written on document.log.

From this error I assume that the line claims the next \fi for itself. However, I thought \let should suppress that? Or is the \iftrue processed earlier than the \let? Are there any ways to establish the expected behavior?

Here is the full Texlipse console output:

running: C:\texlive\2015\bin\win32\pdflatex.exe -synctex=1 -interaction=nonstopmode --src-specials document.tex 
pdflatex.exe> This is pdfTeX, Version 3.14159265-2.6-1.40.16 (TeX Live 2015/W32TeX) (preloaded format=pdflatex)
pdflatex.exe>  restricted \write18 enabled.
pdflatex.exe>  Source specials enabled.
pdflatex.exe> entering extended mode
pdflatex.exe> (./document.tex
pdflatex.exe> LaTeX2e <2016/03/31>
pdflatex.exe> Babel <3.9q> and hyphenation patterns for 81 language(s) loaded.
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/latex/koma-script/scrreprt.cls
pdflatex.exe> Document Class: scrreprt 2015/10/03 v3.19a KOMA-Script document class (report)
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/latex/koma-script/scrkbase.sty
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/latex/koma-script/scrbase.sty
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/latex/graphics/keyval.sty)
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/latex/koma-script/scrlfile.sty
pdflatex.exe> Package scrlfile, 2015/10/03 v3.19a KOMA-Script package (loading files)
pdflatex.exe>                   Copyright (C) Markus Kohm
pdflatex.exe> 
pdflatex.exe> ))) (c:/texlive/2015/texmf-dist/tex/latex/koma-script/tocbasic.sty)
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/latex/koma-script/scrsize11pt.clo)
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/latex/koma-script/typearea.sty
pdflatex.exe> Package typearea, 2015/10/03 v3.19a KOMA-Script package (type area)
pdflatex.exe>                   Copyright (C) Frank Neukam, 1992-1994
pdflatex.exe>                   Copyright (C) Markus Kohm, 1994-
pdflatex.exe> 
pdflatex.exe> )) (c:/texlive/2015/texmf-dist/tex/latex/base/fontenc.sty
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/latex/base/t1enc.def))
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/latex/base/inputenc.sty
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/latex/base/utf8.def
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/latex/base/t1enc.dfu)
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/latex/base/ot1enc.dfu)
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/latex/base/omsenc.dfu)))
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/generic/babel/babel.sty
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/generic/babel-german/ngerman.ldf
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/generic/babel-german/ngermanb.ldf
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/generic/babel/babel.def))))
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/latex/graphics/graphicx.sty
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/latex/graphics/graphics.sty
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/latex/graphics/trig.sty)
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/latex/latexconfig/graphics.cfg)
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/latex/pdftex-def/pdftex.def
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/generic/oberdiek/infwarerr.sty)
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/generic/oberdiek/ltxcmds.sty))))
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/latex/geometry/geometry.sty
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/generic/oberdiek/ifpdf.sty)
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/generic/oberdiek/ifvtex.sty)
pdflatex.exe> (c:/texlive/2015/texmf-dist/tex/generic/ifxetex/ifxetex.sty)))
pdflatex.exe> ! Incomplete \iffalse; all text was ignored after line 12.
pdflatex.exe> <inserted text> 
pdflatex.exe>                 \fi 
pdflatex.exe> <*> document.tex
pdflatex.exe>                 
pdflatex.exe> ! Emergency stop.
pdflatex.exe> <*> document.tex
pdflatex.exe>                 
pdflatex.exe> !  ==> Fatal error occurred, no output PDF file produced!
pdflatex.exe> Transcript written on document.log.
1
  • Since it's \iffalse what's inside is not processed at all; however, conditionals in TeX, keep track of \if..\fi pairs inside of them (which lets you do \iffalse \ifnum1=1 foo\fi \fi with no problem). But only conditionals, TeX is not aware of the rest of tokens, so \let\commentstart=\iftrue is exactly the same as \foo\bar!\iftrue (the only one that actually understands is the \iftrue) hence it doesn't have any way of knowing.
    – Manuel
    Commented May 20, 2016 at 9:46

2 Answers 2

4

Conditionals keep track only of certain tokens (als conditionals) which lets you have many of them inside others (my English is not fluent today). Easy solution: add \fi in any way you can to balance the \if..\fis.

\providecommand*\comment[1]{}
\let\commentstart=\iffalse
\let\commentend=\fi
\iffalse
\renewcommand\comment[1]{#1}
\let\commentstart=\iftrue
\let\commentend=\fi
\fi
8
  • Ah yeah, thanks. That's typical of performance-focused processing. Personally I'd like it better if LaTeX first processed it, then threw away everything that's no actual conditional. That would cause less bugs.
    – Egor Hans
    Commented May 20, 2016 at 12:05
  • 2
    The skipping process using conditionals scans not only real \fi, \if etc. but the control sequences with the meaning of these primitives too. So your example between \iffalse and \fi says: \iffalse \r \c [1]{#1}\l\iffalse=\iftrue \l\fi=\fi \fi
    – wipet
    Commented May 20, 2016 at 12:31
  • @EgorHans It isn't about performance: often it isn't possible to process the code in the non-taken branch, for example it might contain undefined commands. Commented May 20, 2016 at 13:52
  • @wipet Oh, completely true. It just works in this case because they are exactly paired.
    – Manuel
    Commented May 20, 2016 at 14:23
  • 1
    @EgorHans If you want a more LaTeX-approach to conditionals, take a look at booleans and toggles in etoolbox package. And for this specific problem, there are a few packages, for instance comment package.
    – Manuel
    Commented May 20, 2016 at 14:51
4

It's very simple: when TeX skips over tokens in the “false branch” of a conditional, it still keeps track of conditionals. So the \iftrue in the “false branch” needs a matching \fi, which TeX finds in the one you wanted to match the initial \iffalse. So the false branch is not yet finished and TeX basically gobbles everything until finding \else or \fi.

The most common trick is to hide the conditional in a macro.

\newcommand{\comment}[1]{} % not \providecommand
\let\commentstart=\iffalse
\let\commentend=\fi
\newcommand{\setcommentstarttrue}{\let\commentstart\iftrue}
\iffalse
\renewcommand{\comment}[1]{#1}
\setcommentstarttrue
\fi

But you probably want to do this in a different way.

\newcommand{\comment}[1]{}
\makeatletter
\let\commentend=\fi
\newcommand{\showcomments}{%
  \let\commentstart\iftrue
  \let\comment\@firstofone
}
\newcommand{\hidecomments}{%
  \let\commentstart\iffalse
  \let\comment\@gobble
}
\makeatother
\hidecomments % can be \showcomments
1
  • thanks but I like Manuel's solution better (still upvoted though)
    – Egor Hans
    Commented May 20, 2016 at 14:41

You must log in to answer this question.

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