From 89c6f3ffced06219e6fd5c8bd9b97fb31bde33d3 Mon Sep 17 00:00:00 2001
From: Victor Poughon <victor.poughon@cnes.fr>
Date: Mon, 25 Feb 2019 16:56:43 +0100
Subject: [PATCH] REFAC: cookbook examples: support multiple usage

---
 Documentation/Cookbook/CMakeLists.txt         |  1 -
 Documentation/Cookbook/Scripts/RunExamples.py | 33 +++++++++----------
 .../Scripts/otbGenerateExamplesRstDoc.py      | 20 +++++------
 Documentation/Cookbook/Scripts/rst_utils.py   |  3 ++
 4 files changed, 28 insertions(+), 29 deletions(-)

diff --git a/Documentation/Cookbook/CMakeLists.txt b/Documentation/Cookbook/CMakeLists.txt
index 46ced13903..a690ee397e 100644
--- a/Documentation/Cookbook/CMakeLists.txt
+++ b/Documentation/Cookbook/CMakeLists.txt
@@ -151,7 +151,6 @@ add_custom_target(generate_examples_rst
 # Add all applications as dependencies to rst generation
 set(app_names ${OTB_APPLICATIONS_NAME_LIST})
 list(REMOVE_ITEM app_names "TestApplication")
-list(REMOVE_ITEM app_names "ApplicationExample")
 list(REMOVE_DUPLICATES app_names)
 foreach(app_name ${app_names})
   add_dependencies(generate_otbapps_rst otbapp_${app_name})
diff --git a/Documentation/Cookbook/Scripts/RunExamples.py b/Documentation/Cookbook/Scripts/RunExamples.py
index 5bab0c760f..c8a1e005b4 100755
--- a/Documentation/Cookbook/Scripts/RunExamples.py
+++ b/Documentation/Cookbook/Scripts/RunExamples.py
@@ -26,6 +26,8 @@ import os
 from os.path import join
 import re
 
+from rst_utils import examples_usage_regex
+
 def run_example(otb_root, otb_data, name, dry_run):
     """
     Run an example by name
@@ -49,27 +51,24 @@ def run_example(otb_root, otb_data, name, dry_run):
     filename = os.path.abspath(sources_files[0])
 
     # Extract example usage command arguments
-    usage_rx = r"\/\* Example usage:\n\.\/[a-zA-Z]+ (.*?)\*\/"
-    match = re.search(usage_rx, open(filename).read(), flags = re.MULTILINE | re.DOTALL)
-
-    if not match:
-        raise RuntimeError("Can't find example usage in {}".format(filename))
-
-    example_args = match.group(1).replace("\\\n", "").split()
+    matches = list(re.finditer(examples_usage_regex, open(filename).read(), flags = re.MULTILINE | re.DOTALL))
 
-    # Make sure Output dir exists
-    os.makedirs(join(otb_data, "Output"), exist_ok=True)
-
-    print("$ " + binary + " " + " ".join(example_args))
-
-    if dry_run:
+    if len(matches) == 0:
+        print("Warning: no usage for example: {}".format(sources_files[0]))
         return
 
-    # Execute the example with otb_data as working directory,
-    # because paths are given relative to otb_data in the example usage
-    subprocess.check_call([binary, *example_args], cwd=otb_data)
+    for match in matches:
+        # Get command line call and print it
+        example_args = match.group(2).replace("\\\n", "").split()
+        print("$ " + binary + " " + " ".join(example_args))
+
+        if not dry_run:
+            # Make sure Output dir exists
+            os.makedirs(join(otb_data, "Output"), exist_ok=True)
 
-# TODO handle examples with multiple usage (Examples/BasicFilters/DEMToRainbowExample.cxx)
+            # Execute the example with otb_data as working directory,
+            # because paths are given relative to otb_data in the example usage
+            subprocess.check_call([binary, *example_args], cwd=otb_data)
 
 def main():
     parser = argparse.ArgumentParser(usage="Run one or all OTB cxx examples")
diff --git a/Documentation/Cookbook/Scripts/otbGenerateExamplesRstDoc.py b/Documentation/Cookbook/Scripts/otbGenerateExamplesRstDoc.py
index a8a8f9e954..d11f36a06d 100644
--- a/Documentation/Cookbook/Scripts/otbGenerateExamplesRstDoc.py
+++ b/Documentation/Cookbook/Scripts/otbGenerateExamplesRstDoc.py
@@ -27,7 +27,7 @@ from collections import defaultdict
 import re
 import glob
 
-from rst_utils import rst_section, RstPageHeading
+from rst_utils import rst_section, RstPageHeading, examples_usage_regex
 
 def generate_examples_index(rst_dir, list_of_examples):
 
@@ -72,18 +72,16 @@ def render_example(filename, otb_root):
     examples_license_header = open("templates/examples_license_header.txt").read()
     code = code.replace(examples_license_header, "")
 
-    # Extract usage
-    # TODO handle multiple usage
-    rx_usage = r"\/\* Example usage:\n(\.\/[a-zA-Z]+ (.*?))\*\/"
-    usage_match = re.search(rx_usage, code, flags = re.MULTILINE | re.DOTALL)
-    if usage_match is None:
-        print("Warning: no usage found for example " + filename)
-        example_usage = ""
-    else:
-        example_usage = open("templates/example_usage.rst").read().format(indent(usage_match.group(1).strip()))
+    # Extract usages
+    example_usage = ""
+    usage_matches = list(re.finditer(examples_usage_regex, code, flags = re.MULTILINE | re.DOTALL))
+
+    examples_usage_template = open("templates/example_usage.rst").read()
+    for match in usage_matches:
+        example_usage += examples_usage_template.format(indent(match.group(1).strip()))
 
     # Don't show usage in example source
-    code = re.sub(rx_usage, "", code, flags = re.MULTILINE | re.DOTALL)
+    code = re.sub(examples_usage_regex, "", code, flags = re.MULTILINE | re.DOTALL)
 
     # Make the link to the source code
     link_name = os.path.basename(filename)
diff --git a/Documentation/Cookbook/Scripts/rst_utils.py b/Documentation/Cookbook/Scripts/rst_utils.py
index d6096b25a7..42cf7683d0 100644
--- a/Documentation/Cookbook/Scripts/rst_utils.py
+++ b/Documentation/Cookbook/Scripts/rst_utils.py
@@ -1,4 +1,7 @@
 
+# Regex used to find examples usage
+examples_usage_regex = r"\/\* Example usage:\n(\.\/\w+ (.*?))\*\/"
+
 def rst_section(text, delimiter, ref=None):
     "Make a rst section title"
 
-- 
GitLab