Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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
}
\def\myitem@#1,#2\@end{\item\texttt{#1}\quad\marginpar{\small\it#2}}
\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
}
\def\myitem@#1,#2\@end{\item\texttt{#1}\quad\marginpar{\small\it#2}}
\makeatother
\begin{document}
  \begin{description}
    \myitem{align,key} This is documentation for key \emph{align}.
  \end{description}
\end{document}
share|improve this question
add comment

2 Answers

up vote 5 down vote accepted

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
%}
%\def\myitem@#1,#2\@end{\item\texttt{#1}\quad\marginpar{\small\it#2}}
%\makeatother
% \show\myitem
% \begin{description}
%   \myitem{align,key} This is documentation for key \emph{align}.
% \end{description}
% \endinput
share|improve this answer
add comment

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
}
\def\myitem@#1,#2\@end{\item\texttt{#1}\quad\marginpar{\small\it#2}}
\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...

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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