6

I am using the animate package and have the pdf files to animate in a separate folder. I need to input the number for the first and last file, but am occasionally changing the number of files I would like to animate. Is there any way to have LaTex automatically count the number of files in the folder?

Here is some example code that hopefully better explains what I am after

\documentclass{article}
\usepackage{animate}
%
\begin{document}
\animategraphics[controls]{1}{./pdfFolder/fileName_}{1}{numFiles}
\end{document} 

I would like LaTex to automatically update "numFiles" depending on the number of files in "pdfFolder".

Thank you in advance for your help!

  • 1
    Perhaps with bashful and a tiny shell script? – user31729 Mar 1 '17 at 19:25
9

Pure LaTeX: (fileName_1.pdf ... fileName_?.pdf)

\documentclass{article}
\usepackage{animate}
\usepackage{graphicx}

\newcounter{NumFiles}
%\setcounter{NumFiles}{-1} % fileName_0.pdf ... fileName_?.pdf

\newboolean{stop}
\whiledo{\NOT\boolean{stop}}{
  \stepcounter{NumFiles}
  \IfFileExists{./pdfFolder/fileName_\theNumFiles.pdf}{}{
    \addtocounter{NumFiles}{-1}
    \setboolean{stop}{true}
  }
}

\begin{document}
  \animategraphics[controls]{1}{./pdfFolder/fileName_}{1}{\theNumFiles}
\end{document}
5

Here is an approach with basic Unix commands and \write18{}, listing the contents first and using the wc -l command, saving the output into dummyvar.tex and reading that file to the \numFiles macro.

Of course, the shell-script should be much more failsafe, i.e. store it in a separate file, say countmyfiles.sh and source that file within \write18{source countmyfiles.sh} rather.

\documentclass{article}

\usepackage{animate}


\def\numFiles{-1}

\newread\numfileshandle
\begin{document}
\write18{rm -f dummyvar.tex ; ls -l pdfFolder/fileName_* | wc -l > ./dummyvar.tex}
\immediate\openin\numfileshandle=dummyvar.tex
\read\numfileshandle to \numFiles
\immediate\closein\numfileshandle

There are \numFiles Files

%\animategraphics[controls]{1}{./pdfFolder/fileName_}{1}{\numFiles}
\end{document} 

A test with 20 dummy files within my dummy folder pdfFolder yields 20 as output.

  • Don’t forget that you can avoid using a temporary file by having recourse to the “piped input” feature: see, for example, this, this, and this answer of mine. (Sorry for quoting my own answers, but it’s simply the easiest thing for me, since I don’t have to study someone else’s code… ;-) – GuM Mar 1 '17 at 23:16
1

Christian has declined my suggestion about using the piped input feature, but I still think it may be interesting to show how it could be used in this case. Note how the argument of the \countfiles macro is pre-processed in order to permit the use of “special” characters, like _ and balanced occurences of { and }, while, at the same time, allowing macros (or, more generally, expandable control sequences) to be expanded, as it is shown below for \myDirName and \jobname.

% My standard header for TeX.SX answers:
\documentclass[a4paper]{article} % To avoid confusion, let us explicitly 
                                 % declare the paper format.

\usepackage[T1]{fontenc}         % Not always necessary, but recommended.
% End of standard header.  What follows pertains to the problem at hand.

\newcounter{numberOfFiles}

\makeatletter

% Beware: "special" characters like "_" that appear in the directory name must
% be either re-"\catcode"d or "\detokenize"d: the latter method is **much**
% simpler than the former, but it does **not** cope with filenames containing
% the "%" character, or unbalanced "{" and "}" characters, and in addition it
% requires e-TeX extensions (not at all a concern, these days!).
\newcommand*{\countfiles}[1]{%
    \begingroup
        \protected@edef\@tempa{#1}% before detokenizing, expand expandable (and 
                                  % unprotected) tokens
        % We use "\@inputcheck" for the temporary input pipe:
        \openin\@inputcheck "|ls -1 % the last character is the digit "one"
                \expandafter\detokenize\expandafter{\@tempa} % space meant
                |wc -l% the last character is the letter "ell"
                "\relax % without the "\relax", the ensuing "\ifeof" would be 
                        % prematurely expanded
        \ifeof\@inputcheck
            % An error message could be triggered here.
            \typeout{WARNING: Could not read \protect\numFiles!}%
        \else
            \endlinechar \m@ne % cf. exercise 20.18
            \readline\@inputcheck to\@tempa
            \setcounter{numberOfFiles}{\@tempa}%
        \fi
        \closein\@inputcheck % note: no "\immediate" needed for "\closein"
    \endgroup
}

\makeatother

\newcommand*{\myDirName}{some_directory}



\begin{document}

\setcounter{numberOfFiles}{-1}\countfiles{\myDirName}
There are \arabic{numberOfFiles} files in the specified directory.

\bigbreak

\setcounter{numberOfFiles}{-1}
In the current directory there are:
\begin{tabbing}
    \quad 999\=\kill
    \countfiles{\jobname.*}\>\arabic{numberOfFiles}\'
            file(s) whose basename is \texttt{\jobname};\\
    \countfiles{*.{tex,log}}\>\arabic{numberOfFiles}\'
            file(s) whose extension is either \texttt{.tex} or \texttt{.log};\\
    \countfiles{[A-Za-z]*.tex}\>\arabic{numberOfFiles}\'
            file(s) whose name consists only of letters, followed by the 
            extension \texttt{.tex}.
\end{tabbing}
That's all, folks!

\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.