From cfb236f2aaa27adfa1bfbe2efd2797f218a01128 Mon Sep 17 00:00:00 2001
From: Victor Poughon <victor.poughon@cnes.fr>
Date: Fri, 14 Sep 2018 15:48:44 +0200
Subject: [PATCH] ENH: make Cookbook a cmake target

---
 CMakeLists.txt                                |   4 +
 .../RunApplicationsRstGenerator.sh.cmake.in   |   5 +-
 Documentation/Cookbook/CMakeLists.txt         | 105 ++++++++++--------
 .../Scripts/otbGenerateWrappersRstDoc.py      |  51 ++++-----
 Documentation/Cookbook/rst/conf.py.in         |  16 +--
 5 files changed, 95 insertions(+), 86 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6e9e0a2ba1..a03ebb45cd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -455,6 +455,10 @@ add_subdirectory(Utilities/Doxygen)
 
 add_subdirectory(Utilities/Completion)
 
+if (BUILD_DOCUMENTATION)
+    add_subdirectory(Documentation/Cookbook)
+endif()
+
 #----------------------------------------------------------------------------
 # Provide a target to generate the SuperBuild archive (only for Unix)
 if(UNIX)
diff --git a/Documentation/Cookbook/CMake/RunApplicationsRstGenerator.sh.cmake.in b/Documentation/Cookbook/CMake/RunApplicationsRstGenerator.sh.cmake.in
index 3c3a810ca2..747e319c18 100644
--- a/Documentation/Cookbook/CMake/RunApplicationsRstGenerator.sh.cmake.in
+++ b/Documentation/Cookbook/CMake/RunApplicationsRstGenerator.sh.cmake.in
@@ -1,6 +1,7 @@
 #!/bin/sh
 
-export LD_LIBRARY_PATH=@OTB_INSTALL_PREFIX@/lib:$LD_LIBRARY_PATH
+export LD_LIBRARY_PATH=@CMAKE_BINARY_DIR@/lib:$LD_LIBRARY_PATH
 export PYTHONPATH=@OTB_PYTHONPATH@:$PYTHONPATH
 export OTB_APPLICATION_PATH=@OTB_APPLICATION_PATH@
-@PYTHON_EXECUTABLE@ @CMAKE_SOURCE_DIR@/Scripts/otbGenerateWrappersRstDoc.py -o "$1"
+
+python3 @CMAKE_CURRENT_SOURCE_DIR@/Scripts/otbGenerateWrappersRstDoc.py -o "$1"
diff --git a/Documentation/Cookbook/CMakeLists.txt b/Documentation/Cookbook/CMakeLists.txt
index 52cd4f4f01..d7fb74c0f1 100644
--- a/Documentation/Cookbook/CMakeLists.txt
+++ b/Documentation/Cookbook/CMakeLists.txt
@@ -1,62 +1,47 @@
-set(OUT_OF_SOURCE_BUILD FALSE)
+#
+# Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
+#
+# This file is part of Orfeo Toolbox
+#
+#     https://www.orfeo-toolbox.org/
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+#
+# Build the cookbook
+#
+
+message(STATUS "")
+message(STATUS "Configuring Cookbook...")
+message(STATUS "")
 
-if(NOT PROJECT_NAME)
-  cmake_minimum_required(VERSION 3.0)
-  project(OTBCookBook)
-  set(OUT_OF_SOURCE_BUILD TRUE)
-  option(BUILD_TESTING "Build the testing tree." ON)
-endif()
-
-if(BUILD_TESTING)
-  enable_testing()
-  include(CTest)
-endif()
-
-string(TIMESTAMP OTB_COPYRIGHT_YEAR  "%Y")
-set(OTB_COPYRIGHT_TEXT "${OTB_COPYRIGHT_YEAR} CNES.The OTB CookBook is licensed under a Creative Commons Attribution-ShareAlike 4.0 International license (CC-BY-SA)")
-
-#find OTB
 find_package(OTB REQUIRED)
 
 if( OTB_FOUND )
   include(${OTB_USE_FILE})
   message(STATUS "Found OTB: ${OTB_DIR} (found version \"${OTB_VERSION}\")")
 else()
-  message(FATAL_ERROR "OTB not found. Please set OTB_DIR")
+  message(FATAL_ERROR "OTB not found while configuring cookbook")
   return()
 endif()
 
-get_filename_component(OTB_INSTALL_PREFIX ${OTB_MODULES_DIR} PATH)
-get_filename_component(OTB_INSTALL_PREFIX ${OTB_INSTALL_PREFIX} PATH)
-get_filename_component(OTB_INSTALL_PREFIX ${OTB_INSTALL_PREFIX} PATH)
-get_filename_component(OTB_INSTALL_PREFIX ${OTB_INSTALL_PREFIX} PATH)
-
 message(STATUS "OTB_PYTHONPATH        = '${OTB_PYTHONPATH}'")
 message(STATUS "OTB_APPLICATION_PATH  = '${OTB_APPLICATION_PATH}'")
-message(STATUS "OTB_INSTALL_PREFIX    = '${OTB_INSTALL_PREFIX}'")
 
-if(NOT OTB_PYTHONPATH)
-  message(FATAL_ERROR "OTB_PYTHONPATH empty")
-endif()
-
-if(NOT OTB_APPLICATION_PATH)
-  message(FATAL_ERROR "OTB_APPLICATION_PATH empty")
-endif()
-
-if(NOT OTB_INSTALL_PREFIX)
-  message(FATAL_ERROR "OTB_INSTALL_PREFIX empty")
-endif()
-
-
-macro(remove_and_make_directories)
-  foreach(dir in ${ARGV})
-    execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory ${dir})
-    execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${dir})
-  endforeach()
-endmacro()
-
-#find Python
-find_package(PythonInterp REQUIRED)
+# here we could add
+# find_package (Python3 COMPONENTS Interpreter)
+# but it requires cmake 3.12+
 
 find_program(SH_INTERP sh)
 mark_as_advanced(SH_INTERP)
@@ -73,18 +58,37 @@ mark_as_advanced(SPHINX_BUILD)
 find_program(PDFLATEX_COMMAND NAMES pdflatex )
 mark_as_advanced(PDFLATEX_COMMAND)
 
-foreach(cmd LATEX_COMMAND TAR_COMMAND PDFLATEX_COMMAND SPHINX_BUILD SH_INTERP)
+# Check that we found everything we need
+foreach(cmd
+    OTB_PYTHONPATH
+    OTB_APPLICATION_PATH
+    LATEX_COMMAND
+    TAR_COMMAND
+    PDFLATEX_COMMAND
+    SPHINX_BUILD
+    SH_INTERP)
   if(NOT ${cmd})
     message(FATAL_ERROR "${cmd} not set. Cannot continue")
   endif()
 endforeach()
 
 set(RST_SOURCE_DIR  ${CMAKE_CURRENT_SOURCE_DIR}/rst)
-
 set(RST_BINARY_DIR  ${CMAKE_CURRENT_BINARY_DIR}/rst)
 set(LATEX_DIR       ${CMAKE_CURRENT_BINARY_DIR}/latex)
 set(HTML_DIR        ${CMAKE_CURRENT_BINARY_DIR}/html)
 
+message(STATUS "RST_SOURCE_DIR = ${RST_SOURCE_DIR}")
+message(STATUS "RST_BINARY_DIR = ${RST_BINARY_DIR}")
+message(STATUS "LATEX_DIR = ${LATEX_DIR}")
+message(STATUS "HTML_DIR = ${HTML_DIR}")
+
+# Clean any existing build
+macro(remove_and_make_directories)
+  foreach(dir in ${ARGV})
+    execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory ${dir})
+    execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${dir})
+  endforeach()
+endmacro()
 
 remove_and_make_directories(
   ${HTML_DIR}
@@ -107,6 +111,9 @@ file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/Art DESTINATION  ${RST_BINARY_DIR})
 
 set(SPHINX_CONF_DIR ${CMAKE_CURRENT_BINARY_DIR})
 
+string(TIMESTAMP OTB_COPYRIGHT_YEAR  "%Y")
+set(OTB_COPYRIGHT_TEXT "${OTB_COPYRIGHT_YEAR} CNES.The OTB CookBook is licensed under a Creative Commons Attribution-ShareAlike 4.0 International license (CC-BY-SA)")
+
 configure_file(${RST_SOURCE_DIR}/conf.py.in ${SPHINX_CONF_DIR}/conf.py @ONLY)
 
 #configure_file(${RST_SOURCE_DIR}/Makefile.in ${RST_GENERATED_SOURCE_DIR}/Makefile.sphinx @ONLY)
@@ -122,6 +129,8 @@ add_custom_target(generate_otbapps_rst
   ${RST_BINARY_DIR}
   WORKING_DIRECTORY ${RST_BINARY_DIR}
   COMMENT "Auto-generating Application Reference Documentation in RST"
+  DEPENDS OTBSWIGWrapper-all
+  # TODO add DEPENDS to all apps
   )
 
 add_custom_target(CookBookHTML
diff --git a/Documentation/Cookbook/Scripts/otbGenerateWrappersRstDoc.py b/Documentation/Cookbook/Scripts/otbGenerateWrappersRstDoc.py
index 7f0606992f..4b1ae4619a 100755
--- a/Documentation/Cookbook/Scripts/otbGenerateWrappersRstDoc.py
+++ b/Documentation/Cookbook/Scripts/otbGenerateWrappersRstDoc.py
@@ -1,4 +1,5 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
+
 import otbApplication
 import os
 import sys
@@ -59,7 +60,7 @@ def GetPixelType(value):
     # look for type
     foundcode = -1
     foundname = ""
-    for ptypename, ptypecode in pixeltypes.iteritems():
+    for ptypename, ptypecode in pixeltypes.items():
         if value.endswith(ptypename):
             foundcode = ptypecode
             foundname = ptypename
@@ -166,14 +167,14 @@ def FindLengthOfLargestColumnText(app,paramlist):
 
 def RstTableHeaderLine(strlist, listlen, delimiter):
     line = "+"
-    for i in xrange(len(strlist)):
+    for i in range(len(strlist)):
         line += delimiter * listlen[i] + '+'
     line += linesep
     return line
 
 def RstTableHeading(strlist, listlen):
     heading = RstTableHeaderLine(strlist, listlen, '-')
-    for i in xrange(len(strlist)):
+    for i in range(len(strlist)):
          spaces = ' ' * ((listlen[i] - len(strlist[i])) )
          heading += '|' + strlist[i] +  spaces
     heading += '|' + linesep
@@ -189,7 +190,7 @@ def GenerateParametersTable(app,paramlist):
     colLength = FindLengthOfLargestColumnText(app, paramlist)
     output = linesep + ".. [#] Table: Parameters table for " + ConvertString(app.GetDocName()) + "." + linesep + linesep
     headerlist = ["Parameter Key", "Parameter Name", "Parameter Type"]
-    for i in xrange(len(headerlist)):
+    for i in range(len(headerlist)):
         colLength[i] = len(headerlist[i]) if colLength[i] < len(headerlist[i]) else colLength[i]
     output += RstTableHeading(headerlist, colLength)
     for param in paramlist:
@@ -446,7 +447,7 @@ def ApplicationToRst(appname):
     try:
         app = otbApplication.Registry.CreateApplication(appname)
     except e:
-        print e
+        print(e)
     # TODO: remove this when bug 440 is fixed
     app.Init()
     output += RstHeading(app.GetName() + ' - ' + app.GetDocName(), '^')
@@ -516,18 +517,19 @@ def GenerateRstForApplications():
     allApps = None
     try:
         allApps = otbApplication.Registry.GetAvailableApplications( )
+        print(allApps)
     except:
-        print 'error in otbApplication.Registry.GetAvailableApplications()'
+        print('error in otbApplication.Registry.GetAvailableApplications()')
         sys.exit(1)
 
     if not allApps:
-	print 'No OTB applications available. Please check OTB_APPLICATION_PATH env variable'
-	sys.exit(1)
+        print('No OTB applications available. Please check OTB_APPLICATION_PATH env variable')
+        sys.exit(1)
 
     writtenTags = []
     appNames = [app for app in allApps if app not in blackList]
 
-    print "All apps: %s" % (appNames,)
+    print("All apps: %s" % (appNames,))
 
     appIndexFile = open(RST_DIR + '/Applications.rst', 'w')
     appIndexFile.write(RstPageHeading("Applications Reference Documentation", "2", ref="apprefdoc"))
@@ -535,7 +537,7 @@ def GenerateRstForApplications():
         tags = GetApplicationTags(appName)
 
         if not tags:
-            print "No tags for application: "  +  appName
+            print("No tags for application: "  +  appName)
             sys.exit(1)
 
         tag = tags[0]
@@ -545,7 +547,7 @@ def GenerateRstForApplications():
             tag_ = tag.replace(' ', '_')
 
         if not tag_:
-            print 'empty tag found for ' + appName
+            print('empty tag found for ' + appName)
 
         if not tag_ in writtenTags:
             appIndexFile.write('\tApplications/' + tag_ + '.rst' + linesep)
@@ -562,7 +564,7 @@ def GenerateRstForApplications():
             tagFile.write("\tapp_" + appName + linesep)
             tagFile.close()
 
-        print "Generating " + appName + ".rst" +  " on tag " + tag_
+        print("Generating " + appName + ".rst" +  " on tag " + tag_)
         appFile = open(RST_DIR + '/Applications/app_'  + appName + '.rst', 'w')
         out = ApplicationToRst(appName)
         appFile.write(out)
@@ -571,17 +573,16 @@ def GenerateRstForApplications():
     return out
 
 
-# Start parsing options
-parser = OptionParser(usage="Export application(s) to rst file.")
-parser.add_option("-a",dest="appname",help="Generate rst only for this application (eg: OrthoRectification)")
-parser.add_option("-m",dest="module",help="Generate rst only for this module (eg: Image Manipulation)")
-parser.add_option("-o",dest="rstdir",help="directory where rst files are generated")
-(options, args) = parser.parse_args()
+if __name__ == "__main__":
+    parser = OptionParser(usage="Export application(s) to rst file.")
+    parser.add_option("-a",dest="appname",help="Generate rst only for this application (eg: OrthoRectification)")
+    parser.add_option("-m",dest="module",help="Generate rst only for this module (eg: Image Manipulation)")
+    parser.add_option("-o",dest="rstdir",help="directory where rst files are generated")
+    (options, args) = parser.parse_args()
 
-RST_DIR = options.rstdir
+    RST_DIR = options.rstdir
 
-if not options.appname is None:
-    out = ApplicationToRst(options.appname)
-    #print out
-else:
-    GenerateRstForApplications()
+    if not options.appname is None:
+        out = ApplicationToRst(options.appname)
+    else:
+        GenerateRstForApplications()
diff --git a/Documentation/Cookbook/rst/conf.py.in b/Documentation/Cookbook/rst/conf.py.in
index 1e4442b07f..c9e101cb7a 100644
--- a/Documentation/Cookbook/rst/conf.py.in
+++ b/Documentation/Cookbook/rst/conf.py.in
@@ -14,12 +14,7 @@
 
 import sys
 import os
-HAVE_RTD_THEME=False
-try:
-    import sphinx_rtd_theme
-    HAVE_RTD_THEME=True
-except:
-    pass
+import sphinx_rtd_theme
 
 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
@@ -111,11 +106,10 @@ pygments_style = 'sphinx'
 
 # The theme to use for HTML and HTML Help pages.  See the documentation for
 # a list of builtin themes.
-if HAVE_RTD_THEME:
-    html_theme = 'sphinx_rtd_theme'
-    # Add any paths that contain custom themes here, relative to this directory.
-    html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
-    
+html_theme = 'sphinx_rtd_theme'
+# Add any paths that contain custom themes here, relative to this directory.
+html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
+
 # Theme options are theme-specific and customize the look and feel of a theme
 # further.  For a list of options available for each theme, see the
 # documentation.
-- 
GitLab