# Nomenclature definition in hidden places?

This question is related to a previous question of mine Increasing nesting level for parameters and global xparse macros?

I use a modified version of \defsym as given by egreg in this answer to the second question above. However I have the problem that the nomenclature definition fails on occasions, so some symbols are missing. For a MWE check egreg's answer together with the code snippets below.

I do neither understand when exactly it fails nor can I think of a solution how to fix it. It seems to happen when the first use of the symbol is invisible in some way, e.g. \phantom{\Ak} or

\begin{align}
\Uk[j]
\end{align}


The align environment seems to probe the line for the length, therefore the first use is invisible. This can be seen using a \typeout in the symbol definition which will then appear twice in the log.

Inserting one of those snippets above after \begin{document} in egreg's MWE causes the symbols to disappear from the nomenclature.

1. I'd like to understand why \nomenclature does not work e.g. in the following pointless example $\phantom{\nomenclature{$\alpha$}{Foo}}$. I don't understand why writing something to a file fails in this example.
2. Is there some systematic when it fails?
3. How to fix it? Is it possible to check if \nomenclature did successfully write the symbol to the nlo file?
-

The problem here is that the alignment environments of amsmath do two passes over the material, the first to measure it and the second for doing the real typesetting. So the code for doing the annotation and setting the conditional to false at the first appearance is evaluated during the measurement, but the boxes thus created are simply thrown away.

The problem with \phantom is similar: the typeset box is thrown away and the \write instruction can't "migrate" in a vertical list for being performed at the right time. Simply don't put such commands, for the first time, in a \phantom.

For the amsmath environments, we have to interface with the measuring process.

\documentclass{article}
\usepackage{xparse}
\usepackage{nomencl}
\usepackage{xcolor}

\usepackage{amsmath}

\makeatletter
\def\buergi@ifmeasuring#1#2{%
\ifmeasuring@
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi{#1}{#2}}
\makeatother

% colorize to distinguish original and renewed command
\ExplSyntaxOn
% #1 = command name
% #2 = definition
% #3 = default optional argument
% #4 = description
\NewDocumentCommand{\defsym}{mmmm}
{
\bool_new:c { g_buergi_sym_ \cs_to_str:N #1 _bool }
\bool_gset_false:c { g_buergi_sym_ \cs_to_str:N #1 _bool }
\buergi_defsym:nnnn { #1 } { #2 } { #3 } { #4 }
}
\cs_new_protected:Npn \buergi_defsym:nnnn #1 #2 #3 #4
{
\NewDocumentCommand{#1}{O{#3}}
{
\buergi_ifmeasuring:nn
{ #2 }
{
\bool_if:cTF  { g_buergi_sym_ \cs_to_str:N #1 _bool }
{ \textcolor{blue}{#2} }
{
\textcolor{red}{#2}
\nomenclature{$#1$}{#4}
\bool_gset_true:c { g_buergi_sym_ \cs_to_str:N #1 _bool }
}
}
}
}
\cs_set_eq:Nc \buergi_ifmeasuring:nn { buergi@ifmeasuring }
\ExplSyntaxOff

\defsym\Uk{U_{#1}}{k}{Some variable}
\defsym\Ak{A(#1)}{k}{Another}
\defsym\Bk{B(#1)}{k}{Test}

\makenomenclature

\begin{document}
\noindent $\Uk[j]$, $\Uk$, $\Uk[p]$, $\Uk[q]$ and $\Uk[r]$

\noindent $\Ak$, $\Ak[n]$

\begin{align}
\Bk[j]
\end{align}

\printnomenclature
\end{document}


-
again great answer egreg. It does not fully answer my question as it does not explain why it does not work, but it got me on the right track, all answers are on page 227 of the TeXbook. The \write commands will be performed only on shipout. Now my question: is it possible to also set the flag a whatsit object so that it only gets set when the write did actually take places, something like \write16{\bool_gset_true:c { g_buergi_sym_ \cs_to_str:N #1 _bool }}. The later does not work like that due to missing expansion, I tried some \expandafter but had no luck so far. –  buergi Nov 19 '12 at 8:25
@buergi Do you really need those commands in \phantom? :) –  egreg Nov 19 '12 at 10:08
no, that was just an example. Your fix for amsmath environments is perfect. It was just pondering if there is a more general way, but the hack with the \write can't work e.g. for symbols in the same math environment, so just forget it. However, if you can imagine a more general solution, let me know but your's is sufficient for my needs. Thanks again. –  buergi Nov 19 '12 at 10:45