diff --git a/docs/docsite/_extensions/pygments_lexer.py b/docs/docsite/_extensions/pygments_lexer.py
index 1c09893ce6..837d2ea84d 100644
--- a/docs/docsite/_extensions/pygments_lexer.py
+++ b/docs/docsite/_extensions/pygments_lexer.py
@@ -37,9 +37,11 @@
from __future__ import absolute_import, print_function
from pygments.lexer import LexerContext, ExtendedRegexLexer, DelegatingLexer, RegexLexer, bygroups, include
-from pygments.lexers import DjangoLexer, DiffLexer
+from pygments.lexers import DiffLexer
from pygments import token
+import re
+
class AnsibleYamlLexerContext(LexerContext):
"""Indentation context for the YAML lexer."""
@@ -255,7 +257,7 @@ class AnsibleYamlLexer(ExtendedRegexLexer):
# whitespaces separating tokens
(r'[ ]+', token.Text),
# key with colon
- (r'([^,:?\[\]{}\n]+)(:)(?=[ ]|$)',
+ (r'''([^,:?\[\]{}"'\n]+)(:)(?=[ ]|$)''',
bygroups(token.Name.Tag, set_indent(token.Punctuation, implicit=True))),
# tags, anchors and aliases,
include('descriptors'),
@@ -334,7 +336,7 @@ class AnsibleYamlLexer(ExtendedRegexLexer):
# a flow mapping indicated by '{' and '}'
'flow-mapping': [
# key with colon
- (r'([^,:?\[\]{}\n]+)(:)(?=[ ]|$)',
+ (r'''([^,:?\[\]{}"'\n]+)(:)(?=[ ]|$)''',
bygroups(token.Name.Tag, token.Punctuation)),
# include flow collection rules
include('flow-collection'),
@@ -458,6 +460,89 @@ class AnsibleYamlLexer(ExtendedRegexLexer):
return super(AnsibleYamlLexer, self).get_tokens_unprocessed(text, context)
+class AnsibleDjangoLexer(RegexLexer):
+ """
+ Generic `django `_
+ and `jinja `_ template lexer.
+
+ It just highlights django/jinja code between the preprocessor directives,
+ other data is left untouched by the lexer.
+ """
+
+ name = 'Django/Jinja'
+ aliases = ['django', 'jinja']
+ mimetypes = ['application/x-django-templating', 'application/x-jinja']
+
+ flags = re.M | re.S
+
+ tokens = {
+ 'root': [
+ (r'[^{]+', token.Other),
+ (r'\{\{', token.Comment.Preproc, 'var'),
+ # jinja/django comments
+ (r'\{[*#].*?[*#]\}', token.Comment),
+ # django comments
+ (r'(\{%)(-?\s*)(comment)(\s*-?)(%\})(.*?)'
+ r'(\{%)(-?\s*)(endcomment)(\s*-?)(%\})',
+ bygroups(token.Comment.Preproc, token.Text, token.Keyword, token.Text, token.Comment.Preproc,
+ token.Comment, token.Comment.Preproc, token.Text, token.Keyword, token.Text,
+ token.Comment.Preproc)),
+ # raw jinja blocks
+ (r'(\{%)(-?\s*)(raw)(\s*-?)(%\})(.*?)'
+ r'(\{%)(-?\s*)(endraw)(\s*-?)(%\})',
+ bygroups(token.Comment.Preproc, token.Text, token.Keyword, token.Text, token.Comment.Preproc,
+ token.Text, token.Comment.Preproc, token.Text, token.Keyword, token.Text,
+ token.Comment.Preproc)),
+ # filter blocks
+ (r'(\{%)(-?\s*)(filter)(\s+)([a-zA-Z_]\w*)',
+ bygroups(token.Comment.Preproc, token.Text, token.Keyword, token.Text, token.Name.Function),
+ 'block'),
+ (r'(\{%)(-?\s*)([a-zA-Z_]\w*)',
+ bygroups(token.Comment.Preproc, token.Text, token.Keyword), 'block'),
+ (r'\{', token.Other)
+ ],
+ 'varnames': [
+ (r'(\|)(\s*)([a-zA-Z_]\w*)',
+ bygroups(token.Operator, token.Text, token.Name.Function)),
+ (r'(is)(\s+)(not)?(\s+)?([a-zA-Z_]\w*)',
+ bygroups(token.Keyword, token.Text, token.Keyword, token.Text, token.Name.Function)),
+ (r'(_|true|false|none|True|False|None)\b', token.Keyword.Pseudo),
+ (r'(in|as|reversed|recursive|not|and|or|is|if|else|import|'
+ r'with(?:(?:out)?\s*context)?|scoped|ignore\s+missing)\b',
+ token.Keyword),
+ (r'(loop|block|super|forloop)\b', token.Name.Builtin),
+ (r'[a-zA-Z_][\w-]*', token.Name.Variable),
+ (r'\.\w+', token.Name.Variable),
+ (r':?"(\\\\|\\"|[^"])*"', token.String.Double),
+ (r":?'(\\\\|\\'|[^'])*'", token.String.Single),
+ (r'([{}()\[\]+\-*/%,:~]|[><=]=?|!=)', token.Operator),
+ (r"[0-9](\.[0-9]*)?(eE[+-][0-9])?[flFLdD]?|"
+ r"0[xX][0-9a-fA-F]+[Ll]?", token.Number),
+ ],
+ 'var': [
+ (r'\s+', token.Text),
+ (r'(-?)(\}\})', bygroups(token.Text, token.Comment.Preproc), '#pop'),
+ include('varnames')
+ ],
+ 'block': [
+ (r'\s+', token.Text),
+ (r'(-?)(%\})', bygroups(token.Text, token.Comment.Preproc), '#pop'),
+ include('varnames'),
+ (r'.', token.Punctuation)
+ ]
+ }
+
+ def analyse_text(text):
+ rv = 0.0
+ if re.search(r'\{%\s*(block|extends)', text) is not None:
+ rv += 0.4
+ if re.search(r'\{%\s*if\s*.*?%\}', text) is not None:
+ rv += 0.1
+ if re.search(r'\{\{.*?\}\}', text) is not None:
+ rv += 0.1
+ return rv
+
+
class AnsibleYamlJinjaLexer(DelegatingLexer):
"""
Subclass of the `DjangoLexer` that highlights unlexed data with the
@@ -474,7 +559,7 @@ class AnsibleYamlJinjaLexer(DelegatingLexer):
mimetypes = ['text/x-yaml+jinja']
def __init__(self, **options):
- super(AnsibleYamlJinjaLexer, self).__init__(AnsibleYamlLexer, DjangoLexer, **options)
+ super(AnsibleYamlJinjaLexer, self).__init__(AnsibleYamlLexer, AnsibleDjangoLexer, **options)
class AnsibleOutputPrimaryLexer(RegexLexer):
@@ -555,8 +640,8 @@ class AnsibleOutputPrimaryLexer(RegexLexer):
],
'host-error': [
- (r'(?:( )(UNREACHABLE|FAILED)(!))?',
- bygroups(token.Text, token.Keyword, token.Punctuation),
+ (r'(?:(:)( )(UNREACHABLE|FAILED)(!))?',
+ bygroups(token.Punctuation, token.Text, token.Keyword, token.Punctuation),
'host-postfix'),
(r'', token.Text, 'host-postfix'),
],
@@ -579,9 +664,12 @@ class AnsibleOutputPrimaryLexer(RegexLexer):
(r'(fatal|ok|changed|skipping)(:)( )',
bygroups(token.Keyword, token.Punctuation, token.Text),
'host-name'),
+ (r'(\[)(WARNING)(\]:)([^\n]+)',
+ bygroups(token.Punctuation, token.Keyword, token.Punctuation, token.Text)),
(r'([^ ]+)( +)(:)',
bygroups(token.Name, token.Text, token.Punctuation),
'host-result'),
+ (r'(\tto retry, use: )(.*)(\n)', bygroups(token.Text, token.Literal.String, token.Text)),
(r'.*\n', token.Other),
],
}
@@ -609,7 +697,12 @@ def setup(app):
""" Initializer for Sphinx extension API.
See http://www.sphinx-doc.org/en/stable/extdev/index.html#dev-extensions.
"""
- for lexer in [AnsibleYamlLexer(startinline=True), AnsibleYamlJinjaLexer(startinline=True), AnsibleOutputLexer(startinline=True)]:
+ for lexer in [
+ AnsibleDjangoLexer(startinline=True),
+ AnsibleYamlLexer(startinline=True),
+ AnsibleYamlJinjaLexer(startinline=True),
+ AnsibleOutputLexer(startinline=True)
+ ]:
app.add_lexer(lexer.name, lexer)
for alias in lexer.aliases:
app.add_lexer(alias, lexer)
diff --git a/docs/docsite/rst/dev_guide/developing_modules_general.rst b/docs/docsite/rst/dev_guide/developing_modules_general.rst
index 8a8d8a7500..360d6bfe44 100644
--- a/docs/docsite/rst/dev_guide/developing_modules_general.rst
+++ b/docs/docsite/rst/dev_guide/developing_modules_general.rst
@@ -56,7 +56,7 @@ To create a new module:
3. Paste the content below into your new module file. It includes the :ref:`required Ansible format and documentation ` and some example code.
4. Modify and extend the code to do what you want your new module to do. See the :ref:`programming tips ` and :ref:`Python 3 compatibility ` pages for pointers on writing clean, concise module code.
-.. code:: python
+.. code-block:: python
#!/usr/bin/python
diff --git a/docs/docsite/rst/dev_guide/style_guide/index.rst b/docs/docsite/rst/dev_guide/style_guide/index.rst
index 50f158bfbe..fc1543812e 100644
--- a/docs/docsite/rst/dev_guide/style_guide/index.rst
+++ b/docs/docsite/rst/dev_guide/style_guide/index.rst
@@ -63,34 +63,46 @@ Sphinx will 'learn on the fly' when creating a hierarchy of headers.
To make our documents easy to read and to edit, we follow a standard set of header notations.
We use:
-* ``###`` with overline, for parts::
+* ``###`` with overline, for parts:
+
+.. code-block:: rst
###############
Developer guide
###############
-* ``***`` with overline, for chapters::
+* ``***`` with overline, for chapters:
+
+.. code-block:: rst
*******************
Ansible style guide
*******************
-* ``===`` for sections::
+* ``===`` for sections:
+
+.. code-block:: rst
Mechanical guidelines
=====================
-* ``---`` for subsections::
+* ``---`` for subsections:
+
+.. code-block:: rst
Internal navigation
-------------------
-* ``^^^`` for sub-subsections::
+* ``^^^`` for sub-subsections:
+
+.. code-block:: rst
Adding anchors
^^^^^^^^^^^^^^
-* ``"""`` for paragraphs::
+* ``"""`` for paragraphs:
+
+.. code-block:: rst
Paragraph that needs a title
""""""""""""""""""""""""""""
@@ -120,7 +132,9 @@ Adding anchors
Adding internal links
^^^^^^^^^^^^^^^^^^^^^
-* All internal links must use ``:ref:`` syntax. These links both point to the anchor defined above::
+* All internal links must use ``:ref:`` syntax. These links both point to the anchor defined above:
+
+.. code-block:: rst
:ref:`unique_page`
:ref:`this page `
@@ -137,7 +151,9 @@ If you include a local TOC:
* use the ``:local:`` directive so the page's main header is not included
* do not include a title
-The syntax is::
+The syntax is:
+
+.. code-block:: rst
.. contents::
:local:
diff --git a/docs/docsite/rst/plugins/inventory.rst b/docs/docsite/rst/plugins/inventory.rst
index af6fbf8da4..32119214df 100644
--- a/docs/docsite/rst/plugins/inventory.rst
+++ b/docs/docsite/rst/plugins/inventory.rst
@@ -55,7 +55,9 @@ Or for the openstack plugin:
# clouds.yml
plugin: openstack
-The ``auto`` inventory plugin is enabled by default and works by using the ``plugin`` field to indicate the plugin that should attempt to parse it. You can configure the whitelist/precedence of inventory plugins used to parse source using the `ansible.cfg` ['inventory'] ``enable_plugins`` list. After enabling the plugin and providing any required options you can view the populated inventory with ``ansible-inventory -i demo.aws_ec2.yml --graph``::
+The ``auto`` inventory plugin is enabled by default and works by using the ``plugin`` field to indicate the plugin that should attempt to parse it. You can configure the whitelist/precedence of inventory plugins used to parse source using the `ansible.cfg` ['inventory'] ``enable_plugins`` list. After enabling the plugin and providing any required options you can view the populated inventory with ``ansible-inventory -i demo.aws_ec2.yml --graph``:
+
+.. code-block:: text
@all:
|--@aws_ec2:
@@ -88,7 +90,9 @@ You can create dynamic groups using host variables with the constructed ``keyed_
# set the ansible_host variable to connect with the private IP address without changing the hostname
ansible_host: private_ip_address
-Now the output of ``ansible-inventory -i demo.aws_ec2.yml --graph``::
+Now the output of ``ansible-inventory -i demo.aws_ec2.yml --graph``:
+
+.. code-block:: text
@all:
|--@aws_ec2:
diff --git a/docs/docsite/rst/plugins/lookup.rst b/docs/docsite/rst/plugins/lookup.rst
index 4c509057e1..2eb0c94901 100644
--- a/docs/docsite/rst/plugins/lookup.rst
+++ b/docs/docsite/rst/plugins/lookup.rst
@@ -41,24 +41,20 @@ Using lookup plugins
Lookup plugins can be used anywhere you can use templating in Ansible: in a play, in variables file, or in a Jinja2 template for the :ref:`template ` module.
-.. code-block:: yaml
+.. code-block:: YAML+Jinja
vars:
file_contents: "{{lookup('file', 'path/to/file.txt')}}"
Lookups are an integral part of loops. Wherever you see ``with_``, the part after the underscore is the name of a lookup.
-This is also the reason most lookups output lists and take lists as input; for example, ``with_items`` uses the :ref:`items ` lookup:
-
-.. code-block:: yaml
+This is also the reason most lookups output lists and take lists as input; for example, ``with_items`` uses the :ref:`items ` lookup::
tasks:
- name: count to 3
debug: msg={{item}}
with_items: [1, 2, 3]
-You can combine lookups with :ref:`playbooks_filters`, :ref:`playbooks_tests` and even each other to do some complex data generation and manipulation. For example:
-
-.. code-block:: yaml
+You can combine lookups with :ref:`playbooks_filters`, :ref:`playbooks_tests` and even each other to do some complex data generation and manipulation. For example::
tasks:
- name: valid but useless and over complicated chained lookups and filters
@@ -77,6 +73,8 @@ To ignore errors::
- name: file doesnt exist, but i dont care .. file plugin itself warns anyways ...
debug: msg="{{ lookup('file', '/idontexist', errors='ignore') }}"
+.. code-block:: ansible-output
+
[WARNING]: Unable to find '/idontexist' in expected paths (use -vvvvv to see paths)
ok: [localhost] => {
@@ -89,6 +87,8 @@ To get a warning instead of a failure::
- name: file doesnt exist, let me know, but continue
debug: msg="{{ lookup('file', '/idontexist', errors='warn') }}"
+.. code-block:: ansible-output
+
[WARNING]: Unable to find '/idontexist' in expected paths (use -vvvvv to see paths)
[WARNING]: An unhandled exception occurred while running the lookup plugin 'file'. Error was a , original message: could not locate file in lookup: /idontexist
@@ -103,6 +103,8 @@ Fatal error (the default)::
- name: file doesnt exist, FAIL (this is the default)
debug: msg="{{ lookup('file', '/idontexist', errors='strict') }}"
+.. code-block:: ansible-output
+
[WARNING]: Unable to find '/idontexist' in expected paths (use -vvvvv to see paths)
fatal: [localhost]: FAILED! => {"msg": "An unhandled exception occurred while running the lookup plugin 'file'. Error was a , original message: could not locate file in lookup: /idontexist"}
@@ -120,7 +122,9 @@ The default behavior of ``lookup`` is to return a string of comma separated valu
This was done primarily to provide an easier and more consistent interface for interacting with the new ``loop`` keyword, while maintaining backwards compatibility with other uses of ``lookup``.
-The following examples are equivalent::
+The following examples are equivalent:
+
+.. code-block:: jinja
lookup('dict', dict_variable, wantlist=True)
@@ -128,7 +132,9 @@ The following examples are equivalent::
As demonstrated above the behavior of ``wantlist=True`` is implicit when using ``query``.
-Additionally, ``q`` was introduced as a shortform of ``query``::
+Additionally, ``q`` was introduced as a shortform of ``query``:
+
+.. code-block:: jinja
q('dict', dict_variable)
diff --git a/docs/docsite/rst/reference_appendices/YAMLSyntax.rst b/docs/docsite/rst/reference_appendices/YAMLSyntax.rst
index 717ee7f317..5f59fdc67a 100644
--- a/docs/docsite/rst/reference_appendices/YAMLSyntax.rst
+++ b/docs/docsite/rst/reference_appendices/YAMLSyntax.rst
@@ -170,7 +170,9 @@ you can use escapes::
The list of allowed escapes can be found in the YAML Specification under "Escape Sequences" (YAML 1.1) or "Escape Characters" (YAML 1.2).
-The following is invalid YAML::
+The following is invalid YAML:
+
+.. code-block:: text
foo: "an escaped \' single quote"
diff --git a/docs/docsite/rst/scenario_guides/guide_scaleway.rst b/docs/docsite/rst/scenario_guides/guide_scaleway.rst
index 1cc2d62587..5298574ee6 100644
--- a/docs/docsite/rst/scenario_guides/guide_scaleway.rst
+++ b/docs/docsite/rst/scenario_guides/guide_scaleway.rst
@@ -193,10 +193,14 @@ Create a file named ``scaleway_inventory.yml`` with the following content:
This inventory means that we want all hosts that got the tag ``web_server`` on the zones ``ams1`` and ``par1``.
Once you have configured this file, you can get the information using the following command:
-::
+.. code-block:: bash
$ ansible-inventory --list -i scaleway_inventory.yml
+The output will be:
+
+.. code-block:: yaml
+
{
"_meta": {
"hostvars": {
@@ -251,7 +255,7 @@ As the Scaleway API is S3 compatible, Ansible supports it natively through the m
You can find many examples in ``./test/legacy/roles/scaleway_s3``
-.. code-block:: yaml
+.. code-block:: yaml+jinja
- hosts: myserver
vars:
diff --git a/docs/docsite/rst/user_guide/playbooks_async.rst b/docs/docsite/rst/user_guide/playbooks_async.rst
index a4aa1264c7..0210801c2c 100644
--- a/docs/docsite/rst/user_guide/playbooks_async.rst
+++ b/docs/docsite/rst/user_guide/playbooks_async.rst
@@ -100,7 +100,7 @@ of tasks running concurrently, you can do it this way::
- 5
durations: "{{ item }}"
include_tasks: execute_batch.yml
- loop: "{{ sleep_durations | batch(2) | list }}"
+ loop: "{{ sleep_durations | batch(2) | list }}"
#####################
# execute_batch.yml
diff --git a/docs/docsite/rst/user_guide/playbooks_filters.rst b/docs/docsite/rst/user_guide/playbooks_filters.rst
index 6b268e1516..aebb56ffdf 100644
--- a/docs/docsite/rst/user_guide/playbooks_filters.rst
+++ b/docs/docsite/rst/user_guide/playbooks_filters.rst
@@ -904,7 +904,9 @@ style. For example the following::
{{ "Plain style (default)" | comment }}
-will produce this output::
+will produce this output:
+
+.. code-block:: text
#
# Plain style (default)
@@ -923,7 +925,9 @@ above, you can customize it with::
{{ "My Special Case" | comment(decoration="! ") }}
-producing::
+producing:
+
+.. code-block:: text
!
! My Special Case
@@ -935,7 +939,7 @@ It is also possible to fully customize the comment style::
That will create the following output:
-.. code-block:: sh
+.. code-block:: text
#######
#
@@ -1040,7 +1044,7 @@ To search a string with a regex, use the "regex_search" filter::
{{ 'ansible' | regex_search('(foobar)') }}
# case insensitive search in multiline mode
- {{ 'foo\nBAR' | regex_search("^bar", multiline=True, ignorecase=True) }}
+ {{ 'foo\nBAR' | regex_search("^bar", multiline=True, ignorecase=True) }}
To search for all occurrences of regex matches, use the "regex_findall" filter::