From ec651ec0f73970482c84461c27d5fd74db6f4fa6 Mon Sep 17 00:00:00 2001
From: Victor Poughon <victor.poughon@cnes.fr>
Date: Fri, 7 Dec 2018 18:24:16 +0100
Subject: [PATCH] REFAC: rewrite of otbGenerateWrappersRstDoc.py & doc
 improvements

---
 .../RunApplicationsRstGenerator.sh.cmake.in   |   2 +-
 Documentation/Cookbook/CMakeLists.txt         |   4 +-
 .../Scripts/otbGenerateWrappersRstDoc.py      | 714 +++++++-----------
 .../Cookbook/_static/css/otb_theme.css        |  10 +
 Documentation/Cookbook/rst/Installation.rst   |   2 +-
 Documentation/Cookbook/rst/conf.py.in         |  17 +-
 .../Cookbook/rst/templates/application.rst    |  41 +
 .../Cookbook/rst/templates/parameter.rst      |   3 +
 .../rst/templates/parameter_choice.rst        |   5 +
 .../rst/templates/parameter_choice_entry.rst  |   2 +
 .../rst/templates/parameter_group.rst         |   4 +
 .../app/otbFusionOfClassifications.cxx        |   2 +-
 .../app/otbImageClassifier.cxx                |  21 +-
 .../app/otbTrainImagesClassifier.cxx          |  33 +-
 .../app/otbTrainVectorClassifier.cxx          |   2 +-
 .../app/otbVectorClassifier.cxx               |  24 +-
 .../include/otbTrainBoost.hxx                 |   3 +-
 .../include/otbTrainDecisionTree.hxx          |   3 +-
 .../include/otbTrainGradientBoostedTree.hxx   |   3 +-
 .../AppClassification/include/otbTrainKNN.hxx |   3 +-
 .../include/otbTrainNeuralNetwork.hxx         |   5 +-
 .../include/otbTrainNormalBayes.hxx           |   3 +-
 .../include/otbTrainRandomForests.hxx         |   4 +-
 .../AppClassification/include/otbTrainSVM.hxx |   3 +-
 .../include/otbTrainSharkKMeans.hxx           |   5 +-
 .../include/otbTrainSharkRandomForests.hxx    |   3 +-
 .../app/otbDimensionalityReduction.cxx        |   2 +-
 .../app/otbDomainTransform.cxx                |   4 +-
 .../AppFusion/app/otbPansharpening.cxx        |   2 +-
 .../AppImageUtils/app/otbColorMapping.cxx     |  28 +-
 .../AppImageUtils/app/otbCompareImages.cxx    |  21 +-
 .../app/otbConcatenateImages.cxx              |   4 +-
 .../AppImageUtils/app/otbDynamicConvert.cxx   |  17 +-
 .../AppImageUtils/app/otbQuicklook.cxx        |   8 +-
 .../AppIndices/app/otbRadiometricIndices.cxx  |  41 +-
 .../AppMathParser/app/otbBandMath.cxx         |  28 +-
 .../AppMathParserX/app/otbBandMathX.cxx       |  88 ++-
 .../app/otbSARPolarMatrixConvert.cxx          | 120 +--
 .../AppStereo/app/otbStereoFramework.cxx      |  12 +-
 .../src/otbWrapperApplication.cxx             |   6 +-
 .../otbWrapperInputProcessXMLParameter.cxx    |   4 +-
 .../otbWrapperOutputProcessXMLParameter.cxx   |   4 +-
 42 files changed, 613 insertions(+), 697 deletions(-)
 create mode 100644 Documentation/Cookbook/_static/css/otb_theme.css
 create mode 100644 Documentation/Cookbook/rst/templates/application.rst
 create mode 100644 Documentation/Cookbook/rst/templates/parameter.rst
 create mode 100644 Documentation/Cookbook/rst/templates/parameter_choice.rst
 create mode 100644 Documentation/Cookbook/rst/templates/parameter_choice_entry.rst
 create mode 100644 Documentation/Cookbook/rst/templates/parameter_group.rst

diff --git a/Documentation/Cookbook/CMake/RunApplicationsRstGenerator.sh.cmake.in b/Documentation/Cookbook/CMake/RunApplicationsRstGenerator.sh.cmake.in
index ff3c204aa7..1db3cde6aa 100644
--- a/Documentation/Cookbook/CMake/RunApplicationsRstGenerator.sh.cmake.in
+++ b/Documentation/Cookbook/CMake/RunApplicationsRstGenerator.sh.cmake.in
@@ -5,4 +5,4 @@
 export PYTHONPATH=@PYTHONPATH_COOKBOOK@:$PYTHONPATH
 export OTB_APPLICATION_PATH=@CMAKE_BINARY_DIR@/lib/otb/applications
 
-python3 @CMAKE_CURRENT_SOURCE_DIR@/Scripts/otbGenerateWrappersRstDoc.py -o "$1"
+python3 @CMAKE_CURRENT_SOURCE_DIR@/Scripts/otbGenerateWrappersRstDoc.py "$1"
diff --git a/Documentation/Cookbook/CMakeLists.txt b/Documentation/Cookbook/CMakeLists.txt
index 766102aab6..ea309686b4 100644
--- a/Documentation/Cookbook/CMakeLists.txt
+++ b/Documentation/Cookbook/CMakeLists.txt
@@ -120,6 +120,8 @@ set(OTB_COPYRIGHT_TEXT "${OTB_COPYRIGHT_YEAR} CNES.The OTB CookBook is licensed
 
 configure_file(${RST_SOURCE_DIR}/conf.py.in ${SPHINX_CONF_DIR}/conf.py @ONLY)
 
+file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/_static DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+
 add_custom_target(generate_otbapps_rst
   COMMAND ${SH_INTERP} ${CMAKE_CURRENT_BINARY_DIR}/RunApplicationsRstGenerator.sh
   ${RST_BINARY_DIR}
@@ -142,7 +144,6 @@ add_custom_target(CookBookHTML
   -b html
   ${RST_BINARY_DIR}
   ${HTML_DIR}
-  -W
   -v
   -c ${SPHINX_CONF_DIR}
   WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
@@ -163,7 +164,6 @@ add_custom_target(CookBookArchive
    -b latex
    ${RST_BINARY_DIR}
    ${LATEX_DIR}
-   -W
    -v
    -c ${SPHINX_CONF_DIR}
    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
diff --git a/Documentation/Cookbook/Scripts/otbGenerateWrappersRstDoc.py b/Documentation/Cookbook/Scripts/otbGenerateWrappersRstDoc.py
index 7bb739bed0..abd6321947 100755
--- a/Documentation/Cookbook/Scripts/otbGenerateWrappersRstDoc.py
+++ b/Documentation/Cookbook/Scripts/otbGenerateWrappersRstDoc.py
@@ -19,40 +19,16 @@
 # limitations under the License.
 #
 
-import otbApplication
 import os
 import sys
-import glob
-from optparse import OptionParser
+import argparse
+
+import otbApplication
+from otbApplication import ParameterType_Bool, ParameterType_Int, ParameterType_Radius, ParameterType_RAM, ParameterType_Float, ParameterType_String, ParameterType_StringList, ParameterType_InputFilename, ParameterType_OutputFilename, ParameterType_InputImage, ParameterType_ComplexInputImage, ParameterType_OutputImage, ParameterType_ComplexOutputImage, ParameterType_InputVectorData, ParameterType_OutputVectorData, ParameterType_Directory, ParameterType_Choice, ParameterType_InputImageList, ParameterType_InputVectorDataList, ParameterType_InputFilenameList, ParameterType_InputProcessXML, ParameterType_OutputProcessXML, ParameterType_ListView, ParameterType_Group
 
-##############################################################################
-# Parameters
 linesep = os.linesep
 pixeltypes = {' uchar' : 1, ' int8' : 0, ' uint8' : 1, ' int16' : 2, ' uint16': 3, ' int32' : 4, ' uint32' : 5, ' float' : 6, ' double': 7}
 
-import re
-
-#Special/Exceptional cases
-def RstifyDescription(s):
-    s = s.replace(':\n', ':\n\n')
-    s = s.replace('\n', ' ')
-    s = s.replace('*','\*')
-    if not len(s) == 0 and not s.endswith('.'):
-        s += '.'
-    return s
-
-def ConvertString(s):
-    '''Convert a string for compatibility in txt dump'''
-    s = s.strip()
-    s = s.replace('*','\*')
-    return s
-
-def ConvertToLineBlock(s):
-    '''Convert a string into a line bloc (prefix with |) '''
-    s = s.strip()
-    s = s.replace('*','\*')
-    s = "  | " + s.replace('\n','\n  | ')
-    return s
 
 def EncloseString(s):
     if not s.startswith("\"") :
@@ -86,437 +62,310 @@ def GetPixelType(value):
             break
     return foundcode,foundname
 
-def GetParametersDepth(paramlist):
-    depth = 0
-    for param in paramlist:
-        depth = max(param.count("."),depth)
-    return depth
-
-def GenerateChoice(app,param,paramlist, count = 0):
-    output = " Available choices are: " + linesep
-    spaces = ' ' * count
-    for (choicekey,choicename) in zip(app.GetChoiceKeys(param),app.GetChoiceNames(param)):
-        output += linesep + spaces + "- **"+ ConvertString(choicename) + "**"
-        choicedesc = app.GetParameterDescription(param+"."+choicekey)
-        if len(choicedesc) >= 2:
-            output+= " : " + ConvertString(choicedesc)
-        output += linesep + linesep
-        # List option associated to one choice
-        options = []
-        for p in paramlist:
-            if p.startswith(param+"."+choicekey+"."):
-                options.append(p)
-        if len(options) > 0:
-            count += 1
-            spaces = ' ' * count
-            for option in options:
-                output+= linesep + spaces + "- **"+ ConvertString(app.GetParameterName(option))+ "** : " + RstifyDescription(app.GetParameterDescription(option)) + linesep
-            output+= linesep
-    return output
-
-def GenerateParameterType(app,param):
-    if app.GetParameterType(param) == otbApplication.ParameterType_Empty \
-       or app.GetParameterType(param) == otbApplication.ParameterType_Bool:
-        return "Boolean"
-    if app.GetParameterType(param) == otbApplication.ParameterType_Int \
-       or app.GetParameterType(param) == otbApplication.ParameterType_Radius \
-       or app.GetParameterType(param) == otbApplication.ParameterType_RAM:
-        return "Int"
-    if app.GetParameterType(param) == otbApplication.ParameterType_Float:
-        return "Float"
-    if app.GetParameterType(param) == otbApplication.ParameterType_String:
-        return "String"
-    if app.GetParameterType(param) == otbApplication.ParameterType_StringList:
-        return "String list"
-    if app.GetParameterType(param) == otbApplication.ParameterType_InputFilename :
-        return "Input File name"
-    if app.GetParameterType(param) == otbApplication.ParameterType_OutputFilename :
-        return "Output File name"
-    if app.GetParameterType(param) == otbApplication.ParameterType_Directory :
-        return "Directory"
-    if app.GetParameterType(param) ==  otbApplication.ParameterType_Choice:
-        return "Choices"
-    if app.GetParameterType(param) == otbApplication.ParameterType_InputImage \
-            or app.GetParameterType(param) == otbApplication.ParameterType_ComplexInputImage:
-        return "Input image"
-    if app.GetParameterType(param) == otbApplication.ParameterType_InputVectorData:
-        return "Input vector data"
-    if app.GetParameterType(param) == otbApplication.ParameterType_OutputImage \
-            or app.GetParameterType(param) == otbApplication.ParameterType_ComplexOutputImage :
-        return "Output image"
-    if app.GetParameterType(param) == otbApplication.ParameterType_OutputVectorData:
-        return "Output vector data"
-    if app.GetParameterType(param) == otbApplication.ParameterType_InputImageList:
-        return "Input image list"
-    if app.GetParameterType(param) == otbApplication.ParameterType_InputVectorDataList:
-        return "Input vector data list"
-    if app.GetParameterType(param) == otbApplication.ParameterType_InputFilenameList :
-        return "Input File name list"
-    if app.GetParameterType(param) == otbApplication.ParameterType_ListView:
-        if app.GetListViewSingleSelectionMode(param):
-            return "String"
-        else:
-            return "String List"
-    if app.GetParameterType(param) == otbApplication.ParameterType_Group:
-        return "Group"
-    if app.GetParameterType(param) == otbApplication.ParameterType_InputProcessXML:
-        return "XML input parameters file"
-    if app.GetParameterType(param) == otbApplication.ParameterType_OutputProcessXML:
-        return "XML output parameters file"
-
-def FindLengthOfLargestColumnText(app,paramlist):
-    output= ""
-    colLength = [2] * 3
-    for param in paramlist:
-        if app.GetParameterType(param) ==  otbApplication.ParameterType_Choice:
-            for (choicekey,choicename) in zip(app.GetChoiceKeys(param),app.GetChoiceNames(param)):
-                lenp= len(param + " " + choicekey)
-                if colLength[0] < lenp:
-                    colLength[0] = lenp
-                lenpdescr = len(choicename)
-                if colLength[1] < lenpdescr:
-                    colLength[1] = lenpdescr
-        else:
-            if colLength[0] < len(param):
-                colLength[0] = len(param)
-            lenpdescr = len(GenerateParameterType(app, param))
-            if colLength[2] < lenpdescr:
-                colLength[2] = lenpdescr
-        lenptype = len(app.GetParameterName(param))
-        if colLength[1] < lenptype:
-            colLength[1] = lenptype
-    return colLength
-
-def RstTableHeaderLine(strlist, listlen, delimiter):
-    line = "+"
-    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 range(len(strlist)):
-         spaces = ' ' * ((listlen[i] - len(strlist[i])) )
-         heading += '|' + strlist[i] +  spaces
-    heading += '|' + linesep
-    heading += RstTableHeaderLine(strlist, listlen, '=')
-    return heading
-
-def MakeText(text, size):
-    dsize = (size - len(text))
-    output= '|' + text  + ' ' * (dsize)
-    return output
-
-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 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:
-        output += MakeText(param, colLength[0])
-        output += MakeText(app.GetParameterName(param), colLength[1])
-        output += MakeText(GenerateParameterType(app, param), colLength[2])
-        output += '|' + linesep
-        output += RstTableHeaderLine(headerlist, colLength, '-')
-        if app.GetParameterType(param) ==  otbApplication.ParameterType_Choice:
-            for (choicekey,choicename) in zip(app.GetChoiceKeys(param),app.GetChoiceNames(param)):
-                output += MakeText(param + " " + choicekey, colLength[0])
-                output += MakeText(choicename,colLength[1])
-                output += MakeText(" *Choice*", colLength[2])
-                output += '|' + linesep
-                output += RstTableHeaderLine(headerlist, colLength, '-')
-    return output
-
-def unique(seq):
-    # order preserving
-    checked = []
-    for e in seq:
-        if e not in checked:
-            checked.append(e)
-    return checked
-
-def ApplicationParametersToRst(app,paramlist,deep = False,current=""):
-    output = ""
-    # First run
-    if len(current)==0:
-        output += "This section describes in details the parameters available for this application. Table [#]_ presents a summary of these parameters and the parameters keys to be used in command-line and programming languages. Application key is *" + app.GetName() + "* ."  + linesep
-        output += GenerateParametersTable(app,paramlist)
-        firstlevelparams = []
-        for param in paramlist:
-            paramsplit = param.partition(".")
-            firstlevelparams.append(paramsplit[0])
-        firstlevelparams = unique(firstlevelparams)
-
-        if deep:
-            for param in firstlevelparams:
-                output += linesep
-                output += "**" + ConvertString(app.GetParameterName(param)) + "**" + linesep
-                output += RstifyDescription(app.GetParameterDescription(param))
-                if app.GetParameterType(param) ==  otbApplication.ParameterType_Choice:
-                    output += GenerateChoice(app,param,paramlist)
-                    output += linesep
-                else:
-                    output += linesep
-                    output += ApplicationParametersToRst(app,paramlist,deep,param)
-        else:
-            output+= linesep
-            for param in firstlevelparams:
-                output+= "- **"+ ConvertString(app.GetParameterName(param))+ ":** " + RstifyDescription(app.GetParameterDescription(param))
-                if app.GetParameterType(param) ==  otbApplication.ParameterType_Choice:
-                    output += GenerateChoice(app,param,paramlist)
-                output += linesep + linesep
-            output+=  linesep
-    else:
-        currentlevelparams = []
-        for param in paramlist:
-            if param.startswith(current+".") and param.count(".") == current.count(".")+1:
-                currentlevelparams.append(param)
-        if len(currentlevelparams) > 0:
-            output+= linesep
-            for param in currentlevelparams:
-                output+= "- **"+ ConvertString(app.GetParameterName(param))+ ":** " + RstifyDescription(app.GetParameterDescription(param)) + linesep
-                output+= ApplicationParametersToRst(app,paramlist,deep,param) + linesep
-                if app.GetParameterType(param) ==  otbApplication.ParameterType_Choice:
-                    output += GenerateChoice(app,param,paramlist, 1)
-            output+= linesep
+def render_choice(app, key):
+    "Render a choice parameter to rst"
+
+    # First render all the choice values
+    choice_keys = app.GetChoiceKeys(key)
+    choice_names = app.GetChoiceNames(key)
+
+    choice_entries = ""
+    for (choice_key, choice_name) in zip(choice_keys, choice_names):
+        # For the description, replace newlines by |br| because we are in a bullet list item
+        choice_description = app.GetParameterDescription(key + "." + choice_key).replace("\n", " |br| ")
+        choice_entries += template_parameter_choice_entry.format(
+            name=choice_name,
+            #key=choice_key, # if we want to show the key in choice parameter values
+            description=choice_description
+        )
+
+    # Then render the full choice parameter
+    return template_parameter_choice.format(
+        name=app.GetParameterName(key),
+        key=key,
+        value="[" + "|".join(choice_keys) + "]",
+        flags=rst_parameter_flags(app, key),
+        description=app.GetParameterDescription(key),
+        choices=choice_entries,
+    )
 
-    return output
+def GetApplicationExamplePythonSnippet(app,idx,expand = False, inputpath="",outputpath=""):
+    appname = "app"
 
-def ApplicationParametersToRstV2(app,paramlist,deep = False,current=""):
     output = ""
-    # current level
-    level = 0
-    # First run
-    if len(current)==0:
-        output += "This section describes in details the parameters available for this application. Table [#]_ presents a summary of these parameters and the parameters keys to be used in command-line and programming languages. Application key is *" + app.GetName() + "* ."  + linesep
-        output += GenerateParametersTable(app,paramlist)
-    else:
-        level = len(current.split('.'))
-    indentLevel = level
-    if deep == False:
-        indentLevel += 1
-    # compute prefix
-    bulletStyle = "-*+"
-    prefix = ""
-    if indentLevel > 0:
-        prefix = (' ' * (indentLevel-1)) + bulletStyle[(indentLevel-1)%3] + ' '
-    # find parameter for current param
-    currentlevelparams = []
-    for param in paramlist:
-        if param.startswith(current) and len(param.split('.')) == level+1:
-            currentlevelparams.append(param)
-    if len(currentlevelparams) > 0:
-        output+= linesep
-        for param in currentlevelparams:
-            if app.GetParameterType(param) == otbApplication.ParameterType_Group and level == 0:
-                output+= prefix+"**["+ ConvertString(app.GetParameterName(param))+ "]**"
-            else:
-                output+= prefix+"**"+ ConvertString(app.GetParameterName(param))+ "**"
-            descr =  RstifyDescription(app.GetParameterDescription(param))
-            if len(descr):
-                output+= ": "+descr
-            if app.GetParameterType(param) ==  otbApplication.ParameterType_Choice:
-                output+= " Available choices are: "
-                additionalKeys = []
-                for choiceKey in app.GetChoiceKeys(param):
-                    additionalKeys.append(param+'.'+choiceKey)
-                nextParamList = paramlist + tuple(additionalKeys)
-            else:
-                nextParamList = paramlist
-            output+= linesep
-            ret = ApplicationParametersToRstV2(app,nextParamList,deep,param)
-            if indentLevel == 0 and len(ret)==0:
-                output+= linesep
-            output+= ret
-        output+= linesep
-    return output
-
-def GetApplicationExampleCommandLine(app,idx):
-
-    output = "%s%s%s\t%s" % ("::", linesep , linesep, "otbcli_")
-    output+= ConvertString(app.GetName())
-    for i in range(0, app.GetExampleNumberOfParameters(idx)):
-        output+=" -" + app.GetExampleParameterKey(idx,i)+ " " + app.GetExampleParameterValue(idx,i)
-    output += linesep + linesep
-    return output
-
-def GetApplicationExamplePythonSnippet(app,idx,expand = False, inputpath="",outputpath=""):
-    appname = app.GetName()
-    printable = []
-    output = linesep + "::" + linesep + linesep
-    output+= "\t#!/usr/bin/python" + linesep
 
-    output+= linesep
-    output+= "\t# Import the otb applications package" + linesep
     output+= "\timport otbApplication" + linesep + linesep
-    output+= "\t# The following line creates an instance of the " + ConvertString(app.GetName()) + " application " + linesep
-    output+= "\t" + ConvertString(app.GetName()) + " = otbApplication.Registry.CreateApplication(\"" + ConvertString(app.GetName()) + "\")" + linesep + linesep
-    output+= "\t# The following lines set all the application parameters:" + linesep
+    output+= "\t" + appname + " = otbApplication.Registry.CreateApplication(\"" + app.GetName() + "\")" + linesep + linesep
     for i in range(0, app.GetExampleNumberOfParameters(idx)):
         param = app.GetExampleParameterKey(idx,i)
         value = app.GetExampleParameterValue(idx,i)
         paramtype = app.GetParameterType(param)
         paramrole = app.GetParameterRole(param)
-        if paramtype == otbApplication.ParameterType_ListView:
+        if paramtype == ParameterType_ListView:
             break
-        if paramtype == otbApplication.ParameterType_Group:
+        if paramtype == ParameterType_Group:
             break
-        if paramtype ==  otbApplication.ParameterType_Choice:
+        if paramtype ==  ParameterType_Choice:
             #app.SetParameterString(param,value)
-            output+= "\t" + appname + ".SetParameterString(" + EncloseString(param) + "," + EncloseString(value) + ")" + linesep
-        if paramtype == otbApplication.ParameterType_Empty:
-            app.EnableParameter(param)
-            output+= "\t" + appname + ".EnableParameter("+EncloseString(param)+")" + linesep
-        if paramtype == otbApplication.ParameterType_Bool:
-            output+= "\t" + appname + ".SetParameterString("+EncloseString(param)+","+EncloseString(value)+")" + linesep
-        if paramtype == otbApplication.ParameterType_Int \
-                or paramtype == otbApplication.ParameterType_Radius \
-                or paramtype == otbApplication.ParameterType_RAM:
+            output+= "\t" + appname + ".SetParameterString(" + EncloseString(param) + "," + EncloseString(value) + ")"
+        if paramtype == ParameterType_Bool:
+            output+= "\t" + appname + ".SetParameterString("+EncloseString(param)+","+EncloseString(value)+")"
+        if paramtype == ParameterType_Int \
+                or paramtype == ParameterType_Radius \
+                or paramtype == ParameterType_RAM:
             # app.SetParameterString(param,value)
-            output += "\t" + appname + ".SetParameterInt("+EncloseString(param)+", "+value+")" + linesep
-        if paramtype == otbApplication.ParameterType_Float:
+            output += "\t" + appname + ".SetParameterInt("+EncloseString(param)+", "+value+")"
+        if paramtype == ParameterType_Float:
             # app.SetParameterString(param,value)
-            output += "\t" + appname + ".SetParameterFloat("+EncloseString(param)+", "+value + ")" + linesep
-        if paramtype == otbApplication.ParameterType_String:
+            output += "\t" + appname + ".SetParameterFloat("+EncloseString(param)+", "+value + ")"
+        if paramtype == ParameterType_String:
             # app.SetParameterString(param,value)
-            output+= "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(value)+")" + linesep
-        if paramtype == otbApplication.ParameterType_StringList:
+            output+= "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(value)+")"
+        if paramtype == ParameterType_StringList:
             values = value.split(" ")
             # app.SetParameterStringList(param,values)
-            output += "\t" + appname + ".SetParameterStringList("+EncloseString(param)+", "+str(values)+")" + linesep
-        if paramtype == otbApplication.ParameterType_InputFilename \
-            or paramtype == otbApplication.ParameterType_OutputFilename \
-            or paramtype == otbApplication.ParameterType_Directory:
+            output += "\t" + appname + ".SetParameterStringList("+EncloseString(param)+", "+str(values)+")"
+        if paramtype == ParameterType_InputFilename \
+            or paramtype == ParameterType_OutputFilename \
+            or paramtype == ParameterType_Directory:
             if paramrole == 0:
                 # app.SetParameterString(param,EncloseString(ExpandPath(value,inputpath,expand)))
-                output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(ExpandPath(value,inputpath,expand)) + ")" + linesep
-                printable.append(["in","file",ExpandPath(value,inputpath,expand)])
+                output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(ExpandPath(value,inputpath,expand)) + ")"
             elif paramrole == 1:
                 # app.SetParameterString(param,EncloseString(ExpandPath(value,outputpath,expand)))
-                output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(ExpandPath(value,outputpath,expand))+")" + linesep
-                printable.append(["out","file",ExpandPath(value,inputpath,expand)])
-        if paramtype == otbApplication.ParameterType_InputImage :
+                output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(ExpandPath(value,outputpath,expand))+")"
+        if paramtype == ParameterType_InputImage :
             # app.SetParameterString(param,EncloseString(ExpandPath(value,inputpath,expand)))
-            output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(ExpandPath(value,inputpath,expand))+")"+linesep
-            printable.append(["in","img",ExpandPath(value,inputpath,expand)])
-        if paramtype == otbApplication.ParameterType_ComplexInputImage:
+            output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(ExpandPath(value,inputpath,expand))+")"
+        if paramtype == ParameterType_ComplexInputImage:
             # app.SetParameterString(param,EncloseString(ExpandPath(value,inputpath,expand)))
-            output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(ExpandPath(value,inputpath,expand))+")" + linesep
-            printable.append(["in","cimg",ExpandPath(value,inputpath,expand)])
-        if paramtype == otbApplication.ParameterType_InputVectorData:
+            output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(ExpandPath(value,inputpath,expand))+")"
+        if paramtype == ParameterType_InputVectorData:
             # app.SetParameterString(param,EncloseString(ExpandPath(value,inputpath,expand)))
-            output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(ExpandPath(value,inputpath,expand))+")" + linesep
-            printable.append(["in","vdata",ExpandPath(value,inputpath,expand)])
-        if paramtype == otbApplication.ParameterType_OutputImage :
+            output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(ExpandPath(value,inputpath,expand))+")"
+        if paramtype == ParameterType_OutputImage :
             foundcode,foundname = GetPixelType(value)
             if foundcode != -1:
-                # app.SetParameterString(param,EncloseString(ExpandPath(value[:-len(foundname),outputpath,expand))))
-                output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(ExpandPath(value[:-len(foundname)],outputpath,expand))+")" + linesep
-           #app.SetParameterOutputImagePixelType(param,foundcode)
-                if foundcode == 1:
-                    printable.append(["out","ucimg",ExpandPath(value[:len(foundname)],inputpath,expand)])
-                else:
-                    printable.append(["out","img",ExpandPath(value[:len(foundname)],inputpath,expand)])
-                output += "\t" + appname + ".SetParameterOutputImagePixelType("+EncloseString(param)+", "+str(foundcode)+")" + linesep
+                output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(ExpandPath(value[:-len(foundname)],outputpath,expand))+")"
+                output += "\n"
+                output += "\t" + appname + ".SetParameterOutputImagePixelType("+EncloseString(param)+", "+str(foundcode)+")"
             else:
-                # app.SetParameterString(param,EncloseString(ExpandPath(value,outputpath,expand)))
-                output += "\t" + appname +".SetParameterString("+EncloseString(param)+", "+ EncloseString(ExpandPath(value,outputpath,expand)) + ")" + linesep
-                printable.append(["out","img",ExpandPath(value,outputpath,expand)])
-        if paramtype == otbApplication.ParameterType_ComplexOutputImage :
+                output += "\t" + appname +".SetParameterString("+EncloseString(param)+", "+ EncloseString(ExpandPath(value,outputpath,expand)) + ")"
+        if paramtype == ParameterType_ComplexOutputImage :
             # TODO: handle complex type properly
             # app.SetParameterString(param,EncloseString(ExpandPath(value,outputpath,expand)))
-            output += "\t" + appname +".SetParameterString("+EncloseString(param)+", "+ EncloseString(ExpandPath(value,outputpath,expand)) + ")" + linesep
-            printable.append(["out","cimg",ExpandPath(value,outputpath,expand)])
-        if paramtype == otbApplication.ParameterType_OutputVectorData:
+            output += "\t" + appname +".SetParameterString("+EncloseString(param)+", "+ EncloseString(ExpandPath(value,outputpath,expand)) + ")"
+        if paramtype == ParameterType_OutputVectorData:
             # app.SetParameterString(param,EncloseString(ExpandPath(value,outputpath,expand)))
-            output += "\t" + appname +".SetParameterString("+EncloseString(param)+", "+ EncloseString(ExpandPath(value,outputpath,expand)) + ")" + linesep
-            printable.append(["out","vdata",ExpandPath(value,outputpath,expand)])
-        if paramtype == otbApplication.ParameterType_InputImageList:
+            output += "\t" + appname +".SetParameterString("+EncloseString(param)+", "+ EncloseString(ExpandPath(value,outputpath,expand)) + ")"
+        if paramtype == ParameterType_InputImageList:
             values = value.split(" ")
             values = [ExpandPath(val,inputpath,expand) for val in values]
             # app.SetParameterStringList(param,values)
-            output += "\t" + appname + ".SetParameterStringList("+EncloseString(param) + ", " + str(values) + ")" + linesep
-        if paramtype == otbApplication.ParameterType_InputVectorDataList:
+            output += "\t" + appname + ".SetParameterStringList("+EncloseString(param) + ", " + str(values) + ")"
+        if paramtype == ParameterType_InputVectorDataList:
             values = value.split(" ")
             values = [ExpandPath(val,inputpath,expand) for val in values]
             #app.SetParameterStringList(param,values)
-            output += "\t" + appname + ".SetParameterStringList("+EncloseString(param)+ ", " + str(values) + ")" + linesep
+            output += "\t" + appname + ".SetParameterStringList("+EncloseString(param)+ ", " + str(values) + ")"
         output+=linesep
-    output += "\t# The following line execute the application" + linesep
+    output += linesep
     output+= "\t" + appname + ".ExecuteAndWriteOutput()"+ linesep
-    return output,printable
+    return output
 
-def GetApplicationExamplePython(app,idx):
-    output, printable = GetApplicationExamplePythonSnippet(app,idx)
-    output+= linesep
+def rst_section(text, delimiter, ref=None):
+    "Make a rst section title"
+
+    output = ""
+
+    if ref is not None:
+        output += ".. _" + ref + ":\n\n"
+
+    output += text + "\n" + delimiter * len(text) + "\n\n"
     return output
 
-def RstHeading(text, delimiter, ref=None):
-    heading = ""
-    if ref:
-        heading += ".. _" + ref + ":" + linesep + linesep
-    heading += text + linesep
-    heading += delimiter * len(text)  + linesep
-    heading += linesep
-    return heading
+def rst_parameter_value(app, key):
+    "Render a parameter value to rst"
+
+    type = app.GetParameterType(key)
+
+    # ListView is a special case depending on its mode
+    if type == ParameterType_ListView:
+        if app.GetListViewSingleSelectionMode(key):
+            return "string"
+        else:
+            return "string1 string2..."
+
+    # For all other types it's a simple mapping
+    values = {
+        ParameterType_Bool: "bool",
+        **dict.fromkeys([ParameterType_Int, ParameterType_Radius, ParameterType_RAM], "int"),
+        ParameterType_Float: "float",
+        ParameterType_String: "string",
+        ParameterType_StringList: "string1 string2...",
+        **dict.fromkeys([ParameterType_InputFilename, ParameterType_OutputFilename], "filename"),
+        **dict.fromkeys([ParameterType_InputImage, ParameterType_ComplexInputImage, ParameterType_OutputImage, ParameterType_ComplexOutputImage], "image"),
+        **dict.fromkeys([ParameterType_InputVectorData, ParameterType_OutputVectorData], "vectorfile"),
+        ParameterType_Directory: "directory",
+        ParameterType_Choice: "choice",
+        ParameterType_InputImageList: "image1 image2...",
+        ParameterType_InputVectorDataList: "vectorfile1 vectorfile2...",
+        ParameterType_InputFilenameList: "filename1 filename2...",
+        **dict.fromkeys([ParameterType_InputProcessXML, ParameterType_OutputProcessXML], "filename.xml"),
+    }
+
+    if type in values:
+        return values[type]
+    else:
+        raise ValueError("Cannot show parameter value for type ", type)
+
+def rst_parameter_flags(app, key):
+    if app.IsMandatory(key) and not app.HasValue(key):
+        return "*Mandatory* "
+    elif app.HasValue(key) and app.GetParameterType(key) != ParameterType_Group:
+        return "*Default value: {}* ".format(app.GetParameterValue(key))
+    else:
+        return ""
+
+def detect_abuse(app):
+    "Detect choice parameter values which are also used as groups"
+
+    fake_groups = {}
+    keys = app.GetParametersKeys()
+
+    # For each choice parameter
+    for key in keys:
+        if app.GetParameterType(key) == ParameterType_Choice:
+
+            # Consider all its possible values
+            for choice_key in app.GetChoiceKeys(key):
+                fullkey = key + "." + choice_key
+
+                # See if that value is also used as a group anywhere in the application
+                for k in keys:
+                    if k.startswith(fullkey) and k != fullkey:
+
+                        # In that case, mark the first element of that group
+                        if fullkey not in fake_groups.values():
+                            fake_groups[k] = fullkey
+
+    return fake_groups
+
+def rst_parameters(app):
+    "Render application parameters to rst"
 
-def ApplicationToRst(appname):
     output = ""
-    app = None
-    try:
-        app = otbApplication.Registry.CreateApplication(appname)
-    except e:
-        print(e)
+
+    fake_markers = detect_abuse(app)
+
+    previous_level = 1
+    for key in app.GetParametersKeys():
+        type = app.GetParameterType(key)
+
+        # If reducing level not on a group parameter, render a horizontal line
+        current_level = 1 + key.count(".")
+        if current_level < previous_level and type != ParameterType_Group:
+            output += "\n\n------------\n\n"
+        previous_level = current_level
+
+        # Choice parameter values can act as groups
+        # Detect that case to add a section title
+        if key in fake_markers:
+            output += rst_section(app.GetParameterName(fake_markers[key]) + " options", "^")
+
+        if type == ParameterType_Group:
+            output += template_parameter_group.format(
+                name=rst_section(app.GetParameterName(key), "^"),
+                description=app.GetParameterDescription(key)
+            )
+
+        elif type == ParameterType_Choice:
+            output += render_choice(app, key)
+
+        else:
+            output += template_parameter.format(
+                name=app.GetParameterName(key),
+                key=key,
+                value=rst_parameter_value(app, key),
+                description=app.GetParameterDescription(key),
+                flags=rst_parameter_flags(app, key),
+            )
+
+    return output
+
+def render_example_cli(app, index):
+    "Render a command line example to rst (includes indentation)"
+
+    output = ""
+
+    # Render comment
+    if len(app.GetExampleComment(index)) > 0:
+        output += "    # " + app.GetExampleComment(index) + "\n"
+
+    output += "    otbcli_" + app.GetName()
+    for i in range(app.GetExampleNumberOfParameters(index)):
+        output += " -" + app.GetExampleParameterKey(index, i) + " " + app.GetExampleParameterValue(index, i)
+    output += "\n"
+    return output
+
+def render_all_examples_cli(app):
+    "Render all command line examples to rst"
+
+    if app.GetNumberOfExamples() == 0:
+        return "    # No example found"
+    if app.GetNumberOfExamples() == 1:
+        return render_example_cli(app, 0)
+    else:
+        output = ""
+        for i in range(app.GetNumberOfExamples()):
+            if i > 0:
+                output += "\n"
+            output += render_example_cli(app, i)
+        return output
+
+def render_all_examples_python(app):
+    "Render all python examples to rst"
+    output = ""
+    for i in range(app.GetNumberOfExamples()):
+        output += GetApplicationExamplePythonSnippet(app, i)
+    return output
+
+def render_limitations(app):
+    "Render app DocLimitations to rst"
+
+    limitations = app.GetDocLimitations()
+    if limitations is None or len(limitations) == 0 or limitations == "None":
+        return ""
+    else:
+        return rst_section("Limitations", "-") + limitations
+
+def render_see_also(app):
+    "Render app See Also to rst"
+
+    see_also = app.GetDocSeeAlso()
+    if see_also is None or len(see_also) < 2:
+        return ""
+    else:
+        return rst_section("See also", "-") + see_also
+
+def ApplicationToRst(appname):
+    app = otbApplication.Registry.CreateApplication(appname)
+
     # TODO: remove this when bug 440 is fixed
     app.Init()
-    output += RstHeading(app.GetName() + ' - ' + app.GetDocName(), '^')
-    output += app.GetDescription() + linesep * 2
-    output += RstHeading("Detailed description", '-')
-    output += app.GetDocLongDescription() + linesep * 2
-    limitations = app.GetDocLimitations()
-    output += RstHeading("Parameters", '-')
-    depth = GetParametersDepth(app.GetParametersKeys())
-    deep = depth > 0
-    output += ApplicationParametersToRstV2(app,app.GetParametersKeys(),deep) + linesep
-    if app.GetNumberOfExamples() > 1:
-        output += RstHeading("Examples", '-') + linesep
-        #output += appdetailslevel + "{Examples}" + "\\label{appexamples:" + appname + "}" + linesep
-        for i in range(0,app.GetNumberOfExamples()):
-            output += ":Example "+  str(i+1) + ':' + linesep + linesep
-#            output += RstHeading("Example "+  str(i+1) , '-')
-            output += app.GetExampleComment(i)
-            output+= "To run this example in command-line, use the following: " + linesep
-            output += linesep + GetApplicationExampleCommandLine(app,i)
-            output+= "To run this example from Python, use the following code snippet: " + linesep
-            output += GetApplicationExamplePython(app,i)
-    elif app.GetNumberOfExamples() == 1:
-        output += RstHeading("Example", '-')
-        if( len(app.GetExampleComment(0)) > 1):
-            output += app.GetExampleComment(0)
-        output+= "To run this example in command-line, use the following: " + linesep
-        output += GetApplicationExampleCommandLine(app,0)
-        output+= "To run this example from Python, use the following code snippet: " + linesep
-        output += GetApplicationExamplePython(app,0)
-
-    if len(limitations)>=2:
-        output += RstHeading("Limitations", '~')
-#        output += ":Limitations:" + linesep + linesep
-        output += ConvertString(app.GetDocLimitations()) + linesep + linesep
-
-    output += RstHeading("Authors", '~')
-#    output += ":Authors:" + linesep + linesep
-    output += "This application has been written by " + ConvertString(app.GetDocAuthors()) + "." + linesep + linesep
-    seealso = app.GetDocSeeAlso()
-    if len(seealso) >=2:
-        output += RstHeading("See Also", '~')
-#        output += ":See Also:" + linesep + linesep
-        output += "These additional resources can be useful for further information: " + linesep
-        # hlink="<http://www.readthedocs.org/" + ConvertString(app.GetDocSeeAlso()) + ".html>`_ "
-        # output += linesep + "`" + ConvertString(app.GetDocSeeAlso()) + " " + hlink + linesep + linesep
-        output += ConvertToLineBlock(app.GetDocSeeAlso()) + linesep + linesep
+
+    parameters = rst_parameters(app)
+
+    output = template_application.format(
+        heading=rst_section(app.GetName(), '='),
+        description=app.GetDescription(),
+        longdescription=app.GetDocLongDescription(),
+        parameters=parameters,
+        examples_cli=render_all_examples_cli(app),
+        examples_python=render_all_examples_python(app),
+        limitations=render_limitations(app),
+        see_also=render_see_also(app)
+    )
 
     return output
 
@@ -524,22 +373,19 @@ def GetApplicationTags(appname):
      app = otbApplication.Registry.CreateApplication(appname)
      return app.GetDocTags()
 
-import shutil
-
 def RstPageHeading(text, maxdepth, ref=None):
-    output = RstHeading(text, "=", ref=ref) + linesep
+    output = rst_section(text, "=", ref=ref)
     output += ".. toctree::" + linesep
     output += "\t:maxdepth: " + maxdepth + linesep
     output += linesep + linesep
     return output
 
-def GenerateRstForApplications():
+def GenerateRstForApplications(rst_dir):
     out = ""
     blackList = ["TestApplication", "Example", "ApplicationExample"]
     allApps = None
     try:
         allApps = otbApplication.Registry.GetAvailableApplications( )
-        print(allApps)
     except:
         print('error in otbApplication.Registry.GetAvailableApplications()')
         sys.exit(1)
@@ -551,10 +397,8 @@ def GenerateRstForApplications():
     writtenTags = []
     appNames = [app for app in allApps if app not in blackList]
 
-    print("All apps: %s" % (appNames,))
-
-    appIndexFile = open(RST_DIR + '/Applications.rst', 'w')
-    appIndexFile.write(RstPageHeading("Applications Reference Documentation", "2", ref="apprefdoc"))
+    appIndexFile = open(rst_dir + '/Applications.rst', 'w')
+    appIndexFile.write(RstPageHeading("Applications", "2", ref="apprefdoc"))
     for appName in appNames:
         tags = GetApplicationTags(appName)
 
@@ -575,7 +419,7 @@ def GenerateRstForApplications():
             appIndexFile.write('\tApplications/' + tag_ + '.rst' + linesep)
             writtenTags.append(tag_)
 
-        tagFileName = RST_DIR + '/Applications/'  + tag_ + '.rst'
+        tagFileName = rst_dir + '/Applications/'  + tag_ + '.rst'
         if os.path.isfile(tagFileName):
             tagFile = open(tagFileName, 'a')
             tagFile.write("\tapp_" + appName + linesep)
@@ -587,24 +431,24 @@ def GenerateRstForApplications():
             tagFile.close()
 
         print("Generating " + appName + ".rst" +  " on tag " + tag_)
-        appFile = open(RST_DIR + '/Applications/app_'  + appName + '.rst', 'w')
+        appFile = open(rst_dir + '/Applications/app_'  + appName + '.rst', 'w')
         out = ApplicationToRst(appName)
         appFile.write(out)
         appFile.close()
 
     return out
 
-
 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()
+    parser = argparse.ArgumentParser(usage="Export application(s) to rst file")
+    parser.add_argument("rst_dir", help="Directory where rst files are generated")
+    args = parser.parse_args()
 
-    RST_DIR = options.rstdir
+    # Load rst templates
+    template_application = open("templates/application.rst").read()
+    template_parameter = open("templates/parameter.rst").read()
+    template_parameter_group = open("templates/parameter_group.rst").read()
+    template_parameter_choice_entry = open("templates/parameter_choice_entry.rst").read()
+    template_parameter_choice = open("templates/parameter_choice.rst").read()
 
-    if not options.appname is None:
-        out = ApplicationToRst(options.appname)
-    else:
-        GenerateRstForApplications()
+
+    GenerateRstForApplications(args.rst_dir)
diff --git a/Documentation/Cookbook/_static/css/otb_theme.css b/Documentation/Cookbook/_static/css/otb_theme.css
new file mode 100644
index 0000000000..d9553257a4
--- /dev/null
+++ b/Documentation/Cookbook/_static/css/otb_theme.css
@@ -0,0 +1,10 @@
+.wy-nav-content {
+    max-width: 800px;
+}
+
+/* Reduce the effect of the p bottom margin before lists
+ * Very useful for choice parameters in app doc for example
+ */
+p + ul {
+    margin-top: -18px;
+}
diff --git a/Documentation/Cookbook/rst/Installation.rst b/Documentation/Cookbook/rst/Installation.rst
index 3c61ef0b18..d24b59a50f 100644
--- a/Documentation/Cookbook/rst/Installation.rst
+++ b/Documentation/Cookbook/rst/Installation.rst
@@ -24,7 +24,7 @@ Windows
 .. include:: Installation_Windows.rst
 
 Linux
-------------
+-----
 
 .. include:: Installation_Linux.rst
 
diff --git a/Documentation/Cookbook/rst/conf.py.in b/Documentation/Cookbook/rst/conf.py.in
index c9e101cb7a..661328eebb 100644
--- a/Documentation/Cookbook/rst/conf.py.in
+++ b/Documentation/Cookbook/rst/conf.py.in
@@ -21,6 +21,11 @@ import sphinx_rtd_theme
 # documentation root, use os.path.abspath to make it absolute, like shown here.
 #sys.path.insert(0, os.path.abspath('.'))
 
+# Customize read the docs theme a bit with a custom css
+# taken from https://stackoverflow.com/a/43186995/5815110
+def setup(app):
+    app.add_stylesheet("css/otb_theme.css")
+
 # -- General configuration ------------------------------------------------
 
 # If your documentation needs a minimal Sphinx version, state it here.
@@ -75,7 +80,7 @@ release = '@OTB_VERSION@'
 
 # List of patterns, relative to source directory, that match files and
 # directories to ignore when looking for source files.
-exclude_patterns = ['@RST_BUILD_DIR@']
+exclude_patterns = ['@RST_BUILD_DIR@', 'templates/*.rst']
 #exclude_patterns = ['_build']
 # The reST default role (used for this markup: `text`) to use for all
 # documents.
@@ -167,6 +172,16 @@ html_static_path = ['_static']
 # If true, the index is split into individual pages for each letter.
 #html_split_index = False
 
+html_context = {
+    'display_gitlab': True,
+    'gitlab_host': "gitlab.orfeo-toolbox.org",
+    'gitlab_user': 'orfeotoolbox',
+    'gitlab_repo': 'OTB',
+    'gitlab_version': 'develop',
+    'conf_py_path': '/Documentation/Cookbook/rst/',
+    #'source_url_prefix': "https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/tree/develop/Documentation/Cookbook/rst/",
+}
+
 # If true, links to the reST sources are added to the pages.
 html_show_sourcelink = True
 
diff --git a/Documentation/Cookbook/rst/templates/application.rst b/Documentation/Cookbook/rst/templates/application.rst
new file mode 100644
index 0000000000..e5d1081d05
--- /dev/null
+++ b/Documentation/Cookbook/rst/templates/application.rst
@@ -0,0 +1,41 @@
+{heading}
+{description}
+
+Description
+-----------
+
+{longdescription}
+
+Parameters
+----------
+
+.. contents:: :local:
+
+.. |br| raw:: html
+
+   <br />
+
+.. |em| raw:: html
+
+   &emsp;
+
+{parameters}
+
+Examples
+--------
+
+From the command-line:
+
+.. code-block:: bash
+
+{examples_cli}
+
+From Python:
+
+.. code-block:: python
+
+{examples_python}
+
+{limitations}
+
+{see_also}
diff --git a/Documentation/Cookbook/rst/templates/parameter.rst b/Documentation/Cookbook/rst/templates/parameter.rst
new file mode 100644
index 0000000000..2182bcf2bf
--- /dev/null
+++ b/Documentation/Cookbook/rst/templates/parameter.rst
@@ -0,0 +1,3 @@
+**{name}** :code:`-{key} {value}` {flags}|br|
+{description}
+
diff --git a/Documentation/Cookbook/rst/templates/parameter_choice.rst b/Documentation/Cookbook/rst/templates/parameter_choice.rst
new file mode 100644
index 0000000000..0add118a80
--- /dev/null
+++ b/Documentation/Cookbook/rst/templates/parameter_choice.rst
@@ -0,0 +1,5 @@
+**{name}** :code:`-{key} {value}` {flags}|br|
+{description}
+
+{choices}
+
diff --git a/Documentation/Cookbook/rst/templates/parameter_choice_entry.rst b/Documentation/Cookbook/rst/templates/parameter_choice_entry.rst
new file mode 100644
index 0000000000..e835a8c2d7
--- /dev/null
+++ b/Documentation/Cookbook/rst/templates/parameter_choice_entry.rst
@@ -0,0 +1,2 @@
+* **{name}** |br| {description}
+
diff --git a/Documentation/Cookbook/rst/templates/parameter_group.rst b/Documentation/Cookbook/rst/templates/parameter_group.rst
new file mode 100644
index 0000000000..0869424eb0
--- /dev/null
+++ b/Documentation/Cookbook/rst/templates/parameter_group.rst
@@ -0,0 +1,4 @@
+{name}
+
+{description}
+
diff --git a/Modules/Applications/AppClassification/app/otbFusionOfClassifications.cxx b/Modules/Applications/AppClassification/app/otbFusionOfClassifications.cxx
index 554edc2407..948b0f07a9 100644
--- a/Modules/Applications/AppClassification/app/otbFusionOfClassifications.cxx
+++ b/Modules/Applications/AppClassification/app/otbFusionOfClassifications.cxx
@@ -136,7 +136,7 @@ private:
     SetParameterDescription("method.dempstershafer","Fusion of classification maps by the Dempster Shafer combination method for each output pixel.");
 
     AddParameter(ParameterType_InputFilenameList, "method.dempstershafer.cmfl", "Confusion Matrices");
-    SetParameterDescription("method.dempstershafer.cmfl", "A list of confusion matrix files (*.CSV format) to define the masses of belief and the class labels. Each file should be formatted the following way: "
+    SetParameterDescription("method.dempstershafer.cmfl", "A list of confusion matrix files (.csv format) to define the masses of belief and the class labels. Each file should be formatted the following way: "
         "the first line, beginning with a '#' symbol, should be a list of the class labels present in the corresponding input classification image, organized in the same order as the confusion matrix rows/columns.");
 
     AddParameter(ParameterType_Choice, "method.dempstershafer.mob", "Mass of belief measurement");
diff --git a/Modules/Applications/AppClassification/app/otbImageClassifier.cxx b/Modules/Applications/AppClassification/app/otbImageClassifier.cxx
index 59f3cd2936..e05dcc1964 100644
--- a/Modules/Applications/AppClassification/app/otbImageClassifier.cxx
+++ b/Modules/Applications/AppClassification/app/otbImageClassifier.cxx
@@ -116,17 +116,16 @@ private:
     SetDefaultOutputPixelType( "out", ImagePixelType_uint8);
 
     AddParameter(ParameterType_OutputImage, "confmap",  "Confidence map");
-    SetParameterDescription( "confmap", "Confidence map of the produced classification. The confidence index depends on the model : \n"
-      "  - LibSVM : difference between the two highest probabilities (needs a model with probability estimates, so that classes probabilities can be computed for each sample)\n"
-      "  - OpenCV\n"
-      "    * Boost : sum of votes\n"
-      "    * DecisionTree : (not supported)\n"
-      "    * GradientBoostedTree : (not supported)\n"
-      "    * KNearestNeighbors : number of neighbors with the same label\n"
-      "    * NeuralNetwork : difference between the two highest responses\n"
-      "    * NormalBayes : (not supported)\n"
-      "    * RandomForest : Confidence (proportion of votes for the majority class). Margin (normalized difference of the votes of the 2 majority classes) is not available for now.\n"
-      "    * SVM : distance to margin (only works for 2-class models)\n");
+    SetParameterDescription( "confmap", "Confidence map of the produced classification. The confidence index depends on the model: \n\n"
+      "* LibSVM: difference between the two highest probabilities (needs a model with probability estimates, so that classes probabilities can be computed for each sample)\n"
+      "* Boost: sum of votes\n"
+      "* DecisionTree: (not supported)\n"
+      "* GradientBoostedTree: (not supported)\n"
+      "* KNearestNeighbors: number of neighbors with the same label\n"
+      "* NeuralNetwork: difference between the two highest responses\n"
+      "* NormalBayes: (not supported)\n"
+      "* RandomForest: Confidence (proportion of votes for the majority class). Margin (normalized difference of the votes of the 2 majority classes) is not available for now.\n"
+      "* SVM: distance to margin (only works for 2-class models)\n");
     SetDefaultOutputPixelType( "confmap", ImagePixelType_double);
     MandatoryOff("confmap");
 
diff --git a/Modules/Applications/AppClassification/app/otbTrainImagesClassifier.cxx b/Modules/Applications/AppClassification/app/otbTrainImagesClassifier.cxx
index c0a1a8935f..a7decdb4bf 100644
--- a/Modules/Applications/AppClassification/app/otbTrainImagesClassifier.cxx
+++ b/Modules/Applications/AppClassification/app/otbTrainImagesClassifier.cxx
@@ -43,18 +43,27 @@ public:
     // Documentation
     SetDocName( "Train a classifier from multiple images" );
     SetDocLongDescription(
-            "This application performs a classifier training from multiple pairs of input images and training vector data. "
-                    "Samples are composed of pixel values in each band optionally centered and reduced using an XML statistics file produced by "
-                    "the ComputeImagesStatistics application.\n The training vector data must contain polygons with a positive integer field "
-                    "representing the class label. The name of this field can be set using the \"Class label field\" parameter. Training and validation "
-                    "sample lists are built such that each class is equally represented in both lists. One parameter allows controlling the ratio "
-                    "between the number of samples in training and validation sets. Two parameters allow managing the size of the training and "
-                    "validation sets per class and per image.\n Several classifier parameters can be set depending on the chosen classifier. In the "
-                    "validation process, the confusion matrix is organized the following way: rows = reference labels, columns = produced labels. "
-                    "In the header of the optional confusion matrix output file, the validation (reference) and predicted (produced) class labels"
-                    " are ordered according to the rows/columns of the confusion matrix.\n This application is based on LibSVM, OpenCV Machine Learning "
-                    "(2.3.1 and later), and Shark ML. The output of this application is a text model file, whose format corresponds to the "
-                    "ML model type chosen. There is no image nor vector data output." );
+        "Train a classifier from multiple pairs of images and training vector data. "
+        "Samples are composed of pixel values in each band optionally centered and reduced using an XML statistics file produced by "
+        "the ComputeImagesStatistics application.\n\n"
+
+        "The training vector data must contain polygons with a positive integer field "
+        "representing the class label. The name of this field can be set using the *Class label field* parameter.\n\n"
+
+        "Training and validation sample lists are built such that each class is equally represented in both lists. One parameter allows controlling the ratio "
+        "between the number of samples in training and validation sets. Two parameters allow managing the size of the training and "
+        "validation sets per class and per image.\n\n"
+
+        "In the validation process, the confusion matrix is organized the following way:\n\n"
+        "* Rows: reference labels,\n"
+        "* Columns: produced labels.\n\n"
+
+        "In the header of the optional confusion matrix output file, the validation (reference) and predicted (produced) class labels"
+        " are ordered according to the rows/columns of the confusion matrix.\n\n"
+
+        "This application is based on LibSVM, OpenCV Machine Learning, and Shark ML. "
+        "The output of this application is a text model file, whose format corresponds to the "
+        "ML model type chosen. There is no image nor vector data output.");
     SetDocLimitations( "None" );
     SetDocAuthors( "OTB-Team" );
     SetDocSeeAlso( "OpenCV documentation for machine learning http://docs.opencv.org/modules/ml/doc/ml.html " );
diff --git a/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx b/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx
index 6f142bb04a..4ca8e9b031 100644
--- a/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx
+++ b/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx
@@ -67,7 +67,7 @@ protected:
       "Learning (2.3.1 and later), and Shark ML The output of this application "
       "is a text model file, whose format corresponds to the ML model type "
       "chosen. There is no image nor vector data output.");
-    SetDocLimitations( " " );
+    SetDocLimitations("");
     SetDocAuthors( "OTB Team" );
     SetDocSeeAlso( " " );
 
diff --git a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx
index abc87f0098..648b1d465f 100644
--- a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx
+++ b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx
@@ -131,20 +131,16 @@ private:
       "Put the same field names as the TrainVectorClassifier application.");
 
     AddParameter(ParameterType_Bool, "confmap",  "Confidence map");
-    SetParameterDescription( "confmap", "Confidence map of the produced classification. "
-      "The confidence index depends on the model : \n"
-      "  - LibSVM : difference between the two highest probabilities "
-           "(needs a model with probability estimates, so that classes probabilities can be computed for each sample)\n"
-      "  - OpenCV\n"
-      "    * Boost : sum of votes\n"
-      "    * DecisionTree : (not supported)\n"
-      "    * GradientBoostedTree : (not supported)\n"
-      "    * KNearestNeighbors : number of neighbors with the same label\n"
-      "    * NeuralNetwork : difference between the two highest responses\n"
-      "    * NormalBayes : (not supported)\n"
-      "    * RandomForest : Confidence (proportion of votes for the majority class). "
-             "Margin (normalized difference of the votes of the 2 majority classes) is not available for now.\n"
-      "    * SVM : distance to margin (only works for 2-class models).\n");
+    SetParameterDescription( "confmap", "Confidence map of the produced classification. The confidence index depends on the model: \n\n"
+      "* LibSVM: difference between the two highest probabilities (needs a model with probability estimates, so that classes probabilities can be computed for each sample)\n"
+      "* Boost: sum of votes\n"
+      "* DecisionTree: (not supported)\n"
+      "* GradientBoostedTree: (not supported)\n"
+      "* KNearestNeighbors: number of neighbors with the same label\n"
+      "* NeuralNetwork: difference between the two highest responses\n"
+      "* NormalBayes: (not supported)\n"
+      "* RandomForest: Confidence (proportion of votes for the majority class). Margin (normalized difference of the votes of the 2 majority classes) is not available for now.\n"
+      "* SVM: distance to margin (only works for 2-class models)\n");
 
     AddParameter(ParameterType_OutputFilename, "out", "Output vector data file containing class labels");
     SetParameterDescription("out","Output vector data file storing sample values (OGR format)."
diff --git a/Modules/Applications/AppClassification/include/otbTrainBoost.hxx b/Modules/Applications/AppClassification/include/otbTrainBoost.hxx
index 7ea1b673f9..575e004a95 100644
--- a/Modules/Applications/AppClassification/include/otbTrainBoost.hxx
+++ b/Modules/Applications/AppClassification/include/otbTrainBoost.hxx
@@ -34,8 +34,7 @@ namespace Wrapper
   ::InitBoostParams()
   {
     AddChoice("classifier.boost", "Boost classifier");
-    SetParameterDescription("classifier.boost", "This group of parameters allows setting Boost classifier parameters. "
-        "See complete documentation here \\url{http://docs.opencv.org/modules/ml/doc/boosting.html}.");
+    SetParameterDescription("classifier.boost", "http://docs.opencv.org/modules/ml/doc/boosting.html");
     //BoostType
     AddParameter(ParameterType_Choice, "classifier.boost.t", "Boost Type");
     AddChoice("classifier.boost.t.discrete", "Discrete AdaBoost");
diff --git a/Modules/Applications/AppClassification/include/otbTrainDecisionTree.hxx b/Modules/Applications/AppClassification/include/otbTrainDecisionTree.hxx
index 324bc7dd1d..74dafa3f6d 100644
--- a/Modules/Applications/AppClassification/include/otbTrainDecisionTree.hxx
+++ b/Modules/Applications/AppClassification/include/otbTrainDecisionTree.hxx
@@ -35,8 +35,7 @@ LearningApplicationBase<TInputValue,TOutputValue>
 {
   AddChoice("classifier.dt", "Decision Tree classifier");
   SetParameterDescription("classifier.dt",
-    "This group of parameters allows setting Decision Tree classifier parameters. "
-    "See complete documentation here \\url{http://docs.opencv.org/modules/ml/doc/decision_trees.html}.");
+    "http://docs.opencv.org/modules/ml/doc/decision_trees.html");
   //MaxDepth
   AddParameter(ParameterType_Int, "classifier.dt.max", "Maximum depth of the tree");
 #ifdef OTB_OPENCV_3
diff --git a/Modules/Applications/AppClassification/include/otbTrainGradientBoostedTree.hxx b/Modules/Applications/AppClassification/include/otbTrainGradientBoostedTree.hxx
index 719bf8b06e..500af6a4cb 100644
--- a/Modules/Applications/AppClassification/include/otbTrainGradientBoostedTree.hxx
+++ b/Modules/Applications/AppClassification/include/otbTrainGradientBoostedTree.hxx
@@ -38,8 +38,7 @@ LearningApplicationBase<TInputValue,TOutputValue>
   AddChoice("classifier.gbt", "Gradient Boosted Tree classifier");
   SetParameterDescription(
       "classifier.gbt",
-      "This group of parameters allows setting Gradient Boosted Tree classifier parameters. "
-      "See complete documentation here \\url{http://docs.opencv.org/modules/ml/doc/gradient_boosted_trees.html}.");
+      "http://docs.opencv.org/modules/ml/doc/gradient_boosted_trees.html");
 
   if (m_RegressionFlag)
     {
diff --git a/Modules/Applications/AppClassification/include/otbTrainKNN.hxx b/Modules/Applications/AppClassification/include/otbTrainKNN.hxx
index 74639e3a70..774253afec 100644
--- a/Modules/Applications/AppClassification/include/otbTrainKNN.hxx
+++ b/Modules/Applications/AppClassification/include/otbTrainKNN.hxx
@@ -34,8 +34,7 @@ namespace Wrapper
   ::InitKNNParams()
   {
     AddChoice("classifier.knn", "KNN classifier");
-    SetParameterDescription("classifier.knn", "This group of parameters allows setting KNN classifier parameters. "
-        "See complete documentation here \\url{http://docs.opencv.org/modules/ml/doc/k_nearest_neighbors.html}.");
+    SetParameterDescription("classifier.knn", "http://docs.opencv.org/modules/ml/doc/k_nearest_neighbors.html");
 
     //K parameter
     AddParameter(ParameterType_Int, "classifier.knn.k", "Number of Neighbors");
diff --git a/Modules/Applications/AppClassification/include/otbTrainNeuralNetwork.hxx b/Modules/Applications/AppClassification/include/otbTrainNeuralNetwork.hxx
index 72becd8d6b..3e6f722b8e 100644
--- a/Modules/Applications/AppClassification/include/otbTrainNeuralNetwork.hxx
+++ b/Modules/Applications/AppClassification/include/otbTrainNeuralNetwork.hxx
@@ -35,10 +35,7 @@ LearningApplicationBase<TInputValue,TOutputValue>
 ::InitNeuralNetworkParams()
 {
   AddChoice("classifier.ann", "Artificial Neural Network classifier");
-  SetParameterDescription("classifier.ann",
-    "This group of parameters allows setting Artificial Neural Network "
-    "classifier parameters. See complete documentation here "
-    "\\url{http://docs.opencv.org/modules/ml/doc/neural_networks.html}.");
+  SetParameterDescription("classifier.ann", "http://docs.opencv.org/modules/ml/doc/neural_networks.html");
 
   //TrainMethod
   AddParameter(ParameterType_Choice, "classifier.ann.t", "Train Method Type");
diff --git a/Modules/Applications/AppClassification/include/otbTrainNormalBayes.hxx b/Modules/Applications/AppClassification/include/otbTrainNormalBayes.hxx
index 59f882356f..b1086f997c 100644
--- a/Modules/Applications/AppClassification/include/otbTrainNormalBayes.hxx
+++ b/Modules/Applications/AppClassification/include/otbTrainNormalBayes.hxx
@@ -34,8 +34,7 @@ namespace Wrapper
   ::InitNormalBayesParams()
   {
     AddChoice("classifier.bayes", "Normal Bayes classifier");
-    SetParameterDescription("classifier.bayes", "Use a Normal Bayes Classifier. "
-        "See complete documentation here \\url{http://docs.opencv.org/modules/ml/doc/normal_bayes_classifier.html}.");
+    SetParameterDescription("classifier.bayes", "http://docs.opencv.org/modules/ml/doc/normal_bayes_classifier.html");
 
   }
 
diff --git a/Modules/Applications/AppClassification/include/otbTrainRandomForests.hxx b/Modules/Applications/AppClassification/include/otbTrainRandomForests.hxx
index 1751f92702..bca1e8e9d0 100644
--- a/Modules/Applications/AppClassification/include/otbTrainRandomForests.hxx
+++ b/Modules/Applications/AppClassification/include/otbTrainRandomForests.hxx
@@ -34,9 +34,7 @@ LearningApplicationBase<TInputValue,TOutputValue>
 ::InitRandomForestsParams()
 {
   AddChoice("classifier.rf", "Random forests classifier");
-  SetParameterDescription("classifier.rf",
-                          "This group of parameters allows setting Random Forests classifier parameters. "
-                          "See complete documentation here \\url{http://docs.opencv.org/modules/ml/doc/random_trees.html}.");
+  SetParameterDescription("classifier.rf", "http://docs.opencv.org/modules/ml/doc/random_trees.html");
   //MaxDepth
   AddParameter(ParameterType_Int, "classifier.rf.max", "Maximum depth of the tree");
   SetParameterInt("classifier.rf.max",5);
diff --git a/Modules/Applications/AppClassification/include/otbTrainSVM.hxx b/Modules/Applications/AppClassification/include/otbTrainSVM.hxx
index 1e3f47d30f..16b6343312 100644
--- a/Modules/Applications/AppClassification/include/otbTrainSVM.hxx
+++ b/Modules/Applications/AppClassification/include/otbTrainSVM.hxx
@@ -34,8 +34,7 @@ namespace Wrapper
   ::InitSVMParams()
   {
     AddChoice("classifier.svm", "SVM classifier (OpenCV)");
-    SetParameterDescription("classifier.svm", "This group of parameters allows setting SVM classifier parameters. "
-        "See complete documentation here \\url{http://docs.opencv.org/modules/ml/doc/support_vector_machines.html}.");
+    SetParameterDescription("classifier.svm", "http://docs.opencv.org/modules/ml/doc/support_vector_machines.html");
     AddParameter(ParameterType_Choice, "classifier.svm.m", "SVM Model Type");
     SetParameterDescription("classifier.svm.m", "Type of SVM formulation.");
     if (this->m_RegressionFlag)
diff --git a/Modules/Applications/AppClassification/include/otbTrainSharkKMeans.hxx b/Modules/Applications/AppClassification/include/otbTrainSharkKMeans.hxx
index f2008908f1..4c24dc1287 100644
--- a/Modules/Applications/AppClassification/include/otbTrainSharkKMeans.hxx
+++ b/Modules/Applications/AppClassification/include/otbTrainSharkKMeans.hxx
@@ -31,10 +31,7 @@ template<class TInputValue, class TOutputValue>
 void LearningApplicationBase<TInputValue, TOutputValue>::InitSharkKMeansParams()
 {
   AddChoice( "classifier.sharkkm", "Shark kmeans classifier" );
-  SetParameterDescription( "classifier.sharkkm",
-                           "This group of parameters allows setting Shark kMeans classifier parameters. "
-                                   "See complete documentation here "
-                                   "\\url{http://image.diku.dk/shark/sphinx_pages/build/html/rest_sources/tutorials/algorithms/kmeans.html}.\n " );
+  SetParameterDescription("classifier.sharkkm", "http://image.diku.dk/shark/sphinx_pages/build/html/rest_sources/tutorials/algorithms/kmeans.html ");
   //MaxNumberOfIterations
   AddParameter( ParameterType_Int, "classifier.sharkkm.maxiter",
                 "Maximum number of iteration for the kmeans algorithm." );
diff --git a/Modules/Applications/AppClassification/include/otbTrainSharkRandomForests.hxx b/Modules/Applications/AppClassification/include/otbTrainSharkRandomForests.hxx
index 3160740f3f..3559eeabc3 100644
--- a/Modules/Applications/AppClassification/include/otbTrainSharkRandomForests.hxx
+++ b/Modules/Applications/AppClassification/include/otbTrainSharkRandomForests.hxx
@@ -38,8 +38,7 @@ LearningApplicationBase<TInputValue,TOutputValue>
 
   AddChoice("classifier.sharkrf", "Shark Random forests classifier");
   SetParameterDescription("classifier.sharkrf",
-                          "This group of parameters allows setting Shark Random Forests classifier parameters. "
-                          "See complete documentation here \\url{http://image.diku.dk/shark/doxygen_pages/html/classshark_1_1_r_f_trainer.html}.\n It is noteworthy that training is parallel.");
+                          "http://image.diku.dk/shark/doxygen_pages/html/classshark_1_1_r_f_trainer.html.\n It is noteworthy that training is parallel.");
   //MaxNumberOfTrees
   AddParameter(ParameterType_Int, "classifier.sharkrf.nbtrees",
                "Maximum number of trees in the forest");
diff --git a/Modules/Applications/AppDimensionalityReduction/app/otbDimensionalityReduction.cxx b/Modules/Applications/AppDimensionalityReduction/app/otbDimensionalityReduction.cxx
index e14d7753b4..0d044a91e5 100644
--- a/Modules/Applications/AppDimensionalityReduction/app/otbDimensionalityReduction.cxx
+++ b/Modules/Applications/AppDimensionalityReduction/app/otbDimensionalityReduction.cxx
@@ -143,7 +143,7 @@ private:
     SetParameterDescription("method.maf", "Maximum Autocorrelation Factor.");
     AddChoice("method.ica", "ICA");
     SetParameterDescription("method.ica", "Independent Component Analysis.");
-    AddParameter(ParameterType_Int, "method.ica.iter", "number of iterations ");
+    AddParameter(ParameterType_Int, "method.ica.iter", "number of iterations");
     SetMinimumParameterIntValue("method.ica.iter", 1);
     SetDefaultParameterInt("method.ica.iter", 20);
     MandatoryOff("method.ica.iter");
diff --git a/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx b/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx
index dbaced29bc..d43d2753a4 100644
--- a/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx
+++ b/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx
@@ -122,8 +122,8 @@ private:
     AddParameter(ParameterType_OutputImage, "out", "Output Image");
     SetParameterDescription("out", "This parameter holds the output file name to"
       " which transformed image will be written. This has a slightly different"
-      " behaviour depending on transform type. \n For Wavelet, output is a"
-      " single band image for both forward and inverse transform. \n For FFT"
+      " behaviour depending on transform type. \nFor Wavelet, output is a"
+      " single band image for both forward and inverse transform. For FFT"
       " forward transform, output is two band image where first band represents"
       " real part and second band represents imaginary part of a complex image.");
 
diff --git a/Modules/Applications/AppFusion/app/otbPansharpening.cxx b/Modules/Applications/AppFusion/app/otbPansharpening.cxx
index fce89cc116..fda0827b4f 100644
--- a/Modules/Applications/AppFusion/app/otbPansharpening.cxx
+++ b/Modules/Applications/AppFusion/app/otbPansharpening.cxx
@@ -94,7 +94,7 @@ private:
     SetParameterDescription("inxs"," Input XS image.");
 
     AddParameter(ParameterType_OutputImage,  "out",   "Output image");
-    SetParameterDescription("out"," Output image.");
+    SetParameterDescription("out", "Output image.");
 
     AddParameter(ParameterType_Choice, "method", "Algorithm");
     SetParameterDescription("method", "Selection of the pan-sharpening method.");
diff --git a/Modules/Applications/AppImageUtils/app/otbColorMapping.cxx b/Modules/Applications/AppImageUtils/app/otbColorMapping.cxx
index aa7dc56e68..6312116552 100644
--- a/Modules/Applications/AppImageUtils/app/otbColorMapping.cxx
+++ b/Modules/Applications/AppImageUtils/app/otbColorMapping.cxx
@@ -251,21 +251,25 @@ private:
   void DoInit() override
   {
     SetName("ColorMapping");
-    SetDescription("Maps an input label image to 8-bits RGB using look-up tables.");
+    SetDescription("Map a label image to 8-bits RGB using look-up tables.");
 
     SetDocName("Color Mapping");
-    SetDocLongDescription("This application allows one to map a label image to a 8-bits RGB image (in both ways) using different methods.\n"
-                          " -The custom method allows one to use a custom look-up table. The look-up table is loaded "
-                          "from a text file where each line describes an entry. The typical use of this method is to colorise a "
-                          "classification map.\n -The continuous method allows mapping a range of values in a scalar input image "
-                          "to a colored image using continuous look-up table, in order to enhance image interpretation. Several "
-                          "look-up tables can been chosen with different color ranges.\n-The optimal method computes an optimal "
-                          "look-up table. When processing a segmentation label image (label to color), the color difference between"
-                          " adjacent segmented regions is maximized. When processing an unknown color image (color to label), all "
-                          "the present colors are mapped to a continuous label list.\n - The support image method uses a color support "
-                          "image to associate an average color to each region.");
+    SetDocLongDescription(
+        "Map a label image to a 8-bits RGB image (both ways) using different methods:\n\n"
+        " - **Custom**: use a custom look-up table. The look-up table is loaded "
+        "from a text file where each line describes an entry. The typical use of this method is to colorise a "
+        "classification map.\n"
+        " - **Continuous**: Map a range of values in a scalar input image "
+        "to a colored image using continuous look-up table, in order to enhance image interpretation. Several "
+        "look-up tables can been chosen with different color ranges.\n"
+        " - **Optimal**: Compute an optimal "
+        "look-up table. When processing a segmentation label image (label to color), the color difference between"
+        " adjacent segmented regions is maximized. When processing an unknown color image (color to label), all "
+        "the present colors are mapped to a continuous label list.\n"
+        " - **Support image**: Use a color support image to associate an average color to each region.");
+
     SetDocLimitations("The segmentation optimal method does not support streaming, and thus large images. The operation color to label "
-                      "is not implemented for the methods continuous LUT and support image LUT.\n ColorMapping using support image is not threaded.");
+                      "is not implemented for the methods continuous LUT and support image LUT.\n\nColorMapping using support image is not threaded.");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso("ImageSVMClassifier");
 
diff --git a/Modules/Applications/AppImageUtils/app/otbCompareImages.cxx b/Modules/Applications/AppImageUtils/app/otbCompareImages.cxx
index 643d643fdf..f2eb49f7af 100644
--- a/Modules/Applications/AppImageUtils/app/otbCompareImages.cxx
+++ b/Modules/Applications/AppImageUtils/app/otbCompareImages.cxx
@@ -56,7 +56,10 @@ private:
 
     // Documentation
     SetDocName("Images comparison");
-    SetDocLongDescription("This application computes MSE (Mean Squared Error), MAE (Mean Absolute Error) and PSNR (Peak Signal to Noise Ratio) between the channel of two images (reference and measurement). The user has to set the used channel and can specify a ROI.");
+    SetDocLongDescription(
+        "Compute MSE (Mean Squared Error), MAE (Mean Absolute Error) and PSNR (Peak Signal to Noise Ratio) between two image bands (reference and measurement). "
+        "The user has to set the used channel and can specify a ROI."
+    );
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso("BandMath application, ImageStatistics");
@@ -65,17 +68,17 @@ private:
 
     AddParameter(ParameterType_Group, "ref", "Reference image properties");
     AddParameter(ParameterType_InputImage,  "ref.in",   "Reference image");
-    SetParameterDescription("ref.in", "Image used as reference in the comparison");
+    SetParameterDescription("ref.in", "Image used as reference in the comparison.");
     AddParameter(ParameterType_Int,  "ref.channel",   "Reference image channel");
-    SetParameterDescription("ref.channel", "Used channel for the reference image");
+    SetParameterDescription("ref.channel", "Used channel for the reference image.");
     SetDefaultParameterInt("ref.channel", 1);
     SetMinimumParameterIntValue("ref.channel", 1);
 
     AddParameter(ParameterType_Group, "meas", "Measured image properties");
     AddParameter(ParameterType_InputImage,  "meas.in",   "Measured image");
-    SetParameterDescription("meas.in", "Image used as measured in the comparison");
+    SetParameterDescription("meas.in", "Image used as measured in the comparison.");
     AddParameter(ParameterType_Int,  "meas.channel",   "Measured image channel");
-    SetParameterDescription("meas.channel", "Used channel for the measured image");
+    SetParameterDescription("meas.channel", "Used channel for the measured image.");
     SetDefaultParameterInt("meas.channel", 1);
     SetMinimumParameterIntValue("meas.channel", 1);
 
@@ -102,19 +105,19 @@ private:
     SetParameterDescription("roi.sizey","Size along y in pixels.");
 
     AddParameter(ParameterType_Float, "mse",  "MSE");
-    SetParameterDescription("mse", "Mean Squared Error value");
+    SetParameterDescription("mse", "Mean Squared Error value.");
     SetParameterRole("mse", Role_Output );
 
     AddParameter(ParameterType_Float, "mae",  "MAE");
-    SetParameterDescription("mae", "Mean Absolute Error value");
+    SetParameterDescription("mae", "Mean Absolute Error value.");
     SetParameterRole("mae", Role_Output );
 
     AddParameter(ParameterType_Float, "psnr",  "PSNR");
-    SetParameterDescription("psnr", "Peak Signal to Noise Ratio value");
+    SetParameterDescription("psnr", "Peak Signal to Noise Ratio value.");
     SetParameterRole("psnr", Role_Output);
 
     AddParameter(ParameterType_Float, "count",  "count");
-    SetParameterDescription("count", "Nb of pixels which are different");
+    SetParameterDescription("count", "Nb of pixels which are different.");
     SetParameterRole("count", Role_Output);
 
     AddRAMParameter();
diff --git a/Modules/Applications/AppImageUtils/app/otbConcatenateImages.cxx b/Modules/Applications/AppImageUtils/app/otbConcatenateImages.cxx
index 0c9d52659c..eb9d312995 100644
--- a/Modules/Applications/AppImageUtils/app/otbConcatenateImages.cxx
+++ b/Modules/Applications/AppImageUtils/app/otbConcatenateImages.cxx
@@ -57,11 +57,11 @@ private:
   void DoInit() override
   {
     SetName("ConcatenateImages");
-    SetDescription("Concatenate a list of images of the same size into a single multi-channel one.");
+    SetDescription("Concatenate a list of images of the same size into a single multi-channel image.");
 
     // Documentation
     SetDocName("Images Concatenation");
-    SetDocLongDescription("This application performs images channels concatenation. "
+    SetDocLongDescription("Concatenate a list of images of the same size into a single multi-channel image. "
       "It reads the input image list (single or multi-channel) "
       "and generates a single multi-channel image. The channel order is the same as the list.");
     SetDocLimitations("All input images must have the same size.");
diff --git a/Modules/Applications/AppImageUtils/app/otbDynamicConvert.cxx b/Modules/Applications/AppImageUtils/app/otbDynamicConvert.cxx
index 35487cae38..8612c7c41e 100644
--- a/Modules/Applications/AppImageUtils/app/otbDynamicConvert.cxx
+++ b/Modules/Applications/AppImageUtils/app/otbDynamicConvert.cxx
@@ -93,18 +93,21 @@ private:
     SetDescription("Change the pixel type and rescale the image's dynamic");
 
     SetDocName("Dynamic Conversion");
-    SetDocLongDescription("This application performs an image pixel type "
+    SetDocLongDescription(
+      "This application performs an image pixel type "
       "conversion (short, ushort, uchar, int, uint, float and double types are "
       "handled). The output image is written in the specified format (ie. "
-      "that corresponds to the given extension).\n The conversion can include "
-      "a rescale of the data range, by default it's set between the 2nd to "
-      "the 98th percentile. The rescale can be linear or log2. \n The choice "
+      "that corresponds to the given extension).\n"
+      "The conversion can include a rescale of the data range, by default it's set between the 2nd to "
+      "the 98th percentile. The rescale can be linear or log2. \nThe choice "
       "of the output channels can be done with the extended filename, but "
       "less easy to handle. To do this, a 'channels' parameter allows you to "
       "select the desired bands at the output. There are 3 modes, the "
-      "available choices are: \n * grayscale :  to display mono image as "
-      "standard color image \n * rgb : select 3 bands in the input image "
-      "(multi-bands) \n * all : keep all bands.");
+      "available choices are: \n"
+      " * **All**: keep all bands.\n"
+      " * **Grayscale**: to display mono image as standard color image \n"
+      " * **RGB**: select 3 bands in the input image (multi-bands) \n"
+    );
     SetDocLimitations("The application does not support complex pixel types as output.");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso("Convert, Rescale");
diff --git a/Modules/Applications/AppImageUtils/app/otbQuicklook.cxx b/Modules/Applications/AppImageUtils/app/otbQuicklook.cxx
index f31b64075b..e285d8c96a 100644
--- a/Modules/Applications/AppImageUtils/app/otbQuicklook.cxx
+++ b/Modules/Applications/AppImageUtils/app/otbQuicklook.cxx
@@ -58,9 +58,9 @@ private:
     SetName("Quicklook");
     SetDescription("Generates a subsampled version of an image extract");
     SetDocName("Quick Look");
-    SetDocLongDescription("Generates a subsampled version of an extract of an image defined by ROIStart and ROISize.\n "
+    SetDocLongDescription("Generates a subsampled version of an extract of an image defined by ROIStart and ROISize.\n"
                           "This extract is subsampled using the ratio OR the output image Size.");
-    SetDocLimitations(" This application does not provide yet the optimal way to decode coarser level of resolution from JPEG2000 images (like in Monteverdi).\n"
+    SetDocLimitations("This application does not provide yet the optimal way to decode coarser level of resolution from JPEG2000 images (like in Monteverdi).\n"
                       "Trying to subsampled huge JPEG200 image with the application will lead to poor performances for now.");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso(" ");
@@ -100,12 +100,12 @@ private:
     MandatoryOff("sr");
 
     AddParameter(ParameterType_Int, "sx",  "Size X");
-    SetParameterDescription( "sx" , "quicklook size in x-direction (used if no sampling ration is given)" );
+    SetParameterDescription( "sx" , "quicklook size in x-direction (used if no sampling ratio is given)" );
     MandatoryOff("sx");
     DisableParameter("sx");
 
     AddParameter(ParameterType_Int, "sy",  "Size Y");
-    SetParameterDescription( "sy" , "quicklook size in y-direction (used if no sampling ration is given)" );
+    SetParameterDescription( "sy" , "quicklook size in y-direction (used if no sampling ratio is given)" );
     MandatoryOff("sy");
     DisableParameter("sy");
 
diff --git a/Modules/Applications/AppIndices/app/otbRadiometricIndices.cxx b/Modules/Applications/AppIndices/app/otbRadiometricIndices.cxx
index c9e5bdcb56..4b6bdffed5 100644
--- a/Modules/Applications/AppIndices/app/otbRadiometricIndices.cxx
+++ b/Modules/Applications/AppIndices/app/otbRadiometricIndices.cxx
@@ -178,27 +178,26 @@ private:
     //SetDefaultParameterInt("channels.rho1240", 1);
 
     AddParameter(ParameterType_ListView,  "list", "Available Radiometric Indices");
-    SetParameterDescription("list","List of available radiometric indices with their relevant channels in brackets:\n\
-        Vegetation:NDVI - Normalized difference vegetation index (Red, NIR)\n\
-        Vegetation:TNDVI - Transformed normalized difference vegetation index (Red, NIR)\n\
-        Vegetation:RVI - Ratio vegetation index (Red, NIR)\n\
-        Vegetation:SAVI - Soil adjusted vegetation index (Red, NIR)\n\
-        Vegetation:TSAVI - Transformed soil adjusted vegetation index (Red, NIR)\n\
-        Vegetation:MSAVI - Modified soil adjusted vegetation index (Red, NIR)\n\
-        Vegetation:MSAVI2 - Modified soil adjusted vegetation index 2 (Red, NIR)\n\
-        Vegetation:GEMI - Global environment monitoring index (Red, NIR)\n\
-        Vegetation:IPVI - Infrared percentage vegetation index (Red, NIR)\n\
-        \n\
-        Water:NDWI - Normalized difference water index (Gao 1996) (NIR, MIR)\n\
-        Water:NDWI2 - Normalized difference water index (Mc Feeters 1996) (Green, NIR)\n\
-        Water:MNDWI - Modified normalized difference water index (Xu 2006) (Green, MIR)\n\
-        Water:NDPI - Normalized difference pond index (Lacaux et al.) (MIR, Green)\n\
-        Water:NDTI - Normalized difference turbidity index (Lacaux et al.) (Red, Green)\n\
-        \n\
-        Soil:RI - Redness index (Red, Green)\n\
-        Soil:CI - Color index (Red, Green)\n\
-        Soil:BI - Brightness index (Red, Green)\n\
-        Soil:BI2 - Brightness index 2 (NIR, Red, Green)");
+    SetParameterDescription("list",
+        "List of available radiometric indices with their relevant channels in brackets:\n\n"
+        "* Vegetation:NDVI - Normalized difference vegetation index (Red, NIR)\n"
+        "* Vegetation:TNDVI - Transformed normalized difference vegetation index (Red, NIR)\n"
+        "* Vegetation:RVI - Ratio vegetation index (Red, NIR)\n"
+        "* Vegetation:SAVI - Soil adjusted vegetation index (Red, NIR)\n"
+        "* Vegetation:TSAVI - Transformed soil adjusted vegetation index (Red, NIR)\n"
+        "* Vegetation:MSAVI - Modified soil adjusted vegetation index (Red, NIR)\n"
+        "* Vegetation:MSAVI2 - Modified soil adjusted vegetation index 2 (Red, NIR)\n"
+        "* Vegetation:GEMI - Global environment monitoring index (Red, NIR)\n"
+        "* Vegetation:IPVI - Infrared percentage vegetation index (Red, NIR)\n"
+        "* Water:NDWI - Normalized difference water index (Gao 1996) (NIR, MIR)\n"
+        "* Water:NDWI2 - Normalized difference water index (Mc Feeters 1996) (Green, NIR)\n"
+        "* Water:MNDWI - Modified normalized difference water index (Xu 2006) (Green, MIR)\n"
+        "* Water:NDPI - Normalized difference pond index (Lacaux et al.) (MIR, Green)\n"
+        "* Water:NDTI - Normalized difference turbidity index (Lacaux et al.) (Red, Green)\n"
+        "* Soil:RI - Redness index (Red, Green)\n"
+        "* Soil:CI - Color index (Red, Green)\n"
+        "* Soil:BI - Brightness index (Red, Green)\n"
+        "* Soil:BI2 - Brightness index 2 (NIR, Red, Green)");
 
     // Doc example parameter settings
     SetDocExampleParameterValue("in", "qb_RoadExtract.tif");
diff --git a/Modules/Applications/AppMathParser/app/otbBandMath.cxx b/Modules/Applications/AppMathParser/app/otbBandMath.cxx
index 50fd803aa2..9d33383560 100644
--- a/Modules/Applications/AppMathParser/app/otbBandMath.cxx
+++ b/Modules/Applications/AppMathParser/app/otbBandMath.cxx
@@ -68,25 +68,25 @@ private:
       "This application performs a mathematical operation on several multi-band "
       "images and outputs the result into a monoband image. The given expression"
       " is computed at each pixel position. Evaluation of the "
-      "mathematical formula is done by the muParser libraries.\n\n"
+      "mathematical formula is done by the muParser library.\n\n"
 
       "The formula can be written using:\n\n"
       "  * numerical values ( 2.3, -5, 3.1e4, ...)\n"
-      "  * variables containing pixel values (e.g. : 'im2b3' is the pixel value"
+      "  * variables containing pixel values (e.g. : ``im2b3`` is the pixel value"
       " in 2nd image, 3rd band)\n"
       "  * binary operators:\n\n"
-      "    * '+' addition, '-' subtraction, '*' multiplication, '/' division\n"
-      "    * '^' raise x to the power of y\n"
-      "    * '<' less than, '>' greater than, '<=' less or equal, '>=' greater or equal\n"
-      "    * '==' equal, '!=' not equal\n"
+      "    * ``+`` addition, ``-`` subtraction, ``*`` multiplication, ``/`` division\n"
+      "    * ``^`` raise x to the power of y\n"
+      "    * ``<`` less than, ``>`` greater than, ``<=`` less or equal, ``>=`` greater or equal\n"
+      "    * ``==`` equal, ``!=`` not equal\n"
 #ifdef OTB_MUPARSER_HAS_CXX_LOGICAL_OPERATORS
-      "    * '||' logical or, '&&' logical and\n"
-      "  * if-then-else operator: '(condition ? value_true : value_false)'\n"
+      "    * ``||`` logical or, ``&&`` logical and\n"
+      "  * if-then-else operator: ``(condition ? value_true : value_false)``\n"
 #else
-      "    * 'or' logical or, 'and' logical and\n"
-      "  * if-then-else operator: 'if(condition;value_true;value_false)'\n"
+      "    * ``or`` logical or, ``and`` logical and\n"
+      "  * if-then-else operator: ``if(condition;value_true;value_false)``\n"
 #endif
-      "  * functions : exp(), log(), sin(), cos(), min(), max(), ...\n\n"
+      "  * functions : ``exp()``, ``log()``, ``sin()``, ``cos()``, ``min()``, ``max()``, ...\n\n"
 
       "The full list of features and operators is available on the muParser website [1]."
       );
@@ -96,17 +96,17 @@ private:
     SetDocSeeAlso("[1] http://beltoforion.de/article.php?a=muparser");
     AddDocTag(Tags::Manip);
 
-    AddParameter( ParameterType_InputImageList, "il", "Input image-list" );
+    AddParameter( ParameterType_InputImageList, "il", "Input image list" );
     SetParameterDescription(
       "il",
-      "Image-list of operands to the mathematical expression."
+      "Image list of operands to the mathematical expression."
     );
 
     AddParameter( ParameterType_OutputImage, "out", "Output Image" );
     SetParameterDescription(
       "out",
       "Output image which is the result of the mathematical expressions on input"
-      " image-list operands.");
+      " image list operands.");
 
     AddRAMParameter();
 
diff --git a/Modules/Applications/AppMathParserX/app/otbBandMathX.cxx b/Modules/Applications/AppMathParserX/app/otbBandMathX.cxx
index 7352a2d73c..e3639bfee1 100644
--- a/Modules/Applications/AppMathParserX/app/otbBandMathX.cxx
+++ b/Modules/Applications/AppMathParserX/app/otbBandMathX.cxx
@@ -67,7 +67,7 @@ private:
       "This application performs a mathematical operation on several multi-band "
       "images and outputs the result into an image (multi- or mono-band, as "
       "opposed to the BandMath OTB-application). The mathematical formula is "
-      "done by the muParserX libraries.\n\n"
+      "done by the muParserX library.\n\n"
 
       "The list of features and the syntax of muParserX is available at [1].\n\n"
 
@@ -84,25 +84,25 @@ private:
       "  * numerical values ( 2.3, -5, 3.1e4, ...)\n"
       "  * variables containing pixel values (please, note the indexing of "
       "inputs from 1 to N). Examples for the first input image:\n\n"
-      "    * 'im1' a pixel from 1st input, made of n components (n bands)\n"
-      "    * 'im1b2' the 2nd component of a pixel from 1st input (band index is 1-based)\n"
-      "    * 'im1b2N3x4' a 3x4 pixels 'N'eighbourhood of a pixel the 2nd "
+      "    * ``im1`` a pixel from 1st input, made of n components (n bands)\n"
+      "    * ``im1b2`` the 2nd component of a pixel from 1st input (band index is 1-based)\n"
+      "    * ``im1b2N3x4`` a 3x4 pixels Neighbourhood of a pixel the 2nd "
       "component of a pixel from the 1st input\n"
-      "    * 'im1PhyX' horizontal (X-axis) spacing of the 1st input.\n"
-      "    * 'im1PhyY' vertical spacing of the 1st input input.\n"
-      "    * 'im1b2Mean' mean of the 2nd component of the 1st input (global statistics)\n"
-      "    * 'im1b2Mini' minimum of the 2nd component of the 1st input (global statistics)\n"
-      "    * 'im1b2Maxi' maximum of the 2nd component of the 1st input (global statistics)\n"
-      "    * 'im1b2Sum' sum of the 2nd component of the 1st input (global statistics)\n"
-      "    * 'im1b2Var' variance of the 2nd component of the 1st input (global statistics)\n"
-      "    * 'idxX' and 'idxY' are the indices of the current pixel (generic variables)\n"
+      "    * ``im1PhyX`` horizontal (X-axis) spacing of the 1st input.\n"
+      "    * ``im1PhyY`` vertical spacing of the 1st input input.\n"
+      "    * ``im1b2Mean`` mean of the 2nd component of the 1st input (global statistics)\n"
+      "    * ``im1b2Mini`` minimum of the 2nd component of the 1st input (global statistics)\n"
+      "    * ``im1b2Maxi`` maximum of the 2nd component of the 1st input (global statistics)\n"
+      "    * ``im1b2Sum`` sum of the 2nd component of the 1st input (global statistics)\n"
+      "    * ``im1b2Var`` variance of the 2nd component of the 1st input (global statistics)\n"
+      "    * ``idxX`` and ``idxY`` are the indices of the current pixel (generic variables)\n"
       "  * binary operators:\n\n"
-      "    * '+' addition, '-' subtraction, '*' multiplication, '/' division\n"
-      "    * '^' raise x to the power of y\n"
-      "    * '<' less than, '>' greater than, '<=' less or equal, '>=' greater or equal\n"
-      "    * '==' equal, '!=' not equal\n"
-      "    * logical operators: 'or', 'and', 'xor'\n"
-      "  * if-then-else operator: '(condition ? value_true : value_false)'\n"
+      "    * ``+`` addition, ``-`` subtraction, ``*`` multiplication, ``/`` division\n"
+      "    * ``^`` raise x to the power of y\n"
+      "    * ``<`` less than, ``>`` greater than, ``<=`` less or equal, ``>=`` greater or equal\n"
+      "    * ``==`` equal, ``!=`` not equal\n"
+      "    * logical operators: ``or``, ``and``, ``xor``\n"
+      "  * if-then-else operator: ``(condition ? value_true : value_false)``\n"
       "  * functions : abs(), exp(), log(), sin(), cos(), min(), max(), ...\n\n"
 
       "Always keep in mind that this application only addresses mathematically "
@@ -114,15 +114,15 @@ private:
       "represented as a row vector.\n\n"
 
       "Example:\n"
-      "  im1 + im2\n"
+      "  ``im1 + im2``\n"
       "  represents the addition of pixels from the 1st and 2nd inputs. This "
       "expression is consistent only if both inputs have the same number of "
       "bands.\n\n"
 
-      "Please, note that it is also possible to use the following expressions"
+      "Please note that it is also possible to use the following expressions"
       " to obtain the same result:\n\n"
-      "  * im1b1 + im2b1\n"
-      "  * im1b2 + im2b2\n"
+      "  * ``im1b1 + im2b1``\n"
+      "  * ``im1b2 + im2b2``\n"
       "  * ...\n\n"
 
       "Nevertheless, the first expression is by far much pleaseant. We call "
@@ -134,15 +134,14 @@ private:
 
       "Another new feature is the possibility to perform operations that "
       "involve neighborhoods of pixels. Variables related to such neighborhoods "
-      "are always defined following the imIbJNKxP pattern, where:\n\n"
-      "  - I is an number identifying the image input (remember, input #0 = im1, "
+      "are always defined following the ``imIbJNKxP`` pattern, where:\n\n"
+      "  - ``I`` is an number identifying the image input (remember, input #0 = im1, "
       "and so on)\n"
-      "  - J is an number identifying the band (remember, first band is indexed by"
-      "1)\n"
-      "  - KxP are two numbers that represent the size of the neighborhood (first "
+      "  - ``J`` is an number identifying the band (remember, first band is indexed by 1)\n"
+      "  - ``KxP`` are two numbers that represent the size of the neighborhood (first "
       "one is related to the horizontal direction)\n\n"
 
-      "NB: All neighborhood are centered, thus K and P must be odd numbers.\n\n"
+      "NB: All neighborhood are centered, thus ``K`` and ``P`` must be odd numbers.\n\n"
 
       "Many operators come with this new functionality:\n\n"
       "  - dotpr\n"
@@ -153,7 +152,7 @@ private:
       "  - max\n"
       "  - etc.\n\n"
 
-      "For instance, if im1 represents the pixel of 3 bands image::\n\n"
+      "For instance, if ``im1`` represents the pixel of a 3 bands image::\n\n"
       "  im1 - mean( im1b1N5x5, im1b2N5x5, im1b3N5x5 )\n\n"
       "could represent a high pass filter (note that by implying three "
       "neighborhoods, the operator mean returns a row vector of three components"
@@ -163,14 +162,14 @@ private:
       "  - existing operators/functions from muParserX, that were not originally "
       "defined for vectors and matrices (e.g. cos, sin). These new "
       "operators/functions keep the original names to which we added the prefix "
-      "'v' for vector (vcos, vsin, etc.)\n"
-      "  - mult, div and pow operators, that perform element-wise multiplication, "
-      "division or exponentiation of vector/matrices (e.g. im1 div im2).\n"
-      "  - mlt, dv and pw operators, that perform multiplication, division or "
-      "exponentiation of vector/matrices by a scalar (e.g. im1 dv 2.0).\n"
-      "  - bands, which is a very useful operator. It allows selecting specific "
-      "bands from an image, and/or to rearrange them in a new vector (e.g."
-      "bands( im1, { 1, 2, 1, 1 } ) produces a vector of 4 components made of "
+      "``v`` for vector (``vcos``, ``vsin``, etc.)\n"
+      "  - ``mult``, ``div`` and ``pow`` operators, that perform element-wise multiplication, "
+      "division or exponentiation of vector/matrices (e.g. ``im1 div im2``).\n"
+      "  - ``mlt``, ``dv`` and ``pw`` operators, that perform multiplication, division or "
+      "exponentiation of vector/matrices by a scalar (e.g. ``im1 dv 2.0``).\n"
+      "  - ``bands``, which is a very useful operator. It allows selecting specific "
+      "bands from an image, or to rearrange them in a new vector (e.g."
+      "``bands( im1, { 1, 2, 1, 1 } )`` produces a vector of 4 components made of "
       "band 1, band 2, band 1 and band 1 values from the first input.\n\n"
       "Note that curly brackets must be used in order to select the desired band"
       "indices.\n\n"
@@ -178,7 +177,7 @@ private:
       "The application itself\n"
       "----------------------\n\n"
 
-      "The application can use an expression supplied with the 'exp' parameter."
+      "The application can use an expression supplied with the ``-exp`` parameter."
       " It can also use an input context file, that defines variables and "
       "expressions. An example of context file is given below::\n\n"
       "  #F expo 1.1\n"
@@ -191,24 +190,21 @@ private:
       "elements of a row must be separated by commas, and rows must be separated"
       " by semicolons. It is also possible to define expressions within the same"
       " txt file, with #E <expr> (see limitations, below).\n"
-
-      "Finally, we strongly recommend to read the OTB Cookbook which can be "
-      "found at: http://www.orfeo-toolbox.org/packages/OTBCookBook.pdf"
     );
 
     SetDocLimitations(
       "The application is currently unable to produce one output image per "
-      "expression, contrary to otbBandMathXImageFilter.\n\n"
-      "Separating expressions by semi-colons ';' will concatenate their results "
+      "expression, contrary to otbBandMathXImageFilter. "
+      "Separating expressions by semicolons ``;`` will concatenate their results "
       "into a unique multiband output image."
     );
     SetDocAuthors( "OTB-Team" );
-    SetDocSeeAlso("[1] http://articles.beltoforion.de/article.php?a=muparserx\n"
+    SetDocSeeAlso("[1] http://articles.beltoforion.de/article.php?a=muparserx\n\n"
       "[2] BandMath");
     AddDocTag(Tags::Manip);
 
-    AddParameter( ParameterType_InputImageList, "il", "Input image-list" );
-    SetParameterDescription( "il", "Image-list to perform computation on." );
+    AddParameter( ParameterType_InputImageList, "il", "Input image list" );
+    SetParameterDescription( "il", "Image list to perform computation on." );
 
     AddParameter( ParameterType_OutputImage, "out", "Output Image" );
     SetParameterDescription( "out", "Output image." );
diff --git a/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx b/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx
index f11d6384eb..2344e7b004 100644
--- a/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx
+++ b/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx
@@ -197,32 +197,32 @@ private:
     "For instance, it is possible to get the coherency matrix from the Sinclar one, or the Mueller matrix from the coherency one.\n"
     "The filters used in this application never handle matrices, but images where each band is related to their elements.\n"
     "As most of the time SAR polarimetry handles symmetric/hermitian matrices, only the relevant elements are stored, so that the images representing them have a minimal number of bands.\n"
-    "For instance, the coherency matrix size is 3x3 in the monostatic case, and 4x4 in the bistatic case : it will thus be stored in a 6-band or a 10-band complex image (the diagonal and the upper elements of the matrix).\n"
+    "For instance, the coherency matrix size is 3x3 in the monostatic case, and 4x4 in the bistatic case: it will thus be stored in a 6-band or a 10-band complex image (the diagonal and the upper elements of the matrix).\n"
     "\n"
-    "The Sinclair matrix is a special case : it is always represented as 3 or 4 one-band complex images (for mono- or bistatic case).\n"
+    "The Sinclair matrix is a special case: it is always represented as 3 or 4 one-band complex images (for mono- or bistatic case).\n"
     "The available conversions are listed below:\n"
     
 	"\n--- Monostatic case ---\n" 
     
-    "1 msinclairtocoherency --> Sinclair matrix to coherency matrix (input : 3 x 1 complex channel (HH, HV or VH, VV) | output :  6 complex channels)\n"
-    "2 msinclairtocovariance --> Sinclair matrix to covariance matrix (input : 3 x 1 complex channel (HH, HV or VH, VV) | output :  6 complex channels)\n"
-    "3 msinclairtocircovariance --> Sinclair matrix to circular covariance matrix (input : 3 x 1 complex channel (HH, HV or VH, VV) | output :  6 complex channels)\n"
-    "4 mcoherencytomueller --> Coherency matrix to Mueller matrix (input : 6 complex channels | 16 real channels)\n"
-    "5 mcovariancetocoherencydegree --> Covariance matrix to coherency degree (input : 6 complex channels | 3 complex channels)\n"
-    "6 mcovariancetocoherency --> Covariance matrix to coherency matrix (input : 6 complex channels | 6 complex channels)\n"
-    "7 mlinearcovariancetocircularcovariance --> Covariance matrix to circular covariance matrix (input : 6 complex channels | output : 6 complex channels)\n"
+    "1 msinclairtocoherency --> Sinclair matrix to coherency matrix (input: 3 x 1 complex channel (HH, HV or VH, VV) | output:  6 complex channels)\n"
+    "2 msinclairtocovariance --> Sinclair matrix to covariance matrix (input: 3 x 1 complex channel (HH, HV or VH, VV) | output:  6 complex channels)\n"
+    "3 msinclairtocircovariance --> Sinclair matrix to circular covariance matrix (input: 3 x 1 complex channel (HH, HV or VH, VV) | output:  6 complex channels)\n"
+    "4 mcoherencytomueller --> Coherency matrix to Mueller matrix (input: 6 complex channels | 16 real channels)\n"
+    "5 mcovariancetocoherencydegree --> Covariance matrix to coherency degree (input: 6 complex channels | 3 complex channels)\n"
+    "6 mcovariancetocoherency --> Covariance matrix to coherency matrix (input: 6 complex channels | 6 complex channels)\n"
+    "7 mlinearcovariancetocircularcovariance --> Covariance matrix to circular covariance matrix (input: 6 complex channels | output: 6 complex channels)\n"
     
     "\n--- Bistatic case ---\n"
     
-    "8 bsinclairtocoherency --> Sinclair matrix to coherency matrix (input : 4 x 1 complex channel (HH, HV, VH, VV) | 10 complex channels)\n"
-    "9 bsinclairtocovariance --> Sinclair matrix to covariance matrix (input : 4 x 1 complex channel (HH, HV, VH, VV) | output : 10 complex channels)\n"
-    "10 bsinclairtocircovariance --> Sinclair matrix to circular covariance matrix (input : 4 x 1 complex channel (HH, HV, VH, VV) | output : 10 complex channels)\n"
+    "8 bsinclairtocoherency --> Sinclair matrix to coherency matrix (input: 4 x 1 complex channel (HH, HV, VH, VV) | 10 complex channels)\n"
+    "9 bsinclairtocovariance --> Sinclair matrix to covariance matrix (input: 4 x 1 complex channel (HH, HV, VH, VV) | output: 10 complex channels)\n"
+    "10 bsinclairtocircovariance --> Sinclair matrix to circular covariance matrix (input: 4 x 1 complex channel (HH, HV, VH, VV) | output: 10 complex channels)\n"
     
     "\n--- Both cases ---\n"
     
-    "11 sinclairtomueller --> Sinclair matrix to Mueller matrix (input : 4 x 1 complex channel (HH, HV, VH, VV) | output : 16 real channels)\n"
-    "12 muellertomcovariance --> Mueller matrix to covariance matrix (input : 16 real channels | output : 6 complex channels)\n"
-    "13 muellertopoldegandpower --> Mueller matrix to polarization degree and power (input : 16 real channels | output : 4 real channels)"
+    "11 sinclairtomueller --> Sinclair matrix to Mueller matrix (input: 4 x 1 complex channel (HH, HV, VH, VV) | output: 16 real channels)\n"
+    "12 muellertomcovariance --> Mueller matrix to covariance matrix (input: 16 real channels | output: 6 complex channels)\n"
+    "13 muellertopoldegandpower --> Mueller matrix to polarization degree and power (input: 16 real channels | output: 4 real channels)"
 
  );
 						  
@@ -233,28 +233,28 @@ private:
     AddDocTag(Tags::SAR);
 
     AddParameter(ParameterType_InputImage, "inc", "Input: multi-band complex image");
-    SetParameterDescription("inc", "Input : multi-band complex image");
+    SetParameterDescription("inc", "Input: multi-band complex image");
     MandatoryOff("inc");
 
     AddParameter(ParameterType_InputImage, "inf", "Input: multi-band real image");
-    SetParameterDescription("inf", "Input : multi-band real image");
+    SetParameterDescription("inf", "Input: multi-band real image");
     MandatoryOff("inf");
 
 
     AddParameter(ParameterType_InputImage, "inhh", "Input: one-band complex image (HH)");
-    SetParameterDescription("inhh", "Input : one-band complex image (HH)");
+    SetParameterDescription("inhh", "Input: one-band complex image (HH)");
     MandatoryOff("inhh");
 
     AddParameter(ParameterType_InputImage, "inhv", "Input: one-band complex image (HV)");
-    SetParameterDescription("inhv", "Input : one-band complex image (HV)");
+    SetParameterDescription("inhv", "Input: one-band complex image (HV)");
     MandatoryOff("inhv");
 
     AddParameter(ParameterType_InputImage, "invh", "Input: one-band complex image (VH)");
-    SetParameterDescription("invh", "Input : one-band complex image (VH)");
+    SetParameterDescription("invh", "Input: one-band complex image (VH)");
     MandatoryOff("invh");
 
     AddParameter(ParameterType_InputImage, "invv", "Input: one-band complex image (VV)");
-    SetParameterDescription("invv", "Input : one-band complex image (VV)");
+    SetParameterDescription("invv", "Input: one-band complex image (VV)");
     MandatoryOff("invv");
     
     AddParameter(ParameterType_OutputImage, "outc",  "Output Complex Image");
@@ -273,73 +273,73 @@ private:
     
     // #1
     // SinclairToReciprocalCoherency
-    AddChoice("conv.msinclairtocoherency","1 Monostatic : Sinclair matrix to coherency matrix (complex output)");
-    SetParameterDescription("conv.msinclairtocoherency","1 Monostatic :Sinclair matrix to coherency matrix (complex output)");
+    AddChoice("conv.msinclairtocoherency","1 Monostatic: Sinclair matrix to coherency matrix (complex output)");
+    SetParameterDescription("conv.msinclairtocoherency","1 Monostatic: Sinclair matrix to coherency matrix (complex output)");
     
     // #2
     // SinclairToReciprocalCovariance
-    AddChoice("conv.msinclairtocovariance","2 Monostatic : Sinclair matrix to covariance matrix (complex output)");
-    SetParameterDescription("conv.msinclairtocovariance","2 Monostatic : Sinclair matrix to covariance matrix (complex output)");
+    AddChoice("conv.msinclairtocovariance","2 Monostatic: Sinclair matrix to covariance matrix (complex output)");
+    SetParameterDescription("conv.msinclairtocovariance","2 Monostatic: Sinclair matrix to covariance matrix (complex output)");
     
     // #3 
     // SinclairToReciprocalCircularCovariance
-    AddChoice("conv.msinclairtocircovariance","3 Monostatic : Sinclair matrix to circular covariance matrix (complex output)");
-    SetParameterDescription("conv.msinclairtocircovariance","3 Monostatic : Sinclair matrix to circular covariance matrix (complex output)");
+    AddChoice("conv.msinclairtocircovariance","3 Monostatic: Sinclair matrix to circular covariance matrix (complex output)");
+    SetParameterDescription("conv.msinclairtocircovariance","3 Monostatic: Sinclair matrix to circular covariance matrix (complex output)");
     
     // #4 
     // ReciprocalCoherencyToReciprocalMuellerImageFilter
-    AddChoice("conv.mcoherencytomueller","4 Monostatic : Coherency matrix to Mueller matrix"); 
-    SetParameterDescription("conv.mcoherencytomueller","4 Monostatic : Coherency matrix to Mueller matrix"); 
+    AddChoice("conv.mcoherencytomueller","4 Monostatic: Coherency matrix to Mueller matrix"); 
+    SetParameterDescription("conv.mcoherencytomueller","4 Monostatic: Coherency matrix to Mueller matrix"); 
     
     // #5
     // ReciprocalCovarianceToCoherencyDegreeImageFilter 
-    AddChoice("conv.mcovariancetocoherencydegree","5 Monostatic : Covariance matrix to coherency degree "); 
-    SetParameterDescription("conv.mcovariancetocoherencydegree","5 Monostatic : Covariance matrix to coherency degree "); 
+    AddChoice("conv.mcovariancetocoherencydegree","5 Monostatic: Covariance matrix to coherency degree"); 
+    SetParameterDescription("conv.mcovariancetocoherencydegree","5 Monostatic: Covariance matrix to coherency degree "); 
     
     // #6
     // ReciprocalCovarianceToReciprocalCoherencyImageFilter
-    AddChoice("conv.mcovariancetocoherency","6 Monostatic : Covariance matrix to coherency matrix (complex output)"); 
-    SetParameterDescription("conv.mcovariancetocoherency","6 Monostatic : Covariance matrix to coherency matrix (complex output)");  
+    AddChoice("conv.mcovariancetocoherency","6 Monostatic: Covariance matrix to coherency matrix (complex output)"); 
+    SetParameterDescription("conv.mcovariancetocoherency","6 Monostatic: Covariance matrix to coherency matrix (complex output)");  
     
     // #7
     // ReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter
-    AddChoice("conv.mlinearcovariancetocircularcovariance","7 Monostatic : Covariance matrix to circular covariance matrix (complex output)"); 
-    SetParameterDescription("conv.mlinearcovariancetocircularcovariance","7 Monostatic : Covariance matrix to circular covariance matrix (complex output)");  
+    AddChoice("conv.mlinearcovariancetocircularcovariance","7 Monostatic: Covariance matrix to circular covariance matrix (complex output)"); 
+    SetParameterDescription("conv.mlinearcovariancetocircularcovariance","7 Monostatic: Covariance matrix to circular covariance matrix (complex output)");  
     
     // #8
     // MuellerToReciprocalCovarianceImageFilter 
-    AddChoice("conv.muellertomcovariance","8 Bi/mono : Mueller matrix to monostatic covariance matrix");
-    SetParameterDescription("conv.muellertomcovariance","8 Bi/mono : Mueller matrix to monostatic covariance matrix");
+    AddChoice("conv.muellertomcovariance","8 Bi/mono: Mueller matrix to monostatic covariance matrix");
+    SetParameterDescription("conv.muellertomcovariance","8 Bi/mono: Mueller matrix to monostatic covariance matrix");
     
     //Bistatic case
     
     // #9
     // SinclairToCoherency
-    AddChoice("conv.bsinclairtocoherency","9 Bistatic : Sinclair matrix to coherency matrix (complex output)");
-    SetParameterDescription("conv.bsinclairtocoherency","9 Bistatic : Sinclair matrix to coherency matrix (complex output)");
+    AddChoice("conv.bsinclairtocoherency","9 Bistatic: Sinclair matrix to coherency matrix (complex output)");
+    SetParameterDescription("conv.bsinclairtocoherency","9 Bistatic: Sinclair matrix to coherency matrix (complex output)");
     
     // #10
     // SinclairToCovariance  
-    AddChoice("conv.bsinclairtocovariance","10 Bistatic : Sinclair matrix to covariance matrix (complex output)");
-    SetParameterDescription("conv.bsinclairtocovariance","10 Bistatic : Sinclair matrix to covariance matrix (complex output)");
+    AddChoice("conv.bsinclairtocovariance","10 Bistatic: Sinclair matrix to covariance matrix (complex output)");
+    SetParameterDescription("conv.bsinclairtocovariance","10 Bistatic: Sinclair matrix to covariance matrix (complex output)");
     
     // #11
     // SinclairToCircularCovariance 
-    AddChoice("conv.bsinclairtocircovariance","11 Bistatic : Sinclair matrix to circular covariance matrix (complex output)");
-    SetParameterDescription("conv.bsinclairtocircovariance","11 Bistatic : Sinclair matrix to circular covariance matrix (complex output)");
+    AddChoice("conv.bsinclairtocircovariance","11 Bistatic: Sinclair matrix to circular covariance matrix (complex output)");
+    SetParameterDescription("conv.bsinclairtocircovariance","11 Bistatic: Sinclair matrix to circular covariance matrix (complex output)");
     
     //Both case
     
     // #12
     // SinclairToMueller
-    AddChoice("conv.sinclairtomueller","12 Bi/mono : Sinclair matrix to Mueller matrix");
-    SetParameterDescription("conv.sinclairtomueller","12 Bi/mono : Sinclair matrix to Mueller matrix");
+    AddChoice("conv.sinclairtomueller","12 Bi/mono: Sinclair matrix to Mueller matrix");
+    SetParameterDescription("conv.sinclairtomueller","12 Bi/mono: Sinclair matrix to Mueller matrix");
     
     
     // #13
     // MuellerToPolarisationDegreeAndPowerImageFilter
-    AddChoice("conv.muellertopoldegandpower","13 Bi/mono : Mueller matrix to polarisation degree and power");
-    SetParameterDescription("conv.muellertopoldegandpower","13 Bi/mono : Mueller matrix to polarisation degree and power");
+    AddChoice("conv.muellertopoldegandpower","13 Bi/mono: Mueller matrix to polarisation degree and power");
+    SetParameterDescription("conv.muellertopoldegandpower","13 Bi/mono: Mueller matrix to polarisation degree and power");
 
     AddRAMParameter();
 
@@ -509,7 +509,7 @@ private:
 		m_RCohSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
 		m_RCohSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
 		
-		SetParameterOutputImage("outc", m_RCohSRFilter->GetOutput() ); // input : 3 x 1 complex channel | output :  6 complex channels
+		SetParameterOutputImage("outc", m_RCohSRFilter->GetOutput() ); // input: 3 x 1 complex channel | output:  6 complex channels
 		
 		break;
 
@@ -526,7 +526,7 @@ private:
 		m_RCovSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
 		m_RCovSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
 		
-		SetParameterOutputImage("outc", m_RCovSRFilter->GetOutput() ); // input : 3 x 1 complex channel | output :  6 complex channels
+		SetParameterOutputImage("outc", m_RCovSRFilter->GetOutput() ); // input: 3 x 1 complex channel | output:  6 complex channels
 		
 		break;
 		
@@ -544,7 +544,7 @@ private:
 		m_RCCSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
 		m_RCCSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
 		
-		SetParameterOutputImage("outc", m_RCCSRFilter->GetOutput() ); // input : 3 x 1 complex channel | output :  6 complex channels
+		SetParameterOutputImage("outc", m_RCCSRFilter->GetOutput() ); // input: 3 x 1 complex channel | output:  6 complex channels
 		
 		break;
 		
@@ -554,7 +554,7 @@ private:
 		m_RCRMFilter = RCRMFilterType::New();
 		m_RCRMFilter->SetInput(GetParameterComplexDoubleVectorImage("inc"));
 		
-		SetParameterOutputImage("outf", m_RCRMFilter->GetOutput() ); // input : 6 complex channels | 16 real channels
+		SetParameterOutputImage("outf", m_RCRMFilter->GetOutput() ); // input: 6 complex channels | 16 real channels
 		
 		break;
 		
@@ -565,7 +565,7 @@ private:
 		m_RCCDFilter = RCCDFilterType::New();
 		m_RCCDFilter->SetInput(GetParameterComplexDoubleVectorImage("inc"));
 		
-		SetParameterOutputImage("outc", m_RCCDFilter->GetOutput() ); // input : 6 complex channels | 3 complex channels
+		SetParameterOutputImage("outc", m_RCCDFilter->GetOutput() ); // input: 6 complex channels | 3 complex channels
 		
 		break;
 
@@ -575,7 +575,7 @@ private:
 		m_RCRCFilter = RCRCFilterType::New();
 		m_RCRCFilter->SetInput(GetParameterComplexDoubleVectorImage("inc"));
 		
-		SetParameterOutputImage("outc", m_RCRCFilter->GetOutput() ); // input : 6 complex channels | 6 complex channels
+		SetParameterOutputImage("outc", m_RCRCFilter->GetOutput() ); // input: 6 complex channels | 6 complex channels
 		
 		break;
 		
@@ -586,7 +586,7 @@ private:
 		m_RLCRCCFilter = RLCRCCFilterType::New();
 		m_RLCRCCFilter->SetInput(GetParameterComplexDoubleVectorImage("inc"));
 		
-		SetParameterOutputImage("outc", m_RLCRCCFilter->GetOutput() ); // input : 6 complex channels | output : 6 complex channels
+		SetParameterOutputImage("outc", m_RLCRCCFilter->GetOutput() ); // input: 6 complex channels | output: 6 complex channels
 		
 		break;
 		
@@ -597,7 +597,7 @@ private:
 		
 		m_MRCFilter->SetInput(GetParameterDoubleVectorImage("inf"));
 		
-		SetParameterOutputImage("outc", m_MRCFilter->GetOutput() ); // input : 16 real channels | output : 6 complex channels
+		SetParameterOutputImage("outc", m_MRCFilter->GetOutput() ); // input: 16 real channels | output: 6 complex channels
 		
 		break;
 		
@@ -615,7 +615,7 @@ private:
 		m_CohSRFilter->SetInputVH(GetParameterComplexDoubleImage("invh"));
 		m_CohSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
 		
-		SetParameterOutputImage("outc", m_CohSRFilter->GetOutput() ); // input : 4 x 1 complex channel | 10 complex channels
+		SetParameterOutputImage("outc", m_CohSRFilter->GetOutput() ); // input: 4 x 1 complex channel | 10 complex channels
 		
 		break;
 		
@@ -630,7 +630,7 @@ private:
 		m_CovSRFilter->SetInputVH(GetParameterComplexDoubleImage("invh"));
 		m_CovSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
 		
-		SetParameterOutputImage("outc", m_CovSRFilter->GetOutput() ); // input : 4 x 1 complex channel | output : 10 complex channels
+		SetParameterOutputImage("outc", m_CovSRFilter->GetOutput() ); // input: 4 x 1 complex channel | output: 10 complex channels
 		
 		break;
 		
@@ -644,7 +644,7 @@ private:
 		m_CCSRFilter->SetInputVH(GetParameterComplexDoubleImage("invh"));
 		m_CCSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
 		
-		SetParameterOutputImage("outc", m_CCSRFilter->GetOutput() ); // input : 4 x 1 complex channel | output : 10 complex channels
+		SetParameterOutputImage("outc", m_CCSRFilter->GetOutput() ); // input: 4 x 1 complex channel | output: 10 complex channels
 		
 		break;
 		
@@ -662,7 +662,7 @@ private:
 		m_MSRFilter->SetInputVH(GetParameterComplexDoubleImage("invh"));
 		m_MSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
 		
-		SetParameterOutputImage("outf", m_MSRFilter->GetOutput() ); // input : 4 x 1 complex channel | output : 16 real channels
+		SetParameterOutputImage("outf", m_MSRFilter->GetOutput() ); // input: 4 x 1 complex channel | output: 16 real channels
 		
 		break;
 		
@@ -672,7 +672,7 @@ private:
 		
 		m_MPDPFilter->SetInput(GetParameterDoubleVectorImage("inf"));
 		
-		SetParameterOutputImage("outf", m_MPDPFilter->GetOutput() ); //  input : 16 real channels | output : 4 real channels
+		SetParameterOutputImage("outf", m_MPDPFilter->GetOutput() ); //  input: 16 real channels | output: 4 real channels
 		
 		break;
 		
diff --git a/Modules/Applications/AppStereo/app/otbStereoFramework.cxx b/Modules/Applications/AppStereo/app/otbStereoFramework.cxx
index 791d5a223e..3bf5fcab98 100644
--- a/Modules/Applications/AppStereo/app/otbStereoFramework.cxx
+++ b/Modules/Applications/AppStereo/app/otbStereoFramework.cxx
@@ -422,32 +422,32 @@ private:
     AddChoice("output.mode.user", "User Defined");
     SetParameterDescription("output.mode.user","This mode allows you to fully modify default values.");
     // Upper left point coordinates
-    AddParameter(ParameterType_Float, "output.mode.user.ulx", "Upper Left X ");
+    AddParameter(ParameterType_Float, "output.mode.user.ulx", "Upper Left X");
     SetParameterDescription("output.mode.user.ulx","Cartographic X coordinate "
       "of upper-left corner (meters for cartographic projections, degrees for"
       " geographic ones)");
 
-    AddParameter(ParameterType_Float, "output.mode.user.uly", "Upper Left Y ");
+    AddParameter(ParameterType_Float, "output.mode.user.uly", "Upper Left Y");
     SetParameterDescription("output.mode.user.uly","Cartographic Y coordinate "
       "of the upper-left corner (meters for cartographic projections, degrees "
       "for geographic ones)");
 
     // Size of the output image
-    AddParameter(ParameterType_Int, "output.mode.user.sizex", "Size X ");
+    AddParameter(ParameterType_Int, "output.mode.user.sizex", "Size X");
     SetParameterDescription("output.mode.user.sizex","Size of projected image"
       " along X (in pixels)");
 
-    AddParameter(ParameterType_Int, "output.mode.user.sizey", "Size Y ");
+    AddParameter(ParameterType_Int, "output.mode.user.sizey", "Size Y");
     SetParameterDescription("output.mode.user.sizey","Size of projected image"
       " along Y (in pixels)");
 
     // Spacing of the output image
-    AddParameter(ParameterType_Float, "output.mode.user.spacingx", "Pixel Size X ");
+    AddParameter(ParameterType_Float, "output.mode.user.spacingx", "Pixel Size X");
     SetParameterDescription("output.mode.user.spacingx","Size of each pixel "
       "along X axis (meters for cartographic projections, degrees for geographic ones)");
 
 
-    AddParameter(ParameterType_Float, "output.mode.user.spacingy", "Pixel Size Y ");
+    AddParameter(ParameterType_Float, "output.mode.user.spacingy", "Pixel Size Y");
     SetParameterDescription("output.mode.user.spacingy","Size of each pixel "
       "along Y axis (meters for cartographic projections, degrees for geographic ones)");
 
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx
index 9f820a3e8f..97e7bc75ec 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx
@@ -2097,11 +2097,9 @@ void Application::AddRAMParameter(std::string paramKey, std::string paramName, u
 void Application::AddRAMParameter(std::string paramKey)
 {
   // Get the  RAM Parameter from the configuration manager
-  AddRAMParameter(paramKey,
-                    "Available RAM (Mb)",
-                  otb::ConfigurationManager::GetMaxRAMHint());
+  AddRAMParameter(paramKey, "Available RAM (MB)", otb::ConfigurationManager::GetMaxRAMHint());
   MandatoryOff(paramKey);
-  SetParameterDescription(paramKey, "Available memory for processing (in MB)");
+  SetParameterDescription(paramKey, "Available memory for processing (in MB).");
 }
 
 void Application::AddRANDParameter(std::string paramKey, std::string paramName, unsigned int defaultValue)
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputProcessXMLParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputProcessXMLParameter.cxx
index 11f0e6b482..db900e90ff 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputProcessXMLParameter.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputProcessXMLParameter.cxx
@@ -48,8 +48,8 @@ namespace Wrapper
 InputProcessXMLParameter::InputProcessXMLParameter()
 {
   this->SetKey("inxml");
-  this->SetName("Load otb application from xml file");
-  this->SetDescription("Load otb application from xml file");
+  this->SetName("Load parameters from XML");
+  this->SetDescription("Load application parameters from an XML file.");
   this->SetMandatory(false);
   this->SetActive(false);
   this->SetRole(Role_Input);
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputProcessXMLParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputProcessXMLParameter.cxx
index 22791595c0..75cc7c9b24 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputProcessXMLParameter.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputProcessXMLParameter.cxx
@@ -49,8 +49,8 @@ OutputProcessXMLParameter::OutputProcessXMLParameter()
   , m_Appli()
 {
   this->SetKey("outxml");
-  this->SetName("Save otb application to xml file");
-  this->SetDescription("Save otb application to xml file");
+  this->SetName("Save parameters to XML");
+  this->SetDescription("Save application parameters to an XML file.");
   this->SetMandatory(false);
   this->SetActive(false);
   this->SetRole(Role_Output);
-- 
GitLab