0030396: Infinite recursion during ShapeFix after BRepAlgoAPI_Cut
[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   } else {
183     set exe ""
184   }
185
186   set g_flag "no"
187   set d_flag "no"
188   set i_flag "no"
189   set h_flag "no"
190   set l_flag "no"
191
192   puts ""
193   set envPath $::env(PATH)
194   if { $is_win == "yes" } {
195     set searchPathsList [split $envPath ";"]
196   } else {
197     set searchPathsList [split $envPath ":"]
198   }
199
200   foreach path $searchPathsList {
201     if { ($is_win == "no") && 
202          (($path == "/usr/bin") || ($path == "/usr/local/bin")) } {
203         # Avoid searching in default bin location
204         continue
205     }
206     if {$d_flag == "no"} {
207       if { [file exists $path/doxygen$exe] } {
208         catch { exec $path/doxygen -V } version_string 
209         set version [lindex [split $version_string "\n"] 0]
210         puts "Info: $version "
211         puts "      found in $path."
212         set doxy_path "$path/doxygen$exe"
213         set d_flag "yes"
214       }
215     }
216     if {$g_flag == "no"} {
217       if { [file exists $path/dot$exe] } {
218         catch { exec $path/dot -V } version
219
220         puts "Info: $version "
221         puts "      found in $path."
222         set graph_path "$path/dot$exe"
223         set g_flag "yes"
224       }
225     }
226     if {$i_flag == "no"} {
227       if { [file exists $path/inkscape$exe] } {
228         catch { exec $path/inkscape -V } version
229         puts "Info: $version " 
230         puts "      found in $path."
231         set inkscape_path "$path/inkscape$exe"
232         set i_flag "yes"
233       }
234     }
235     if {$l_flag == "no"} {
236       if { [file exists $path/pdflatex$exe] } {
237         catch { exec $path/pdflatex -version } version
238         set version [lindex [split $version "\n"] 0]
239         puts "Info: $version " 
240         puts "      found in $path."
241         set latex_path "$path/pdflatex$exe"
242         set l_flag "yes"
243       }
244     }
245     if { ("$is_win" == "yes") && ($h_flag == "no") } {
246       if { [file exists $path/hhc.exe] } {
247         puts "Info: hhc " 
248         puts "      found in $path."
249         set hhc_path "hhc$exe"
250         set h_flag "yes"
251       }
252     }
253     if { ($d_flag == "yes") &&
254          ($i_flag == "yes") &&
255          ($g_flag == "yes") &&
256          ($l_flag == "yes") &&
257          (($is_win == "yes") && 
258           ($h_flag == "yes")) } {
259       break
260     }
261   }
262
263   # On Windows search for hhc.exe in the default location 
264   # if it has not been found yet
265   if { ("$is_win" == "yes") && ($h_flag == "no") } {
266     if { [info exists ::env(ProgramFiles\(x86\))] } {
267       set h_flag "yes"
268       set path "$::env(ProgramFiles\(x86\))\\HTML Help Workshop"
269       set hhc_path "$path\\hhc.exe"
270       puts "Info: hhc " 
271       puts "      found in $path."
272     } else {
273       if { [info exists ::env(ProgramFiles)] } {
274         set h_flag   "yes"
275         set path     "$::env(ProgramFiles)\\HTML Help Workshop"
276         set hhc_path "$path\\hhc.exe"
277         puts "Info: hhc" 
278         puts "      found in $path."
279       }
280     }
281   }
282
283   # On *nix-like platforms, 
284   # check the default binary locations if the tools had not been found yet
285   if {  $is_win == "no"  &&
286       (($d_flag == "no") ||
287        ($i_flag == "no") ||
288        ($g_flag == "no") ||
289        ($l_flag == "no")) } {
290
291     set default_path { "/usr/bin" "/usr/local/bin" }
292     foreach path $default_path {
293       if {$d_flag == "no"} {
294         if { [file exists $path/doxygen$exe] } {
295           catch { exec $path/doxygen -V } version_string 
296           set version [lindex [split $version_string "\n"] 0]
297           puts "Info: $version "
298           puts "      found in $path."
299           set doxy_path "$path/doxygen$exe"
300           set d_flag "yes"
301         }
302       }
303       if {$g_flag == "no"} {
304         if { [file exists $path/dot$exe] } {
305           catch { exec $path/dot -V } version
306
307           puts "Info: $version "
308           puts "      found in $path."
309           set graph_path "$path/dot$exe"
310           set g_flag "yes"
311         }
312       }
313       if {$i_flag == "no"} {
314         if { [file exists $path/inkscape$exe] } {
315           catch { exec $path/inkscape -V } version
316           puts "Info: $version " 
317           puts "      found in $path."
318           set inkscape_path "$path/inkscape$exe"
319           set i_flag "yes"
320         }
321       }
322       if {$l_flag == "no"} {
323         if { [file exists $path/pdflatex$exe] } {
324           catch { exec $path/pdflatex -version } version
325           set version [lindex [split $version "\n"] 0]
326           puts "Info: $version " 
327           puts "      found in $path."
328           set latex_path "$path/pdflatex$exe"
329           set l_flag "yes"
330         }
331       }
332     }
333   }
334
335   # Check if tools have been found
336   if { $d_flag == "no" } {
337     puts "Warning: Could not find doxygen installed."
338     return -1
339   }
340   if { $g_flag == "no" } {
341     puts "Warning: Could not find graphviz installed."
342   }
343   if { $i_flag == "no" } {
344     puts "Warning: Could not find inkscape installed."
345   }  
346   if { $l_flag == "no" } {
347     puts "Warning: Could not find pdflatex installed."
348   }
349   if { ("$::tcl_platform(platform)" == "windows") && ($h_flag == "no") } {
350     puts "Warning: Could not find hhc installed."
351   }
352
353   puts ""
354 }
355
356 # Convert SVG files to PDF format to allow including them to PDF
357 # (requires InkScape to be in PATH)
358 proc OCCDoc_ProcessSvg {latexDir verboseMode} {
359
360   foreach file [glob -nocomplain $latexDir/*.svg] {
361     if {$verboseMode == "YES"} {
362       puts "Info: Converting file $file..."
363     }
364     set pdffile "[file rootname $file].pdf"
365     if { [catch {exec inkscape -z -D --file=$file --export-pdf=$pdffile} res] } {
366       #puts "Error: $res."
367       return
368     }
369   }
370 }
371
372 # ==============================================
373 # Reference Manual-specific functions
374 # ==============================================
375
376 # Finds dependencies between all modules  
377 proc OCCDoc_CreateModulesDependencyGraph {dir filename modules mpageprefix} {
378   global module_dependency
379
380   if {![catch {open $dir/$filename.dot "w"} file]} {
381     puts $file "digraph $filename"
382     puts $file "\{"
383
384     foreach mod $modules {
385       if { $mod == "" } {
386         continue
387       }
388       puts $file "\t$mod \[ URL = \"[string tolower $mpageprefix$mod.html]\" \]"
389       foreach mod_depend $module_dependency($mod) {
390         puts $file "\t$mod_depend -> $mod \[ dir = \"back\", color = \"midnightblue\", style = \"solid\" \]"
391       }
392     }
393     
394     puts $file "\}"
395     close $file
396
397     return $filename
398   }
399 }
400
401 # Finds dependencies between all toolkits in module
402 proc OCCDoc_CreateModuleToolkitsDependencyGraph {dir filename modulename tpageprefix} {
403   global toolkits_in_module
404   global toolkit_dependency
405   global toolkit_parent_module
406
407   if {![catch {open $dir/$filename.dot "w"} file]} {
408     puts $file "digraph $filename"
409     puts $file "\{"
410
411     foreach tk $toolkits_in_module($modulename) {
412       puts $file "\t$tk \[ URL = \"[string tolower $tpageprefix$tk.html]\"\ ]"
413       foreach tkd $toolkit_dependency($tk) {
414         if { [info exists toolkit_parent_module($tkd)] } {
415           if {$toolkit_parent_module($tkd) == $modulename} {
416             puts $file "\t$tkd -> $tk \[ dir = \"back\", color = \"midnightblue\", style = \"solid\" \]"    
417           }
418         }
419       }
420     }
421     
422     puts $file "\}"
423     close $file
424     
425     return $filename
426   }
427 }
428
429 # Finds dependencies between the current toolkit and other toolkits
430 proc OCCDoc_CreateToolkitDependencyGraph {dir filename toolkitname tpageprefix} {
431   global toolkit_dependency
432   
433   if {![catch {open $dir/$filename.dot "w"} file]} {
434     puts $file "digraph $filename"
435     puts $file "\{"
436     
437     puts $file "\t$toolkitname \[ URL = \"[string tolower $tpageprefix$toolkitname.html]\"\, shape = box ]"
438     foreach tkd $toolkit_dependency($toolkitname) {
439       puts $file "\t$tkd \[ URL = \"[string tolower $tpageprefix$tkd.html]\"\ , shape = box ]"
440       puts $file "\t$toolkitname -> $tkd \[ color = \"midnightblue\", style = \"solid\" \]"    
441     }
442     
443     if {[llength $toolkit_dependency($toolkitname)] > 1} {
444     puts $file "\taspect = 1"
445     }
446     
447     puts $file "\}"
448     close $file
449     
450     return $filename
451   }
452 }
453
454 # Fills arrays of modules, toolkits, dependency of modules/toolkits etc 
455 proc OCCDoc_LoadData { {theProductsDir ""} } {
456   global toolkits_in_module
457   global toolkit_dependency
458   global toolkit_parent_module
459   global module_dependency
460
461   if { $theProductsDir == ""} {
462     set modules_files [glob -nocomplain -type f -directory "[OCCDoc_GetSourceDir $theProductsDir]/OS/" *.tcl]
463   } else {
464     set modules_files [glob -nocomplain -type f -directory "[OCCDoc_GetSourceDir $theProductsDir]/VAS/" *.tcl]
465   }
466
467   foreach module_file $modules_files {
468     source $module_file
469   }
470
471   set modules [OCCDoc_GetModulesList $theProductsDir]
472   foreach mod $modules {
473
474     if { $mod == "" } {
475       continue
476     }
477     # Get toolkits of current module
478     set toolkits_in_module($mod) [$mod:toolkits]
479     # Get all dependence of current toolkit 
480     foreach tk $toolkits_in_module($mod) {
481       # set parent module of current toolkit
482       set toolkit_parent_module($tk) $mod
483       set exlibfile      [open "[OCCDoc_GetSourceDir $theProductsDir]/$tk/EXTERNLIB" r]
484       set exlibfile_data [read $exlibfile]
485       set exlibfile_data [split $exlibfile_data "\n"]
486         
487       set toolkit_dependency($tk) {}
488       foreach dtk $exlibfile_data {
489         if { ([string first "TK" $dtk 0] == 0) || 
490              ([string first "P"  $dtk 0] == 0) } {
491           lappend toolkit_dependency($tk) $dtk
492         }
493       }
494       close $exlibfile
495     }
496   }
497
498   # Get modules dependency
499   foreach mod $modules {
500     set module_dependency($mod) {}
501     foreach tk $toolkits_in_module($mod) {
502       foreach tkd $toolkit_dependency($tk) {
503         if { [info exists toolkit_parent_module($tkd)] } {
504           if { $toolkit_parent_module($tkd) != $mod &&
505                [lsearch $module_dependency($mod) $toolkit_parent_module($tkd)] == -1} {
506             lappend module_dependency($mod) $toolkit_parent_module($tkd)
507           }
508         }
509       }
510     }
511   }
512 }
513
514 # Returns list of packages of the given toolkit
515 proc OCCDoc_GetPackagesList { theToolKitPath } {
516
517   set packages_list {}
518   
519   # Open file with list of packages of the given toolkit
520   set fileid [open "$theToolKitPath/PACKAGES" "r"]
521   
522   while { [eof $fileid] == 0 } {
523     set str [gets $fileid]
524     if { $str != "" } {
525       lappend packages_list $str
526     }
527   }
528
529   close $fileid
530   
531   return $packages_list
532 }
533
534 # Returns list of modules from UDLIST
535 proc OCCDoc_GetModulesList { {theProductsDir ""} } {
536
537   if { $theProductsDir == "" } {
538     source "[OCCDoc_GetSourceDir $theProductsDir]/OS/Modules.tcl"
539     # load a command from this file
540     set modules [OS:Modules]
541   } else {
542     source "[OCCDoc_GetSourceDir $theProductsDir]/VAS/Products.tcl"
543     # load a command from this file
544     set modules [VAS:Products]
545         set modules [lsearch -not -all -inline $modules "VAS"]
546   }
547
548   return $modules
549 }
550
551 # Returns list of desired files in the specified location
552 proc OCCDoc_GetHeadersList { theDesiredContent thePackageName {theProductsDir ""} } {
553
554   # Get list of header files with path
555   set files_list [split [glob -nocomplain -type f -directory "[OCCDoc_GetSourceDir $theProductsDir]/$thePackageName" "${thePackageName}.hxx" "${thePackageName}_*.hxx"]]
556
557   # Get content according to desired type ('p' for path and 'f' for filenames only)
558   if { $theDesiredContent == "p" } {
559     return $files_list
560   } elseif { $theDesiredContent == "f" } {
561
562     # Cut paths from filenames
563     foreach file $files_list {
564       set elem_index [lsearch $files_list $file]
565       lset files_list $elem_index [OCCDoc_GetNameFromPath [lindex $files_list $elem_index]]
566     }
567     return $files_list
568   }
569 }
570
571 # Returns location of the toolkit
572 proc OCCDoc_Locate { theToolKitName {theProductsDir ""} } {
573   set tk_dir "[OCCDoc_GetSourceDir $theProductsDir]/[OCCDoc_GetNameFromPath $theToolKitName]"
574   return $tk_dir
575 }
576
577 # Gets contents of the given html node (for Post-processing)
578 proc OCCDoc_GetNodeContents {node props html} {
579   set openTag "<$node$props>"
580   set closingTag "</$node>"
581   set start [string first $openTag $html]
582   if {$start == -1} {
583     return ""
584   }
585   set start [expr $start + [string length $openTag]]
586   set end   [string length $html]
587   set html  [string range $html $start $end]
588   set start [string first $closingTag $html]
589   set end   [string length $html]
590   if {$start == -1} {
591     return ""
592   }
593   set start [expr $start - 1]
594   return [string range $html 0 $start]
595 }
596
597 # Generates main page file describing module structure
598 proc OCCDoc_MakeMainPage {outDir outFile modules {theProductsDir ""} } {
599   global env
600
601   set one_module [expr [llength $modules] == 1]
602   set fd [open $outFile "w"]
603
604   set module_prefix "module_"
605   set toolkit_prefix "toolkit_"
606   set package_prefix "package_"
607
608   if { ! [file exists "$outDir/html"] } {
609     file mkdir "$outDir/html"
610   }
611
612   OCCDoc_LoadData $theProductsDir
613
614   # Main page: list of modules
615   if { ! $one_module } {
616     puts $fd "/**"
617     puts $fd "\\mainpage Open CASCADE Technology"
618
619     foreach mod $modules {
620         puts $fd "\\li \\subpage [string tolower $module_prefix$mod]"
621     }
622     # insert modules relationship diagramm
623     puts $fd "\\dotfile [OCCDoc_CreateModulesDependencyGraph $outDir/html schema_all_modules $modules $module_prefix]"
624     puts $fd "**/\n"
625   }
626
627   # One page per module: list of toolkits
628   set toolkits {}
629   foreach mod $modules {
630     if { $mod == "" } {
631         continue
632     }
633     puts $fd "/**"
634     if { $one_module } {
635         puts $fd "\\mainpage OCCT Module [$mod:name]"
636     } else {
637         puts $fd "\\page [string tolower module_$mod] Module [$mod:name]"
638     }
639     foreach tk [lsort [$mod:toolkits]] {
640         lappend toolkits $tk
641         puts $fd "\\li \\subpage [string tolower $toolkit_prefix$tk]"
642     }
643     puts $fd "\\dotfile [OCCDoc_CreateModuleToolkitsDependencyGraph $outDir/html schema_$mod $mod $toolkit_prefix]"
644     puts $fd "**/\n"
645   }
646
647   # One page per toolkit: list of packages
648   set packages {}
649   foreach tk $toolkits {
650     puts $fd "/**"
651     puts $fd "\\page [string tolower toolkit_$tk] Toolkit $tk"
652     foreach pk [lsort [OCCDoc_GetPackagesList [OCCDoc_Locate $tk $theProductsDir]]] {
653         lappend packages $pk
654         set u [OCCDoc_GetNameFromPath $pk]
655         puts $fd "\\li \\subpage [string tolower $package_prefix$u]"
656     }
657     puts $fd "\\dotfile [OCCDoc_CreateToolkitDependencyGraph $outDir/html schema_$tk $tk $toolkit_prefix]"
658     puts $fd "**/\n"
659   }
660
661   # One page per package: list of classes
662   foreach pk $packages {
663     set u [OCCDoc_GetNameFromPath $pk]
664     puts $fd "/**"
665     puts $fd "\\page [string tolower $package_prefix$u] Package $u"
666     foreach hdr [lsort [OCCDoc_GetHeadersList "f" "$pk" "$theProductsDir"]] {
667       if { ! [regexp {^Handle_} $hdr] && [regexp {(.*)[.]hxx} $hdr str obj] } {
668         puts $fd "\\li \\subpage $obj"
669       }
670     }
671     puts $fd "**/\n"
672   }
673
674   close $fd
675
676   return $outFile
677 }
678
679 # Parses generated files to add a navigation path 
680 proc OCCDoc_PostProcessor {outDir} {
681   puts "[clock format [clock seconds] -format {%Y.%m.%d %H:%M}] Post-process is started ..."
682   append outDir "/html"
683   set files [glob -nocomplain -type f $outDir/package_*]
684   if { $files != {} } {
685     foreach f [lsort $files] {
686       set packageFilePnt  [open $f r]
687       set packageFile     [read $packageFilePnt]
688       set navPath         [OCCDoc_GetNodeContents "div" " id=\"nav-path\" class=\"navpath\"" $packageFile]
689       set packageName     [OCCDoc_GetNodeContents "div" " class=\"title\"" $packageFile]
690       regsub -all {<[^<>]*>} $packageName "" packageName 
691
692       # add package link to nav path
693       set first           [expr 1 + [string last "/" $f]]
694       set last            [expr [string length $f] - 1]
695       set packageFileName [string range $f $first $last]
696       set end             [string first "</ul>" $navPath]
697       set end             [expr $end - 1]
698       set navPath         [string range $navPath 0 $end]
699       append navPath "  <li class=\"navelem\"><a class=\"el\" href=\"$packageFileName\">$packageName</a>      </li>\n    </ul>"
700
701       # get list of files to update
702       set listContents [OCCDoc_GetNodeContents "div" " class=\"textblock\"" $packageFile]
703       set listContents [OCCDoc_GetNodeContents "ul" "" $listContents]
704       set lines [split $listContents "\n"]
705       foreach line $lines {
706         if {[regexp {href=\"([^\"]*)\"} $line tmpLine classFileName]} {
707           # check if anchor is there
708           set anchorPos [string first "#" $classFileName]
709           if {$anchorPos != -1} {
710             set classFileName [string range $classFileName 0 [expr $anchorPos - 1]]
711           }
712
713           # read class file
714           set classFilePnt [open $outDir/$classFileName r+]
715           set classFile    [read $classFilePnt]
716
717           # find position of content block 
718           set contentPos   [string first "<div class=\"header\">" $classFile]
719           set navPart      [string range $classFile 0 [expr $contentPos - 1]]
720
721           # position where to insert nav path
722           set posToInsert  [string last "</div>" $navPart]
723           set prePart      [string range $classFile 0 [expr $posToInsert - 1]]
724           set postPart     [string range $classFile $posToInsert [string length $classFile]]
725           set newClassFile ""
726           append newClassFile $prePart "  <div id=\"nav-path\" class=\"navpath\">" $navPath \n "  </div>" \n $postPart
727
728           # write updated content
729           seek $classFilePnt 0
730           puts $classFilePnt $newClassFile
731           close $classFilePnt
732         } 
733       }
734       close $packageFilePnt
735     }
736     return 0
737   } else {
738     puts "no files found"
739     return 1
740   }
741 }
742
743 # ======================================
744 #  User Guides-specific functions
745 # ======================================
746
747 # Loads a list of docfiles from file FILES.txt
748 proc OCCDoc_LoadFilesList {} {
749   set INPUTDIR [OCCDoc_GetDoxDir [OCCDoc_GetProdRootDir]]
750
751   global available_docfiles
752   set available_docfiles {}
753
754   # Read data from file
755   if { [file exists "$INPUTDIR/FILES_HTML.txt"] == 1 } {
756     set FILE [open "$INPUTDIR/FILES_HTML.txt" r]
757     while {1} {
758       set line [string trim [gets $FILE]]
759
760       # trim possible comments starting with '#'
761       set line [regsub {\#.*} $line {}]
762       if {$line != ""} {
763         lappend available_docfiles $line
764       }
765       if {[eof $FILE]} {
766         close $FILE
767         break
768       }
769     }
770   } else {
771     return -1
772   }
773
774   global available_pdf
775   set    available_pdf {}
776
777   # Read data from file
778   if { [file exists "$INPUTDIR/FILES_PDF.txt"] } {
779     set FILE [open "$INPUTDIR/FILES_PDF.txt" r]
780     while {1} {
781       set line [string trim [gets $FILE]]
782
783       # Trim possible comments starting with '#'
784       set line [regsub {\#.*} $line {}]
785       if {$line != ""} {
786         lappend available_pdf $line
787       }
788       if {[eof $FILE]} {
789         close $FILE
790         break
791       }
792     }
793   } else {
794     return -1
795   }
796   return 0
797 }
798
799 # Writes new TeX file for conversion from tex to pdf for a specific doc
800 proc OCCDoc_MakeRefmanTex {fileName latexDir verboseMode latexFilesList} {
801
802   if { $verboseMode == "YES" } {
803     puts "Info: Making refman.tex file for $fileName..."
804   }
805   set DOCNAME "$latexDir/refman.tex"
806   if {[file exists $DOCNAME] == 1} {
807     file delete -force $DOCNAME
808   }
809
810   # Copy template file to latex folder
811   if { "[OCCDoc_GetProdRootDir]" != "" } {
812     file copy "[OCCDoc_GetDoxDir [OCCDoc_GetProdRootDir]]/resources/prod_pdf_template.tex" $DOCNAME
813   } else {
814     file copy "[OCCDoc_GetDoxDir]/resources/occt_pdf_template.tex" $DOCNAME
815   }
816
817   # Get templatized data
818   set texfile [open $DOCNAME "r"]
819   set texfile_loaded [read $texfile]
820   close $texfile
821
822   # Replace dummy values 
823   set year       [clock format [clock seconds] -format {%Y}]
824   set month      [clock format [clock seconds] -format {%B}]
825   set texfile    [open $DOCNAME "w"]
826   set casVersion [OCCDoc_DetectCasVersion]
827
828   # Get name of the document
829   set docLabel   ""
830   foreach aFileName $latexFilesList {
831     # Find the file in FILES_PDF.txt
832     set parsedFileName [file rootname [lindex [split $aFileName "/" ] end]]
833     if { [regexp "${parsedFileName}$" $fileName] } {
834       set filepath "[OCCDoc_GetDoxDir [OCCDoc_GetProdRootDir]]/$aFileName"
835       if { [file exists $filepath] } {
836         set MDFile   [open $filepath "r"]
837         set label    [split [gets $MDFile] "\{"]
838         set docLabel [lindex $label 0]
839         close $MDFile
840         break
841       }
842     }
843   }
844
845   set occtlogo_path "[OCCDoc_GetDoxDir]/resources/occt_logo.png"
846   set occlogo_path  "[OCCDoc_GetDoxDir]/resources/occ_logo.png"
847   set copyright_path  "[OCCDoc_GetDoxDir [OCCDoc_GetProdRootDir]]/resources/prod_pdf_template.tex"
848   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]
849
850   # Get data
851   puts $texfile $texfile_loaded
852
853   close $texfile
854 }
855
856 # Postprocesses generated TeX files
857 proc OCCDoc_ProcessTex {{texFiles {}} {latexDir} verboseMode} {
858
859   foreach TEX $texFiles {
860     if {$verboseMode == "YES"} {
861       puts "Info: Preprocessing file $TEX..."
862     }
863
864     if {![file exists $TEX]} {
865       puts "Error: file $TEX does not exist."
866       return -1
867     }
868
869     set IN_F        [open "$TEX" "r"]
870     set TMPFILENAME "$latexDir/temp.tex"
871     set OUT_F       [open $TMPFILENAME w]
872
873         while {1} {
874             set line [gets $IN_F]
875             if { [string first "\\includegraphics" $line] != -1 } {
876               # replace svg extension by pdf
877               set line [regsub {[.]svg} $line ".pdf"]
878               # Center images in TeX files
879               set line "\\begin{center}\n $line\n\\end{center}"
880             } elseif { [string first "\\subsection" $line] != -1 } {
881                 # Replace \subsection with \section tag
882                 regsub -all "\\\\subsection" $line "\\\\section" line
883             } elseif { [string first "\\subsubsection" $line] != -1 } {
884                 # Replace \subsubsection with \subsection tag
885                 regsub -all "\\\\subsubsection" $line "\\\\subsection" line
886             } elseif { [string first "\\paragraph" $line] != -1 } {
887                 # Replace \paragraph with \subsubsection tag
888                 regsub -all "\\\\paragraph" $line "\\\\subsubsection" line
889             }
890             puts $OUT_F $line
891
892       if {[eof $IN_F]} {
893         close $IN_F
894         close $OUT_F
895         break
896       }
897     }
898
899     file delete -force $TEX
900     file rename $TMPFILENAME $TEX
901   }
902 }