5

everyone, I've found a very strange behavior of latex \iffalse with \newcommand\NAT@parse... inside of it (\NAT@parse taken directly from natbib). If I add that macro in style, then latex breaks with "! Too many }'s."

for example I'll create a style temp.sty:

\iffalse
  \newcommand\NAT@parse[1]{%
    \begingroup
     \let\protect=\@unexpandable@protect
     \let~\relax
     \let\active@prefix=\@gobble
     \edef\NAT@temp{\csname b@#1\@extra@b@citeb\endcsname}%
     \aftergroup\NAT@split
     \expandafter
    \endgroup
    \NAT@temp{}{}{}{}{}@@%
    \expandafter\NAT@parse@date\NAT@date??????@@%
    \ifciteindex\NAT@index\fi
  }%
\fi

\endinput

And load it in sample.tex:

\documentclass{article}
\usepackage{temp}
\begin{document}
nothing
\end{document}

\iffalse should ignore everything till \fi, but it breaks. Can somebody explain why it happens?

  • Because \ifciteindex is not yet defined as a conditional when the code is processed, so TeX skips over it and uses the next \fi to match \iffalse. This leaves }\fi outside any conditional. – egreg Mar 4 '15 at 13:29
  • @egreg Looks like an answer to me! – Joseph Wright Mar 4 '15 at 13:32
  • Thanks a lot. It's a great answer. Long time a go I had such an issue. And I'll remember that it was because of undefined \if. Now I didn't noticed that. – Linuxss Mar 4 '15 at 13:41
  • I don't know "latex tokens reader", I know only "TeX tokens reader". So the title of this thread may make confusion. – wipet Mar 9 '15 at 8:29
4

Just naming a token \ifciteindex doesn't make it into a conditional. Only

\let\ifciteindex\iftrue

or

\let\ifciteindex\iffalse

guarantees this.

So in your code, \ifciteindex is skipped over as any other non conditional token and the immediately following \fi matches the initial \iffalse. This leaves an unbalanced } and also a \fi.

Fix. Add

\@ifundefined{ifciteindex}
  {\expandafter\let\csname ifciteindex\expandafter\endcsname\csname iffalse\endcsname}
  {}

before the first \iffalse.

| improve this answer | |
  • \@ifundefined{ifciteindex} {\newif\ifciteindex} {} and then \if....\ifciteindex..\fi...\fi – Linuxss Mar 4 '15 at 13:49
  • @Linuxss This will break if \ifciteindex is defined as a conditional (because you load natbib before temp, for instance). ;-) – egreg Mar 4 '15 at 13:51
  • I can't argue. I agree – Linuxss Mar 4 '15 at 14:53
1

This is typical that a macro code has not blanced \if...\fi, so the surrounding such macro code by \iffalse...\fi is bad idea. Much better is to use \endinput before skipped macro code or simply to use \iffalse...\fi in main document, i. e.

\iffalse \usepackage{temp}\fi

or more simple:

%\usepackage{temp}
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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