0025114: CMake-based build tools for OCCT 7.0
[occt.git] / adm / cmake / occt_gendoc.cmake
1 # ==========================================================================#
2 # Brief:  This script compiles OCCT documents from *.md files to HTML pages #
3 # ==========================================================================#
4
5 # ======================================
6 #  Common functions
7 # ======================================
8
9 # Print single line or print the line to the file
10 function(puts theLine)
11   if(${ARGC} EQUAL 1)
12     message(STATUS "${theLine}")
13   elseif(${ARGC} EQUAL 2)
14     file(APPEND ${ARGV0} "${ARGV1}\n")
15   endif()
16 endfunction()
17
18 # Print CMake Error, stop processing and generation
19 function(error theLine)
20   message(FATAL_ERROR "${theLine}")
21 endfunction()
22
23 # Prints help message
24 function (OCCDoc_PrintHelpMessage)
25   puts("Usage: gendoc [-h] {-refman|-overview} [-html|-pdf|-chm] [-m=<list of modules>|-ug=<list of docs>] [-v] [-s=<search_mode>] [-mathjax=<path>]")
26   puts("")
27   puts("Options are:")
28   puts("")
29   puts("choice of documentation to be generated:")
30   puts("  -overview          : To generate Overview and User Guides")
31   puts("                       (cannot be used with -refman)")
32   puts("  -refman            : To generate class Reference Manual")
33   puts("                       (cannot be used with -overview)")
34   puts("")
35   puts("choice of output format:")
36   puts("  -html              : To generate HTML files")
37   puts("                       (default, cannot be used with -pdf or -chm)")
38   puts("  -pdf               : To generate PDF files")
39   puts("                       (cannot be used with -refman, -html, or -chm)")
40   puts("  -chm               : To generate CHM files")
41   puts("                       (cannot be used with -html or -pdf)")
42   puts("")
43   puts("additional options:")
44   puts("  -m=<modules_list>  : List of OCCT modules (separated with comma),")
45   puts("                       for generation of Reference Manual")
46   puts("  -ug=<docs_list>    : List of MarkDown documents (separated with comma),")
47   puts("                       to use for generation of Overview / User Guides")
48   puts("  -mathjax=<path>    : To use local or alternative copy of MathJax")
49   puts("  -s=<search_mode>   : Specifies the Search mode of HTML documents")
50   puts("                       Can be: none | local | server | external")
51   puts("  -h                 : Prints this help message")
52   puts("  -v                 : Enables more verbose output")
53 endfunction()
54
55 # A command for User Documentation compilation
56 function (gendoc)
57   # Parameters
58   set (DOC_TYPE "REFMAN")
59   set (GEN_MODE "HTML_ONLY")
60   set (DOCFILES)
61   set (MODULES)
62   set (DOCLABEL "")
63   set (VERB_MODE "NO")
64   set (SEARCH_MODE "none")
65   set (MATHJAX_LOCATION "http://cdn.mathjax.org/mathjax/latest")
66   set (mathjax_js_name "MathJax.js")
67   set (DOCTYPE_COMBO_FLAG 0)
68   set (GENMODE_COMBO_FLAG 0)
69   set (GENERATE_PRODUCTS_REFMAN "NO")
70
71   #available_docfiles;   # The full list of md files for HTML or CHM generation
72   #available_pdf;        # The full list of md files for PDF generation
73   #args_names
74   #args_values
75
76   # Load list of docfiles
77   OCCDoc_LoadFilesList()
78
79   # Parse CL arguments
80   OCCDoc_ParseArguments(${ARGV})
81
82   # Print help message if no arguments provided
83   separate_arguments(args_names)
84   list(LENGTH args_names length)
85   if (${length} EQUAL 0)
86     OCCDoc_PrintHelpMessage()
87     return()
88   endif()
89
90   list(FIND args_names "pdf" FIND_pdf)
91   list(FIND args_names "chm" FIND_chm)
92   list(FIND args_names "ug"  FIND_ug)
93   list(FIND args_names "m"  FIND_m)
94   list(FIND args_names "refman" FIND_refman)
95   list(FIND args_names "overview" FIND_overview)
96   foreach (arg_n ${args_names})
97     if ("${arg_n}" STREQUAL "h")
98       OCCDoc_PrintHelpMessage()
99       return()
100     elseif ("${arg_n}" STREQUAL "html")
101       if(${FIND_refman} EQUAL -1 AND ${FIND_overview} EQUAL -1 )
102         error("Error: Please specify -refman or -overview argument.")
103       endif()
104       if(${FIND_refman} EQUAL -1)
105         if (NOT ${GENMODE_COMBO_FLAG} EQUAL 1)
106           set (GEN_MODE "HTML_ONLY")
107           set (GENMODE_COMBO_FLAG 1)
108         else()
109           error("Error: Options -html, -pdf and -chm can not be combined.")
110         endif()
111       endif()
112     elseif ("${arg_n}" STREQUAL "chm")
113       if(${FIND_refman} EQUAL -1 AND ${FIND_overview} EQUAL -1 )
114         error("Error: Please specify -refman or -overview argument.")
115       endif()
116       if(${FIND_refman} EQUAL -1)
117         if(NOT ${GENMODE_COMBO_FLAG} EQUAL 1)
118           set (GEN_MODE "CHM_ONLY")
119           set (GENMODE_COMBO_FLAG 1)
120         else()
121           error("Error: Options -html, -pdf and -chm cannot be combined.")
122         endif()
123       endif()
124     elseif ("${arg_n}" STREQUAL "pdf")
125       if(${FIND_refman} EQUAL -1 AND ${FIND_overview} EQUAL -1 )
126         error("Error: Please specify -refman or -overview argument.")
127       endif()
128       if(${FIND_refman} EQUAL -1)
129         if (NOT ${GENMODE_COMBO_FLAG} EQUAL 1)
130           set (GEN_MODE "PDF_ONLY")
131           set (GENMODE_COMBO_FLAG 1)
132         else()
133           error("Error: Options -html, -pdf and -chm cannot be combined.")
134         endif()
135       endif()
136     elseif ("${arg_n}" STREQUAL "overview")
137       if (NOT ${DOCTYPE_COMBO_FLAG} EQUAL 1)
138         set (DOC_TYPE "OVERVIEW")
139         set (DOCTYPE_COMBO_FLAG 1)
140       else()
141         error("Error: Options -refman and -overview cannot be combined.")
142       endif()
143       # Print ignored options
144       if ( NOT ${FIND_m} EQUAL -1 )
145         puts ("Info: The following options will be ignored:")
146         puts ("  * -m")
147       endif()
148       puts ("")
149     elseif ("${arg_n}" STREQUAL "refman")
150       if (NOT ${DOCTYPE_COMBO_FLAG} EQUAL 1)
151         set (DOC_TYPE "REFMAN")
152         set (DOCTYPE_COMBO_FLAG 1)
153         if ( EXISTS "${PRODUCTS_SOURCE_DIR}/src/VAS/Products.tcl")
154           set (GENERATE_PRODUCTS_REFMAN "YES")
155         endif()
156       else()
157         error("Error: Options -refman and -overview cannot be combined.")
158       endif()
159       # Print ignored options
160       if (NOT ${FIND_pdf} EQUAL -1 OR NOT ${FIND_chm} EQUAL -1 OR NOT ${FIND_ug} EQUAL -1)
161         puts ("Info: The following options will be ignored:")
162         if (NOT ${FIND_pdf} EQUAL -1)
163           puts ("  * -pdf")
164         endif()
165         if (NOT ${FIND_chm} EQUAL -1)
166           puts ("  * -chm")
167         endif()
168         if (NOT ${FIND_ug} EQUAL -1)
169           puts ("  * -ug")
170         endif()
171         puts("")
172       endif()
173       if ( "${GENERATE_PRODUCTS_REFMAN}" STREQUAL "YES")
174         if (${FIND_m} EQUAL -1)
175           error("Error: Cannot generate Reference Manual for the whole set of OCC Products.")
176         endif()
177       endif()
178     elseif ("${arg_n}" STREQUAL "v")
179       set (VERB_MODE "YES")
180     elseif ("${arg_n}" STREQUAL "ug")
181       if(${FIND_refman} EQUAL -1)
182         list(FIND args_names "ug" curIndex)
183         list(GET args_values ${curIndex} curValue)
184         if ( NOT "${curValue}" STREQUAL "NULL")
185           string(REPLACE "," " " curValue "${curValue}")
186           separate_arguments(curValue)
187           set (DOCFILES ${curValue})
188         else()
189           error("Error in argument ug.")
190         endif()
191         # Check if all chosen docfiles are correct
192         foreach (docfile ${DOCFILES})
193           if(${FIND_pdf} EQUAL -1)
194             # Check to generate HTMLs
195             list(FIND available_docfiles "${docfile}" FIND_doc)
196             if (${FIND_doc} EQUAL -1)
197               error("Error: File \"${docfile}\" is not presented in the list of available docfiles.")
198             endif()
199           else()
200             # Check to generate PDFs
201             list(FIND available_pdf "${docfile}" FIND_doc)
202             if ( ${FIND_doc} EQUAL -1)
203               error("Error: File \"${docfile}\" is not presented in the list of generic PDFs.")
204             endif()
205           endif()
206         endforeach()
207       endif()
208     elseif ("${arg_n}" STREQUAL "m")
209       if (${FIND_overview} EQUAL -1)
210         list(FIND args_names "m" curIndex)
211         list(GET args_values ${curIndex} curValue)
212         if ( NOT "${curValue}" STREQUAL "NULL")
213           string(REPLACE "," " " curValue "${curValue}")
214           separate_arguments(curValue)
215           set(MODULES ${curValue})
216         else()
217           error("Error in argument m.")
218         endif()
219       endif()
220     elseif ("${arg_n}" STREQUAL "s")
221       if (${FIND_pdf} EQUAL -1)
222         list(FIND args_names "s" curIndex)
223         list(GET args_values ${curIndex} curValue)
224         if ( NOT "${curValue}" STREQUAL "NULL")
225           string(REPLACE "," " " curValue "${curValue}")
226           separate_arguments(curValue)
227           set (SEARCH_MODE ${curValue})
228         else()
229           error("Error in argument s.")
230         endif()
231       endif()
232     elseif ("${arg_n}" STREQUAL "mathjax")
233       if (NOT ${FIND_pdf} EQUAL -1)
234         list(FIND args_names "mathjax" curIndex)
235         list(GET args_values ${curIndex} curValue)
236         string(REPLACE "," " " curValue "${curValue}")
237         separate_arguments(curValue)
238         set (possible_mathjax_loc ${curValue})
239         if (EXISTS "${possible_mathjax_loc}/${mathjax_js_name}")
240           set (MATHJAX_LOCATION ${curValue})
241           puts ("${MATHJAX_LOCATION}")
242         else()
243           puts ("Warning: ${mathjax_js_name} is not found in ${possible_mathjax_loc}.")
244           puts ("         MathJax will be used from ${MATHJAX_LOCATION}")
245         endif()
246       else()
247         puts("Warning: MathJax is not used with pdf and will be ignored.")
248       endif()
249     else()
250       OCCDoc_PrintHelpMessage()
251       error("Wrong argument: ${arg_n}")
252     endif()
253   endforeach()
254
255   # Check the existence of the necessary tools
256   find_program(DOC_DOXYGEN_PATH "doxygen")
257   if ("${DOC_DOXYGEN_PATH}" STREQUAL "DOC_DOXYGEN_PATH-NOTFOUND")
258     error(" Aborting... Could not find Doxygen, check DOC_DOXYGEN_PATH variable")
259   endif()
260
261   if("${DOC_TYPE}" STREQUAL "REFMAN")
262     find_program(DOC_GRAPHVIZ_PATH "dot")
263     if ("${DOC_GRAPHVIZ_PATH}" STREQUAL "DOC_GRAPHVIZ_PATH-NOTFOUND")
264       puts("Warning: Could not find Dot Part of Graphviz software. Doxygen will skip generation of class diagrams in Reference Manual, check DOC_GRAPHVIZ_PATH variable")
265     endif()
266   endif()
267
268   if (WIN32)
269     if ("${GEN_MODE}" STREQUAL "CHM_ONLY")
270       find_program(DOC_HHC_PATH "hhc")
271       if("${DOC_HHC_PATH}" STREQUAL "DOC_HHC_PATH-NOTFOUND")
272         error(" Aborting... Could not find HHC, check DOC_HHC_PATH variable")
273       endif()
274     endif()
275   endif()
276
277   if ("${GEN_MODE}" STREQUAL "PDF_ONLY")
278     find_program(DOC_INKSCAPE_PATH "inkscape")
279     if("${DOC_INKSCAPE_PATH}" STREQUAL "DOC_INKSCAPE_PATH-NOTFOUND")
280       puts ("Warning: Could not find Inkscape, check DOC_INKSCAPE_PATH variable.")
281       puts ("\tSVG images will be lost in PDF documents.")
282     endif()
283     find_program(DOC_PDFLATEX_PATH "pdflatex")
284     if("${DOC_PDFLATEX_PATH}" STREQUAL "DOC_PDFLATEX_PATH-NOTFOUND")
285       error(" Aborting... Could not find PDFLATEX, check DOC_PDFLATEX_PATH variable")
286     endif()
287   endif()
288
289   # If we do not specify list for docfiles with -m argument,
290   # we assume that we have to generate all docfiles
291   list(LENGTH DOCFILES DOCFILES_length)
292   if (${DOCFILES_length} EQUAL 0)
293     if (NOT "${GEN_MODE}" STREQUAL "PDF_ONLY")
294       set (DOCFILES ${available_docfiles})
295     else()
296       set (DOCFILES ${available_pdf})
297     endif()
298   endif()
299
300   OCCDoc_GetRootDir(ROOTDIR)
301
302   # Clean logfiles
303   set (OUTDIR  "${ROOTDIR}/doc")
304   set (DOXYLOG "${OUTDIR}/doxygen_warnings_and_errors.log")
305   set (PDFLOG  "${OUTDIR}/pdflatex_warnings_and_errors.log")
306
307   file(REMOVE "${PDFLOG}")
308   file(REMOVE "${DOXYLOG}")
309
310   # Start main activities
311   if (NOT "${GEN_MODE}" STREQUAL "PDF_ONLY")
312     OCCDoc_Main(${DOC_TYPE} DOCFILES MODULES ${GEN_MODE} ${VERB_MODE} ${SEARCH_MODE} ${MATHJAX_LOCATION} ${GENERATE_PRODUCTS_REFMAN} available_docfiles available_pdf)
313   else()
314     puts ("Generating OCCT User Guides in PDF format...")
315     foreach (pdf ${DOCFILES})
316       puts ("Info: Processing file ${pdf}")
317       # Some values are hardcoded because they are related only to PDF generation
318       separate_arguments(pdf)
319       OCCDoc_Main("OVERVIEW" pdf "" "PDF_ONLY" ${VERB_MODE} "none" ${MATHJAX_LOCATION} "NO" available_docfiles available_pdf)
320     endforeach()
321     string(TIMESTAMP time "%Y-%m-%d %H:%M")
322     puts ("${time} Generation completed.")
323     puts ("PDF files are generated in \n\t${OUTDIR}/pdf")
324   endif()
325 endfunction()
326
327 # Main procedure for documents compilation
328 function (OCCDoc_Main docType docfiles modules generatorMode verboseMode searchMode mathjaxLocation generateProductsRefman the_available_docfiles the_available_pdf)
329   set(docfiles ${${docfiles}})
330   set(modules ${${modules}})
331   set(available_docfiles ${${the_available_docfiles}})
332   set(available_pdf ${${the_available_pdf}})
333
334   if ("${generateProductsRefman}" STREQUAL "YES")
335     set (ROOTDIR "${PRODUCTS_SOURCE_DIR}")
336   else()
337     set (ROOTDIR "${OCCT_SOURCE_DIR}")
338   endif()
339
340   OCCDoc_GetDoxDir(INDIR)
341   set (OUTDIR     "${ROOTDIR}/doc")
342   set (PDFDIR     "${OUTDIR}/pdf")
343   set (UGDIR      "${PDFDIR}/user_guides")
344   set (DGDIR      "${PDFDIR}/dev_guides")
345   set (TAGFILEDIR "${OUTDIR}/refman")
346   set (HTMLDIR    "${OUTDIR}/overview/html")
347   set (LATEXDIR   "${OUTDIR}/overview/latex")
348   set (DOXYFILE   "${OUTDIR}/OCCT.cfg")
349
350   # Create or cleanup the output folders
351   if (NOT "${generateProductsRefman}" STREQUAL "YES")
352     foreach(dir ${OUTDIR} ${HTMLDIR} ${PDFDIR} ${UGDIR} ${DGDIR})
353       if (NOT EXISTS "${dir}")
354         file(MAKE_DIRECTORY "${dir}")
355       endif()
356     endforeach()
357     if (EXISTS "${LATEXDIR}")
358       file(REMOVE_RECURSE "${LATEXDIR}")
359     endif()
360     file(MAKE_DIRECTORY "${LATEXDIR}")
361   endif()
362   if ("${docType}" STREQUAL "REFMAN")
363     if (NOT EXISTS "${TAGFILEDIR}")
364       file(MAKE_DIRECTORY "${TAGFILEDIR}")
365     endif()
366   endif()
367
368   # is MathJax HLink?
369   set (mathjax_relative_location "${mathjaxLocation}")
370   if (IS_DIRECTORY "${mathjaxLocation}")
371     if ( "${generatorMode}" STREQUAL "HTML_ONLY")
372       # related path
373       file(RELATIVE_PATH mathjax_relative_location ${HTMLDIR} ${mathjaxLocation})
374     elseif ("${generatorMode}" STREQUAL "CHM_ONLY")
375       # absolute path
376       set (mathjax_relative_location ${mathjaxLocation})
377     endif()
378   endif()
379
380   if ( "${generateProductsRefman}" STREQUAL "YES")
381     set (DOCDIR "${OUTDIR}/refman")
382     puts ("Generating OCC Products Reference Manual")
383   else()
384     if ( "${docType}" STREQUAL "REFMAN")
385       set (DOCDIR "${OUTDIR}/refman")
386       puts ("Generating Open CASCADE Reference Manual")
387     elseif ("${docType}" STREQUAL "OVERVIEW")
388       set (DOCDIR "${OUTDIR}/overview")
389       set (FORMAT "")
390       if ( "${generatorMode}" STREQUAL "HTML_ONLY" OR "${generatorMode}" STREQUAL "CHM_ONLY")
391         if ( "${generatorMode}" STREQUAL "HTML_ONLY")
392           set (FORMAT " in HTML format...")
393         elseif ( "${generatorMode}" STREQUAL "CHM_ONLY")
394           set (FORMAT " in CHM format...")
395         endif()
396         puts ("Generating OCCT User Guides${FORMAT}")
397       endif()
398     else()
399       error("Error: Invalid documentation type: ${docType}. Can not process.")
400     endif()
401   endif()
402
403   # Generate Doxyfile
404   string(TIMESTAMP time "%Y-%m-%d %H:%M")
405   puts ("${time} Generating Doxyfile...")
406
407   OCCDoc_MakeDoxyfile(${docType} ${DOCDIR} ${TAGFILEDIR} ${DOXYFILE} ${generatorMode} docfiles modules ${verboseMode} ${searchMode} ${mathjax_relative_location})
408
409   # Run doxygen tool
410   string(TIMESTAMP starttimestamp "%Y-%m-%d %H:%M")
411   if ("${generatorMode}" STREQUAL "HTML_ONLY" OR "${docType}" STREQUAL "REFMAN")
412     puts("${starttimestamp} Generating HTML files...")
413     # Copy index file to provide fast access to HTML documentation
414     file(COPY "${INDIR}/resources/index.html" DESTINATION "${DOCDIR}")
415   elseif ("${generatorMode}" STREQUAL "CHM_ONLY")
416     puts ("${starttimestamp} Generating CHM file...")
417   elseif ("${generatorMode}" STREQUAL "PDF_ONLY")
418     puts ("${starttimestamp} Generating PDF file...")
419   endif()
420   execute_process(COMMAND ${DOC_DOXYGEN_PATH} ${DOXYFILE}
421                   OUTPUT_FILE ${OUTDIR}/doxygen_out.log
422                   ERROR_FILE ${OUTDIR}/doxygen_warnings_and_errors.log
423                  )
424   # Start Post Processing
425   string(TIMESTAMP curtime "%Y-%m-%d %H:%M")
426   if( "${docType}" STREQUAL "REFMAN")
427     # Post Process generated HTML pages and draw dependency graphs
428     OCCDoc_PostProcessor(${DOCDIR})
429     if (${isOK} EQUAL 0)
430       puts ("${curtime} Generation completed.")
431       puts ("Info: doxygen log file is located in:")
432       puts ("\t${OUTDIR}/doxygen_out.log.")
433       puts ("Reference Manual is generated in \n\t${DOCDIR}")
434     endif()
435   elseif ("${docType}" STREQUAL "OVERVIEW")
436     # Start PDF generation routine
437     if ("${generatorMode}" STREQUAL "PDF_ONLY")
438       # Prepare a list of TeX files, generated by Doxygen
439       file(GLOB TEXFILES RELATIVE "${LATEXDIR}" "${LATEXDIR}/*.tex")
440       list(REMOVE_ITEM TEXFILES "refman.tex")
441       if ("${verboseMode}" STREQUAL "YES")
442         puts ("Info: Preprocessing generated TeX files...")
443       endif()
444
445       OCCDoc_ProcessTex(TEXFILES ${LATEXDIR} ${verboseMode})
446
447       if ("${verboseMode}" STREQUAL "YES")
448         puts ("Info: Converting SVG images to PNG format...")
449       endif()
450
451       if (NOT "${DOC_INKSCAPE_PATH}" STREQUAL "DOC_INKSCAPE_PATH-NOTFOUND")
452         OCCDoc_ProcessSvg(${LATEXDIR} ${verboseMode})
453       endif()
454
455       if ("${verboseMode}" STREQUAL "YES")
456         puts ("Info: Generating PDF file from TeX files...")
457       endif()
458       foreach (TEX ${TEXFILES})
459         # Rewrite existing REFMAN.tex file...
460         get_filename_component(TEX ${TEX} NAME_WE)
461         if ("${verboseMode}" STREQUAL "YES")
462           puts ("Info: Generating PDF file from ${TEX}...")
463         endif()
464
465         OCCDoc_MakeRefmanTex(${TEX} ${LATEXDIR} ${verboseMode} available_pdf)
466
467         if ("${verboseMode}" STREQUAL "YES")
468           # ...and use it to generate PDF from TeX...
469           if (WIN32)
470             puts ("Info: Executing ${LATEXDIR}/make.bat...")
471           else()
472             puts ("Info: Executing ${LATEXDIR}/Makefile...")
473           endif()
474         endif()
475         set (PDFLOG "${OUTDIR}/pdflatex_warnings_and_errors.log")
476
477         if (WIN32)
478
479           execute_process(COMMAND ${LATEXDIR}/make.bat
480                   OUTPUT_FILE ${OUTDIR}/pdflatex_out.log
481                   WORKING_DIRECTORY ${LATEXDIR}
482                   ERROR_FILE ${OUTDIR}/pdflatex_warnings_and_errors.log
483                  )
484         else()
485           execute_process(COMMAND make -f ${LATEXDIR}/Makefile
486                   OUTPUT_FILE ${OUTDIR}/pdflatex_out.log
487                   WORKING_DIRECTORY ${LATEXDIR}
488                   ERROR_FILE ${OUTDIR}/pdflatex_warnings_and_errors.log
489                  )
490           # Small workaround for *nix stations
491           execute_process(COMMAND ${DOC_PDFLATEX_PATH} ${LATEXDIR}/refman.tex
492                   WORKING_DIRECTORY ${LATEXDIR}
493                   OUTPUT_FILE ${OUTDIR}/pdflatex_out.log
494                   ERROR_FILE ${OUTDIR}/pdflatex_warnings_and_errors.log
495                  )
496         endif()
497
498         if (NOT EXISTS "${LATEXDIR}/refman.pdf")
499           error("Fatal: PDFLaTeX failed to create output file, stopping!\n\tCheck \"${OUTDIR}/pdflatex_warnings_and_errors.log\" log file")
500         endif()
501
502         set (destFolder "${PDFDIR}")
503         string(REGEX MATCHALL "([a-zA-Z]+)" parsed_string ${TEX})
504         list(FIND parsed_string "tutorial" isTUTORIAL)
505         list(FIND parsed_string "user" isUSER)
506         list(FIND parsed_string "dev" isDEV)
507
508         if (NOT ${isTUTORIAL} EQUAL -1)
509           string(REPLACE "occt__" "occt_" TEX ${TEX})
510           set (destFolder ${PDFDIR})
511         elseif (NOT ${isUSER} EQUAL -1)
512           string(REPLACE "user_guides__" "" TEX ${TEX})
513           set (destFolder ${UGDIR})
514         elseif (NOT ${isDEV} EQUAL -1)
515           string(REPLACE "dev_guides__" "" TEX ${TEX})
516           set (destFolder ${DGDIR})
517         endif()
518         file (RENAME "${LATEXDIR}/refman.pdf" "${destFolder}/${TEX}.pdf")
519       endforeach()
520     elseif ( "${generatorMode}" STREQUAL "CHM_ONLY" )
521       file (RENAME "${OUTDIR}/overview.chm" "${OUTDIR}/occt_overview.chm")
522     endif()
523     if ( "${generatorMode}" STREQUAL "HTML_ONLY" )
524       puts ("HTML documentation is generated in \n\t${DOCDIR}")
525     endif()
526     if ( "${generatorMode}" STREQUAL "CHM_ONLY" )
527       puts ("Generated CHM documentation is in \n\t${OUTDIR}/overview.chm")
528     endif()
529
530     puts ("")
531   endif()
532
533   file(GLOB_RECURSE deleteList "${OUTDIR}/*.tmp")
534   foreach(file ${deleteList})
535     file (REMOVE ${file})
536   endforeach()
537 endfunction()
538
539 # Generates Doxygen configuration file for Overview documentation
540 function (OCCDoc_MakeDoxyfile docType outDir tagFileDir doxyFileName generatorMode DocFilesList ModulesList verboseMode searchMode mathjaxLocation)
541   set(DocFilesList ${${DocFilesList}})
542   set(ModulesList ${${ModulesList}})
543   OCCDoc_GetDoxDir(inputDir)
544   set (TEMPLATES_DIR ${inputDir}/resources)
545   OCCDoc_DetectCasVersion(occt_version)
546   # Delete existent doxyfile
547   file (REMOVE "${doxyFileName}")
548
549   # Copy specific template to the target folder
550   if ( "${docType}" STREQUAL "REFMAN")
551     configure_file("${TEMPLATES_DIR}/occt_rm.doxyfile" "${doxyFileName}" COPYONLY)
552   elseif ("${docType}" STREQUAL "OVERVIEW")
553     if ("${generatorMode}" STREQUAL "HTML_ONLY" OR "${generatorMode}" STREQUAL "CHM_ONLY")
554       configure_file("${TEMPLATES_DIR}/occt_ug_html.doxyfile" "${doxyFileName}" COPYONLY)
555     elseif ("${generatorMode}" STREQUAL "PDF_ONLY")
556       configure_file("${TEMPLATES_DIR}/occt_ug_pdf.doxyfile" "${doxyFileName}" COPYONLY)
557     else()
558       error("Error: Unknown generation mode")
559     endif()
560   else()
561     error("Error: Cannot generate unknown document type")
562   endif()
563
564   # Write specific options
565   if ("${docType}" STREQUAL "REFMAN")
566     GET_OCCT_MODULES(modules)
567     if (NOT "${ModulesList}" STREQUAL "")
568       # Detect invalid names of modules
569       foreach (module ${ModulesList})
570         list(FIND modules "${module}" isFound)
571         if (${isFound} EQUAL -1)
572           error("Error: No module ${module} is known. Aborting...")
573         endif()
574       endforeach()
575       set (modules "${ModulesList}")
576     endif()
577
578     # Set context
579     list(LENGTH modules length)
580     if (${length} EQUAL 1)
581       set (title "OCCT ${modules}")
582       set (name "${modules}")
583     else()
584       set (title "Open CASCADE Technology")
585       set (name "OCCT")
586     endif()
587
588     # Get list of header files in the specified modules
589     set (filelist)
590     foreach (module ${modules})
591       foreach (tk ${${module}_TOOLKITS})
592         OCCDoc_GetPackagesList(${tk} ${tk}_PACKAGES)
593         foreach (pk ${${tk}_PACKAGES})
594           OCCDoc_GetRootDir(theRoot)
595           file(GLOB INC_FILES "${theRoot}/src/${pk}/*.[hg]*")
596           set(TEMP_INC_FILES)
597           foreach (INC_FILE ${INC_FILES})
598             string(FIND "${INC_FILE}" "/Handle_" isFound)
599             if(${isFound} EQUAL -1)
600               list(APPEND TEMP_INC_FILES "${INC_FILE}")
601             endif()
602           endforeach()
603           list(APPEND filelist "${TEMP_INC_FILES}")
604         endforeach()
605       endforeach()
606     endforeach()
607
608     puts (${doxyFileName} "PROJECT_NAME           = \"${title}\"")
609     puts (${doxyFileName} "PROJECT_NUMBER         = ${occt_version}")
610     puts (${doxyFileName} "OUTPUT_DIRECTORY       = ${outDir}/.")
611     puts (${doxyFileName} "GENERATE_TAGFILE       = ${outDir}/${name}.tag")
612
613     if ("${searchMode}" STREQUAL "none")
614       puts (${doxyFileName} "SEARCHENGINE           = NO")
615       puts (${doxyFileName} "SERVER_BASED_SEARCH    = NO")
616       puts (${doxyFileName} "EXTERNAL_SEARCH        = NO")
617     else()
618       puts (${doxyFileName} "SEARCHENGINE           = YES")
619       if ("${searchMode}" STREQUAL "local")
620         puts (${doxyFileName} "SERVER_BASED_SEARCH    = NO")
621         puts (${doxyFileName} "EXTERNAL_SEARCH        = NO")
622       elseif ("${searchMode}" STREQUAL "server")
623         puts (${doxyFileName} "SERVER_BASED_SEARCH    = YES")
624         puts (${doxyFileName} "EXTERNAL_SEARCH        = NO")
625       elseif ("${searchMode}" STREQUAL "external")
626         puts (${doxyFileName} "SERVER_BASED_SEARCH    = YES")
627         puts (${doxyFileName} "EXTERNAL_SEARCH        = YES")
628       else()
629         error("Error: Wrong search engine type: ${searchMode}.")
630       endif()
631     endif()
632     if(EXISTS "${DOC_GRAPHVIZ_PATH}")
633       set(DOT_PATH "${DOC_GRAPHVIZ_PATH}")
634     endif()
635     puts (${doxyFileName} "DOTFILE_DIRS             = ${outDir}/html")
636     puts (${doxyFileName} "DOT_PATH                 = ${DOT_PATH}")
637     puts (${doxyFileName} "INCLUDE_PATH             = ${INSTALL_DIR}/inc")
638     # list of files to generate
639     OCCDoc_MakeMainPage(${outDir} "${outDir}/${name}.dox" modules)
640     set (mainpage "${outDir}/${name}.dox")
641     puts (${doxyFileName} "")
642     puts (${doxyFileName} "INPUT    = ${mainpage} \\")
643     foreach (header ${filelist})
644       puts (${doxyFileName} "               ${header} \\")
645     endforeach()
646
647     puts (${doxyFileName} "MATHJAX_FORMAT         = HTML-CSS")
648     puts (${doxyFileName} "MATHJAX_RELPATH        = ${mathjaxLocation}")
649
650     puts (${doxyFileName} "")
651
652   elseif ( "${docType}" STREQUAL "OVERVIEW")
653     # Add common options for generation of Overview and User Guides
654     puts (${doxyFileName} "PROJECT_NUMBER         = ${occt_version}")
655     puts (${doxyFileName} "OUTPUT_DIRECTORY       = ${outDir}/.")
656     puts (${doxyFileName} "PROJECT_LOGO           = ${inputDir}/resources/occ_logo.png")
657
658     set (PARAM_INPUT "INPUT                 =")
659     set (PARAM_IMAGEPATH "IMAGE_PATH        = ${inputDir}/resources/ ")
660     foreach (docFile ${DocFilesList})
661       set (NEW_IMG_PATH "${inputDir}/${docFile}")
662       OCCDoc_GetRootDir(theRoot)
663       if (NOT "${NEW_IMG_PATH}" STREQUAL "${theRoot}")
664         get_filename_component(img_string ${NEW_IMG_PATH} DIRECTORY)
665         set (img_string "${img_string}/images")
666         if (EXISTS ${img_string})
667           set(PARAM_IMAGEPATH "${PARAM_IMAGEPATH} ${img_string}")
668         endif()
669       endif()
670       set(PARAM_INPUT "${PARAM_INPUT} ${inputDir}/${docFile}")
671     endforeach()
672     puts (${doxyFileName} ${PARAM_INPUT})
673     puts (${doxyFileName} ${PARAM_IMAGEPATH})
674
675     # Add document type-specific options
676     if ( "${generatorMode}" STREQUAL "HTML_ONLY")
677       # generate tree view
678       puts (${doxyFileName} "GENERATE_TREEVIEW      = YES")
679
680       # Set a reference to a TAGFILE
681       if (NOT "${tagFileDir}" STREQUAL "")
682         if (EXISTS "${tagFileDir}/OCCT.tag")
683           set (tagPath ${tagFileDir})
684           puts (${doxyFileName} "TAGFILES               = ${tagFileDir}/OCCT.tag=../../refman/html")
685         endif()
686       endif()
687       # HTML Search engine options
688       string(TOLOWER "${searchMode}" searchMode)
689       if ("${searchMode}" STREQUAL "none")
690         puts (${doxyFileName} "SEARCHENGINE           = NO")
691         puts (${doxyFileName} "SERVER_BASED_SEARCH    = NO")
692         puts (${doxyFileName} "EXTERNAL_SEARCH        = NO")
693       else()
694         puts (${doxyFileName} "SEARCHENGINE           = YES")
695         if ("${searchMode}" STREQUAL "local")
696           puts (${doxyFileName} "SERVER_BASED_SEARCH    = NO")
697           puts (${doxyFileName} "EXTERNAL_SEARCH        = NO")
698         elseif ("${searchMode}" STREQUAL "server")
699           puts (${doxyFileName} "SERVER_BASED_SEARCH    = YES")
700           puts (${doxyFileName} "EXTERNAL_SEARCH        = NO")
701         elseif ("${searchMode}" STREQUAL "external")
702           puts (${doxyFileName} "SERVER_BASED_SEARCH    = YES")
703           puts (${doxyFileName} "EXTERNAL_SEARCH        = YES")
704         else()
705           error("Error: Wrong search engine type: ${searchMode}.")
706         endif()
707       endif()
708     elseif ( "${generatorMode}" STREQUAL "CHM_ONLY")
709       # specific options for CHM file generation
710       if(EXISTS "${DOC_HHC_PATH}")
711         set(HHC_LOCATION "${DOC_HHC_PATH}")
712       endif()
713       puts (${doxyFileName} "GENERATE_TREEVIEW      = NO")
714       puts (${doxyFileName} "SEARCHENGINE           = NO")
715       puts (${doxyFileName} "GENERATE_HTMLHELP      = YES")
716       puts (${doxyFileName} "CHM_FILE               = ../../overview.chm")
717       puts (${doxyFileName} "HHC_LOCATION           = \"${HHC_LOCATION}\"")
718       puts (${doxyFileName} "DISABLE_INDEX          = YES")
719     endif()
720
721     # Formula options
722     puts (${doxyFileName} "MATHJAX_RELPATH        = ${mathjaxLocation}")
723   endif()
724 endfunction()
725
726 # Parses arguments line like "-arg1=val1 -arg2=val2 ..." to array args_names and map args_values
727 function (OCCDoc_ParseArguments)
728   #args_names
729   #args_values
730   set (args_names)
731   set (args_values)
732
733   separate_arguments(ARGV)
734
735   string(REGEX MATCHALL "^[a-zA-Z]+$" single_var "${ARGV}")
736   string(REGEX MATCHALL "^[a-zA-Z]+[=].*$" multi_var "${ARGV}")
737
738   separate_arguments(ARGV)
739   foreach (arg ${ARGV})
740     STRING(FIND "${arg}" "=" equalChar)
741     STRING(FIND "${arg}" "-" firstChar)
742     if(NOT "${firstChar}" EQUAL 0)
743       error("Error in argument \"${arg}\".")
744     endif()
745     if(NOT "${equalChar}" EQUAL -1)
746       math(EXPR valueChar "${equalChar} + 1")
747       math(EXPR nameChar "${equalChar} - 1")
748       string(SUBSTRING "${arg}" "${valueChar}" -1 aValue)
749       string(SUBSTRING "${arg}" 1 "${nameChar}" aName)
750     else()
751       string(SUBSTRING "${arg}" 1 -1 aName)
752       set(aValue "NULL")
753     endif()
754     list(APPEND args_names "${aName}")
755     list(APPEND args_values "${aValue}")
756   endforeach()
757   set (args_names ${args_names} PARENT_SCOPE)
758   set (args_values ${args_values} PARENT_SCOPE)
759   set (isOK 0 PARENT_SCOPE)
760 endfunction()
761
762 # Returns script parent folder
763 function (OCCDoc_GetDoxDir result)
764   if (BUILD_PATCH_DIR AND EXISTS "${BUILD_PATCH_DIR}/dox")
765     set (filePATH ${BUILD_PATCH_DIR})
766   elseif (EXISTS "${CMAKE_SOURCE_DIR}/dox")
767     set (filePATH ${CMAKE_SOURCE_DIR})
768   endif()
769   set(${result} "${filePATH}/dox" PARENT_SCOPE)
770 endfunction()
771
772 # Returns OCCT root dir
773 function (OCCDoc_GetOCCTRootDir result)
774   OCCDoc_GetDoxDir(path)
775   get_filename_component(path "${path}" DIRECTORY)
776   set(${result} "${path}" PARENT_SCOPE)
777 endfunction()
778
779 # Returns root dir
780 function (OCCDoc_GetRootDir result)
781   OCCDoc_GetOCCTRootDir(path)
782   set(${result} "${path}" PARENT_SCOPE)
783 endfunction()
784
785 # Returns OCCT source dir
786 function (OCCDoc_GetSourceDir result)
787   OCCDoc_GetRootDir(theRoot)
788   set(${result} "${theRoot}/src" PARENT_SCOPE)
789 endfunction()
790
791 # Returns OCCT version string from file Standard_Version.hxx (if available)
792 function (OCCDoc_DetectCasVersion theVersion)
793   set (occt_ver 6.7.0)
794   set (occt_ver_add "")
795   OCCDoc_GetSourceDir(filename)
796   set(filename "${filename}/Standard/Standard_Version.hxx")
797   if(EXISTS "${filename}")
798     foreach (var OCC_VERSION_COMPLETE OCC_VERSION_DEVELOPMENT)
799       file (STRINGS "${filename}" ${var} REGEX "^#define ${var} .*")
800       STRING(REGEX REPLACE ".*${var} .*\"([^ ]+)\".*" "\\1" ${var} "${${var}}" )
801     endforeach()
802     if(NOT "${OCC_VERSION_DEVELOPMENT}" STREQUAL "")
803       set(${theVersion} "${OCC_VERSION_COMPLETE}.${OCC_VERSION_DEVELOPMENT}" PARENT_SCOPE)
804     else()
805       set(${theVersion} "${OCC_VERSION_COMPLETE}" PARENT_SCOPE)
806     endif()
807   endif()
808 endfunction()
809
810 # Convert SVG files to PDF format to allow including them to PDF
811 # (requires InkScape to be in PATH)
812 function (OCCDoc_ProcessSvg latexDir verboseMode)
813   file(GLOB aFILES "${latexDir}/*.svg")
814   foreach (file ${aFILES})
815     if ("${verboseMode}" STREQUAL "YES")
816       puts ("Info: Converting file ${file}...")
817     endif()
818     get_filename_component(aDir ${file} DIRECTORY )
819     get_filename_component(aName ${file} NAME_WE )
820     set (pdffile "${aDir}/${aName}.pdf")
821     execute_process(COMMAND ${DOC_INKSCAPE_PATH} -z -D --file=${file} --export-pdf=${pdffile}
822         WORKING_DIRECTORY ${LATEXDIR}
823         OUTPUT_FILE ${OUTDIR}/inkscape_out.log
824         ERROR_FILE ${OUTDIR}/inkscape_warnings_and_errors.log
825     )
826   endforeach()
827 endfunction()
828
829 # ==============================================
830 # Reference Manual-specific functions
831 # ==============================================
832
833 # Finds dependencies between all modules
834 function (OCCDoc_CreateModulesDependencyGraph dir filename modules mpageprefix)
835   set(modules ${${modules}})
836   #module_dependency
837   set (file "${dir}/${filename}.dot")
838   file(REMOVE ${file})
839   puts (${file} "digraph ${filename}")
840   puts (${file} "{")
841   foreach (mod ${modules})
842     if ( NOT "${mod}" STREQUAL "")
843       string(TOLOWER "${mpageprefix}${mod}.html" aLowerString)
844       puts (${file} "\t${mod} [ URL = \"${aLowerString}\" ]")
845       foreach (mod_depend ${${mod}_DEPS})
846         puts (${file} "\t${mod_depend} -> ${mod} [ dir = \"back\", color = \"midnightblue\", style = \"solid\" ]")
847       endforeach()
848     endif()
849   endforeach()
850   puts (${file} "}")
851 endfunction()
852
853 # Finds dependencies between all toolkits in module
854 function(OCCDoc_CreateModuleToolkitsDependencyGraph dir filename modulename tpageprefix)
855   #toolkits_in_module
856   #toolkit_dependency
857   #toolkit_parent_module
858   set (file "${dir}/${filename}.dot")
859   file(REMOVE ${file})
860   puts (${file} "digraph ${filename}")
861   puts (${file} "{")
862   foreach (tk ${${modulename}_TOOLKITS})
863     string(TOLOWER "${tpageprefix}${tk}.html" LowerString)
864     OCC_GetUnitType("${tk}" theType)
865     if("${theType}" STREQUAL "t")
866       puts (${file} "\t${tk} [ URL = \"${LowerString}\"]")
867       foreach (tkd ${${tk}_DEPS})
868         IS_OCCT_TOOLKIT(${tkd})
869         OCC_GetUnitType("${tkd}" theType)
870         if("${theType}" STREQUAL "t")
871           if(NOT ${isFOUND} EQUAL -1)
872             if("${isFOUND}" STREQUAL "${modulename}")
873               puts (${file} "\t${tkd} -> ${tk} [ dir = \"back\", color = \"midnightblue\", style = \"solid\" ]")
874             endif()
875           endif()
876         endif()
877       endforeach()
878     endif()
879   endforeach()
880   puts (${file} "}")
881 endfunction()
882
883 # Finds dependencies between the current toolkit and other toolkits
884 function(OCCDoc_CreateToolkitDependencyGraph dir filename toolkitname tpageprefix)
885   #toolkit_dependency
886   set (file "${dir}/${filename}.dot")
887   file(REMOVE ${file})
888   puts(${file} "digraph ${filename}")
889   puts(${file} "{")
890   string(TOLOWER "${tpageprefix}${toolkitname}.html" LowerString)
891   puts(${file} "\t${toolkitname} [ URL = \"${LowerString}\", shape = box ]")
892   foreach (tkd ${${toolkitname}_DEPS})
893     string(TOLOWER "${tpageprefix}${tkd}.html" LowerString)
894     puts(${file} "\t${tkd} [ URL = \"${LowerString}\"\ , shape = box ]")
895     puts(${file} "\t${toolkitname} -> ${tkd} [ color = \"midnightblue\", style = \"solid\" ]")
896   endforeach()
897   list(LENGTH ${toolkitname}_DEPS length)
898   if (${length} GREATER 1)
899     puts(${file} "\taspect = 1")
900   endif()
901   puts(${file} "}")
902 endfunction()
903
904 # Fills arrays of modules, toolkits, dependency of modules/toolkits etc
905 function (OCCDoc_LoadData)
906   #toolkits_in_module
907   #toolkit_dependency
908   #toolkit_parent_module
909   #module_dependency
910   GET_OCCT_MODULES(modules)
911   set(MODULES ${modules} PARENT_SCOPE)
912   foreach (mod ${modules})
913     set(${mod}_TOOLKITS "${${mod}_TOOLKITS}" PARENT_SCOPE)
914     foreach (tk ${${mod}_TOOLKITS})
915       OCCT_TOOLKIT_DEP(${tk})
916       foreach (dtk ${${tk}_DEPS})
917         IS_OCCT_TOOLKIT(${dtk})
918         if(${isFOUND} EQUAL -1)
919           list(REMOVE_ITEM ${tk}_DEPS ${dtk})
920         endif()
921       endforeach()
922       set(${tk}_DEPS ${${tk}_DEPS} PARENT_SCOPE)
923     endforeach()
924   endforeach()
925
926   # Get modules dependency
927   foreach (mod ${modules})
928     set(${mod}_DEPS)
929     foreach (tk ${${mod}_TOOLKITS})
930       foreach(dtk ${${tk}_DEPS})
931         IS_OCCT_TOOLKIT(${dtk})
932         if(NOT ${isFOUND} EQUAL -1)
933           if(NOT "${mod}" STREQUAL "${isFOUND}")
934             list(APPEND ${mod}_DEPS "${isFOUND}")
935           endif()
936         endif()
937       endforeach()
938     endforeach()
939     list(LENGTH ${mod}_DEPS length)
940     if(NOT ${length} EQUAL 0)
941       list(REMOVE_DUPLICATES ${mod}_DEPS)
942     endif()
943     set(${mod}_DEPS ${${mod}_DEPS} PARENT_SCOPE)
944   endforeach()
945 endfunction()
946
947 # Returns list of packages of the given toolkit
948 function (OCCDoc_GetExternLibList theToolkit theExternLibs)
949   OCCDoc_GetRootDir(theRoot)
950   # Open file with list of packages of the given toolkit
951   file(READ "${theRoot}/src/${theToolkit}/EXTERNLIB" CONTENT)
952   set(${theExternLibs} ${CONTENT} PARENT_SCOPE)
953 endfunction()
954
955 # Returns list of packages of the given toolkit
956 function (OCC_GetUnitType theName theResult)
957   OCCDoc_GetRootDir(theRoot)
958   # Open file with list of packages of the given toolkit
959   set(aType "")
960   if(EXISTS "${theRoot}/adm/UDLIST")
961     file(STRINGS "${theRoot}/adm/UDLIST" CONTENT REGEX ". ${theName}")
962   endif()
963   string(SUBSTRING "${CONTENT}" 0 1 aType)
964   set(${theResult} "${aType}" PARENT_SCOPE)
965 endfunction()
966
967 # Returns list of packages of the given toolkit
968 function (OCCDoc_GetPackagesList theToolkit thePackages)
969   OCCDoc_GetRootDir(theRoot)
970   # Open file with list of packages of the given toolkit
971   set(CONTENT "")
972   if(EXISTS "${theRoot}/src/${theToolkit}/PACKAGES")
973     file(STRINGS "${theRoot}/src/${theToolkit}/PACKAGES" CONTENT)
974   endif()
975   set(${thePackages} "${CONTENT}" PARENT_SCOPE)
976 endfunction()
977
978 # Function to get toolkits dependencies from file src/TOOLKIT_NAME/EXTERNLIB.
979 # Creates <TOOLKIT_NAME>_DEPS variable to store them.
980 function (OCCT_TOOLKIT_DEP TOOLKIT_NAME)
981   if (BUILD_PATCH_DIR AND EXISTS "${BUILD_PATCH_DIR}/src/${TOOLKIT_NAME}/EXTERNLIB")
982     set (MODULE_PATH_PREFIX ${BUILD_PATCH_DIR})
983   elseif (EXISTS "${CMAKE_SOURCE_DIR}/src/${TOOLKIT_NAME}/EXTERNLIB")
984     set (MODULE_PATH_PREFIX ${CMAKE_SOURCE_DIR})
985   else()
986     RETURN()
987   endif()
988   file (STRINGS "${MODULE_PATH_PREFIX}/src/${TOOLKIT_NAME}/EXTERNLIB" CONTENT)
989   set (${TOOLKIT_NAME}_DEPS ${CONTENT} PARENT_SCOPE)
990 endfunction()
991
992 # Function to determine if TOOLKIT is OCC toolkit
993 # Creates "isFOUND" variable to store result
994 function (IS_OCCT_TOOLKIT TOOLKIT_NAME)
995   set (isFOUND -1 PARENT_SCOPE)
996   GET_OCCT_MODULES(MODULES)
997   foreach(MODULE ${MODULES})
998     set(TOOLKITS ${${MODULE}_TOOLKITS})
999     list(FIND TOOLKITS ${TOOLKIT_NAME} isOK)
1000     if (NOT ${isOK} EQUAL -1)
1001       set (isFOUND "${MODULE}" PARENT_SCOPE)
1002       return()
1003     endif()
1004   endforeach(MODULE)
1005 endfunction()
1006
1007 # Function to get list of modules and toolkits from file adm/MODULES.
1008 # Creates list <${MODULES_LIST}> to store list of MODULES and
1009 # <NAME_OF_MODULE>_TOOLKITS foreach module to store its toolkits.
1010 function (GET_OCCT_MODULES MODULES_LIST)
1011   set (MODULE_PATH_POSTFIX "/adm/MODULES")
1012   if (BUILD_PATCH_DIR AND EXISTS "${BUILD_PATCH_DIR}${MODULE_PATH_POSTFIX}")
1013     set (MODULE_PATH_PREFIX "${BUILD_PATCH_DIR}")
1014   elseif (EXISTS "${CMAKE_SOURCE_DIR}${MODULE_PATH_POSTFIX}")
1015     set (MODULE_PATH_PREFIX "${CMAKE_SOURCE_DIR}")
1016   else()
1017     RETURN()
1018   endif()
1019
1020   file (STRINGS "${MODULE_PATH_PREFIX}${MODULE_PATH_POSTFIX}" CONTENT)
1021
1022   set (${MODULES_LIST})
1023   foreach (CONTENT_LINE ${CONTENT})
1024     string (REPLACE " " ";" CONTENT_LINE ${CONTENT_LINE})
1025     list (GET CONTENT_LINE 0 NAME_OF_MODULE)
1026     list (REMOVE_AT CONTENT_LINE 0)
1027     list (APPEND ${MODULES_LIST} ${NAME_OF_MODULE})
1028     set (${NAME_OF_MODULE}_TOOLKITS "${CONTENT_LINE}" PARENT_SCOPE)
1029   endforeach()
1030
1031   set (${MODULES_LIST} ${${MODULES_LIST}} PARENT_SCOPE)
1032 endfunction()
1033
1034 # Gets contents of the given html node (for Post-processing)
1035 function(OCCDoc_GetNodeContents node props html theResult)
1036   set (openTag "<${node}${props}>")
1037   set (closingTag "</${node}>")
1038   string(FIND "${html}" "${openTag}" start)
1039   if (${start} EQUAL -1)
1040     set(theResult "" PARENT_SCOPE)
1041     return()
1042   endif()
1043   string(LENGTH "${openTag}" length)
1044   math(EXPR start "${start} + ${length}")
1045   string(SUBSTRING "${html}" ${start} -1 html)
1046   string(FIND "${html}" "${closingTag}" start)
1047   if (${start} EQUAL -1)
1048     set(theResult "" PARENT_SCOPE)
1049     return()
1050   endif()
1051   math(EXPR start "${start} - 1")
1052   string(SUBSTRING "${html}" 0 ${start} theResult)
1053   set(theResult "" PARENT_SCOPE)
1054 endfunction()
1055
1056 # Generates main page file describing module structure
1057 function (OCCDoc_MakeMainPage outDir outFile inModules)
1058   set(inModules "${${inModules}}")
1059   #env
1060   set (module_prefix "module_")
1061   set (toolkit_prefix "toolkit_")
1062   set (package_prefix "package_")
1063
1064   if (NOT EXISTS "${outDir}/html")
1065     file(MAKE_DIRECTORY "${outDir}/html")
1066   endif()
1067
1068   OCCDoc_LoadData()
1069   # Main page: list of modules
1070   separate_arguments(inModules)
1071   list(LENGTH inModules length)
1072   if (NOT ${length} EQUAL 1)
1073     puts (${outFile} "/**")
1074     puts (${outFile} "\\mainpage Open CASCADE Technology")
1075     foreach (mod ${inModules})
1076       string(TOLOWER "${module_prefix}${mod}" LowerString)
1077       puts (${outFile} "\\li \\subpage ${LowerString}")
1078     endforeach()
1079     OCCDoc_CreateModulesDependencyGraph("${outDir}/html" "schema_all_modules" inModules ${module_prefix})
1080     # insert modules relationship diagramm
1081     puts (${outFile} "\\dotfile schema_all_modules")
1082     puts (${outFile} "**/")
1083   endif()
1084
1085   # One page per module: list of toolkits
1086   set (toolkits)
1087   foreach (mod ${inModules})
1088     puts (${outFile} "/**")
1089     if (${length} EQUAL 1)
1090         puts (${outFile} "\\mainpage OCCT Module ${mod}")
1091     else()
1092         string(TOLOWER "module_${mod}" LowerString)
1093         puts (${outFile} "\\page ${LowerString} Module ${mod}")
1094     endif()
1095     list(SORT ${mod}_TOOLKITS)
1096     foreach (tk ${${mod}_TOOLKITS})
1097       OCC_GetUnitType("${tk}" theType)
1098       if("${theType}" STREQUAL "t")
1099         list(APPEND toolkits ${tk})
1100         string(TOLOWER "${toolkit_prefix}${tk}" LowerString)
1101         puts (${outFile} "\\li \\subpage ${LowerString}")
1102       endif()
1103     endforeach()
1104     OCCDoc_CreateModuleToolkitsDependencyGraph("${outDir}/html" "schema_${mod}" ${mod} ${toolkit_prefix})
1105     puts (${outFile} "\\dotfile schema_${mod}")
1106     puts (${outFile} "**/")
1107   endforeach()
1108
1109   # One page per toolkit: list of packages
1110   set (packages)
1111   foreach (tk ${toolkits})
1112     puts (${outFile} "/**")
1113     string(TOLOWER "toolkit_${tk}" LowerString)
1114     puts (${outFile} "\\page ${LowerString} Toolkit ${tk}")
1115     OCCDoc_GetPackagesList(${tk} ${tk}_PACKAGES)
1116     list(SORT ${tk}_PACKAGES)
1117     foreach (pk ${${tk}_PACKAGES})
1118       list(APPEND packages ${pk})
1119       string(TOLOWER "${package_prefix}${pk}" LowerString)
1120       puts (${outFile} "\\li \\subpage ${LowerString}")
1121     endforeach()
1122     OCCDoc_CreateToolkitDependencyGraph("${outDir}/html" "schema_${tk}" "${tk}" "${toolkit_prefix}")
1123     puts (${outFile} "\\dotfile schema_${tk}")
1124     puts (${outFile} "**/")
1125   endforeach()
1126
1127   # One page per package: list of classes
1128   foreach (pk ${packages})
1129     puts (${outFile} "/**")
1130     string(TOLOWER "${package_prefix}${pk}" LowerString)
1131     puts (${outFile} "\\page ${LowerString} Package ${pk}")
1132     file(GLOB INC_FILES RELATIVE "${theRoot}/src/${pk}" "${theRoot}/src/${pk}/*.hxx")
1133     foreach (hdr ${INC_FILES})
1134       string(FIND "${hdr}" "Handle_" isHandle)
1135       if(NOT ${isHandle} EQUAL 0)
1136         string(LENGTH "${hdr}" length)
1137         math(EXPR length "${length} - 4")
1138         string(SUBSTRING "${hdr}" 0 ${length} aName)
1139         puts (${outFile} "\\li \\subpage ${aName}")
1140       endif()
1141     endforeach()
1142     puts (${outFile} "**/")
1143   endforeach()
1144 endfunction()
1145
1146 # Parses generated files to add a navigation path
1147 function(OCCDoc_PostProcessor outDir)
1148   string(TIMESTAMP time "%Y-%m-%d %H:%M")
1149   puts("${time} Post-process is started ...")
1150   set(outDir "${outDir}/html")
1151   file(GLOB files "${outDir}/package_*")
1152   list(LENGTH files length)
1153   if (NOT ${length} EQUAL 0)
1154     list(SORT files)
1155     foreach(f ${files})
1156       file(READ ${f} packageFile)
1157       OCCDoc_GetNodeContents("div" " id=\"nav-path\" class=\"navpath\"" "${packageFile}" navPath)
1158       OCCDoc_GetNodeContents("div" " class=\"title\"" "${packageFile}" packageName)
1159       get_filename_component(packageFileName "${f}" NAME)
1160       # add package link to nav path
1161       string(REPLACE "</ul>" "" navPath "${navPath}")
1162       set (navPath "${navPath}  <li class=\"navelem\"><a class=\"el\" href=\"${packageFileName}\">${packageName}</a>      </li>\n    </ul>")
1163       # get list of files to update
1164       OCCDoc_GetNodeContents("div" " class=\"textblock\"" "${packageFile}" listContents)
1165       OCCDoc_GetNodeContents("ul" "" "${listContents}" listContents)
1166       foreach(line ${listContents})
1167         STRING(REGEX REPLACE ".*href=\"([^\"]+)\".*" "\\1" classFileName "${test}" )
1168         if (NOT "${classFileName}" STREQUAL "${line}")
1169           # check if anchor is there
1170           string(FIND "${classFileName}" "#" anchorPos)
1171           if (NOT ${anchorPos} EQUAL -1)
1172             math(EXPR anchorPos "${anchorPos} - 1")
1173             string(SUBSTRING "${classFileName}" 0 ${anchorPos} classFileName)
1174           endif()
1175
1176           # read class file
1177           set (classFilePnt "${outDir}/${classFileName}")
1178           file(READ ${classFilePnt} classFile)
1179
1180           # find position of content block
1181           string(FIND "${classFile}" "<div class=\"header\">" contentPos)
1182           math(EXPR contentPos "${contentPos} - 1")
1183           string(SUBSTRING "${classFile}" 0 ${contentPos} navPart)
1184
1185           # position where to insert nav path
1186           string(FIND "${navPart}" "</div>" posToInsert REVERSE)
1187           math(EXPR posToInsert "${posToInsert} - 1")
1188           string(SUBSTRING "${classFile}" 0 ${posToInsert} prePart)
1189           string(SUBSTRING "${classFile}" ${posToInsert} -1 postPart)
1190           list(APPEND newClassFile "${prePart}" "  <div id=\"nav-path\" class=\"navpath\">" "${navPath}" "\n" "  </div>" "\n" "${postPart}")
1191
1192           # write updated content
1193           file(WRITE ${classFilePnt} "${newClassFile}")
1194           file(APPEND ${classFilePnt} "${classFile}")
1195         endif()
1196       endforeach()
1197     endforeach()
1198   else()
1199     puts ("no files found")
1200   endif()
1201 endfunction()
1202
1203 # ======================================
1204 #  User Guides-specific functions
1205 # ======================================
1206
1207 # Loads a list of docfiles from file FILES.txt
1208 function(OCCDoc_LoadFilesList)
1209   OCCDoc_GetDoxDir(INPUTDIR)
1210
1211   #available_docfiles
1212   set (available_docfiles "")
1213   # Read data from file
1214   if ( EXISTS "${INPUTDIR}/FILES_HTML.txt" )
1215     file (STRINGS "${INPUTDIR}/FILES_HTML.txt" available_docfiles REGEX "^[^#]+")
1216   else()
1217     error("File FILES_HTML.txt was not found on this computer.\nAborting...")
1218   endif()
1219   set(available_docfiles "${available_docfiles}" PARENT_SCOPE)
1220
1221   #available_pdf
1222   set(available_pdf "")
1223   # Read data from file
1224   if ( EXISTS "${INPUTDIR}/FILES_PDF.txt" )
1225     file (STRINGS "${INPUTDIR}/FILES_PDF.txt" available_pdf REGEX "^[^#]+")
1226   else()
1227     error("File FILES_PDF.txt was not found on this computer.\nAborting...")
1228   endif()
1229   set(available_pdf "${available_pdf}" PARENT_SCOPE)
1230 endfunction()
1231
1232 # Writes new TeX file for conversion from tex to pdf for a specific doc
1233 function(OCCDoc_MakeRefmanTex fileName latexDir verboseMode latexFilesList)
1234   set(latexFilesList ${${latexFilesList}})
1235   if ( "${verboseMode}" STREQUAL "YES")
1236     puts ("Info: Making refman.tex file for ${fileName}...")
1237   endif()
1238   set (DOCNAME "${latexDir}/refman.tex")
1239   if (EXISTS ${DOCNAME})
1240     file(REMOVE ${DOCNAME})
1241   endif()
1242
1243   # Copy template file to latex folder
1244   OCCDoc_GetDoxDir(temp_path)
1245
1246   configure_file("${temp_path}/resources/occt_pdf_template.tex" "${DOCNAME}" COPYONLY)
1247
1248   # Get templatized data
1249   file(READ ${DOCNAME} texfile_loaded)
1250
1251   # Replace dummy values
1252   OCCDoc_DetectCasVersion(casVersion)
1253
1254   # Get name of the document
1255   set (docLabel "")
1256   foreach (aFileName ${latexFilesList})
1257     # Find the file in FILES_PDF.txt
1258     string(REPLACE "/" ";" parsedFileName "${aFileName}")
1259     separate_arguments(parsedFileName)
1260     string(FIND "${fileName}" "__" aFirst)
1261     math(EXPR aFirst "${aFirst} + 2")
1262     string(SUBSTRING "${fileName}" ${aFirst} -1 newfileName)
1263     list(FIND parsedFileName "${newfileName}.md" isFOUND)
1264     if (NOT ${isFOUND} EQUAL -1)
1265       OCCDoc_GetDoxDir(temp_path)
1266       set (filepath "${temp_path}/${aFileName}")
1267       if (EXISTS ${filepath})
1268         file(STRINGS "${filepath}" MDFile LIMIT_COUNT 1)
1269         string(REPLACE "{" ";" MDFile "${MDFile}")
1270         separate_arguments(MDFile)
1271         list(GET MDFile 0 label)
1272         set (docLabel "${label}")
1273         break()
1274       endif()
1275     endif()
1276   endforeach()
1277   string(TIMESTAMP curYear "%Y")
1278   string(REPLACE "DEFDOCLABEL" "${docLabel}" texfile_loaded "${texfile_loaded}")
1279   string(REPLACE "DEFCASVERSION" "${casVersion}" texfile_loaded "${texfile_loaded}")
1280   string(REPLACE "DEFFILENAME" "${fileName}" texfile_loaded "${texfile_loaded}")
1281   string(REPLACE "DEFYEAR" "${curYear}" texfile_loaded "${texfile_loaded}")
1282   # Get data
1283   file(WRITE ${DOCNAME} "${texfile_loaded}")
1284 endfunction()
1285
1286 # Postprocesses generated TeX files
1287 function(OCCDoc_ProcessTex texFiles latexDir verboseMode)
1288   set(texFiles ${${texFiles}})
1289   foreach (TEX ${texFiles})
1290     if ("${verboseMode}" STREQUAL "YES")
1291       puts("Info: Preprocessing file ${TEX}...")
1292     endif()
1293
1294     if (NOT EXISTS ${latexDir}/${TEX})
1295       error("Error: file ${TEX} does not exist.")
1296     endif()
1297
1298     file(STRINGS "${latexDir}/${TEX}" IN_F)
1299     set(TEMP_LIST)
1300     foreach(line ${IN_F})
1301       string(FIND "${line}" "\\includegraphics" includegraphicsPos)
1302       string(FIND "${line}" "\\subsection" subsectionPos)
1303       string(FIND "${line}" "\\subsubsection" subsubsectionPos)
1304       string(FIND "${line}" "\\paragraph" paragraphPos)
1305
1306       if (NOT ${includegraphicsPos} EQUAL -1)
1307         # replace svg extension by pdf
1308         string(REPLACE ".svg" ".pdf" line "${line}")
1309         # Center images in TeX files
1310         set(line "\\begin{center}\n ${line}\n\\end{center}")
1311       elseif (NOT ${subsectionPos} EQUAL -1)
1312           # Replace \subsection with \section tag
1313           string(REPLACE "\\\\subsection" "\\\\section" line "${line}")
1314       elseif (NOT ${subsubsectionPos} EQUAL -1)
1315           # Replace \subsubsection with \subsection tag
1316           string(REPLACE "\\\\subsubsection" "\\\\subsection" line "${line}")
1317       elseif (NOT ${paragraphPos} EQUAL -1)
1318           # Replace \paragraph with \subsubsection tag
1319           string(REPLACE "\\\\paragraph" "\\\\subsubsection" line "${line}")
1320       endif()
1321       list(APPEND TEMP_LIST "${line}")
1322     endforeach()
1323     file(WRITE "${latexDir}/${TEX}" ${TEMP_LIST})
1324   endforeach()
1325 endfunction()