\defclass{PdfLatex}

This task allows one to automate the PDF documentation generation.
It uses pdf\LaTeX{} to convert the \LaTeX{} documentation into
PDF.  To avoid errors when using the \LaTeX{} {\tt hyperref}
package, all {\tt .aux} files are first deleted.  The pdf\LaTeX{}
program is then called one time to make an initial run.
BIB\TeX{} is called to generate to bibliography file, then
pdf\LaTeX{} is called two more times to fix references
and table of contents.  It always runs pdf\LaTeX{} in
\emph{nonstop} interaction mode, preventing it from
blocking on errors.  It is therefore recommended to sometimes
run pdf\LaTeX{} manually to ensure that all documentation
is free from syntax errors.
This seems a lot of work, but it is necessary to get a fully-automated
documentation building system.

\paragraph{Supported attributes.}
This task supports only one attribute.

\noindent
{\tt latexfile}

\begin{tab}
This gives the name of the file to be converted.
\end{tab}

\paragraph{Example.}

As an example, this is the command used to produce
the PDF file for the {\tt util} package.

\begin{verbatim}
   <pdflatex latexfile="src/umontreal/iro/lecuyer/util/guideutil.tex"/>
\end{verbatim}

\bigskip\hrule\bigskip

\begin{code}
package umontreal.iro.lecuyer.tcode;\begin{hide}

import org.apache.tools.ant.util.*;
import org.apache.tools.ant.*;
import org.apache.tools.ant.taskdefs.Execute;
import org.apache.tools.ant.taskdefs.Delete;
import org.apache.tools.ant.taskdefs.LogStreamHandler;
import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.types.FileList;
import org.apache.tools.ant.types.FileSet;
import java.util.Enumeration;
import java.util.Vector;
import java.io.IOException;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.File;\end{hide}

public class PdfLatex extends Task\begin{hide} {
   private File latexFile;\end{hide}

   public File getLatexfile()\begin{hide} {
      return latexFile;
   }\end{hide}
\end{code}
\begin{tabb}  Returns the name of the \LaTeX{} file to be processed.
\end{tabb}
\begin{code}

   public void setLatexfile (File latexFile)\begin{hide} {
      this.latexFile = latexFile;
   }\end{hide}
\end{code}
\begin{tabb} Sets the name of the \LaTeX{} file to be processed.
\end{tabb}
\begin{code}

   public void execute() throws BuildException\begin{hide} {
      if (latexFile == null)
         throw new BuildException ("No LaTeX file given", getLocation());
      if (!latexFile.exists())
         throw new BuildException ("Given LaTeX file " + latexFile.getAbsoluteFile() +
                                   " does not exist", getLocation());
      boolean mustrebuild = false;
      GlobPatternMapper m = new GlobPatternMapper();
      m.setFrom ("*.tex");
      m.setTo ("*.pdf");
      File pdfFile = new File (latexFile.getParentFile(), m.mapFileName (latexFile.getName())[0]);
      if (latexFile.lastModified() > pdfFile.lastModified())
         mustrebuild = true;
      // Open the LaTeX file and check for \include's.
      // If one \include'd file is more recent than the PDf,
      // we rebuild the PDF.
      final String INCCMD = "\\include";
      try {
         BufferedReader mainin = new BufferedReader (new FileReader (latexFile));
         String li = null;
         while ((li = mainin.readLine()) != null && !mustrebuild) {
            String incarg = null;
            int idx = li.indexOf ('%');
            if (idx != -1)
               // Strip off TeX comments
               li = li.substring (0, idx);
            
            idx = li.indexOf (INCCMD);
            // Have an include command been found?
            // Is it \include or something else, like \includex?
            if (idx != -1 && !Character.isLetter (li.charAt (idx+INCCMD.length()))) {
               for (idx = idx + INCCMD.length();
                     idx < li.length() && Character.isWhitespace (li.charAt (idx)); idx++);
               if (idx == li.length())
                  log ("Could not find argument to \\include command", Project.MSG_WARN);
               if (li.charAt (idx) == '{') {
                  int idx2 = idx + 1;
                  for (; idx2 < li.length() && li.charAt (idx2) != '}'; idx2++);
                  if (idx2 == li.length())
                     log ("Could not find matching brace for \\include command", Project.MSG_WARN);
                  else
                     incarg = li.substring (idx+1, idx2).trim();
               }
               else
                  incarg = li.substring (idx,idx+1);
            }

            // If an argument to include command could be found,
            // locate the included file and check the date.
            if (incarg != null) {
               File texFile = new File (latexFile.getParentFile(), incarg + ".tex");
               if (!texFile.exists())
                  log ("The included file " + texFile.getAbsolutePath() + " could not be found",
                     Project.MSG_WARN);
               else if (texFile.lastModified() > pdfFile.lastModified())
                  mustrebuild = true;
            }
         }
         mainin.close();
      }
      catch (IOException e) {
         throw new BuildException ("Cannot open the input LaTeX file",
           e, getLocation());
      }

      if (!mustrebuild)
         return;

      Execute exe = new Execute
         (new LogStreamHandler
          (this, Project.MSG_VERBOSE, Project.MSG_WARN));
      exe.setAntRun (getProject());
      exe.setWorkingDirectory (latexFile.getParentFile());
      Delete del = new Delete();
      del.setDir (latexFile.getParentFile());
      del.setIncludes ("*.aux");
      for (int i = 0; i < 3; i++) {
         if (i == 0)
            log ("Initial run of pdfLaTeX on " + latexFile.getAbsoluteFile());
         else if (i == 1)
            log ("Reference updating run of pdfLaTeX on " + latexFile.getAbsoluteFile());
         else
            log ("Updating toc run of pdfLaTeX on " + latexFile.getAbsoluteFile());
         Commandline cmd = new Commandline();
         cmd.setExecutable ("pdflatex");
         cmd.createArgument().setValue ("-interaction");
         cmd.createArgument().setValue ("nonstopmode");
         cmd.createArgument().setFile (latexFile);
         exe.setCommandline (cmd.getCommandline());
         try {
            exe.execute();
         }
         catch (IOException e) {
            throw new BuildException ("Error executing pdfLaTeX", e, getLocation());
         }
         if (exe.getExitValue() != 0)
            throw new BuildException ("Could not execute pdfLaTeX", getLocation());

         if (i == 0) {
            log ("Running bibTeX on " + latexFile.getAbsoluteFile());
            cmd = new Commandline();
            cmd.setExecutable ("bibtex");
            m.setTo ("*");
            cmd.createArgument().setFile
               (new File (latexFile.getParentFile(), m.mapFileName (latexFile.getName())[0]));
            exe.setCommandline (cmd.getCommandline());
            try {
               exe.execute();
            }
            catch (IOException e) {
               throw new BuildException ("Error executing bibTeX", e, getLocation());
            }
            if (exe.getExitValue() != 0)
               log ("Could not execute bibTeX");
         }
      }
   }
}\end{hide}
\end{code}
\begin{tabb}   Executes the task.
\end{tabb}