Skip to content

Commit

Permalink
📚 Use new need-example directive for all examples (#1190)
Browse files Browse the repository at this point in the history
This commit removes the duplication of examples (as literal and rendered), by adding a `need-example` directive that handles both from the same source content.

This removes issues with inconsistencies, and also allows for consistent/centralised formatting of the examples.
  • Loading branch information
chrisjsewell authored Jun 3, 2024
1 parent 6e0d0eb commit 14fffc5
Show file tree
Hide file tree
Showing 20 changed files with 342 additions and 2,187 deletions.
7 changes: 7 additions & 0 deletions docs/_static/_css/sphinx_immaterial.css
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,10 @@ body {
width: 100%;
padding-right: 0.6em !important; /* note, this line can be removed in sphinx-design v0.6.1 */
}

.needs-example {
border: .05rem solid rgb(72,138,87);
padding-left: .5rem;
padding-right: .5rem;
padding-bottom: .5rem;
}
3 changes: 0 additions & 3 deletions docs/builders.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,6 @@ or :ref:`needflow` gets exported, if the option :ref:`export_id` is used in the

This allows to export specified filter results only.


|ex|:

.. code-block:: rst
.. needtable::
Expand Down
47 changes: 43 additions & 4 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,6 @@

rst_epilog = """
.. |ex| replace:: **Example**
.. |out| replace:: **Result**
.. |br| raw:: html
<br>
Expand Down Expand Up @@ -612,3 +608,46 @@ def custom_defined_func():

# Absolute path to the needs_report_template_file based on the conf.py directory
# needs_report_template = "/needs_templates/report_template.need" # Use custom report template

# -- custom extensions ---------------------------------------

from docutils import nodes # noqa: E402
from sphinx.application import Sphinx # noqa: E402
from sphinx.directives import SphinxDirective # noqa: E402


class NeedExampleDirective(SphinxDirective):
"""Directive to add example content to the documentation.
It adds a container with a title, a code block, and a parsed content block.
"""

optional_arguments = 1
final_argument_whitespace = True
has_content = True

def run(self):
count = self.env.temp_data.setdefault("needs-example-count", 0)
count += 1
self.env.temp_data["needs-example-count"] = count
root = nodes.container(classes=["needs-example"])
self.set_source_info(root)
title = f"Example {count}"
title_nodes, _ = (
self.state.inline_text(f"{title}: {self.arguments[0]}", self.lineno)
if self.arguments
else ([nodes.Text(title)], [])
)
root += nodes.rubric("", "", *title_nodes)
code = nodes.literal_block(
"", "\n".join(self.content), language="rst", classes=["needs-example-raw"]
)
root += code
parsed = nodes.container(classes=["needs-example-raw"])
root += parsed
self.state.nested_parse(self.content, self.content_offset, parsed)
return [root]


def setup(app: Sphinx):
app.add_directive("need-example", NeedExampleDirective)
133 changes: 26 additions & 107 deletions docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -343,28 +343,15 @@ Configuration example:
The above example configuration allows the following usage:
|ex|
.. code-block:: rst
.. need-example::
.. req:: My requirement
:id: EXTRA_REQ_001
:id: EXTRA_REQ_001
.. test:: Test of requirements
:id: EXTRA_TEST_001
:checks: EXTRA_REQ_001, DEAD_LINK_NOT_ALLOWED
:triggers: DEAD_LINK
|out|
.. req:: My requirement
:id: EXTRA_REQ_001
.. test:: Test of requirements
:id: EXTRA_TEST_001
:checks: EXTRA_REQ_001, DEAD_LINK_NOT_ALLOWED
:triggers: DEAD_LINK
:id: EXTRA_TEST_001
:checks: EXTRA_REQ_001, DEAD_LINK_NOT_ALLOWED
:triggers: DEAD_LINK
.. attention:: The used option name can not be reused in the configuration of :ref:`needs_global_options`.
Expand Down Expand Up @@ -541,8 +528,6 @@ Fields can be added or existing fields can even be manipulated.
If set to False, the filter results contains the original need fields and any manipulations of need fields are lost.
|ex|
.. code-block:: python
needs_allow_unsafe_filters = True
Expand Down Expand Up @@ -611,21 +596,13 @@ These configs can then be selected when using :ref:`needflow`.
This configurations can then be used like this:
|ex|
.. need-example::
.. code-block:: rst
.. needflow::
:tags: flow_example
:types: spec
:config: my_config
|out|
.. needflow::
:tags: flow_example
:types: spec
:config: my_config
.. needflow::
:tags: flow_example
:types: spec
:config: my_config
See :ref:`needflow config option <needflow_config>` for more details and already available configurations.
Expand Down Expand Up @@ -809,11 +786,9 @@ needs_id_from_title
Generates needs ID from title. By default, this setting is set to **False**.
When no need ID is given by the user, and `needs_id_from_title` is set to **True**, then a need ID
will be calculated based on the current need directive prefix, title, and a hased value from title.
will be calculated based on the current need directive prefix, title, and a hashed value from title.
|ex|
.. code-block:: rst
.. need-example::
.. req:: Group big short
Expand Down Expand Up @@ -853,27 +828,17 @@ A title can be auto-generated for a requirement by either setting
:ref:`needs_title_from_content` to **True** or providing the flag
`:title_from_content:` as follows:
|ex|
The resulting requirement would have the title derived from the first
sentence of the requirement.
.. code-block:: rst
.. need-example::
.. req::
:title_from_content:
This will be my title. Anything after the first sentence will not be
part of the title.
The resulting requirement would have the title derived from the first
sentence of the requirement.
|out|
.. req::
:title_from_content:
This will be my title. Anything after the first sentence will not be
part of the title.
.. _needs_title_from_content:
Expand All @@ -896,22 +861,12 @@ setting (which is not limited by default).
If a title is specified for an individual requirement, then that title
will be used over the generated title.
|ex|
.. code-block:: rst
.. need-example::
.. req::
The tool must have error logging. All critical errors must be
written to the console.
This will render the first sentence as the title
.. req::
The tool must have error logging. All critical errors must be
written to the console.
The tool must have error logging.
All critical errors must be written to the console.
.. _needs_max_title_length:
Expand Down Expand Up @@ -1710,9 +1665,7 @@ link name and url.
}
|ex|
.. code-block:: rst
.. need-example::
.. spec:: Use needs_string_links
:id: EXAMPLE_STRING_LINKS
Expand All @@ -1721,15 +1674,6 @@ link name and url.
Replaces the string from ``:config:`` and ``:github:`` with a link to the related website.
|out|
.. spec:: Use needs_string_links
:id: EXAMPLE_STRING_LINKS
:config: needs_string_links
:github: 404,652
Replaces the string from ``:config:`` and ``:github:`` with a link to the related website.
.. note::
You must define the options specified under :ref:`needs_string_links` inside :ref:`needs_extra_options` as well.
Expand Down Expand Up @@ -2024,9 +1968,7 @@ needs_variants
``needs_variants`` configuration option must be a dictionary which has pre-defined variants assigned to
"filter strings". The filter string defines which variant a need belongs in the current situations.
|ex|
In ``conf.py``:
For example, in ``conf.py``:
.. code-block:: python
Expand All @@ -2049,9 +1991,7 @@ needs_variant_options
``needs_variant_options`` must be a list which consists of the options to apply variants handling.
You can specify the names of the options you want to check for variants.
|ex|
In ``conf.py``:
for example, in ``conf.py``:
.. code-block:: python
Expand Down Expand Up @@ -2082,58 +2022,37 @@ Configuration example:
def custom_defined_func():
return "my_tag"
def sum_example(number_1, number_2):
return number_1 + number_2
needs_render_context = {
"custom_data_1": "Project_X",
"custom_data_2": custom_defined_func(),
"custom_data_3": True,
"custom_data_4": [("Daniel", 811982), ("Marco", 234232)],
"sum_example": sum_example
}
The``needs_render_context`` configuration option must be a dictionary.
The dictionary consists of key-value pairs where the key is a string used as reference to the value.
The value can be any data type (string, integer, list, dict, etc.) or a custom defined function, which return
value is used or the function itself can be used (see ``sum_example``).
The value can be any data type (string, integer, list, dict, etc.)
.. warning:: The value can also be a custom defined function,
however, this will deactivate the caching and incremental build feature of Sphinx.
The data passed via needs_render_context will be available as variable(s) when rendering Jinja templates or strings.
You can use the data passed via needs_render_context as shown below:
|ex|
.. code-block:: jinja
.. need-example::
.. req:: Need with jinja_content enabled
:id: JINJA1D8913
:jinja_content: true
Need with alias {{ custom_data_1 }} and ``jinja_content`` option set to {{ custom_data_3 }}.
4 + 5 = {{ sum_example(4,5) }}
{{ custom_data_2 }}
{% for author in custom_data_4 %}
* author[0]
+ author[1]
{% endfor %}
.. req:: Need with jinja_content enabled
:id: JINJA1D8913
:jinja_content: true
Need with alias {{ custom_data_1 }} and ``jinja_content`` option set to {{ custom_data_3 }}.
{{ custom_data_2 }}
{% for author in custom_data_4 %}
* {{ author[0] }} --> ID-{{ author[1] }}
{% endfor %}
.. _needs_debug_measurement:
Expand Down
Loading

0 comments on commit 14fffc5

Please sign in to comment.