ref2html.cppGo 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 "" << PluginsString() << "" " << 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 "Arial Unicode MS" from a recent MS Office package" << std::endl; 00211 *pStream << "or the freely available" << std::endl; 00212 *pStream << ""<a href=\"http://greekfonts.teilar.gr/\">Symbola</a>"" << 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\"> </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,"<","<"); 00329 buff=StringSubstitute(buff,">",">"); 00330 buff=StringSubstitute(buff,"&","&"); 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(" "); continue;} 00380 // explicit: "\," 00381 if(pos+1 < rTexString.length()) 00382 if(rTexString.substr(pos,2)=="\\,") 00383 {pos+=2; res.append(" "); continue;} 00384 // explicit: "\;" 00385 if(pos+1 < rTexString.length()) 00386 if(rTexString.substr(pos,2)=="\\;") 00387 {pos+=2; res.append(" "); continue;} 00388 // explict: "\quad" 00389 if(pos+4 < rTexString.length()) 00390 if(rTexString.substr(pos,5)=="\\quad") 00391 {pos+=5; res.append(" "); 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\">↑</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\">⇧</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,"&","&"); 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,"="," = "); 00527 buff=StringSubstitute(buff,"class = ","class="); // fix csss class 00528 buff=StringSubstitute(buff,": = "," := "); //fix := 00529 buff=StringSubstitute(buff,"\\neq"," ≠ "); 00530 buff=StringSubstitute(buff,"\\lt"," < "); 00531 buff=StringSubstitute(buff,"\\gt"," > "); 00532 buff=StringSubstitute(buff,"\\le"," ≤ "); 00533 buff=StringSubstitute(buff,"\\ge"," ≥ "); 00534 buff=StringSubstitute(buff,"\\emptyset","0"); 00535 buff=StringSubstitute(buff,"\\times"," x "); 00536 buff=StringSubstitute(buff,"\\ldots","..."); 00537 buff=StringSubstitute(buff,"\\cdots","..."); 00538 buff=StringSubstitute(buff,"\\cdot","."); 00539 buff=StringSubstitute(buff,"\\infty","∞"); 00540 buff=StringSubstitute(buff,"\\nin"," ∉ "); 00541 buff=StringSubstitute(buff,"\\not\\in"," ∉ "); 00542 buff=StringSubstitute(buff,"\\in"," ∈ "); 00543 buff=StringSubstitute(buff,"\\subseteq"," ⊆ "); 00544 buff=StringSubstitute(buff,"\\subset"," ⊂ "); 00545 buff=StringSubstitute(buff,"\\supseteq"," ⊇ "); 00546 buff=StringSubstitute(buff,"\\supset"," ⊃ "); 00547 buff=StringSubstitute(buff,"\\cup","∪"); 00548 buff=StringSubstitute(buff,"\\dcup","∪"); // should be "∪̇" for "dot above" 00549 buff=StringSubstitute(buff,"\\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","∀ "); 00556 buff=StringSubstitute(buff,"\\exists","∃ "); 00557 buff=StringSubstitute(buff,"\\leftarrow","←"); 00558 buff=StringSubstitute(buff,"\\rightarrow","→"); 00559 buff=StringSubstitute(buff,"\\leftrightarrow","↔"); 00560 buff=StringSubstitute(buff,"\\Leftarrow","⇐"); 00561 buff=StringSubstitute(buff,"\\Rightarrow","⇒"); 00562 buff=StringSubstitute(buff,"\\Leftrightarrow","⇔"); 00563 buff=StringSubstitute(buff,"\\uparrow","↑"); 00564 buff=StringSubstitute(buff,"\\downarrow","↓"); 00565 buff=StringSubstitute(buff,"\\Uparrow","⇧"); 00566 buff=StringSubstitute(buff,"\\Downarrow","⇩"); 00567 // ie7 fallback symbols 00568 buff=StringSubstitute(buff,"∈","<span class=\"faudes_fmath\">∈</span>"); 00569 buff=StringSubstitute(buff,"∉","<span class=\"faudes_fmath\">∉</span>"); 00570 buff=StringSubstitute(buff,"∃","<span class=\"faudes_fmath\">∃</span>"); 00571 buff=StringSubstitute(buff,"∀","<span class=\"faudes_fmath\">∀</span>"); 00572 buff=StringSubstitute(buff,"∪","<span class=\"faudes_fmath\">∪</span>"); 00573 buff=StringSubstitute(buff,"&dcup;","<span class=\"faudes_fmath\">∪</span>"); // see above 00574 buff=StringSubstitute(buff,"∩","<span class=\"faudes_fmath\">∩</span>"); 00575 buff=StringSubstitute(buff,"←","<span class=\"faudes_fmath\">←</span>"); 00576 buff=StringSubstitute(buff,"→","<span class=\"faudes_fmath\">→</span>"); 00577 buff=StringSubstitute(buff,"↔","<span class=\"faudes_fmath\">↔</span>"); 00578 buff=StringSubstitute(buff,"⇐","<span class=\"faudes_fmath\">⇐</span>"); 00579 buff=StringSubstitute(buff,"⇒","<span class=\"faudes_fmath\">⇒</span>"); 00580 buff=StringSubstitute(buff,"⇔","<span class=\"faudes_fmath\">⇔</span>"); 00581 buff=StringSubstitute(buff,"⊂","<span class=\"faudes_fmath\">⊂</span>"); 00582 buff=StringSubstitute(buff,"⊆","<span class=\"faudes_fmath\">⊆</span>"); 00583 buff=StringSubstitute(buff,"⊃","<span class=\"faudes_fmath\">⊃</span>"); 00584 buff=StringSubstitute(buff,"⊇","<span class=\"faudes_fmath\">⊇</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\"> </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\"> </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\"> </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\"> </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\"> </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\"> </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>>></span>" << std::endl; 01918 *pOutFile << "<ul class=\"registry_list\">" << std::endl; 01919 SectionIndexHtml(pOutFile,mFrefSection); 01920 *pOutFile << "<li class=\"registry_blanc\"> </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>>></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\"> </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\"> </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\"> </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\"> </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>>></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\"> </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 |