#include "TDocDirective.h"

#include "TApplication.h"
#include "TClass.h"
#include "TDocInfo.h"
#include "TDocOutput.h"
#include "TDocParser.h"
#include "TError.h"
#include "THtml.h"
#include "TInterpreter.h"
#include "TLatex.h"
#include "TMacro.h"
#include "TObjString.h"
#include "TPRegexp.h"
#include "TROOT.h"
#include "TStyle.h"
#include "TSystem.h"
#include "TVirtualPad.h"
#include "TVirtualMutex.h"
#include <typeinfo>
#include <fstream>
#include <sstream>
#include <stdlib.h>

//______________________________________________________________________________
//
// When THtml parses documentation (through TDocParser), it checks for special
// words ("begin_something", "end_something", where the begin and end are the
// significant part). THtml then searches for a TDocDirective which can handle
// these tags ("whatever" in the example), passes the text enclosed by these
// tags to the directive, which in turn processes it.
//
// That way, HTML, latex, and C++ macros can be processed by THtml, e.g. to
// generate plain HTML or GIF pictures. The classes reposinsible for parsing
// that are TDocHtmlDirective, TDocLatexDirective, and TDocMacroDirective,
// respecively.
//
// Directives can have optional parameters; these are passed as paranthesis
// enclosed, comma delimited name=value pairs; see SetParameters().
//
// You can implement your own directive simply by deriving from TDocDirective;
// the tag corresponds to TDocDirective's name (e.g. "HTML" for "begin_html" /
// "end_html").
//______________________________________________________________________________

ClassImp(TDocDirective);

//______________________________________________________________________________
void TDocDirective::DeleteOutputFiles(const char* ext) const
{
   // Delete all output generated by the directive beginning
   // with Name() and ending with ext
   TString basename;
   GetName(basename);
   basename += "_";
   TString dirname(GetOutputDir());
   void* hDir = gSystem->OpenDirectory(dirname);
   const char* entry = 0;
   while ((entry = gSystem->GetDirEntry(hDir))) {
      TString sEntry(entry);
      if (sEntry.BeginsWith(basename) && isdigit(sEntry[basename.Length()]) && (!ext || sEntry.EndsWith(ext)))
         gSystem->Unlink((dirname + "/" + entry).Data());
   }
   gSystem->FreeDirectory(hDir);
}

//______________________________________________________________________________
void TDocDirective::GetName(TString& name) const
{
   // Get the full name, based on fName, fTitle, fDocParser's tag.

   name = fName;
   if (fDocParser && fDocParser->GetCurrentClass()) {
      name += "_";
      TString outfilename;
      GetHtml()->GetHtmlFileName(fDocParser->GetCurrentClass(), outfilename);
      outfilename = gSystem->BaseName(outfilename);
      Ssiz_t posExt = outfilename.Last('.');
      outfilename.Remove(posExt, outfilename.Length() - posExt);
      name += outfilename;
   }
   if (GetTitle() && strlen(GetTitle())) {
      name += "_";
      name += GetTitle();
   }
   if (fCounter != -1) {
      name += "_";
      name += fCounter;
   }
}

//______________________________________________________________________________
const char* TDocDirective::GetOutputDir() const
{
   // Get the directory for documentation output.

   return fHtml ? fHtml->GetOutputDir().Data() : 0;
}

//______________________________________________________________________________
void TDocDirective::SetParameters(const char* params)
{
   // Given a string containing parameters in params,
   // we call AddParameter() for each of them.
   // This function splits the parameter names and
   // extracts their values if they are given.
   // Parameters are separated by ",", values are
   // separated from parameter names by "=".
   // params being
   //    a = "a, b, c", b='d,e'
   // will issue two calls to AddParameter(), one for
   // a with value "a, b, c" and one for b with value
   // "d,e" (each without the quotation marks).

   fParameters = params;

   if (!fParameters.Length())
      return;

   TString param;
   Ssiz_t pos = 0;
   while (fParameters.Tokenize(param, pos, ",")) {
      param = param.Strip(TString::kBoth);
      if (!param.Length())
         continue;

      Ssiz_t posAssign = param.Index('=');
      if (posAssign != kNPOS) {
         TString value(param(posAssign + 1, param.Length()));
         value = value.Strip(TString::kBoth);
         if (value[0] == '\'')
            value = value.Strip(TString::kBoth, '\'');
         else if (value[0] == '"')
            value = value.Strip(TString::kBoth, '"');
         param.Remove(posAssign, param.Length());
         param = param.Strip(TString::kBoth);
         AddParameter(param, value);
      } else {
         param = param.Strip(TString::kBoth);
         AddParameter(param, 0);
      }
   }
}

//______________________________________________________________________________
void TDocDirective::SetParser(TDocParser* parser)
{
   // Set the parser, and fDocOutput, fHtml from that
   fDocParser    = parser;
   fDocOutput = parser ? parser->GetDocOutput() : 0;
   fHtml      = fDocOutput? fDocOutput->GetHtml() : 0;
}


//______________________________________________________________________________
//
// Process a "begin_html" / "end_html" block. Stop linking keywords and simply
// copy the text enclosed by the directive to the output HTML file.
//______________________________________________________________________________

ClassImp(TDocHtmlDirective);

//______________________________________________________________________________
void TDocHtmlDirective::AddLine(const TSubString& line)
{
   // Add a line of HTML

   if (line.Start() == -1) return;

   TPRegexp pretag("</?[pP][rR][eE][ >]");
   TSubString iLine(line);
   Ssiz_t posPre = iLine.String().Index(pretag, iLine.Start());
   if (posPre == kNPOS)
      fText += line;
   else {
      // remove <pre> in fVerbatim environments, and
      // </pre> in !fVerbatim environments.
      while (posPre != kNPOS && posPre > 0) {
         Bool_t isOpen = line[posPre + 1 - line.Start()] != '/';
         Ssiz_t posClose = iLine.String().Index(">", posPre);
         if (posClose ==kNPOS) break; // aka oops.
         Ssiz_t len = posClose - posPre;

         if (fVerbatim) {
            if (isOpen) {
               // skip
               fText += iLine.String()(iLine.Start(), posPre - iLine.Start());
            } else {
               // write it out
               fText += iLine.String()(iLine.Start(), posPre + len - iLine.Start());
               fVerbatim = kFALSE;
            }
         } else {
            if (!isOpen) {
               // skip
               fText += iLine.String()(iLine.Start(), posPre - iLine.Start());
            } else {
               // write it out
               fText += iLine.String()(iLine.Start(), posPre + len - iLine.Start());
               fVerbatim = kTRUE;
            }
         }

         iLine = iLine.String()(posPre + len, iLine.Length());
         posPre = iLine.String().Index(pretag, iLine.Start());
      }

      fText += iLine;
   }
   fText += "\n";
}

//______________________________________________________________________________
Bool_t TDocHtmlDirective::GetResult(TString& result)
{
   // Set result to the HTML code that was passed in via AddLine().
   // Prepend a closing </pre>, append an opening <pre>

   result = "</pre><!-- TDocHtmlDirective start -->";
   result += fText + "<!-- TDocHtmlDirective end --><pre>";
   return kTRUE;
}



//______________________________________________________________________________
//
// Process a "begin_macro" / "end_macro" block. The block can be a file name
// or a CINT script (i.e. even ".x file.C" is allowed). See AddParameter() for
// supported options. Example (the quotes prevent THtml from expanding the
// example):
//
// "BEGIN_MACRO"
// .x $ROOTSYS/tutorials/hsimple.C
// "END_MACRO"
//
// The macro is meant to create an object that can be saved as a GIF file by
// calling object->SaveAs(outputfile.gif). The macro is expected to return that
// object as a TObject*; if it does not, gPad is used and saved. The object
// is deleted by TDocMacroDirective once saved.
//______________________________________________________________________________

ClassImp(TDocMacroDirective);

//______________________________________________________________________________
TDocMacroDirective::~TDocMacroDirective()
{
   // Destructor
   delete fMacro;
}

//______________________________________________________________________________
void TDocMacroDirective::SubProcess(const TString& what, const TString& out) {
   Int_t error = TInterpreter::kNoError;
   Long_t ret = gROOT->ProcessLine(TString(".x ") + what, &error);
   Int_t sleepCycles = 50; // 50 = 5 seconds
   while (error == TInterpreter::kProcessing && --sleepCycles > 0)
      gSystem->Sleep(100);

   gSystem->ProcessEvents(); // in case ret needs to handle some events first

   if (error != TInterpreter::kNoError) {
      ::Error("TDocMacroDirective::HandleDirective_Macro",
              "Error processing macro for %s!", out.Data());
      return;
   }
   if (!ret) {
      return;
   }

   // Something with a vtable
   const TObject* objRet = (const TObject*)ret;
   try {
      typeid(*objRet).name(); // needed to test whether ret is indeed an object with a vtable!
      objRet = dynamic_cast<const TObject*>(objRet);
   }
   catch (...) {
      objRet = 0;
   }

   if (!objRet) {
      return;
   }

   if (gDebug > 3)
      ::Info("TDocMacroDirective::HandleDirective_Macro",
             "Saving returned %s to file %s.",
             objRet->IsA()->GetName(), out.Data());

   if (!gROOT->IsBatch()) {
      // to get X11 to sync :-( gVirtualX->Update()/Sync() don't do it
      gSystem->Sleep(1000);
      gVirtualX->Update(0);
      gVirtualX->Update(1);
   }

   gSystem->ProcessEvents();
   if (!gROOT->IsBatch()) {
      gVirtualX->Update(0);
      gVirtualX->Update(1);
   }

   objRet->SaveAs(out);
   gSystem->ProcessEvents(); // SaveAs triggers an event

#ifdef R__BEPAEPSTLICHERALSDERPAPST
   // ensure objRet is not e.g. the TGMainFrame of a new TCanvas: require padSave == gPad
   if (objRet != gPad && padSave == gPad)
      delete objRet;
   }
#endif
}

//______________________________________________________________________________
void TDocMacroDirective::AddLine(const TSubString& line)
{
   // Add a macro line.
   // Lines ending on "*HIDE*" will be executed as part of the
   // macro, but not shown in the source tab if the parameter
   // source is supplied.

   if (!fMacro) {
      TString name;
      GetName(name);
      fMacro = new TMacro(name);
   }

   // return if no line - or if there was an intentinal line-break,
   // i.e. an empty line
   if (line.Start() == -1 && const_cast<TSubString&>(line).String().Length()) return;

   TString sLine(line);
   fMacro->AddLine(sLine);
   fIsFilename &= !sLine.Contains('{');
}

//______________________________________________________________________________
TString TDocMacroDirective::CreateSubprocessInputFile() {
   // Create the input file for SubProcess().

   if (!fIsFilename) {
      TString fileSysName;
      GetName(fileSysName);
      fileSysName += ".C";
      gSystem->PrependPathName(gSystem->TempDirectory(), fileSysName);
      fMacro->SaveSource(fileSysName);
      return fileSysName;
   }

   // We have a filename; find it and build the invocation.
   TString filename;
   TIter iLine(fMacro->GetListOfLines());
   while (filename.Length() == 0)
      filename = ((TObjString*)iLine())->String().Strip(TString::kBoth);

   TString macroPath;
   TString modulename;
   if (GetHtml() && GetDocParser()) {
      if (GetDocParser()->GetCurrentClass())
         GetHtml()->GetModuleNameForClass(modulename, GetDocParser()->GetCurrentClass());
      else GetDocParser()->GetCurrentModule(modulename);
   }
   if (modulename.Length()) {
      GetHtml()->GetModuleMacroPath(modulename, macroPath);
   } else macroPath = gSystem->pwd();

   const char* pathDelimiter = ":"; // use ":" even on windows
   TObjArray* arrDirs(macroPath.Tokenize(pathDelimiter));
   TIter iDir(arrDirs);
   TObjString* osDir = 0;
   macroPath = "";
   TString filenameDirPart(gSystem->DirName(filename));
   filenameDirPart.Prepend('/'); // as dir delimiter, not as root dir
   while ((osDir = (TObjString*)iDir())) {
      if (osDir->String().EndsWith("\\"))
         osDir->String().Remove(osDir->String().Length() - 1);
      osDir->String() += filenameDirPart;
      macroPath += osDir->String() + pathDelimiter;
   }

   TString plusplus;
   while (filename.EndsWith("+")) {
      plusplus += '+';
      filename.Remove(filename.Length() - 1);
   }

   TString params;
   if (filename.EndsWith(")")) {
      Ssiz_t posOpen = filename.Last('(');
      if (posOpen != kNPOS) {
         params = filename(posOpen, filename.Length());
         filename.Remove(posOpen, filename.Length());
      }
   }

   TString fileSysName(gSystem->BaseName(filename));
   if (!gSystem->FindFile(macroPath, fileSysName)) {
      Error("GetResult", "Cannot find macro '%s' in path '%s'!",
            gSystem->BaseName(filename), macroPath.Data());
      return "";
   }
   fileSysName += params;
   fileSysName += plusplus;


   if (fShowSource) {
      // copy macro into fMacro - before running it, in case the macro blocks its file
      std::ifstream ifMacro(fileSysName);
      fMacro->GetListOfLines()->Delete();
      TString line;
      while (ifMacro) {
         if (!line.ReadLine(ifMacro, kFALSE) || ifMacro.eof())
            break;
         fMacro->AddLine(line);
      }
   }
   return fileSysName;
}

//______________________________________________________________________________
Bool_t TDocMacroDirective::GetResult(TString& result)
{
   // Get the result (i.e. an HTML img tag) for the macro invocation.
   // If fShowSource is set, a second tab will be created which shows
   // the source.

   if (!fMacro)
      return kFALSE;

   if (!fMacro->GetListOfLines()
      || !fMacro->GetListOfLines()->First()) {
      Warning("GetResult", "Empty directive found!");
      return kTRUE;
   }

   R__LOCKGUARD(GetHtml()->GetMakeClassMutex());

   if (gDebug > 3)
      Info("HandleDirective_Macro", "executing macro \"%s\" with %d lines.",
         fMacro->GetName(), fMacro->GetListOfLines() ? fMacro->GetListOfLines()->GetEntries() + 1 : 0);

   Bool_t wasBatch = gROOT->IsBatch();
   Bool_t wantBatch = kFALSE;
   if (!wasBatch && !fNeedGraphics)
      wantBatch = kTRUE;
   else if (fNeedGraphics) {
      if (fHtml->IsBatch()) {
         Warning("GetResult()", "Will not initialize the graphics system; skipping macro %s!", GetName());
         result = "";
         return kFALSE;
      }
   }

   TString outFileName;
   {
      GetName(outFileName);
      GetDocOutput()->NameSpace2FileName(outFileName);
      outFileName += ".gif";
      outFileName.ReplaceAll(" ", "_");
      gSystem->PrependPathName(GetOutputDir(), outFileName);
   }

   TString subProcInputFile = CreateSubprocessInputFile();
   if (!subProcInputFile.Length()) return kFALSE;

   subProcInputFile.ReplaceAll("\\", "\\\\");
   subProcInputFile.ReplaceAll("\"", "\\\"");
   TString invoc("root.exe -l -q ");
   if (wantBatch) {
      invoc += "-b ";
   }
   invoc += "-e 'TDocMacroDirective::SubProcess(\""
      + subProcInputFile + "\",\"" + outFileName + "\");'";
   gSystem->Unlink(outFileName);
   Int_t exitCode = gSystem->Exec(invoc.Data());

   if (exitCode && gDebug > 0) {
      Info("GetResult()", "Subprocess exited with status %d\n", exitCode);
   } else if (!fIsFilename) {
      // we have created the input file.
      gSystem->Unlink(subProcInputFile);
   }

   if (!gSystem->AccessPathName(outFileName)) {
      // Output file was created
      result = "<span class=\"macro\"><img class=\"macro\" alt=\"output of ";
      result += outFileName;

      result += "\" title=\"MACRO\" src=\"";
      result += gSystem->BaseName(outFileName);
      result += "\" /></span>";
   }

   if (fShowSource) {
      // convert the macro source
      TIter iLine(fMacro->GetListOfLines());
      TObjString* osLine = 0;
      std::stringstream ssRaw;
      while ((osLine = (TObjString*)iLine()))
         ssRaw << osLine->String() << std::endl;

      TDocParser *dparser = 0;
      if (GetDocParser()->GetCurrentClass())
         dparser = new TDocParser(*(TClassDocOutput*)GetDocOutput(), GetDocParser()->GetCurrentClass());
      else dparser = new TDocParser(*GetDocOutput());
      std::stringstream ssConverted;
      dparser->Convert(ssConverted, ssRaw, "./", kTRUE /*code*/, kFALSE /*process directives*/);
      delete dparser;

      fMacro->GetListOfLines()->Delete();
      TString line;
      while (!ssConverted.fail()) {
         if (!line.ReadLine(ssConverted, kFALSE) || ssConverted.eof())
            break;
         fMacro->AddLine(line);
      }

      TString id(gSystem->BaseName(outFileName));
      id = id(0, id.Length()-4); // remove ".gif"
      // TODO: we need an accessible version of the source, i.e. visible w/o javascript
      TString tags("</pre><div class=\"tabs\">\n"
               "<a id=\"" + id + "_A0\" class=\"tabsel\" href=\"" + gSystem->BaseName(outFileName) + "\" onclick=\"javascript:return SetDiv('" + id + "',0);\">Picture</a>\n"
               "<a id=\"" + id + "_A1\" class=\"tab\" href=\"#\" onclick=\"javascript:return SetDiv('" + id + "',1);\">Source</a>\n"
               "<br /></div><div class=\"tabcontent\">\n"
               "<div id=\"" + id + "_0\" class=\"tabvisible\">" + result + "</div>\n"
               "<div id=\"" + id + "_1\" class=\"tabhidden\"><div class=\"listing\"><pre class=\"code\">");
      iLine.Reset();
      osLine = 0;
      while ((osLine = (TObjString*) iLine()))
         if (!TString(osLine->String().Strip()).EndsWith("*HIDE*"))
            tags += osLine->String() + "\n";
      if (tags.EndsWith("\n"))
         tags.Remove(tags.Length()-1); // trailing line break
      tags += "</pre></div></div><div class=\"clear\"></div></div><pre>";
      result = tags;
      // Protect the nested comments from being stripped by a
      // TDocParser::ProcessComment() in the call stack.
      result.ReplaceAll("<span class=\"comment\">", "<span class=\"codecomment\">");
   }

   return kTRUE;
}

//______________________________________________________________________________
void TDocMacroDirective::AddParameter(const TString& name, const char* /*value=0*/)
{
   // Setting fNeedGraphics if name is "GUI",
   // setting fShowSource if name is "SOURCE"

   if (!name.CompareTo("gui", TString::kIgnoreCase))
      fNeedGraphics = kTRUE;
   else if (!name.CompareTo("source", TString::kIgnoreCase))
      fShowSource = kTRUE;
   else Warning("AddParameter", "Unknown option %s!", name.Data());
}



namespace {
   Float_t gLinePadding = 10.; //px
   Float_t gColumnPadding = 10.; //px

   class TLatexLine {
   private:
      std::vector<Float_t> fWidths;
      Float_t fHeight;
      TObjArray* fColumns; // of TObjString*

   public:
      TLatexLine(TObjArray* columns = 0):
         fHeight(0.), fColumns(columns) { if (columns) fWidths.resize(Size());}

      Float_t& Width(UInt_t col) {return fWidths[col];}
      Float_t& Height() {return fHeight;}
      TString* operator[](Int_t column) {
         if (fColumns && fColumns->GetEntriesFast() > column)
            return &(((TObjString*)fColumns->At(column))->String());
         return 0;
      }
      UInt_t Size() const { return fColumns ? fColumns->GetEntries() : 0; }
      void Delete() { delete fColumns; }
   };
}

//______________________________________________________________________________
//
// Handle a "Begin_Latex"/"End_Latex" directive.
// called as
// "Begin_Latex(fontsize=10, separator='=,', rseparator='=|,', align=lcl)"
// will create and include a TLatex-processed image, with a given fontsize
// in pixels (defaults to 16). If (r)separator is given, the formulas on the
// following lines will be grouped into columns; a new column starts with
// (regexp) match of the separator; by default there is only one column.
// separator matches any character, rseparator matches as regexp with one
// column per pattern match. Only one of separator or rseparator can be given.
// align defines the alignment for each columns; be default, all columns
// are right aligned. NOTE that the column separator counts as a column itself!
//______________________________________________________________________________


ClassImp(TDocLatexDirective);

//______________________________________________________________________________
TDocLatexDirective::~TDocLatexDirective()
{
   // Destructor
   gSystem->ProcessEvents();
   delete fLatex;
   delete fBBCanvas;
   gSystem->ProcessEvents();
}

//______________________________________________________________________________
void TDocLatexDirective::AddLine(const TSubString& line)
{
   // Add a latex line

   if (line.Length() == 0)
      return;

   if (!fLatex) {
      TString name;
      GetName(name);
      fLatex = new TMacro(name);
   }

   TString sLine(line);
   GetDocParser()->Strip(sLine);
   if (sLine.Length() == 0)
      return;

   fLatex->AddLine(sLine);
}

//______________________________________________________________________________
void TDocLatexDirective::CreateLatex(const char* filename)
{
   // Create a gif file named filename from a latex expression in fLatex.
   // Called when "Begin_Latex"/"End_Latex" is processed.

   if (!fLatex
      || !fLatex->GetListOfLines()
      || !fLatex->GetListOfLines()->First())
      return;

   R__LOCKGUARD(GetHtml()->GetMakeClassMutex());

   TVirtualPad* oldPad = gPad;

   Bool_t wasBatch = gROOT->IsBatch();
   if (!wasBatch)
      gROOT->SetBatch();

   const Float_t canvSize = 1200.;
   if (!fBBCanvas)
      // add magic batch vs. gui canvas sizes (4, 28)
      fBBCanvas = (TVirtualPad*)gROOT->ProcessLineFast(
         Form("new TCanvas(\"R__TDocLatexDirective_BBCanvas\",\"fBBCanvas\",%g,%g);", -(canvSize + 4.), canvSize + 28.));
   if (!fBBCanvas) {
      Error("CreateLatex", "Cannot create a TCanvas via the interpreter!");
      return;
   }
   fBBCanvas->SetBorderMode(0);
   fBBCanvas->SetFillColor(kWhite);

   gSystem->ProcessEvents();

   std::list<TLatexLine> latexLines;
   std::vector<Float_t> maxWidth(20);
   UInt_t numColumns = 0;
   Float_t totalHeight = gLinePadding;

   TLatex latex;
   latex.SetTextFont(43);
   latex.SetTextSize((Float_t)fFontSize);
   latex.SetTextAlign(12);

   // calculate positions
   TIter iterLine(fLatex->GetListOfLines());
   TObjString* line = 0;
   TPRegexp regexp;
   if (fSeparator.Length()) {
      if (fSepIsRegexp)
         regexp = TPRegexp(fSeparator);
   } else fSepIsRegexp = kFALSE;

   while ((line = (TObjString*) iterLine())) {
      const TString& str = line->String();
      TObjArray* split = 0;
      if (!fSepIsRegexp) {
         split = new TObjArray();
         split->SetOwner();
      }
      if (!fSeparator.Length())
         split->Add(new TObjString(str));
      else {
         if (fSepIsRegexp)
            split = regexp.MatchS(str);
         else {
            Ssiz_t prevStart = 0;
            for (Ssiz_t pos = 0; pos < str.Length(); ++pos) {
               if (fSeparator.Index(str[pos]) != kNPOS) {
                  split->Add(new TObjString(TString(str(prevStart, pos - prevStart))));
                  split->Add(new TObjString(TString(str(pos, 1))));
                  prevStart = pos + 1;
               }
            }
            split->Add(new TObjString(TString(str(prevStart, str.Length() - prevStart))));
         }
      }

      latexLines.push_back(TLatexLine(split));
      if (numColumns < (UInt_t)split->GetEntries())
         numColumns = split->GetEntries();

      Float_t heightLine = -1.;
      for (UInt_t col = 0; col < (UInt_t)split->GetEntries(); ++col) {
         Float_t widthLatex = 0.;
         Float_t heightLatex = 0.;
         TString* strCol = latexLines.back()[col];
         if (strCol)
            GetBoundingBox(latex, *strCol, widthLatex, heightLatex);
         if (heightLine < heightLatex)   heightLine = heightLatex;
         if (maxWidth.size() < col)
            maxWidth.resize(col * 2);
         if (maxWidth[col] < widthLatex)
            maxWidth[col] = widthLatex;
         latexLines.back().Width(col) = widthLatex;
      }
      latexLines.back().Height() = heightLine;
      totalHeight += heightLine + gLinePadding;
   } // while next line

   std::vector<Float_t> posX(numColumns + 1);
   for (UInt_t col = 0; col <= numColumns; ++col) {
      if (col == 0) posX[col] = gColumnPadding;
      else          posX[col] = posX[col - 1] + maxWidth[col - 1] + gColumnPadding;
   }
   Float_t totalWidth = posX[numColumns];

   // draw
   fBBCanvas->Clear();
   fBBCanvas->cd();
   Float_t padSizeX = totalWidth;
   Float_t padSizeY = totalHeight + 8.;
   // add magic batch vs. gui canvas sizes (4, 28) + rounding
   TVirtualPad* padImg = (TVirtualPad*)gROOT->ProcessLineFast(
      Form("new TCanvas(\"R__TDocLatexDirective_padImg\",\"padImg\",-(Int_t)%g,(Int_t)%g);",
           padSizeX + 4.5, padSizeY + 28.5));
   padImg->SetBorderMode(0);
   padImg->SetFillColor(kWhite);
   padImg->cd();

   Float_t posY = 0.;
   for (std::list<TLatexLine>::iterator iLine = latexLines.begin();
      iLine != latexLines.end(); ++iLine) {
      posY += iLine->Height()/2. + gLinePadding;
      for (UInt_t iCol = 0; iCol < iLine->Size(); ++iCol) {
         TString* str = (*iLine)[iCol];
         if (!str) continue;
         char align = 'l';
         if ((UInt_t)fAlignment.Length() > iCol)
            align = fAlignment[(Int_t)iCol];
         Float_t x = posX[iCol];
         switch (align) {
            case 'l': break;
            case 'r': x += maxWidth[iCol] - iLine->Width(iCol); break;
            case 'c': x += 0.5*(maxWidth[iCol] - iLine->Width(iCol)); break;
            default:
               if (iLine == latexLines.begin())
                  Error("CreateLatex", "Invalid alignment character '%c'!", align);
         }
         latex.DrawLatex( x / padSizeX, 1. - posY / padSizeY, str->Data());
      }
      posY += iLine->Height()/2.;
   }

   padImg->Print(filename);

   // delete the latex objects
   for (std::list<TLatexLine>::iterator iLine = latexLines.begin();
      iLine != latexLines.end(); ++iLine) {
      iLine->Delete();
   }

   delete padImg;

   if (!wasBatch)
      gROOT->SetBatch(kFALSE);

   gPad = oldPad;
}

//______________________________________________________________________________
void TDocLatexDirective::GetBoundingBox(TLatex& latex, const char* text, Float_t& width, Float_t& height)
{
   // Determines the bounding box for text as height and width.
   // Assumes that we are in batch mode.

   UInt_t uiWidth = 0;
   UInt_t uiHeight = 0;
   fBBCanvas->cd();
   latex.SetText(0.1, 0.5, text);
   latex.GetBoundingBox(uiWidth, uiHeight);

   width = uiWidth;
   height = uiHeight;
}

//______________________________________________________________________________
TList* TDocLatexDirective::GetListOfLines() const
{
   // Get the list of lines as TObjStrings
   return fLatex ? fLatex->GetListOfLines() : 0;
}

//______________________________________________________________________________
Bool_t TDocLatexDirective::GetResult(TString& result)
{
   // convert fLatex to a gif by creating a TLatex, drawing it on a
   // temporary canvas, and saving that to a filename in the output
   // directory.

   TString filename;
   GetName(filename);
   filename.ReplaceAll(" ", "_");
   const TString& firstLine = ((TObjString*)fLatex->GetListOfLines()->First())->String();
   TString latexFilename(firstLine);
   for (Ssiz_t namepos = 0; namepos < latexFilename.Length(); ++namepos)
      if (!GetDocParser()->IsWord(latexFilename[namepos])) {
         latexFilename.Remove(namepos, 1);
         --namepos;
      }
   filename += "_";
   filename += latexFilename;

   GetDocOutput()->NameSpace2FileName(filename);
   filename += ".gif";

   TString altText(firstLine);
   GetDocOutput()->ReplaceSpecialChars(altText);
   altText.ReplaceAll("\"", "&quot;");
   result = "<span class=\"latex\"><img class=\"latex\" alt=\"";
   result += altText;
   result += "\" title=\"LATEX\" src=\"";
   result += filename;
   result += "\" /></span>";

   gSystem->PrependPathName(GetOutputDir(), filename);

   if (gDebug > 3)
      Info("HandleDirective_Latex", "Writing Latex \"%s\" to file %s.",
           fLatex->GetName(), filename.Data());

   CreateLatex(filename);

   return kTRUE;
}

//______________________________________________________________________________
void TDocLatexDirective::AddParameter(const TString& name, const char* value /*=0*/)
{
   // Parse fParameters, setting fFontSize, fAlignment, and fSeparator

   if (!name.CompareTo("fontsize", TString::kIgnoreCase)) {
      if (!value || !value[0])
         Error("AddParameter", "Option \"fontsize\" needs a value!");
      else fFontSize = atol(value);
   } else if (!name.CompareTo("separator", TString::kIgnoreCase)) {
      if (!value || !value[0])
         Error("AddParameter", "Option \"separator\" needs a value!");
      else fSeparator = value;
   } else if (!name.CompareTo("align", TString::kIgnoreCase)) {
      if (!value || !value[0])
         Error("AddParameter", "Option \"align\" needs a value!");
      else fAlignment = value;
   } else
      Warning("AddParameter", "Unknown option %s!", name.Data());
}
 TDocDirective.cxx:1
 TDocDirective.cxx:2
 TDocDirective.cxx:3
 TDocDirective.cxx:4
 TDocDirective.cxx:5
 TDocDirective.cxx:6
 TDocDirective.cxx:7
 TDocDirective.cxx:8
 TDocDirective.cxx:9
 TDocDirective.cxx:10
 TDocDirective.cxx:11
 TDocDirective.cxx:12
 TDocDirective.cxx:13
 TDocDirective.cxx:14
 TDocDirective.cxx:15
 TDocDirective.cxx:16
 TDocDirective.cxx:17
 TDocDirective.cxx:18
 TDocDirective.cxx:19
 TDocDirective.cxx:20
 TDocDirective.cxx:21
 TDocDirective.cxx:22
 TDocDirective.cxx:23
 TDocDirective.cxx:24
 TDocDirective.cxx:25
 TDocDirective.cxx:26
 TDocDirective.cxx:27
 TDocDirective.cxx:28
 TDocDirective.cxx:29
 TDocDirective.cxx:30
 TDocDirective.cxx:31
 TDocDirective.cxx:32
 TDocDirective.cxx:33
 TDocDirective.cxx:34
 TDocDirective.cxx:35
 TDocDirective.cxx:36
 TDocDirective.cxx:37
 TDocDirective.cxx:38
 TDocDirective.cxx:39
 TDocDirective.cxx:40
 TDocDirective.cxx:41
 TDocDirective.cxx:42
 TDocDirective.cxx:43
 TDocDirective.cxx:44
 TDocDirective.cxx:45
 TDocDirective.cxx:46
 TDocDirective.cxx:47
 TDocDirective.cxx:48
 TDocDirective.cxx:49
 TDocDirective.cxx:50
 TDocDirective.cxx:51
 TDocDirective.cxx:52
 TDocDirective.cxx:53
 TDocDirective.cxx:54
 TDocDirective.cxx:55
 TDocDirective.cxx:56
 TDocDirective.cxx:57
 TDocDirective.cxx:58
 TDocDirective.cxx:59
 TDocDirective.cxx:60
 TDocDirective.cxx:61
 TDocDirective.cxx:62
 TDocDirective.cxx:63
 TDocDirective.cxx:64
 TDocDirective.cxx:65
 TDocDirective.cxx:66
 TDocDirective.cxx:67
 TDocDirective.cxx:68
 TDocDirective.cxx:69
 TDocDirective.cxx:70
 TDocDirective.cxx:71
 TDocDirective.cxx:72
 TDocDirective.cxx:73
 TDocDirective.cxx:74
 TDocDirective.cxx:75
 TDocDirective.cxx:76
 TDocDirective.cxx:77
 TDocDirective.cxx:78
 TDocDirective.cxx:79
 TDocDirective.cxx:80
 TDocDirective.cxx:81
 TDocDirective.cxx:82
 TDocDirective.cxx:83
 TDocDirective.cxx:84
 TDocDirective.cxx:85
 TDocDirective.cxx:86
 TDocDirective.cxx:87
 TDocDirective.cxx:88
 TDocDirective.cxx:89
 TDocDirective.cxx:90
 TDocDirective.cxx:91
 TDocDirective.cxx:92
 TDocDirective.cxx:93
 TDocDirective.cxx:94
 TDocDirective.cxx:95
 TDocDirective.cxx:96
 TDocDirective.cxx:97
 TDocDirective.cxx:98
 TDocDirective.cxx:99
 TDocDirective.cxx:100
 TDocDirective.cxx:101
 TDocDirective.cxx:102
 TDocDirective.cxx:103
 TDocDirective.cxx:104
 TDocDirective.cxx:105
 TDocDirective.cxx:106
 TDocDirective.cxx:107
 TDocDirective.cxx:108
 TDocDirective.cxx:109
 TDocDirective.cxx:110
 TDocDirective.cxx:111
 TDocDirective.cxx:112
 TDocDirective.cxx:113
 TDocDirective.cxx:114
 TDocDirective.cxx:115
 TDocDirective.cxx:116
 TDocDirective.cxx:117
 TDocDirective.cxx:118
 TDocDirective.cxx:119
 TDocDirective.cxx:120
 TDocDirective.cxx:121
 TDocDirective.cxx:122
 TDocDirective.cxx:123
 TDocDirective.cxx:124
 TDocDirective.cxx:125
 TDocDirective.cxx:126
 TDocDirective.cxx:127
 TDocDirective.cxx:128
 TDocDirective.cxx:129
 TDocDirective.cxx:130
 TDocDirective.cxx:131
 TDocDirective.cxx:132
 TDocDirective.cxx:133
 TDocDirective.cxx:134
 TDocDirective.cxx:135
 TDocDirective.cxx:136
 TDocDirective.cxx:137
 TDocDirective.cxx:138
 TDocDirective.cxx:139
 TDocDirective.cxx:140
 TDocDirective.cxx:141
 TDocDirective.cxx:142
 TDocDirective.cxx:143
 TDocDirective.cxx:144
 TDocDirective.cxx:145
 TDocDirective.cxx:146
 TDocDirective.cxx:147
 TDocDirective.cxx:148
 TDocDirective.cxx:149
 TDocDirective.cxx:150
 TDocDirective.cxx:151
 TDocDirective.cxx:152
 TDocDirective.cxx:153
 TDocDirective.cxx:154
 TDocDirective.cxx:155
 TDocDirective.cxx:156
 TDocDirective.cxx:157
 TDocDirective.cxx:158
 TDocDirective.cxx:159
 TDocDirective.cxx:160
 TDocDirective.cxx:161
 TDocDirective.cxx:162
 TDocDirective.cxx:163
 TDocDirective.cxx:164
 TDocDirective.cxx:165
 TDocDirective.cxx:166
 TDocDirective.cxx:167
 TDocDirective.cxx:168
 TDocDirective.cxx:169
 TDocDirective.cxx:170
 TDocDirective.cxx:171
 TDocDirective.cxx:172
 TDocDirective.cxx:173
 TDocDirective.cxx:174
 TDocDirective.cxx:175
 TDocDirective.cxx:176
 TDocDirective.cxx:177
 TDocDirective.cxx:178
 TDocDirective.cxx:179
 TDocDirective.cxx:180
 TDocDirective.cxx:181
 TDocDirective.cxx:182
 TDocDirective.cxx:183
 TDocDirective.cxx:184
 TDocDirective.cxx:185
 TDocDirective.cxx:186
 TDocDirective.cxx:187
 TDocDirective.cxx:188
 TDocDirective.cxx:189
 TDocDirective.cxx:190
 TDocDirective.cxx:191
 TDocDirective.cxx:192
 TDocDirective.cxx:193
 TDocDirective.cxx:194
 TDocDirective.cxx:195
 TDocDirective.cxx:196
 TDocDirective.cxx:197
 TDocDirective.cxx:198
 TDocDirective.cxx:199
 TDocDirective.cxx:200
 TDocDirective.cxx:201
 TDocDirective.cxx:202
 TDocDirective.cxx:203
 TDocDirective.cxx:204
 TDocDirective.cxx:205
 TDocDirective.cxx:206
 TDocDirective.cxx:207
 TDocDirective.cxx:208
 TDocDirective.cxx:209
 TDocDirective.cxx:210
 TDocDirective.cxx:211
 TDocDirective.cxx:212
 TDocDirective.cxx:213
 TDocDirective.cxx:214
 TDocDirective.cxx:215
 TDocDirective.cxx:216
 TDocDirective.cxx:217
 TDocDirective.cxx:218
 TDocDirective.cxx:219
 TDocDirective.cxx:220
 TDocDirective.cxx:221
 TDocDirective.cxx:222
 TDocDirective.cxx:223
 TDocDirective.cxx:224
 TDocDirective.cxx:225
 TDocDirective.cxx:226
 TDocDirective.cxx:227
 TDocDirective.cxx:228
 TDocDirective.cxx:229
 TDocDirective.cxx:230
 TDocDirective.cxx:231
 TDocDirective.cxx:232
 TDocDirective.cxx:233
 TDocDirective.cxx:234
 TDocDirective.cxx:235
 TDocDirective.cxx:236
 TDocDirective.cxx:237
 TDocDirective.cxx:238
 TDocDirective.cxx:239
 TDocDirective.cxx:240
 TDocDirective.cxx:241
 TDocDirective.cxx:242
 TDocDirective.cxx:243
 TDocDirective.cxx:244
 TDocDirective.cxx:245
 TDocDirective.cxx:246
 TDocDirective.cxx:247
 TDocDirective.cxx:248
 TDocDirective.cxx:249
 TDocDirective.cxx:250
 TDocDirective.cxx:251
 TDocDirective.cxx:252
 TDocDirective.cxx:253
 TDocDirective.cxx:254
 TDocDirective.cxx:255
 TDocDirective.cxx:256
 TDocDirective.cxx:257
 TDocDirective.cxx:258
 TDocDirective.cxx:259
 TDocDirective.cxx:260
 TDocDirective.cxx:261
 TDocDirective.cxx:262
 TDocDirective.cxx:263
 TDocDirective.cxx:264
 TDocDirective.cxx:265
 TDocDirective.cxx:266
 TDocDirective.cxx:267
 TDocDirective.cxx:268
 TDocDirective.cxx:269
 TDocDirective.cxx:270
 TDocDirective.cxx:271
 TDocDirective.cxx:272
 TDocDirective.cxx:273
 TDocDirective.cxx:274
 TDocDirective.cxx:275
 TDocDirective.cxx:276
 TDocDirective.cxx:277
 TDocDirective.cxx:278
 TDocDirective.cxx:279
 TDocDirective.cxx:280
 TDocDirective.cxx:281
 TDocDirective.cxx:282
 TDocDirective.cxx:283
 TDocDirective.cxx:284
 TDocDirective.cxx:285
 TDocDirective.cxx:286
 TDocDirective.cxx:287
 TDocDirective.cxx:288
 TDocDirective.cxx:289
 TDocDirective.cxx:290
 TDocDirective.cxx:291
 TDocDirective.cxx:292
 TDocDirective.cxx:293
 TDocDirective.cxx:294
 TDocDirective.cxx:295
 TDocDirective.cxx:296
 TDocDirective.cxx:297
 TDocDirective.cxx:298
 TDocDirective.cxx:299
 TDocDirective.cxx:300
 TDocDirective.cxx:301
 TDocDirective.cxx:302
 TDocDirective.cxx:303
 TDocDirective.cxx:304
 TDocDirective.cxx:305
 TDocDirective.cxx:306
 TDocDirective.cxx:307
 TDocDirective.cxx:308
 TDocDirective.cxx:309
 TDocDirective.cxx:310
 TDocDirective.cxx:311
 TDocDirective.cxx:312
 TDocDirective.cxx:313
 TDocDirective.cxx:314
 TDocDirective.cxx:315
 TDocDirective.cxx:316
 TDocDirective.cxx:317
 TDocDirective.cxx:318
 TDocDirective.cxx:319
 TDocDirective.cxx:320
 TDocDirective.cxx:321
 TDocDirective.cxx:322
 TDocDirective.cxx:323
 TDocDirective.cxx:324
 TDocDirective.cxx:325
 TDocDirective.cxx:326
 TDocDirective.cxx:327
 TDocDirective.cxx:328
 TDocDirective.cxx:329
 TDocDirective.cxx:330
 TDocDirective.cxx:331
 TDocDirective.cxx:332
 TDocDirective.cxx:333
 TDocDirective.cxx:334
 TDocDirective.cxx:335
 TDocDirective.cxx:336
 TDocDirective.cxx:337
 TDocDirective.cxx:338
 TDocDirective.cxx:339
 TDocDirective.cxx:340
 TDocDirective.cxx:341
 TDocDirective.cxx:342
 TDocDirective.cxx:343
 TDocDirective.cxx:344
 TDocDirective.cxx:345
 TDocDirective.cxx:346
 TDocDirective.cxx:347
 TDocDirective.cxx:348
 TDocDirective.cxx:349
 TDocDirective.cxx:350
 TDocDirective.cxx:351
 TDocDirective.cxx:352
 TDocDirective.cxx:353
 TDocDirective.cxx:354
 TDocDirective.cxx:355
 TDocDirective.cxx:356
 TDocDirective.cxx:357
 TDocDirective.cxx:358
 TDocDirective.cxx:359
 TDocDirective.cxx:360
 TDocDirective.cxx:361
 TDocDirective.cxx:362
 TDocDirective.cxx:363
 TDocDirective.cxx:364
 TDocDirective.cxx:365
 TDocDirective.cxx:366
 TDocDirective.cxx:367
 TDocDirective.cxx:368
 TDocDirective.cxx:369
 TDocDirective.cxx:370
 TDocDirective.cxx:371
 TDocDirective.cxx:372
 TDocDirective.cxx:373
 TDocDirective.cxx:374
 TDocDirective.cxx:375
 TDocDirective.cxx:376
 TDocDirective.cxx:377
 TDocDirective.cxx:378
 TDocDirective.cxx:379
 TDocDirective.cxx:380
 TDocDirective.cxx:381
 TDocDirective.cxx:382
 TDocDirective.cxx:383
 TDocDirective.cxx:384
 TDocDirective.cxx:385
 TDocDirective.cxx:386
 TDocDirective.cxx:387
 TDocDirective.cxx:388
 TDocDirective.cxx:389
 TDocDirective.cxx:390
 TDocDirective.cxx:391
 TDocDirective.cxx:392
 TDocDirective.cxx:393
 TDocDirective.cxx:394
 TDocDirective.cxx:395
 TDocDirective.cxx:396
 TDocDirective.cxx:397
 TDocDirective.cxx:398
 TDocDirective.cxx:399
 TDocDirective.cxx:400
 TDocDirective.cxx:401
 TDocDirective.cxx:402
 TDocDirective.cxx:403
 TDocDirective.cxx:404
 TDocDirective.cxx:405
 TDocDirective.cxx:406
 TDocDirective.cxx:407
 TDocDirective.cxx:408
 TDocDirective.cxx:409
 TDocDirective.cxx:410
 TDocDirective.cxx:411
 TDocDirective.cxx:412
 TDocDirective.cxx:413
 TDocDirective.cxx:414
 TDocDirective.cxx:415
 TDocDirective.cxx:416
 TDocDirective.cxx:417
 TDocDirective.cxx:418
 TDocDirective.cxx:419
 TDocDirective.cxx:420
 TDocDirective.cxx:421
 TDocDirective.cxx:422
 TDocDirective.cxx:423
 TDocDirective.cxx:424
 TDocDirective.cxx:425
 TDocDirective.cxx:426
 TDocDirective.cxx:427
 TDocDirective.cxx:428
 TDocDirective.cxx:429
 TDocDirective.cxx:430
 TDocDirective.cxx:431
 TDocDirective.cxx:432
 TDocDirective.cxx:433
 TDocDirective.cxx:434
 TDocDirective.cxx:435
 TDocDirective.cxx:436
 TDocDirective.cxx:437
 TDocDirective.cxx:438
 TDocDirective.cxx:439
 TDocDirective.cxx:440
 TDocDirective.cxx:441
 TDocDirective.cxx:442
 TDocDirective.cxx:443
 TDocDirective.cxx:444
 TDocDirective.cxx:445
 TDocDirective.cxx:446
 TDocDirective.cxx:447
 TDocDirective.cxx:448
 TDocDirective.cxx:449
 TDocDirective.cxx:450
 TDocDirective.cxx:451
 TDocDirective.cxx:452
 TDocDirective.cxx:453
 TDocDirective.cxx:454
 TDocDirective.cxx:455
 TDocDirective.cxx:456
 TDocDirective.cxx:457
 TDocDirective.cxx:458
 TDocDirective.cxx:459
 TDocDirective.cxx:460
 TDocDirective.cxx:461
 TDocDirective.cxx:462
 TDocDirective.cxx:463
 TDocDirective.cxx:464
 TDocDirective.cxx:465
 TDocDirective.cxx:466
 TDocDirective.cxx:467
 TDocDirective.cxx:468
 TDocDirective.cxx:469
 TDocDirective.cxx:470
 TDocDirective.cxx:471
 TDocDirective.cxx:472
 TDocDirective.cxx:473
 TDocDirective.cxx:474
 TDocDirective.cxx:475
 TDocDirective.cxx:476
 TDocDirective.cxx:477
 TDocDirective.cxx:478
 TDocDirective.cxx:479
 TDocDirective.cxx:480
 TDocDirective.cxx:481
 TDocDirective.cxx:482
 TDocDirective.cxx:483
 TDocDirective.cxx:484
 TDocDirective.cxx:485
 TDocDirective.cxx:486
 TDocDirective.cxx:487
 TDocDirective.cxx:488
 TDocDirective.cxx:489
 TDocDirective.cxx:490
 TDocDirective.cxx:491
 TDocDirective.cxx:492
 TDocDirective.cxx:493
 TDocDirective.cxx:494
 TDocDirective.cxx:495
 TDocDirective.cxx:496
 TDocDirective.cxx:497
 TDocDirective.cxx:498
 TDocDirective.cxx:499
 TDocDirective.cxx:500
 TDocDirective.cxx:501
 TDocDirective.cxx:502
 TDocDirective.cxx:503
 TDocDirective.cxx:504
 TDocDirective.cxx:505
 TDocDirective.cxx:506
 TDocDirective.cxx:507
 TDocDirective.cxx:508
 TDocDirective.cxx:509
 TDocDirective.cxx:510
 TDocDirective.cxx:511
 TDocDirective.cxx:512
 TDocDirective.cxx:513
 TDocDirective.cxx:514
 TDocDirective.cxx:515
 TDocDirective.cxx:516
 TDocDirective.cxx:517
 TDocDirective.cxx:518
 TDocDirective.cxx:519
 TDocDirective.cxx:520
 TDocDirective.cxx:521
 TDocDirective.cxx:522
 TDocDirective.cxx:523
 TDocDirective.cxx:524
 TDocDirective.cxx:525
 TDocDirective.cxx:526
 TDocDirective.cxx:527
 TDocDirective.cxx:528
 TDocDirective.cxx:529
 TDocDirective.cxx:530
 TDocDirective.cxx:531
 TDocDirective.cxx:532
 TDocDirective.cxx:533
 TDocDirective.cxx:534
 TDocDirective.cxx:535
 TDocDirective.cxx:536
 TDocDirective.cxx:537
 TDocDirective.cxx:538
 TDocDirective.cxx:539
 TDocDirective.cxx:540
 TDocDirective.cxx:541
 TDocDirective.cxx:542
 TDocDirective.cxx:543
 TDocDirective.cxx:544
 TDocDirective.cxx:545
 TDocDirective.cxx:546
 TDocDirective.cxx:547
 TDocDirective.cxx:548
 TDocDirective.cxx:549
 TDocDirective.cxx:550
 TDocDirective.cxx:551
 TDocDirective.cxx:552
 TDocDirective.cxx:553
 TDocDirective.cxx:554
 TDocDirective.cxx:555
 TDocDirective.cxx:556
 TDocDirective.cxx:557
 TDocDirective.cxx:558
 TDocDirective.cxx:559
 TDocDirective.cxx:560
 TDocDirective.cxx:561
 TDocDirective.cxx:562
 TDocDirective.cxx:563
 TDocDirective.cxx:564
 TDocDirective.cxx:565
 TDocDirective.cxx:566
 TDocDirective.cxx:567
 TDocDirective.cxx:568
 TDocDirective.cxx:569
 TDocDirective.cxx:570
 TDocDirective.cxx:571
 TDocDirective.cxx:572
 TDocDirective.cxx:573
 TDocDirective.cxx:574
 TDocDirective.cxx:575
 TDocDirective.cxx:576
 TDocDirective.cxx:577
 TDocDirective.cxx:578
 TDocDirective.cxx:579
 TDocDirective.cxx:580
 TDocDirective.cxx:581
 TDocDirective.cxx:582
 TDocDirective.cxx:583
 TDocDirective.cxx:584
 TDocDirective.cxx:585
 TDocDirective.cxx:586
 TDocDirective.cxx:587
 TDocDirective.cxx:588
 TDocDirective.cxx:589
 TDocDirective.cxx:590
 TDocDirective.cxx:591
 TDocDirective.cxx:592
 TDocDirective.cxx:593
 TDocDirective.cxx:594
 TDocDirective.cxx:595
 TDocDirective.cxx:596
 TDocDirective.cxx:597
 TDocDirective.cxx:598
 TDocDirective.cxx:599
 TDocDirective.cxx:600
 TDocDirective.cxx:601
 TDocDirective.cxx:602
 TDocDirective.cxx:603
 TDocDirective.cxx:604
 TDocDirective.cxx:605
 TDocDirective.cxx:606
 TDocDirective.cxx:607
 TDocDirective.cxx:608
 TDocDirective.cxx:609
 TDocDirective.cxx:610
 TDocDirective.cxx:611
 TDocDirective.cxx:612
 TDocDirective.cxx:613
 TDocDirective.cxx:614
 TDocDirective.cxx:615
 TDocDirective.cxx:616
 TDocDirective.cxx:617
 TDocDirective.cxx:618
 TDocDirective.cxx:619
 TDocDirective.cxx:620
 TDocDirective.cxx:621
 TDocDirective.cxx:622
 TDocDirective.cxx:623
 TDocDirective.cxx:624
 TDocDirective.cxx:625
 TDocDirective.cxx:626
 TDocDirective.cxx:627
 TDocDirective.cxx:628
 TDocDirective.cxx:629
 TDocDirective.cxx:630
 TDocDirective.cxx:631
 TDocDirective.cxx:632
 TDocDirective.cxx:633
 TDocDirective.cxx:634
 TDocDirective.cxx:635
 TDocDirective.cxx:636
 TDocDirective.cxx:637
 TDocDirective.cxx:638
 TDocDirective.cxx:639
 TDocDirective.cxx:640
 TDocDirective.cxx:641
 TDocDirective.cxx:642
 TDocDirective.cxx:643
 TDocDirective.cxx:644
 TDocDirective.cxx:645
 TDocDirective.cxx:646
 TDocDirective.cxx:647
 TDocDirective.cxx:648
 TDocDirective.cxx:649
 TDocDirective.cxx:650
 TDocDirective.cxx:651
 TDocDirective.cxx:652
 TDocDirective.cxx:653
 TDocDirective.cxx:654
 TDocDirective.cxx:655
 TDocDirective.cxx:656
 TDocDirective.cxx:657
 TDocDirective.cxx:658
 TDocDirective.cxx:659
 TDocDirective.cxx:660
 TDocDirective.cxx:661
 TDocDirective.cxx:662
 TDocDirective.cxx:663
 TDocDirective.cxx:664
 TDocDirective.cxx:665
 TDocDirective.cxx:666
 TDocDirective.cxx:667
 TDocDirective.cxx:668
 TDocDirective.cxx:669
 TDocDirective.cxx:670
 TDocDirective.cxx:671
 TDocDirective.cxx:672
 TDocDirective.cxx:673
 TDocDirective.cxx:674
 TDocDirective.cxx:675
 TDocDirective.cxx:676
 TDocDirective.cxx:677
 TDocDirective.cxx:678
 TDocDirective.cxx:679
 TDocDirective.cxx:680
 TDocDirective.cxx:681
 TDocDirective.cxx:682
 TDocDirective.cxx:683
 TDocDirective.cxx:684
 TDocDirective.cxx:685
 TDocDirective.cxx:686
 TDocDirective.cxx:687
 TDocDirective.cxx:688
 TDocDirective.cxx:689
 TDocDirective.cxx:690
 TDocDirective.cxx:691
 TDocDirective.cxx:692
 TDocDirective.cxx:693
 TDocDirective.cxx:694
 TDocDirective.cxx:695
 TDocDirective.cxx:696
 TDocDirective.cxx:697
 TDocDirective.cxx:698
 TDocDirective.cxx:699
 TDocDirective.cxx:700
 TDocDirective.cxx:701
 TDocDirective.cxx:702
 TDocDirective.cxx:703
 TDocDirective.cxx:704
 TDocDirective.cxx:705
 TDocDirective.cxx:706
 TDocDirective.cxx:707
 TDocDirective.cxx:708
 TDocDirective.cxx:709
 TDocDirective.cxx:710
 TDocDirective.cxx:711
 TDocDirective.cxx:712
 TDocDirective.cxx:713
 TDocDirective.cxx:714
 TDocDirective.cxx:715
 TDocDirective.cxx:716
 TDocDirective.cxx:717
 TDocDirective.cxx:718
 TDocDirective.cxx:719
 TDocDirective.cxx:720
 TDocDirective.cxx:721
 TDocDirective.cxx:722
 TDocDirective.cxx:723
 TDocDirective.cxx:724
 TDocDirective.cxx:725
 TDocDirective.cxx:726
 TDocDirective.cxx:727
 TDocDirective.cxx:728
 TDocDirective.cxx:729
 TDocDirective.cxx:730
 TDocDirective.cxx:731
 TDocDirective.cxx:732
 TDocDirective.cxx:733
 TDocDirective.cxx:734
 TDocDirective.cxx:735
 TDocDirective.cxx:736
 TDocDirective.cxx:737
 TDocDirective.cxx:738
 TDocDirective.cxx:739
 TDocDirective.cxx:740
 TDocDirective.cxx:741
 TDocDirective.cxx:742
 TDocDirective.cxx:743
 TDocDirective.cxx:744
 TDocDirective.cxx:745
 TDocDirective.cxx:746
 TDocDirective.cxx:747
 TDocDirective.cxx:748
 TDocDirective.cxx:749
 TDocDirective.cxx:750
 TDocDirective.cxx:751
 TDocDirective.cxx:752
 TDocDirective.cxx:753
 TDocDirective.cxx:754
 TDocDirective.cxx:755
 TDocDirective.cxx:756
 TDocDirective.cxx:757
 TDocDirective.cxx:758
 TDocDirective.cxx:759
 TDocDirective.cxx:760
 TDocDirective.cxx:761
 TDocDirective.cxx:762
 TDocDirective.cxx:763
 TDocDirective.cxx:764
 TDocDirective.cxx:765
 TDocDirective.cxx:766
 TDocDirective.cxx:767
 TDocDirective.cxx:768
 TDocDirective.cxx:769
 TDocDirective.cxx:770
 TDocDirective.cxx:771
 TDocDirective.cxx:772
 TDocDirective.cxx:773
 TDocDirective.cxx:774
 TDocDirective.cxx:775
 TDocDirective.cxx:776
 TDocDirective.cxx:777
 TDocDirective.cxx:778
 TDocDirective.cxx:779
 TDocDirective.cxx:780
 TDocDirective.cxx:781
 TDocDirective.cxx:782
 TDocDirective.cxx:783
 TDocDirective.cxx:784
 TDocDirective.cxx:785
 TDocDirective.cxx:786
 TDocDirective.cxx:787
 TDocDirective.cxx:788
 TDocDirective.cxx:789
 TDocDirective.cxx:790
 TDocDirective.cxx:791
 TDocDirective.cxx:792
 TDocDirective.cxx:793
 TDocDirective.cxx:794
 TDocDirective.cxx:795
 TDocDirective.cxx:796
 TDocDirective.cxx:797
 TDocDirective.cxx:798
 TDocDirective.cxx:799
 TDocDirective.cxx:800
 TDocDirective.cxx:801
 TDocDirective.cxx:802
 TDocDirective.cxx:803
 TDocDirective.cxx:804
 TDocDirective.cxx:805
 TDocDirective.cxx:806
 TDocDirective.cxx:807
 TDocDirective.cxx:808
 TDocDirective.cxx:809
 TDocDirective.cxx:810
 TDocDirective.cxx:811
 TDocDirective.cxx:812
 TDocDirective.cxx:813
 TDocDirective.cxx:814
 TDocDirective.cxx:815
 TDocDirective.cxx:816
 TDocDirective.cxx:817
 TDocDirective.cxx:818
 TDocDirective.cxx:819
 TDocDirective.cxx:820
 TDocDirective.cxx:821
 TDocDirective.cxx:822
 TDocDirective.cxx:823
 TDocDirective.cxx:824
 TDocDirective.cxx:825
 TDocDirective.cxx:826
 TDocDirective.cxx:827
 TDocDirective.cxx:828
 TDocDirective.cxx:829
 TDocDirective.cxx:830
 TDocDirective.cxx:831
 TDocDirective.cxx:832
 TDocDirective.cxx:833
 TDocDirective.cxx:834
 TDocDirective.cxx:835
 TDocDirective.cxx:836
 TDocDirective.cxx:837
 TDocDirective.cxx:838
 TDocDirective.cxx:839
 TDocDirective.cxx:840
 TDocDirective.cxx:841
 TDocDirective.cxx:842
 TDocDirective.cxx:843
 TDocDirective.cxx:844
 TDocDirective.cxx:845
 TDocDirective.cxx:846
 TDocDirective.cxx:847
 TDocDirective.cxx:848
 TDocDirective.cxx:849
 TDocDirective.cxx:850
 TDocDirective.cxx:851
 TDocDirective.cxx:852
 TDocDirective.cxx:853
 TDocDirective.cxx:854
 TDocDirective.cxx:855
 TDocDirective.cxx:856
 TDocDirective.cxx:857
 TDocDirective.cxx:858
 TDocDirective.cxx:859
 TDocDirective.cxx:860
 TDocDirective.cxx:861
 TDocDirective.cxx:862
 TDocDirective.cxx:863
 TDocDirective.cxx:864
 TDocDirective.cxx:865
 TDocDirective.cxx:866
 TDocDirective.cxx:867
 TDocDirective.cxx:868
 TDocDirective.cxx:869
 TDocDirective.cxx:870
 TDocDirective.cxx:871
 TDocDirective.cxx:872
 TDocDirective.cxx:873
 TDocDirective.cxx:874
 TDocDirective.cxx:875
 TDocDirective.cxx:876
 TDocDirective.cxx:877
 TDocDirective.cxx:878
 TDocDirective.cxx:879