From 496ce388ab4dc464b9b3f821e05b98ebfc7fb17f Mon Sep 17 00:00:00 2001 From: Wolfgang Felbermeier Date: Wed, 22 Nov 2017 22:53:53 +0100 Subject: [PATCH] documentation: render nested return dicts for more then one level (#33143) * Render nested return value documentation for more then one level in the generated webdocs. * Remove unnecessary code and cleanup * Implement recursive option documentation * Build elbow intendation style for options and return documentation --- .../docsite/_themes/srtd/static/css/theme.css | 47 ++- docs/templates/plugin.rst.j2 | 336 ++++++++---------- 2 files changed, 196 insertions(+), 187 deletions(-) diff --git a/docs/docsite/_themes/srtd/static/css/theme.css b/docs/docsite/_themes/srtd/static/css/theme.css index f1a2f685ef7..9a0a84a6384 100644 --- a/docs/docsite/_themes/srtd/static/css/theme.css +++ b/docs/docsite/_themes/srtd/static/css/theme.css @@ -4748,7 +4748,7 @@ th, td { } table { - overflow-x: scroll; + overflow-x: auto; display: block; max-width: 100%; } @@ -4864,3 +4864,48 @@ table { padding: 8px 13px; } } + +.outer-elbow-container { + display: flex; + height: 100%; + flex-direction: row; +} + +.elbow-placeholder { + border-left: 1px solid #000; + height: 100%; + width: 30px; +} + +.elbow-key { + height: 100%; + padding: 4px; + border-top: 1px solid #000; + flex-grow: 1; + border-left: 1px solid #000; +} + +.elbow-blocker { + height: 0; + overflow: hidden; +} + +.return-value-column { + height: 1px +} + +.return-value-column td { + height: inherit +} + +.cell-border { + padding: 4px; + border-left: 1px solid #000; + border-top: 1px solid #000; + height: 100%; +} + +.documentation-table { + border-right: 1px solid #000; + border-bottom: 1px solid #000; +} \ No newline at end of file diff --git a/docs/templates/plugin.rst.j2 b/docs/templates/plugin.rst.j2 index 0fb1ac6712f..6d93079a4e1 100644 --- a/docs/templates/plugin.rst.j2 +++ b/docs/templates/plugin.rst.j2 @@ -86,135 +86,103 @@ Options .. raw:: html - - - - - - - -{% if plugin_type != 'module' %} - -{% endif %} - - -{% for k in option_keys -%} -{% set v = options[k] -%} -{% if not v['suboptions'] %} - - - - - -{% if v.get('type', 'not_bool') == 'bool' %} - -{% else %} - -{% endif %} -{% if plugin_type != 'module' %} - -{% endif %} - - -{% else %} - - - - -{% if plugin_type != 'module' %} - -{% endif %} - - - - - - -{% endif %} - - -{% endfor %} - + {% for key, value in options.items() recursive %} + + {# parameter name with introduced label #} + + {# required #} + + {# default value #} + + {# choices #} + + {# configuration #} + {% if plugin_type != 'module' %} + + {% endif %} + {# description #} + + + {% if value.suboptions %} + {% if value.suboptions.items %} + @{ loop(value.suboptions.items()) }@ + {% elif value.suboptions[0].items %} + @{ loop(value.suboptions[0].items()) }@ + {% endif %} + {% endif %} + {% endfor %}
parameterrequireddefaultchoicesconfigurationcomments
@{ k }@
{% if v['version_added'] -%} (added in @{v['version_added']}@){% endif -%}
{% if v.get('required', False) -%}yes{% else %}no{% endif -%}{% if v['default'] -%}@{ v['default'] }@{% endif -%}
  • yes
  • no
{% if v['choices'] -%}
    {% for choice in v.get('choices',[]) -%}
  • @{ choice }@
  • {% endfor -%}
{% endif -%}
- {% if 'ini' in v %} -
ini entries: - {% for ini in v.get('ini') %} -

[@{ ini.section }@ ]
@{ ini.key}@ = @{ v['default']|default('VALUE') }@

- {% endfor %} -
- {% endif %} - {% if 'env' in v %} - {% for env in v.get('env') %} -
env:@{ env.name }@
- {% endfor %} - {% endif %} - {% if 'vars' in v %} - {% for myvar in v.get('vars') %} -
var: @{ myvar.name }@
- {% endfor %} - {% endif %} -
-{% if v.description is string %} -
@{ v.description | replace('\n', '\n ') | html_ify }@
-{% else %} -{% for desc in v.description %} -

@{ desc | replace('\n', '\n ') | html_ify }@

-{% endfor %} -{% endif %} -{% if 'aliases' in v and v.aliases %} -
aliases: @{ v.aliases|join(', ') }@
-{% endif %} -
@{ k }@
{% if v['version_added'] -%} (added in @{v['version_added']}@){% endif -%}
{% if v.get('required', False) -%}yes{% else -%}no{% endif -%} -{% if v.description is string %} -
@{ v.description | replace('\n', '\n ') | html_ify }@
-{% else %} -{% for desc in v.description %} -
@{ desc | replace('\n', '\n ') | html_ify }@
-{% endfor %} -{% endif %} -{% if 'aliases' in v and v.aliases %} -
aliases: @{ v.aliases|join(', ') }@
-{% endif %} -
- - - +
Dictionary object @{ k }@
+ {# Header of the documentation #} - - - - - + + + + + {% if plugin_type != 'module' %} + + {% endif %} + -{% for k2 in v['suboptions'] %} -{% set v2 = v['suboptions'] [k2] %} - - - - - -{% if v2.get('type', 'not_bool') == 'bool' %} - -{% else %} - -{% endif %} - - -{% endfor %} - -
parameterrequireddefaultchoicescomments
parameter
required
default
choices
configuration
comments
@{ k2 }@
{% if v2['version_added'] -%} (added in @{v2['version_added']}@){% endif -%}
{% if v2.get('required', False) -%}yes{% else -%}no{% endif -%}{% if v2['default'] -%}@{ v2['default'] }@{% endif -%}
  • yes
  • no
{% if v2['choices'] -%}
    {% for choice in v2.get('choices',[]) -%}
  • @{ choice }@
  • {% endfor -%}
{% endif -%}
-{% if v2.description is string %} -
@{ v2.description | replace('\n', '\n ') | html_ify }@
-{% else %} -{% for desc in v2.description %} -
@{ desc | replace('\n', '\n ') | html_ify }@
-{% endfor %} -{% endif %} -{% if 'aliases' in v and v2.aliases %} -
aliases: @{ v2.aliases|join(', ') }@
-{% endif %} -
- -
+
+ {% for i in range(1, loop.depth) %} +
+
+ {% endfor %} +
+ @{ key }@
{% if value.version_added %} (added in @{value.version_added}@){% endif %}
+
+
+
{% if value.get('required', False) %}yes{% else %}no{% endif %}
{% if value.default %}@{ value.default }@{% endif %}
+
+ {% if value.type == 'boolean' %} +
    +
  • yes
  • +
  • no
  • +
+ {% else %} + {% if value.choices %} +
    + {% for choice in value.choices %} +
  • @{ choice }@
  • + {% endfor %} +
+ {% endif %} + {% endif %} +
+
+
+ {% if 'ini' in value %} +
ini entries: + {% for ini in value.ini %} +

[@{ ini.section }@ ]
@{ ini.key }@ = @{ value.default | default('VALUE') }@

+ {% endfor %} +
+ {% endif %} + {% if 'env' in value %} + {% for env in value.env %} +
env:@{ env.name }@
+ {% endfor %} + {% endif %} + {% if 'vars' in value %} + {% for myvar in value.vars %} +
var: @{ myvar.name }@
+ {% endfor %} + {% endif %} +
+
+
+ {% if value.description is string %} +
@{ value.description | replace('\n', '\n ') | html_ify }@
+ {% else %} + {% for desc in value.description %} +

@{ desc | replace('\n', '\n ') | html_ify }@

+ {% endfor %} + {% endif %} + {% if 'aliases' in value and value.aliases %} +
aliases: @{ value.aliases|join(', ') }@
+ {% endif %} +
+

@@ -245,68 +213,64 @@ Common return values are documented :ref:`here `, the foll .. raw:: html - - - - - - - - - -{% for entry in returndocs %} - - - - - - - - -{% if returndocs[entry].type == 'complex' %} - - - - -{% endif %} -{% endfor %} + {% for key, value in returndocs.items() recursive %} + + + + + + + + {# --------------------------------------------------------- + # sadly we cannot blindly iterate through the child dicts, + # since in some documentations, + # lists are used instead of dicts. This handles both types + # ---------------------------------------------------------#} + {% if value.contains %} + {% if value.contains.items %} + @{ loop(value.contains.items()) }@ + {% elif value.contains[0].items %} + @{ loop(value.contains[0].items()) }@ + {% endif %} + {% endif %} + {% endfor %}
namedescriptionreturnedtypesample
@{ entry }@ -{% if returndocs[entry].description is string %} -
@{ returndocs[entry].description | replace('\n', '\n ') | html_ify }@
-{% else %} -{% for desc in returndocs[entry].description %} -
@{ desc | replace('\n', '\n ') | html_ify }@
-{% endfor %} -{% endif %} -
@{ returndocs[entry].returned }@@{ returndocs[entry].type }@@{ returndocs[entry].sample | replace('\n', '\n ') | html_ify }@
contains: - + +
- - - - - + + + + + -{% for sub in returndocs[entry].contains %} - - - - - - - - -{% endfor %} -
namedescriptionreturnedtypesample
name
description
returned
type
sample
@{ sub }@ -{% if returndocs[entry].contains[sub].description is string %} -
@{ returndocs[entry].contains[sub].description | replace('\n', '\n ') | html_ify }@
-{% else %} -{% for desc in returndocs[entry].contains[sub].description %} -
@{ desc | replace('\n', '\n ') | html_ify }@
-{% endfor %} -{% endif %} -
@{ returndocs[entry].contains[sub].returned }@@{ returndocs[entry].contains[sub].type }@@{ returndocs[entry].contains[sub].sample }@
-
+
+ {% for i in range(1, loop.depth) %} +
+
+ {% endfor %} +
+ @{ key }@ +
+
+
+ {% if value.description is string %} +
@{ value.description | replace('\n', '\n ') | html_ify }@
+ {% else %} + {% for desc in value.description %} +
@{ desc | replace('\n', '\n ') | html_ify }@
+ {% endfor %} + {% endif %} +
@{ value.returned }@
@{ value.type }@
@{ value.sample | replace('\n', '\n ') | html_ify }@


{% endif %}