From e348dc28e922c29e0ab1fd61be24ecc6616e34ed Mon Sep 17 00:00:00 2001
From: Toshio Kuratomi <a.badger@gmail.com>
Date: Mon, 25 Jun 2018 11:27:15 -0700
Subject: [PATCH] Changes to support building docs with old jinja2

This commit: fa5c0282a4816c4dd48e80b983ffc1e14506a1f5 relied upon
features present in Jinja-2.10 and above.  The changes here allow us to
build the *rst* with older versions of jinja2.
---
 docs/bin/plugin_formatter.py | 30 +++++++++++++++++
 docs/templates/plugin.rst.j2 | 80 ++++++++++++++++++++++----------------------
 2 files changed, 70 insertions(+), 40 deletions(-)

diff --git a/docs/bin/plugin_formatter.py b/docs/bin/plugin_formatter.py
index 5df8b3d86e..330a7540ab 100755
--- a/docs/bin/plugin_formatter.py
+++ b/docs/bin/plugin_formatter.py
@@ -85,6 +85,28 @@ pp = PrettyPrinter()
 display = Display()
 
 
+# kludge_ns gives us a kludgey way to set variables inside of loops that need to be visible outside
+# the loop.  We can get rid of this when we no longer need to build docs with less than Jinja-2.10
+# http://jinja.pocoo.org/docs/2.10/templates/#assignments
+# With Jinja-2.10 we can use jinja2's namespace feature, restoring the namespace template portion
+# of: fa5c0282a4816c4dd48e80b983ffc1e14506a1f5
+NS_MAP = {}
+
+
+def to_kludge_ns(key, value):
+    NS_MAP[key] = value
+    return ""
+
+
+def from_kludge_ns(key):
+    return NS_MAP[key]
+
+
+# The max filter was added in Jinja2-2.10.  Until we can require that version, use this
+def do_max(seq):
+    return max(seq)
+
+
 def rst_ify(text):
     ''' convert symbols like I(this is in italics) to valid restructured text '''
 
@@ -298,6 +320,14 @@ def jinja2_environment(template_dir, typ, plugin_type):
                       trim_blocks=True)
     env.globals['xline'] = rst_xline
 
+    # Can be removed (and template switched to use namespace) when we no longer need to build
+    # with <Jinja-2.10
+    env.globals['to_kludge_ns'] = to_kludge_ns
+    env.globals['from_kludge_ns'] = from_kludge_ns
+    if 'max' not in env.filters:
+        # Jinja < 2.10
+        env.filters['max'] = do_max
+
     templates = {}
     if typ == 'rst':
         env.filters['convert_symbols_to_format'] = rst_ify
diff --git a/docs/templates/plugin.rst.j2 b/docs/templates/plugin.rst.j2
index dcd43171e7..d3ebc7c560 100644
--- a/docs/templates/plugin.rst.j2
+++ b/docs/templates/plugin.rst.j2
@@ -88,21 +88,21 @@ Parameters
 .. raw:: html
 
     <table  border=0 cellpadding=0 class="documentation-table">
-        {# Pre-compute the nesting depth to allocate columns #}
-        {% set ns = namespace(maxdepth=1) %}
-        {% for key, value in options|dictsort recursive %}
-            {% set ns.maxdepth = [loop.depth, ns.maxdepth] | max %}
-            {% if value.suboptions %}
-                {% if value.suboptions.items %}
-                    @{ loop(value.suboptions.items()) }@
-                {% elif value.suboptions[0].items %}
-                    @{ loop(value.suboptions[0].items()) }@
-                {% endif %}
-            {% endif %}
-        {% endfor %}
-        {# Header of the documentation #}
+        {# Pre-compute the nesting depth to allocate columns -#}
+        @{ to_kludge_ns('maxdepth', 1) -}@
+        {% for key, value in options|dictsort recursive -%}
+            @{ to_kludge_ns('maxdepth', [loop.depth, from_kludge_ns('maxdepth')] | max) -}@
+            {% if value.suboptions -%}
+                {% if value.suboptions.items -%}
+                    @{ loop(value.suboptions.items()) -}@
+                {% elif value.suboptions[0].items -%}
+                    @{ loop(value.suboptions[0].items()) -}@
+                {% endif -%}
+            {% endif -%}
+        {% endfor -%}
+        {# Header of the documentation -#}
         <tr>
-            <th colspan="@{ ns.maxdepth }@">Parameter</th>
+            <th colspan="@{ from_kludge_ns('maxdepth') }@">Parameter</th>
             <th>Choices/<font color="blue">Defaults</font></th>
             {% if plugin_type != 'module' %}
                 <th>Configuration</th>
@@ -116,7 +116,7 @@ Parameters
                     <td class="elbow-placeholder"></td>
                 {% endfor %}
                 {# parameter name with required and/or introduced label #}
-                <td colspan="@{ ns.maxdepth - loop.depth0 }@">
+                <td colspan="@{ from_kludge_ns('maxdepth') - loop.depth0 }@">
                     <b>@{ key }@</b>
                     {% if value.get('required', False) %}<br/><div style="font-size: small; color: red">required</div>{% endif %}
                     {% if value.version_added %}<br/><div style="font-size: small; color: darkgreen">(added in @{value.version_added}@)</div>{% endif %}
@@ -246,19 +246,19 @@ Facts returned by this module are added/updated in the ``hostvars`` host facts a
 
     <table border=0 cellpadding=0 class="documentation-table">
         {# Pre-compute the nesting depth to allocate columns #}
-        {% set ns = namespace(maxdepth=1) %}
+        @{ to_kludge_ns('maxdepth', 1) -}@
         {% for key, value in returnfacts|dictsort recursive %}
-            {% set ns.maxdepth = [loop.depth, ns.maxdepth] | max %}
-            {% if value.contains %}
-                {% if value.contains.items %}
-                    @{ loop(value.contains.items()) }@
-                {% elif value.contains[0].items %}
-                    @{ loop(value.contains[0].items()) }@
-                {% endif %}
-            {% endif %}
-        {% endfor %}
+            @{ to_kludge_ns('maxdepth', [loop.depth, from_kludge_ns('maxdepth')] | max) -}@
+            {% if value.contains -%}
+                {% if value.contains.items -%}
+                    @{ loop(value.contains.items()) -}@
+                {% elif value.contains[0].items -%}
+                    @{ loop(value.contains[0].items()) -}@
+                {% endif -%}
+            {% endif -%}
+        {% endfor -%}
         <tr>
-            <th colspan="@{ ns.maxdepth }@">Fact</th>
+            <th colspan="@{ from_kludge_ns('maxdepth') }@">Fact</th>
             <th>Returned</th>
             <th width="100%">Description</th>
         </tr>
@@ -267,7 +267,7 @@ Facts returned by this module are added/updated in the ``hostvars`` host facts a
                 {% for i in range(1, loop.depth) %}
                     <td class="elbow-placeholder"></td>
                 {% endfor %}
-                <td colspan="@{ ns.maxdepth - loop.depth0 }@" colspan="@{ ns.maxdepth - loop.depth0 }@">
+                <td colspan="@{ from_kludge_ns('maxdepth') - loop.depth0 }@" colspan="@{ from_kludge_ns('maxdepth') - loop.depth0 }@">
                     <b>@{ key }@</b>
                     <br/><div style="font-size: small; color: red">@{ value.type }@</div>
                 </td>
@@ -317,19 +317,19 @@ Common return values are documented :ref:`here <common_return_values>`, the foll
 .. raw:: html
 
     <table border=0 cellpadding=0 class="documentation-table">
-        {% set ns = namespace(maxdepth=1) %}
-        {% for key, value in returndocs|dictsort recursive %}
-            {% set ns.maxdepth = [loop.depth, ns.maxdepth] | max %}
-            {% if value.contains %}
-                {% if value.contains.items %}
-                    @{ loop(value.contains.items()) }@
-                {% elif value.contains[0].items %}
-                    @{ loop(value.contains[0].items()) }@
-                {% endif %}
-            {% endif %}
-        {% endfor %}
+        @{ to_kludge_ns('maxdepth', 1) -}@
+        {% for key, value in returndocs|dictsort recursive -%}
+            @{ to_kludge_ns('maxdepth', [loop.depth, from_kludge_ns('maxdepth')] | max) -}@
+            {% if value.contains -%}
+                {% if value.contains.items -%}
+                    @{ loop(value.contains.items()) -}@
+                {% elif value.contains[0].items -%}
+                    @{ loop(value.contains[0].items()) -}@
+                {% endif -%}
+            {% endif -%}
+        {% endfor -%}
         <tr>
-            <th colspan="@{ ns.maxdepth }@">Key</th>
+            <th colspan="@{ from_kludge_ns('maxdepth') }@">Key</th>
             <th>Returned</th>
             <th width="100%">Description</th>
         </tr>
@@ -338,7 +338,7 @@ Common return values are documented :ref:`here <common_return_values>`, the foll
                 {% for i in range(1, loop.depth) %}
                     <td class="elbow-placeholder">&nbsp;</td>
                 {% endfor %}
-                <td colspan="@{ ns.maxdepth - loop.depth0 }@">
+                <td colspan="@{ from_kludge_ns('maxdepth') - loop.depth0 }@">
                     <b>@{ key }@</b>
                     <br/><div style="font-size: small; color: red">@{ value.type }@</div>
                 </td>
-- 
2.14.4

