MakeTutorials.C

Go to the documentation of this file.
00001 // This script generates the html pages for the ROOT tutorials hierarchy.
00002 // It creates $ROOTSYS/htmldoc if not already there
00003 // It creates $ROOTSYS/htmldoc/tutorials if not already there
00004 // It creates $ROOTSYS/htmldoc/tutorials/index.html (index to all directory tutorials)
00005 // It creates $ROOTSYS/htmldoc/tutorials/dir/index.html with index of tutorials in dir
00006 // It creates $ROOTSYS/htmldoc/tutorials/dir/*.C.html with one html file for each tutorial
00007 // Author: Rene Brun
00008 
00009 #include "THtml.h"
00010 #include "TDocOutput.h"
00011 #include "TROOT.h"
00012 #include "TSystem.h"
00013 #include "TEnv.h"
00014 #include "TDatime.h"
00015 #include "TStyle.h"
00016 #include "TList.h"
00017 #include <iostream>
00018 #include <fstream>
00019 
00020 using namespace std;
00021 
00022 void scandir(THtml& html, const char *dir, const char *title, TObjLink* toplnk);
00023 
00024 
00025 void AppendLink(TString& links, int id, const TNamed* n)
00026 {
00027    // Used to construct the context links (prev/up/next) at the top of each html page.
00028    // "links" contains the html code that AppendLink() adds to.
00029    // "id"    contains the pass (id == 0: prev, 1: up, 2: next)
00030    // "n"     points to a TNamed that has the URL (without trailing ".html") as the name
00031    //         and the title as the title.
00032 
00033    static const char* tag[] = {"&lt;", "^", "&gt;"}; // "<" "^" ">"
00034    static const char* name[] = {"prev", "up", "next"}; // for CSS
00035    static const TNamed emptyName;
00036 
00037    // for CSS
00038    TString arrowid("contextheadarrow_"); arrowid += name[id];
00039    TString entryid("contextheadentry_"); entryid += name[id];
00040    TString ardivid("divcontextheadar_"); ardivid += name[id];
00041    if (!n) n = &emptyName;
00042 
00043    TString title;
00044    // format for prev, next: script: title (if not empty)
00045    // format for up: title
00046    if (id != 1) title = n->GetName();
00047    if (title.Length()) title += ": ";
00048    title += n->GetTitle();
00049    const char* mytag = tag[id];
00050    // if we don't have a link we don't write <^>
00051    if (!n->GetName()[0]) mytag = "";
00052    // td for "<" "^" ">"
00053    TString arrow = TString::Format("<td id=\"%s\"><div id=\"%s\">"
00054                                    "<a class=\"contextheadarrow\" href=\"%s.html\">%s</a></div></td>",
00055                                    arrowid.Data(), ardivid.Data(), n->GetName(), mytag);
00056    // td for the text
00057    TString entry = TString::Format("<td class=\"contextheadentry\" id=\"%s\">"
00058                                    "<a class=\"contextheadentry\" href=\"%s.html\">%s</a></td>",
00059                                    entryid.Data(), n->GetName(), title.Data());
00060    if (id == 2)
00061       // "next" has the text first
00062       links += entry + arrow;
00063    else 
00064       links += arrow + entry;
00065 }
00066 
00067 
00068 void MakeTopLinks(TString &links, const char* name, const char* title, const char* upLink, const char* upTitle,
00069                   TObjLink *lnk, const char* dir)
00070 {
00071 // Create the html code for the navigation box at the top of each page,
00072 // showing a link to the previous and next tutorial and to the upper level.
00073 // "links"   will hold the html code after the function returns,
00074 // "title"   is the title for the page, displayed below the naviation links
00075 // "upLink"  is the URL for the up link,
00076 // "upTitle" is the text to display for the link.
00077 // "lnk"     has TNamed as prev and next, with name as URL and title as
00078 //           title for the previous and next links.
00079 
00080    links = "<div id=\"toplinks\"><div class=\"descrhead\">"
00081            "<table class=\"descrtitle\" id=\"contexttitle\"><tr class=\"descrtitle\">";
00082    TObjLink *prevlnk = lnk ? lnk->Prev() : 0;
00083    TObjLink *nextlnk = lnk ? lnk->Next() : 0;
00084 
00085    TNamed* prevname = prevlnk ? (TNamed*)prevlnk->GetObject() : 0;
00086    AppendLink(links, 0, prevname);
00087 
00088    TNamed upname;
00089    if (upLink && upLink[0])
00090       upname.SetNameTitle(upLink, upTitle);
00091    AppendLink(links, 1, &upname);
00092 
00093    TNamed* nextname = nextlnk ? (TNamed*)nextlnk->GetObject() : 0;
00094    AppendLink(links, 2, nextname);
00095 
00096    links += TString("</tr></table></div><h1 class=\"convert\">") + title + "</h1></div>\n";
00097    TString suburl = dir;
00098    TString subtitle = dir;
00099    if (name) {
00100       if (!subtitle.EndsWith("/")) {
00101          subtitle += '/';
00102       }
00103       subtitle += TString(name);
00104       suburl = subtitle + "?view=markup";
00105    }
00106    links += TString::Format("<div class=\"location\"><h2>From <a href=\"http://root.cern.ch/viewvc/trunk/tutorials/%s\">$ROOTSYS/tutorials/%s</a></h2></div>",
00107                             suburl.Data(), subtitle.Data());
00108 }
00109 
00110 void writeHeader(THtml& html, ostream& out, const char *title, const char* relPath="../") {
00111    // Write the html file header
00112    // "html"    THtml object to use
00113    // "out"     where to write to
00114    // "title"   title to display in the browser's bar
00115    // "relPath" relative path to the root of the documentation output,
00116    // i.e. where to find ROOT.css generated below by THtml::CreateAuxiliaryFiles()
00117 
00118    TDocOutput docout(html);
00119    docout.WriteHtmlHeader(out, title, relPath);
00120 }
00121 
00122 void writeTrailer(THtml& html, ostream& out) {
00123    // Write the html file trailer
00124    // "html"    THtml object to use
00125    // "out"     where to write to
00126 
00127    TDocOutput docout(html);
00128    docout.WriteHtmlFooter(out);
00129 }
00130 
00131 void writeItem(ostream& out, Int_t numb, const char *ref, const char *name, const char *title, Bool_t isnew) {
00132    // Write a list entry in the directory index.
00133    // "out"     where to write to
00134    // "numb"    number of the current line
00135    // "ref"     URL of the line's page
00136    // "name"    name to display for the link
00137    //
00138    const char *imagenew = "";
00139    cout << "writingItem: " << numb << ", ref=" << ref << ", name=" << name << ", title=" << title << endl;
00140    if (isnew) imagenew = " <img src=\"http://root.cern.ch/root/images/new01.gif\" alt=\"new\" align=\"top\" />";
00141    out << "<li class=\"idxl" << numb%2 << "\">";
00142    out << "<a href=\"" << ref << "\"><span class=\"typename\">" << numb << ". " << name << "</span></a> "
00143        << title << imagenew << "</li>" << endl;
00144 }
00145 
00146 void writeItemDir(THtml& html, ostream& out, TObjLink* lnk) {
00147    // Process a tutorial directory: add a list entry for it in the
00148    // topmost index and add all tutorials in this directory.
00149    // "html"   THtml object to use
00150    // "out"    where to write the html code to
00151    // "lnk"    a TObjLink with Prev() and Next() pointing to TNamed that
00152    //          hold the URL (name) and the title (title) for the previous
00153    //          and next tutorial directory.
00154 
00155    static int n=0;
00156    const char *dir = lnk->GetObject()->GetName();
00157    const char *title = lnk->GetObject()->GetTitle();
00158    out << "<li class=\"idxl" << (n++)%2 << "\"><a href=\"" << dir << "/index.html\">"
00159        << "<span class=\"typename\">" << dir << "</span></a>" << title << "</li>" << endl;
00160 
00161    scandir(html, dir, title, lnk);
00162 }
00163 
00164 void writeTutorials(THtml& html) {
00165    // Process all tutorials by looking over the directories in
00166    // $ROOTSYS/tutorials, generating index pages showing them
00167    // and index pages for each directory showing its tutorials,
00168    // and by converting all tutorials to html code, including
00169    // the graphics output where possible. The latter is done
00170    // using THtml::Convert().
00171 
00172    // tutorials and their titles; ordered by "significance"
00173    const char* tutorials[][2] = {
00174       {"hist",     "Histograms"},
00175       {"graphics", "Basic Graphics"}, 
00176       {"graphs",   "TGraph, TGraphErrors, etc"}, 
00177       {"gui",      "Graphics User Interface"}, 
00178       {"fit",      "Fitting tutorials"}, 
00179       {"fitsio",   "CFITSIO interface"}, 
00180       {"io",       "Input/Output"}, 
00181       {"tree",     "Trees I/O, Queries, Graphics"}, 
00182       {"math",     "Math tutorials"}, 
00183       {"matrix",   "Matrix packages tutorials"}, 
00184       {"geom",     "Geometry package"}, 
00185       {"gl",       "OpenGL examples"}, 
00186       {"eve",      "Event Display"}, 
00187       {"fft",      "Fast Fourier Transforms"}, 
00188       {"foam",     "TFoam example"}, 
00189       {"image",    "Image Processing"}, 
00190       {"mlp",      "Neural Networks"}, 
00191       {"net",      "Network, Client/server"}, 
00192       {"physics",  "Physics misc"}, 
00193       {"proof",    "PROOF tutorials"}, 
00194       {"pyroot",   "Python-ROOT"}, 
00195       {"pythia",   "Pythia event generator"}, 
00196       {"quadp",    "Quadratic Programming package"}, 
00197       {"roofit",   "RooFit tutorials"}, 
00198       {"roostats", "Roostats tutorials"}, 
00199       {"ruby",     "Ruby-ROOT"}, 
00200       {"spectrum", "Peak Finder, Deconvolutions"}, 
00201       {"splot",    "TSPlot example"}, 
00202       {"sql",      "SQL Data Bases interfaces"}, 
00203       {"thread",   "Multi-Threading examples"}, 
00204       {"unuran",   "The Unuran package"}, 
00205       {"xml",      "XML tools"},
00206       {0, 0}
00207    };
00208 
00209    // the output file for the directory index
00210    ofstream fptop("htmldoc/tutorials/index.html");
00211    writeHeader(html, fptop,"ROOT Tutorials");
00212    TString topLinks;
00213    MakeTopLinks(topLinks, 0, "ROOT Tutorials", "../index", "ROOT", 0, "");
00214    fptop << topLinks << endl;
00215    fptop << "<ul id=\"indx\">" << endl;
00216 
00217    // Iterate over all tutorial directories.
00218    // We need prev and next, so keep prev, curr, and next
00219    // in a TList containing three TNamed, and sweep through
00220    // the char array tutorials.
00221    TList contextList;
00222    TNamed prev;
00223    TNamed curr(tutorials[0][0], tutorials[0][1]);
00224    TNamed next(tutorials[1][0], tutorials[1][1]);
00225    contextList.AddLast(&prev);
00226    contextList.AddLast(&curr);
00227    contextList.AddLast(&next);
00228    TObjLink* lnk = contextList.FirstLink();
00229    lnk = lnk->Next(); // "curr" is the second link
00230    const char** iTut = tutorials[2];
00231    while (iTut[0]) {
00232       writeItemDir(html, fptop, lnk);
00233       prev = curr;
00234       curr = next;
00235       next.SetNameTitle(iTut[0], iTut[1]);
00236       ++iTut; // skip name
00237       ++iTut; // skip title
00238    }
00239 
00240    fptop << "</ul>" << endl;
00241    fptop << "<p><a href=\"http://root.cern.ch/drupal/content/downloading-root\">Download ROOT</a> and run the tutorials in $ROOTSYS/tutorials yourself!</p>" << endl;
00242    writeTrailer(html, fptop);
00243 }
00244 
00245 void GetMacroTitle(const char *fullpath, TString &comment, Bool_t &compile) {
00246    // Find the best line with a title by scanning the first 50 lines of a macro.
00247    // "fullpath" location of the macro
00248    // "comment"  is set to the comment (i.e. title) found in the macro
00249    // "compile"  is set to true if the macro should be compiled, i.e. the
00250    //            title line starts with "//+ " (note the space)
00251    compile = kFALSE;
00252    FILE *fp = fopen(fullpath,"r");
00253    char line[250];
00254    int nlines = 0;
00255    while (fgets(line,240,fp)) {
00256       nlines++;
00257       char *com = strstr(line,"//");
00258       if (com) {
00259          if (strstr(line,"Author")) continue;
00260          if (strstr(line,"@(#)")) continue;
00261          if (strstr(line,"****")) continue;
00262          if (strstr(line,"////")) continue;
00263          if (strstr(line,"====")) continue;
00264          if (strstr(line,"....")) continue;
00265          if (strstr(line,"----")) continue;
00266          if (strstr(line,"____")) continue;
00267          if (strlen(com+1)  < 5)  continue;
00268          if (!strncmp(com,"//+ ", 4)) {
00269             compile = kTRUE;
00270             com += 2; // skip "+ ", too.
00271          }
00272          comment = com+2;
00273          break;
00274       }
00275       if (nlines > 50) break;
00276    }
00277    fclose(fp);
00278 }
00279 
00280 Bool_t IsNew(const char *filename) {
00281    // Check if filename in SVN is newer than 6 months
00282    gSystem->Exec(Form("svn info %s >x.log",filename));
00283    FILE *fpdate = fopen("x.log","r");
00284    char line[250];
00285    Bool_t isnew = kFALSE;
00286    TDatime today;
00287    Int_t now = 365*(today.GetYear()-1)+12*(today.GetMonth()-1) + today.GetDay();
00288    Int_t year,month,day;
00289    while (fgets(line,240,fpdate)) {
00290       const char *com = strstr(line,"Last Changed Date: ");
00291       if (com) {
00292          sscanf(&com[19],"%d-%d-%d",&year,&month,&day);
00293          Int_t filedate = 365*(year-1) + 12*(month-1) + day; //see TDatime::GetDate
00294          if (now-filedate< 6*30) isnew = kTRUE;
00295          break;
00296       } 
00297    }
00298    fclose(fpdate);
00299    return isnew;
00300 }
00301 
00302 Bool_t CreateOutput_Dir(const char* dir) {
00303    // Whether THtml::Convert() should run the tutorials in the
00304    // directory "dir" and store their output
00305 
00306    if (strstr(dir,"net")) return kFALSE;
00307    if (strstr(dir,"xml")) return kFALSE;
00308    if (strstr(dir,"sql")) return kFALSE;
00309    if (strstr(dir,"proof")) return kFALSE;
00310    if (strstr(dir,"foam"))  return kFALSE;
00311    if (strstr(dir,"unuran"))  return kFALSE;
00312    if (strstr(dir,"roofit"))  return kFALSE;
00313    if (strstr(dir,"thread"))  return kFALSE;
00314    return kTRUE;
00315 }
00316 Bool_t CreateOutput_Tutorial(const char* tut) {
00317    // Whether THtml::Convert() should run the tutorial "tut"
00318    // and store its output
00319 
00320    static const char* vetoed[] = {
00321       "geodemo",
00322       "peaks2",
00323       "testUnfold",
00324       "readCode",
00325       "importCode",
00326       "hadd",
00327       "line3Dfit",
00328       "gtime",
00329       "games",
00330       "guiWithCINT",
00331       "Qt",
00332       "rs401d_FeldmanCousins",
00333       "graph_edit_playback",
00334       "fitpanel_playback",
00335       "guitest_playback",
00336       "geom_cms_playback",
00337       "gviz3d.C",
00338       0
00339    };
00340 
00341    for (const char** iVetoed = vetoed; *iVetoed; ++iVetoed)
00342       if (strstr(tut, *iVetoed))
00343          return kFALSE;
00344 
00345    return kTRUE;
00346 }
00347 
00348 void scandir(THtml& html, const char *dir, const char *title, TObjLink* toplnk) {
00349    // Process a directory containing tutorials by converting all tutorials to
00350    // html and creating an index of all tutorials in the directory.
00351 
00352    TString fullpath("htmldoc/tutorials/");
00353    fullpath += dir;
00354    if (!gSystem->OpenDirectory(fullpath)) gSystem->MakeDirectory(fullpath);
00355    fullpath += "/index.html";
00356    // The index for the current directory
00357    ofstream fpind(fullpath);
00358    writeHeader(html, fpind, title, "../../");
00359 
00360    TString topLinks;
00361    // Creates links to prev: "hist.html", up: ".html", next: "graph.html".
00362    MakeTopLinks(topLinks, 0, title, ".", "ROOT Tutorials", toplnk, dir);
00363    // But we need links to prev: "../hist/index.html", up: "../index.html", next: "graph/index.html",
00364    // so the following works:
00365    topLinks.ReplaceAll("href=\"", "href=\"../");
00366    topLinks.ReplaceAll("href=\"../http://", "href=\"http://");
00367    topLinks.ReplaceAll("href=\"../https://", "href=\"https://");
00368    topLinks.ReplaceAll(".html\"", "/index.html\"");
00369    // Also prepend "ROOT Tutorials" to the current title:
00370    topLinks.ReplaceAll("<h1 class=\"convert\">", "<h1 class=\"convert\">ROOT Tutorials: ");
00371    fpind << topLinks << endl;
00372    fpind << "<ul id=\"indx\">" << endl;
00373 
00374    TString outpath("htmldoc/tutorials/");
00375    outpath += dir;
00376    TString inpath("tutorials/");
00377    inpath += dir;
00378    inpath += "/";
00379    void *thedir = gSystem->OpenDirectory(inpath);
00380    const char *direntry;
00381    THashList h;
00382    while ((direntry = gSystem->GetDirEntry(thedir))) {
00383       if(*direntry =='.') continue;
00384       const char *CC = strstr(direntry,".C");
00385       // must end on ".C"
00386       if (!CC || *(CC+2)) continue;
00387       // do not even document these; they are part of another tutorial:
00388       if(strstr(direntry,"h1anal")) continue;
00389       if(strstr(direntry,"hsimpleProxy")) continue;
00390       if(strstr(direntry,"tv3")) continue;
00391       if(strstr(direntry,"tvdemo")) continue;
00392       if(strstr(direntry,"na49")) continue;
00393       if(strstr(direntry,"fit1_C")) continue;
00394       if(strstr(direntry,"c1.C")) continue;
00395       if(strstr(direntry,"MDF.C")) continue;
00396       if(strstr(direntry,"cms_calo_detail")) continue;
00397       TString atut(inpath + direntry);
00398       TString comment;
00399       Bool_t compile;
00400       GetMacroTitle(atut,comment, compile);
00401       TNamed *named = new TNamed(direntry,comment.Data());
00402       if (compile) named->SetBit(BIT(14));
00403       h.Add(named);
00404    }
00405    h.Sort();
00406    int numb = 0;
00407    TObjLink *lnk = h.FirstLink();
00408    while (lnk) {
00409       TNamed* named = (TNamed*)lnk->GetObject();
00410       Bool_t compile = named->TestBit(BIT(14));
00411       direntry = named->GetName();
00412       TString atut(inpath + direntry);
00413       numb++;
00414       TString iname(direntry);
00415       iname += ".html";
00416       writeItem(fpind, numb, iname, direntry, named->GetTitle(), IsNew(atut));
00417       Int_t includeOutput = THtml::kNoOutput;
00418       if (!gROOT->IsBatch()) {
00419          if (compile)
00420             includeOutput = THtml::kCompiledOutput;
00421          else
00422             includeOutput = THtml::kInterpretedOutput;
00423          includeOutput |= THtml::kSeparateProcessOutput;
00424       }
00425       if (!CreateOutput_Dir(dir) || !CreateOutput_Tutorial(direntry))
00426          includeOutput = THtml::kNoOutput;
00427 
00428       TString links;
00429       TString tutTitle(named->GetName());
00430       tutTitle += ": ";
00431       tutTitle += named->GetTitle();
00432       MakeTopLinks(links,named->GetName(),tutTitle,"index",title,lnk, dir);
00433       html.Convert(atut,named->GetTitle(),outpath,"../../",includeOutput,links);
00434       gROOT->GetListOfCanvases()->Delete();
00435       gROOT->GetListOfFiles()->Delete();
00436       gROOT->GetListOfFunctions()->Delete();
00437       gROOT->GetListOfBrowsers()->Delete();
00438       gROOT->GetListOfGeometries()->Delete();
00439       //gROOT->GetListOfSpecials()->Delete();
00440       // Create some styles
00441       gStyle = 0;
00442       TStyle::BuildStyles();
00443       gROOT->SetStyle("Default");
00444       lnk = lnk->Next();
00445    }
00446    fpind << "</ul>" << endl;
00447    writeTrailer(html, fpind);
00448 }
00449 
00450 void MakeTutorials() {
00451    // Bring the ROOT tutorials on the web, see http://root.cern.ch/root/html/tutorials/.
00452    // Demonstrates the use of THtml:Convert() in a realistic context.
00453 
00454    if (!gSystem->OpenDirectory("htmldoc")) gSystem->MakeDirectory("htmldoc");
00455    if (!gSystem->OpenDirectory("htmldoc/tutorials")) gSystem->MakeDirectory("htmldoc/tutorials");
00456    gEnv->SetValue("Unix.*.Root.Html.SourceDir", "$(ROOTSYS)");
00457    gEnv->SetValue("Root.Html.ViewCVS","http://root.cern.ch/viewcvs/trunk/%f?view=log");
00458    gEnv->SetValue("Root.Html.Search", "http://www.google.com/search?q=%s+site%3A%u");
00459    THtml html;
00460    html.LoadAllLibs();
00461    //gROOT->ProcessLine(".x htmlLoadlibs.C");
00462    html.CreateAuxiliaryFiles();
00463    writeTutorials(html);
00464 }

Generated on Tue Jul 5 15:44:48 2011 for ROOT_528-00b_version by  doxygen 1.5.1