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

libFAUDES 2.20d --- 2011.04.26 --- c++ source docu by doxygen