summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDick Visser <dick.visser@geant.org>2020-02-03 20:11:48 +0100
committerGitHub <noreply@github.com>2020-02-03 20:11:48 +0100
commit5b93a14a0f2474bbab86a41f3f0841a02158eaf5 (patch)
tree15f9e4d32e980d28987efc35d754e8f7e7c5927e
parent6024c09be5fc37012764b1a71167b2f1be07547c (diff)
downloadansible-5b93a14a0f2474bbab86a41f3f0841a02158eaf5.tar.gz
Add anchor to each parameter row (#66895)
* Add anchor to each paramater row * Update docs/templates/plugin.rst.j2 Co-Authored-By: Felix Fontein <felix@fontein.de> * Insert full keys into plugin docs. * Added visible links. Co-authored-by: Felix Fontein <felix@fontein.de>
-rw-r--r--docs/docsite/_static/ansible.css25
-rw-r--r--docs/templates/plugin.rst.j29
-rw-r--r--hacking/build_library/build_ansible/command_plugins/plugin_formatter.py32
3 files changed, 60 insertions, 6 deletions
diff --git a/docs/docsite/_static/ansible.css b/docs/docsite/_static/ansible.css
index 5d9ce2bdab..2fd26cebad 100644
--- a/docs/docsite/_static/ansible.css
+++ b/docs/docsite/_static/ansible.css
@@ -28,3 +28,28 @@ table.documentation-table .value-name {
display: inline;
}
*/table.documentation-table .value-type{font-size:x-small;color:purple;display:inline}table.documentation-table .value-separator{font-size:x-small;display:inline}table.documentation-table .value-required{font-size:x-small;color:red;display:inline}.value-added-in{font-size:x-small;font-style:italic;color:green;display:inline}/*! Ansible-specific CSS pulled out of rtd theme for 2.9 */.DocSiteProduct-header{flex:1;-webkit-flex:1;padding:10px 20px 20px;display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;align-items:center;-webkit-align-items:center;justify-content:flex-start;-webkit-justify-content:flex-start;margin-left:20px;margin-right:20px;text-decoration:none;font-weight:400;font-family:'Open Sans',sans-serif}.DocSiteProduct-header:active,.DocSiteProduct-header:focus,.DocSiteProduct-header:visited{color:#fff}.DocSiteProduct-header--core{font-size:25px;background-color:#5bbdbf;border:2px solid #5bbdbf;border-top-left-radius:4px;border-top-right-radius:4px;color:#fff;padding-left:2px;margin-left:2px}.DocSiteProduct-headerAlign{width:100%}.DocSiteProduct-logo{width:60px;height:60px;margin-bottom:-9px}.DocSiteProduct-logoText{margin-top:6px;font-size:25px;text-align:left}.DocSiteProduct-CheckVersionPara{margin-left:2px;padding-bottom:4px;margin-right:2px;margin-bottom:10px}/*! Ansible color scheme */.wy-nav-top,.wy-side-nav-search{background-color:#5bbdbf}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#5bbdbf}.wy-menu-vertical a{padding:0}.wy-menu-vertical a.reference.internal{padding:.4045em 1.618em}/*! Override sphinx rtd theme max-with of 800px */.wy-nav-content{max-width:100%}/*! Override sphinx_rtd_theme - keeps left-nav from overwriting Documentation title */.wy-nav-side{top:45px}/*! Ansible - changed absolute to relative to remove extraneous side scroll bar */.wy-grid-for-nav{position:relative}/*! Ansible narrow the search box */.wy-side-nav-search input[type=text]{width:90%;padding-left:24px}/*! Ansible - remove so highlight indenting is correct */.rst-content .highlighted{padding:0}.DocSiteBanner{display:flex;display:-webkit-flex;justify-content:center;-webkit-justify-content:center;flex-wrap:wrap;-webkit-flex-wrap:wrap;margin-bottom:25px}.DocSiteBanner-imgWrapper{max-width:100%}td,th{min-width:100px}table{overflow-x:auto;display:block;max-width:100%}.documentation-table td.elbow-placeholder{border-left:1px solid #000;border-top:0;width:30px;min-width:30px}.documentation-table td,.documentation-table th{padding:4px;border-left:1px solid #000;border-top:1px solid #000}.documentation-table{border-right:1px solid #000;border-bottom:1px solid #000}@media print{*{background:0 0!important;color:#000!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}#nav,a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}/*! Don't show links for images, or javascript/internal links */pre,blockquote{border:0 solid #999;page-break-inside:avoid}thead{display:table-header-group}/*! h5bp.com/t */tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}#google_image_div,.DocSiteBanner{display:none!important}}#sideBanner,.DocSite-globalNav{display:none}.DocSite-sideNav{display:block;margin-bottom:40px}.DocSite-nav{display:none}.ansibleNav{background:#000;padding:0 20px;width:auto;border-bottom:1px solid #444;font-size:14px;z-index:1}.ansibleNav ul{list-style:none;padding-left:0;margin-top:0}.ansibleNav ul li{padding:7px 0;border-bottom:1px solid #444}.ansibleNav ul li:last-child{border:none}.ansibleNav ul li a{color:#fff;text-decoration:none;text-transform:uppercase;padding:6px 0}.ansibleNav ul li a:hover{color:#5bbdbf;background:0 0}h4{font-size:105%}h5{font-size:90%}h6{font-size:80%}@media screen and (min-width:768px){.DocSite-globalNav{display:block;position:fixed}#sideBanner{display:block}.DocSite-sideNav{display:none}.DocSite-nav{flex:initial;-webkit-flex:initial;display:flex;display:-webkit-flex;flex-direction:row;-webkit-flex-direction:row;justify-content:flex-start;-webkit-justify-content:flex-start;padding:15px;background-color:#000;text-decoration:none;font-family:'Open Sans',sans-serif}.DocSiteNav-logo{width:28px;height:28px;margin-right:8px;margin-top:-6px;position:fixed;z-index:1}.DocSiteNav-title{color:#fff;font-size:20px;position:fixed;margin-left:40px;margin-top:-4px;z-index:1}.ansibleNav{height:45px;width:100%;font-size:13px;padding:0 60px 0 0}.ansibleNav ul{float:right;display:flex;flex-wrap:nowrap;margin-top:13px}.ansibleNav ul li{padding:0;border-bottom:none}.ansibleNav ul li a{color:#fff;text-decoration:none;text-transform:uppercase;padding:8px 13px}h4{font-size:105%}h5{font-size:90%}h6{font-size:80%}}@media screen and (min-width:768px){#sideBanner,.DocSite-globalNav{display:block}.DocSite-sideNav{display:none}.DocSite-nav{flex:initial;-webkit-flex:initial;display:flex;display:-webkit-flex;flex-direction:row;-webkit-flex-direction:row;justify-content:flex-start;-webkit-justify-content:flex-start;padding:15px;background-color:#000;text-decoration:none;font-family:'Open Sans',sans-serif}.DocSiteNav-logo{width:28px;height:28px;margin-right:8px;margin-top:-6px;position:fixed}.DocSiteNav-title{color:#fff;font-size:20px;position:fixed;margin-left:40px;margin-top:-4px}.ansibleNav{height:45px;font-size:13px;padding:0 60px 0 0}.ansibleNav ul{float:right;display:flex;flex-wrap:nowrap;margin-top:13px}.ansibleNav ul li{padding:0;border-bottom:none}.ansibleNav ul li a{color:#fff;text-decoration:none;text-transform:uppercase;padding:8px 13px}h4{font-size:105%}h5{font-size:90%}h6{font-size:80%}}
+/* ansibleOptionLink is adapted from h1 .headerlink in sphinx_rtd_theme */
+tr:hover .ansibleOptionLink::after {
+ visibility: visible;
+}
+tr .ansibleOptionLink::after {
+ content: "";
+ font-family: FontAwesome;
+}
+tr .ansibleOptionLink::before {
+ font-family: "FontAwesome";
+ display: inline-block;
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1;
+ text-decoration: inherit;
+ -webkit-font-smoothing: antialiased;
+}
+tr .ansibleOptionLink {
+ visibility: hidden;
+ display: inline-block;
+ font: normal normal normal 14px/1 FontAwesome;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
diff --git a/docs/templates/plugin.rst.j2 b/docs/templates/plugin.rst.j2
index 0d974f2cca..af99932fe9 100644
--- a/docs/templates/plugin.rst.j2
+++ b/docs/templates/plugin.rst.j2
@@ -106,7 +106,7 @@ Parameters
<th width="100%">Comments</th>
</tr>
{% for key, value in options|dictsort recursive %}
- <tr>
+ <tr id="parameter-{% for part in value.full_key %}@{ part }@{% if not loop.last %}/{% endif %}{% endfor %}">
{# indentation based on nesting level #}
{% for i in range(1, loop.depth) %}
<td class="elbow-placeholder"></td>
@@ -114,6 +114,7 @@ Parameters
{# parameter name with required and/or introduced label #}
<td colspan="@{ from_kludge_ns('maxdepth') - loop.depth0 }@">
<b>@{ key }@</b>
+ <a class="ansibleOptionLink" href="#parameter-{% for part in value.full_key %}@{ part }@{% if not loop.last %}/{% endif %}{% endfor %}" title="Permalink to this option">¶</a>
<div style="font-size: small">
<span style="color: purple">@{ value.type | documented_type }@</span>
{% if value.get('elements') %} / <span style="color: purple">elements=@{ value.elements | documented_type }@</span>{% endif %}
@@ -282,12 +283,13 @@ Facts returned by this module are added/updated in the ``hostvars`` host facts a
<th width="100%">Description</th>
</tr>
{% for key, value in returnfacts|dictsort recursive %}
- <tr>
+ <tr id="return-{% for part in value.full_key %}@{ part }@{% if not loop.last %}/{% endif %}{% endfor %}">
{% for i in range(1, loop.depth) %}
<td class="elbow-placeholder"></td>
{% endfor %}
<td colspan="@{ from_kludge_ns('maxdepth') - loop.depth0 }@" colspan="@{ from_kludge_ns('maxdepth') - loop.depth0 }@">
<b>@{ key }@</b>
+ <a class="ansibleOptionLink" href="#return-{% for part in value.full_key %}@{ part }@{% if not loop.last %}/{% endif %}{% endfor %}" title="Permalink to this fact">¶</a>
<div style="font-size: small">
<span style="color: purple">@{ value.type | documented_type }@</span>
{% if value.elements %} / <span style="color: purple">elements=@{ value.elements | documented_type }@</span>{% endif %}
@@ -357,12 +359,13 @@ Common return values are documented :ref:`here <common_return_values>`, the foll
<th width="100%">Description</th>
</tr>
{% for key, value in returndocs|dictsort recursive %}
- <tr>
+ <tr id="return-{% for part in value.full_key %}@{ part }@{% if not loop.last %}/{% endif %}{% endfor %}">
{% for i in range(1, loop.depth) %}
<td class="elbow-placeholder">&nbsp;</td>
{% endfor %}
<td colspan="@{ from_kludge_ns('maxdepth') - loop.depth0 }@">
<b>@{ key }@</b>
+ <a class="ansibleOptionLink" href="#return-{% for part in value.full_key %}@{ part }@{% if not loop.last %}/{% endif %}{% endfor %}" title="Permalink to this return value">¶</a>
<div style="font-size: small">
<span style="color: purple">@{ value.type | documented_type }@</span>
{% if value.elements %} / <span style="color: purple">elements=@{ value.elements | documented_type }@</span>{% endif %}
diff --git a/hacking/build_library/build_ansible/command_plugins/plugin_formatter.py b/hacking/build_library/build_ansible/command_plugins/plugin_formatter.py
index 4fcf99a1c9..6482e71fd7 100644
--- a/hacking/build_library/build_ansible/command_plugins/plugin_formatter.py
+++ b/hacking/build_library/build_ansible/command_plugins/plugin_formatter.py
@@ -346,11 +346,17 @@ def too_old(added):
return added_float < TOO_OLD_TO_BE_NOTABLE
-def process_options(module, options):
+def process_options(module, options, full_key=None):
option_names = []
+ if full_key is None:
+ full_key = []
if options:
for (k, v) in iteritems(options):
+ # Make sure that "full key" is contained
+ full_key_k = full_key + [k]
+ v['full_key'] = full_key_k
+
# Error out if there's no description
if 'description' not in v:
raise AnsibleError("Missing required description for parameter '%s' in '%s' " % (k, module))
@@ -376,9 +382,9 @@ def process_options(module, options):
if 'suboptions' in v and v['suboptions']:
if isinstance(v['suboptions'], dict):
- process_options(module, v['suboptions'])
+ process_options(module, v['suboptions'], full_key=full_key_k)
elif isinstance(v['suboptions'][0], dict):
- process_options(module, v['suboptions'][0])
+ process_options(module, v['suboptions'][0], full_key=full_key_k)
option_names.append(k)
@@ -387,6 +393,25 @@ def process_options(module, options):
return option_names
+def process_returndocs(returndocs, full_key=None):
+ if full_key is None:
+ full_key = []
+
+ if returndocs:
+ for (k, v) in iteritems(returndocs):
+ # Make sure that "full key" is contained
+ full_key_k = full_key + [k]
+ v['full_key'] = full_key_k
+
+ # Process suboptions
+ suboptions = v.get('contains')
+ if suboptions:
+ if isinstance(suboptions, dict):
+ process_returndocs(suboptions, full_key=full_key_k)
+ elif is_sequence(suboptions):
+ process_returndocs(suboptions[0], full_key=full_key_k)
+
+
def process_plugins(module_map, templates, outputname, output_dir, ansible_version, plugin_type):
for module_index, module in enumerate(module_map):
@@ -483,6 +508,7 @@ def process_plugins(module_map, templates, outputname, output_dir, ansible_versi
if module_map[module]['returndocs']:
try:
doc['returndocs'] = yaml.safe_load(module_map[module]['returndocs'])
+ process_returndocs(doc['returndocs'])
except Exception as e:
print("%s:%s:yaml error:%s:returndocs=%s" % (fname, module, e, module_map[module]['returndocs']))
doc['returndocs'] = None