0031939: Coding - correction of spelling errors in comments [part 2]
[occt.git] / adm / occaux.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 # =======================================================================
19 # This script contains auxilary functions which can be used 
20 # in documentation generation process
21 # =======================================================================
22
23 # ==============================================
24 # Commonly used functions
25 # ==============================================
26
27 # Parses arguments line like "-arg1=val1 -arg2=val2 ..." to array args_names and map args_values
28 proc OCCDoc_ParseArguments {arguments} {
29   global args_names
30   global args_values
31   set args_names {}
32   array set args_values {}
33
34   foreach arg $arguments {
35     if {[regexp {^(-)[a-z_]+$} $arg] == 1} {
36       set name [string range $arg 1 [string length $arg]-1]
37       lappend args_names $name
38       set args_values($name) "NULL"
39       continue
40     } elseif {[regexp {^(-)[a-z_]+=.+$} $arg] == 1} {
41       set equal_symbol_position [string first "=" $arg]
42       set name [string range $arg 1 $equal_symbol_position-1]
43       lappend args_names $name
44       set value [string range $arg $equal_symbol_position+1 [string length $arguments]-1]
45       
46       # To parse a list of values for -m parameter
47       if { [string first "," $value] != -1 } {
48         set value [split $value ","];
49       }
50
51       set args_values($name) $value
52
53     } else {
54       puts "Error in argument $arg."
55       return 1
56     }
57   }
58   return 0
59 }
60
61 # Returns script parent folder
62 proc OCCDoc_GetDoxDir { {theProductsPath ""} } {
63   if { $theProductsPath == "" } {
64     return [file normalize [file dirname [info script]]/../dox]
65   } else {
66     return [file normalize $theProductsPath]/dox
67   }
68 }
69
70 # Returns products root folder
71 proc OCCDoc_GetProdRootDir {} {
72   if {[info exists ::env(PRODROOT)]} {
73     return [file normalize $::env(PRODROOT)]
74   }
75 }
76
77 # Returns OCCT root dir
78 proc OCCDoc_GetOCCTRootDir {} {
79   set path [OCCDoc_GetDoxDir]
80   return [file normalize $path/..]
81 }
82
83 # Returns root dir
84 proc OCCDoc_GetRootDir { {theProductsPath ""} } {
85   if { $theProductsPath == "" } {
86     return [OCCDoc_GetOCCTRootDir]
87   } else {
88     return [file normalize $theProductsPath]
89   }
90 }
91
92 # Returns OCCT include dir
93 proc OCCDoc_GetIncDir { {theProductsPath ""} } {
94   set path [OCCDoc_GetRootDir $theProductsPath]
95   return "$path/inc"
96 }
97
98 # Returns OCCT source dir
99 proc OCCDoc_GetSourceDir { {theProductsPath ""} } {
100   set path [OCCDoc_GetRootDir $theProductsPath]
101   return "$path/src"
102 }
103
104 # Returns name of the package from the current toolkit
105 proc OCCDoc_GetNameFromPath { thePath } {
106
107   set splitted_path [split $thePath "/" ]
108   set package_name  [lindex $splitted_path end]
109
110   return $package_name
111 }
112
113 # Returns the relative path between two folders
114 proc OCCDoc_GetRelPath {thePathFrom thePathTo} {
115   if { [file isdirectory "$thePathFrom"] == 0 } {
116     return ""
117   }
118
119   set aPathFrom [file normalize "$thePathFrom"]
120   set aPathTo   [file normalize "$thePathTo"]
121
122   set aCutedPathFrom "${aPathFrom}/dummy"
123   set aRelatedDeepPath ""
124
125   while { "$aCutedPathFrom" != [file normalize "$aCutedPathFrom/.."] } {
126     set aCutedPathFrom [file normalize "$aCutedPathFrom/.."]
127     # does aPathTo contain aCutedPathFrom?
128     regsub -all $aCutedPathFrom $aPathTo "" aPathFromAfterCut
129     if { "$aPathFromAfterCut" != "$aPathTo" } { # if so
130       if { "$aCutedPathFrom" == "$aPathFrom" } { # just go higher, for example, ./somefolder/someotherfolder
131         set aPathTo ".${aPathTo}"
132       } elseif { "$aCutedPathFrom" == "$aPathTo" } { # remove the last "/"
133         set aRelatedDeepPath [string replace $aRelatedDeepPath end end ""]
134       }
135       regsub -all $aCutedPathFrom $aPathTo $aRelatedDeepPath aPathToAfterCut
136       regsub -all "//" $aPathToAfterCut "/" aPathToAfterCut
137       return $aPathToAfterCut
138     }
139     set aRelatedDeepPath "$aRelatedDeepPath../"
140   }
141
142   return $thePathTo
143 }
144
145 # Returns OCCT version string from file Standard_Version.hxx (if available)
146 proc OCCDoc_DetectCasVersion {} {
147   set occt_ver 6.7.0
148   set occt_ver_add ""
149   set filename "[OCCDoc_GetSourceDir]/Standard/Standard_Version.hxx"
150   if { [file exists $filename] } {
151     set fh [open $filename "r"]
152     set fh_loaded [read $fh]
153     close $fh
154     regexp {[^/]\s*#\s*define\s+OCC_VERSION_COMPLETE\s+\"([^\s]*)\"} $fh_loaded dummy occt_ver
155     regexp {[^/]\s*#\s*define\s+OCC_VERSION_DEVELOPMENT\s+\"([^\s]*)\"} $fh_loaded dummy occt_ver_add
156     if { "$occt_ver_add" != "" } { set occt_ver ${occt_ver}.$occt_ver_add }
157   }
158   return $occt_ver
159 }
160
161 # Checks if the necessary tools exist
162 proc OCCDoc_DetectNecessarySoftware { DOXYGEN_PATH GRAPHVIZ_PATH INKSCAPE_PATH HHC_PATH PDFLATEX_PATH } {
163
164   upvar 1 DOXYGEN_PATH  doxy_path
165   upvar 1 GRAPHVIZ_PATH graph_path
166   upvar 1 INKSCAPE_PATH inkscape_path
167   upvar 1 HHC_PATH      hhc_path
168   upvar 1 PDFLATEX_PATH latex_path
169
170   set doxy_path     ""
171   set graph_path    ""
172   set inkscape_path ""
173   set latex_path    ""
174   set hhc_path      ""
175
176   set is_win "no"
177   if { "$::tcl_platform(platform)" == "windows" } {
178     set is_win "yes"
179   }
180   if {"$is_win" == "yes"} {
181     set exe ".exe"
182     set com ".com"
183   } else {
184     set exe ""
185     set com ""
186   }
187
188   set g_flag "no"
189   set d_flag "no"
190   set i_flag "no"
191   set h_flag "no"
192   set l_flag "no"
193
194   puts ""
195   set envPath $::env(PATH)
196   if { $is_win == "yes" } {
197     set searchPathsList [split $envPath ";"]
198   } else {
199     set searchPathsList [split $envPath ":"]
200   }
201
202   foreach path $searchPathsList {
203     if { ($is_win == "no") && 
204          (($path == "/usr/bin") || ($path == "/usr/local/bin")) } {
205         # Avoid searching in default bin location
206         continue
207     }
208     if {$d_flag == "no"} {
209       if { [file exists $path/doxygen$exe] } {
210         catch { exec $path/doxygen -V } version_string 
211         set version [lindex [split $version_string "\n"] 0]
212         puts "Info: $version "
213         puts "      found in $path."
214         set doxy_path "$path/doxygen$exe"
215         set d_flag "yes"
216       }
217     }
218     if {$g_flag == "no"} {
219       if { [file exists $path/dot$exe] } {
220         catch { exec $path/dot -V } version
221
222         puts "Info: $version "
223         puts "      found in $path."
224         set graph_path "$path/dot$exe"
225         set g_flag "yes"
226       }
227     }
228     if {$i_flag == "no"} {
229       if { [file exists $path/inkscape$com] } {
230         catch { exec $path/inkscape -V } version
231         puts "Info: $version " 
232         puts "      found in $path."
233         set inkscape_path "$path/inkscape$com"
234         set i_flag "yes"
235       }
236     }
237     if {$l_flag == "no"} {
238       if { [file exists $path/pdflatex$exe] } {
239         catch { exec $path/pdflatex -version } version
240         set version [lindex [split $version "\n"] 0]
241         puts "Info: $version " 
242         puts "      found in $path."
243         set latex_path "$path/pdflatex$exe"
244         set l_flag "yes"
245       }
246     }
247     if { ("$is_win" == "yes") && ($h_flag == "no") } {
248       if { [file exists $path/hhc.exe] } {
249         puts "Info: hhc " 
250         puts "      found in $path."
251         set hhc_path "hhc$exe"
252         set h_flag "yes"
253       }
254     }
255     if { ($d_flag == "yes") &&
256          ($i_flag == "yes") &&
257          ($g_flag == "yes") &&
258          ($l_flag == "yes") &&
259          (($is_win == "yes") && 
260           ($h_flag == "yes")) } {
261       break
262     }
263   }
264
265   # On Windows search for hhc.exe in the default location 
266   # if it has not been found yet
267   if { ("$is_win" == "yes") && ($h_flag == "no") } {
268     if { [info exists ::env(ProgramFiles\(x86\))] } {
269       set h_flag "yes"
270       set path "$::env(ProgramFiles\(x86\))\\HTML Help Workshop"
271       set hhc_path "$path\\hhc.exe"
272       puts "Info: hhc " 
273       puts "      found in $path."
274     } else {
275       if { [info exists ::env(ProgramFiles)] } {
276         set h_flag   "yes"
277         set path     "$::env(ProgramFiles)\\HTML Help Workshop"
278         set hhc_path "$path\\hhc.exe"
279         puts "Info: hhc" 
280         puts "      found in $path."
281       }
282     }
283   }
284
285   # On *nix-like platforms, 
286   # check the default binary locations if the tools had not been found yet
287   if {  $is_win == "no"  &&
288       (($d_flag == "no") ||
289        ($i_flag == "no") ||
290        ($g_flag == "no") ||
291        ($l_flag == "no")) } {
292
293     set default_path { "/usr/bin" "/usr/local/bin" }
294     foreach path $default_path {
295       if {$d_flag == "no"} {
296         if { [file exists $path/doxygen$exe] } {
297           catch { exec $path/doxygen -V } version_string 
298           set version [lindex [split $version_string "\n"] 0]
299           puts "Info: $version "
300           puts "      found in $path."
301           set doxy_path "$path/doxygen$exe"
302           set d_flag "yes"
303         }
304       }
305       if {$g_flag == "no"} {
306         if { [file exists $path/dot$exe] } {
307           catch { exec $path/dot -V } version
308
309           puts "Info: $version "
310           puts "      found in $path."
311           set graph_path "$path/dot$exe"
312           set g_flag "yes"
313         }
314       }
315       if {$i_flag == "no"} {
316         if { [file exists $path/inkscape$exe] } {
317           catch { exec $path/inkscape -V } version
318           puts "Info: $version " 
319           puts "      found in $path."
320           set inkscape_path "$path/inkscape$exe"
321           set i_flag "yes"
322         }
323       }
324       if {$l_flag == "no"} {
325         if { [file exists $path/pdflatex$exe] } {
326           catch { exec $path/pdflatex -version } version
327           set version [lindex [split $version "\n"] 0]
328           puts "Info: $version " 
329           puts "      found in $path."
330           set latex_path "$path/pdflatex$exe"
331           set l_flag "yes"
332         }
333       }
334     }
335   }
336
337   # Check if tools have been found
338   if { $d_flag == "no" } {
339     puts "Warning: Could not find doxygen installed."
340     return -1
341   }
342   if { $g_flag == "no" } {
343     puts "Warning: Could not find graphviz installed."
344   }
345   if { $i_flag == "no" } {
346     puts "Warning: Could not find inkscape installed."
347   }  
348   if { $l_flag == "no" } {
349     puts "Warning: Could not find pdflatex installed."
350   }
351   if { ("$::tcl_platform(platform)" == "windows") && ($h_flag == "no") } {
352     puts "Warning: Could not find hhc installed."
353   }
354
355   puts ""
356 }
357
358 # Convert SVG files to PDF format to allow including them to PDF
359 # (requires InkScape to be in PATH)
360 proc OCCDoc_ProcessSvg {latexDir verboseMode} {
361   set anSvgList [glob -nocomplain $latexDir/*.svg]
362   if { $anSvgList == {} } {
363     return
364   }
365
366   catch { exec inkscape -V } anInkVer
367   set isOldSyntax 0
368   if {[string match "Inkscape 0.*" $anInkVer]} { set isOldSyntax 1 }
369   foreach file $anSvgList {
370     if {$verboseMode == "YES"} {
371       puts "Info: Converting file $file..."
372     }
373     set pdffile "[file rootname $file].pdf"
374     if { $isOldSyntax == 1 } {
375       if { [catch {exec inkscape -z -D --file=$file --export-pdf=$pdffile} res] } {
376         #puts "Error: $res."
377         return
378       }
379     } else {
380       if { [catch {exec inkscape $file --export-area-drawing --export-type=pdf --export-filename=$pdffile} res] } {
381         #puts "Error: $res."
382         return
383       }
384     }
385   }
386 }
387
388 # ==============================================
389 # Reference Manual-specific functions
390 # ==============================================
391
392 # Finds dependencies between all modules  
393 proc OCCDoc_CreateModulesDependencyGraph {dir filename modules mpageprefix} {
394   global module_dependency
395
396   if {![catch {open $dir/$filename.dot "w"} file]} {
397     puts $file "digraph $filename"
398     puts $file "\{"
399
400     foreach mod $modules {
401       if { $mod == "" } {
402         continue
403       }
404       puts $file "\t$mod \[ URL = \"[string tolower $mpageprefix$mod.html]\" \]"
405       foreach mod_depend $module_dependency($mod) {
406         puts $file "\t$mod_depend -> $mod \[ dir = \"back\", color = \"midnightblue\", style = \"solid\" \]"
407       }
408     }
409     
410     puts $file "\}"
411     close $file
412
413     return $filename
414   }
415 }
416
417 # Finds dependencies between all toolkits in module
418 proc OCCDoc_CreateModuleToolkitsDependencyGraph {dir filename modulename tpageprefix} {
419   global toolkits_in_module
420   global toolkit_dependency
421   global toolkit_parent_module
422
423   if {![catch {open $dir/$filename.dot "w"} file]} {
424     puts $file "digraph $filename"
425     puts $file "\{"
426
427     foreach tk $toolkits_in_module($modulename) {
428       puts $file "\t$tk \[ URL = \"[string tolower $tpageprefix$tk.html]\"\ ]"
429       foreach tkd $toolkit_dependency($tk) {
430         if { [info exists toolkit_parent_module($tkd)] } {
431           if {$toolkit_parent_module($tkd) == $modulename} {
432             puts $file "\t$tkd -> $tk \[ dir = \"back\", color = \"midnightblue\", style = \"solid\" \]"    
433           }
434         }
435       }
436     }
437     
438     puts $file "\}"
439     close $file
440     
441     return $filename
442   }
443 }
444
445 # Finds dependencies between the current toolkit and other toolkits
446 proc OCCDoc_CreateToolkitDependencyGraph {dir filename toolkitname tpageprefix} {
447   global toolkit_dependency
448   
449   if {![catch {open $dir/$filename.dot "w"} file]} {
450     puts $file "digraph $filename"
451     puts $file "\{"
452     
453     puts $file "\t$toolkitname \[ URL = \"[string tolower $tpageprefix$toolkitname.html]\"\, shape = box ]"
454     foreach tkd $toolkit_dependency($toolkitname) {
455       puts $file "\t$tkd \[ URL = \"[string tolower $tpageprefix$tkd.html]\"\ , shape = box ]"
456       puts $file "\t$toolkitname -> $tkd \[ color = \"midnightblue\", style = \"solid\" \]"    
457     }
458     
459     if {[llength $toolkit_dependency($toolkitname)] > 1} {
460     puts $file "\taspect = 1"
461     }
462     
463     puts $file "\}"
464     close $file
465     
466     return $filename
467   }
468 }
469
470 # Fills arrays of modules, toolkits, dependency of modules/toolkits etc 
471 proc OCCDoc_LoadData { {theProductsDir ""} } {
472   global toolkits_in_module
473   global toolkit_dependency
474   global toolkit_parent_module
475   global module_dependency
476
477   if { $theProductsDir == ""} {
478     set modules_files [glob -nocomplain -type f -directory "[OCCDoc_GetSourceDir $theProductsDir]/OS/" *.tcl]
479   } else {
480     set modules_files [glob -nocomplain -type f -directory "[OCCDoc_GetSourceDir $theProductsDir]/VAS/" *.tcl]
481   }
482
483   foreach module_file $modules_files {
484     source $module_file
485   }
486
487   set modules [OCCDoc_GetModulesList $theProductsDir]
488   foreach mod $modules {
489
490     if { $mod == "" } {
491       continue
492     }
493     # Get toolkits of current module
494     set toolkits_in_module($mod) [$mod:toolkits]
495     # Get all dependence of current toolkit 
496     foreach tk $toolkits_in_module($mod) {
497       # set parent module of current toolkit
498       set toolkit_parent_module($tk) $mod
499       set exlibfile      [open "[OCCDoc_GetSourceDir $theProductsDir]/$tk/EXTERNLIB" r]
500       set exlibfile_data [read $exlibfile]
501       set exlibfile_data [split $exlibfile_data "\n"]
502         
503       set toolkit_dependency($tk) {}
504       foreach dtk $exlibfile_data {
505         if { ([string first "TK" $dtk 0] == 0) || 
506              ([string first "P"  $dtk 0] == 0) } {
507           lappend toolkit_dependency($tk) $dtk
508         }
509       }
510       close $exlibfile
511     }
512   }
513
514   # Get modules dependency
515   foreach mod $modules {
516     set module_dependency($mod) {}
517     foreach tk $toolkits_in_module($mod) {
518       foreach tkd $toolkit_dependency($tk) {
519         if { [info exists toolkit_parent_module($tkd)] } {
520           if { $toolkit_parent_module($tkd) != $mod &&
521                [lsearch $module_dependency($mod) $toolkit_parent_module($tkd)] == -1} {
522             lappend module_dependency($mod) $toolkit_parent_module($tkd)
523           }
524         }
525       }
526     }
527   }
528 }
529
530 # Returns list of packages of the given toolkit
531 proc OCCDoc_GetPackagesList { theToolKitPath } {
532
533   set packages_list {}
534   
535   # Open file with list of packages of the given toolkit
536   set fileid [open "$theToolKitPath/PACKAGES" "r"]
537   
538   while { [eof $fileid] == 0 } {
539     set str [gets $fileid]
540     if { $str != "" } {
541       lappend packages_list $str
542     }
543   }
544
545   close $fileid
546   
547   return $packages_list
548 }
549
550 # Returns list of modules from UDLIST
551 proc OCCDoc_GetModulesList { {theProductsDir ""} } {
552
553   if { $theProductsDir == "" } {
554     source "[OCCDoc_GetSourceDir $theProductsDir]/OS/Modules.tcl"
555     # load a command from this file
556     set modules [OS:Modules]
557   } else {
558     source "[OCCDoc_GetSourceDir $theProductsDir]/VAS/Products.tcl"
559     # load a command from this file
560     set modules [VAS:Products]
561         set modules [lsearch -not -all -inline $modules "VAS"]
562   }
563
564   return $modules
565 }
566
567 # Returns list of desired files in the specified location
568 proc OCCDoc_GetHeadersList { theDesiredContent thePackageName {theProductsDir ""} } {
569
570   # Get list of header files with path
571   set files_list [split [glob -nocomplain -type f -directory "[OCCDoc_GetSourceDir $theProductsDir]/$thePackageName" "${thePackageName}.hxx" "${thePackageName}_*.hxx"]]
572
573   # Get content according to desired type ('p' for path and 'f' for filenames only)
574   if { $theDesiredContent == "p" } {
575     return $files_list
576   } elseif { $theDesiredContent == "f" } {
577
578     # Cut paths from filenames
579     foreach file $files_list {
580       set elem_index [lsearch $files_list $file]
581       lset files_list $elem_index [OCCDoc_GetNameFromPath [lindex $files_list $elem_index]]
582     }
583     return $files_list
584   }
585 }
586
587 # Returns location of the toolkit
588 proc OCCDoc_Locate { theToolKitName {theProductsDir ""} } {
589   set tk_dir "[OCCDoc_GetSourceDir $theProductsDir]/[OCCDoc_GetNameFromPath $theToolKitName]"
590   return $tk_dir
591 }
592
593 # Gets contents of the given html node (for Post-processing)
594 proc OCCDoc_GetNodeContents {node props html} {
595   set openTag "<$node$props>"
596   set closingTag "</$node>"
597   set start [string first $openTag $html]
598   if {$start == -1} {
599     return ""
600   }
601   set start [expr $start + [string length $openTag]]
602   set end   [string length $html]
603   set html  [string range $html $start $end]
604   set start [string first $closingTag $html]
605   set end   [string length $html]
606   if {$start == -1} {
607     return ""
608   }
609   set start [expr $start - 1]
610   return [string range $html 0 $start]
611 }
612
613 # Generates main page file describing module structure
614 proc OCCDoc_MakeMainPage {outDir outFile modules {theProductsDir ""} } {
615   global env
616
617   set one_module [expr [llength $modules] == 1]
618   set fd [open $outFile "w"]
619
620   set module_prefix "module_"
621   set toolkit_prefix "toolkit_"
622   set package_prefix "package_"
623
624   if { ! [file exists "$outDir/html"] } {
625     file mkdir "$outDir/html"
626   }
627
628   OCCDoc_LoadData $theProductsDir
629
630   # Main page: list of modules
631   if { ! $one_module } {
632     puts $fd "/**"
633     puts $fd "\\mainpage Open CASCADE Technology"
634
635     foreach mod $modules {
636         puts $fd "\\li \\subpage [string tolower $module_prefix$mod]"
637     }
638     # insert modules relationship diagram
639     puts $fd "\\dotfile [OCCDoc_CreateModulesDependencyGraph $outDir/html schema_all_modules $modules $module_prefix]"
640     puts $fd "**/\n"
641   }
642
643   # One page per module: list of toolkits
644   set toolkits {}
645   foreach mod $modules {
646     if { $mod == "" } {
647         continue
648     }
649     puts $fd "/**"
650     if { $one_module } {
651         puts $fd "\\mainpage OCCT Module [$mod:name]"
652     } else {
653         puts $fd "\\page [string tolower module_$mod] Module [$mod:name]"
654     }
655     foreach tk [lsort [$mod:toolkits]] {
656         lappend toolkits $tk
657         puts $fd "\\li \\subpage [string tolower $toolkit_prefix$tk]"
658     }
659     puts $fd "\\dotfile [OCCDoc_CreateModuleToolkitsDependencyGraph $outDir/html schema_$mod $mod $toolkit_prefix]"
660     puts $fd "**/\n"
661   }
662
663   # One page per toolkit: list of packages
664   set packages {}
665   foreach tk $toolkits {
666     puts $fd "/**"
667     puts $fd "\\page [string tolower toolkit_$tk] Toolkit $tk"
668     foreach pk [lsort [OCCDoc_GetPackagesList [OCCDoc_Locate $tk $theProductsDir]]] {
669         lappend packages $pk
670         set u [OCCDoc_GetNameFromPath $pk]
671         puts $fd "\\li \\subpage [string tolower $package_prefix$u]"
672     }
673     puts $fd "\\dotfile [OCCDoc_CreateToolkitDependencyGraph $outDir/html schema_$tk $tk $toolkit_prefix]"
674     puts $fd "**/\n"
675   }
676
677   # One page per package: list of classes
678   foreach pk $packages {
679     set u [OCCDoc_GetNameFromPath $pk]
680     puts $fd "/**"
681     puts $fd "\\page [string tolower $package_prefix$u] Package $u"
682     foreach hdr [lsort [OCCDoc_GetHeadersList "f" "$pk" "$theProductsDir"]] {
683       if { ! [regexp {^Handle_} $hdr] && [regexp {(.*)[.]hxx} $hdr str obj] } {
684         puts $fd "\\li \\subpage $obj"
685       }
686     }
687     puts $fd "**/\n"
688   }
689
690   close $fd
691
692   return $outFile
693 }
694
695 # Parses generated files to add a navigation path 
696 proc OCCDoc_PostProcessor {outDir} {
697   puts "[clock format [clock seconds] -format {%Y.%m.%d %H:%M}] Post-process is started ..."
698   append outDir "/html"
699   set files [glob -nocomplain -type f $outDir/package_*]
700   if { $files != {} } {
701     foreach f [lsort $files] {
702       set packageFilePnt  [open $f r]
703       set packageFile     [read $packageFilePnt]
704       set navPath         [OCCDoc_GetNodeContents "div" " id=\"nav-path\" class=\"navpath\"" $packageFile]
705       set packageName     [OCCDoc_GetNodeContents "div" " class=\"title\"" $packageFile]
706       regsub -all {<[^<>]*>} $packageName "" packageName 
707
708       # add package link to nav path
709       set first           [expr 1 + [string last "/" $f]]
710       set last            [expr [string length $f] - 1]
711       set packageFileName [string range $f $first $last]
712       set end             [string first "</ul>" $navPath]
713       set end             [expr $end - 1]
714       set navPath         [string range $navPath 0 $end]
715       append navPath "  <li class=\"navelem\"><a class=\"el\" href=\"$packageFileName\">$packageName</a>      </li>\n    </ul>"
716
717       # get list of files to update
718       set listContents [OCCDoc_GetNodeContents "div" " class=\"textblock\"" $packageFile]
719       set listContents [OCCDoc_GetNodeContents "ul" "" $listContents]
720       set lines [split $listContents "\n"]
721       foreach line $lines {
722         if {[regexp {href=\"([^\"]*)\"} $line tmpLine classFileName]} {
723           # check if anchor is there
724           set anchorPos [string first "#" $classFileName]
725           if {$anchorPos != -1} {
726             set classFileName [string range $classFileName 0 [expr $anchorPos - 1]]
727           }
728
729           # read class file
730           set classFilePnt [open $outDir/$classFileName r+]
731           set classFile    [read $classFilePnt]
732
733           # find position of content block 
734           set contentPos   [string first "<div class=\"header\">" $classFile]
735           set navPart      [string range $classFile 0 [expr $contentPos - 1]]
736
737           # position where to insert nav path
738           set posToInsert  [string last "</div>" $navPart]
739           set prePart      [string range $classFile 0 [expr $posToInsert - 1]]
740           set postPart     [string range $classFile $posToInsert [string length $classFile]]
741           set newClassFile ""
742           append newClassFile $prePart "  <div id=\"nav-path\" class=\"navpath\">" $navPath \n "  </div>" \n $postPart
743
744           # write updated content
745           seek $classFilePnt 0
746           puts $classFilePnt $newClassFile
747           close $classFilePnt
748         } 
749       }
750       close $packageFilePnt
751     }
752     return 0
753   } else {
754     puts "no files found"
755     return 1
756   }
757 }
758
759 # ======================================
760 #  User Guides-specific functions
761 # ======================================
762
763 # Loads a list of docfiles from file FILES.txt
764 proc OCCDoc_LoadFilesList {} {
765   set INPUTDIR [OCCDoc_GetDoxDir [OCCDoc_GetProdRootDir]]
766
767   global available_docfiles
768   set available_docfiles {}
769
770   # Read data from file
771   if { [file exists "$INPUTDIR/FILES_HTML.txt"] == 1 } {
772     set FILE [open "$INPUTDIR/FILES_HTML.txt" r]
773     while {1} {
774       set line [string trim [gets $FILE]]
775
776       # trim possible comments starting with '#'
777       set line [regsub {\#.*} $line {}]
778       if {$line != ""} {
779         lappend available_docfiles $line
780       }
781       if {[eof $FILE]} {
782         close $FILE
783         break
784       }
785     }
786   } else {
787     return -1
788   }
789
790   global available_pdf
791   set    available_pdf {}
792
793   # Read data from file
794   if { [file exists "$INPUTDIR/FILES_PDF.txt"] } {
795     set FILE [open "$INPUTDIR/FILES_PDF.txt" r]
796     while {1} {
797       set line [string trim [gets $FILE]]
798
799       # Trim possible comments starting with '#'
800       set line [regsub {\#.*} $line {}]
801       if {$line != ""} {
802         lappend available_pdf $line
803       }
804       if {[eof $FILE]} {
805         close $FILE
806         break
807       }
808     }
809   } else {
810     return -1
811   }
812   return 0
813 }
814
815 # Writes new TeX file for conversion from tex to pdf for a specific doc
816 proc OCCDoc_MakeRefmanTex {fileName latexDir verboseMode latexFilesList} {
817
818   if { $verboseMode == "YES" } {
819     puts "Info: Making refman.tex file for $fileName..."
820   }
821   set DOCNAME "$latexDir/refman.tex"
822   if {[file exists $DOCNAME] == 1} {
823     file delete -force $DOCNAME
824   }
825
826   # Copy template file to latex folder
827   if { "[OCCDoc_GetProdRootDir]" != "" } {
828     file copy "[OCCDoc_GetDoxDir [OCCDoc_GetProdRootDir]]/resources/prod_pdf_template.tex" $DOCNAME
829   } else {
830     file copy "[OCCDoc_GetDoxDir]/resources/occt_pdf_template.tex" $DOCNAME
831   }
832
833   # Get templatized data
834   set texfile [open $DOCNAME "r"]
835   set texfile_loaded [read $texfile]
836   close $texfile
837
838   # Replace dummy values 
839   set year       [clock format [clock seconds] -format {%Y}]
840   set month      [clock format [clock seconds] -format {%B}]
841   set texfile    [open $DOCNAME "w"]
842   set casVersion [OCCDoc_DetectCasVersion]
843
844   # Get name of the document
845   set docLabel   ""
846   foreach aFileName $latexFilesList {
847     # Find the file in FILES_PDF.txt
848     set parsedFileName [file rootname [lindex [split $aFileName "/" ] end]]
849     if { [regexp "${parsedFileName}$" $fileName] } {
850       set filepath "[OCCDoc_GetDoxDir [OCCDoc_GetProdRootDir]]/$aFileName"
851       if { [file exists $filepath] } {
852         set MDFile   [open $filepath "r"]
853         set label    [split [gets $MDFile] "\{"]
854         set docLabel [lindex $label 0]
855         close $MDFile
856         break
857       }
858     }
859   }
860
861   set occtlogo_path "[OCCDoc_GetDoxDir]/resources/occt_logo.png"
862   set occlogo_path  "[OCCDoc_GetDoxDir]/resources/occ_logo.png"
863   set copyright_path  "[OCCDoc_GetDoxDir [OCCDoc_GetProdRootDir]]/resources/prod_pdf_template.tex"
864   set texfile_loaded [string map [list DEFDOCLABEL "$docLabel" DEFCASVERSION "$casVersion" DEFFILENAME "$fileName" DEFYEAR "$year" DEFMONTH "$month" DEFCOPYRIGHT "$copyright_path" DEFLOGO "$occtlogo_path" DEFOCCLOGO "$occlogo_path" DEFTITLE ""] $texfile_loaded]
865
866   # Get data
867   puts $texfile $texfile_loaded
868
869   close $texfile
870 }
871
872 # Postprocesses generated TeX files
873 proc OCCDoc_ProcessTex {{texFiles {}} {latexDir} verboseMode} {
874
875   foreach TEX $texFiles {
876     if {$verboseMode == "YES"} {
877       puts "Info: Preprocessing file $TEX..."
878     }
879
880     if {![file exists $TEX]} {
881       puts "Error: file $TEX does not exist."
882       return -1
883     }
884
885     set IN_F        [open "$TEX" "r"]
886     set TMPFILENAME "$latexDir/temp.tex"
887     set OUT_F       [open $TMPFILENAME w]
888
889         while {1} {
890             set line [gets $IN_F]
891             if { [string first "\\includegraphics" $line] != -1 } {
892               # replace svg extension by pdf
893               set line [regsub {[.]svg} $line ".pdf"]
894               # Center images in TeX files
895               set line "\\begin{center}\n $line\n\\end{center}"
896             } elseif { [string first "\\subsection" $line] != -1 } {
897                 # Replace \subsection with \section tag
898                 regsub -all "\\\\subsection" $line "\\\\section" line
899             } elseif { [string first "\\subsubsection" $line] != -1 } {
900                 # Replace \subsubsection with \subsection tag
901                 regsub -all "\\\\subsubsection" $line "\\\\subsection" line
902             } elseif { [string first "\\paragraph" $line] != -1 } {
903                 # Replace \paragraph with \subsubsection tag
904                 regsub -all "\\\\paragraph" $line "\\\\subsubsection" line
905             }
906             puts $OUT_F $line
907
908       if {[eof $IN_F]} {
909         close $IN_F
910         close $OUT_F
911         break
912       }
913     }
914
915     file delete -force $TEX
916     file rename $TMPFILENAME $TEX
917   }
918 }