diff --git a/strictdoc/core/query_engine/grammar.py b/strictdoc/core/query_engine/grammar.py index b1a420bf3..60f519fab 100644 --- a/strictdoc/core/query_engine/grammar.py +++ b/strictdoc/core/query_engine/grammar.py @@ -37,6 +37,8 @@ | NotInExpression | + NodeContainsExpression + | NodeIsRequirementExpression | NodeIsSectionExpression @@ -60,6 +62,10 @@ 'node["' field_name = /[A-Za-z0-9]+/ '"]' ; +NodeContainsExpression: + 'node.contains("' string = /[A-Za-z0-9]+/ '")' +; + NodeHasParentRequirementsExpression: _ = 'node.has_parent_requirements' ; diff --git a/strictdoc/core/query_engine/query_object.py b/strictdoc/core/query_engine/query_object.py index 622d4e1b5..983f0bbc7 100644 --- a/strictdoc/core/query_engine/query_object.py +++ b/strictdoc/core/query_engine/query_object.py @@ -1,7 +1,10 @@ from typing import List, Optional from strictdoc.backend.sdoc.models.document_grammar import GrammarElement -from strictdoc.backend.sdoc.models.requirement import Requirement +from strictdoc.backend.sdoc.models.requirement import ( + Requirement, + RequirementField, +) from strictdoc.backend.sdoc.models.section import Section from strictdoc.core.traceability_index import TraceabilityIndex from strictdoc.helpers.cast import assert_cast @@ -28,6 +31,12 @@ def __init__(self, parent, field_name: str): self.field_name = field_name +class NodeContainsExpression: + def __init__(self, parent, string: str): + self.parent = parent + self.string: str = string + + class NodeHasParentRequirementsExpression: def __init__(self, parent, _): self.parent = parent @@ -117,6 +126,8 @@ def _evaluate(self, node, expression) -> bool: return self._evaluate_equal(node, expression) if isinstance(expression, NotEqualExpression): return self._evaluate_not_equal(node, expression) + if isinstance(expression, NodeContainsExpression): + return self._evaluate_node_contains(node, expression) if isinstance(expression, NodeHasParentRequirementsExpression): return self._evaluate_node_has_parent_requirements(node) if isinstance(expression, NodeHasChildRequirementsExpression): @@ -217,3 +228,27 @@ def _evaluate_node_has_child_requirements(self, node): f"the error, prepend your query with node.is_requirement." ) return self.traceability_index.has_children_requirements(node) + + def _evaluate_node_contains( + self, node, expression: NodeContainsExpression + ) -> bool: + if isinstance(node, Requirement): + requirement = assert_cast(node, Requirement) + requirement_field_: RequirementField + for requirement_field_ in requirement.enumerate_fields(): + if requirement_field_.field_value is not None: + if expression.string in requirement_field_.field_value: + return True + elif requirement_field_.field_value_multiline is not None: + if ( + expression.string + in requirement_field_.field_value_multiline + ): + return True + return False + if isinstance(node, Section): + section = assert_cast(node, Section) + if expression.string in section.title: + return True + return False + raise NotImplementedError diff --git a/strictdoc/core/query_engine/query_reader.py b/strictdoc/core/query_engine/query_reader.py index 4e967a9ed..1968f0790 100644 --- a/strictdoc/core/query_engine/query_reader.py +++ b/strictdoc/core/query_engine/query_reader.py @@ -5,25 +5,27 @@ AndExpression, EqualExpression, InExpression, + NodeContainsExpression, NodeFieldExpression, + NodeHasChildRequirementsExpression, NodeHasParentRequirementsExpression, NodeIsRequirementExpression, + NodeIsRootExpression, NodeIsSectionExpression, + NoneExpression, NotEqualExpression, NotExpression, + NotInExpression, OrExpression, Query, StringExpression, - NodeIsRootExpression, - NotInExpression, - NoneExpression, - NodeHasChildRequirementsExpression, ) QUERY_MODELS = [ AndExpression, EqualExpression, InExpression, + NodeContainsExpression, NodeFieldExpression, NodeHasChildRequirementsExpression, NodeHasParentRequirementsExpression, diff --git a/strictdoc/export/html/templates/screens/project_statistics/main.jinja b/strictdoc/export/html/templates/screens/project_statistics/main.jinja index 7137789d2..641e1c55d 100644 --- a/strictdoc/export/html/templates/screens/project_statistics/main.jinja +++ b/strictdoc/export/html/templates/screens/project_statistics/main.jinja @@ -180,11 +180,31 @@ TBD/TBC - Total TBD + {% if project_config.is_activated_search() %} + + + Total TBD + + + {% else %} + Total TBD + {% endif %} {{ document_tree_stats.total_tbd }} - Total TBC + {% if project_config.is_activated_search() %} + + + Total TBC + + + {% else %} + Total TBC + {% endif %} {{ document_tree_stats.total_tbc }}