diff --git a/ekglib/maturity_model_parser/capability.py b/ekglib/maturity_model_parser/capability.py index 7ee6eca..8865989 100644 --- a/ekglib/maturity_model_parser/capability.py +++ b/ekglib/maturity_model_parser/capability.py @@ -23,6 +23,7 @@ def __init__(self, area: MaturityModelCapabilityArea, capability_node: Node, mkd self.mkdocs = mkdocs self.name = self.graph.name_for(self.capability_node, self.class_label) + self.number = self.graph.capability_number_for(self.capability_node, self.class_label) self.local_name = self.graph.local_name_for(self.capability_node, self.class_label) self.local_type_name = self.graph.local_type_name_for(self.capability_node, self.class_label) self.full_dir = self.area.full_dir / self.local_type_name / self.local_name @@ -32,7 +33,7 @@ def __init__(self, area: MaturityModelCapabilityArea, capability_node: Node, mkd def generate_markdown(self): self.generate_link_from_area_to_capability() self.md_file = MarkdownDocument(path=self.full_dir / 'index.md', metadata={ - "title": self.name + "title": f"{self.number}. {self.name}" }) self.generate_summary() self.md_file.create_md_file() @@ -50,9 +51,10 @@ def summaries(self): def generate_summary(self): # self.md_file.heading(2, "Summary") self.md_file.write( - f"The capability _{self.name}_\n" + f"The capability _{self.name}_ ({self.number})\n" f"is part of the capability area [_{self.area.name}_](../../index.md)\n" - f"in the [_{self.area.pillar.name}_](../../index.md)." + f"in the [_{self.area.pillar.name}_](../../index.md).", + wrap_width=0 ) self.md_file.write("\n") for summary in self.summaries(): @@ -71,7 +73,7 @@ def generate_index_md(cls, area: MaturityModelCapabilityArea): f'An overview of all the capabilities in the area _{area.name}_:\n\n' ) for capability in area.capabilities(): - md_file.heading(2, f"[{capability.name}](./{capability.local_name}/)") + md_file.heading(2, f"{capability.number}. [{capability.name}](./{capability.local_name}/)") for summary in capability.summaries(): md_file.write(str(summary).strip(), wrap_width=0) md_file.write("\n\n") diff --git a/ekglib/maturity_model_parser/capability_area.py b/ekglib/maturity_model_parser/capability_area.py index f5f5c85..07303e4 100644 --- a/ekglib/maturity_model_parser/capability_area.py +++ b/ekglib/maturity_model_parser/capability_area.py @@ -8,6 +8,7 @@ from .markdown_document import MarkdownDocument from .pages_yaml import PagesYaml from .pillar import MaturityModelPillar +from ..log.various import value_error, log_item from ..namespace import MATURIY_MODEL @@ -32,12 +33,13 @@ def __init__(self, pillar: MaturityModelPillar, area_node: Node, mkdocs: bool): makedirs(self.full_dir, self.class_label) def generate_markdown(self): + from .capability import MaturityModelCapability self.generate_link_from_pillar_to_capability_area() self.md_file = MarkdownDocument(path=self.full_path, metadata={ 'title': self.name }) self.summary() - self.md_file.heading(2, "Capabilities") + self.md_file.heading(2, MaturityModelCapability.class_label_plural) self.generate_capabilities() self.md_file.create_md_file() @@ -57,12 +59,26 @@ def generate_link_from_pillar_to_capability_area(self): link=str(link), text=self.name )) - def capabiliy_nodes(self): - return self.graph.g.subjects(MATURIY_MODEL.inArea, self.area_node) + def capabiliy_nodes_unsorted(self): + for capability_node in self.graph.g.subjects(MATURIY_MODEL.inArea, self.area_node): + yield capability_node + + def sort_key(self, element): + for sort_key in self.graph.g.objects(element, MATURIY_MODEL.sortKey): + log_item("Sort key of", f"{sort_key} -> {element}") + return str(sort_key) + sort_key = str(element) + log_item("No sort key for", element) + return sort_key + + def capability_nodes(self): + nodes = list(self.capabiliy_nodes_unsorted()) + nodes.sort(key=self.sort_key) + return nodes def capabilities_non_cached(self): from .capability import MaturityModelCapability - for capability_node in self.capabiliy_nodes(): + for capability_node in self.capability_nodes(): yield MaturityModelCapability(self, capability_node, self.mkdocs) def capabilities(self): diff --git a/ekglib/maturity_model_parser/graph.py b/ekglib/maturity_model_parser/graph.py index f9cdf04..e5c60c0 100644 --- a/ekglib/maturity_model_parser/graph.py +++ b/ekglib/maturity_model_parser/graph.py @@ -37,6 +37,12 @@ def name_for(self, subject_uri, hint: str) -> str: return name raise value_error(f"{hint} has no label: {subject_uri}") + def capability_number_for(self, capability_node, hint: str): + for number in self.g.objects(capability_node, MATURIY_MODEL.capabilityNumber): + log_item(f"{hint} Number", number) + return str(number) + raise value_error(f"{hint} has no capabilityNumber: {capability_node}") + def local_name_for(self, subject_node: Node, hint: str) -> str: for local_name in self.g.objects(subject_node, MATURIY_MODEL.iriLocalName): log_item(f"{hint} Local Name", local_name) @@ -143,5 +149,14 @@ def rewrite_fragment_references(self, fragments_root: Path): self.g.remove((subject, predicate, objekt)) self.g.add((subject, predicate, Literal(str(fragment_path)))) + def create_sort_keys(self): + """ Generate sortKeys for anything with an ekgmm:capabilityNumber """ + for subject, capability_number in self.g.subject_objects(MATURIY_MODEL.capabilityNumber): + capability_number_parts = str(capability_number).split('.') + if len(capability_number_parts) != 3: + raise value_error(f"{subject} has an invalid number: {capability_number}") + sort_key = f'{capability_number_parts[0]}.{capability_number_parts[1]:0>3}.{capability_number_parts[2]:0>3}' + self.g.add((subject, MATURIY_MODEL.sortKey, Literal(sort_key))) + diff --git a/ekglib/maturity_model_parser/loader.py b/ekglib/maturity_model_parser/loader.py index 25846a0..e7711b3 100644 --- a/ekglib/maturity_model_parser/loader.py +++ b/ekglib/maturity_model_parser/loader.py @@ -13,7 +13,7 @@ from ..kgiri import EKG_NS from ..log import error, log_item from ..main import load_rdf_file_into_graph -from ..namespace import RULE, PROV, RAW, DATAOPS, DATASET +from ..namespace import RULE, PROV, RAW, DATAOPS, DATASET, MATURIY_MODEL OWL._fail = False # workaround for this issue: https://github.com/RDFLib/OWL-RL/issues/53 DefinedNamespaceMeta._warn = False @@ -75,6 +75,7 @@ def load(self) -> MaturityModelGraph: if len(list(graph.models())) == 0: raise value_error("No models loaded") graph.rewrite_fragment_references(self.fragments_root) + graph.create_sort_keys() return graph def load_ontology_from_stream(self, ontology_stream: BytesIO):