rdf-construct 0.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rdf_construct/__init__.py +12 -0
- rdf_construct/__main__.py +0 -0
- rdf_construct/cli.py +3429 -0
- rdf_construct/core/__init__.py +33 -0
- rdf_construct/core/config.py +116 -0
- rdf_construct/core/ordering.py +219 -0
- rdf_construct/core/predicate_order.py +212 -0
- rdf_construct/core/profile.py +157 -0
- rdf_construct/core/selector.py +64 -0
- rdf_construct/core/serialiser.py +232 -0
- rdf_construct/core/utils.py +89 -0
- rdf_construct/cq/__init__.py +77 -0
- rdf_construct/cq/expectations.py +365 -0
- rdf_construct/cq/formatters/__init__.py +45 -0
- rdf_construct/cq/formatters/json.py +104 -0
- rdf_construct/cq/formatters/junit.py +104 -0
- rdf_construct/cq/formatters/text.py +146 -0
- rdf_construct/cq/loader.py +300 -0
- rdf_construct/cq/runner.py +321 -0
- rdf_construct/diff/__init__.py +59 -0
- rdf_construct/diff/change_types.py +214 -0
- rdf_construct/diff/comparator.py +338 -0
- rdf_construct/diff/filters.py +133 -0
- rdf_construct/diff/formatters/__init__.py +71 -0
- rdf_construct/diff/formatters/json.py +192 -0
- rdf_construct/diff/formatters/markdown.py +210 -0
- rdf_construct/diff/formatters/text.py +195 -0
- rdf_construct/docs/__init__.py +60 -0
- rdf_construct/docs/config.py +238 -0
- rdf_construct/docs/extractors.py +603 -0
- rdf_construct/docs/generator.py +360 -0
- rdf_construct/docs/renderers/__init__.py +7 -0
- rdf_construct/docs/renderers/html.py +803 -0
- rdf_construct/docs/renderers/json.py +390 -0
- rdf_construct/docs/renderers/markdown.py +628 -0
- rdf_construct/docs/search.py +278 -0
- rdf_construct/docs/templates/html/base.html.jinja +44 -0
- rdf_construct/docs/templates/html/class.html.jinja +152 -0
- rdf_construct/docs/templates/html/hierarchy.html.jinja +28 -0
- rdf_construct/docs/templates/html/index.html.jinja +110 -0
- rdf_construct/docs/templates/html/instance.html.jinja +90 -0
- rdf_construct/docs/templates/html/namespaces.html.jinja +37 -0
- rdf_construct/docs/templates/html/property.html.jinja +124 -0
- rdf_construct/docs/templates/html/single_page.html.jinja +169 -0
- rdf_construct/lint/__init__.py +75 -0
- rdf_construct/lint/config.py +214 -0
- rdf_construct/lint/engine.py +396 -0
- rdf_construct/lint/formatters.py +327 -0
- rdf_construct/lint/rules.py +692 -0
- rdf_construct/localise/__init__.py +114 -0
- rdf_construct/localise/config.py +508 -0
- rdf_construct/localise/extractor.py +427 -0
- rdf_construct/localise/formatters/__init__.py +36 -0
- rdf_construct/localise/formatters/markdown.py +229 -0
- rdf_construct/localise/formatters/text.py +224 -0
- rdf_construct/localise/merger.py +346 -0
- rdf_construct/localise/reporter.py +356 -0
- rdf_construct/main.py +6 -0
- rdf_construct/merge/__init__.py +165 -0
- rdf_construct/merge/config.py +354 -0
- rdf_construct/merge/conflicts.py +281 -0
- rdf_construct/merge/formatters.py +426 -0
- rdf_construct/merge/merger.py +425 -0
- rdf_construct/merge/migrator.py +339 -0
- rdf_construct/merge/rules.py +377 -0
- rdf_construct/merge/splitter.py +1102 -0
- rdf_construct/puml2rdf/__init__.py +103 -0
- rdf_construct/puml2rdf/config.py +230 -0
- rdf_construct/puml2rdf/converter.py +420 -0
- rdf_construct/puml2rdf/merger.py +200 -0
- rdf_construct/puml2rdf/model.py +202 -0
- rdf_construct/puml2rdf/parser.py +565 -0
- rdf_construct/puml2rdf/validators.py +451 -0
- rdf_construct/refactor/__init__.py +72 -0
- rdf_construct/refactor/config.py +362 -0
- rdf_construct/refactor/deprecator.py +328 -0
- rdf_construct/refactor/formatters/__init__.py +8 -0
- rdf_construct/refactor/formatters/text.py +311 -0
- rdf_construct/refactor/renamer.py +294 -0
- rdf_construct/shacl/__init__.py +56 -0
- rdf_construct/shacl/config.py +166 -0
- rdf_construct/shacl/converters.py +520 -0
- rdf_construct/shacl/generator.py +364 -0
- rdf_construct/shacl/namespaces.py +93 -0
- rdf_construct/stats/__init__.py +29 -0
- rdf_construct/stats/collector.py +178 -0
- rdf_construct/stats/comparator.py +298 -0
- rdf_construct/stats/formatters/__init__.py +83 -0
- rdf_construct/stats/formatters/json.py +38 -0
- rdf_construct/stats/formatters/markdown.py +153 -0
- rdf_construct/stats/formatters/text.py +186 -0
- rdf_construct/stats/metrics/__init__.py +26 -0
- rdf_construct/stats/metrics/basic.py +147 -0
- rdf_construct/stats/metrics/complexity.py +137 -0
- rdf_construct/stats/metrics/connectivity.py +130 -0
- rdf_construct/stats/metrics/documentation.py +128 -0
- rdf_construct/stats/metrics/hierarchy.py +207 -0
- rdf_construct/stats/metrics/properties.py +88 -0
- rdf_construct/uml/__init__.py +22 -0
- rdf_construct/uml/context.py +194 -0
- rdf_construct/uml/mapper.py +371 -0
- rdf_construct/uml/odm_renderer.py +789 -0
- rdf_construct/uml/renderer.py +684 -0
- rdf_construct/uml/uml_layout.py +393 -0
- rdf_construct/uml/uml_style.py +613 -0
- rdf_construct-0.3.0.dist-info/METADATA +496 -0
- rdf_construct-0.3.0.dist-info/RECORD +110 -0
- rdf_construct-0.3.0.dist-info/WHEEL +4 -0
- rdf_construct-0.3.0.dist-info/entry_points.txt +3 -0
- rdf_construct-0.3.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
"""Search index generation for client-side documentation search."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import re
|
|
7
|
+
from dataclasses import asdict, dataclass
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import TYPE_CHECKING
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from rdf_construct.docs.config import DocsConfig
|
|
13
|
+
from rdf_construct.docs.extractors import ClassInfo, ExtractedEntities, InstanceInfo, PropertyInfo
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class SearchEntry:
|
|
18
|
+
"""A single entry in the search index."""
|
|
19
|
+
|
|
20
|
+
uri: str
|
|
21
|
+
qname: str
|
|
22
|
+
entity_type: str # class, object_property, datatype_property, instance
|
|
23
|
+
label: str
|
|
24
|
+
keywords: list[str]
|
|
25
|
+
url: str
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def extract_keywords(text: str | None) -> list[str]:
|
|
29
|
+
"""Extract searchable keywords from text.
|
|
30
|
+
|
|
31
|
+
Splits on whitespace and punctuation, lowercases, and removes
|
|
32
|
+
common stop words.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
text: Text to extract keywords from.
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
List of keyword strings.
|
|
39
|
+
"""
|
|
40
|
+
if not text:
|
|
41
|
+
return []
|
|
42
|
+
|
|
43
|
+
# Split on non-alphanumeric characters
|
|
44
|
+
words = re.split(r"[^a-zA-Z0-9]+", text.lower())
|
|
45
|
+
|
|
46
|
+
# Remove stop words and short words
|
|
47
|
+
stop_words = {
|
|
48
|
+
"a", "an", "the", "is", "are", "was", "were", "be", "been",
|
|
49
|
+
"being", "have", "has", "had", "do", "does", "did", "will",
|
|
50
|
+
"would", "could", "should", "may", "might", "must", "shall",
|
|
51
|
+
"can", "need", "of", "to", "in", "for", "on", "with", "at",
|
|
52
|
+
"by", "from", "as", "or", "and", "but", "if", "this", "that",
|
|
53
|
+
"which", "who", "whom", "whose", "what", "when", "where", "why",
|
|
54
|
+
"how", "all", "each", "every", "both", "few", "more", "most",
|
|
55
|
+
"other", "some", "such", "no", "not", "only", "same", "so",
|
|
56
|
+
"than", "too", "very", "just", "also", "any",
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
keywords = [w for w in words if w and len(w) > 2 and w not in stop_words]
|
|
60
|
+
return list(set(keywords)) # Remove duplicates
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def class_to_search_entry(
|
|
64
|
+
class_info: "ClassInfo",
|
|
65
|
+
config: "DocsConfig",
|
|
66
|
+
) -> SearchEntry:
|
|
67
|
+
"""Convert a ClassInfo to a SearchEntry.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
class_info: Class information.
|
|
71
|
+
config: Documentation configuration.
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
SearchEntry for the class.
|
|
75
|
+
"""
|
|
76
|
+
# Build keywords from various sources
|
|
77
|
+
keywords = []
|
|
78
|
+
|
|
79
|
+
# QName parts
|
|
80
|
+
if ":" in class_info.qname:
|
|
81
|
+
prefix, local = class_info.qname.split(":", 1)
|
|
82
|
+
keywords.extend(extract_keywords(local))
|
|
83
|
+
keywords.append(prefix.lower())
|
|
84
|
+
|
|
85
|
+
# Label
|
|
86
|
+
if class_info.label:
|
|
87
|
+
keywords.extend(extract_keywords(class_info.label))
|
|
88
|
+
|
|
89
|
+
# Definition
|
|
90
|
+
if class_info.definition:
|
|
91
|
+
keywords.extend(extract_keywords(class_info.definition))
|
|
92
|
+
|
|
93
|
+
# Superclass names
|
|
94
|
+
for uri in class_info.superclasses:
|
|
95
|
+
if "#" in str(uri):
|
|
96
|
+
keywords.extend(extract_keywords(str(uri).split("#")[-1]))
|
|
97
|
+
elif "/" in str(uri):
|
|
98
|
+
keywords.extend(extract_keywords(str(uri).split("/")[-1]))
|
|
99
|
+
|
|
100
|
+
from .config import entity_to_url
|
|
101
|
+
return SearchEntry(
|
|
102
|
+
uri=str(class_info.uri),
|
|
103
|
+
qname=class_info.qname,
|
|
104
|
+
entity_type="class",
|
|
105
|
+
label=class_info.label or class_info.qname,
|
|
106
|
+
keywords=list(set(keywords)),
|
|
107
|
+
url=entity_to_url(class_info.qname, "class", config),
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def property_to_search_entry(
|
|
112
|
+
prop_info: "PropertyInfo",
|
|
113
|
+
config: "DocsConfig",
|
|
114
|
+
) -> SearchEntry:
|
|
115
|
+
"""Convert a PropertyInfo to a SearchEntry.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
prop_info: Property information.
|
|
119
|
+
config: Documentation configuration.
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
SearchEntry for the property.
|
|
123
|
+
"""
|
|
124
|
+
keywords = []
|
|
125
|
+
|
|
126
|
+
# QName parts
|
|
127
|
+
if ":" in prop_info.qname:
|
|
128
|
+
prefix, local = prop_info.qname.split(":", 1)
|
|
129
|
+
keywords.extend(extract_keywords(local))
|
|
130
|
+
keywords.append(prefix.lower())
|
|
131
|
+
|
|
132
|
+
# Label
|
|
133
|
+
if prop_info.label:
|
|
134
|
+
keywords.extend(extract_keywords(prop_info.label))
|
|
135
|
+
|
|
136
|
+
# Definition
|
|
137
|
+
if prop_info.definition:
|
|
138
|
+
keywords.extend(extract_keywords(prop_info.definition))
|
|
139
|
+
|
|
140
|
+
# Property type
|
|
141
|
+
keywords.append(prop_info.property_type)
|
|
142
|
+
|
|
143
|
+
# Domain/range class names
|
|
144
|
+
for uri in prop_info.domain + prop_info.range:
|
|
145
|
+
if "#" in str(uri):
|
|
146
|
+
keywords.extend(extract_keywords(str(uri).split("#")[-1]))
|
|
147
|
+
elif "/" in str(uri):
|
|
148
|
+
keywords.extend(extract_keywords(str(uri).split("/")[-1]))
|
|
149
|
+
|
|
150
|
+
entity_type = f"{prop_info.property_type}_property"
|
|
151
|
+
|
|
152
|
+
from .config import entity_to_url
|
|
153
|
+
return SearchEntry(
|
|
154
|
+
uri=str(prop_info.uri),
|
|
155
|
+
qname=prop_info.qname,
|
|
156
|
+
entity_type=entity_type,
|
|
157
|
+
label=prop_info.label or prop_info.qname,
|
|
158
|
+
keywords=list(set(keywords)),
|
|
159
|
+
url=entity_to_url(prop_info.qname, entity_type, config),
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def instance_to_search_entry(
|
|
164
|
+
instance_info: "InstanceInfo",
|
|
165
|
+
config: "DocsConfig",
|
|
166
|
+
) -> SearchEntry:
|
|
167
|
+
"""Convert an InstanceInfo to a SearchEntry.
|
|
168
|
+
|
|
169
|
+
Args:
|
|
170
|
+
instance_info: Instance information.
|
|
171
|
+
config: Documentation configuration.
|
|
172
|
+
|
|
173
|
+
Returns:
|
|
174
|
+
SearchEntry for the instance.
|
|
175
|
+
"""
|
|
176
|
+
keywords = []
|
|
177
|
+
|
|
178
|
+
# QName parts
|
|
179
|
+
if ":" in instance_info.qname:
|
|
180
|
+
prefix, local = instance_info.qname.split(":", 1)
|
|
181
|
+
keywords.extend(extract_keywords(local))
|
|
182
|
+
keywords.append(prefix.lower())
|
|
183
|
+
|
|
184
|
+
# Label
|
|
185
|
+
if instance_info.label:
|
|
186
|
+
keywords.extend(extract_keywords(instance_info.label))
|
|
187
|
+
|
|
188
|
+
# Definition
|
|
189
|
+
if instance_info.definition:
|
|
190
|
+
keywords.extend(extract_keywords(instance_info.definition))
|
|
191
|
+
|
|
192
|
+
# Type names
|
|
193
|
+
for uri in instance_info.types:
|
|
194
|
+
if "#" in str(uri):
|
|
195
|
+
keywords.extend(extract_keywords(str(uri).split("#")[-1]))
|
|
196
|
+
elif "/" in str(uri):
|
|
197
|
+
keywords.extend(extract_keywords(str(uri).split("/")[-1]))
|
|
198
|
+
|
|
199
|
+
# Add "instance" as a keyword
|
|
200
|
+
keywords.append("instance")
|
|
201
|
+
|
|
202
|
+
from .config import entity_to_url
|
|
203
|
+
return SearchEntry(
|
|
204
|
+
uri=str(instance_info.uri),
|
|
205
|
+
qname=instance_info.qname,
|
|
206
|
+
entity_type="instance",
|
|
207
|
+
label=instance_info.label or instance_info.qname,
|
|
208
|
+
keywords=list(set(keywords)),
|
|
209
|
+
url=entity_to_url(instance_info.qname, "instance", config),
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def generate_search_index(
|
|
214
|
+
entities: "ExtractedEntities",
|
|
215
|
+
config: "DocsConfig",
|
|
216
|
+
) -> list[SearchEntry]:
|
|
217
|
+
"""Generate a search index from extracted entities.
|
|
218
|
+
|
|
219
|
+
Args:
|
|
220
|
+
entities: All extracted entities from the ontology.
|
|
221
|
+
config: Documentation configuration.
|
|
222
|
+
|
|
223
|
+
Returns:
|
|
224
|
+
List of SearchEntry objects for all entities.
|
|
225
|
+
"""
|
|
226
|
+
entries: list[SearchEntry] = []
|
|
227
|
+
|
|
228
|
+
# Classes
|
|
229
|
+
if config.include_classes:
|
|
230
|
+
for class_info in entities.classes:
|
|
231
|
+
entries.append(class_to_search_entry(class_info, config))
|
|
232
|
+
|
|
233
|
+
# Properties
|
|
234
|
+
if config.include_object_properties:
|
|
235
|
+
for prop_info in entities.object_properties:
|
|
236
|
+
entries.append(property_to_search_entry(prop_info, config))
|
|
237
|
+
|
|
238
|
+
if config.include_datatype_properties:
|
|
239
|
+
for prop_info in entities.datatype_properties:
|
|
240
|
+
entries.append(property_to_search_entry(prop_info, config))
|
|
241
|
+
|
|
242
|
+
if config.include_annotation_properties:
|
|
243
|
+
for prop_info in entities.annotation_properties:
|
|
244
|
+
entries.append(property_to_search_entry(prop_info, config))
|
|
245
|
+
|
|
246
|
+
# Instances
|
|
247
|
+
if config.include_instances:
|
|
248
|
+
for instance_info in entities.instances:
|
|
249
|
+
entries.append(instance_to_search_entry(instance_info, config))
|
|
250
|
+
|
|
251
|
+
return entries
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def write_search_index(
|
|
255
|
+
entries: list[SearchEntry],
|
|
256
|
+
output_dir: Path,
|
|
257
|
+
) -> Path:
|
|
258
|
+
"""Write the search index to a JSON file.
|
|
259
|
+
|
|
260
|
+
Args:
|
|
261
|
+
entries: List of search entries.
|
|
262
|
+
output_dir: Output directory.
|
|
263
|
+
|
|
264
|
+
Returns:
|
|
265
|
+
Path to the written search index file.
|
|
266
|
+
"""
|
|
267
|
+
output_path = output_dir / "search.json"
|
|
268
|
+
|
|
269
|
+
# Convert to serialisable format
|
|
270
|
+
data = {
|
|
271
|
+
"entities": [asdict(entry) for entry in entries],
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
275
|
+
with open(output_path, "w") as f:
|
|
276
|
+
json.dump(data, f, indent=2)
|
|
277
|
+
|
|
278
|
+
return output_path
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>{% block title %}{{ ontology.title or "Ontology Documentation" }}{% endblock %}</title>
|
|
7
|
+
<link rel="stylesheet" href="{{ config.base_url }}/assets/style.css">
|
|
8
|
+
{% block head %}{% endblock %}
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<header class="header">
|
|
12
|
+
<h1>{{ ontology.title or "Ontology Documentation" }}</h1>
|
|
13
|
+
{% if ontology.description %}
|
|
14
|
+
<p class="description">{{ ontology.description }}</p>
|
|
15
|
+
{% endif %}
|
|
16
|
+
</header>
|
|
17
|
+
|
|
18
|
+
<nav class="nav">
|
|
19
|
+
<a href="{{ config.base_url }}/index.html">Index</a>
|
|
20
|
+
<a href="{{ config.base_url }}/hierarchy.html">Hierarchy</a>
|
|
21
|
+
<a href="{{ config.base_url }}/namespaces.html">Namespaces</a>
|
|
22
|
+
</nav>
|
|
23
|
+
|
|
24
|
+
{% if config.include_search %}
|
|
25
|
+
<div class="search-box">
|
|
26
|
+
<input type="text" id="search-input" placeholder="Search entities...">
|
|
27
|
+
<ul id="search-results" class="search-results"></ul>
|
|
28
|
+
</div>
|
|
29
|
+
{% endif %}
|
|
30
|
+
|
|
31
|
+
<main>
|
|
32
|
+
{% block content %}{% endblock %}
|
|
33
|
+
</main>
|
|
34
|
+
|
|
35
|
+
<footer class="footer">
|
|
36
|
+
<p>Generated by <a href="https://github.com/aigora-de/rdf-construct">rdf-construct</a></p>
|
|
37
|
+
</footer>
|
|
38
|
+
|
|
39
|
+
{% if config.include_search %}
|
|
40
|
+
<script src="{{ config.base_url }}/assets/search.js"></script>
|
|
41
|
+
{% endif %}
|
|
42
|
+
{% block scripts %}{% endblock %}
|
|
43
|
+
</body>
|
|
44
|
+
</html>
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
{% extends "base.html.jinja" %}
|
|
2
|
+
|
|
3
|
+
{% block title %}{{ class_info.label or class_info.qname }} - {{ ontology.title or "Documentation" }}{% endblock %}
|
|
4
|
+
|
|
5
|
+
{% block content %}
|
|
6
|
+
<article class="entity-card">
|
|
7
|
+
<h1>{{ class_info.label or class_info.qname }} <span class="entity-type">Class</span></h1>
|
|
8
|
+
<p class="uri">{{ class_info.uri }}</p>
|
|
9
|
+
|
|
10
|
+
{% if class_info.definition %}
|
|
11
|
+
<p class="definition">{{ class_info.definition }}</p>
|
|
12
|
+
{% endif %}
|
|
13
|
+
|
|
14
|
+
{% if class_info.superclasses %}
|
|
15
|
+
<section class="section">
|
|
16
|
+
<h3>Superclasses</h3>
|
|
17
|
+
<ul class="entity-list">
|
|
18
|
+
{% for uri in class_info.superclasses %}
|
|
19
|
+
<li>
|
|
20
|
+
{% set found = namespace(value=false) %}
|
|
21
|
+
{% for c in classes %}
|
|
22
|
+
{% if c.uri|string == uri|string %}
|
|
23
|
+
<a href="{{ c.qname | entity_url('class') }}">{{ c.label or c.qname }}</a>
|
|
24
|
+
{% set found.value = true %}
|
|
25
|
+
{% endif %}
|
|
26
|
+
{% endfor %}
|
|
27
|
+
{% if not found.value %}
|
|
28
|
+
<code>{{ uri }}</code>
|
|
29
|
+
{% endif %}
|
|
30
|
+
</li>
|
|
31
|
+
{% endfor %}
|
|
32
|
+
</ul>
|
|
33
|
+
</section>
|
|
34
|
+
{% endif %}
|
|
35
|
+
|
|
36
|
+
{% if class_info.subclasses %}
|
|
37
|
+
<section class="section">
|
|
38
|
+
<h3>Subclasses</h3>
|
|
39
|
+
<ul class="entity-list">
|
|
40
|
+
{% for uri in class_info.subclasses %}
|
|
41
|
+
<li>
|
|
42
|
+
{% set found = namespace(value=false) %}
|
|
43
|
+
{% for c in classes %}
|
|
44
|
+
{% if c.uri|string == uri|string %}
|
|
45
|
+
<a href="{{ c.qname | entity_url('class') }}">{{ c.label or c.qname }}</a>
|
|
46
|
+
{% set found.value = true %}
|
|
47
|
+
{% endif %}
|
|
48
|
+
{% endfor %}
|
|
49
|
+
{% if not found.value %}
|
|
50
|
+
<code>{{ uri }}</code>
|
|
51
|
+
{% endif %}
|
|
52
|
+
</li>
|
|
53
|
+
{% endfor %}
|
|
54
|
+
</ul>
|
|
55
|
+
</section>
|
|
56
|
+
{% endif %}
|
|
57
|
+
|
|
58
|
+
{% if class_info.domain_of %}
|
|
59
|
+
<section class="section">
|
|
60
|
+
<h3>Properties (Domain)</h3>
|
|
61
|
+
<ul class="entity-list">
|
|
62
|
+
{% for prop in class_info.domain_of %}
|
|
63
|
+
<li>
|
|
64
|
+
<a href="{{ prop.qname | entity_url(prop.property_type + '_property') }}">
|
|
65
|
+
{{ prop.label or prop.qname }}
|
|
66
|
+
</a>
|
|
67
|
+
<span class="entity-type {{ prop.property_type }}">{{ prop.property_type }}</span>
|
|
68
|
+
</li>
|
|
69
|
+
{% endfor %}
|
|
70
|
+
</ul>
|
|
71
|
+
</section>
|
|
72
|
+
{% endif %}
|
|
73
|
+
|
|
74
|
+
{% if inherited_properties %}
|
|
75
|
+
<section class="section">
|
|
76
|
+
<h3>Inherited Properties</h3>
|
|
77
|
+
<ul class="entity-list">
|
|
78
|
+
{% for prop in inherited_properties %}
|
|
79
|
+
<li>
|
|
80
|
+
<a href="{{ prop.qname | entity_url(prop.property_type + '_property') }}">
|
|
81
|
+
{{ prop.label or prop.qname }}
|
|
82
|
+
</a>
|
|
83
|
+
<span class="entity-type {{ prop.property_type }}">{{ prop.property_type }}</span>
|
|
84
|
+
<span class="annotation">(inherited)</span>
|
|
85
|
+
</li>
|
|
86
|
+
{% endfor %}
|
|
87
|
+
</ul>
|
|
88
|
+
</section>
|
|
89
|
+
{% endif %}
|
|
90
|
+
|
|
91
|
+
{% if class_info.range_of %}
|
|
92
|
+
<section class="section">
|
|
93
|
+
<h3>Used as Range</h3>
|
|
94
|
+
<ul class="entity-list">
|
|
95
|
+
{% for prop in class_info.range_of %}
|
|
96
|
+
<li>
|
|
97
|
+
<a href="{{ prop.qname | entity_url(prop.property_type + '_property') }}">
|
|
98
|
+
{{ prop.label or prop.qname }}
|
|
99
|
+
</a>
|
|
100
|
+
</li>
|
|
101
|
+
{% endfor %}
|
|
102
|
+
</ul>
|
|
103
|
+
</section>
|
|
104
|
+
{% endif %}
|
|
105
|
+
|
|
106
|
+
{% if class_info.instances and config.include_instances %}
|
|
107
|
+
<section class="section">
|
|
108
|
+
<h3>Instances</h3>
|
|
109
|
+
<ul class="entity-list">
|
|
110
|
+
{% for uri in class_info.instances %}
|
|
111
|
+
<li>
|
|
112
|
+
{% set found = namespace(value=false) %}
|
|
113
|
+
{% for i in instances %}
|
|
114
|
+
{% if i.uri|string == uri|string %}
|
|
115
|
+
<a href="{{ i.qname | entity_url('instance') }}">{{ i.label or i.qname }}</a>
|
|
116
|
+
{% set found.value = true %}
|
|
117
|
+
{% endif %}
|
|
118
|
+
{% endfor %}
|
|
119
|
+
{% if not found.value %}
|
|
120
|
+
<code>{{ uri }}</code>
|
|
121
|
+
{% endif %}
|
|
122
|
+
</li>
|
|
123
|
+
{% endfor %}
|
|
124
|
+
</ul>
|
|
125
|
+
</section>
|
|
126
|
+
{% endif %}
|
|
127
|
+
|
|
128
|
+
{% if class_info.annotations %}
|
|
129
|
+
<section class="section">
|
|
130
|
+
<h3>Annotations</h3>
|
|
131
|
+
<table>
|
|
132
|
+
<thead>
|
|
133
|
+
<tr>
|
|
134
|
+
<th>Property</th>
|
|
135
|
+
<th>Value</th>
|
|
136
|
+
</tr>
|
|
137
|
+
</thead>
|
|
138
|
+
<tbody>
|
|
139
|
+
{% for name, values in class_info.annotations.items() %}
|
|
140
|
+
{% for value in values %}
|
|
141
|
+
<tr>
|
|
142
|
+
<td><code>{{ name }}</code></td>
|
|
143
|
+
<td>{{ value }}</td>
|
|
144
|
+
</tr>
|
|
145
|
+
{% endfor %}
|
|
146
|
+
{% endfor %}
|
|
147
|
+
</tbody>
|
|
148
|
+
</table>
|
|
149
|
+
</section>
|
|
150
|
+
{% endif %}
|
|
151
|
+
</article>
|
|
152
|
+
{% endblock %}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{% extends "base.html.jinja" %}
|
|
2
|
+
|
|
3
|
+
{% block title %}Class Hierarchy - {{ ontology.title or "Documentation" }}{% endblock %}
|
|
4
|
+
|
|
5
|
+
{% block content %}
|
|
6
|
+
<h2>Class Hierarchy</h2>
|
|
7
|
+
|
|
8
|
+
{% macro render_tree(nodes) %}
|
|
9
|
+
<ul class="hierarchy-tree">
|
|
10
|
+
{% for node in nodes %}
|
|
11
|
+
<li>
|
|
12
|
+
<a href="{{ node.class.qname | entity_url('class') }}">
|
|
13
|
+
{{ node.class.label or node.class.qname }}
|
|
14
|
+
</a>
|
|
15
|
+
{% if node.children %}
|
|
16
|
+
{{ render_tree(node.children) }}
|
|
17
|
+
{% endif %}
|
|
18
|
+
</li>
|
|
19
|
+
{% endfor %}
|
|
20
|
+
</ul>
|
|
21
|
+
{% endmacro %}
|
|
22
|
+
|
|
23
|
+
{% if hierarchy %}
|
|
24
|
+
{{ render_tree(hierarchy) }}
|
|
25
|
+
{% else %}
|
|
26
|
+
<p>No class hierarchy found.</p>
|
|
27
|
+
{% endif %}
|
|
28
|
+
{% endblock %}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
{% extends "base.html.jinja" %}
|
|
2
|
+
|
|
3
|
+
{% block title %}{{ ontology.title or "Ontology Documentation" }}{% endblock %}
|
|
4
|
+
|
|
5
|
+
{% block content %}
|
|
6
|
+
<section class="stats">
|
|
7
|
+
<div class="stat-card">
|
|
8
|
+
<div class="number">{{ total_classes }}</div>
|
|
9
|
+
<div class="label">Classes</div>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="stat-card">
|
|
12
|
+
<div class="number">{{ total_properties }}</div>
|
|
13
|
+
<div class="label">Properties</div>
|
|
14
|
+
</div>
|
|
15
|
+
{% if instances %}
|
|
16
|
+
<div class="stat-card">
|
|
17
|
+
<div class="number">{{ total_instances }}</div>
|
|
18
|
+
<div class="label">Instances</div>
|
|
19
|
+
</div>
|
|
20
|
+
{% endif %}
|
|
21
|
+
</section>
|
|
22
|
+
|
|
23
|
+
{% if classes %}
|
|
24
|
+
<section class="section">
|
|
25
|
+
<h2>Classes</h2>
|
|
26
|
+
<ul class="entity-list">
|
|
27
|
+
{% for class in classes %}
|
|
28
|
+
<li>
|
|
29
|
+
<a href="{{ class.qname | entity_url('class') }}">
|
|
30
|
+
{{ class.label or class.qname }}
|
|
31
|
+
</a>
|
|
32
|
+
{% if class.definition %}
|
|
33
|
+
<span class="definition">— {{ class.definition[:100] }}{% if class.definition|length > 100 %}...{% endif %}</span>
|
|
34
|
+
{% endif %}
|
|
35
|
+
</li>
|
|
36
|
+
{% endfor %}
|
|
37
|
+
</ul>
|
|
38
|
+
</section>
|
|
39
|
+
{% endif %}
|
|
40
|
+
|
|
41
|
+
{% if object_properties %}
|
|
42
|
+
<section class="section">
|
|
43
|
+
<h2>Object Properties</h2>
|
|
44
|
+
<ul class="entity-list">
|
|
45
|
+
{% for prop in object_properties %}
|
|
46
|
+
<li>
|
|
47
|
+
<a href="{{ prop.qname | entity_url('object_property') }}">
|
|
48
|
+
{{ prop.label or prop.qname }}
|
|
49
|
+
</a>
|
|
50
|
+
<span class="entity-type object">Object</span>
|
|
51
|
+
{% if prop.definition %}
|
|
52
|
+
<span class="definition">— {{ prop.definition[:80] }}{% if prop.definition|length > 80 %}...{% endif %}</span>
|
|
53
|
+
{% endif %}
|
|
54
|
+
</li>
|
|
55
|
+
{% endfor %}
|
|
56
|
+
</ul>
|
|
57
|
+
</section>
|
|
58
|
+
{% endif %}
|
|
59
|
+
|
|
60
|
+
{% if datatype_properties %}
|
|
61
|
+
<section class="section">
|
|
62
|
+
<h2>Datatype Properties</h2>
|
|
63
|
+
<ul class="entity-list">
|
|
64
|
+
{% for prop in datatype_properties %}
|
|
65
|
+
<li>
|
|
66
|
+
<a href="{{ prop.qname | entity_url('datatype_property') }}">
|
|
67
|
+
{{ prop.label or prop.qname }}
|
|
68
|
+
</a>
|
|
69
|
+
<span class="entity-type datatype">Datatype</span>
|
|
70
|
+
{% if prop.definition %}
|
|
71
|
+
<span class="definition">— {{ prop.definition[:80] }}{% if prop.definition|length > 80 %}...{% endif %}</span>
|
|
72
|
+
{% endif %}
|
|
73
|
+
</li>
|
|
74
|
+
{% endfor %}
|
|
75
|
+
</ul>
|
|
76
|
+
</section>
|
|
77
|
+
{% endif %}
|
|
78
|
+
|
|
79
|
+
{% if annotation_properties %}
|
|
80
|
+
<section class="section">
|
|
81
|
+
<h2>Annotation Properties</h2>
|
|
82
|
+
<ul class="entity-list">
|
|
83
|
+
{% for prop in annotation_properties %}
|
|
84
|
+
<li>
|
|
85
|
+
<a href="{{ prop.qname | entity_url('annotation_property') }}">
|
|
86
|
+
{{ prop.label or prop.qname }}
|
|
87
|
+
</a>
|
|
88
|
+
<span class="entity-type annotation">Annotation</span>
|
|
89
|
+
</li>
|
|
90
|
+
{% endfor %}
|
|
91
|
+
</ul>
|
|
92
|
+
</section>
|
|
93
|
+
{% endif %}
|
|
94
|
+
|
|
95
|
+
{% if instances and config.include_instances %}
|
|
96
|
+
<section class="section">
|
|
97
|
+
<h2>Instances</h2>
|
|
98
|
+
<ul class="entity-list">
|
|
99
|
+
{% for inst in instances %}
|
|
100
|
+
<li>
|
|
101
|
+
<a href="{{ inst.qname | entity_url('instance') }}">
|
|
102
|
+
{{ inst.label or inst.qname }}
|
|
103
|
+
</a>
|
|
104
|
+
<span class="entity-type instance">Instance</span>
|
|
105
|
+
</li>
|
|
106
|
+
{% endfor %}
|
|
107
|
+
</ul>
|
|
108
|
+
</section>
|
|
109
|
+
{% endif %}
|
|
110
|
+
{% endblock %}
|