ref2html.cpp
Go to the documentation of this file.
1 /** ref2html.cpp Utility to generate a html documents from fref files */
2 
3 /* FAU Discrete Event Systems Library (libfaudes)
4 
5 Copyright (C) 2011 Thomas Moor
6 
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11 
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16 
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
20 
21 
22 /*
23 
24 Note: in its current state, this utility is badly organized.
25 
26 Issues include
27 - preformance (linear searchs)
28 - normelizad section labels etc
29 - global configuration data
30 - embedded HTML fragments
31 
32 */
33 
34 
35 
36 #include <string>
37 #include <cctype>
38 #include <ctime>
39 #include <iostream>
40 #include <fstream>
41 #include "corefaudes.h"
42 
43 
44 using namespace faudes;
45 
46 // ******************************************************************
47 // error exit
48 // ******************************************************************
49 
50 void usage_exit(const std::string& rMessage="") {
51  // ui hints
52  if(rMessage!="") {
53  std::cerr << rMessage << std::endl;
54  std::cout << "" << std::endl;
55  }
56  std::cerr << "ref2html: " << VersionString() << std::endl;
57  std::cout << "" << std::endl;
58  std::cerr << "utility to generate HTML from libFAUDES reference pages (*.fref)" << std::endl;
59  std::cerr << std::endl << "usage: " << std::endl;
60  std::cerr << " ref2html [options...] <fref-file> <html-file>" << std::endl;
61  std::cerr << " ref2html [options...] <fref-file 1> [...] <fref-file n> <html-dir>" << std::endl;
62  std::cerr << " ref2html [options...] <fref-dir> <html-dir>" << std::endl;
63  std::cerr << "with options as follows:" << std::endl;
64  std::cerr << " -rti <rti-file> use specified run-time-interface definition" << std::endl;
65  std::cerr << " -flx <flx-file> use specified lua-extension file" << std::endl;
66  std::cerr << " -css <css-file> use specified style sheet" << std::endl;
67  std::cerr << " -cnav <fref-file> use specified chapter navigation file" << std::endl;
68  std::cerr << " -chapter <label> overwrite chapter label" << std::endl;
69  std::cerr << " -section <label> overwrite section label" << std::endl;
70  std::cerr << " -rel <prefix> prefix to chapter documentation base" << std::endl;
71  std::cerr << " -inc <fref-file> include table of contents" << std::endl;
72  std::cerr << std::endl << std::endl;
73  std::cerr << " ref2html -toc <fref-files> <output-file>" << std::endl;
74  std::cerr << "to generate table of contents file" << std::endl;
75  std::cerr << std::endl << std::endl;
76  std::cerr << " ref2html -doxheader <output-file>" << std::endl;
77  std::cerr << " ref2html -doxfooter <output-file>" << std::endl;
78  std::cerr << "to generate header/footer for c++ api documentation" << std::endl;
79  std::cerr << std::endl << std::endl;
80  std::cerr << " ref2html -extract <input-file> <output-directory>" << std::endl;
81  std::cerr << "to extract multiple reference pages from one file" << std::endl;
82  std::cerr << std::endl;
83  std::cerr << std::endl << "note: use \"-\" as output file for console output" << std::endl;
84  exit(1);
85 }
86 
87 
88 // ******************************************************************
89 // configuration
90 // ******************************************************************
91 
92 bool mStandaloneReference = false;
93 
94 std::string mFrefTitle="";
95 std::string mFrefChapter="";
96 std::string mFrefSection="";
97 std::string mFrefPage="";
98 std::string mFrefLink="";
99 std::string mFrefSummary="";
100 
101 std::string mRtiFile="";
102 std::string mFlxFile="";
103 std::string mDstFile="";
104 std::set< std::string > mSrcFiles;
105 std::string mChapterFile="";
106 std::string mIncludeFile="";
107 
108 std::string mBooksPrefix="../";
109 std::string mChaptersPrefix="./";
110 std::string mImagePrefix="./images/";
111 std::string mReferencePrefix="./reference/";
112 std::string mCsourcePrefix="./csource/";
113 std::string mLuafaudesPrefix="./luafaudes/";
114 
115 /*
116 std::string mDownloadLink="http://www.rt.eei.uni-erlangen.de/FGdes/download.html";
117 std::string mFaudesLink="http://www.rt.eei.uni-erlangen.de/FGdes/faudes";
118 std::string mDestoolLink="http://www.rt.eei.uni-erlangen.de/FGdes/destool";
119 std::string mLuafaudesLink="http://www.rt.eei.uni-erlangen.de/FGdes/faudes/luafaudes/";
120 std::string mCsourceLink="http://www.rt.eei.uni-erlangen.de/FGdes/faudes/csource/";
121 std::string mCssFile="faudes.css";
122 */
123 
124 std::string mDownloadLink="http://www.rt.techfak.fau.de/FGdes/download.html";
125 std::string mFaudesLink="http://www.rt.techfak.fau.de/FGdes/faudes";
126 std::string mDestoolLink="http://www.rt.techfak.fau.de/FGdes/destool";
127 std::string mLuafaudesLink="http://www.rt.techfak.fau.de/FGdes/faudes/luafaudes/";
128 std::string mCsourceLink="http://www.rt.techfak.fau.de/FGdes/faudes/csource/";
129 std::string mCssFile="faudes.css";
130 
131 std::string mThisChapterClass="chapter_this";
132 std::string mOtherChapterClass="chapter_other";
133 std::string mExitChapterClass="chapter_exit";
134 
135 // ******************************************************************
136 // configure: set my chapter prefix
137 // ******************************************************************
138 
139 void ChaptersPrefix(const std::string& prefix) {
140  mChaptersPrefix=prefix;
141  mBooksPrefix=prefix+"../";
142  mImagePrefix=prefix+"images/";
143  mReferencePrefix=prefix+"reference/";
144  mCsourcePrefix=prefix+"csource/";
145  mLuafaudesPrefix=prefix+"luafaudes/";
146  mCssFile=prefix+mCssFile;
147 }
148 
149 // ******************************************************************
150 // helper: time stamp
151 // ******************************************************************
152 
153 std::string TimeStamp(void) {
154  time_t now;
155  struct tm * local;
156  char buffer[80];
157  time(&now );
158  local=localtime(&now);
159  strftime(buffer,80,"%Y.%m.%d",local);
160  return std::string(buffer);
161 }
162 
163 
164 // ******************************************************************
165 // helper: convert page to printable
166 // ******************************************************************
167 
168 std::string PrettyPage(const std::string page){
169  // swallow page number
170  std::string ppage = page;
171  std::size_t upos = ppage.find_first_of("_");
172  std::size_t spos = ppage.find_first_of(" ");
173  std::size_t dpos = 0;
174  for(; dpos < ppage.size();dpos++)
175  if(!isdigit(ppage.at(dpos))) break;
176  if(upos!=std::string::npos)
177  if(upos==dpos)
178  if(upos+1<ppage.size())
179  ppage=ppage.substr(upos+1,ppage.size()-upos-1);
180  if(spos!=std::string::npos)
181  if(spos==dpos)
182  if(spos+1<ppage.size())
183  ppage=ppage.substr(spos+1,ppage.size()-spos-1);
184  // turn underscore to space
185  ppage=StringSubstitute(ppage,"_"," ");
186  // done
187  return ppage;
188 }
189 
190 
191 // ******************************************************************
192 // helper: bottom line
193 // ******************************************************************
194 
195 void BottomLineHtml(std::ostream* pStream) {
196  *pStream << "<p class=\"bottom_line\"> " << std::endl;
197  *pStream << "<a href=\"" << mFaudesLink << "\" target=\"_top\">" << VersionString() << "</a> " << std::endl;
198  *pStream << "--- " << TimeStamp() << " " << std::endl;
199  if(PluginsString()!="" && mFrefChapter!="cppapi")
200  *pStream << "--- with &quot;" << PluginsString() << "&quot; " << std::endl;
201  if(mFrefChapter=="cppapi")
202  *pStream << "--- c++ api documentaion by <a href=\"http://www.doxygen.org\" target=\"_top\">doxygen</a>" << std::endl;
203  *pStream << "</p>" << std::endl;
204  if(mFrefChapter=="reference") {
205  *pStream << "<!--[if IE]>" << std::endl;
206  *pStream << "<p class=\"bottom_line_warning\">" << std::endl;
207  *pStream << "If MS Internet Explorer fails to display certain mathematical symbols," << std::endl;
208  *pStream << "your system misses the corresponding unicode fonts." << std::endl;
209  *pStream << "<br>" << std::endl;
210  *pStream << "You may either install &quot;Arial Unicode MS&quot; from a recent MS Office package" << std::endl;
211  *pStream << "or the freely available" << std::endl;
212  *pStream << "&quot;<a href=\"http://greekfonts.teilar.gr/\">Symbola</a>&quot;" << std::endl;
213  *pStream << "<br>" << std::endl;
214  *pStream << "See also <a href=\"http://www.alanwood.net/\">Allan Woods</a> unicode page." << std::endl;
215  *pStream << "B.t.w.: <a href=\"http://www.mozilla.com\">Firefox</a> will display" << std::endl;
216  *pStream << "all relevant symbols out-of-the-box and nicely render SVG diagrams." << std::endl;
217  *pStream << "<br>" << std::endl;
218  *pStream << "<br>" << std::endl;
219  *pStream << "</p>" << std::endl;
220  *pStream << "<![endif]-->" << std::endl;
221  }
222 }
223 
224 
225 // ******************************************************************
226 // helper: html header
227 // ******************************************************************
228 
229 void HeaderHtml(std::ostream* pStream) {
230  *pStream << "<!doctype html>" << std::endl;
231  *pStream << "<html xmlns=\"http://www.w3.org/1999/xhtml\">" << std::endl;
232  *pStream << "<head>" << std::endl;
233  *pStream << "<title>" << mFrefTitle << "</title>" << std::endl;
234  *pStream << "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />" << std::endl;
235  *pStream << "<meta name=\"contents\" content=\"discrete event systems, libFAUDES, supervisory control, controller synthesis, automata, software library, regular languages, open source, GPL.\"/>" << std::endl;
236  *pStream << "<link href=\"" << mCssFile << "\" rel=\"stylesheet\" type=\"text/css\" />" << std::endl;
237  *pStream << "<link rel=\"shortcut icon\" href=\""<< mImagePrefix << "des.ico\">" << std::endl;
238  *pStream << "</head>" << std::endl;
239  *pStream << "<body>" << std::endl;
240  *pStream << "<div id=\"cwrapper1000\">" << std::endl;
241  *pStream << "<div id=\"dwrapper1000\">" << std::endl;
242 }
243 
244 // ******************************************************************
245 // helper: html footer
246 // ******************************************************************
247 
248 void FooterHtml(std::ostream* pStream) {
249  *pStream << "</div>" << std::endl;
250  *pStream << "</div>" << std::endl;
251  *pStream << "</body>" << std::endl;
252  *pStream << "</html>" << std::endl;
253 }
254 
255 // ******************************************************************
256 // helper: html for image
257 // ******************************************************************
258 
259 void ImageHtml(std::ostream* pStream, const std::string& rFileName) {
260  *pStream << "<a class=\"faudes_image\" href=\"" << mImagePrefix << rFileName << ".html\">";
261  *pStream << "<img src=\"" << mImagePrefix << rFileName << ".png\"/>";
262  *pStream << "</a>" << std::endl;
263 }
264 
265 // ******************************************************************
266 // helper: fancy reference for resgistry list
267 // ******************************************************************
268 
269 
270 void ListItemHtml(std::ostream* pStream, const std::string& rLink, const std::string& rText) {
271  *pStream << "<li class=\"registry_item\">" << std::endl
272  << "<a href=\"" << rLink << "\">" << rText << "</a>" << std::endl
273  << "<a href=\"" << rLink << "\" class=\"registry_blinda\">&nbsp;</a>" << std::endl
274  << "</li>" << std::endl;
275  }
276 
277 // ******************************************************************
278 // helper: html for linked type name
279 // ******************************************************************
280 
281 void TypeHtml(std::ostream* pStream, const std::string& rTypeName) {
282 
283  // just text if unknown
284  if(!TypeRegistry::G()->Exists(rTypeName)) {
285  *pStream << rTypeName;
286  return;
287  }
288 
289  // retrieve definition
290  const TypeDefinition& tdef=TypeRegistry::G()->Definition(rTypeName);
291  std::string tyname = tdef.Name();
292  std::string tyhtml = tdef.HtmlDoc();
293  if(tyhtml=="" || tyhtml=="none") {
294  *pStream << tyname;
295  } else {
296  *pStream << "<a href=\"" << mReferencePrefix << tyhtml << "\">" << tyname << "</a>";
297  }
298 }
299 
300 
301 // ******************************************************************
302 // helper: html for linked function name
303 // ******************************************************************
304 
305 void FunctionHtml(std::ostream* pStream, const std::string& rFunctionName) {
306 
307  // just text if unknown
308  if(!FunctionRegistry::G()->Exists(rFunctionName)) {
309  *pStream << rFunctionName;
310  return;
311  }
312 
313  // retrieve definition
314  const FunctionDefinition& fdef=FunctionRegistry::G()->Definition(rFunctionName);
315  std::string fname = fdef.Name();
316  std::string fhtml = fdef.HtmlDoc();
317  if(fhtml=="" || fhtml=="none") {
318  *pStream << fname;
319  } else {
320  *pStream << "<a href=\"" << mReferencePrefix << fhtml << "\">" << fname << "</a>";
321  }
322 }
323 
324 // ******************************************************************
325 // helper: html for ascii text
326 // ******************************************************************
327 
328 void TextHtml(std::ostream* pStream, const std::string& rText) {
329  std::string buff;
330  buff=StringSubstitute(buff,"<","&lt;");
331  buff=StringSubstitute(buff,">","&gt;");
332  buff=StringSubstitute(buff,"&","&amp;");
333  *pStream << buff;
334 }
335 
336 // ******************************************************************
337 // helper: html for math
338 // (we really need at least regex here!)
339 // ******************************************************************
340 
341 // resolve simple one-arg macros
342 std::string TexMacroSubstitute1(const std::string& rTexString, const std::string& rMacro, const std::string& rSubst) {
343  // prep result
344  std::string res;
345  std::size_t pos=0;
346  // loop over occurences of "macro"
347  while(pos<rTexString.length()) {
348  std::size_t next=rTexString.find(rMacro,pos);
349  if(next==std::string::npos) break;
350  res.append(rTexString.substr(pos,next-pos));
351  std::string arg;
352  pos=next+rMacro.length();
353  if(!(pos+1<rTexString.length())) continue;
354  if(rTexString.at(pos)!='{') continue;
355  std::size_t aend=rTexString.find('}',pos);
356  if(aend==std::string::npos) break;
357  arg=rTexString.substr(pos+1,aend-pos-1);
358  arg=StringSubstitute(rSubst,"#1",arg);
359  res.append(arg);
360  pos=aend+1;
361  }
362  // get end
363  if(pos<rTexString.length())
364  res.append(rTexString.substr(pos));
365  // done
366  return res;
367 }
368 
369 
370 // mimique tex spacing
371 std::string TexSpacing(const std::string& rTexString) {
372  // prep result
373  std::string res;
374  std::size_t pos=0;
375  bool math=true;
376  // traverse string
377  while(pos<rTexString.length()) {
378  // explict: "\ "
379  if(pos+1 < rTexString.length())
380  if(rTexString.substr(pos,2)=="\\ ")
381  {pos+=2; res.append("&nbsp;"); continue;}
382  // explicit: "\,"
383  if(pos+1 < rTexString.length())
384  if(rTexString.substr(pos,2)=="\\,")
385  {pos+=2; res.append("&ensp;"); continue;}
386  // explicit: "\;"
387  if(pos+1 < rTexString.length())
388  if(rTexString.substr(pos,2)=="\\;")
389  {pos+=2; res.append("&ensp;"); continue;}
390  // explict: "\quad"
391  if(pos+4 < rTexString.length())
392  if(rTexString.substr(pos,5)=="\\quad")
393  {pos+=5; res.append("&nbsp;&nbsp;&nbsp;&nbsp;"); continue;}
394  // math swallow space
395  if(math)
396  if(isspace(rTexString.at(pos)))
397  { pos+=1; continue;}
398  // sense end of math mode
399  if(math)
400  if(pos+5 < rTexString.length())
401  if(rTexString.substr(pos,6)=="\\text{")
402  {pos+=6; math=false; continue;};
403  // sense end of text mode
404  if(!math)
405  if(rTexString.at(pos)=='}')
406  { pos+=1; math=true; continue;}
407  // default: copy
408  res.append(1,rTexString.at(pos));
409  pos+=1;
410  }
411  return res;
412 }
413 
414 // mimique tex scripts
415 std::string TexScripts(const std::string& rTexString) {
416  // prep result
417  std::string res;
418  std::size_t pos=0;
419  int c0=-1;
420  int cm1=-1;
421  int cm2=-1;
422  // traverse string
423  while(pos<rTexString.length()) {
424  // fill buffer
425  cm2=cm1; cm1=c0; c0=rTexString.at(pos);
426  // full script
427  if(cm1=='^' || cm1=='_')
428  if(c0=='{') {
429  std::size_t aend=rTexString.find('}',pos);
430  if(aend==std::string::npos) break;
431  std::string script=rTexString.substr(pos+1,aend-pos-1);
432  res.append(1,cm1);
433  res.append(script);
434  cm1=-1; cm2=-1; pos=aend+1;
435  continue;
436  }
437  // superscript uparrow
438  if(cm1=='^')
439  if(c0=='\\') {
440  size_t mpos=rTexString.find("\\uparrow",pos);
441  if(mpos==pos) {
442  res.append("<span class=\"faudes_sup\">&uarr;</span>");
443  cm1=-1; cm2=-1; pos+=8;
444  continue;
445  }
446  }
447  // superscript uparrow
448  if(cm1=='^')
449  if(c0=='\\') {
450  size_t mpos=rTexString.find("\\Uparrow",pos);
451  if(mpos==pos) {
452  res.append("<span class=\"faudes_sup\">&#x21e7;</span>");
453  cm1=-1; cm2=-1; pos+=8;
454  continue;
455  }
456  }
457  // digit subscript
458  if(cm1=='_')
459  if(isalpha(cm2))
460  if(isdigit(c0)) {
461  res.append(1,c0);
462  cm1=-1; cm2=-1; pos+=1;
463  continue;
464  }
465  // lower subscript
466  if(cm1=='_')
467  if(islower(c0))
468  if(isupper(cm2)) {
469  res.append(1,c0);
470  cm1=-1; cm2=-1; pos+=1;
471  continue;
472  }
473  // super star
474  if(cm1=='^')
475  if(c0=='*' || c0=='+') {
476  res.append(1,c0);
477  cm1=-1; cm2=-1; pos+=1;
478  continue;
479  }
480  // other script
481  if(cm1=='^' || cm1=='_') {
482  res.append(1,cm1);
483  res.append(1,c0);
484  cm1=-1; cm2=-1; pos+=1;
485  continue;
486  }
487  // plain copy default
488  if(c0!='_')
489  if(c0!='^') {
490  res.append(1,c0);
491  }
492  // continue
493  pos+=1;
494  }
495  return res;
496 }
497 
498 
499 // over all tex processing
500 void MathHtml(std::ostream* pStream, const std::string& rMathString) {
501  std::string buff=rMathString;
502  // xml quote
503  buff=StringSubstitute(buff,"&","&amp;");
504  // tex quote
505  buff=StringSubstitute(buff,"#","&hash;");
506  // greek letters
507  buff=StringSubstitute(buff,"\\Sigma","Sigma");
508  buff=StringSubstitute(buff,"\\sigma","o");
509  buff=StringSubstitute(buff,"\\delta","delta");
510  buff=StringSubstitute(buff,"\\epsilon","epsilon");
511  buff=StringSubstitute(buff,"\\omega","w");
512  // one-arg macros
513  buff=TexMacroSubstitute1(buff,"\\ProInv","Pinv#1");
514  buff=TexMacroSubstitute1(buff,"\\Pro","P#1");
515  buff=TexMacroSubstitute1(buff,"\\Closure","Closure(#1)");
516  buff=TexMacroSubstitute1(buff,"\\Prefix","Prefix(#1)");
517  // tex math spacing and plain text
518  buff=TexMacroSubstitute1(buff,"\\texttt","\\text{<tt>#1</tt>}");
519  buff=TexMacroSubstitute1(buff,"\\mathtt","\\text{<tt>#1</tt>}");
520  buff=TexMacroSubstitute1(buff,"\\textit","\\text{<i>#1</i>}");
521  buff=TexMacroSubstitute1(buff,"\\mathit","\\text{<i>#1</i>}");
522  buff=TexMacroSubstitute1(buff,"\\mathsf","\\text{<sf>#1</i>}");
523  buff=TexSpacing(buff);
524  // super- and subscripts
525  buff=TexScripts(buff);
526  // symbols
527  buff=StringSubstitute(buff,"\\{","{");
528  buff=StringSubstitute(buff,"\\}","}");
529  buff=StringSubstitute(buff,"\\[","[");
530  buff=StringSubstitute(buff,"\\]","]");
531  buff=StringSubstitute(buff,"=","&nbsp;=&nbsp;");
532  buff=StringSubstitute(buff,"class&nbsp;=&nbsp;","class="); // fix csss class
533  buff=StringSubstitute(buff,":&nbsp;=&nbsp;","&nbsp;:=&nbsp;"); //fix :=
534  buff=StringSubstitute(buff,"\\neq","&nbsp&ne;&nbsp;");
535  buff=StringSubstitute(buff,"\\lt","&nbsp;&lt;&nbsp;");
536  buff=StringSubstitute(buff,"\\gt","&nbsp;&gt;&nbsp;");
537  buff=StringSubstitute(buff,"\\le","&nbsp;&le;&nbsp;");
538  buff=StringSubstitute(buff,"\\ge","&nbsp;&ge;&nbsp;");
539  buff=StringSubstitute(buff,"\\emptyset","0");
540  buff=StringSubstitute(buff,"\\times","&nbsp;x&nbsp;");
541  buff=StringSubstitute(buff,"\\ldots","...");
542  buff=StringSubstitute(buff,"\\cdots","...");
543  buff=StringSubstitute(buff,"\\cdot",".");
544  buff=StringSubstitute(buff,"\\infty","&infin;");
545  buff=StringSubstitute(buff,"\\nin","&nbsp;&notin;&nbsp;");
546  buff=StringSubstitute(buff,"\\not\\in","&nbsp;&notin;&nbsp;");
547  buff=StringSubstitute(buff,"\\in","&nbsp;&isin;&nbsp;");
548  buff=StringSubstitute(buff,"\\subseteq","&nbsp;&sube;&nbsp;");
549  buff=StringSubstitute(buff,"\\subset","&nbsp;&sub;&nbsp;");
550  buff=StringSubstitute(buff,"\\supseteq","&nbsp;&supe;&nbsp;");
551  buff=StringSubstitute(buff,"\\supset","&nbsp;&sup;&nbsp;");
552  buff=StringSubstitute(buff,"\\cup","&cup;");
553  buff=StringSubstitute(buff,"\\dcup","&cup;"); // should be "&cup;&#775;" for "dot above"
554  buff=StringSubstitute(buff,"\\cap","&cap;");
555  buff=StringSubstitute(buff,"\\sup","sup");
556  buff=StringSubstitute(buff,"\\inf","inf");
557  buff=StringSubstitute(buff,"\\max","max");
558  buff=StringSubstitute(buff,"\\min","min");
559  buff=StringSubstitute(buff,"\\parallel","||");
560  buff=StringSubstitute(buff,"\\forall","&forall;&nbsp;");
561  buff=StringSubstitute(buff,"\\exists","&exist;&nbsp;");
562  buff=StringSubstitute(buff,"\\leftarrow","&larr;");
563  buff=StringSubstitute(buff,"\\rightarrow","&rarr;");
564  buff=StringSubstitute(buff,"\\leftrightarrow","&harr;");
565  buff=StringSubstitute(buff,"\\Leftarrow","&lArr;");
566  buff=StringSubstitute(buff,"\\Rightarrow","&rArr;");
567  buff=StringSubstitute(buff,"\\Leftrightarrow","&hArr;");
568  buff=StringSubstitute(buff,"\\uparrow","&uarr;");
569  buff=StringSubstitute(buff,"\\downarrow","&darr;");
570  buff=StringSubstitute(buff,"\\Uparrow","&#x21e7;");
571  buff=StringSubstitute(buff,"\\Downarrow","&#x21e9;");
572  // ie7 fallback symbols
573  buff=StringSubstitute(buff,"&isin;","<span class=\"faudes_fmath\">&isin;</span>");
574  buff=StringSubstitute(buff,"&notin;","<span class=\"faudes_fmath\">&notin;</span>");
575  buff=StringSubstitute(buff,"&exist;","<span class=\"faudes_fmath\">&exist;</span>");
576  buff=StringSubstitute(buff,"&forall;","<span class=\"faudes_fmath\">&forall;</span>");
577  buff=StringSubstitute(buff,"&cup;","<span class=\"faudes_fmath\">&cup;</span>");
578  buff=StringSubstitute(buff,"&dcup;","<span class=\"faudes_fmath\">&cup;</span>"); // see above
579  buff=StringSubstitute(buff,"&cap;","<span class=\"faudes_fmath\">&cap;</span>");
580  buff=StringSubstitute(buff,"&larr;","<span class=\"faudes_fmath\">&larr;</span>");
581  buff=StringSubstitute(buff,"&rarr;","<span class=\"faudes_fmath\">&rarr;</span>");
582  buff=StringSubstitute(buff,"&harr;","<span class=\"faudes_fmath\">&harr;</span>");
583  buff=StringSubstitute(buff,"&lArr;","<span class=\"faudes_fmath\">&lArr;</span>");
584  buff=StringSubstitute(buff,"&rArr;","<span class=\"faudes_fmath\">&rArr;</span>");
585  buff=StringSubstitute(buff,"&hArr;","<span class=\"faudes_fmath\">&hArr;</span>");
586  buff=StringSubstitute(buff,"&sub;","<span class=\"faudes_fmath\">&sub;</span>");
587  buff=StringSubstitute(buff,"&sube;","<span class=\"faudes_fmath\">&sube;</span>");
588  buff=StringSubstitute(buff,"&sup;","<span class=\"faudes_fmath\">&sup;</span>");
589  buff=StringSubstitute(buff,"&supe;","<span class=\"faudes_fmath\">&supe;</span>");
590  // done
591  *pStream << buff;
592 }
593 
594 
595 // ******************************************************************
596 // record pages
597 // ******************************************************************
598 
599 
600 // section lists (from reading rti/flx)
601 std::set< std::string > mExclLuaSections;
602 std::set< std::string > mInclLuaSections;
603 
604 // page data
605 class PageRecord {
606 public:
607  std::string mTitle;
608  std::string mChapter;
609  std::string mSection;
610  std::string mPage;
611  std::string mLink;
612  std::string mSummary;
613 };
614 
615 
616 // record all pages
617 std::vector<PageRecord> mAllPages;
618 
619 // record all pages within reference section (keys to lower)
620 std::map< std::string , std::map< std::string , PageRecord > > mRefSectPages;
621 
622 // extract page data (works with both, *.flx and *.ftoc)
624  // record my level
625  int clevel = rTr.Level();
626  // std::cerr << "process level " << clevel << "\n";
627  // token loop
628  while(true) {
629  // skip plain text
630  std::string text=rTr.ReadCharacterData();
631  if(text.size()>0) continue;
632  // break on no token or end of my level
633  Token token;
634  if(!rTr.Peek(token)) break;
635  if(token.IsEnd() && !token.IsBegin() && rTr.Level()==clevel)
636  break;
637  // ignore irrelevant
638  if(!token.IsBegin("ReferencePage")) {
639  rTr.Get(token);
640  continue;
641  }
642  // take my section
643  rTr.ReadBegin("ReferencePage");
644  // extract page data
645  mFrefChapter="";
646  if(token.ExistsAttributeString("chapter"))
647  mFrefChapter=token.AttributeStringValue("chapter");
648  mFrefSection="";
649  if(token.ExistsAttributeString("section"))
650  mFrefSection=token.AttributeStringValue("section");
651  mFrefPage="";
652  if(token.ExistsAttributeString("page"))
653  mFrefPage=token.AttributeStringValue("page");
654  mFrefTitle="";
655  if(token.ExistsAttributeString("title"))
656  mFrefTitle=token.AttributeStringValue("title");
657  mFrefLink=ExtractBasename(rTr.FileName())+".html";;
658  if(token.ExistsAttributeString("link"))
659  mFrefLink=token.AttributeStringValue("link");
660  // find optional findexdoc
661  mFrefSummary="";
662  if(rTr.ExistsBegin("fsummary")) {
663  rTr.ReadBegin("fsummary");
665  rTr.ReadEnd("fsummary");
666  }
667  // autodetect misslabled index pages
668  if(mFrefPage=="") {
669  std::string indexfile=mFrefSection + "_index.fref";
670  std::transform(indexfile.begin(), indexfile.end(), indexfile.begin(), tolower);
671  if(ExtractFilename(rTr.FileName())==indexfile)
672  mFrefPage="0_Index";
673  }
674  // ensure page number for index page
675  if(mFrefPage=="index") mFrefPage="Index";
676  if(mFrefPage=="Index") mFrefPage="0_Index";
677  // autogenerate page name
678  if(mFrefPage=="") {
680  std::string title=mFrefTitle;
681  std::transform(mFrefTitle.begin(), mFrefTitle.end(), title.begin(), tolower);
682  std::string section=mFrefSection;
683  std::transform(mFrefSection.begin(), mFrefSection.end(), section.begin(), tolower);
684  std::size_t spos = title.find(section);
685  if(spos==0 && title.size()>section.size())
686  mFrefPage=mFrefPage.substr(section.size(),mFrefPage.size()-section.size());
687  for(spos=0; spos<mFrefPage.size(); spos++){
688  int c= mFrefPage.at(spos);
689  if(c==' ') continue;
690  if(c=='-') continue;
691  if(c=='_') continue;
692  break;
693  }
694  if(spos<mFrefPage.size())
695  mFrefPage=mFrefPage.substr(spos,mFrefPage.size()-spos);
696  if(mFrefPage=="Index") mFrefPage="";
697  }
698  // read end
699  rTr.ReadEnd("ReferencePage");
700  // report
701  // std::cerr << "ref2html: found chapter \"" << mFrefChapter << "\" section \"" << mFrefSection << "\"" << std::endl;
702  // record
703  PageRecord pagerec;
704  pagerec.mChapter = mFrefChapter;
705  pagerec.mSection = mFrefSection;
706  pagerec.mPage = mFrefPage;
707  pagerec.mTitle = mFrefTitle;
708  pagerec.mLink = mFrefLink;
709  pagerec.mSummary=mFrefSummary;
710  // normalize
711  std::transform(mFrefChapter.begin(), mFrefChapter.end(), mFrefChapter.begin(), tolower);
712  std::transform(mFrefSection.begin(), mFrefSection.end(), mFrefSection.begin(), tolower);
713  std::transform(mFrefPage.begin(), mFrefPage.end(), mFrefPage.begin(), tolower);
714  // insert entry
715  if(mFrefChapter!="")
716  if(mFrefChapter!="none")
717  mAllPages.push_back(pagerec);
718  // insert entry to section pages of reference
719  if(mFrefChapter=="reference")
720  if(mFrefPage!="")
721  if(mFrefPage!="none")
723  }
724 }
725 
726 
727 // dump page records to include file
728 void DumpPages(TokenWriter& rTw) {
729  // loop records
730  std::vector<PageRecord>::iterator pit;
731  for(pit=mAllPages.begin(); pit!=mAllPages.end(); pit++) {
732  Token btag;
733  btag.SetEmpty("ReferencePage");
734  btag.InsAttributeString("title",pit->mTitle);
735  btag.InsAttributeString("chapter",pit->mChapter);
736  btag.InsAttributeString("section",pit->mSection);
737  btag.InsAttributeString("page",pit->mPage);
738  btag.InsAttributeString("link",pit->mLink);
739  // if we have no summary, that's it
740  if(pit->mSummary=="") {
741  rTw << btag << "\n";
742  continue;
743  }
744  // summary present
745  btag.ClrEnd();
746  rTw << btag << "\n";
747  rTw.WriteBegin("fsummary");
748  rTw.WriteCharacterData(pit->mSummary);
749  rTw.WriteEnd("fsummary");
750  rTw << "\n";
751  rTw.WriteEnd("ReferencePage");
752  }
753 }
754 
755 
756 // ******************************************************************
757 // search for types
758 // ******************************************************************
759 
760 void ListTypesHtml(std::ostream* pIndexFile, const std::string& key="") {
761 
762  // table output
763  *pIndexFile << "<table class=\"registry_toc\">" << std::endl;
764  // traverse type registry
765  bool found=false;
766  for(TypeRegistry::Iterator tit=TypeRegistry::G()->Begin();
767  tit!=TypeRegistry::G()->End(); tit++) {
768  // test for exact key
769  if(key!="") {
770  std::string section= tit->second->Name();
771  std::transform(section.begin(), section.end(), section.begin(), tolower);
772  if(section!=key) continue;
773  }
774  // test for user doc
775  if(tit->second->TextDoc()=="") continue;
776  // table row
777  *pIndexFile << "<tr><td valign=\"top\">";
778  TypeHtml(pIndexFile,tit->second->Name());
779  *pIndexFile << "</td><td valign=\"top\">";
780  TypeHtml(pIndexFile,tit->second->TextDoc());
781  *pIndexFile << "</td></tr>" << std::endl;
782  // record success
783  found=true;
784  }
785  // no matches
786  if(!found) *pIndexFile << "<tr><td><i>no matches found</i></td></tr>" << std::endl;
787  // table output
788  *pIndexFile << "</table>" << std::endl;
789 }
790 
791 // ******************************************************************
792 // search for functions
793 // ******************************************************************
794 
795 void ListFunctionsHtml(std::ostream* pIndexFile, const std::string& key="") {
796 
797  // table output
798  *pIndexFile << "<table class=\"registry_toc\">" << std::endl;
799  // traverse function registry
800  bool found=false;
802  fit!=FunctionRegistry::G()->End(); fit++) {
803  // test for exact key
804  if(key!="") {
805  std::string section= fit->second->Name();
806  std::transform(section.begin(), section.end(), section.begin(), tolower);
807  if(section!=key) continue;
808  }
809  // test for user doc
810  if(fit->second->TextDoc()=="") continue;
811  // table row
812  *pIndexFile << "<tr><td valign=\"top\">";
813  FunctionHtml(pIndexFile,fit->second->Name());
814  *pIndexFile << "</td><td valign=\"top\">";
815  TypeHtml(pIndexFile,fit->second->TextDoc());
816  *pIndexFile << "</td></tr>" << std::endl;
817  // record success
818  found=true;
819  }
820  // no matches
821  if(!found) *pIndexFile << "<tr><td><i>no matches found</i></td></tr>" << std::endl;
822  // table output
823  *pIndexFile << "</table>" << std::endl;
824 }
825 
826 // ******************************************************************
827 // search for sections
828 // ******************************************************************
829 
830 void ListSectionsHtml(std::ostream* pIndexFile, const std::string& key="") {
831 
832  // here: use special key "luaext" to filter lua-extensions"
833 
834  // traverse pages
835  std::set< std::string > sections;
836  std::map< std::string , std::string > link;
837  std::map< std::string , std::string > summary;
838  std::vector< PageRecord >::iterator pit;
839  for(pit=mAllPages.begin(); pit != mAllPages.end(); pit++) {
840  std::string chap=pit->mChapter;
841  std::transform(chap.begin(), chap.end(), chap.begin(), tolower);
842  std::string sect=pit->mSection;
843  std::transform(sect.begin(), sect.end(), sect.begin(), tolower);
844  std::string page=pit->mPage;
845  std::transform(page.begin(), page.end(), page.begin(), tolower);
846  page=PrettyPage(page);
847  // my chapter only
848  if(chap!="reference") continue;
849  if(sect=="none") continue;
850  if(sect=="") continue;
851  if(page!="index") continue;
852  // lua ext only
853  if(key=="luaext") {
854  if(mExclLuaSections.find(sect)!=mExclLuaSections.end()) continue;
855  if(mInclLuaSections.find(sect)==mInclLuaSections.end()) continue;
856  }
857  // get nice name
858  std::string pname = pit->mSection;
859  // use title as fallback summary
860  std::string psumm = pit->mSummary;
861  if(psumm=="") psumm = pit->mTitle;
862  // record
863  sections.insert(pname);
864  link[pname]=pit->mLink;
865  summary[pname]=psumm;
866  }
867 
868  // produce sorted index with corefaudes first
869  std::vector< std::string > sortvec;
870  if(sections.find("CoreFaudes")!=sections.end())
871  sortvec.push_back("CoreFaudes");
872  std::set< std::string >::iterator sit;
873  for(sit=sections.begin(); sit != sections.end(); sit++) {
874  if(*sit=="CoreFaudes") continue;
875  sortvec.push_back(*sit);
876  }
877 
878  // table output
879  *pIndexFile << "<table class=\"registry_toc\">" << std::endl;
880 
881  // populate table
882  std::vector< std::string >::iterator vit;
883  bool found=false;
884  for(vit=sortvec.begin(); vit != sortvec.end(); vit++) {
885  // get nice name
886  std::string sname = *vit;
887  std::string shtml = mReferencePrefix+link[sname];
888  std::string ssumm = summary[sname];
889  // table row
890  *pIndexFile << "<tr>" << std::endl;
891  *pIndexFile << "<td valign=\"top\"><a href=\"" << shtml << "\">" << sname << "</a></td>";
892  *pIndexFile << "<td valign=\"top\">";
893  *pIndexFile << ssumm;
894  *pIndexFile << "</td></tr>"<< std::endl;
895  // record success
896  found=true;
897  }
898  // no matches
899  if(!found) *pIndexFile << "<tr><td><i>no matches found</i></td></tr>" << std::endl;
900 
901  // table output
902  *pIndexFile << "</table>" << std::endl;
903 }
904 
905 
906 
907 
908 
909 // ******************************************************************
910 // Type index by keyword (aka section name)
911 // ******************************************************************
912 
913 void TypeIndexHtml(std::ostream* pIndexFile, const std::string& key="") {
914 
915  // traverse type registry
916  bool head=false;
917  for(TypeRegistry::Iterator tit=TypeRegistry::G()->Begin();
918  tit!=TypeRegistry::G()->End(); tit++)
919  {
920  // test for exact key
921  if(key!="") {
922  std::string section= tit->second->KeywordAt(0);
923  std::transform(section.begin(), section.end(), section.begin(), tolower);
924  if(section!=key) continue;
925  }
926  // get name and reference
927  std::string tyname = tit->second->Name();
928  std::string tyhtml = tit->second->HtmlDoc();
929  // no doc
930  if(tyhtml=="") continue;
931  if(tyhtml=="none") continue;
932  // head line
933  if(!head) {
934  head=true;
935  *pIndexFile << "<li class=\"registry_heading\">Types</li>" << std::endl;
936  }
937  // index entry for this type
938  ListItemHtml(pIndexFile, tyhtml, tyname);
939  }
940  // done
941  if(head) *pIndexFile << "<li class=\"registry_blanc\">&nbsp;</li>" << std::endl;
942 }
943 
944 // ******************************************************************
945 // Function index by keyword (aka plugin)
946 // ******************************************************************
947 
948 void FunctionIndexHtml(std::ostream* pIndexFile, const std::string& key="") {
949 
950  // have lower case key
951  std::string lkey=key;
952  std::transform(lkey.begin(), lkey.end(), lkey.begin(), tolower);
953 
954  // traverse function registry
955  bool head=false;
957  fit!=FunctionRegistry::G()->End(); fit++)
958  {
959  // test for key
960  if(lkey!="") {
961  std::string section= fit->second->KeywordAt(0);
962  std::transform(section.begin(), section.end(), section.begin(), tolower);
963  if(section!=lkey) continue;
964  }
965  // test for user doc
966  if(fit->second->TextDoc()=="") continue;
967  // index entry for this function
968  std::string fname = fit->second->Name();
969  std::string fhtml = fit->second->HtmlDoc();
970  if(fhtml=="") continue;
971  // head line
972  if(!head){
973  head=true;
974  *pIndexFile << "<li class=\"registry_heading\">Functions</li>" << std::endl;
975  }
976  // list entry: no doc
977  if(fhtml=="none") {
978  *pIndexFile << "<li class=\"registry_item\"> "<< fname << "</li>" << std::endl;
979  continue;
980  }
981  // list entry: link
982  ListItemHtml(pIndexFile, fhtml, fname);
983  }
984 
985  // done
986  if(head) *pIndexFile << "<li class=\"registry_blanc\">&nbsp;</li>" << std::endl;
987 
988 }
989 
990 // ******************************************************************
991 // Reference index by keyword (aka section)
992 // ******************************************************************
993 
994 void ReferenceIndexHtml(std::ostream* pIndexFile, const std::string& key="") {
995 
996  // prepare list of all sections
997  std::map< std::string , std::string > sectlink;
998  std::vector< PageRecord >::iterator pit;
999  for(pit=mAllPages.begin(); pit != mAllPages.end(); pit++) {
1000  std::string chap=pit->mChapter;
1001  std::transform(chap.begin(), chap.end(), chap.begin(), tolower);
1002  std::string sect=pit->mSection;
1003  std::transform(sect.begin(), sect.end(), sect.begin(), tolower);
1004  // my chapter only
1005  if(chap!="reference") continue;
1006  if(sect=="none") continue;
1007  if(sect=="") continue;
1008  // get nice name
1009  std::string pname = pit->mSection;
1010  // have link
1011  std::string phtml = sect+"_index.html";
1012  // record
1013  sectlink[pname]=phtml;
1014  }
1015 
1016  // produce sorted index, have corefaudes first
1017  std::vector< std::string > sections;
1018  if(sectlink["CoreFaudes"]!="") sections.push_back("CoreFaudes");
1019  std::map< std::string , std::string >::iterator sit;
1020  for(sit=sectlink.begin(); sit!=sectlink.end(); sit++) {
1021  std::string psect=sit->first;
1022  if(psect=="CoreFaudes") continue;
1023  sections.push_back(psect);
1024  }
1025 
1026  // sections headline
1027  if(sections.size()!=0)
1028  *pIndexFile << "<li class=\"registry_heading\">Sections</li>" << std::endl;
1029 
1030  // iterate sections
1031  std::size_t vit;
1032  for(vit=0; vit<sections.size(); vit++) {
1033  std::string psect=sections.at(vit);
1034  std::string plink=sectlink[psect];
1035  if(plink=="") continue;
1036  // find all pages within reference that match this section (keys to lower, skip index)
1037  std::string sect=psect;
1038  std::transform(sect.begin(), sect.end(), sect.begin(), tolower);
1039  std::map< std::string , std::map< std::string , PageRecord > > ::iterator spit = mRefSectPages.find(sect);
1040  int pcnt=0;
1041  if(spit!=mRefSectPages.end()) {
1042  std::map< std::string , PageRecord >::iterator pit = spit->second.begin();
1043  for(;pit!=spit->second.end();pit++) {
1044  std::string ppage = pit->second.mPage;
1045  std::transform(ppage.begin(), ppage.end(), ppage.begin(), tolower);
1046  if(ppage=="index") continue;
1047  if(ppage=="0_index") continue;
1048  if(ppage=="00_index") continue;
1049  pcnt++;
1050  }
1051  }
1052  // case a) no pages: just a link
1053  if(pcnt==0) {
1054  ListItemHtml(pIndexFile, plink, psect);
1055  continue;
1056  }
1057  // case b) generate link for sub menu for pages (do this my self)
1058  *pIndexFile << "<li class=\"registry_pitem\">" << std::endl
1059  << "<a href=\"" << plink << "\">" << psect << "</a>" << std::endl
1060  << "<a href=\"" << plink << "\" class=\"registry_blinda\">&nbsp;</a>" << std::endl
1061  << "<ul>" << std::endl
1062  << "<li class=\"registry_heading\">" << psect << "</li>" << std::endl;
1063  std::map< std::string , PageRecord >::iterator pit = spit->second.begin();
1064  for(;pit!=spit->second.end();pit++) {
1065  // swallow page number
1066  std::string ppage = PrettyPage(pit->second.mPage);
1067  // normalize
1068  std::string ipage = ppage;
1069  std::transform(ipage.begin(), ipage.end(), ipage.begin(), tolower);
1070  // rename indes
1071  if(ipage=="index") ppage="Introduction";
1072  // page entry
1073  *pIndexFile << "<li class=\"registry_item\"><a href=\"" << pit->second.mLink << "\">"
1074  << ppage << "</a></li>" << std::endl;
1075  }
1076  // close page list
1077  *pIndexFile << "</ul></li>" << std::endl;
1078  }
1079 
1080  // sections done
1081  if(sections.size()!=0)
1082  *pIndexFile << "<li class=\"registry_blanc\">&nbsp;</li>" << std::endl;
1083 
1084  // list types
1085  if(key!="") TypeIndexHtml(pIndexFile,key);
1086 
1087  // list functions
1088  if(key!="") FunctionIndexHtml(pIndexFile,key);
1089 }
1090 
1091 
1092 // ******************************************************************
1093 // Section index (aka bottom navigation for key section)
1094 // ******************************************************************
1095 
1096 
1097 void SectionIndexHtml(std::ostream* pIndexFile, const std::string& key) {
1098 
1099  // find all pages within reference that match this section (keys to lower, skip index)
1100  std::string sect=key;
1101  std::transform(sect.begin(), sect.end(), sect.begin(), tolower);
1102  std::string plink=sect+"_index.html";
1103  std::string psect=key;
1104  std::map< std::string , std::map< std::string , PageRecord > > ::iterator spit = mRefSectPages.find(sect);
1105  int pcnt=0;
1106  if(spit!=mRefSectPages.end()) {
1107  std::map< std::string , PageRecord >::iterator pit = spit->second.begin();
1108  for(;pit!=spit->second.end();pit++) {
1109  std::string ppage = pit->second.mPage;
1110  psect=pit->second.mSection;
1111  std::transform(ppage.begin(), ppage.end(), ppage.begin(), tolower);
1112  if(ppage=="index") continue;
1113  if(ppage=="0_index") continue;
1114  if(ppage=="00_index") continue;
1115  pcnt++;
1116  }
1117  }
1118 
1119  // bail out if there are no pages
1120  //if(pcnt==0) return;
1121 
1122  // tweak: key="" refers to the reference_index.html
1123  if(key=="") psect="Reference";
1124 
1125  // generate menu for pages
1126  *pIndexFile << "<li class=\"registry_heading\">" << psect << "</li>" << std::endl;
1127  std::map< std::string , PageRecord >::iterator pit = spit->second.begin();
1128  for(;pit!=spit->second.end();pit++) {
1129  // swallow page number
1130  std::string ppage = PrettyPage(pit->second.mPage);
1131  // normalize
1132  std::string ipage = ppage;
1133  std::transform(ipage.begin(), ipage.end(), ipage.begin(), tolower);
1134  // rename index
1135  if(ipage=="index") ppage="Introduction";
1136  // page entry
1137  *pIndexFile << "<li class=\"registry_item\"><a href=\"" << pit->second.mLink << "\">"
1138  << ppage << "</a></li>" << std::endl;
1139  }
1140 }
1141 
1142 
1143 // ******************************************************************
1144 // signature
1145 // ******************************************************************
1146 
1147 void SignatureHtml(std::ostream* pOutFile, std::string function) {
1148 
1149  // bail out on non existence
1150  if(!FunctionRegistry::G()->Exists(function)) return;
1151 
1152  // function definition
1153  const FunctionDefinition& fdef=FunctionRegistry::G()->Definition(function);
1154 
1155  // bail out if there is no signature
1156  if(fdef.VariantsSize()==0) return;
1157 
1158  // start signature box
1159  *pOutFile << "<div class=\"registry_signature\">" << std::endl;
1160  *pOutFile << "<h5><strong>Signature:</strong></h5>" << std::endl;
1161 
1162  // loop signatures
1163  for(int i=0; i< fdef.VariantsSize(); i++) {
1164  const Signature& sigi=fdef.Variant(i);
1165  *pOutFile << "<p>" << fdef.Name() << "(";
1166  // loop params
1167  for(int j=0; j < sigi.Size(); j++) {
1168  if(j!=0) *pOutFile << ", ";
1169  const Parameter& parj=sigi.At(j);
1170  *pOutFile << "<span>+" << Parameter::AStr(parj.Attribute()) << "+ ";
1171  TypeHtml(pOutFile,parj.Type());
1172  *pOutFile << " <i>" << parj.Name() << "</i></span>";
1173  }
1174  *pOutFile << ")</p>" << std::endl;
1175  }
1176 
1177 
1178  // close signature box
1179  *pOutFile << std::endl << "</div>" << std::endl;
1180 }
1181 
1182 // ******************************************************************
1183 // short doc
1184 // ******************************************************************
1185 
1186 void ShortdocHtml(std::ostream* pOutFile, std::string fname) {
1187 
1188  // its a function
1189  if(FunctionRegistry::G()->Exists(fname)) {
1190 
1191  // function definition
1192  const FunctionDefinition& fdef=FunctionRegistry::G()->Definition(fname);
1193 
1194  // stream doc
1195  //*pOutFile << "<div class=\"registry_signature\">" << std::endl;
1196  *pOutFile << "<p>" << fdef.TextDoc() << "</p>" << std::endl;
1197  //*pOutFile << "</div>" << std::endl;
1198 
1199  // stream signature
1200  SignatureHtml(pOutFile,fname);
1201  }
1202 
1203  // its a type
1204  if(TypeRegistry::G()->Exists(fname)) {
1205 
1206  // type definition
1207  const TypeDefinition& tdef=TypeRegistry::G()->Definition(fname);
1208 
1209  // stream doc
1210  //*pOutFile << "<div class=\"registry_signature\">" << std::endl;
1211  *pOutFile << "<p>" << tdef.TextDoc() << "<p>" << std::endl;
1212  //*pOutFile << "</div>" << std::endl;
1213 
1214  }
1215 
1216 }
1217 
1218 
1219 
1220 
1221 // ******************************************************************
1222 // record literature
1223 // ******************************************************************
1224 
1225 // record
1227 public:
1228  std::string mLabel;
1229  std::string mLink;
1230  std::string mAuthors;
1231  std::string mTitle;
1232  std::string mJournal;
1233  std::string mPublisher;
1234  std::string mYear;
1235 };
1236 
1237 // data
1238 std::map<std::string,LiteratureRecord> mLiterature;
1239 
1240 // extract all from a section
1242  // record my level
1243  int clevel = rTr.Level();
1244  // std::cerr << "process level " << clevel << "\n";
1245  // token loop
1246  while(true) {
1247  // skip plain text
1248  std::string text=rTr.ReadCharacterData();
1249  if(text.size()>0) continue;
1250  // break on no token or end of my level
1251  Token token;
1252  if(!rTr.Peek(token)) break;
1253  if(token.IsEnd() && !token.IsBegin() && rTr.Level()==clevel)
1254  break;
1255  // track where we are
1256  if(token.IsBegin("ReferencePage")) {
1257  mFrefChapter="";
1258  if(token.ExistsAttributeString("chapter"))
1259  mFrefChapter=token.AttributeStringValue("chapter");
1260  mFrefSection="";
1261  if(token.ExistsAttributeString("section"))
1262  mFrefSection=token.AttributeStringValue("section");
1263  std::transform(mFrefChapter.begin(), mFrefChapter.end(), mFrefChapter.begin(), tolower);
1264  std::transform(mFrefSection.begin(), mFrefSection.end(), mFrefSection.begin(), tolower);
1265  // report
1266  // std::cerr << "ref2html: found chapter \"" << mFrefChapter << "\" section \"" << mFrefSection << "\"" << std::endl;
1267  }
1268  // ignore other tokens
1269  if(!token.IsBegin("fliterature")) {
1270  rTr.Get(token);
1271  continue;
1272  }
1273  // do my special tag: fliterature
1274  rTr.ReadBegin("fliterature");
1275  std::string label=token.AttributeStringValue("name");
1276  //std::cerr << "process literature " << label << "\n";
1277  LiteratureRecord litrec;
1278  litrec.mLabel=label;
1279  litrec.mLink = mFrefSection + "_index.html#lit_" + label;
1280  //process entries
1281  while(!rTr.Eos("fliterature")) {
1282  Token token;
1283  rTr.Peek(token);
1284  //std::cerr << "process literature peek " << token.Str() << "\n";
1285  if(token.IsBegin("fauthors")) {
1286  rTr.ReadBegin("fauthors");
1287  litrec.mAuthors=rTr.ReadSection();
1288  rTr.ReadEnd("fauthors");
1289  continue;
1290  }
1291  if(token.IsBegin("ftitle")) {
1292  rTr.ReadBegin("ftitle");
1293  litrec.mTitle=rTr.ReadSection();
1294  rTr.ReadEnd("ftitle");
1295  continue;
1296  }
1297  if(token.IsBegin("fjournal")) {
1298  rTr.ReadBegin("fjournal");
1299  litrec.mJournal=rTr.ReadSection();
1300  rTr.ReadEnd("fjournal");
1301  continue;
1302  }
1303  if(token.IsBegin("fyear")) {
1304  rTr.ReadBegin("fyear");
1305  litrec.mYear=rTr.ReadSection();
1306  rTr.ReadEnd("fyear");
1307  continue;
1308  }
1309  if(token.IsBegin("flink")) {
1310  rTr.ReadBegin("flink");
1311  litrec.mLink=rTr.ReadSection();
1312  rTr.ReadEnd("flink");
1313  continue;
1314  }
1315  if(token.IsBegin()) {
1316  rTr.ReadBegin(token.StringValue());
1317  rTr.ReadEnd(token.StringValue());
1318  continue;
1319  }
1320  rTr.Get(token);
1321  }
1322  // insert entry
1323  if(litrec.mLabel!="")
1324  mLiterature[litrec.mLabel]=litrec;
1325  // done
1326  rTr.ReadEnd("fliterature");
1327  }
1328 }
1329 
1330 
1331 // dump literature records to include file
1333  // loop records
1334  std::map<std::string,LiteratureRecord>::iterator lit;
1335  for(lit=mLiterature.begin(); lit!=mLiterature.end(); lit++) {
1336  Token btag;
1337  btag.SetBegin("fliterature");
1338  btag.InsAttributeString("name",lit->second.mLabel);
1339  rTw << btag << "\n";
1340  if(lit->second.mAuthors!="") {
1341  rTw.WriteBegin("fauthors");
1342  rTw.WriteCharacterData(lit->second.mAuthors);
1343  rTw.WriteEnd("fauthors");
1344  rTw <<"\n";
1345  }
1346  if(lit->second.mTitle!="") {
1347  rTw.WriteBegin("ftitle");
1348  rTw.WriteCharacterData(lit->second.mTitle);
1349  rTw.WriteEnd("ftitle");
1350  rTw <<"\n";
1351  }
1352  if(lit->second.mJournal!="") {
1353  rTw.WriteBegin("fjournal");
1354  rTw.WriteCharacterData(lit->second.mJournal);
1355  rTw.WriteEnd("fjournal");
1356  rTw <<"\n";
1357  }
1358  if(lit->second.mPublisher!="") {
1359  rTw.WriteBegin("fpublisher");
1360  rTw.WriteCharacterData(lit->second.mPublisher);
1361  rTw.WriteEnd("fpublisher");
1362  rTw <<"\n";
1363  }
1364  if(lit->second.mYear!="") {
1365  rTw.WriteBegin("fyear");
1366  rTw.WriteCharacterData(lit->second.mYear);
1367  rTw.WriteEnd("fyear");
1368  rTw <<"\n";
1369  }
1370  if(lit->second.mLink!="") {
1371  rTw.WriteBegin("flink");
1372  rTw.WriteCharacterData(lit->second.mLink);
1373  rTw.WriteEnd("flink");
1374  rTw <<"\n";
1375  }
1376  rTw.WriteEnd("fliterature"); rTw <<"\n";
1377  rTw.Endl();
1378  }
1379 }
1380 
1381 
1382 // html for (one) literature reference
1383 void LiteratureHtml(std::ostream* pStream, const std::string& rLabel="") {
1384  // loop records
1385  std::map<std::string,LiteratureRecord>::iterator lit;
1386  for(lit=mLiterature.begin(); lit!=mLiterature.end(); lit++) {
1387  // skip for no match
1388  if(rLabel!="")
1389  if(rLabel!=lit->second.mLabel) continue;
1390  // produce html
1391  *pStream << "<p>" << std::endl;
1392  *pStream << "<a id=\"" << "lit_" << lit->second.mLabel << "\">[" << lit->second.mLabel << "]</a>" << std::endl;
1393  *pStream << lit->second.mAuthors << ": ";
1394  *pStream << "<i>" << lit->second.mTitle << "</i>";
1395  if(lit->second.mJournal!="") *pStream << ", " << lit->second.mJournal;
1396  if(lit->second.mPublisher!="") *pStream << ", " << lit->second.mPublisher;
1397  if(lit->second.mYear!="") *pStream << ", " << lit->second.mYear;
1398  *pStream << ".</p>" << std::endl;
1399  }
1400 }
1401 
1402 
1403 // html for literature citation
1404 void CiteHtml(std::ostream* pStream, const std::string& rLabel) {
1405  // prepare
1406  std::string link="reference_literature.html";
1407  // find records
1408  std::map<std::string,LiteratureRecord>::iterator lit;
1409  lit=mLiterature.find(rLabel);
1410  if(lit!=mLiterature.end()) link=lit->second.mLink;
1411  // produce HTML
1412  *pStream << "<a href=\"" << link << "\">[" << rLabel << "]</a>";
1413 }
1414 
1415 
1416 // ******************************************************************
1417 // extract pages
1418 // ******************************************************************
1419 
1420 void XtractPages(TokenReader& src,const std::string& rDstDir) {
1421 
1422  // scan for reference page sections
1423  Token btag;
1424  while(src.Peek(btag)) {
1425  // skip tokens
1426  if(!btag.IsBegin("ReferencePage")) {
1427  src.Get(btag);
1428  continue;
1429  }
1430  // read begin tag
1431  src.ReadBegin("ReferencePage",btag);
1432  // extract title & friends
1433  mFrefTitle="libFAUDES Reference";
1434  if(btag.ExistsAttributeString("title"))
1435  mFrefTitle=btag.AttributeStringValue("title");
1436  mFrefChapter="Reference";
1437  if(btag.ExistsAttributeString("chapter"))
1438  mFrefChapter=btag.AttributeStringValue("chapter");
1439  mFrefSection="";
1440  if(btag.ExistsAttributeString("section"))
1441  mFrefSection=btag.AttributeStringValue("section");
1442  mFrefPage="";
1443  if(btag.ExistsAttributeString("page"))
1444  mFrefPage=btag.AttributeStringValue("page");
1445  // insist in page and section
1446  if(mFrefSection=="" || mFrefPage=="") {
1447  std::cerr << "ref2html: skipping undefined page at " << src.FileLine() << std::endl;
1448  src.ReadEnd("ReferencePage");
1449  continue;
1450  }
1451  // normalize & report
1452  std::transform(mFrefChapter.begin(), mFrefChapter.end(), mFrefChapter.begin(), tolower);
1453  std::transform(mFrefSection.begin(), mFrefSection.end(), mFrefSection.begin(), tolower);
1454  std::transform(mFrefPage.begin(), mFrefPage.end(), mFrefPage.begin(), tolower);
1455  // dst file
1456  std::string dstfile=rDstDir + faudes_pathsep() + mFrefSection + "_" + mFrefPage +".fref";
1457  std::cerr << "ref2html: extracting page to \"" << dstfile << "\"" << std::endl;
1458  TokenWriter dst(dstfile);
1459  // copy section
1460  dst.Write(btag);
1461  std::string scttext = src.ReadSection();
1462  dst.WriteCharacterData(scttext);
1463  dst.WriteEnd("ReferencePage");
1464  // read end tag
1465  src.ReadEnd("ReferencePage");
1466  }
1467 }
1468 
1469 // ******************************************************************
1470 // extract files
1471 // ******************************************************************
1472 
1473 void XtractFiles(TokenReader& src,const std::string& rDstDir) {
1474 
1475  // scan for file sections
1476  Token btag;
1477  while(src.Peek(btag)) {
1478  // skip tokens
1479  if(!btag.IsBegin("ImageFile")) {
1480  src.Get(btag);
1481  continue;
1482  }
1483  // read begin tag
1484  src.ReadBegin("ImageFile",btag);
1485  std::string name=btag.AttributeStringValue("name");
1486  if(name==""){
1487  std::cerr << "ref2html: skipping undefined image file at " << src.FileLine() << std::endl;
1488  src.ReadEnd("ImageFile");
1489  continue;
1490  }
1491  // read data
1492  Token data;
1493  src.Get(data);
1494  if(!data.IsBinary()){
1495  std::cerr << "ref2html: skipping invalid image file at " << src.FileLine() << std::endl;
1496  src.ReadEnd("ImageFile");
1497  continue;
1498  }
1499  // dst file
1500  std::string dstfile=rDstDir + faudes_pathsep() + "images" +
1501  faudes_pathsep() + name;
1502  std::transform(dstfile.begin(), dstfile.end(), dstfile.begin(), tolower);
1503  std::cerr << "ref2html: extracting image file to \"" << dstfile << "\"" << std::endl;
1504  // setup stream
1505  std::fstream fsout;
1506  fsout.exceptions(std::ios::badbit|std::ios::failbit);
1507  try{
1508  fsout.open(dstfile.c_str(), std::ios::out | std::ios::binary);
1509  fsout.write(data.StringValue().c_str(),data.StringValue().size());
1510  fsout.close();
1511  }
1512  catch (std::ios::failure&) {
1513  std::cerr << "ref2html: file io error when writing \"" << dstfile << "\"" << std::endl;
1514  }
1515  // read end tag
1516  src.ReadEnd("ImageFile");
1517  }
1518 }
1519 
1520 // ******************************************************************
1521 // luafaudes index
1522 // ******************************************************************
1523 
1524 void LuafaudesIndexHtml(std::ostream* pIndexFile) {
1525 
1526  // prepare list of all sections
1527  std::map< std::string , std::string > pages;
1528  std::vector< PageRecord >::iterator pit;
1529  for(pit=mAllPages.begin(); pit != mAllPages.end(); pit++) {
1530  // my chapter only
1531  if(pit->mChapter!="luafaudes") continue;
1532  if(pit->mSection=="none") continue;
1533  if(pit->mSection=="") continue;
1534  if(pit->mPage=="") continue;
1535  // get nice name
1536  std::string pname = pit->mPage;
1537  // have link
1538  std::string phtml = pit->mLink;
1539  // record
1540  pages[pname]=phtml;
1541  }
1542  // produce sorted index
1543  std::map< std::string , std::string >::iterator sit;
1544  for(sit=pages.begin(); sit!=pages.end(); sit++) {
1545  // have entry
1546  ListItemHtml(pIndexFile,sit->second, sit->first);
1547  }
1548  // empty
1549  if(pages.size()==0) {
1550  *pIndexFile << "<li class=\"registry_item\">" << "none" << "</li>" << std::endl;
1551  }
1552 }
1553 
1554 // ******************************************************************
1555 // process current section
1556 // ******************************************************************
1557 
1559 
1560  // record my level
1561  int clevel = rTr.Level();
1562 
1563  // std::cerr << "process level " << clevel << "\n";
1564 
1565  // token copy loop
1566  while(true) {
1567  // see whether we can grab and copy some plain text
1568  std::string text=rTr.ReadCharacterData();
1569  if(text.size()>0) {
1570  //std::cerr << "copy text \"" << text << "\"\n";
1571  *rTw.Streamp() << text;
1572  continue;
1573  }
1574  // break on no token or end of my level
1575  Token token;
1576  if(!rTr.Peek(token)) break;
1577  if(token.IsEnd() && !token.IsBegin() && rTr.Level()==clevel)
1578  break;
1579  // do my special tags: ftype
1580  if(token.IsBegin("ftype")) {
1581  rTr.ReadBegin("ftype");
1582  std::string ftype=rTr.ReadText();
1583  TypeHtml(rTw.Streamp(),ftype);
1584  rTr.ReadEnd("ftype");
1585  continue;
1586  }
1587  // do my special tags: ffnct
1588  if(token.IsBegin("ffnct")) {
1589  rTr.ReadBegin("ffnct");
1590  std::string ffnct=rTr.ReadText();
1591  FunctionHtml(rTw.Streamp(),ffnct);
1592  rTr.ReadEnd("ffnct");
1593  continue;
1594  }
1595  // do my special tags: fimage
1596  if(token.IsBegin("fimage")) {
1597  rTr.ReadBegin("fimage", token);
1598  std::string fsrc=token.AttributeStringValue("fsrc");
1599  fsrc = StringSubstitute(fsrc,"FAUDES_IMAGES/",""); // be nice
1600  fsrc = ExtractBasename(fsrc); // be even niecer
1601  ImageHtml(rTw.Streamp(),fsrc);
1602  rTr.ReadEnd("fimage");
1603  continue;
1604  }
1605  // do my special tags: dmath
1606  if(token.IsBegin("fdmath")) {
1607  rTr.ReadBegin("fdmath", token);
1608  std::string mtext=rTr.ReadCharacterData();
1609  *rTw.Streamp()<< "<span class=\"faudes_dmath\">";
1610  MathHtml(rTw.Streamp(),mtext);
1611  *rTw.Streamp()<< "</span>";
1612  rTr.ReadEnd("fdmath");
1613  continue;
1614  }
1615  // do my special tags: dmath
1616  if(token.IsBegin("fimath")) {
1617  rTr.ReadBegin("fimath", token);
1618  std::string mtext=rTr.ReadCharacterData();
1619  *rTw.Streamp()<< "<span class=\"faudes_imath\">";
1620  MathHtml(rTw.Streamp(),mtext);
1621  *rTw.Streamp()<< "</span>";
1622  rTr.ReadEnd("fimath");
1623  continue;
1624  }
1625  // do my special tags: ffnct_reference
1626  if(token.IsBegin("ffnct_reference")) {
1627  rTr.ReadBegin("ffnct_reference", token);
1628  std::string ffnct = token.AttributeStringValue("name");
1629  *rTw.Streamp() << "<div class=\"registry_function\"> <h2>"
1630  << "<a id=\"" << ffnct << "\">" << ffnct << "</a></h2>" << std::endl;
1631  ShortdocHtml(rTw.Streamp(),ffnct);
1632  ProcessSection(rTw,rTr);
1633  *rTw.Streamp() << "</div>" << std::endl;
1634  rTr.ReadEnd("ffnct_reference");
1635  continue;
1636  }
1637  // do my special tags: ftype_reference
1638  if(token.IsBegin("ftype_reference")) {
1639  rTr.ReadBegin("ftype_reference", token);
1640  std::string ffnct = token.AttributeStringValue("name");
1641  *rTw.Streamp() << "<div class=\"registry_type\"> <h2>"
1642  << "<a id=\"" << ffnct << "\">" << ffnct << "</a></h2>" << std::endl;
1643  ShortdocHtml(rTw.Streamp(),ffnct);
1644  ProcessSection(rTw,rTr);
1645  *rTw.Streamp() << "</div>" << std::endl;
1646  rTr.ReadEnd("ftype_reference");
1647  continue;
1648  }
1649  // do my special tags: fdetails
1650  if(token.IsBegin("fdetails")) {
1651  rTr.ReadBegin("fdetails", token);
1652  *rTw.Streamp() << "<h5>Detailed description:</h5>" << std::endl;
1653  rTr.ReadEnd("fdetails");
1654  continue;
1655  }
1656  // do my special tags: fconditions
1657  if(token.IsBegin("fconditions")) {
1658  rTr.ReadBegin("fconditions", token);
1659  *rTw.Streamp() << "<h5>Parameter Conditions:</h5>" << std::endl;
1660  rTr.ReadEnd("fconditions");
1661  continue;
1662  }
1663  // do my special tags: fexample
1664  if(token.IsBegin("fexample")) {
1665  rTr.ReadBegin("fexample", token);
1666  *rTw.Streamp() << "<h5>Example:</h5>" << std::endl;
1667  rTr.ReadEnd("fexample");
1668  continue;
1669  }
1670  // do my special tags: falltypes
1671  if(token.IsBegin("falltypes")) {
1672  rTr.ReadBegin("falltypes", token);
1673  ListTypesHtml(rTw.Streamp());
1674  rTr.ReadEnd("falltypes");
1675  continue;
1676  }
1677  // do my special tags: fallfncts
1678  if(token.IsBegin("fallfncts")) {
1679  rTr.ReadBegin("fallfncts", token);
1680  ListFunctionsHtml(rTw.Streamp());
1681  rTr.ReadEnd("fallfncts");
1682  continue;
1683  }
1684  // do my special tags: fallsects
1685  if(token.IsBegin("fallsects")) {
1686  rTr.ReadBegin("fallsects", token);
1687  ListSectionsHtml(rTw.Streamp());
1688  rTr.ReadEnd("fallsects");
1689  continue;
1690  }
1691  // do my special tags: fluasects
1692  if(token.IsBegin("fluasects")) {
1693  rTr.ReadBegin("fluasects", token);
1694  ListSectionsHtml(rTw.Streamp(),"luaext");
1695  rTr.ReadEnd("fluasects");
1696  continue;
1697  }
1698  // do my special tags: fliteratur (list all)
1699  if(token.IsBegin("falllit")) {
1700  rTr.ReadBegin("falllit");
1701  LiteratureHtml(rTw.Streamp());
1702  rTr.ReadEnd("falllit");
1703  continue;
1704  }
1705  // do my special tags: fliteratur (definition of)
1706  if(token.IsBegin("fliterature")) {
1707  rTr.ReadBegin("fliterature", token);
1708  std::string label=token.AttributeStringValue("name");
1709  LiteratureHtml(rTw.Streamp(),label);
1710  rTr.ReadEnd("fliterature");
1711  continue;
1712  }
1713  // do my special tags: fcontributors
1714  if(token.IsBegin("fcontributors")) {
1715  rTr.ReadBegin("fcontributors");
1716  *rTw.Streamp() << ContributorsString();
1717  rTr.ReadEnd("fcontributors");
1718  continue;
1719  }
1720  // do my special tags: flink
1721  if(token.IsBegin("fcite")) {
1722  rTr.ReadBegin("fcite", token);
1723  std::string label=token.AttributeStringValue("name");
1724  CiteHtml(rTw.Streamp(),label);
1725  rTr.ReadEnd("fcite");
1726  continue;
1727  }
1728  // do my special tags: fix br for HTML
1729  if(token.IsBegin("br")) {
1730  rTr.ReadBegin("br");
1731  Token etag;
1732  rTr.Peek(etag);
1733  if(etag.IsEnd("br")) rTr.ReadEnd("br"); // optionally accept balanced <br>
1734  token.ClrEnd();
1735  rTw.Write(token); // intentionall write unbalanced <br> for HTML
1736  continue;
1737  }
1738  // do my special tags: fsummary
1739  if(token.IsBegin("fsummary")) {
1740  rTr.ReadBegin("fsummary");
1741  rTr.ReadEnd("fsummary");
1742  continue;
1743  }
1744  // get token to do my special attributes
1745  rTr.Get(token);
1746  //std::cerr << "copy token (lv " << rTr.Level() << "): " << token.Str() << "\n";
1747  // sense chapter classes
1748  if(token.ExistsAttributeString("ftcclass")) {
1749  mThisChapterClass=token.AttributeStringValue("ftcclass");
1750  token.ClrAttribute("ftcclass");
1751  }
1752  if(token.ExistsAttributeString("focclass")) {
1753  mOtherChapterClass=token.AttributeStringValue("focclass");
1754  token.ClrAttribute("focclass");
1755  }
1756  if(token.ExistsAttributeString("fxcclass")) {
1757  mExitChapterClass=token.AttributeStringValue("fxcclass");
1758  token.ClrAttribute("fxcclass");
1759  }
1760  // chapter attribute
1761  if(token.ExistsAttributeString("fchapter")) {
1762  std::string chapter = token.AttributeStringValue("fchapter");
1763  std::string cclass=mOtherChapterClass;
1764  if(chapter==mFrefChapter) cclass=mThisChapterClass;
1765  if(chapter=="exit") cclass=mExitChapterClass;
1766  token.InsAttributeString("class",cclass);
1767  token.ClrAttribute("fchapter");
1768  }
1769  // fhref attribute: ref only
1770  if(token.ExistsAttributeString("fhref") && mStandaloneReference) {
1771  std::string href = token.AttributeStringValue("fhref");
1772  href = StringSubstitute(href,"FAUDES_BOOKS/",mBooksPrefix);
1773  href = StringSubstitute(href,"FAUDES_CHAPTERS/",mChaptersPrefix);
1774  href = StringSubstitute(href,"FAUDES_IMAGES/",mImagePrefix);
1775  href = StringSubstitute(href,"FAUDES_REFERENCE/",mReferencePrefix);
1776  href = StringSubstitute(href,"FAUDES_CSOURCE/",mCsourceLink);
1777  href = StringSubstitute(href,"FAUDES_LUAFAUDES/",mLuafaudesLink);
1778  href = StringSubstitute(href,"FAUDES_ONLINE",mFaudesLink);
1779  href = StringSubstitute(href,"FAUDES_GETLINUX",mDownloadLink+"#Packages");
1780  href = StringSubstitute(href,"FAUDES_GETMSWIN",mDownloadLink+"#Packages");
1781  href = StringSubstitute(href,"DESTOOL_ONLINE",mDestoolLink);
1782  token.InsAttributeString("href",href);
1783  token.ClrAttribute("fhref");
1784  }
1785  // fhref attribute
1786  if(token.ExistsAttributeString("fhref") && !mStandaloneReference) {
1787  std::string href = token.AttributeStringValue("fhref");
1788  href = StringSubstitute(href,"FAUDES_BOOKS/",mBooksPrefix);
1789  href = StringSubstitute(href,"FAUDES_CHAPTERS/",mChaptersPrefix);
1790  href = StringSubstitute(href,"FAUDES_IMAGES/",mImagePrefix);
1791  href = StringSubstitute(href,"FAUDES_REFERENCE/",mReferencePrefix);
1792  href = StringSubstitute(href,"FAUDES_CSOURCE/",mCsourcePrefix);
1793  href = StringSubstitute(href,"FAUDES_LUAFAUDES/",mLuafaudesPrefix);
1794  href = StringSubstitute(href,"FAUDES_ONLINE",mFaudesLink);
1795  href = StringSubstitute(href,"FAUDES_GETLINUX",mDownloadLink+"#Packages");
1796  href = StringSubstitute(href,"FAUDES_GETMSWIN",mDownloadLink+"#Packages");
1797  href = StringSubstitute(href,"DESTOOL_ONLINE",mDestoolLink);
1798  token.InsAttributeString("href",href);
1799  token.ClrAttribute("fhref");
1800  }
1801  // fsrc attribute
1802  if(token.ExistsAttributeString("fsrc")) {
1803  std::string fsrc = token.AttributeStringValue("fsrc");
1804  fsrc = StringSubstitute(fsrc,"FAUDES_IMAGES/",mImagePrefix);
1805  fsrc = StringSubstitute(fsrc,"FAUDES_CSOURCE/",mCsourcePrefix);
1806  fsrc = StringSubstitute(fsrc,"FAUDES_LUAFAUDES/",mLuafaudesPrefix);
1807  token.InsAttributeString("src",fsrc);
1808  token.ClrAttribute("fsrc");
1809  }
1810  rTw.Write(token);
1811  }
1812 }
1813 
1814 
1815 // ******************************************************************
1816 // reference page
1817 // ******************************************************************
1818 
1819 void RefpageHtml(std::ostream* pOutFile, std::string inputfile) {
1820 
1821  // setup token io
1822  TokenReader src(inputfile);
1823  TokenWriter dst(*pOutFile);
1824 
1825  // find the reference page section
1826  Token btag;
1827  src.SeekBegin("ReferencePage");
1828  src.ReadBegin("ReferencePage",btag);
1829 
1830  // extract title & friends
1831  mFrefTitle="libFAUDES Reference";
1832  if(btag.ExistsAttributeString("title"))
1833  mFrefTitle=btag.AttributeStringValue("title");
1834  mFrefChapter="";
1835  if(btag.ExistsAttributeString("chapter"))
1836  mFrefChapter=btag.AttributeStringValue("chapter");
1837  mFrefSection="";
1838  if(btag.ExistsAttributeString("section"))
1839  mFrefSection=btag.AttributeStringValue("section");
1840  std::transform(mFrefChapter.begin(), mFrefChapter.end(), mFrefChapter.begin(), tolower);
1841  std::transform(mFrefSection.begin(), mFrefSection.end(), mFrefSection.begin(), tolower);
1842 
1843  // report
1844  // std::cerr << "ref2html: found chapter \"" << mFrefChapter << "\" section \"" << mFrefSection << "\"" << std::endl;
1845 
1846  // generate generic html header
1847  dst.Flush();
1848  HeaderHtml(pOutFile);
1849 
1850  // begin body
1851  dst.Flush();
1852 
1853  // include chapter level navigation
1854  if(mChapterFile!="") {
1855  //std::cerr << "using " << mChapterFile << std::endl;
1857  ProcessSection(dst,inc);
1858  }
1859 
1860  // include section level navigation, part 1
1861  if(mFrefChapter=="reference") {
1862  *pOutFile << "<table id=\"registry_page\">" << std::endl;
1863  *pOutFile << "<tr id=\"registry_row\">" << std::endl;
1864  *pOutFile << "<td id=\"registry_index\">" << std::endl;
1865  *pOutFile << "<ul class=\"registry_list\">" << std::endl;
1866  *pOutFile << "<li class=\"registry_heading\">libFAUDES</li>" << std::endl;
1867  ListItemHtml(pOutFile,"reference_index.html", "Reference");
1868  ListItemHtml(pOutFile,"reference_types.html", "Type Index");
1869  ListItemHtml(pOutFile,"reference_functions.html", "Function Index");
1870  ListItemHtml(pOutFile,"reference_literature.html", "Literature");
1871  *pOutFile << "<li class=\"registry_blanc\">&nbsp;</li>" << std::endl;
1872  ReferenceIndexHtml(pOutFile, mFrefSection);
1873  *pOutFile << "</ul></td>" << std::endl;
1874  *pOutFile << "<td id=\"registry_content\">" << std::endl;
1875  }
1876 
1877  // include section level navigation, part 1
1878  if(mFrefChapter=="luafaudes") {
1879  *pOutFile << "<table id=\"registry_page\">" << std::endl;
1880  *pOutFile << "<tr id=\"registry_row\">" << std::endl;
1881  *pOutFile << "<td id=\"registry_index\">" << std::endl;
1882  *pOutFile << "<ul class=\"registry_list\">" << std::endl;
1883  *pOutFile << "<li class=\"registry_heading\">luafaudes</li>" << std::endl;
1884  *pOutFile
1885  << "<script language=\"JavaScript\"> var luafaudes=function() { "
1886  << " popupWin = window.open('luafaudes_repl.html','open_window',"
1887  << " 'resizable,dependent, width=720, height=480, left=0, top=0'); } "
1888  << "</script>" << std::endl;
1889  ListItemHtml(pOutFile,"index.html", "Introduction");
1890  ListItemHtml(pOutFile,"javascript:luafaudes();", "Lua-Console");
1891  ListItemHtml(pOutFile,"faudes_luaext.html", "Lua-Extensions");
1892  ListItemHtml(pOutFile,"faudes_luatech.html", "Technical Detail");
1893  *pOutFile << "<li class=\"registry_blanc\">&nbsp;</li>" << std::endl;
1894  *pOutFile << "<li class=\"registry_heading\">Tutorials</li>" << std::endl;
1895  LuafaudesIndexHtml(pOutFile);
1896  *pOutFile << "</ul></td>" << std::endl;
1897  *pOutFile << "<td id=\"registry_content\">" << std::endl;
1898  }
1899 
1900  // process src
1901  ProcessSection(dst,src);
1902  src.ReadEnd("ReferencePage");
1903  dst.Flush();
1904 
1905  // track bottom line
1906  bool bottom=false;
1907 
1908  // include section level navigation, part 2
1909  if(mFrefChapter=="reference") {
1910  BottomLineHtml(pOutFile);
1911  bottom=true;
1912  *pOutFile << "</td>" << std::endl;
1913  *pOutFile << "</tr>" << std::endl;
1914  *pOutFile << "</table>" << std::endl;
1915  }
1916 
1917  // include section level navigation, part 2
1918  if(mFrefChapter=="luafaudes") {
1919  BottomLineHtml(pOutFile);
1920  bottom=true;
1921  *pOutFile << "</td>" << std::endl;
1922  *pOutFile << "</tr>" << std::endl;
1923  *pOutFile << "</table>" << std::endl;
1924  }
1925 
1926  // include section level navigation, part 3
1927  if(mFrefChapter=="reference") {
1928  *pOutFile << "</div>" << std::endl << "</div>" << std::endl;
1929  *pOutFile << "<div id=\"cxwrapper1000\">" << std::endl;
1930  *pOutFile << "<div id=\"dxwrapper1000\">" << std::endl;
1931  *pOutFile << "<div class=\"registry_trigger\"> <span>&gt;&gt;</span>" << std::endl;
1932  *pOutFile << "<ul class=\"registry_list\">" << std::endl;
1933  SectionIndexHtml(pOutFile,mFrefSection);
1934  *pOutFile << "<li class=\"registry_blanc\">&nbsp;</li>" << std::endl;
1935  ListItemHtml(pOutFile,"#", "Top of Page");
1936  *pOutFile << "</ul></div>" << std::endl;
1937  }
1938 
1939  // include section level navigation, part 3
1940  if(mFrefChapter=="luafaudes" && mFrefSection=="tutorials") {
1941  *pOutFile << "</div>" << std::endl << "</div>" << std::endl;
1942  *pOutFile << "<div id=\"cxwrapper1000\">" << std::endl;
1943  *pOutFile << "<div id=\"dxwrapper1000\">" << std::endl;
1944  *pOutFile << "<div class=\"registry_trigger\"> <span>&gt;&gt;</span>" << std::endl;
1945  *pOutFile << "<ul class=\"registry_list\">" << std::endl;
1946  *pOutFile << "<li class=\"registry_heading\">luafaudes</li>" << std::endl;
1947  *pOutFile << "<li class=\"registry_item\"><a href=\"faudes_luafaudes.html\">Introduction</a></li>" << std::endl;
1948  *pOutFile << "<li class=\"registry_item\"><a href=\"faudes_luaext.html\">Lua-Extansions</a></li>" << std::endl;
1949  *pOutFile << "<li class=\"registry_item\"><a href=\"faudes_luatech.html\">Techn. Details</a></li>" << std::endl;
1950  *pOutFile << "<li class=\"registry_blanc\">&nbsp;</li>" << std::endl;
1951  *pOutFile << "<li class=\"registry_item\"><a href=\"#\">Top of Page</a></li>" << std::endl;
1952  *pOutFile << "</ul></div>" << std::endl;
1953  }
1954 
1955  // bottom line
1956  if(!bottom) BottomLineHtml(pOutFile);
1957 
1958  // generic footer
1959  FooterHtml(pOutFile);
1960 
1961 }
1962 
1963 
1964 
1965 // ******************************************************************
1966 // Doxygen header and footer
1967 // ******************************************************************
1968 
1969 void DoxygenHeader(std::ostream* pOutFile) {
1970 
1971  // setup token io
1972  TokenWriter dst(*pOutFile);
1973 
1974  // configure
1975  mFrefTitle="C++ API";
1976  mFrefChapter="cppapi";
1977  mFrefSection="none";
1978 
1979  // generate generic html header
1980  dst.Flush();
1981  HeaderHtml(pOutFile);
1982 
1983  // include chapter level navigation
1984  if(mChapterFile!="") {
1986  ProcessSection(dst,inc);
1987  }
1988 
1989  // include section level navigation, part 1
1990  *pOutFile << "<table id=\"registry_page\">" << std::endl;
1991  *pOutFile << "<tr id=\"registry_row\">" << std::endl;
1992  *pOutFile << "<td id=\"registry_index\">" << std::endl;
1993  *pOutFile << "<ul class=\"registry_list\">" << std::endl;
1994  *pOutFile << "<li class=\"registry_heading\">libFAUDES</li>" << std::endl;
1995  ListItemHtml(pOutFile, "index.html", "C++ API");
1996  *pOutFile << "<li class=\"registry_blanc\">&nbsp;</li>" << std::endl;
1997  *pOutFile << "<li class=\"registry_heading\">Sections</li>" << std::endl;
1998  ListItemHtml(pOutFile, "group__ContainerClasses.html", "Sets");
1999  ListItemHtml(pOutFile, "group__GeneratorClasses.html", "Generators");
2000  ListItemHtml(pOutFile, "group__GeneratorFunctions.html", "Functions");
2001  ListItemHtml(pOutFile, "group__AllPlugins.html", "PlugIns");
2002  ListItemHtml(pOutFile, "group__Tutorials.html", "Tutorials");
2003  *pOutFile << "<li class=\"registry_blanc\">&nbsp;</li>" << std::endl;
2004  *pOutFile << "<li class=\"registry_heading\">Index</li>" << std::endl;
2005  ListItemHtml(pOutFile, "classes.html", "Classes");
2006  ListItemHtml(pOutFile, "files.html", "Files");
2007  *pOutFile << "<li class=\"registry_blanc\">&nbsp;</li>" << std::endl;
2008  *pOutFile << "</ul></td>" << std::endl;
2009  *pOutFile << "<td id=\"registry_content\">" << std::endl;
2010 }
2011 
2012 
2013 void DoxygenFooter(std::ostream* pOutFile) {
2014 
2015  // setup token io
2016  TokenWriter dst(*pOutFile);
2017 
2018  // configure
2019  mFrefTitle="C++ API";
2020  mFrefChapter="cppapi";
2021  mFrefSection="none";
2022 
2023  // include section level navigation, part 2
2024  BottomLineHtml(pOutFile);
2025  *pOutFile << "</td>" << std::endl;
2026  *pOutFile << "</tr>" << std::endl;
2027  *pOutFile << "</table>" << std::endl;
2028 
2029  // include section level navigation, part 3
2030  *pOutFile << "</div>" << std::endl << "</div>" << std::endl;
2031  *pOutFile << "<div id=\"cxwrapper1000\">" << std::endl;
2032  *pOutFile << "<div id=\"dxwrapper1000\">" << std::endl;
2033  *pOutFile << "<div class=\"registry_trigger\"> <span>&gt;&gt;</span>" << std::endl;
2034  *pOutFile << "<ul class=\"registry_list\">" << std::endl;
2035  *pOutFile << "<li class=\"registry_heading\">C++ API</li>" << std::endl;
2036  *pOutFile << "<li class=\"registry_item\"><a href=\"index.html\">Introduction</a></li>" << std::endl;
2037  *pOutFile << "<li class=\"registry_item\"><a href=\"group__ContainerClasses.html\">Sets</a></li>" << std::endl;
2038  *pOutFile << "<li class=\"registry_item\"><a href=\"group__GeneratorClasses.html\">Generators</a></li>" << std::endl;
2039  *pOutFile << "<li class=\"registry_item\"><a href=\"group__GeneratorFunctions.html\">Functions</a></li>" << std::endl;
2040  *pOutFile << "<li class=\"registry_item\"><a href=\"group__AllPlugins.html\">PlugIns</a></li>" << std::endl;
2041  *pOutFile << "<li class=\"registry_item\"><a href=\"group__Tutorials.html\">Tutorials</a></li>" << std::endl;
2042  *pOutFile << "<li class=\"registry_item\"><a href=\"classes.html\">Classes</a></li>" << std::endl;
2043  *pOutFile << "<li class=\"registry_item\"><a href=\"files.html\">Files</a></li>" << std::endl;
2044  *pOutFile << "<li class=\"registry_blanc\">&nbsp;</li>" << std::endl;
2045  *pOutFile << "<li class=\"registry_item\"><a href=\"#\">Top of Page</a></li>" << std::endl;
2046  *pOutFile << "</ul></div>" << std::endl;
2047 
2048  // end page
2049  dst.Flush();
2050  FooterHtml(pOutFile);
2051 
2052 }
2053 
2054 // ******************************************************************
2055 // command line ui
2056 // ******************************************************************
2057 
2058 
2059 int main(int argc, char *argv[]) {
2060 
2061  // local config
2062  bool dotoc=false;
2063  bool dodhd=false;
2064  bool dodft=false;
2065  bool xpage=false;
2066 
2067  // min args
2068  if(argc < 3) usage_exit();
2069 
2070  // primitive commad line parsing
2071  int i;
2072  for(i=1; i<argc; i++) {
2073  std::string option(argv[i]);
2074  // option: rti file
2075  if(option=="-rti") {
2076  i++; if(i>=argc) usage_exit();
2077  mRtiFile=argv[i];
2078  continue;
2079  }
2080  // option: flx file
2081  if(option=="-flx") {
2082  i++; if(i>=argc) usage_exit();
2083  mFlxFile=argv[i];
2084  continue;
2085  }
2086  // option: css file
2087  if(option=="-css") {
2088  i++; if(i>=argc) usage_exit();
2089  mCssFile=argv[i];
2090  continue;
2091  }
2092  // option: navigation include
2093  if(option=="-cnav") {
2094  i++; if(i>=argc) usage_exit();
2095  mChapterFile=argv[i];
2096  continue;
2097  }
2098  // option: toc include
2099  if(option=="-inc") {
2100  i++; if(i>=argc) usage_exit();
2101  mIncludeFile=argv[i];
2102  continue;
2103  }
2104  // option: target prefix
2105  if(option=="-rel") {
2106  i++; if(i>=argc) usage_exit();
2107  ChaptersPrefix(argv[i]);
2108  continue;
2109  }
2110  // option: overwrite chapter
2111  if(option=="-chapter") {
2112  i++; if(i>=argc) usage_exit();
2113  mFrefChapter=argv[i];
2114  continue;
2115  }
2116  // option: overwrite section
2117  if(option=="-section") {
2118  i++; if(i>=argc) usage_exit();
2119  mFrefSection=argv[i];
2120  continue;
2121  }
2122  // option: extract multiple pages
2123  if(option=="-extract") {
2124  if(i+2!=argc-1) usage_exit();
2125  xpage=true;
2126  break;
2127  }
2128  // option: generate toc (break)
2129  if(option=="-toc") {
2130  i++; if(i+1>=argc) usage_exit();
2131  dotoc=true;
2132  mDstFile = argv[argc-1];
2133  break;
2134  }
2135  // option: generate doxygen header (break)
2136  if(option=="-doxheader") {
2137  i++; if(i>=argc) usage_exit();
2138  dodhd=true;
2139  mDstFile = argv[argc-1];
2140  break;
2141  }
2142  // option: generate doxygen footer (break)
2143  if(option=="-doxfooter") {
2144  i++; if(i>=argc) usage_exit();
2145  dodft=true;
2146  mDstFile = argv[argc-1];
2147  break;
2148  }
2149  // option: generate standalone reference
2150  if(option=="-app") {
2151  mStandaloneReference=true;
2152  continue;
2153  }
2154  // option: help
2155  if((option=="-?") || (option=="--help")) {
2156  usage_exit();
2157  continue;
2158  }
2159  // option: unknown
2160  if(option.size()>1)
2161  if(option.at(0)=='-') {
2162  usage_exit("unknown option " + option);
2163  continue;
2164  }
2165  // non-option: break
2166  break;
2167  }
2168 
2169  // figure source
2170  for(;i<argc-1; i++) {
2171  std::string option(argv[i]);
2172  if(option.size()>1)
2173  if(option.at(0)=='-') {
2174  usage_exit("missplaced/unknown option " + option);
2175  continue;
2176  }
2177  mSrcFiles.insert(option);
2178  }
2179 
2180  // figure destination
2181  for(;i<argc; i++) {
2182  std::string option(argv[i]);
2183  if(option.size()>1)
2184  if(option.at(0)=='-') {
2185  usage_exit("missplaced/unknown option " + option);
2186  continue;
2187  }
2188  mDstFile=option;
2189  }
2190 
2191  // test
2192  if(mDstFile=="") {
2193  usage_exit("no destination file specified");
2194  }
2195  bool dirdst=DirectoryExists(mDstFile);
2196 
2197  // load registry
2198  if(mRtiFile!="") {
2200  }
2201 
2202  // record plug-in and buil-in sections
2203  for(FunctionRegistry::Iterator fit=FunctionRegistry::G()->Begin();
2204  fit!=FunctionRegistry::G()->End(); fit++) {
2205  std::string section=fit->second->KeywordAt(0);
2206  std::transform(section.begin(), section.end(), section.begin(), tolower);
2207  mExclLuaSections.insert(section);
2208  }
2209 
2210  // extend registry
2211  if(mFlxFile!="") {
2213  }
2214 
2215  // record lua sections
2216  for(FunctionRegistry::Iterator fit=FunctionRegistry::G()->Begin();
2217  fit!=FunctionRegistry::G()->End(); fit++) {
2218  std::string section=fit->second->KeywordAt(0);
2219  std::transform(section.begin(), section.end(), section.begin(), tolower);
2220  mInclLuaSections.insert(section);
2221  }
2222 
2223 
2224  // include toc
2225  if(mIncludeFile!="") {
2227  RecordLiterature(tr);
2228  tr.Rewind();
2229  RecordPages(tr);
2230  }
2231 
2232 
2233  // special case: xtract fref
2234  if(xpage) {
2235  if(mSrcFiles.size()!=1) {
2236  usage_exit("extract mode requires one source file");
2237  }
2238  if(!dirdst) {
2239  usage_exit("extract mode requires destination directory");
2240  }
2241  std::cerr << "ref2html: extract pages from " << *mSrcFiles.begin() << std::endl;
2242  TokenReader tr(*mSrcFiles.begin());
2243  XtractPages(tr,mDstFile);
2244  tr.Rewind();
2245  XtractFiles(tr,mDstFile);
2246  exit(0);
2247  }
2248 
2249 
2250  // special case: generate toc
2251  if(dotoc) {
2252  if(dirdst) {
2253  usage_exit("toc mode requires destination file");
2254  }
2255  // output file
2256  std::ostream* hout= &std::cout;
2257  std::ofstream fout;
2258  if(mDstFile != "-") {
2259  fout.open(mDstFile.c_str(), std::ios::out);
2260  hout = &fout;
2261  }
2262  // process all input
2263  std::set< std::string >::iterator sit=mSrcFiles.begin();
2264  for(;sit!=mSrcFiles.end();++sit) {
2265  std::cerr << "ref2html: process toc " << *sit << std::endl;
2266  TokenReader tr(*sit);
2267  RecordLiterature(tr);
2268  tr.Rewind();
2269  RecordPages(tr);
2270  }
2271  // dump
2272  TokenWriter dst(*hout);
2273  DumpPages(dst);
2274  DumpLiterature(dst);
2275  dst.Flush();
2276  exit(0);
2277  }
2278 
2279  // special case: generate dox header/footer
2280  if(dodhd || dodft) {
2281  if(dirdst) {
2282  usage_exit("header-footer mode requires destination file");
2283  }
2284  // output file
2285  std::ostream* hout= &std::cout;
2286  std::ofstream fout;
2287  if(mDstFile != "-") {
2288  fout.open(mDstFile.c_str(), std::ios::out);
2289  hout = &fout;
2290  }
2291  // doit
2292  if(dodhd) DoxygenHeader(hout);
2293  if(dodft) DoxygenFooter(hout);
2294  exit(0);
2295  }
2296 
2297 
2298  // convert all source directories
2299  std::set< std::string > srcfiles;
2300  std::set< std::string >::iterator sit=mSrcFiles.begin();
2301  for(;sit!=mSrcFiles.end();++sit) {
2302  if(!DirectoryExists(*sit)) { srcfiles.insert(*sit); continue;}
2303  std::set< std::string > dirfiles = ReadDirectory(*sit);
2304  std::set< std::string >::iterator dit=dirfiles.begin();
2305  for(;dit!=dirfiles.end();++dit) {
2306  std::string ext = ExtractExtension(*dit);
2307  std::string base = ExtractBasename(*dit);
2308  std::string src= PrependDirectory(*sit,base + ".fref");
2309  // skip if not an fref file
2310  if(ext!="fref") continue;
2311  // record
2312  srcfiles.insert(src);
2313  }
2314  }
2315  mSrcFiles=srcfiles;
2316 
2317  // insist in target dir
2318  if(mSrcFiles.size()>1 && ! dirdst) {
2319  usage_exit("multiple source files require destination directory");
2320  }
2321 
2322 
2323  // do loop
2324  /*std::set< std::string >::iterator*/ sit=mSrcFiles.begin();
2325  for(;sit!=mSrcFiles.end();++sit) {
2326  std::string base = ExtractBasename(*sit);
2327  std::string src= *sit;
2328  std::string dst= mDstFile;
2329  if(dirdst) dst=PrependDirectory(mDstFile,base + ".html");
2330  // process
2331  if(mSrcFiles.size()>1)
2332  std::cout << "ref2html: processing " << src << " to " << dst << std::endl;
2333  std::ofstream fout;
2334  fout.open(dst.c_str(), std::ios::out);
2335  RefpageHtml(&fout,src);
2336  }
2337  exit(0);
2338 }

libFAUDES 2.26g --- 2015.08.17 --- c++ api documentaion by doxygen