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

libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen