Let's say I have a value stored in my aux using the csname syntax.

Aux Contains

\expandafter\gdef \csname inputsectioncount@en-US\endcsname{0}

This is correct, because I have not added any sections within the context "en-US".


\ifnum <number stored in aux> > 3\relax \tableofcontents\else Sorry, not enough sections to warrant a contents table.\fi


I tried different techniques to expand the \csname macro twice before \ifnum processes it.

\usepackage{fontspec}% xelatex
\newcounter{inputsectioncount}% latex counter, equiv of \global\newcount\inputsectioncounter\inputsectioncounter=0

% Add aux write hook

  \setcounter{inputsectioncount}{0}% reset inputsectioncounter
  \def\contextid{en-US}% set context id (just a suffix to differentiate contexts)
  Hello, I just simulated inputting some file within a context. Afterwhich, I'd like to know how many sections I just added.   
  \immediate\write\@mainaux{\string\expandafter\gdef\noexpand\csname inputsectioncount@\contextid\string\endcsname{\the\c@   inputsectioncount}}%
% Above code writes \expandafter\gdef \csname inputsectioncount@en-US\endcsname{0} to aux
% Now we can use this on next run

\newcommand\inputcontents{% Add contents lists if requirements are met (more than 3 sections within a context)
%  \expandafter\let\expandafter\expandafter\expandafter\reserved@a\csname inputsectioncount@\ithlanguage\endcsname
%  \expandafter\ifnum\reserved@a>3\relax Here should be tableofcontents\fi
%  \expandafter\ifnum\csname inputsectioncount@\ithlanguage\endcsname>3\relax\tableofcontents\fi



  • 2
    \ifnum 3<0\csname inputsectioncount@en-US\endcsname\relax should work (also on a run when the csname is not yet defined.
    – egreg
    Nov 6 '17 at 10:26
  • @egreg It does. Why does that work? This seems counter-intuitive to me. Nov 6 '17 at 10:32
  • why shouldn't it work? (what does your intuition suggest should happen?) \csname inputsectioncount@en-US\endcsname expands to \inputsectioncount@en-US which expands to 0 so this is \ifnum 3<00\relax Nov 6 '17 at 11:14
  • @DavidCarlisle I mean 1. humans read left to right (so the order is backwards from thought) 2. \ifnum 3<00\relax is what I would expect. If \inputsectioncount@en-US expanded to 32, I would expect \ifnum 3<032 (I suppose leading zeros are ignored? I'd like to know) 4. Why does the double expansion of \csname suddenly work? Was the problem not caused by number of expansions? It looks like the problem was due to the csname macro not existing. Could I have solved it with an \@ifundefined or \ifx<csmacro><somesurelyunsusedname>? Nov 6 '17 at 11:23
  • \ifnum expands an arbitrary number of times until it finds something that is a <number> to TeX, so it doesn't matter how many expansions it takes to make the number. If \inputsectioncount@en-US expanded to 32, I would expect \ifnum 3<032 yes exactly that's what happens. (and 032 is the same as 32) Nov 6 '17 at 11:44

You can write the test as

\ifnum 3<0\csname inputsectioncount@en-US\endcsname\relax

Why this way and not the apparently more obvious

\ifnum \csname inputsectioncount@en-US\endcsname>3\relax

that ought to work? Actually, the second way will fail when the annotation in the .aux file has not yet been read (for instance, the .aux file did not exist at the beginning of the job, which is the case for the first run). It doesn't work, because if the macro resulting from \csname hasn't yet a definition it becomes \relax and


is illegal.

With the first code, instead, this doesn't happen: the initial zero has been added in order to cope with the case the macro hasn't yet a definition. In this case we'd obtain


If, say, the annotation in the .aux file defines the macro to hold the value 42, then the test would become, after macro expansion


and initial zeros are ignored in number specifications.

Note that the tokens after \ifnum are fully expanded until finding tokens that make sense for \ifnum, so \csname gets expanded and also the macro resulting from it (if not made equal to \relax).

  • 1
    Note that the variable csname is intentional. i.e.en-US must be replacable-the replacement value held by \contextid. Outside the realm of this question, I have many context ids. Good explanation! Nov 6 '17 at 12:54

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.