0025011: IntAna_QuaQuadGeo can crash with out-of-bounds exception
[occt.git] / adm / gendoc.tcl
1 # =======================================================================
2 # Created on: 2014-03-21
3 # Created by: OMY
4 # Copyright (c) 1996-1999 Matra Datavision
5 # Copyright (c) 1999-2014 OPEN CASCADE SAS
6 #
7 # This file is part of Open CASCADE Technology software library.
8 #
9 # This library is free software; you can redistribute it and/or modify it under
10 # the terms of the GNU Lesser General Public License version 2.1 as published
11 # by the Free Software Foundation, with special exception defined in the file
12 # OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
13 # distribution for complete text of the license and disclaimer of any warranty.
14 #
15 # Alternatively, this file may be used under the terms of Open CASCADE
16 # commercial license or contractual agreement.
17
18 # Brief:  This script compiles OCCT documents from *.md files to HTML pages
19 # =======================================================================
20
21 # ======================================
22 #  Common functions
23 # ======================================
24
25 # Prints help message
26 proc OCCDoc_PrintHelpMessage {} {
27     puts "\nUsage: gendoc \[-h\] {-refman|-overview} \[-html|-pdf|-chm\] \[-m=<list of modules>|-ug=<list of docs>\] \[-v\] \[-s=<search_mode>\] \[-mathjax=<path>\]"
28     puts ""
29     puts "Options are:"
30     puts ""
31     puts "choice of documentation to be generated:"
32     puts "  -overview          : To generate Overview and User Guides"
33     puts "                       (cannot be used with -refman)"
34     puts "  -refman            : To generate class Reference Manual"
35     puts "                       (cannot be used with -overview)"
36     puts ""
37     puts "choice of output format:"
38     puts "  -html              : To generate HTML files"
39     puts "                       (default, cannot be used with -pdf or -chm)"
40     puts "  -pdf               : To generate PDF files"
41     puts "                       (cannot be used with -refman, -html, or -chm)"
42     puts "  -chm               : To generate CHM files"
43     puts "                       (cannot be used with -html or -pdf)"
44     puts ""
45     puts "additional options:"
46     puts "  -m=<modules_list>  : List of OCCT modules (separated with comma),"
47     puts "                       for generation of Reference Manual"
48     puts "  -ug=<docs_list>    : List of MarkDown documents (separated with comma),"
49     puts "                       to use for generation of Overview / User Guides"
50     puts "  -mathjax=<path>    : To use local or alternative copy of MathJax"
51     puts "  -s=<search_mode>   : Specifies the Search mode of HTML documents"
52     puts "                       Can be: none | local | server | external"
53     puts "  -h                 : Prints this help message"
54     puts "  -v                 : Enables more verbose output"    
55 }
56
57 # A command for User Documentation compilation
58 proc gendoc {args} {
59
60   # Parameters
61   set DOC_TYPE                  "REFMAN"
62   set GEN_MODE                  "HTML_ONLY"
63   set DOCFILES                  {}
64   set MODULES                   {}
65   set DOCLABEL                  ""
66   set VERB_MODE                 "NO"
67   set SEARCH_MODE               "none"
68   set MATHJAX_LOCATION          "http://cdn.mathjax.org/mathjax/latest"
69   set mathjax_js_name           "MathJax.js"
70   set DOCTYPE_COMBO_FLAG        0
71   set GENMODE_COMBO_FLAG        0
72   set GENERATE_PRODUCTS_REFMAN "NO"
73
74   global available_docfiles;   # The full list of md files for HTML or CHM generation
75   global available_pdf;        # The full list of md files for PDF generation
76   global tcl_platform
77   global args_names
78   global args_values
79   global env
80
81   # Load list of docfiles
82   if { [OCCDoc_LoadFilesList] != 0 } {
83     puts "Error: File FILES_HTML.txt or FILES_PDF.txt was not found on this computer.\nAborting..."
84     return -1
85   }
86
87   # Parse CL arguments
88   if {[OCCDoc_ParseArguments $args] == 1} {
89     return -1
90   }
91
92   # Print help message if no arguments provided
93   if {[llength $args_names] == 0} {
94     OCCDoc_PrintHelpMessage
95     return 0
96   }
97
98   foreach arg_n $args_names {
99     if {$arg_n == "h"} {
100       OCCDoc_PrintHelpMessage
101       return 0
102     } elseif {$arg_n == "html"} {
103       if { ([ lsearch $args_names "refman" ]   == -1) &&
104            ([ lsearch $args_names "overview" ] == -1) } {
105         puts "Warning: Please specify -refman or -overview argument."
106         return -1
107       }
108       if { [ lsearch $args_names "refman" ] != -1 } {
109         continue
110       }
111       if { $GENMODE_COMBO_FLAG != 1 } {
112         set GEN_MODE "HTML_ONLY"
113         set GENMODE_COMBO_FLAG 1
114       } else {
115         puts "Error: Options -html, -pdf and -chm can not be combined."
116         return -1
117       }
118     } elseif {$arg_n == "chm"} {
119       if { ([ lsearch $args_names "refman" ]   == -1) &&
120            ([ lsearch $args_names "overview" ] == -1) } {
121         puts "Warning: Please specify -refman or -overview argument."
122         return -1
123       }
124       if { [ lsearch $args_names "refman" ] != -1 } {
125         continue
126       }
127       if { $GENMODE_COMBO_FLAG != 1 } { 
128         set GEN_MODE "CHM_ONLY"
129         set GENMODE_COMBO_FLAG 1
130       } else {
131         puts "Error: Options -html, -pdf and -chm cannot be combined."
132         return -1
133       }
134     } elseif {$arg_n == "pdf"} {
135       if { ([ lsearch $args_names "refman" ]   == -1) &&
136            ([ lsearch $args_names "overview" ] == -1) } {
137         puts "Warning: Please specify -refman or -overview argument."
138         return -1
139       }
140       if { [ lsearch $args_names "refman" ] != -1 } {
141         continue
142       }
143       if { $GENMODE_COMBO_FLAG != 1 } { 
144         set GEN_MODE "PDF_ONLY"
145         set GENMODE_COMBO_FLAG 1
146       } else {
147         puts "Error: Options -html, -pdf and -chm cannot be combined."
148         return -1
149       }
150     } elseif {$arg_n == "overview"} {
151       if { $DOCTYPE_COMBO_FLAG != 1 } {
152         set DOC_TYPE "OVERVIEW"
153         set DOCTYPE_COMBO_FLAG 1
154       } else {
155         puts "Error: Options -refman and -overview cannot be combined."
156         return -1
157       }
158
159       # Print ignored options
160       if { [ lsearch $args_names "m" ] != -1 } {
161         puts "\nInfo: The following options will be ignored: \n"
162         puts "  * -m"
163       }
164       puts ""
165     } elseif {$arg_n == "refman"} {
166       if { $DOCTYPE_COMBO_FLAG != 1 } { 
167         set DOC_TYPE "REFMAN"
168         set DOCTYPE_COMBO_FLAG 1
169         if { [file exists [pwd]/src/VAS/Products.tcl] } {
170           set GENERATE_PRODUCTS_REFMAN "YES"
171         }
172       } else {
173         puts "Error: Options -refman and -overview cannot be combined."
174         return -1
175       }
176       # Print ignored options
177       if { ([ lsearch $args_names "pdf" ]     != -1) || 
178            ([ lsearch $args_names "chm" ]     != -1) || 
179            ([ lsearch $args_names "ug" ]      != -1) } {
180         puts "\nInfo: The following options will be ignored: \n"
181         if { [ lsearch $args_names "pdf" ] != -1 } {
182           puts "  * -pdf"
183         }
184         if { [ lsearch $args_names "chm" ] != -1 } {
185           puts "  * -chm"
186         }
187         if { [ lsearch $args_names "ug" ] != -1 } {
188           puts "  * -ug"
189         }
190         puts ""
191       }
192       
193       if { $GENERATE_PRODUCTS_REFMAN == "YES" } {
194         if { [ lsearch $args_names "m" ] == -1 } {
195           puts "\nError: Cannot generate Reference Manual for the whole set of OCC Products."
196           puts "Aborting..."
197           return -1
198         }
199       }
200     } elseif {$arg_n == "v"} {
201       set VERB_MODE "YES"
202     } elseif {$arg_n == "ug"} {
203       if { ([ lsearch $args_names "refman" ]   != -1) } {
204         continue
205       }
206       if {$args_values(ug) != "NULL"} {
207         set DOCFILES $args_values(ug)
208       } else {
209         puts "Error in argument ug."
210         return -1
211       }
212       # Check if all chosen docfiles are correct
213       foreach docfile $DOCFILES {
214         if { [ lsearch $args_names "pdf" ] == -1 } {
215           # Check to generate HTMLs
216           if { [lsearch $available_docfiles $docfile] == -1 } {
217             puts "Error: File \"$docfile\" is not presented in the list of available docfiles."
218             puts "       Please specify the correct docfile name."
219             return -1
220           } 
221         } else {
222           # Check to generate PDFs
223           if { [lsearch $available_pdf $docfile] == -1 } {
224             puts "Error: File \"$docfile\" is not presented in the list of generic PDFs."
225             puts "       Please specify the correct pdf name."
226             return -1
227           }
228         }
229       }
230     } elseif {$arg_n == "m"} {
231       if { [ lsearch $args_names "overview" ] != -1 } {
232         continue
233       }
234       if {$args_values(m) != "NULL"} {
235         set MODULES $args_values(m)
236       } else {
237         puts "Error in argument m."
238         return -1
239       }
240     } elseif {$arg_n == "s"} {
241       if { [ lsearch $args_names "pdf" ] != -1 } {
242         continue
243       }
244       if {$args_values(s) != "NULL"} {
245         set SEARCH_MODE $args_values(s)
246       } else {
247         puts "Error in argument s."
248         return -1
249       }
250     } elseif {$arg_n == "mathjax"} {
251       if { [ lsearch $args_names "pdf" ] != -1 } {
252         set possible_mathjax_loc $args_values(mathjax)
253         if {[file exist [file join $possible_mathjax_loc $mathjax_js_name]]} {
254           set MATHJAX_LOCATION $args_values(mathjax)
255           puts "$MATHJAX_LOCATION"
256         } else {
257           puts "Warning: $mathjax_js_name is not found in $possible_mathjax_loc."
258           puts "         MathJax will be used from $MATHJAX_LOCATION"
259         }
260       } else {
261         puts "Warning: MathJax is not used with pdf and will be ignored."
262       }
263     } else {
264       puts "\nWrong argument: $arg_n"
265       OCCDoc_PrintHelpMessage
266       return -1
267     }
268   }
269
270   # Check the existence of the necessary tools
271   set DOXYGEN_PATH  ""
272   set GRAPHVIZ_PATH ""
273   set INKSCAPE_PATH ""
274   set PDFLATEX_PATH ""
275   set HHC_PATH      ""
276
277   OCCDoc_DetectNecessarySoftware $DOXYGEN_PATH $GRAPHVIZ_PATH $INKSCAPE_PATH $HHC_PATH $PDFLATEX_PATH
278
279   if {$DOXYGEN_PATH == ""} {
280     puts " Aborting..."
281     return -1
282   }
283
284   if {"$::tcl_platform(platform)" == "windows"} {
285     if { ($GEN_MODE == "CHM_ONLY") && ($HHC_PATH == "") } {
286       puts " Aborting..."
287       return -1
288     }
289   }
290
291   if { ($PDFLATEX_PATH == "") && ($GEN_MODE == "PDF_ONLY") } {
292     puts " Aborting..."
293     return -1
294   }
295
296   # If we do not specify list for docfiles with -m argument,
297   # we assume that we have to generate all docfiles
298   if { [llength $DOCFILES] == 0 } {
299     if { $GEN_MODE != "PDF_ONLY" } {
300       set DOCFILES $available_docfiles
301     } else {
302       set DOCFILES $available_pdf
303     }
304   }
305
306   puts ""
307
308   # Clean logfiles
309   set OUTDIR  [OCCDoc_GetRootDir]/doc/
310   set DOXYLOG $OUTDIR/doxygen_warnings_and_errors.log
311   set PDFLOG  $OUTDIR/pdflatex_warnings_and_errors.log
312
313   file delete -force $PDFLOG
314   file delete -force $DOXYLOG
315   
316   # Start main activities
317   if { $GEN_MODE != "PDF_ONLY" } {
318     OCCDoc_Main $DOC_TYPE $DOCFILES $MODULES $GEN_MODE $VERB_MODE $SEARCH_MODE $MATHJAX_LOCATION $GENERATE_PRODUCTS_REFMAN $DOXYGEN_PATH $GRAPHVIZ_PATH $INKSCAPE_PATH $HHC_PATH
319   } else {
320     puts "Generating OCCT User Guides in PDF format...\n"
321     foreach pdf $DOCFILES {
322
323       puts "Info: Processing file $pdf\n"
324
325       # Some values are hardcoded because they are related only to PDF generation
326       OCCDoc_Main "OVERVIEW" [list $pdf] {} "PDF_ONLY" $VERB_MODE "none" $MATHJAX_LOCATION "NO" $DOXYGEN_PATH $GRAPHVIZ_PATH $INKSCAPE_PATH $HHC_PATH
327     }
328     puts "[clock format [clock seconds] -format {%Y-%m-%d %H:%M}] Generation completed."
329     puts "\nPDF files are generated in \n[file normalize [OCCDoc_GetRootDir]/doc/pdf]"
330   }
331 }
332
333 # Main procedure for documents compilation
334 proc OCCDoc_Main {docType {docfiles {}} {modules {}} generatorMode verboseMode searchMode mathjaxLocation generateProductsRefman DOXYGEN_PATH GRAPHVIZ_PATH INKSCAPE_PATH HHC_PATH} {
335
336   global available_docfiles
337   global available_pdf
338
339   set PRODPATH   ""
340   if { [string compare -nocase $generateProductsRefman "YES"] == 0 } {
341     set PRODPATH [pwd]
342   }
343
344   set ROOTDIR    [OCCDoc_GetRootDir $PRODPATH]
345   set INDIR      [OCCDoc_GetDoxDir]
346   set OUTDIR     $ROOTDIR/doc
347   set PDFDIR     $OUTDIR/pdf
348   set UGDIR      $PDFDIR/user_guides
349   set DGDIR      $PDFDIR/dev_guides
350   set TAGFILEDIR $OUTDIR/refman
351   set HTMLDIR    $OUTDIR/overview/html
352   set LATEXDIR   $OUTDIR/overview/latex
353   set DOXYFILE   $OUTDIR/OCCT.cfg
354
355   # Create or cleanup the output folders
356   if { [string compare -nocase $generateProductsRefman "YES"] != 0 } {
357     if { ![file exists $OUTDIR] } {
358       file mkdir $OUTDIR
359     } 
360     if { ![file exists $HTMLDIR] } {
361       file mkdir $HTMLDIR
362     }
363     if { ![file exists $PDFDIR] } {
364       file mkdir $PDFDIR
365     }
366     if { ![file exists $UGDIR] } {
367       file mkdir $UGDIR
368     }
369     if { ![file exists $DGDIR] } {
370       file mkdir $DGDIR
371     }
372     if { [file exists $LATEXDIR] } {
373       file delete -force $LATEXDIR
374     }
375     file mkdir $LATEXDIR
376   }
377   if { $docType == "REFMAN" } {
378     if { ![file exists $TAGFILEDIR] } {
379       file mkdir $TAGFILEDIR
380     }
381   }
382
383   # is MathJax HLink?
384   set mathjax_relative_location $mathjaxLocation
385   if { [file isdirectory "$mathjaxLocation"] } {
386     if { $generatorMode == "HTML_ONLY" } {
387       # related path
388       set mathjax_relative_location [OCCDoc_GetRelPath $HTMLDIR $mathjaxLocation]
389     } elseif { $generatorMode == "CHM_ONLY" } {
390       # absolute path
391       set mathjax_relative_location [file normalize $mathjaxLocation]
392     }
393   }
394
395   if { $generateProductsRefman == "YES" } {
396     set DOCDIR "$OUTDIR/refman"
397     puts "\nGenerating OCC Products Reference Manual\n"
398   } else {
399     if { $docType == "REFMAN"} {
400       set DOCDIR "$OUTDIR/refman"
401       puts "\nGenerating Open CASCADE Reference Manual\n"
402     } elseif { $docType == "OVERVIEW" } {
403       set DOCDIR "$OUTDIR/overview"
404       set FORMAT ""
405       if { ($generatorMode == "HTML_ONLY") || ($generatorMode == "CHM_ONLY") } {
406         if { $generatorMode == "HTML_ONLY" } { 
407           set FORMAT " in HTML format..."
408         } elseif { $generatorMode == "CHM_ONLY" } {
409           set FORMAT " in CHM format..."
410         }
411         puts "Generating OCCT User Guides$FORMAT\n"
412       }
413     } else {
414       puts "Error: Invalid documentation type: $docType. Can not process."
415       return -1
416     }
417   }
418
419   # Generate Doxyfile
420   puts "[clock format [clock seconds] -format {%Y-%m-%d %H:%M}] Generating Doxyfile..."
421
422   if { [OCCDoc_MakeDoxyfile $docType $DOCDIR $TAGFILEDIR $DOXYFILE $generatorMode $docfiles $modules $verboseMode $searchMode $HHC_PATH $mathjax_relative_location $GRAPHVIZ_PATH $PRODPATH] == -1 } {
423     return -1
424   }
425
426   # Run doxygen tool
427   set starttimestamp [clock format [clock seconds] -format {%Y-%m-%d %H:%M}]
428
429   if { ($generatorMode == "HTML_ONLY") || ($docType == "REFMAN") } {
430     puts "$starttimestamp Generating HTML files..."
431
432     # Copy index file to provide fast access to HTML documentation
433     file copy -force $INDIR/resources/index.html $DOCDIR/index.html
434   } elseif { $generatorMode == "CHM_ONLY" } {
435     puts "$starttimestamp Generating CHM file..."
436   } elseif { $generatorMode == "PDF_ONLY" } {
437     puts "$starttimestamp Generating PDF file..."
438   }
439
440   set DOXYLOG $OUTDIR/doxygen_warnings_and_errors.log
441   set RESULT [catch {exec $DOXYGEN_PATH $DOXYFILE >> $OUTDIR/doxygen_out.log} DOX_ERROR] 
442   if {$RESULT != 0} {
443     set NbErrors [regexp -all -line {^\s*[^\s]+} $DOX_ERROR]
444     if {$NbErrors > 0} {
445       puts "\nWarning: Doxygen reported $NbErrors messages."
446       puts "See log in $DOXYLOG\n"
447       set DOX_ERROR_FILE [open $DOXYLOG "a"]
448       if {$generatorMode == "PDF_ONLY"} {
449         puts $DOX_ERROR_FILE "\n===================================================="
450         puts $DOX_ERROR_FILE "Logfile for $docfiles"
451         puts $DOX_ERROR_FILE "====================================================\n"
452       }
453       puts $DOX_ERROR_FILE $DOX_ERROR
454       close $DOX_ERROR_FILE
455     }
456   }
457
458   # Close the Doxygen application
459   after 300
460
461   # Start Post Processing
462   set curtime [clock format [clock seconds] -format {%Y-%m-%d %H:%M}]
463   if { $docType == "REFMAN" } {
464     # Post Process generated HTML pages and draw dependency graphs
465     if {[OCCDoc_PostProcessor $DOCDIR] == 0} {
466       puts "$curtime Generation completed."
467       puts "\nInfo: doxygen log file is located in:"
468       puts "$OUTDIR/doxygen_out.log."
469       puts "\nReference Manual is generated in \n$DOCDIR"
470     }
471   } elseif { $docType == "OVERVIEW" } {
472     # Start PDF generation routine
473     if { $generatorMode == "PDF_ONLY" } {
474       set OS $::tcl_platform(platform)
475       if { $OS == "unix" } {
476         set PREFIX ".sh"
477       } elseif { $OS == "windows" } {
478         set PREFIX ".bat"
479       }
480
481       # Prepare a list of TeX files, generated by Doxygen
482       cd $LATEXDIR
483
484       set TEXFILES   [glob $LATEXDIR -type f -directory $LATEXDIR -tails "*.tex" ]
485       foreach path $TEXFILES {
486         if { [string compare -nocase $path $LATEXDIR] == 0 } {
487           set DEL_IDX [lsearch $TEXFILES $path]
488           if { $DEL_IDX != -1 } {
489             set TEXFILES [lreplace $TEXFILES $DEL_IDX $DEL_IDX]
490           }
491         }
492       }
493       set TEXFILES   [string map [list refman.tex ""] $TEXFILES]
494       if {$verboseMode == "YES"} {
495         puts "Info: Preprocessing generated TeX files..."
496       }
497       OCCDoc_ProcessTex $TEXFILES $LATEXDIR $verboseMode
498
499       if {$verboseMode == "YES"} {
500         puts "Info: Converting SVG images to PNG format..."
501       }
502
503       if { $INKSCAPE_PATH != "" } {
504         OCCDoc_ProcessSvg $LATEXDIR $verboseMode
505       } else {
506         puts "Warning: SVG images will be lost in PDF documents."
507       }
508
509       if {$verboseMode == "YES"} {
510         puts "Info: Generating PDF file from TeX files..."
511       }
512       foreach TEX $TEXFILES {
513         # Rewrite existing REFMAN.tex file...
514         set TEX [lindex [split $TEX "."] 0]
515
516         if {$verboseMode == "YES"} {
517           puts "Info: Generating PDF file from $TEX..."
518         }
519
520         OCCDoc_MakeRefmanTex $TEX $LATEXDIR $verboseMode $available_pdf
521
522         if {"$::tcl_platform(platform)" == "windows"} {
523           set is_win "yes"
524         } else {
525           set is_win "no"
526         }
527         if {$verboseMode == "YES"} {
528           # ...and use it to generate PDF from TeX...
529           if {$is_win == "yes"} {
530             puts "Info: Executing $LATEXDIR/make.bat..."
531           } else {
532             puts "Info: Executing $LATEXDIR/Makefile..."
533           }
534         }
535         set PDFLOG $OUTDIR/pdflatex_warnings_and_errors.log
536
537         if {"$is_win" == "yes"} {
538           set RESULT [catch {eval exec [auto_execok $LATEXDIR/make.bat] >> "$OUTDIR/pdflatex_out.log"} LaTeX_ERROR]
539         } else {
540           set RESULT [catch {eval exec "make -f $LATEXDIR/Makefile" >> "$OUTDIR/pdflatex_out.log"} LaTeX_ERROR]
541
542           # Small workaround for *nix stations
543           set prev_loc [pwd]
544           cd $LATEXDIR
545           set RESULT [catch {eval exec "pdflatex refman.tex" >> "$OUTDIR/pdflatex_out.log"} LaTeX_ERROR]
546           cd $prev_loc
547         }
548
549         if {$RESULT != 0} {
550           set NbErrors [regexp -all -line {^\s*[^\s]+} $LaTeX_ERROR]
551           if {$NbErrors > 0} {
552             puts "\nWarning: PDFLaTeX reported $NbErrors messages.\nSee log in $PDFLOG\n"
553             set LaTeX_ERROR_FILE [open $PDFLOG "a"]
554             puts $LaTeX_ERROR_FILE "\n===================================================="
555             puts $LaTeX_ERROR_FILE "Logfile of file $TEX:"
556             puts $LaTeX_ERROR_FILE "====================================================\n"
557             puts $LaTeX_ERROR_FILE $LaTeX_ERROR
558             close $LaTeX_ERROR_FILE
559           }
560         }
561
562         # ...and place it to the specific folder
563         if {![file exists "$LATEXDIR/refman.pdf"]} {
564           puts "Fatal: PDFLaTeX failed to create output file, stopping!"
565           return -1
566         }
567
568         set destFolder $PDFDIR
569         set parsed_string [split $TEX "_"]
570         if { [lsearch $parsed_string "tutorial"] != -1 } {
571           set TEX [string map [list occt__ occt_] $TEX]
572           set destFolder $PDFDIR
573         } elseif { [lsearch $parsed_string "user"] != -1 } {
574           set TEX [string map [list user_guides__ ""] $TEX]
575           set destFolder $UGDIR
576         } elseif { [lsearch $parsed_string "dev"]  != -1 } {
577           set TEX [string map [list dev_guides__ ""] $TEX]
578           set destFolder $DGDIR
579         }
580         file rename -force $LATEXDIR/refman.pdf "$destFolder/$TEX.pdf"
581
582       }
583     } elseif { $generatorMode == "CHM_ONLY" } {
584       file rename  $OUTDIR/overview.chm $OUTDIR/occt_overview.chm
585     }
586     cd $INDIR
587
588     if { $generatorMode == "HTML_ONLY" } {
589       puts "\nHTML documentation is generated in \n$DOCDIR"
590     }
591     if { $generatorMode == "CHM_ONLY" } {
592       puts "\nGenerated CHM documentation is in \n$OUTDIR/overview.chm"
593     }
594
595     puts ""
596   }
597
598   # Remove temporary Doxygen files
599   set deleteList [glob -nocomplain -type f "*.tmp"]
600   foreach file $deleteList {
601     file delete $file
602   }
603   return 0
604 }
605
606 # Generates Doxygen configuration file for Overview documentation
607 proc OCCDoc_MakeDoxyfile {docType outDir tagFileDir {doxyFileName} {generatorMode ""} {DocFilesList {}} {ModulesList {}} verboseMode searchMode hhcPath mathjaxLocation graphvizPath productsPath} {
608
609   set inputDir      [OCCDoc_GetDoxDir]
610   set TEMPLATES_DIR $inputDir/resources
611   set occt_version  [OCCDoc_DetectCasVersion]
612
613   # Delete existent doxyfile
614   file delete $doxyFileName
615
616   # Copy specific template to the target folder
617   if { $docType == "REFMAN" } {
618     file copy "$TEMPLATES_DIR/occt_rm.doxyfile" $doxyFileName
619   } elseif { $docType == "OVERVIEW" } {
620     if { $generatorMode == "HTML_ONLY" || $generatorMode == "CHM_ONLY" } {
621       file copy "$TEMPLATES_DIR/occt_ug_html.doxyfile" $doxyFileName
622     } elseif { $generatorMode == "PDF_ONLY"} {
623       file copy "$TEMPLATES_DIR/occt_ug_pdf.doxyfile" $doxyFileName
624     } else {
625       puts "Error: Unknown generation mode"
626       return -1
627     }
628   } else {
629     puts "Error: Cannot generate unknown document type"
630     return -1
631   }
632
633   set doxyFile [open $doxyFileName "a"]
634   # Write specific options
635   if { $docType == "REFMAN" } {
636
637     # Load lists of modules scripts
638     if { $productsPath == "" } {
639       set modules_scripts [glob -nocomplain -type f -directory "[OCCDoc_GetSourceDir $productsPath]/OS/" *.tcl]
640     } else {
641       set modules_scripts [glob -nocomplain -type f -directory "[OCCDoc_GetSourceDir $productsPath]/VAS/" *.tcl]
642     }
643     if { [llength $modules_scripts] != 0} {
644       foreach module_file $modules_scripts {
645         source $module_file
646       }
647     }
648
649     set ALL_MODULES [OCCDoc_GetModulesList $productsPath]
650     if { [llength $ModulesList] == 0 } {
651       # by default take all modules
652       set modules $ALL_MODULES
653     } else {
654       set modules $ModulesList
655     }
656
657     # Detect invalid names of modules
658     foreach module $modules {
659       if { $module == "" } {
660         continue
661       }
662       if {[lsearch $ALL_MODULES $module] == -1 } {
663         puts "Error: No module $module is known. Aborting..."
664         return -1
665       }
666     }
667
668     # Set context
669     set one_module [expr [llength $modules] == 1]
670     if { $one_module } {
671       set title "OCCT [$modules:name]"
672       set name $modules
673     } else {
674       set title "Open CASCADE Technology"
675       set name OCCT
676     }
677
678     # Get list of header files in the specified modules
679     set filelist {}
680     foreach module $modules {
681       if { $module == "" } {
682         continue
683       }
684       foreach tk [$module:toolkits] {
685         foreach pk [split [OCCDoc_GetPackagesList [OCCDoc_Locate $tk $productsPath]]] {
686           if { [llength $pk] != "{}" } {
687             lappend filelist [OCCDoc_GetHeadersList "p" "pubinclude" "$pk" "$productsPath"]
688           }
689         }
690       }
691     }
692
693     # Filter out files Handle_*.hxx and *.lxx
694     set hdrlist {}
695     foreach fileset $filelist {
696       set hdrset {}
697       foreach hdr $fileset {
698         if { ! [regexp {Handle_.*[.]hxx} $hdr] && ! [regexp {.*[.]lxx} $hdr] } {
699           lappend hdrset $hdr
700         }
701       }
702       lappend hdrlist $hdrset
703     }
704     set filelist $hdrlist
705
706     set doxyFile [open $doxyFileName "a"]
707   
708     puts $doxyFile "PROJECT_NAME           = \"$title\""
709     puts $doxyFile "PROJECT_NUMBER         = $occt_version"
710     puts $doxyFile "OUTPUT_DIRECTORY       = $outDir/."
711     puts $doxyFile "GENERATE_TAGFILE       = $outDir/${name}.tag"
712
713     if { [string tolower $searchMode] == "none" } {
714       puts $doxyFile "SEARCHENGINE           = NO"
715       puts $doxyFile "SERVER_BASED_SEARCH    = NO"
716       puts $doxyFile "EXTERNAL_SEARCH        = NO"
717     } else {
718       puts $doxyFile "SEARCHENGINE           = YES"
719       if { [string tolower $searchMode] == "local" } {
720         puts $doxyFile "SERVER_BASED_SEARCH    = NO"
721         puts $doxyFile "EXTERNAL_SEARCH        = NO"
722       } elseif { [string tolower $searchMode] == "server" } {
723         puts $doxyFile "SERVER_BASED_SEARCH    = YES"
724         puts $doxyFile "EXTERNAL_SEARCH        = NO"
725       } elseif { [string tolower $searchMode] == "external" } {
726         puts $doxyFile "SERVER_BASED_SEARCH    = YES"
727         puts $doxyFile "EXTERNAL_SEARCH        = YES"
728       } else {
729         puts "Error: Wrong search engine type: $searchMode."
730         close $doxyFile 
731         return -1
732       }
733     }
734
735     puts $doxyFile "DOTFILE_DIRS             = $outDir/html"
736     puts $doxyFile "DOT_PATH                 = $graphvizPath"
737     puts $doxyFile "INCLUDE_PATH             = [OCCDoc_GetIncDir $productsPath]"
738     
739     # list of files to generate
740     set mainpage [OCCDoc_MakeMainPage $outDir $outDir/$name.dox $modules $productsPath]
741     puts $doxyFile ""
742     puts $doxyFile "INPUT    = $mainpage \\"
743     foreach header $filelist {
744       puts $doxyFile "               $header \\"
745     }
746
747     puts $doxyFile "MATHJAX_FORMAT         = HTML-CSS"
748     puts $doxyFile "MATHJAX_RELPATH        = ${mathjaxLocation}"
749
750     puts $doxyFile ""
751
752   } elseif { $docType == "OVERVIEW" } {
753
754     # Add common options for generation of Overview and User Guides
755     puts $doxyFile "PROJECT_NUMBER         = $occt_version"
756     puts $doxyFile "OUTPUT_DIRECTORY       = $outDir/."
757     puts $doxyFile "PROJECT_LOGO           = $inputDir/resources/occ_logo.png"
758
759     set PARAM_INPUT "INPUT                 ="
760     set PARAM_IMAGEPATH "IMAGE_PATH        = $inputDir/resources/ "
761     foreach docFile $DocFilesList {
762       set NEW_IMG_PATH "$inputDir/$docFile"
763       if { [string compare $NEW_IMG_PATH [OCCDoc_GetRootDir $productsPath]] != 0 } {
764         set img_string [file dirname $NEW_IMG_PATH]/images
765         if { [file exists $img_string] } {
766           append PARAM_IMAGEPATH " $img_string"
767         }
768       }
769       append PARAM_INPUT " " $inputDir/$docFile
770     }
771     puts $doxyFile $PARAM_INPUT
772     puts $doxyFile $PARAM_IMAGEPATH
773
774     # Add document type-specific options
775     if { $generatorMode == "HTML_ONLY"} {
776       # generate tree view
777       puts $doxyFile "GENERATE_TREEVIEW      = YES"
778
779       # Set a reference to a TAGFILE
780       if { $tagFileDir != "" } {
781         if {[file exists $tagFileDir/OCCT.tag] == 1} {
782           #set tagPath [OCCDoc_GetRelPath $tagFileDir $outDir/html]
783           set tagPath $tagFileDir
784           puts $doxyFile "TAGFILES               = $tagFileDir/OCCT.tag=../../refman/html"
785         }
786       }
787       # HTML Search engine options
788       if { [string tolower $searchMode] == "none" } {
789         puts $doxyFile "SEARCHENGINE           = NO"
790         puts $doxyFile "SERVER_BASED_SEARCH    = NO"
791         puts $doxyFile "EXTERNAL_SEARCH        = NO"
792       } else {
793         puts $doxyFile "SEARCHENGINE           = YES"
794         if { [string tolower $searchMode] == "local" } {
795           puts $doxyFile "SERVER_BASED_SEARCH    = NO"
796           puts $doxyFile "EXTERNAL_SEARCH        = NO"
797         } elseif { [string tolower $searchMode] == "server" } {
798           puts $doxyFile "SERVER_BASED_SEARCH    = YES"
799           puts $doxyFile "EXTERNAL_SEARCH        = NO"
800         } elseif { [string tolower $searchMode] == "external" } {
801           puts $doxyFile "SERVER_BASED_SEARCH    = YES"
802           puts $doxyFile "EXTERNAL_SEARCH        = YES"
803         } else {
804           puts "Error: Wrong search engine type: $searchMode."
805           close $doxyFile 
806           return -1
807         }
808       }
809     } elseif { $generatorMode == "CHM_ONLY"} {
810       # specific options for CHM file generation
811       puts $doxyFile "GENERATE_TREEVIEW      = NO"
812       puts $doxyFile "SEARCHENGINE           = NO"
813       puts $doxyFile "GENERATE_HTMLHELP      = YES"
814       puts $doxyFile "CHM_FILE               = ../../overview.chm"
815       puts $doxyFile "HHC_LOCATION           = \"$hhcPath\""
816       puts $doxyFile "DISABLE_INDEX          = YES"
817     }
818
819     # Formula options
820     puts $doxyFile "MATHJAX_RELPATH        = ${mathjaxLocation}"
821   }
822
823   close $doxyFile
824   return 0
825 }