# A dangerous \if@ in the dtx preamble

Why does the following .dtx not compile, while the equivalent .tex file does? (You must name the file error.dtx, that's what \DocInput includes.)

DTX:

% \iffalse meta-comment
%<*driver>
\documentclass{ltxdoc}
\input pgfutil-common
\makeatletter
\def\myitem#1{%
\pgfutil@in@{,}{#1}%
\ifpgfutil@in@
\myitem@#1\@end
\else
\myitem@#1,\@end
\fi
}
\makeatother
\begin{document}
\DocInput{error.dtx}
\end{document}
%</driver>
% \fi
% \begin{description}
%   \myitem{align,key} This is documentation for key \emph{align}.
% \end{description}
% \endinput


LaTeX:

\documentclass{ltxdoc}
\input pgfutil-common
\makeatletter
\def\myitem#1{%
\pgfutil@in@{,}{#1}%
\ifpgfutil@in@
\myitem@#1\@end
\else
\myitem@#1,\@end
\fi
}
\makeatother
\begin{document}
\begin{description}
\myitem{align,key} This is documentation for key \emph{align}.
\end{description}
\end{document}

-

The diagnosis that this is due to \else is correct. An alternative approach to solving it is to put the new code in the Docstrip 'document' part. To do that, the comment characters in the definition will need to be converted to ^^A

% \iffalse meta-comment
%<*driver>
\documentclass{ltxdoc}
\input pgfutil-common %
\begin{document}
\DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%\makeatletter
%\def\myitem#1{^^A
%  \pgfutil@in@{,}{#1}^^A
%  \ifpgfutil@in@
%    \myitem@#1\@end
%  \else
%    \myitem@#1,\@end
%  \fi
%}
%\makeatother
% \show\myitem
% \begin{description}
%   \myitem{align,key} This is documentation for key \emph{align}.
% \end{description}
% \endinput

-

When the document is processed the second time (being inputted by \DocInput), TeX finds \iffalse at the top of the file. The intention is that this \iffalse will match the \fi following the comment sign, thereby skipping over the preamble. But it doesn't. It gets stuck at \else in the definition of \myitem.

Normally, \ifpgfutil@in@ is safe to use in nested conditionals, so why does this happen?

The answer is that TeX finds no \ifpgfutil@in@ on the second pass, since the catcode of @ is other, not letter --- \makeatletter was skipped over by the very \iffalse that got stuck on \ifpgfutil@in@'s \else...

A quick&dirty solution is to provide a commented \if that will only be visible to TeX on the second pass:

% \iffalse meta-comment
%<*driver>
\documentclass{ltxdoc}
\input pgfutil-common
\makeatletter
\def\myitem#1{%
\pgfutil@in@{,}{#1}%
\ifpgfutil@in@          %\if
\myitem@#1\@end
\else
\myitem@#1,\@end
\fi
}
\makeatother
\begin{document}
\DocInput{error.dtx}
\end{document}
%</driver>
% \fi
% \begin{description}
%   \myitem{align,key} This is documentation for key \emph{align}.
% \end{description}
% \endinput


Or, maybe even better, to put all the potentially offending code in a separate file...

-