4

I have a file 0012 in the directory of the following tex file. I want to check the existence or non-existence of files inside the \forloop from 11 to 13.

\documentclass{article}
\usepackage{numprint}
\newcounter{ct} 
\newcommand{\fileno}{\npfourdigitnosep\nplpadding{4}\numprint{\arabic{ct}}}
\usepackage{forloop}
\setlength\parindent{0pt}
\begin{document}
    \forloop{ct}{11}{\value{ct} < 14} { 
        % \IfFileExists{0012} {
        \IfFileExists{\fileno} {
           fileno: "\fileno{}" exists! \\
        } {       
           fileno: "\fileno{}" doesn't exist! \\
        }
    }    
\end{document}

I get this compile error:

! Incomplete \iffalse; all text was ignored after line 15.
<inserted text>
                \fi

I have no compiler error if I switch to

\IfFileExists{0012} 

which produces this output:

fileno: ”0011” exists!
fileno: ”0012” exists!
fileno: ”0013” exists!

How can I check the existence of files with my \fileno macro?

I want this output:

fileno: ”0011” doesn't exist!
fileno: ”0012” exists!
fileno: ”0013” doesn't exist!
5

The problem is that \IfFileExists expects something that expands to a string of characters, the file name. However the macros in numprint can't safely expand to just strings because they do assignments and so on. You could do the settings (I suppose they are settings) \npfourdigitnosep\nplpadding{4} outside of \IfFileExists, but then \numprint itself isn't expandable, so you'd have to figure out a way to store the printed number and only then pass it to \IfFileExists. Too much work :-)

With xparse and a few expl3 funcions you can make \fileno safely expandable :D

I made the \fileno macro take an optional argument, then a mandatory argument. The optional argument is the width of the number to print. If no optional argument is given, the default is 4. The mandatory argument is the actual number to be printed.

I took the liberty to create a \forloop macro with expl3 as well. You can use the one from the forloop package here, it wasn't causing the problem. The new \forloop macro has the syntax: \forloop{<first>}[<step>]{<last>}{<code>}, where <first> and <last> are the beginning and end of the loop, <step> is the increment (the default is 1), and the <code> is arbitrary TeX code to be executed at each iteration of the loop. Inside the <code> the current value of the loop counter is available as #1.

Creating two sample files 0011 and 0013 the output is:

enter image description here

Code:

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand \fileno { O{4} m }
  { \exp_args:Nf \kopi_leading_zeros:nn { \int_eval:n {#2} } {#1} }
\cs_new:Npn \kopi_leading_zeros:nn #1 #2
  { \prg_replicate:nn { #2 - \str_count:n {#1} } { 0 } \int_eval:n {#1} }
\NewDocumentCommand \forloop { m O{1} m m }
  { \int_step_inline:nnnn {#1} {#2} {#3} {#4} }
\ExplSyntaxOff

% Dummy files
\begin{filecontents}{0011}
blub
\end{filecontents}
\begin{filecontents}{0013}
zzzz
\end{filecontents}

\setlength\parindent{0pt}
\begin{document}
\forloop{11}{13}{%
  \IfFileExists {\fileno{#1}} {%
    fileno: ``\fileno{#1}'' exists! \\
  } {%
    fileno: ``\fileno{#1}'' doesn't exist! \\
  }%
}
\end{document}

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.