About
User Reference
C++ API
luafaudes
Developer
Links
libFAUDES online
libFAUDES

Sections

Index

ref2html.cpp

Go to the documentation of this file.
00001 /** ref2html.cpp  Utility to generate a html documents from fref files */
00002 
00003 /* FAU Discrete Event Systems Library (libfaudes)
00004 
00005 Copyright (C) 2011 Thomas Moor
00006 
00007 This library is free software; you can redistribute it and/or
00008 modify it under the terms of the GNU Lesser General Public
00009 License as published by the Free Software Foundation; either
00010 version 2.1 of the License, or (at your option) any later version.
00011 
00012 This library is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015 Lesser General Public License for more details.
00016 
00017 You should have received a copy of the GNU Lesser General Public
00018 License along with this library; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00020    
00021 
00022 /*
00023 
00024 Note: in ist current state, this utility is badly organized.
00025 Issues include
00026 - preformance (linear searchs)
00027 - normelized section labels etc
00028 - global configuration data 
00029 - embedded HTML fragments
00030 
00031 */
00032 
00033 
00034 
00035 #include <string>
00036 #include <cctype>
00037 #include <ctime>
00038 #include <iostream>
00039 #include <fstream>
00040 #include "corefaudes.h"
00041 
00042 
00043 using namespace faudes;
00044 
00045 // ******************************************************************
00046 // error exit
00047 // ******************************************************************
00048 
00049 void usage_exit(const std::string& rMessage="") {
00050   // ui hints
00051   if(rMessage!="") {
00052     std::cerr << rMessage << std::endl;
00053     std::cout << "" << std::endl;
00054   }
00055   std::cerr << "ref2html: " << VersionString()  << std::endl;
00056   std::cout << "" << std::endl;
00057   std::cerr << "utility to generate HTML from libFAUDES reference pages (*.fref)" << std::endl;
00058   std::cerr << std::endl << "usage: " << std::endl;
00059   std::cerr << " ref2html [options...]  <fref-file> <output-file>" << std::endl;
00060   std::cerr << "with options as follows:" << std::endl;
00061   std::cerr << " -rti  <rti-file>   use specified run-time-interface definition" << std::endl;
00062   std::cerr << " -flx  <flx-file>   use specified lua-extension file" << std::endl;
00063   std::cerr << " -css  <css-file>   use specified style sheet" << std::endl;
00064   std::cerr << " -cnav <fref-file>  use specified chapter navigation file" << std::endl;
00065   std::cerr << " -chapter <label>   overwrite chapter label" << std::endl;
00066   std::cerr << " -section <label>   overwrite section label" << std::endl;
00067   std::cerr << " -rel <prefix>      prefix to chapter documentation base" << std::endl;
00068   std::cerr << " -inc <fref-file>   include table of contents" << std::endl;
00069   std::cerr << " -app               no other libFAUDES chapters present" << std::endl;
00070   std::cerr << std::endl << std::endl;
00071   std::cerr << " ref2html -toc <fref-files> <output-file>" << std::endl;
00072   std::cerr << "to generate table of contents file" << std::endl;
00073   std::cerr << std::endl << std::endl;
00074   std::cerr << " ref2html -doxheader <output-file>" << std::endl;
00075   std::cerr << " ref2html -doxfooter <output-file>" << std::endl;
00076   std::cerr << "to generate header/footer for c++ api documentation" << std::endl;
00077   std::cerr << std::endl << std::endl;
00078   std::cerr << " ref2html -extract <input-file> <output-directory>" << std::endl;
00079   std::cerr << "to extract multiple reference pages from one file" << std::endl;
00080   std::cerr << std::endl;
00081   std::cerr << std::endl << "note: use \"-\" as output file for console output" << std::endl;
00082   exit(1);
00083 }
00084 
00085 
00086 // ******************************************************************
00087 // configuration
00088 // ******************************************************************
00089 
00090 bool mStandaloneReference = false;
00091 
00092 std::string mFrefTitle="";
00093 std::string mFrefChapter="";
00094 std::string mFrefSection="";
00095 std::string mFrefPage="";
00096 std::string mFrefLink="";
00097 
00098 std::string mRtiFile="";
00099 std::string mFlxFile="";
00100 std::string mHtmlFile="";
00101 std::string mFrefFile="";
00102 std::string mChapterFile="";
00103 std::string mIncludeFile="";
00104 
00105 std::string mBooksPrefix="../";
00106 std::string mChaptersPrefix="./";
00107 std::string mImagePrefix="./faudes_images/";
00108 std::string mRegistryPrefix="./registry/";
00109 std::string mCsourcePrefix="./csource/";
00110 std::string mLuafaudesPrefix="./luafaudes/";
00111 
00112 std::string mDownloadLink="http://www.rt.eei.uni-erlangen.de/FGdes/download.html";
00113 std::string mFaudesLink="http://www.rt.eei.uni-erlangen.de/FGdes/faudes";
00114 std::string mDestoolLink="http://www.rt.eei.uni-erlangen.de/FGdes/destool";
00115 std::string mLuafaudesLink="http://www.rt.eei.uni-erlangen.de/FGdes/faudes/luafaudes/";
00116 std::string mCsourceLink="http://www.rt.eei.uni-erlangen.de/FGdes/faudes/csource/";
00117 std::string mCssFile="faudes.css";
00118 
00119 std::string mThisChapterClass="chapter_this";
00120 std::string mOtherChapterClass="chapter_other";
00121 std::string mExitChapterClass="chapter_exit";
00122 
00123 void ChaptersPrefix(const std::string& prefix) {
00124   mChaptersPrefix=prefix;
00125   mBooksPrefix=prefix+"../";
00126   mImagePrefix=prefix+"faudes_images/";
00127   mRegistryPrefix=prefix+"registry/";
00128   mCsourcePrefix=prefix+"csource/";
00129   mLuafaudesPrefix=prefix+"luafaudes/";
00130 }
00131 
00132 // ******************************************************************
00133 // helper: time stamp
00134 // ******************************************************************
00135 
00136 std::string TimeStamp(void) {
00137   time_t now;
00138   struct tm * local;
00139   char buffer[80];
00140   time(&now );
00141   local=localtime(&now);
00142   strftime(buffer,80,"%Y.%m.%d",local);
00143   return std::string(buffer);
00144 }
00145 
00146 // ******************************************************************
00147 // helper: html header
00148 // ******************************************************************
00149 
00150 void HeaderHtml(std::ostream* pStream) {
00151   *pStream << "<html xmlns=\"http://www.w3.org/1999/xhtml\">" << std::endl; 
00152   *pStream << "<head>" << std::endl;
00153   *pStream << "<title>" << mFrefTitle << "</title>" << std::endl; 
00154   *pStream << "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />" << std::endl;
00155   *pStream << "<meta name=\"contents\" content=\"discrete event systems, libFAUDES, supervisory control, controller synthesis, automata, software library, regular languages, open source, GPL.\"/>"  << std::endl;
00156   *pStream << "<link href=\"" << mChaptersPrefix << mCssFile << "\" rel=\"stylesheet\" type=\"text/css\" />" << std::endl;
00157   *pStream << "<link rel=\"shortcut icon\" href=\""<< mImagePrefix << "des.ico\">" << std::endl;
00158   *pStream << "</head>" << std::endl;
00159   *pStream << "<body>" << std::endl;
00160 }
00161 
00162 // ******************************************************************
00163 // helper: html footer
00164 // ******************************************************************
00165 
00166 void FooterHtml(std::ostream* pStream) {
00167   *pStream << "<p class=\"bottom_line\"> " << std::endl;
00168   *pStream << "<a href=\"" << mFaudesLink << "\" target=\"_top\">" << VersionString() << "</a> " << std::endl;
00169   *pStream << "--- " << TimeStamp() <<  "  " << std::endl;
00170   if(PluginsString()!="" && mFrefChapter!="cppapi")
00171      *pStream << "--- with &quot;" << PluginsString() << "&quot; " << std::endl;
00172   if(mFrefChapter=="cppapi")
00173      *pStream << "--- c++ source docu by <a href=\"http://www.doxygen.org\" target=\"_top\">doxygen</a>" << std::endl;
00174   *pStream << "</p>" << std::endl;
00175   if(mFrefChapter=="reference") {
00176     *pStream << "<!--[if IE]>" << std::endl;
00177     *pStream << "<p class=\"bottom_line_warning\">" << std::endl;
00178     *pStream << "If MS Internet Explorer fails to display certain mathematical symbols," << std::endl;
00179     *pStream << "your system misses the corresponding unicode fonts." << std::endl; 
00180     *pStream << "<br>" << std::endl;
00181     *pStream << "You may either install &quot;Arial Unicode MS&quot; from a recent MS Office package" << std::endl;
00182     *pStream << "or the freely available" << std::endl; 
00183     *pStream << "&quot;<a href=\"http://greekfonts.teilar.gr/\">Symbola</a>&quot;" << std::endl;
00184     *pStream << "<br>" << std::endl;
00185     *pStream << "See also <a href=\"http://www.alanwood.net/\">Allan Woods</a> unicode page." << std::endl;
00186     *pStream << "B.t.w.: <a href=\"http://www.mozilla.com\">Firefox</a> will display" << std::endl;
00187     *pStream << "all relevant symbols out-of-the-box and nicely render SVG diagrams." << std::endl;
00188     *pStream << "<br>" << std::endl;
00189     *pStream << "<br>" << std::endl;
00190     *pStream << "</p>" << std::endl;
00191     *pStream << "<![endif]-->" << std::endl;
00192   }
00193   *pStream << "</body>" << std::endl;
00194   *pStream << "</html>" << std::endl;
00195 }
00196 
00197 // ******************************************************************
00198 // helper: html for image
00199 // ******************************************************************
00200 
00201 void ImageHtml(std::ostream* pStream, const std::string& rFileName) {
00202   *pStream << "<a class=\"faudes_image\" href=\"" << mImagePrefix << rFileName << ".html\">";
00203   *pStream << "<img src=\"" << mImagePrefix << rFileName << ".png\"/>";
00204   *pStream << "</a>" << std::endl;
00205 }
00206 
00207 // ******************************************************************
00208 // helper: html for linked type name
00209 // ******************************************************************
00210 
00211 void TypeHtml(std::ostream* pStream, const std::string& rTypeName) {
00212 
00213   // just text if unknown
00214   if(!TypeRegistry::G()->Exists(rTypeName)) {
00215     *pStream << rTypeName;
00216     return;
00217   }
00218 
00219   // retrieve definition
00220   const TypeDefinition& tdef=TypeRegistry::G()->Definition(rTypeName);
00221   std::string tyname = tdef.Name();
00222   std::string tyhtml = tdef.HtmlDoc();
00223   if(tyhtml=="" || tyhtml=="none") {
00224     *pStream << tyname;
00225   } else {
00226     *pStream << "<a href=\"" << mRegistryPrefix << tyhtml << "\">" << tyname << "</a>";
00227   }
00228 }
00229 
00230 
00231 // ******************************************************************
00232 // helper: html for linked function name
00233 // ******************************************************************
00234 
00235 void FunctionHtml(std::ostream* pStream, const std::string& rFunctionName) {
00236 
00237   // just text if unknown
00238   if(!FunctionRegistry::G()->Exists(rFunctionName)) {
00239     *pStream << rFunctionName;
00240     return;
00241   }
00242 
00243   // retrieve definition
00244   const FunctionDefinition& fdef=FunctionRegistry::G()->Definition(rFunctionName);
00245   std::string fname = fdef.Name();
00246   std::string fhtml = fdef.HtmlDoc();
00247   if(fhtml=="" || fhtml=="none") {
00248     *pStream << fname;
00249   } else {
00250     *pStream << "<a href=\"" << mRegistryPrefix << fhtml << "\">" << fname << "</a>";
00251   }
00252 }
00253 
00254 // ******************************************************************
00255 // helper: html for ascii text
00256 // ******************************************************************
00257 
00258 void TextHtml(std::ostream* pStream, const std::string& rText) {
00259   std::string buff;
00260   buff=StringSubstitute(buff,"<","&lt;");
00261   buff=StringSubstitute(buff,">","&gt;");
00262   buff=StringSubstitute(buff,"&","&amp;");
00263   *pStream << buff;
00264 }
00265 
00266 // ******************************************************************
00267 // helper: html for math
00268 // (we really need at least regex here!)
00269 // ******************************************************************
00270 
00271 // resolve simple one-arg macros
00272 std::string TexMacroSubstitute1(const std::string& rTexString, const std::string& rMacro, const std::string& rSubst) {
00273   // prep result
00274   std::string res;
00275   std::size_t pos=0; 
00276   // loop over occurences of "macro"
00277   while(pos<rTexString.length()) {
00278     std::size_t next=rTexString.find(rMacro,pos);
00279     if(next==std::string::npos) break;
00280     res.append(rTexString.substr(pos,next-pos));
00281     std::string arg;
00282     pos=next+rMacro.length();
00283     if(!(pos+1<rTexString.length())) continue;
00284     if(rTexString.at(pos)!='{') continue;
00285     std::size_t aend=rTexString.find('}',pos);
00286     if(aend==std::string::npos) break;
00287     arg=rTexString.substr(pos+1,aend-pos-1);
00288     arg=StringSubstitute(rSubst,"#1",arg);
00289     res.append(arg);
00290     pos=aend+1;
00291   }
00292   // get end
00293   if(pos<rTexString.length()) 
00294     res.append(rTexString.substr(pos));
00295   // done
00296   return res;
00297 }
00298    
00299 
00300 // mimique tex spacing
00301 std::string TexSpacing(const std::string& rTexString) {
00302   // prep result
00303   std::string res;
00304   std::size_t pos=0; 
00305   bool math=true;
00306   // traverse string 
00307   while(pos<rTexString.length()) {
00308     // explict: "\ "
00309     if(pos+1 < rTexString.length())
00310     if(rTexString.substr(pos,2)=="\\ ")
00311       {pos+=2; res.append("&nbsp;"); continue;}
00312     // explicit: "\," 
00313     if(pos+1 < rTexString.length())
00314     if(rTexString.substr(pos,2)=="\\,")
00315       {pos+=2; res.append("&ensp;"); continue;}
00316     // explicit: "\;" 
00317     if(pos+1 < rTexString.length())
00318     if(rTexString.substr(pos,2)=="\\;")
00319       {pos+=2; res.append("&ensp;"); continue;}
00320     // explict: "\quad"
00321     if(pos+4 < rTexString.length())
00322     if(rTexString.substr(pos,5)=="\\quad")
00323       {pos+=5; res.append("&nbsp;&nbsp;&nbsp;&nbsp;"); continue;}
00324     // math swallow space
00325     if(math)
00326     if(isspace(rTexString.at(pos)))
00327       { pos+=1; continue;}
00328     // sense end of math mode
00329     if(math)
00330     if(pos+5 < rTexString.length())
00331     if(rTexString.substr(pos,6)=="\\text{")
00332       {pos+=6; math=false; continue;};
00333     // sense end of text mode
00334     if(!math)
00335     if(rTexString.at(pos)=='}')
00336       { pos+=1; math=true; continue;}
00337     // default: copy
00338     res.append(1,rTexString.at(pos));
00339     pos+=1;
00340     }
00341   return res;
00342 }
00343 
00344 // mimique tex scripts
00345 std::string TexScripts(const std::string& rTexString) {
00346   // prep result
00347   std::string res;
00348   std::size_t pos=0; 
00349   int c0=-1;
00350   int cm1=-1;
00351   int cm2=-1;
00352   // traverse string 
00353   while(pos<rTexString.length()) {
00354     // fill buffer
00355     cm2=cm1; cm1=c0; c0=rTexString.at(pos);
00356     // full script
00357     if(cm1=='^' || cm1=='_')
00358     if(c0=='{') {
00359       std::size_t aend=rTexString.find('}',pos);
00360       if(aend==std::string::npos) break;
00361       std::string script=rTexString.substr(pos+1,aend-pos-1);
00362       res.append(1,cm1);
00363       res.append(script);
00364       cm1=-1; cm2=-1; pos=aend+1;
00365       continue;
00366     }
00367     // superscript uparrow
00368     if(cm1=='^')
00369     if(c0=='\\') {
00370       size_t mpos=rTexString.find("\\uparrow",pos);
00371       if(mpos==pos) {
00372         res.append("<span class=\"faudes_sup\">&uarr;</span>");
00373         cm1=-1; cm2=-1; pos+=8;
00374         continue;
00375       }
00376     }
00377     // superscript uparrow
00378     if(cm1=='^')
00379     if(c0=='\\') {
00380       size_t mpos=rTexString.find("\\Uparrow",pos);
00381       if(mpos==pos) {
00382         res.append("<span class=\"faudes_sup\">&#x21e7;</span>");
00383         cm1=-1; cm2=-1; pos+=8;
00384         continue;
00385       }
00386     }
00387     // digit subscript
00388     if(cm1=='_')
00389     if(isalpha(cm2)) 
00390     if(isdigit(c0)) {
00391       res.append(1,c0);
00392       cm1=-1; cm2=-1; pos+=1;
00393       continue;
00394     }
00395     // lower subscript
00396     if(cm1=='_')
00397     if(islower(c0)) 
00398     if(isupper(cm2)) {
00399       res.append(1,c0);
00400       cm1=-1; cm2=-1; pos+=1;
00401       continue;
00402     }
00403     // super star
00404     if(cm1=='^')
00405     if(c0=='*' || c0=='+') { 
00406       res.append(1,c0);
00407       cm1=-1; cm2=-1; pos+=1;
00408       continue;
00409     }
00410     // other script
00411     if(cm1=='^' || cm1=='_') {
00412       res.append(1,cm1);
00413       res.append(1,c0);
00414       cm1=-1; cm2=-1; pos+=1;
00415       continue;
00416     }     
00417     // plain copy default
00418     if(c0!='_')
00419     if(c0!='^') {
00420       res.append(1,c0);
00421     }
00422     // continue
00423     pos+=1;
00424   }
00425   return res;
00426 }
00427 
00428   
00429 // over all tex processing
00430 void MathHtml(std::ostream* pStream, const std::string& rMathString) {
00431   std::string buff=rMathString;
00432   // xml quote
00433   buff=StringSubstitute(buff,"&","&amp;");
00434   // tex quote
00435   buff=StringSubstitute(buff,"#","&hash;");
00436   // greek letters 
00437   buff=StringSubstitute(buff,"\\Sigma","Sigma");
00438   buff=StringSubstitute(buff,"\\sigma","o");
00439   buff=StringSubstitute(buff,"\\delta","delta");
00440   buff=StringSubstitute(buff,"\\epsilon","epsilon");
00441   buff=StringSubstitute(buff,"\\omega","w");
00442   // one-arg macros
00443   buff=TexMacroSubstitute1(buff,"\\ProInv","Pinv#1");
00444   buff=TexMacroSubstitute1(buff,"\\Pro","P#1");
00445   buff=TexMacroSubstitute1(buff,"\\Closure","Closure(#1)");
00446   buff=TexMacroSubstitute1(buff,"\\Prefix","Prefix(#1)");
00447   // tex math spacing and plain text
00448   buff=TexMacroSubstitute1(buff,"\\texttt","\\text{<tt>#1</tt>}");
00449   buff=TexMacroSubstitute1(buff,"\\textit","\\text{<i>#1</i>}");
00450   buff=TexSpacing(buff);
00451   // super- and subscripts
00452   buff=TexScripts(buff);
00453   // symbols
00454   buff=StringSubstitute(buff,"\\{","{");
00455   buff=StringSubstitute(buff,"\\}","}");
00456   buff=StringSubstitute(buff,"\\[","[");
00457   buff=StringSubstitute(buff,"\\]","]");
00458   buff=StringSubstitute(buff,"=","&nbsp;=&nbsp;");
00459   buff=StringSubstitute(buff,"class&nbsp;=&nbsp;","class=");     // fix csss class
00460   buff=StringSubstitute(buff,":&nbsp;=&nbsp;","&nbsp;:=&nbsp;"); //fix :=
00461   buff=StringSubstitute(buff,"\\neq","&nbsp&ne;&nbsp;");
00462   buff=StringSubstitute(buff,"\\lt","&nbsp;&lt;&nbsp;");
00463   buff=StringSubstitute(buff,"\\gt","&nbsp;&gt;&nbsp;");
00464   buff=StringSubstitute(buff,"\\le","&nbsp;&le;&nbsp;");
00465   buff=StringSubstitute(buff,"\\ge","&nbsp;&ge;&nbsp;");
00466   buff=StringSubstitute(buff,"\\emptyset","0");
00467   buff=StringSubstitute(buff,"\\times","&nbsp;x&nbsp;");
00468   buff=StringSubstitute(buff,"\\ldots","...");
00469   buff=StringSubstitute(buff,"\\cdots","...");
00470   buff=StringSubstitute(buff,"\\cdot",".");
00471   buff=StringSubstitute(buff,"\\infty","&infin;");
00472   buff=StringSubstitute(buff,"\\nin","&nbsp;&notin;&nbsp;");
00473   buff=StringSubstitute(buff,"\\not\\in","&nbsp;&notin;&nbsp;");
00474   buff=StringSubstitute(buff,"\\in","&nbsp;&isin;&nbsp;");
00475   buff=StringSubstitute(buff,"\\subseteq","&nbsp;&sube;&nbsp;");
00476   buff=StringSubstitute(buff,"\\subset","&nbsp;&sub;&nbsp;");
00477   buff=StringSubstitute(buff,"\\supseteq","&nbsp;&supe;&nbsp;");
00478   buff=StringSubstitute(buff,"\\supset","&nbsp;&sup;&nbsp;");
00479   buff=StringSubstitute(buff,"\\cup","&cup;");
00480   buff=StringSubstitute(buff,"\\dcup","&cup;"); // should be "&cup;&#775;" for "dot above"
00481   buff=StringSubstitute(buff,"\\cap","&cap;");
00482   buff=StringSubstitute(buff,"\\sup","sup");
00483   buff=StringSubstitute(buff,"\\inf","inf");
00484   buff=StringSubstitute(buff,"\\max","max");
00485   buff=StringSubstitute(buff,"\\min","min");
00486   buff=StringSubstitute(buff,"\\parallel","||");
00487   buff=StringSubstitute(buff,"\\forall","&forall;&nbsp;");
00488   buff=StringSubstitute(buff,"\\exists","&exist;&nbsp;");
00489   buff=StringSubstitute(buff,"\\leftarrow","&larr;");
00490   buff=StringSubstitute(buff,"\\rightarrow","&rarr;");
00491   buff=StringSubstitute(buff,"\\leftrightarrow","&harr;");
00492   buff=StringSubstitute(buff,"\\Leftarrow","&lArr;");
00493   buff=StringSubstitute(buff,"\\Rightarrow","&rArr;");
00494   buff=StringSubstitute(buff,"\\Leftrightarrow","&hArr;");
00495   buff=StringSubstitute(buff,"\\uparrow","&uarr;");
00496   buff=StringSubstitute(buff,"\\downarrow","&darr;");
00497   buff=StringSubstitute(buff,"\\Uparrow","&#x21e7;");
00498   buff=StringSubstitute(buff,"\\Downarrow","&#x21e9;");
00499   // ie7 fallback symbols
00500   buff=StringSubstitute(buff,"&isin;","<span class=\"faudes_fmath\">&isin;</span>"); 
00501   buff=StringSubstitute(buff,"&notin;","<span class=\"faudes_fmath\">&notin;</span>"); 
00502   buff=StringSubstitute(buff,"&exist;","<span class=\"faudes_fmath\">&exist;</span>"); 
00503   buff=StringSubstitute(buff,"&forall;","<span class=\"faudes_fmath\">&forall;</span>"); 
00504   buff=StringSubstitute(buff,"&cup;","<span class=\"faudes_fmath\">&cup;</span>"); 
00505   buff=StringSubstitute(buff,"&dcup;","<span class=\"faudes_fmath\">&cup;</span>"); // see above
00506   buff=StringSubstitute(buff,"&cap;","<span class=\"faudes_fmath\">&cap;</span>"); 
00507   buff=StringSubstitute(buff,"&larr;","<span class=\"faudes_fmath\">&larr;</span>"); 
00508   buff=StringSubstitute(buff,"&rarr;","<span class=\"faudes_fmath\">&rarr;</span>"); 
00509   buff=StringSubstitute(buff,"&harr;","<span class=\"faudes_fmath\">&harr;</span>"); 
00510   buff=StringSubstitute(buff,"&lArr;","<span class=\"faudes_fmath\">&lArr;</span>"); 
00511   buff=StringSubstitute(buff,"&rArr;","<span class=\"faudes_fmath\">&rArr;</span>"); 
00512   buff=StringSubstitute(buff,"&hArr;","<span class=\"faudes_fmath\">&hArr;</span>"); 
00513   buff=StringSubstitute(buff,"&sub;","<span class=\"faudes_fmath\">&sub;</span>"); 
00514   buff=StringSubstitute(buff,"&sube;","<span class=\"faudes_fmath\">&sube;</span>"); 
00515   buff=StringSubstitute(buff,"&sup;","<span class=\"faudes_fmath\">&sup;</span>"); 
00516   buff=StringSubstitute(buff,"&supe;","<span class=\"faudes_fmath\">&supe;</span>"); 
00517   // done
00518   *pStream << buff;
00519 }
00520 
00521 // ******************************************************************
00522 // record pages
00523 // ******************************************************************
00524 
00525 // record
00526 class PageRecord {
00527 public:
00528   std::string mTitle;
00529   std::string mChapter;
00530   std::string mSection;
00531   std::string mPage;
00532   std::string mLink;
00533 };
00534 
00535 // data
00536 std::vector<PageRecord> mPages;
00537 
00538 // extract page data
00539 void RecordPages(TokenReader& rTr) {
00540   // record my level
00541   int clevel = rTr.Level();
00542   // std::cerr << "process level " << clevel << "\n";
00543   // token loop
00544   while(true) {
00545     // skip plain text
00546     std::string text=rTr.ReadCharacterData();
00547     if(text.size()>0) continue;
00548     // break on no token or end of my level
00549     Token token;
00550     if(!rTr.Peek(token)) break;
00551     if(token.IsEnd() && !token.IsBegin() && rTr.Level()==clevel) 
00552       break;
00553     // get token, ignore irrelevant
00554     rTr.Get(token);
00555     if(!token.IsBegin("ReferencePage")) continue;
00556     // extract page data      
00557     mFrefChapter="";
00558     if(token.ExistsAttributeString("chapter")) 
00559       mFrefChapter=token.AttributeStringValue("chapter");
00560     mFrefSection="";
00561     if(token.ExistsAttributeString("section")) 
00562       mFrefSection=token.AttributeStringValue("section");
00563     mFrefPage="";
00564     if(token.ExistsAttributeString("page")) 
00565       mFrefPage=token.AttributeStringValue("page");
00566     mFrefTitle="";
00567     if(token.ExistsAttributeString("title")) 
00568       mFrefTitle=token.AttributeStringValue("title");
00569     mFrefLink=ExtractBasename(rTr.FileName())+".html";;
00570     if(token.ExistsAttributeString("link")) 
00571       mFrefLink=token.AttributeStringValue("link");
00572     // report
00573     // std::cerr << "ref2html: found chapter \"" << mFrefChapter << "\" section \"" << mFrefSection << "\"" << std::endl;
00574     // record
00575     PageRecord pagerec;
00576     pagerec.mChapter = mFrefChapter;
00577     pagerec.mSection = mFrefSection;
00578     pagerec.mPage = mFrefPage;
00579     pagerec.mTitle = mFrefTitle;
00580     pagerec.mLink = mFrefLink;
00581     // normalize
00582     std::transform(mFrefChapter.begin(), mFrefChapter.end(), mFrefChapter.begin(), tolower);
00583     std::transform(mFrefSection.begin(), mFrefSection.end(), mFrefSection.begin(), tolower);
00584     // insert entry
00585     if(mFrefChapter!="")
00586     if(mFrefChapter!="none")
00587       mPages.push_back(pagerec);
00588   }
00589 }
00590 
00591 
00592 // dump page records to include file
00593 void DumpPages(TokenWriter& rTw) {
00594   // loop records
00595   std::vector<PageRecord>::iterator pit;
00596   for(pit=mPages.begin(); pit!=mPages.end(); pit++) {
00597     Token btag;
00598     btag.SetEmpty("ReferencePage");
00599     btag.InsAttributeString("title",pit->mTitle);
00600     btag.InsAttributeString("chapter",pit->mChapter);
00601     btag.InsAttributeString("section",pit->mSection);
00602     btag.InsAttributeString("page",pit->mPage);
00603     btag.InsAttributeString("link",pit->mLink);
00604     rTw << btag << "\n";
00605   }
00606 }
00607 
00608 
00609 // ******************************************************************
00610 // search for types
00611 // ******************************************************************
00612 
00613 void ListTypesHtml(std::ostream* pIndexFile, const std::string& key="") {
00614 
00615   // table output 
00616   *pIndexFile << "<table class=\"plain\">" << std::endl;
00617   // traverse type registry
00618   bool found=false;
00619   for(TypeRegistry::Iterator tit=TypeRegistry::G()->Begin(); 
00620     tit!=TypeRegistry::G()->End(); tit++) {
00621     // test for exact key
00622     if(key!="") {
00623       std::string section= tit->second->Name();
00624       std::transform(section.begin(), section.end(), section.begin(), tolower);
00625       if(section!=key) continue;
00626     }
00627     // test for user doc
00628     if(tit->second->TextDoc()=="") continue;
00629     // table row
00630     *pIndexFile << "<tr><td valign=\"top\">";
00631     TypeHtml(pIndexFile,tit->second->Name());
00632     *pIndexFile << "</td><td valign=\"top\">";
00633     TypeHtml(pIndexFile,tit->second->TextDoc());
00634     *pIndexFile << "</td><tr>" << std::endl;
00635     // record success
00636     found=true;
00637   }
00638   // no matches
00639   if(!found) *pIndexFile << "<td><i>no matches found</i></td>" << std::endl;
00640   // table output 
00641   *pIndexFile << "</table>" << std::endl;
00642 }
00643 
00644 // ******************************************************************
00645 // search for functions
00646 // ******************************************************************
00647 
00648 void ListFunctionsHtml(std::ostream* pIndexFile, const std::string& key="") {
00649 
00650   // table output 
00651   *pIndexFile << "<table class=\"plain\">" << std::endl;
00652   // traverse function registry
00653   bool found=false;
00654   for(FunctionRegistry::Iterator fit=FunctionRegistry::G()->Begin(); 
00655     fit!=FunctionRegistry::G()->End(); fit++) {
00656     // test for exact key
00657     if(key!="") {
00658       std::string section= fit->second->Name();
00659       std::transform(section.begin(), section.end(), section.begin(), tolower);
00660       if(section!=key) continue;
00661     }
00662     // test for user doc
00663     if(fit->second->TextDoc()=="") continue;
00664     // table row
00665     *pIndexFile << "<tr><td valign=\"top\">";
00666     FunctionHtml(pIndexFile,fit->second->Name());
00667     *pIndexFile << "</td><td valign=\"top\">";
00668     TypeHtml(pIndexFile,fit->second->TextDoc());
00669     *pIndexFile << "</td><tr>" << std::endl;
00670     // record success
00671     found=true;
00672   }
00673   // no matches
00674   if(!found) *pIndexFile << "<td><i>no matches found</i></td>" << std::endl;
00675   // table output 
00676   *pIndexFile << "</table>" << std::endl;
00677 }
00678 
00679 // ******************************************************************
00680 // search for sections
00681 // ******************************************************************
00682 
00683 void ListSectionsHtml(std::ostream* pIndexFile, const std::string& key="") {
00684 
00685   // prepare list of all sections
00686   std::set< std::string > sections;
00687   for(TypeRegistry::Iterator tit=TypeRegistry::G()->Begin(); 
00688       tit!=TypeRegistry::G()->End(); tit++) {
00689     std::string section= tit->second->KeywordAt(0);
00690     // bail out on trivial
00691     if(section=="") continue;
00692     // test for exact key
00693     if(key!="") {
00694       std::transform(section.begin(), section.end(), section.begin(), tolower);
00695       if(section!=key) continue;
00696     }
00697     // record
00698     sections.insert(tit->second->KeywordAt(0));
00699   }
00700   for(FunctionRegistry::Iterator fit=FunctionRegistry::G()->Begin(); 
00701       fit!=FunctionRegistry::G()->End(); fit++) {
00702     std::string section=fit->second->KeywordAt(0);
00703     // bail out on trivial
00704     if(section=="") continue;
00705     // test for exact key
00706     if(key!="") {
00707       std::transform(section.begin(), section.end(), section.begin(), tolower);
00708       if(section!=key) continue;
00709     }
00710     // record
00711     sections.insert(fit->second->KeywordAt(0));
00712   }
00713 
00714   // list sections as links
00715   std::set< std::string >::iterator pit;
00716   for(pit=sections.begin(); pit != sections.end(); pit++) {
00717     // get nice name
00718     std::string sname = *pit;
00719     // have link
00720     std::string shtml = sname+"_index.html";
00721     std::transform(shtml.begin(),shtml.end(),shtml.begin(),tolower);
00722     // have entry as link
00723     if(pit!=sections.begin()) *pIndexFile << "," << std::endl;
00724     *pIndexFile << "<a href=\"" << shtml << "\">" << sname << "</a>";
00725   }
00726 }
00727 
00728 
00729 
00730 
00731 // ******************************************************************
00732 // type index by keyword (aka section name)
00733 // ******************************************************************
00734 
00735 void TypeIndexHtml(std::ostream* pIndexFile, const std::string& key="") {
00736 
00737   // traverse type registry
00738   bool head=false;
00739   for(TypeRegistry::Iterator tit=TypeRegistry::G()->Begin(); 
00740     tit!=TypeRegistry::G()->End(); tit++) 
00741   {
00742     // test for exact key
00743     if(key!="") {
00744       std::string section= tit->second->KeywordAt(0);
00745       std::transform(section.begin(), section.end(), section.begin(), tolower);
00746       if(section!=key) continue;
00747     }
00748     // test for user doc
00749     if(tit->second->TextDoc()=="") continue;
00750     // head line
00751     if(!head) {
00752       head=true;
00753       *pIndexFile << "<div class=\"registry_heading\"><strong>Types</strong></div>" << std::endl;
00754     }
00755     // index entry for this type
00756     *pIndexFile << "<div class=\"registry_index\">";
00757     TypeHtml(pIndexFile,tit->second->Name());
00758     *pIndexFile << "</div>" << std::endl;
00759   }
00760   // done
00761   if(head) *pIndexFile << "<br>" << std::endl;
00762 }
00763 
00764 // ******************************************************************
00765 // function index by keyword (aka plugin)
00766 // ******************************************************************
00767 
00768 void FunctionIndexHtml(std::ostream* pIndexFile, const std::string& key="") {
00769 
00770   // have lower case key
00771   std::string lkey=key;
00772   std::transform(lkey.begin(), lkey.end(), lkey.begin(), tolower);
00773   
00774   // traverse function registry
00775   bool head=false;
00776   for(FunctionRegistry::Iterator fit=FunctionRegistry::G()->Begin(); 
00777     fit!=FunctionRegistry::G()->End(); fit++) 
00778   {
00779     // test for key
00780     if(lkey!="") {
00781       std::string section= fit->second->KeywordAt(0);
00782       std::transform(section.begin(), section.end(), section.begin(), tolower);
00783       if(section!=lkey) continue;
00784     }
00785     // test for user doc
00786     if(fit->second->TextDoc()=="") continue;
00787     // index entry for this function
00788     std::string fname = fit->second->Name();
00789     std::string fhtml = fit->second->HtmlDoc();
00790     if(fhtml=="") continue;
00791     // head line
00792     if(!head){
00793       head=true;
00794       *pIndexFile << "<div class=\"registry_heading\"><strong>Functions</strong></div>" << std::endl;
00795     }
00796     // list entry
00797     if(fhtml=="none") {
00798       *pIndexFile << "<div class=\"registry_index\"> "<< fhtml << "</div>" << std::endl;
00799       continue;
00800     }
00801     *pIndexFile << "<div class=\"registry_index\"><a href=\"" << fhtml << "\">" 
00802       << fname << "</a></div>" << std::endl;
00803   }
00804 
00805   // done
00806   if(head) *pIndexFile << "<br>" << std::endl;
00807 
00808 }
00809 
00810 // ******************************************************************
00811 // reference index by keyword (aka section)
00812 // ******************************************************************
00813 
00814 void ReferenceIndexHtml(std::ostream* pIndexFile, const std::string& key="") {
00815 
00816   // prepare list of all sections
00817   std::map< std::string , std::string > sections;
00818   std::vector< PageRecord >::iterator pit;
00819   for(pit=mPages.begin(); pit != mPages.end(); pit++) {
00820     std::string chap=pit->mChapter;
00821     std::transform(chap.begin(), chap.end(), chap.begin(), tolower);
00822     std::string sect=pit->mSection;
00823     std::transform(sect.begin(), sect.end(), sect.begin(), tolower);
00824     // my chapter only
00825     if(chap!="reference") continue;
00826     if(sect=="none") continue;
00827     if(sect=="") continue;
00828     // get nice name
00829     std::string pname = pit->mSection;
00830     // have link
00831     std::string phtml = sect+"_index.html";
00832     // record
00833     sections[pname]=phtml;
00834   }
00835 
00836   // sections headline
00837   if(sections.size()!=0) 
00838     *pIndexFile << "<div class=\"registry_heading\"><strong>Sections</strong></div>" << std::endl;
00839 
00840   // produce sorted index, have corefaudes first
00841   if(sections["CoreFaudes"]!="")
00842     *pIndexFile << "<div class=\"registry_index\"><a href=\"" << sections["CoreFaudes"] << "\">CoreFaudes</a></div>" << std::endl;
00843   sections["CoreFaudes"]="";
00844   std::map< std::string , std::string >::iterator sit;
00845   for(sit=sections.begin(); sit!=sections.end(); sit++) {
00846     if(sit->second=="") continue;
00847     // have entry
00848     *pIndexFile << "<div class=\"registry_index\"><a href=\"" << sit->second << "\">" 
00849       << sit->first << "</a></div>" << std::endl;
00850   }
00851   
00852 
00853   // sections done
00854   if(sections.size()!=0) 
00855     *pIndexFile << "<br>" << std::endl;
00856 
00857   // list types
00858   if(key!="") TypeIndexHtml(pIndexFile,key);
00859 
00860   // list functions
00861   if(key!="") FunctionIndexHtml(pIndexFile,key);
00862 }
00863 
00864 // ******************************************************************
00865 // signature
00866 // ******************************************************************
00867 
00868 void SignatureHtml(std::ostream* pOutFile, std::string function) {
00869 
00870   // bail out on non existence
00871   if(!FunctionRegistry::G()->Exists(function)) return;
00872 
00873   // function definition
00874   const FunctionDefinition& fdef=FunctionRegistry::G()->Definition(function);
00875   
00876   // bail out if there is no signature
00877   if(fdef.VariantsSize()==0) return;
00878 
00879   // start signature box
00880   *pOutFile << "<div class=\"registry_signature\">" << std::endl;
00881   *pOutFile << "<p><strong>Signature:</strong></p>" << std::endl;
00882   *pOutFile << "<p>" << std::endl;
00883 
00884   // loop signatures
00885   for(int i=0; i< fdef.VariantsSize(); i++) {
00886     const Signature& sigi=fdef.Variant(i);
00887     *pOutFile << fdef.Name() << "(";
00888     // loop params
00889     for(int j=0; j < sigi.Size(); j++) {
00890       if(j!=0) *pOutFile << ", ";
00891       const Parameter& parj=sigi.At(j);
00892       *pOutFile << "+" << Parameter::AStr(parj.Attribute()) << "+ ";
00893       TypeHtml(pOutFile,parj.Type());
00894       *pOutFile << " <i>" << parj.Name() << "</i>";
00895     }
00896     *pOutFile << ")<br>" << std::endl;
00897   }
00898   *pOutFile << "</p>" << std::endl;
00899 
00900 
00901   // close signature box
00902   *pOutFile << std::endl << "</div>" << std::endl;
00903 }
00904 
00905 // ******************************************************************
00906 // short doc
00907 // ******************************************************************
00908 
00909 void ShortdocHtml(std::ostream* pOutFile, std::string fname) {
00910 
00911   // its a function
00912   if(FunctionRegistry::G()->Exists(fname)) {
00913 
00914     // function definition
00915     const FunctionDefinition& fdef=FunctionRegistry::G()->Definition(fname);
00916   
00917     // stream doc
00918     *pOutFile << "<div class=\"registry_signature\">" << std::endl;
00919     *pOutFile << "<p>" << fdef.TextDoc() << "</p>" << std::endl;
00920     *pOutFile << "</div>" << std::endl;
00921 
00922     // stream signature
00923     SignatureHtml(pOutFile,fname);
00924   }
00925 
00926   // its a type
00927   if(TypeRegistry::G()->Exists(fname)) {
00928 
00929     // type definition
00930     const TypeDefinition& tdef=TypeRegistry::G()->Definition(fname);
00931   
00932     // stream doc
00933     *pOutFile << "<div class=\"registry_signature\">" << std::endl;
00934     *pOutFile << "<p>" << tdef.TextDoc() << "<p>" << std::endl;
00935     *pOutFile << "</div>" << std::endl;
00936 
00937   }
00938 
00939 }
00940 
00941 
00942 
00943 
00944 // ******************************************************************
00945 // record literature
00946 // ******************************************************************
00947 
00948 // record
00949 class LiteratureRecord {
00950 public:
00951   std::string mLabel;
00952   std::string mLink;
00953   std::string mAuthors;
00954   std::string mTitle;
00955   std::string mJournal;
00956   std::string mPublisher;
00957   std::string mYear;
00958 };
00959 
00960 // data
00961 std::map<std::string,LiteratureRecord> mLiterature;
00962 
00963 // extract all from a section
00964 void RecordLiterature(TokenReader& rTr) {
00965   // record my level
00966   int clevel = rTr.Level();
00967   // std::cerr << "process level " << clevel << "\n";
00968   // token loop
00969   while(true) {
00970     // skip plain text
00971     std::string text=rTr.ReadCharacterData();
00972     if(text.size()>0) continue;
00973     // break on no token or end of my level
00974     Token token;
00975     if(!rTr.Peek(token)) break;
00976     if(token.IsEnd() && !token.IsBegin() && rTr.Level()==clevel) 
00977       break;
00978     // track where we are
00979     if(token.IsBegin("ReferencePage")) {
00980       mFrefChapter="";
00981       if(token.ExistsAttributeString("chapter")) 
00982         mFrefChapter=token.AttributeStringValue("chapter");
00983       mFrefSection="";
00984       if(token.ExistsAttributeString("section")) 
00985         mFrefSection=token.AttributeStringValue("section");
00986       std::transform(mFrefChapter.begin(), mFrefChapter.end(), mFrefChapter.begin(), tolower);
00987       std::transform(mFrefSection.begin(), mFrefSection.end(), mFrefSection.begin(), tolower);
00988      // report
00989      // std::cerr << "ref2html: found chapter \"" << mFrefChapter << "\" section \"" << mFrefSection << "\"" << std::endl;
00990     }
00991     // ignore other tokens
00992     if(!token.IsBegin("fliterature")) {
00993       rTr.Get(token);
00994       continue;
00995     }
00996     // do my special tag: fliterature
00997     rTr.ReadBegin("fliterature");
00998     std::string label=token.AttributeStringValue("name");
00999     //std::cerr << "process literature " << label << "\n";
01000     LiteratureRecord litrec;
01001     litrec.mLabel=label;
01002     litrec.mLink = mFrefSection + "_index.html#lit_" + label;
01003     //process entries
01004     while(!rTr.Eos("fliterature")) {
01005       Token token;
01006       rTr.Peek(token);
01007       //std::cerr << "process literature peek " << token.Str() << "\n";
01008       if(token.IsBegin("fauthors")) {
01009         rTr.ReadBegin("fauthors");
01010         litrec.mAuthors=rTr.ReadSection();
01011         rTr.ReadEnd("fauthors");
01012         continue;
01013       }
01014       if(token.IsBegin("ftitle")) {
01015         rTr.ReadBegin("ftitle");
01016         litrec.mTitle=rTr.ReadSection();
01017         rTr.ReadEnd("ftitle");
01018         continue;
01019       }
01020       if(token.IsBegin("fjournal")) {
01021         rTr.ReadBegin("fjournal");
01022         litrec.mJournal=rTr.ReadSection();
01023         rTr.ReadEnd("fjournal");
01024         continue;
01025       }
01026       if(token.IsBegin("fyear")) {
01027         rTr.ReadBegin("fyear");
01028         litrec.mYear=rTr.ReadSection();
01029         rTr.ReadEnd("fyear");
01030         continue;
01031       }
01032       if(token.IsBegin("flink")) {
01033         rTr.ReadBegin("flink");
01034         litrec.mLink=rTr.ReadSection();
01035         rTr.ReadEnd("flink");
01036         continue;
01037       }
01038       if(token.IsBegin()) {
01039         rTr.ReadBegin(token.StringValue());
01040         rTr.ReadEnd(token.StringValue());
01041         continue;
01042       }
01043       rTr.Get(token);
01044     }
01045     // insert entry
01046     if(litrec.mLabel!="")
01047       mLiterature[litrec.mLabel]=litrec;
01048     // done
01049     rTr.ReadEnd("fliterature");
01050   }
01051 }
01052 
01053 
01054 // dump literature records to include file
01055 void DumpLiterature(TokenWriter& rTw) {
01056   // loop records
01057   std::map<std::string,LiteratureRecord>::iterator lit;
01058   for(lit=mLiterature.begin(); lit!=mLiterature.end(); lit++) {
01059     Token btag;
01060     btag.SetBegin("fliterature");
01061     btag.InsAttributeString("name",lit->second.mLabel);
01062     rTw << btag << "\n";
01063     if(lit->second.mAuthors!="") {
01064       rTw.WriteBegin("fauthors");
01065       rTw.WriteCharacterData(lit->second.mAuthors); 
01066       rTw.WriteEnd("fauthors");
01067       rTw <<"\n";
01068     }
01069     if(lit->second.mTitle!="") {
01070       rTw.WriteBegin("ftitle");
01071       rTw.WriteCharacterData(lit->second.mTitle); 
01072       rTw.WriteEnd("ftitle");
01073       rTw <<"\n";
01074     }
01075     if(lit->second.mJournal!="") {
01076       rTw.WriteBegin("fjournal");
01077       rTw.WriteCharacterData(lit->second.mJournal); 
01078       rTw.WriteEnd("fjournal");
01079       rTw <<"\n";
01080     }
01081     if(lit->second.mPublisher!="") {
01082       rTw.WriteBegin("fpublisher");
01083       rTw.WriteCharacterData(lit->second.mPublisher); 
01084       rTw.WriteEnd("fpublisher");
01085       rTw <<"\n";
01086     }
01087     if(lit->second.mYear!="") {
01088       rTw.WriteBegin("fyear");
01089       rTw.WriteCharacterData(lit->second.mYear); 
01090       rTw.WriteEnd("fyear");
01091       rTw <<"\n";
01092     }
01093     if(lit->second.mLink!="") {
01094       rTw.WriteBegin("flink");
01095       rTw.WriteCharacterData(lit->second.mLink); 
01096       rTw.WriteEnd("flink");
01097       rTw <<"\n";
01098     }
01099     rTw.WriteEnd("fliterature"); rTw <<"\n";
01100     rTw.Endl();
01101   }
01102 }
01103 
01104 
01105 // html for (one) literature reference
01106 void LiteratureHtml(std::ostream* pStream, const std::string& rLabel="") {
01107   // loop records
01108   std::map<std::string,LiteratureRecord>::iterator lit;
01109   for(lit=mLiterature.begin(); lit!=mLiterature.end(); lit++) {
01110     // skip for no match
01111     if(rLabel!="")
01112     if(rLabel!=lit->second.mLabel) continue;
01113     // produce html
01114     *pStream << "<p>" << std::endl;
01115     *pStream << "<a id=\"" << "lit_" << lit->second.mLabel << "\">[" << lit->second.mLabel << "]</a>" << std::endl;
01116     *pStream << lit->second.mAuthors << ": ";
01117     *pStream << "<i>" << lit->second.mTitle << "</i>";
01118     if(lit->second.mJournal!="")   *pStream << ", " << lit->second.mJournal;
01119     if(lit->second.mPublisher!="") *pStream << ", " << lit->second.mPublisher;
01120     if(lit->second.mYear!="")      *pStream << ", " << lit->second.mYear;
01121     *pStream << ".</p>" << std::endl;
01122   }
01123 }
01124 
01125 
01126 // html for literature cittion
01127 void CiteHtml(std::ostream* pStream, const std::string& rLabel) {
01128   // prepare
01129   std::string link="reference_index.html#literature";
01130   // find records
01131   std::map<std::string,LiteratureRecord>::iterator lit;
01132   lit=mLiterature.find(rLabel);
01133   if(lit!=mLiterature.end()) link=lit->second.mLink;
01134   // produce HTML
01135   *pStream << "<a href=\"" << link << "\">[" << rLabel << "]</a>";
01136 }
01137 
01138 
01139 // ******************************************************************
01140 // extract pages
01141 // ******************************************************************
01142 
01143 void  XtractPages(TokenReader& src,const std::string& rDstDir) {
01144 
01145   // scan for reference page sections
01146   Token btag;
01147   while(src.Peek(btag)) {
01148     // skip tokens
01149     if(!btag.IsBegin("ReferencePage")) {
01150       src.Get(btag);
01151       continue;
01152     }
01153     // read begin tag
01154     src.ReadBegin("ReferencePage",btag);
01155     // extract title & friends
01156     mFrefTitle="libFAUDES Reference";
01157     if(btag.ExistsAttributeString("title")) 
01158       mFrefTitle=btag.AttributeStringValue("title");
01159     mFrefChapter="Reference";
01160     if(btag.ExistsAttributeString("chapter")) 
01161       mFrefChapter=btag.AttributeStringValue("chapter");
01162     mFrefSection="";
01163     if(btag.ExistsAttributeString("section")) 
01164       mFrefSection=btag.AttributeStringValue("section");
01165     mFrefPage="";
01166     if(btag.ExistsAttributeString("page")) 
01167       mFrefPage=btag.AttributeStringValue("page");
01168     // insist in page and section
01169     if(mFrefSection=="" || mFrefPage=="") {
01170       std::cerr << "ref2html: skipping undefined page at " << src.FileLine() << std::endl;
01171       src.ReadEnd("ReferencePage");
01172       continue;
01173     } 
01174     // normalize & report 
01175     std::transform(mFrefChapter.begin(), mFrefChapter.end(), mFrefChapter.begin(), tolower);
01176     std::transform(mFrefSection.begin(), mFrefSection.end(), mFrefSection.begin(), tolower);
01177     std::transform(mFrefPage.begin(), mFrefPage.end(), mFrefPage.begin(), tolower);
01178     // dst file
01179     std::string dstfile=rDstDir + faudes_pathsep() + mFrefSection + "_" + mFrefPage +".fref";
01180     std::cerr << "ref2html: extracting page to \"" << dstfile << "\"" << std::endl;
01181     TokenWriter dst(dstfile);
01182     // copy section
01183     dst.Write(btag);
01184     std::string scttext = src.ReadSection();
01185     dst.WriteCharacterData(scttext);
01186     dst.WriteEnd("ReferencePage");    
01187     // read end tag
01188     src.ReadEnd("ReferencePage");
01189   }  
01190 }
01191 
01192 // ******************************************************************
01193 // extract files
01194 // ******************************************************************
01195 
01196 void  XtractFiles(TokenReader& src,const std::string& rDstDir) {
01197 
01198   // scan for file  sections
01199   Token btag;
01200   while(src.Peek(btag)) {
01201     // skip tokens
01202     if(!btag.IsBegin("ImageFile")) {
01203       src.Get(btag);
01204       continue;
01205     }
01206     // read begin tag
01207     src.ReadBegin("ImageFile",btag);
01208     std::string name=btag.AttributeStringValue("name");
01209     if(name==""){
01210       std::cerr << "ref2html: skipping undefined image file at " << src.FileLine() << std::endl;
01211       src.ReadEnd("ImageFile");
01212       continue;
01213     } 
01214     // read data
01215     Token data;
01216     src.Get(data);
01217     if(!data.IsBinary()){
01218       std::cerr << "ref2html: skipping invalid image file at " << src.FileLine() << std::endl;
01219       src.ReadEnd("ImageFile");
01220       continue;
01221     } 
01222     // dst file
01223     std::string dstfile=rDstDir + faudes_pathsep() + "faudes_images" + 
01224       faudes_pathsep() + name;
01225     std::transform(dstfile.begin(), dstfile.end(), dstfile.begin(), tolower);
01226     std::cerr << "ref2html: extracting image file to \"" << dstfile << "\"" << std::endl;
01227     // setup stream
01228     std::fstream fsout;
01229     fsout.exceptions(std::ios::badbit|std::ios::failbit);
01230     try{
01231       fsout.open(dstfile.c_str(), std::ios::out | std::ios::binary); 
01232       fsout.write(data.StringValue().c_str(),data.StringValue().size());
01233       fsout.close();
01234     } 
01235     catch (std::ios::failure&) {
01236       std::cerr << "ref2html: file io error when writing  \"" << dstfile << "\"" << std::endl;
01237     }
01238     // read end tag
01239     src.ReadEnd("ImageFile");
01240   }  
01241 }
01242 
01243 // ******************************************************************
01244 // luafaudes index 
01245 // ******************************************************************
01246 
01247 void LuafaudesIndexHtml(std::ostream* pIndexFile) {
01248 
01249   // prepare list of all sections
01250   std::map< std::string , std::string > pages;
01251   std::vector< PageRecord >::iterator pit;
01252   for(pit=mPages.begin(); pit != mPages.end(); pit++) {
01253     // my chapter only
01254     if(pit->mChapter!="luafaudes") continue;
01255     if(pit->mSection=="none") continue;
01256     if(pit->mSection=="") continue;
01257     if(pit->mPage=="") continue;
01258     // get nice name
01259     std::string pname = pit->mPage;
01260     // have link
01261     std::string phtml = pit->mLink;
01262     // record
01263     pages[pname]=phtml;
01264   }
01265   // produce sorted index
01266   std::map< std::string , std::string >::iterator sit;
01267   for(sit=pages.begin(); sit!=pages.end(); sit++) {
01268     // have entry
01269     *pIndexFile << "<div class=\"registry_index\"><a href=\"" << sit->second << "\">" 
01270       << sit->first << "</a></div>" << std::endl;
01271   }
01272   // empty
01273   if(pages.size()==0) {
01274     *pIndexFile << "<div class=\"registry_index\">" << "none" << "</div>" << std::endl;
01275   }
01276 }
01277 
01278 // ******************************************************************
01279 // process current section
01280 // ******************************************************************
01281 
01282 void ProcessSection(TokenWriter& rTw, TokenReader& rTr) {
01283 
01284   // record my level
01285   int clevel = rTr.Level();
01286 
01287   // std::cerr << "process level " << clevel << "\n";
01288 
01289   // token copy loop
01290   while(true) {
01291     // see whether we can grab and copy some plain text
01292     std::string text=rTr.ReadCharacterData();
01293     if(text.size()>0) {
01294       //std::cerr << "copy text \"" << text << "\"\n";
01295       *rTw.Streamp() << text;
01296       continue;
01297     }
01298     // break on no token or end of my level
01299     Token token;
01300     if(!rTr.Peek(token)) break;
01301     if(token.IsEnd() && !token.IsBegin() && rTr.Level()==clevel) 
01302       break;
01303     // do my special tags: ftype
01304     if(token.IsBegin("ftype")) {
01305   rTr.ReadBegin("ftype");
01306         std::string ftype=rTr.ReadText();
01307         TypeHtml(rTw.Streamp(),ftype);
01308   rTr.ReadEnd("ftype");
01309   continue;
01310     }
01311     // do my special tags: ffnct
01312     if(token.IsBegin("ffnct")) {
01313   rTr.ReadBegin("ffnct");
01314         std::string ffnct=rTr.ReadText();
01315         FunctionHtml(rTw.Streamp(),ffnct);
01316   rTr.ReadEnd("ffnct");
01317   continue;
01318     }
01319     // do my special tags: fimage
01320     if(token.IsBegin("fimage")) {
01321         rTr.ReadBegin("fimage", token);
01322         std::string fsrc=token.AttributeStringValue("fsrc");
01323         ImageHtml(rTw.Streamp(),fsrc);
01324   rTr.ReadEnd("fimage");
01325   continue;
01326     }
01327     // do my special tags: dmath
01328     if(token.IsBegin("fdmath")) {
01329         rTr.ReadBegin("fdmath", token);
01330         std::string mtext=rTr.ReadCharacterData();
01331         *rTw.Streamp()<< "<span class=\"faudes_dmath\">";
01332         MathHtml(rTw.Streamp(),mtext);
01333         *rTw.Streamp()<< "</span>";
01334   rTr.ReadEnd("fdmath");
01335   continue;
01336     }
01337     // do my special tags: dmath
01338     if(token.IsBegin("fimath")) {
01339         rTr.ReadBegin("fimath", token);
01340         std::string mtext=rTr.ReadCharacterData();
01341         *rTw.Streamp()<< "<span class=\"faudes_imath\">";
01342         MathHtml(rTw.Streamp(),mtext);
01343         *rTw.Streamp()<< "</span>";
01344   rTr.ReadEnd("fimath");
01345   continue;
01346     }
01347     // do my special tags: ffnct_reference
01348     if(token.IsBegin("ffnct_reference")) {
01349         rTr.ReadBegin("ffnct_reference", token);
01350         std::string ffnct = token.AttributeStringValue("name");
01351         *rTw.Streamp() << "<div class=\"registry_function\"> <h2>" 
01352      << "<a id=\"" << ffnct << "\">" << ffnct << "</a></h2>" << std::endl;
01353         ShortdocHtml(rTw.Streamp(),ffnct);
01354         ProcessSection(rTw,rTr);
01355         *rTw.Streamp() << "</div>" << std::endl;
01356   rTr.ReadEnd("ffnct_reference");
01357   continue;
01358     }
01359     // do my special tags: ftype_reference
01360     if(token.IsBegin("ftype_reference")) {
01361         rTr.ReadBegin("ftype_reference", token);
01362         std::string ffnct = token.AttributeStringValue("name");
01363         *rTw.Streamp() << "<div class=\"registry_type\"> <h2>" 
01364      << "<a id=\"" << ffnct << "\">" << ffnct << "</a></h2>" << std::endl;
01365         ShortdocHtml(rTw.Streamp(),ffnct);
01366         ProcessSection(rTw,rTr);
01367         *rTw.Streamp() << "</div>" << std::endl;
01368   rTr.ReadEnd("ftype_reference");
01369   continue;
01370     }
01371     // do my special tags: fdetails
01372     if(token.IsBegin("fdetails")) {
01373         rTr.ReadBegin("fdetails", token);
01374         *rTw.Streamp() << "<p><strong>Detailed description:</strong></p>" << std::endl;
01375   rTr.ReadEnd("fdetails");
01376   continue;
01377     }
01378     // do my special tags: fconditions
01379     if(token.IsBegin("fconditions")) {
01380         rTr.ReadBegin("fconditions", token);
01381         *rTw.Streamp() << "<p><strong>Parameter Conditions:</strong></p>" << std::endl;
01382   rTr.ReadEnd("fconditions");
01383   continue;
01384     }
01385     // do my special tags: fexample
01386     if(token.IsBegin("fexample")) {
01387         rTr.ReadBegin("fexample", token);
01388         *rTw.Streamp() << "<p><strong>Example:</strong></p>" << std::endl;
01389   rTr.ReadEnd("fexample");
01390   continue;
01391     }
01392     // do my special tags: falltypes
01393     if(token.IsBegin("falltypes")) {
01394         rTr.ReadBegin("falltypes", token);
01395         ListTypesHtml(rTw.Streamp());
01396   rTr.ReadEnd("falltypes");
01397   continue;
01398     }
01399     // do my special tags: fallfncts
01400     if(token.IsBegin("fallfncts")) {
01401         rTr.ReadBegin("fallfncts", token);
01402         ListFunctionsHtml(rTw.Streamp());
01403   rTr.ReadEnd("fallfncts");
01404   continue;
01405     }
01406     // do my special tags: fallsects
01407     if(token.IsBegin("fallsects")) {
01408         rTr.ReadBegin("fallsects", token);
01409         ListSectionsHtml(rTw.Streamp());
01410   rTr.ReadEnd("fallsects");
01411   continue;
01412     }
01413     // do my special tags: fliteratur (list all)
01414     if(token.IsBegin("falllit")) {
01415         rTr.ReadBegin("falllit");
01416         LiteratureHtml(rTw.Streamp());
01417   rTr.ReadEnd("falllit");
01418   continue;
01419     }
01420     // do my special tags: fliteratur (definition of)
01421     if(token.IsBegin("fliterature")) {
01422         rTr.ReadBegin("fliterature", token);
01423   std::string label=token.AttributeStringValue("name");
01424         LiteratureHtml(rTw.Streamp(),label);
01425   rTr.ReadEnd("fliterature");
01426   continue;
01427     }
01428     // do my special tags: fcontributors
01429     if(token.IsBegin("fcontributors")) {
01430         rTr.ReadBegin("fcontributors");
01431         *rTw.Streamp() << ContributorsString();
01432   rTr.ReadEnd("fcontributors");
01433   continue;
01434     }
01435     // do my special tags: flink
01436     if(token.IsBegin("fcite")) {
01437         rTr.ReadBegin("fcite", token);
01438         std::string label=token.AttributeStringValue("name");
01439         CiteHtml(rTw.Streamp(),label);
01440   rTr.ReadEnd("fcite");
01441   continue;
01442     }
01443     // do my special tags: fix br for HTML
01444     if(token.IsBegin("br")) {
01445         rTr.ReadBegin("br");
01446   Token etag;
01447         rTr.Peek(etag); 
01448         if(etag.IsEnd("br")) rTr.ReadEnd("br"); // optionally accept balanced <br>
01449         token.ClrEnd();
01450         rTw.Write(token); // intentionall write unbalanced <br> for HTML
01451   continue;
01452     }
01453     // get token to do my special attributes
01454     rTr.Get(token);
01455     //std::cerr << "copy token (lv " << rTr.Level() << "): " << token.Str() << "\n";
01456     // sense chapter classes
01457     if(token.ExistsAttributeString("ftcclass")) {
01458       mThisChapterClass=token.AttributeStringValue("ftcclass");
01459       token.ClrAttribute("ftcclass");
01460     }
01461     if(token.ExistsAttributeString("focclass"))  {
01462       mOtherChapterClass=token.AttributeStringValue("focclass");  
01463       token.ClrAttribute("focclass");
01464     }
01465     if(token.ExistsAttributeString("fxcclass"))  {
01466       mExitChapterClass=token.AttributeStringValue("fxcclass");  
01467       token.ClrAttribute("fxcclass");
01468     }
01469     // chapter attribute
01470     if(token.ExistsAttributeString("fchapter")) {
01471       std::string chapter = token.AttributeStringValue("fchapter");
01472       std::string cclass=mOtherChapterClass;
01473       if(chapter==mFrefChapter) cclass=mThisChapterClass;
01474       if(chapter=="exit") cclass=mExitChapterClass;
01475       token.InsAttributeString("class",cclass);
01476       token.ClrAttribute("fchapter");
01477     }
01478     // fhref attribute: ref only
01479     if(token.ExistsAttributeString("fhref") && mStandaloneReference) {
01480       std::string href = token.AttributeStringValue("fhref");
01481       href = StringSubstitute(href,"FAUDES_BOOKS/",mBooksPrefix);
01482       href = StringSubstitute(href,"FAUDES_CHAPTERS/",mChaptersPrefix);
01483       href = StringSubstitute(href,"FAUDES_IMAGES/",mImagePrefix);
01484       href = StringSubstitute(href,"FAUDES_REGISTRY/",mRegistryPrefix);
01485       href = StringSubstitute(href,"FAUDES_CSOURCE/",mCsourceLink);
01486       href = StringSubstitute(href,"FAUDES_LUAFAUDES/",mLuafaudesLink);
01487       href = StringSubstitute(href,"FAUDES_ONLINE",mFaudesLink);
01488       href = StringSubstitute(href,"FAUDES_GETLINUX",mDownloadLink+"#Linux");
01489       href = StringSubstitute(href,"FAUDES_GETMSWIN",mDownloadLink+"#MsWin");
01490       href = StringSubstitute(href,"DESTOOL_ONLINE",mDestoolLink);
01491       token.InsAttributeString("href",href);
01492       token.ClrAttribute("fhref");
01493     }
01494     // fhref attribute
01495     if(token.ExistsAttributeString("fhref")  && !mStandaloneReference) {
01496       std::string href = token.AttributeStringValue("fhref");
01497       href = StringSubstitute(href,"FAUDES_BOOKS/",mBooksPrefix);
01498       href = StringSubstitute(href,"FAUDES_CHAPTERS/",mChaptersPrefix);
01499       href = StringSubstitute(href,"FAUDES_IMAGES/",mImagePrefix);
01500       href = StringSubstitute(href,"FAUDES_REGISTRY/",mRegistryPrefix);
01501       href = StringSubstitute(href,"FAUDES_CSOURCE/",mCsourcePrefix);
01502       href = StringSubstitute(href,"FAUDES_LUAFAUDES/",mLuafaudesPrefix);
01503       href = StringSubstitute(href,"FAUDES_ONLINE",mFaudesLink);
01504       href = StringSubstitute(href,"FAUDES_GETLINUX",mDownloadLink+"#Linux");
01505       href = StringSubstitute(href,"FAUDES_GETMSWIN",mDownloadLink+"#MsWin");
01506       href = StringSubstitute(href,"DESTOOL_ONLINE",mDestoolLink);
01507       token.InsAttributeString("href",href);
01508       token.ClrAttribute("fhref");
01509     }
01510     // fsrc attribute
01511     if(token.ExistsAttributeString("fsrc")) {
01512       std::string fsrc = token.AttributeStringValue("fsrc");
01513       fsrc = StringSubstitute(fsrc,"FAUDES_IMAGES/",mImagePrefix);
01514       fsrc = StringSubstitute(fsrc,"FAUDES_CSOURCE/",mCsourcePrefix);
01515       fsrc = StringSubstitute(fsrc,"FAUDES_LUAFAUDES/",mLuafaudesPrefix);
01516       token.InsAttributeString("src",fsrc);
01517       token.ClrAttribute("fsrc");
01518     }
01519     rTw.Write(token);
01520   }
01521 }
01522 
01523 
01524 // ******************************************************************
01525 // reference page
01526 // ******************************************************************
01527 
01528 void RefpageHtml(std::ostream* pOutFile, std::string inputfile) {
01529 
01530   // setup token io
01531   TokenReader src(inputfile);
01532   TokenWriter dst(*pOutFile);
01533 
01534   // find the reference page section
01535   Token btag;
01536   src.SeekBegin("ReferencePage");
01537   src.ReadBegin("ReferencePage",btag);
01538 
01539   // extract title & friends
01540   mFrefTitle="libFAUDES Reference";
01541   if(btag.ExistsAttributeString("title")) 
01542     mFrefTitle=btag.AttributeStringValue("title");
01543   mFrefChapter="";
01544   if(btag.ExistsAttributeString("chapter")) 
01545     mFrefChapter=btag.AttributeStringValue("chapter");
01546   mFrefSection="";
01547   if(btag.ExistsAttributeString("section")) 
01548     mFrefSection=btag.AttributeStringValue("section");
01549   std::transform(mFrefChapter.begin(), mFrefChapter.end(), mFrefChapter.begin(), tolower);
01550   std::transform(mFrefSection.begin(), mFrefSection.end(), mFrefSection.begin(), tolower);
01551 
01552   // report
01553   // std::cerr << "ref2html: found chapter \"" << mFrefChapter << "\" section \"" << mFrefSection << "\"" << std::endl;
01554 
01555   // generate generic html header
01556   dst.Flush();
01557   HeaderHtml(pOutFile);
01558 
01559   // begin body
01560   dst.Flush();
01561 
01562   // include chapter level navigation
01563   if(mChapterFile!="") {
01564     TokenReader inc(mChapterFile);
01565     ProcessSection(dst,inc);
01566   }
01567 
01568   // include section level navigation, part 1
01569   if(mFrefChapter=="reference") {
01570     *pOutFile << "<table id=\"registry_page\">" << std::endl;
01571     *pOutFile << "<tr id=\"registry_row\">" << std::endl;
01572     *pOutFile << "<td id=\"registry_index\">" << std::endl;
01573     *pOutFile << "<div class=\"registry_heading\"><strong>libFAUDES</strong></div>" << std::endl;
01574     *pOutFile << "<div class=\"registry_index\"><a href=\"reference_index.html\">Reference</a></div>" << std::endl;
01575     *pOutFile << "<div class=\"registry_index\"><a href=\"reference_index.html#types\">Type Index</a></div>" << std::endl;
01576     *pOutFile << "<div class=\"registry_index\"><a href=\"reference_index.html#functions\">Function Index</a></div>" << std::endl;
01577     *pOutFile << "<div class=\"registry_index\"><a href=\"reference_index.html#literature\">Literature</a></div>" << std::endl;
01578     *pOutFile << "<br>" << std::endl;
01579     ReferenceIndexHtml(pOutFile, mFrefSection);
01580     *pOutFile << "</td>" << std::endl;
01581     *pOutFile << "<td id=\"registry_content\">" << std::endl;
01582   }
01583 
01584   // include section level navigation, part 1
01585   if(mFrefChapter=="luafaudes") {
01586     *pOutFile << "<table id=\"registry_page\">" << std::endl;
01587     *pOutFile << "<tr id=\"registry_row\">" << std::endl;
01588     *pOutFile << "<td id=\"registry_index\">" << std::endl;
01589     *pOutFile << "<div class=\"registry_heading\"><strong>luafaudes</strong></div>" << std::endl;
01590     *pOutFile << "<div class=\"registry_index\"><a href=\"index.html\">Overview</a></div>" << std::endl;
01591     *pOutFile << "<div class=\"registry_index\"><a href=\"faudes_luatech.html\">Technical Details</a></div>" << std::endl;
01592     *pOutFile << "<div class=\"registry_index\"><a href=\"faudes_luaext.html\">LuaExtensions</a></div>" << std::endl;
01593     *pOutFile << "<br>" << std::endl;
01594     *pOutFile << "<div class=\"registry_heading\"><strong>Tutorials</strong></div>" << std::endl;
01595     LuafaudesIndexHtml(pOutFile);
01596     *pOutFile << "</td>" << std::endl;
01597     *pOutFile << "<td id=\"registry_content\">" << std::endl;
01598   }
01599 
01600   // process src
01601   ProcessSection(dst,src);
01602   src.ReadEnd("ReferencePage");
01603 
01604   // include section level navigation, part 2
01605   if(mFrefChapter=="reference") {
01606     *pOutFile << "</td>" << std::endl;
01607     *pOutFile << "</tr>" << std::endl;
01608     *pOutFile << "</table>" << std::endl;
01609   }
01610 
01611   // include section level navigation, part 2
01612   if(mFrefChapter=="luafaudes") {
01613     *pOutFile << "</td>" << std::endl;
01614     *pOutFile << "</tr>" << std::endl;
01615     *pOutFile << "</table>" << std::endl;
01616   }
01617 
01618   // end page
01619   dst.Flush();
01620   FooterHtml(pOutFile);
01621 
01622 }
01623 
01624 
01625 
01626 // ******************************************************************
01627 // Doxygen header and footer
01628 // ******************************************************************
01629 
01630 void DoxygenHeader(std::ostream* pOutFile) {
01631 
01632   // setup token io
01633   TokenWriter dst(*pOutFile);
01634 
01635   // configure
01636   mFrefTitle="C++ API";
01637   mFrefChapter="cppapi";
01638   mFrefSection="none";
01639 
01640   // generate generic html header
01641   dst.Flush();
01642   HeaderHtml(pOutFile);
01643 
01644   // include chapter level navigation
01645   if(mChapterFile!="") {
01646     TokenReader inc(mChapterFile);
01647     ProcessSection(dst,inc);
01648   }
01649 
01650   // include section level navigation, part 1
01651   *pOutFile << "<table id=\"registry_page\">" << std::endl;
01652   *pOutFile << "<tr id=\"registry_row\">" << std::endl;
01653   *pOutFile << "<td id=\"registry_index\">" << std::endl;
01654   *pOutFile << "<div class=\"registry_heading\"><strong>libFAUDES</strong></div>" << std::endl;
01655   *pOutFile << "<div class=\"registry_index\"><a href=\"main.html\">C++ API</a></div>" << std::endl;
01656   *pOutFile << "<br>" << std::endl;  
01657   *pOutFile << "<div class=\"registry_heading\"><strong>Sections</strong></div>" << std::endl;
01658   *pOutFile << "<div class=\"registry_index\"><a href=\"group__ContainerClasses.html\">Sets</a></div>" << std::endl;
01659   *pOutFile << "<div class=\"registry_index\"><a href=\"group__GeneratorClasses.html\">Generators</a></div>" << std::endl;
01660   *pOutFile << "<div class=\"registry_index\"><a href=\"group__GeneratorFunctions.html\">Functions</a></div>" << std::endl;
01661   *pOutFile << "<div class=\"registry_index\"><a href=\"group__AllPlugins.html\">PlugIns</a></div>" << std::endl;
01662   *pOutFile << "<div class=\"registry_index\"><a href=\"group__Tutorials.html\">Tutorials</a></div>" << std::endl;
01663   *pOutFile << "<br>" << std::endl;  
01664   *pOutFile << "<div class=\"registry_heading\"><strong>Index</strong></div>" << std::endl;
01665   *pOutFile << "<div class=\"registry_index\"><a href=\"classes.html\">Classes</a></div>" << std::endl;
01666   *pOutFile << "<div class=\"registry_index\"><a href=\"namespacefaudes.html\">Namespace</a></div>" << std::endl;
01667   *pOutFile << "<div class=\"registry_index\"><a href=\"files.html\">Files</a></div>" << std::endl;
01668   *pOutFile << "<br>" << std::endl;  
01669   *pOutFile << "</td>" << std::endl;
01670   *pOutFile << "<td id=\"registry_content\">" << std::endl;
01671 }
01672 
01673 
01674 void DoxygenFooter(std::ostream* pOutFile) {
01675 
01676   // setup token io
01677   TokenWriter dst(*pOutFile);
01678 
01679   // configure
01680   mFrefTitle="C++ API";
01681   mFrefChapter="cppapi";
01682   mFrefSection="none";
01683 
01684   // include section level navigation, part 2
01685   *pOutFile << "</td>" << std::endl;
01686   *pOutFile << "</tr>" << std::endl;
01687   *pOutFile << "</table>" << std::endl;
01688 
01689   // end page
01690   dst.Flush();
01691   FooterHtml(pOutFile);
01692 
01693 }
01694 
01695 // ******************************************************************
01696 // command line ui
01697 // ******************************************************************
01698 
01699 
01700 int main(int argc, char *argv[]) {
01701 
01702   // local config 
01703   bool dotoc=false;
01704   bool dodhd=false;
01705   bool dodft=false;
01706   bool xpage=false;
01707 
01708   // min args
01709   if(argc < 3) usage_exit();
01710 
01711   // primitive commad line parsing
01712   int i;
01713   for(i=1; i<argc; i++) {
01714     std::string option(argv[i]);
01715     // option: rti file
01716     if(option=="-rti") { 
01717       i++; if(i>=argc) usage_exit();
01718       mRtiFile=argv[i];
01719       continue;
01720     }
01721     // option: flx file
01722     if(option=="-flx") { 
01723       i++; if(i>=argc) usage_exit();
01724       mFlxFile=argv[i];
01725       continue;
01726     }
01727     // option: css file
01728     if(option=="-css") { 
01729       i++; if(i>=argc) usage_exit();
01730       mCssFile=argv[i];
01731       continue;
01732     }
01733     // option: navigation include
01734     if(option=="-cnav") {
01735       i++; if(i>=argc) usage_exit();
01736       mChapterFile=argv[i];
01737       continue;
01738     }
01739     // option: toc include
01740     if(option=="-inc") { 
01741       i++; if(i>=argc) usage_exit();
01742       mIncludeFile=argv[i];
01743       continue;
01744     }
01745     // option: target prefix
01746     if(option=="-rel") {
01747       i++; if(i>=argc) usage_exit();
01748       ChaptersPrefix(argv[i]);
01749       continue;
01750     }
01751     // option: overwrite chapter
01752     if(option=="-chapter") {
01753       i++; if(i>=argc) usage_exit();
01754       mFrefChapter=argv[i];
01755       continue;
01756     }
01757     // option: overwrite section
01758     if(option=="-section") {
01759       i++; if(i>=argc) usage_exit();
01760       mFrefSection=argv[i];
01761       continue;
01762     }
01763     // option: extrac multiple pages
01764     if(option=="-extract") {
01765       if(i+2!=argc-1) usage_exit();
01766       xpage=true;
01767       break;
01768     }
01769     // option: generate toc (break)
01770     if(option=="-toc") {
01771       i++; if(i+1>=argc) usage_exit();
01772       dotoc=true;
01773       mHtmlFile = argv[argc-1];
01774       break;
01775     }
01776     // option: generate doxygen header (break)
01777     if(option=="-doxheader") {
01778       i++; if(i>=argc) usage_exit();
01779       dodhd=true;
01780       mHtmlFile = argv[argc-1];
01781       break;
01782     }
01783     // option: generate doxygen footer (break)
01784     if(option=="-doxfooter") {
01785       i++; if(i>=argc) usage_exit();
01786       dodft=true;
01787       mHtmlFile = argv[argc-1];
01788       break;
01789     }
01790     // option: generate doxygen footer (break)
01791     if(option=="-app") {
01792       mStandaloneReference=true;
01793       continue;
01794     }
01795     // option: help
01796     if((option=="-?") || (option=="--help")) {
01797       usage_exit();
01798       continue;
01799     }
01800     // option: unknown
01801     if(option.size()>1)
01802     if(option.at(0)=='-') {
01803       usage_exit("unknown option " + option);
01804       continue;
01805     }
01806     // filename: input
01807     if(mFrefFile=="") {
01808        mFrefFile=option;
01809        continue;
01810     }
01811     // filename: output
01812     if(mHtmlFile=="") {
01813        mHtmlFile=option;
01814        continue;
01815     }
01816     // too many filenames
01817     usage_exit("more than one filname specified" );
01818   }
01819 
01820 
01821   // load registry 
01822   if(mRtiFile!="") {
01823     LoadRegistry(mRtiFile);
01824   }
01825 
01826   // extend registry 
01827   if(mFlxFile!="") {
01828     FunctionRegistry::G()->MergeDocumentation(mFlxFile);
01829   }
01830 
01831   // special case: xtract fref
01832   if(xpage) {
01833     mFrefFile=argv[i+1];
01834     std::string dstdir =argv[i+2];
01835     std::cerr << "ref2html: extract pages from " << mFrefFile << std::endl;
01836     TokenReader tr(mFrefFile);
01837     XtractPages(tr,dstdir);
01838     tr.Rewind();
01839     XtractFiles(tr,dstdir);
01840     exit(0);
01841   }
01842 
01843 
01844   // output file
01845   std::ostream* hout= &std::cout;
01846   std::ofstream fout;
01847   if(mHtmlFile != "-") {
01848     fout.open(argv[argc-1], std::ios::out);
01849     hout = &fout;
01850   }
01851   
01852   // special case: generate toc
01853   if(dotoc) {
01854     // process all input 
01855     for(;i<argc-1;i++) {
01856       mFrefFile=argv[i];
01857       std::cerr << "ref2html: process toc " << mFrefFile << std::endl;
01858       TokenReader tr(mFrefFile);
01859       RecordLiterature(tr);
01860       tr.Rewind();
01861       RecordPages(tr);
01862     }
01863     // dump
01864     TokenWriter dst(*hout);
01865     DumpPages(dst);
01866     DumpLiterature(dst);
01867     dst.Flush();
01868     exit(0);
01869   }
01870 
01871   // special case: generate dox header
01872   if(dodhd) {
01873     DoxygenHeader(hout);
01874     exit(0);
01875   }
01876 
01877   // special case: generate dox footer
01878   if(dodft) {
01879     DoxygenFooter(hout);
01880     exit(0);
01881   }
01882 
01883   // include to
01884   if(mIncludeFile!="") {
01885     TokenReader tr(mIncludeFile);
01886     RecordLiterature(tr);
01887     tr.Rewind();
01888     RecordPages(tr);
01889   }
01890 
01891   // std: process reference page
01892   RefpageHtml(hout,mFrefFile);
01893   return 0;
01894 
01895   // error
01896   usage_exit();
01897   return(1);
01898 }

libFAUDES 2.22k --- 2013.04.02 --- c++ source docu by doxygen