rdf-construct 0.2.1__py3-none-any.whl → 0.4.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 +1 -1
- rdf_construct/cli.py +1794 -0
- rdf_construct/describe/__init__.py +93 -0
- rdf_construct/describe/analyzer.py +176 -0
- rdf_construct/describe/documentation.py +146 -0
- rdf_construct/describe/formatters/__init__.py +47 -0
- rdf_construct/describe/formatters/json.py +65 -0
- rdf_construct/describe/formatters/markdown.py +275 -0
- rdf_construct/describe/formatters/text.py +315 -0
- rdf_construct/describe/hierarchy.py +232 -0
- rdf_construct/describe/imports.py +213 -0
- rdf_construct/describe/metadata.py +187 -0
- rdf_construct/describe/metrics.py +145 -0
- rdf_construct/describe/models.py +552 -0
- rdf_construct/describe/namespaces.py +180 -0
- rdf_construct/describe/profiles.py +415 -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/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/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-0.2.1.dist-info → rdf_construct-0.4.0.dist-info}/METADATA +91 -6
- {rdf_construct-0.2.1.dist-info → rdf_construct-0.4.0.dist-info}/RECORD +43 -7
- {rdf_construct-0.2.1.dist-info → rdf_construct-0.4.0.dist-info}/WHEEL +0 -0
- {rdf_construct-0.2.1.dist-info → rdf_construct-0.4.0.dist-info}/entry_points.txt +0 -0
- {rdf_construct-0.2.1.dist-info → rdf_construct-0.4.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
"""URI renaming logic for ontology refactoring.
|
|
2
|
+
|
|
3
|
+
This module handles renaming URIs in RDF graphs:
|
|
4
|
+
- Single entity renames (fixing typos, etc.)
|
|
5
|
+
- Bulk namespace changes (project/org renames)
|
|
6
|
+
- Predicate position handling (URIs as predicates are also renamed)
|
|
7
|
+
|
|
8
|
+
The renamer does NOT modify text inside literals - comments mentioning
|
|
9
|
+
renamed entities are left unchanged (this is intentional to avoid
|
|
10
|
+
corrupting documentation).
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from dataclasses import dataclass, field
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import Any
|
|
16
|
+
|
|
17
|
+
from rdflib import Graph, URIRef, Literal, BNode
|
|
18
|
+
|
|
19
|
+
from rdf_construct.refactor.config import RenameConfig, RenameMapping
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass
|
|
23
|
+
class RenameStats:
|
|
24
|
+
"""Statistics from a rename operation.
|
|
25
|
+
|
|
26
|
+
Attributes:
|
|
27
|
+
subjects_renamed: URIs renamed in subject position.
|
|
28
|
+
predicates_renamed: URIs renamed in predicate position.
|
|
29
|
+
objects_renamed: URIs renamed in object position.
|
|
30
|
+
entities_by_source: Count of entities by mapping source.
|
|
31
|
+
literal_mentions: Count of mentions in literals (NOT renamed).
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
subjects_renamed: int = 0
|
|
35
|
+
predicates_renamed: int = 0
|
|
36
|
+
objects_renamed: int = 0
|
|
37
|
+
entities_by_source: dict[str, int] = field(default_factory=dict)
|
|
38
|
+
literal_mentions: dict[str, int] = field(default_factory=dict)
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def total_renames(self) -> int:
|
|
42
|
+
"""Total number of URI substitutions made."""
|
|
43
|
+
return self.subjects_renamed + self.predicates_renamed + self.objects_renamed
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def namespace_entities(self) -> int:
|
|
47
|
+
"""Number of entities renamed by namespace rules."""
|
|
48
|
+
return self.entities_by_source.get("namespace", 0)
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def explicit_entities(self) -> int:
|
|
52
|
+
"""Number of entities renamed by explicit rules."""
|
|
53
|
+
return self.entities_by_source.get("explicit", 0)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@dataclass
|
|
57
|
+
class RenameResult:
|
|
58
|
+
"""Result of a rename operation.
|
|
59
|
+
|
|
60
|
+
Attributes:
|
|
61
|
+
renamed_graph: The graph with URIs renamed.
|
|
62
|
+
stats: Rename statistics.
|
|
63
|
+
success: Whether the operation succeeded.
|
|
64
|
+
error: Error message if success is False.
|
|
65
|
+
mappings_applied: List of mappings that were actually applied.
|
|
66
|
+
source_triples: Original triple count.
|
|
67
|
+
result_triples: Final triple count.
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
renamed_graph: Graph | None = None
|
|
71
|
+
stats: RenameStats = field(default_factory=RenameStats)
|
|
72
|
+
success: bool = True
|
|
73
|
+
error: str | None = None
|
|
74
|
+
mappings_applied: list[RenameMapping] = field(default_factory=list)
|
|
75
|
+
source_triples: int = 0
|
|
76
|
+
result_triples: int = 0
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class OntologyRenamer:
|
|
80
|
+
"""Renames URIs in RDF ontology graphs.
|
|
81
|
+
|
|
82
|
+
Handles both single entity renames and bulk namespace changes.
|
|
83
|
+
The renamer processes subjects, predicates, and objects, but
|
|
84
|
+
intentionally leaves literal values unchanged.
|
|
85
|
+
|
|
86
|
+
Example usage:
|
|
87
|
+
renamer = OntologyRenamer()
|
|
88
|
+
config = RenameConfig(entities={
|
|
89
|
+
"http://example.org/Buiding": "http://example.org/Building"
|
|
90
|
+
})
|
|
91
|
+
result = renamer.rename(graph, config)
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
def rename(
|
|
95
|
+
self,
|
|
96
|
+
graph: Graph,
|
|
97
|
+
config: RenameConfig,
|
|
98
|
+
) -> RenameResult:
|
|
99
|
+
"""Rename URIs in a graph according to configuration.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
graph: Source RDF graph.
|
|
103
|
+
config: Rename configuration with namespace and entity mappings.
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
RenameResult with the modified graph and statistics.
|
|
107
|
+
"""
|
|
108
|
+
result = RenameResult()
|
|
109
|
+
result.source_triples = len(graph)
|
|
110
|
+
|
|
111
|
+
# Build concrete mappings from config
|
|
112
|
+
mappings = config.build_mappings(graph)
|
|
113
|
+
if not mappings:
|
|
114
|
+
# Nothing to rename
|
|
115
|
+
result.renamed_graph = graph
|
|
116
|
+
result.result_triples = len(graph)
|
|
117
|
+
return result
|
|
118
|
+
|
|
119
|
+
# Create URI lookup map for efficient substitution
|
|
120
|
+
uri_map: dict[URIRef, tuple[URIRef, str]] = {
|
|
121
|
+
m.from_uri: (m.to_uri, m.source) for m in mappings
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
# Track which mappings were actually applied
|
|
125
|
+
applied_mappings: set[URIRef] = set()
|
|
126
|
+
|
|
127
|
+
# Create new graph with renamed URIs
|
|
128
|
+
renamed_graph = Graph()
|
|
129
|
+
|
|
130
|
+
# Copy namespace bindings, updating if needed
|
|
131
|
+
old_ns_to_new: dict[str, str] = {}
|
|
132
|
+
if config.namespaces:
|
|
133
|
+
old_ns_to_new = config.namespaces
|
|
134
|
+
|
|
135
|
+
for prefix, ns in graph.namespace_manager.namespaces():
|
|
136
|
+
ns_str = str(ns)
|
|
137
|
+
new_ns_str = ns_str
|
|
138
|
+
for old_ns, new_ns in old_ns_to_new.items():
|
|
139
|
+
if ns_str.startswith(old_ns) or ns_str == old_ns:
|
|
140
|
+
new_ns_str = ns_str.replace(old_ns, new_ns, 1)
|
|
141
|
+
break
|
|
142
|
+
renamed_graph.bind(prefix, new_ns_str, override=True)
|
|
143
|
+
|
|
144
|
+
# Process each triple
|
|
145
|
+
for s, p, o in graph:
|
|
146
|
+
new_s, new_p, new_o = s, p, o
|
|
147
|
+
|
|
148
|
+
# Check subject
|
|
149
|
+
if isinstance(s, URIRef) and s in uri_map:
|
|
150
|
+
new_s = uri_map[s][0]
|
|
151
|
+
result.stats.subjects_renamed += 1
|
|
152
|
+
applied_mappings.add(s)
|
|
153
|
+
source = uri_map[s][1]
|
|
154
|
+
result.stats.entities_by_source[source] = (
|
|
155
|
+
result.stats.entities_by_source.get(source, 0) + 1
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
# Check predicate
|
|
159
|
+
if isinstance(p, URIRef) and p in uri_map:
|
|
160
|
+
new_p = uri_map[p][0]
|
|
161
|
+
result.stats.predicates_renamed += 1
|
|
162
|
+
applied_mappings.add(p)
|
|
163
|
+
# Don't double-count in entities_by_source
|
|
164
|
+
|
|
165
|
+
# Check object (only URIRefs, not Literals)
|
|
166
|
+
if isinstance(o, URIRef) and o in uri_map:
|
|
167
|
+
new_o = uri_map[o][0]
|
|
168
|
+
result.stats.objects_renamed += 1
|
|
169
|
+
applied_mappings.add(o)
|
|
170
|
+
# Don't double-count in entities_by_source
|
|
171
|
+
|
|
172
|
+
renamed_graph.add((new_s, new_p, new_o))
|
|
173
|
+
|
|
174
|
+
# Scan for literal mentions (informational only)
|
|
175
|
+
for mapping in mappings:
|
|
176
|
+
old_local = str(mapping.from_uri).split("#")[-1].split("/")[-1]
|
|
177
|
+
for s, p, o in graph:
|
|
178
|
+
if isinstance(o, Literal) and old_local in str(o):
|
|
179
|
+
key = str(mapping.from_uri)
|
|
180
|
+
result.stats.literal_mentions[key] = (
|
|
181
|
+
result.stats.literal_mentions.get(key, 0) + 1
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
# Build list of applied mappings
|
|
185
|
+
result.mappings_applied = [m for m in mappings if m.from_uri in applied_mappings]
|
|
186
|
+
|
|
187
|
+
result.renamed_graph = renamed_graph
|
|
188
|
+
result.result_triples = len(renamed_graph)
|
|
189
|
+
result.success = True
|
|
190
|
+
|
|
191
|
+
return result
|
|
192
|
+
|
|
193
|
+
def rename_single(
|
|
194
|
+
self,
|
|
195
|
+
graph: Graph,
|
|
196
|
+
from_uri: str,
|
|
197
|
+
to_uri: str,
|
|
198
|
+
) -> RenameResult:
|
|
199
|
+
"""Convenience method for renaming a single URI.
|
|
200
|
+
|
|
201
|
+
Args:
|
|
202
|
+
graph: Source RDF graph.
|
|
203
|
+
from_uri: URI to rename.
|
|
204
|
+
to_uri: New URI.
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
RenameResult with the modified graph.
|
|
208
|
+
"""
|
|
209
|
+
config = RenameConfig(entities={from_uri: to_uri})
|
|
210
|
+
return self.rename(graph, config)
|
|
211
|
+
|
|
212
|
+
def rename_namespace(
|
|
213
|
+
self,
|
|
214
|
+
graph: Graph,
|
|
215
|
+
from_namespace: str,
|
|
216
|
+
to_namespace: str,
|
|
217
|
+
) -> RenameResult:
|
|
218
|
+
"""Convenience method for bulk namespace rename.
|
|
219
|
+
|
|
220
|
+
Args:
|
|
221
|
+
graph: Source RDF graph.
|
|
222
|
+
from_namespace: Old namespace prefix.
|
|
223
|
+
to_namespace: New namespace prefix.
|
|
224
|
+
|
|
225
|
+
Returns:
|
|
226
|
+
RenameResult with the modified graph.
|
|
227
|
+
"""
|
|
228
|
+
config = RenameConfig(namespaces={from_namespace: to_namespace})
|
|
229
|
+
return self.rename(graph, config)
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def rename_file(
|
|
233
|
+
source_path: Path,
|
|
234
|
+
output_path: Path,
|
|
235
|
+
config: RenameConfig,
|
|
236
|
+
) -> RenameResult:
|
|
237
|
+
"""Convenience function to rename URIs in a file.
|
|
238
|
+
|
|
239
|
+
Args:
|
|
240
|
+
source_path: Path to source RDF file.
|
|
241
|
+
output_path: Path to write renamed output.
|
|
242
|
+
config: Rename configuration.
|
|
243
|
+
|
|
244
|
+
Returns:
|
|
245
|
+
RenameResult with statistics.
|
|
246
|
+
"""
|
|
247
|
+
# Load source graph
|
|
248
|
+
graph = Graph()
|
|
249
|
+
try:
|
|
250
|
+
graph.parse(source_path.as_posix())
|
|
251
|
+
except Exception as e:
|
|
252
|
+
result = RenameResult()
|
|
253
|
+
result.success = False
|
|
254
|
+
result.error = f"Failed to parse {source_path}: {e}"
|
|
255
|
+
return result
|
|
256
|
+
|
|
257
|
+
# Perform rename
|
|
258
|
+
renamer = OntologyRenamer()
|
|
259
|
+
result = renamer.rename(graph, config)
|
|
260
|
+
|
|
261
|
+
if not result.success:
|
|
262
|
+
return result
|
|
263
|
+
|
|
264
|
+
# Write output
|
|
265
|
+
if result.renamed_graph:
|
|
266
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
267
|
+
result.renamed_graph.serialize(destination=output_path.as_posix(), format="turtle")
|
|
268
|
+
|
|
269
|
+
return result
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def rename_files(
|
|
273
|
+
source_paths: list[Path],
|
|
274
|
+
output_dir: Path,
|
|
275
|
+
config: RenameConfig,
|
|
276
|
+
) -> list[tuple[Path, RenameResult]]:
|
|
277
|
+
"""Rename URIs in multiple files.
|
|
278
|
+
|
|
279
|
+
Args:
|
|
280
|
+
source_paths: Paths to source RDF files.
|
|
281
|
+
output_dir: Directory to write renamed outputs.
|
|
282
|
+
config: Rename configuration.
|
|
283
|
+
|
|
284
|
+
Returns:
|
|
285
|
+
List of (output_path, result) tuples.
|
|
286
|
+
"""
|
|
287
|
+
results: list[tuple[Path, RenameResult]] = []
|
|
288
|
+
|
|
289
|
+
for source_path in source_paths:
|
|
290
|
+
output_path = output_dir / source_path.name
|
|
291
|
+
result = rename_file(source_path, output_path, config)
|
|
292
|
+
results.append((output_path, result))
|
|
293
|
+
|
|
294
|
+
return results
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rdf-construct
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Semantic RDF manipulation toolkit - order, serialize, and diff RDF ontologies
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -10,7 +10,7 @@ Author-email: 23141680+aigora-de@users.noreply.github.com
|
|
|
10
10
|
Maintainer: Dave Dyke
|
|
11
11
|
Maintainer-email: 23141680+aigora-de@users.noreply.github.com
|
|
12
12
|
Requires-Python: >=3.10
|
|
13
|
-
Classifier: Development Status ::
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
14
|
Classifier: Intended Audience :: Developers
|
|
15
15
|
Classifier: Intended Audience :: Science/Research
|
|
16
16
|
Classifier: Intended Audience :: Information Technology
|
|
@@ -50,16 +50,22 @@ Description-Content-Type: text/markdown
|
|
|
50
50
|
## Features
|
|
51
51
|
|
|
52
52
|
- **Semantic Ordering**: Serialise RDF/Turtle with intelligent ordering instead of alphabetical chaos
|
|
53
|
+
- **Ontology Description**: Quick orientation to unfamiliar ontologies with profile detection
|
|
53
54
|
- **Documentation Generation**: Create navigable HTML, Markdown, or JSON documentation from ontologies
|
|
54
55
|
- **UML Generation**: Create PlantUML class diagrams from RDF ontologies
|
|
55
56
|
- **PUML2RDF**: Convert PlantUML diagrams to RDF/OWL ontologies (diagram-first design)
|
|
56
57
|
- **SHACL Generation**: Generate SHACL validation shapes from OWL definitions
|
|
57
58
|
- **Semantic Diff**: Compare ontology versions and identify meaningful changes
|
|
59
|
+
- **Ontology Merging**: Combine multiple ontologies with conflict detection and data migration
|
|
60
|
+
- **Ontology Splitting**: Split monolithic ontologies into modules with dependency tracking
|
|
61
|
+
- **Ontology Refactoring**: Rename URIs and deprecate entities with OWL annotations
|
|
62
|
+
- **Multi-Language Support**: Extract, translate, and merge translations for internationalised ontologies
|
|
58
63
|
- **Ontology Linting**: Check quality with 11 configurable rules
|
|
59
64
|
- **Competency Question Testing**: Validate ontologies against SPARQL-based tests
|
|
60
65
|
- **Ontology Statistics**: Comprehensive metrics with comparison mode
|
|
61
66
|
- **Flexible Styling**: Configure colours, layouts, and visual themes for diagrams
|
|
62
67
|
- **Profile-Based**: Define multiple strategies in YAML configuration
|
|
68
|
+
- **Multi-Format Input**: Supports Turtle, RDF/XML, JSON-LD, N-Triples
|
|
63
69
|
- **Deterministic**: Same input + profile = same output, always
|
|
64
70
|
|
|
65
71
|
## Why?
|
|
@@ -89,6 +95,19 @@ pip install -e .
|
|
|
89
95
|
poetry install
|
|
90
96
|
```
|
|
91
97
|
|
|
98
|
+
### Describe an Ontology
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# Quick orientation to an unfamiliar ontology
|
|
102
|
+
rdf-construct describe ontology.ttl
|
|
103
|
+
|
|
104
|
+
# Brief summary (metadata + metrics + profile)
|
|
105
|
+
rdf-construct describe ontology.ttl --brief
|
|
106
|
+
|
|
107
|
+
# JSON output for scripting
|
|
108
|
+
rdf-construct describe ontology.ttl --format json
|
|
109
|
+
```
|
|
110
|
+
|
|
92
111
|
### Compare Ontology Versions
|
|
93
112
|
|
|
94
113
|
```bash
|
|
@@ -177,20 +196,80 @@ rdf-construct stats ontology.ttl
|
|
|
177
196
|
rdf-construct stats v1.ttl v2.ttl --compare --format markdown
|
|
178
197
|
```
|
|
179
198
|
|
|
199
|
+
### Merge Ontologies
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
# Basic merge
|
|
203
|
+
rdf-construct merge core.ttl extension.ttl -o merged.ttl
|
|
204
|
+
|
|
205
|
+
# With priorities (higher wins conflicts)
|
|
206
|
+
rdf-construct merge core.ttl extension.ttl -o merged.ttl -p 1 -p 2
|
|
207
|
+
|
|
208
|
+
# Generate conflict report
|
|
209
|
+
rdf-construct merge core.ttl extension.ttl -o merged.ttl --report conflicts.md
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Split Ontologies
|
|
213
|
+
```bash
|
|
214
|
+
# Split by namespace (auto-detect modules)
|
|
215
|
+
rdf-construct split large.ttl -o modules/ --by-namespace
|
|
216
|
+
|
|
217
|
+
# Split with configuration file
|
|
218
|
+
rdf-construct split large.ttl -o modules/ -c split.yml
|
|
219
|
+
|
|
220
|
+
# Preview what would be created
|
|
221
|
+
rdf-construct split large.ttl -o modules/ --by-namespace --dry-run
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Refactor Ontologies
|
|
225
|
+
```bash
|
|
226
|
+
# Fix a typo
|
|
227
|
+
rdf-construct refactor rename ontology.ttl \
|
|
228
|
+
--from "ex:Buiding" --to "ex:Building" -o fixed.ttl
|
|
229
|
+
|
|
230
|
+
# Bulk namespace change
|
|
231
|
+
rdf-construct refactor rename ontology.ttl \
|
|
232
|
+
--from-namespace "http://old/" --to-namespace "http://new/" -o migrated.ttl
|
|
233
|
+
|
|
234
|
+
# Deprecate an entity with replacement
|
|
235
|
+
rdf-construct refactor deprecate ontology.ttl \
|
|
236
|
+
--entity "ex:LegacyClass" --replaced-by "ex:NewClass" \
|
|
237
|
+
--message "Use NewClass instead." -o updated.ttl
|
|
238
|
+
|
|
239
|
+
# Preview changes
|
|
240
|
+
rdf-construct refactor rename ontology.ttl --from "ex:Old" --to "ex:New" --dry-run
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Multi-Language Translations
|
|
244
|
+
```bash
|
|
245
|
+
# Extract strings for German translation
|
|
246
|
+
rdf-construct localise extract ontology.ttl --language de -o translations/de.yml
|
|
247
|
+
|
|
248
|
+
# Merge completed translations
|
|
249
|
+
rdf-construct localise merge ontology.ttl translations/de.yml -o localised.ttl
|
|
250
|
+
|
|
251
|
+
# Check translation coverage
|
|
252
|
+
rdf-construct localise report ontology.ttl --languages en,de,fr
|
|
253
|
+
```
|
|
254
|
+
|
|
180
255
|
## Documentation
|
|
181
256
|
|
|
182
257
|
📚 **[Complete Documentation](docs/index.md)** - Start here
|
|
183
258
|
|
|
184
259
|
**For Users**:
|
|
185
260
|
- [Getting Started](docs/user_guides/GETTING_STARTED.md) - 5-minute quick start
|
|
261
|
+
- [Describe Guide](docs/user_guides/DESCRIBE_GUIDE.md) - Quick ontology orientation
|
|
186
262
|
- [Docs Guide](docs/user_guides/DOCS_GUIDE.md) - Documentation generation
|
|
187
263
|
- [UML Guide](docs/user_guides/UML_GUIDE.md) - Complete UML features
|
|
188
|
-
- [
|
|
264
|
+
- [PUML2RDF Guide](docs/user_guides/PUML2RDF_GUIDE.md) - Diagram-first design
|
|
189
265
|
- [SHACL Guide](docs/user_guides/SHACL_GUIDE.md) - SHACL shape generation
|
|
190
266
|
- [Diff Guide](docs/user_guides/DIFF_GUIDE.md) - Semantic ontology comparison
|
|
191
267
|
- [Lint Guide](docs/user_guides/LINT_GUIDE.md) - Ontology quality checking
|
|
192
268
|
- [CQ Testing Guide](docs/user_guides/CQ_TEST_GUIDE.md) - Competency question testing
|
|
193
269
|
- [Stats Guide](docs/user_guides/STATS_GUIDE.md) - Ontology metrics
|
|
270
|
+
- [Merge & Split Guide](docs/user_guides/MERGE_SPLIT_GUIDE.md) - Combining and modularising ontologies
|
|
271
|
+
- [Refactor Guide](docs/user_guides/REFACTOR_GUIDE.md) - Renaming and deprecation
|
|
272
|
+
- [Localise Guide](docs/user_guides/LOCALISE_GUIDE.md) - Multi-language translations
|
|
194
273
|
- [CLI Reference](docs/user_guides/CLI_REFERENCE.md) - All commands and options
|
|
195
274
|
|
|
196
275
|
**For Developers**:
|
|
@@ -346,7 +425,7 @@ properties:
|
|
|
346
425
|
|
|
347
426
|
## Project Status
|
|
348
427
|
|
|
349
|
-
**Current**: v0.
|
|
428
|
+
**Current**: v0.4.0 - Feature complete for core ontology workflows
|
|
350
429
|
**License**: MIT
|
|
351
430
|
|
|
352
431
|
### Implemented
|
|
@@ -362,10 +441,15 @@ properties:
|
|
|
362
441
|
✅ Ontology linting (11 rules)
|
|
363
442
|
✅ Competency question testing
|
|
364
443
|
✅ Ontology statistics
|
|
444
|
+
✅ Ontology merging and splitting
|
|
445
|
+
✅ Ontology refactoring (rename, deprecate)
|
|
446
|
+
✅ Multi-language translation management
|
|
447
|
+
✅ Ontology description and profile detection
|
|
448
|
+
✅ Multi-format input support (Turtle, RDF/XML, JSON-LD, N-Triples)
|
|
365
449
|
✅ Comprehensive documentation
|
|
366
450
|
|
|
367
451
|
### (Possible) Roadmap
|
|
368
|
-
- [ ]
|
|
452
|
+
- [ ] OWL 2 named profile detection (EL, RL, QL)
|
|
369
453
|
- [ ] Streaming mode for very large graphs
|
|
370
454
|
- [ ] Web UI for diagram configuration
|
|
371
455
|
- [ ] Additional lint rules
|
|
@@ -428,6 +512,7 @@ MIT License - see [LICENSE](LICENSE) file for details.
|
|
|
428
512
|
|
|
429
513
|
---
|
|
430
514
|
|
|
431
|
-
**Status**: v0.
|
|
515
|
+
**Status**: v0.4.0
|
|
432
516
|
**Python**: 3.10+ required
|
|
433
517
|
**Maintainer**: See [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
518
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
rdf_construct/__init__.py,sha256=
|
|
1
|
+
rdf_construct/__init__.py,sha256=9M_dNYQYdJqwwXnwonajTNqDJrxQQWUNk5SVd4nlkGM,296
|
|
2
2
|
rdf_construct/__main__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
rdf_construct/cli.py,sha256=
|
|
3
|
+
rdf_construct/cli.py,sha256=Z3iMI_w8pLWAOAAwKk6IwAx-O2HuiHChUUjCPooVPeY,108330
|
|
4
4
|
rdf_construct/core/__init__.py,sha256=YgxXUPGHgBqToc8u06qksfWh_vx25g2eCg8_X8vg5l4,781
|
|
5
5
|
rdf_construct/core/config.py,sha256=uOAvvZ7keI8o4o6r6ESzHC4AkKHN1Ja2FADiHZqZDaM,3523
|
|
6
6
|
rdf_construct/core/ordering.py,sha256=fGw5aGIY8SpsGgbm1Z1YH5mzlDv7mU7b9Is07ekJxZg,7248
|
|
@@ -17,6 +17,20 @@ rdf_construct/cq/formatters/junit.py,sha256=Jd019364vFZXKfNO6wxBwtlXe7FGPN7OpdE1
|
|
|
17
17
|
rdf_construct/cq/formatters/text.py,sha256=GI059SUomtyXDorxlQ7Whc7eHpw9AeyPnkwnwiIndco,4278
|
|
18
18
|
rdf_construct/cq/loader.py,sha256=at224OKu6Y7JKdJU-JRd03_54Q2m0bSCRhZ9R0pWEEU,8771
|
|
19
19
|
rdf_construct/cq/runner.py,sha256=QqkobjHHjxSdO2XeFaOHjBx5wrcokJme94QQhNgDHkA,9930
|
|
20
|
+
rdf_construct/describe/__init__.py,sha256=hAFzlKXNoB0y13eaW6QkJHP8dXNHuJF703TEOVjCn3M,2465
|
|
21
|
+
rdf_construct/describe/analyzer.py,sha256=LlCDGEN3HBKIG5AE8zu_6WaKTvi-ifK6Hu4FFxAxwbc,5140
|
|
22
|
+
rdf_construct/describe/documentation.py,sha256=4lpMl2fz4IK52QbZV6aTIl5BZL1lniPkJjGeWiuM0eQ,3987
|
|
23
|
+
rdf_construct/describe/formatters/__init__.py,sha256=sE2PYrT87pDvmaD168aA0EVKsVusSyOOumSP7du0rA0,1385
|
|
24
|
+
rdf_construct/describe/formatters/json.py,sha256=TVjLVqZqajQ85y32LnXXVZz_Xgt4R-zVczorHFmzNEQ,1473
|
|
25
|
+
rdf_construct/describe/formatters/markdown.py,sha256=ZQFvgsvfT0dVXQX5yiQjQJ1w6nxB9zdFMEtsIv0pfTU,8761
|
|
26
|
+
rdf_construct/describe/formatters/text.py,sha256=80BmUsga1i6BoLONNCROUk7N-irOIMo0Ahn59M8v448,10066
|
|
27
|
+
rdf_construct/describe/hierarchy.py,sha256=sFSL3Lia7-fJcAEPLZJ0z6htvGxvUVK8VRDbUVkCsgA,6243
|
|
28
|
+
rdf_construct/describe/imports.py,sha256=y8JwMBvPGdEiWn-AolRVhINB4VhXT6VIrNWHMeAvGvk,6585
|
|
29
|
+
rdf_construct/describe/metadata.py,sha256=DHvEWicLYi0PJ2xqrEevHmH-S-VGuQLZqV2lSTALas0,5518
|
|
30
|
+
rdf_construct/describe/metrics.py,sha256=3M33xnQwUcAD_7j9Gp4T5tO3ge01_RbE7f9FqIWPS_4,4260
|
|
31
|
+
rdf_construct/describe/models.py,sha256=g-dLZnnpj-H1s-6RAuAQZJacQEQj7kTCmxbW8nv-MRo,18720
|
|
32
|
+
rdf_construct/describe/namespaces.py,sha256=n7NpxK-qNq6Jyj4QuXEUNsw-kwVC_z0s6r7_stbZ9vU,5403
|
|
33
|
+
rdf_construct/describe/profiles.py,sha256=7pHd8MV1OhJuepqkKZco_39oEOrywofs-6SpNxPAMWw,13245
|
|
20
34
|
rdf_construct/diff/__init__.py,sha256=EewERur1p2ynqpyzwGFzpPS-E5DkA-VJEGO7QX9VhLU,1378
|
|
21
35
|
rdf_construct/diff/change_types.py,sha256=t12h6O6WQSrpSJdzTutuOXLB1fqm8gTob5gIhAfQ8rU,6383
|
|
22
36
|
rdf_construct/diff/comparator.py,sha256=e1bmXPJS-tkyC9Flopl6R8wcP5wHK8Tsk0-ngpUxwDc,10247
|
|
@@ -47,7 +61,23 @@ rdf_construct/lint/config.py,sha256=aMrP-B8UNlI-8lgegG0i6go_7UzXOmctskcEWZ3iL-s,
|
|
|
47
61
|
rdf_construct/lint/engine.py,sha256=Eppc9ax6FiAPWVQa71xBM2tKCDd9mhFL8VYplMhjAGE,12362
|
|
48
62
|
rdf_construct/lint/formatters.py,sha256=IG6jPXn0YmyNAc2PnU5ZcPluGPQHnUt5PCysPuq7tMc,10019
|
|
49
63
|
rdf_construct/lint/rules.py,sha256=qkC_cGNMnd9fnq13dP30Hzao_1paZt_iS8y3t_6PEMk,22177
|
|
64
|
+
rdf_construct/localise/__init__.py,sha256=fKPOZ_TzvvQ-Yz_hR733sy5wM4zArpp4D-hyVO8HTdo,2659
|
|
65
|
+
rdf_construct/localise/config.py,sha256=7n0Ld1zT5YYNahB3DXeqbQpu4SFdd1lniXWlRK5wBOQ,15847
|
|
66
|
+
rdf_construct/localise/extractor.py,sha256=HxIjNi8EiOHQ_IcN48Os2RRoQIlBOi1aUolWFzbbgE8,13592
|
|
67
|
+
rdf_construct/localise/formatters/__init__.py,sha256=i2Mlo62BBUs7ywhncr6GDK4nVzdzdRB6EtSpdTZCw_w,948
|
|
68
|
+
rdf_construct/localise/formatters/markdown.py,sha256=ayKbma2SsO3pr5KIaJElU3-nqilxawXGnoUl1thwNUw,7572
|
|
69
|
+
rdf_construct/localise/formatters/text.py,sha256=AESBDjD89QzhkaMMq4UZYHM0bffLVnRAgOg8U7Es8jA,7596
|
|
70
|
+
rdf_construct/localise/merger.py,sha256=X5Wj_bKHWeiR4XqRxFvKVbCuklBneuvscoDDC0PnnbI,10480
|
|
71
|
+
rdf_construct/localise/reporter.py,sha256=idsMsKbzR2JXhJNBvVGz504fpIMMfh6R5Mi3_rtDeq4,10828
|
|
50
72
|
rdf_construct/main.py,sha256=k3Lm5MY9gO_q-mIchCoUMOJU5veeQSXHPEGzICUZ5NU,107
|
|
73
|
+
rdf_construct/merge/__init__.py,sha256=mK2cWplLhPsGoDbNGh9PPGm8AGeQ8w3n1mBH0JReCxM,3730
|
|
74
|
+
rdf_construct/merge/config.py,sha256=AelWI6AMmLwR7o-y7PEIypQrMlgL4j2Heswsw_hS6TA,10415
|
|
75
|
+
rdf_construct/merge/conflicts.py,sha256=3sTvIm5L_g8aNkjwkDaB660HMaM4rliBSTqels0RaFU,8944
|
|
76
|
+
rdf_construct/merge/formatters.py,sha256=OsMicZUMoLTmPZkgs6VQTeoB484fRfkEyCrlUt5yHdQ,14810
|
|
77
|
+
rdf_construct/merge/merger.py,sha256=kF3JNy3Ze0KB_cGs_RyC05U99f1ly7ULYsMak7LR0_c,13651
|
|
78
|
+
rdf_construct/merge/migrator.py,sha256=6_4AUxf8PL0CWQVuItsSxVyoEg-ClYsPY_F9GckCqjg,11318
|
|
79
|
+
rdf_construct/merge/rules.py,sha256=-Txf1-EuSMhWnGVNwnoI4Dt-qtxUQ5f5zfDDlCigzMw,11663
|
|
80
|
+
rdf_construct/merge/splitter.py,sha256=rom12dbPANi01KFmF8oY6J7-4526uMuQuZZLP2jDesg,36006
|
|
51
81
|
rdf_construct/puml2rdf/__init__.py,sha256=H6OCPA15ucd3snMNA08Nsnf3LJYizTwZrFRzmXQnd44,2247
|
|
52
82
|
rdf_construct/puml2rdf/config.py,sha256=FwTR--KsS2i5dwKi81LUZ9QcGF4h9OF1LquJl_dlhqw,7200
|
|
53
83
|
rdf_construct/puml2rdf/converter.py,sha256=uvhAdotxKP8uXP3X0XFsLjnP1cCNGcKkbqrbobPIwl4,14669
|
|
@@ -55,6 +85,12 @@ rdf_construct/puml2rdf/merger.py,sha256=xEyk5d6AoeA49d-7mYhqgeEExCDxCakcgvdofOoe
|
|
|
55
85
|
rdf_construct/puml2rdf/model.py,sha256=L73spx4XTmo99i1SfeNNoKMOXRMPA7MsUWonDSydsgE,6187
|
|
56
86
|
rdf_construct/puml2rdf/parser.py,sha256=I_8nF6wPcuZGZ5ihRUd8t42AoDSs_Hv1OhRjS_Zlyds,18608
|
|
57
87
|
rdf_construct/puml2rdf/validators.py,sha256=PiY9uJdiDUn08uRd4R2by9gD_KQWIOdLEzzOv1Akybg,15313
|
|
88
|
+
rdf_construct/refactor/__init__.py,sha256=PDIAdn04OVKqKzwVb6OIS5e4i30GIp3kicL354pTmuk,1814
|
|
89
|
+
rdf_construct/refactor/config.py,sha256=6kX5RuNFh1EN0_fbIQ6Ti4pQx4H_YO8tRlmZRFEjd5s,10490
|
|
90
|
+
rdf_construct/refactor/deprecator.py,sha256=mxCTXMcpLKm1eXBu8RXK2bR2LkREso1R7f4Kpah2GoA,10742
|
|
91
|
+
rdf_construct/refactor/formatters/__init__.py,sha256=_iz4UXCPvZv-xhgVAOKrP1d3Mtv0wN5koYlVR64X5fs,216
|
|
92
|
+
rdf_construct/refactor/formatters/text.py,sha256=QgrTTQi83OTYWW4VWMCygy22PCln2HhADwrld135i2k,11777
|
|
93
|
+
rdf_construct/refactor/renamer.py,sha256=20CFQe7SuKSIqpmqr3LMIi11qVV3gboFCqO9yvn0HyY,9300
|
|
58
94
|
rdf_construct/shacl/__init__.py,sha256=ft45S6QvDvNCZAKqdbbs8tM5xC1dzh2wLUp9FAMz3X0,1488
|
|
59
95
|
rdf_construct/shacl/config.py,sha256=eVJGEjiqyLpvBpz4i8F0YsCLjow6TGEvNxkk37dwBhA,5499
|
|
60
96
|
rdf_construct/shacl/converters.py,sha256=vtqNcZcUqhJxyAo27-KlAUT7I4ylnvZBAy3mrtxCIsM,17827
|
|
@@ -81,8 +117,8 @@ rdf_construct/uml/odm_renderer.py,sha256=X4QqzWXJ-FX64ZIfu0Nx6gpHbEQsJOo2hq2fbY3
|
|
|
81
117
|
rdf_construct/uml/renderer.py,sha256=Zj3udsghxXqJ5NPqvVSoIK177Vtzh-fFgsDzYxF5OoY,23755
|
|
82
118
|
rdf_construct/uml/uml_layout.py,sha256=PBd_qOBJzDq2N8SCqDJqgAoFmYnzZC4jrLgCQ4biYBM,13217
|
|
83
119
|
rdf_construct/uml/uml_style.py,sha256=ngVqmbS18Y4mAi9ggtL26IeVF5VbcOIOvalvI62jSO4,21876
|
|
84
|
-
rdf_construct-0.
|
|
85
|
-
rdf_construct-0.
|
|
86
|
-
rdf_construct-0.
|
|
87
|
-
rdf_construct-0.
|
|
88
|
-
rdf_construct-0.
|
|
120
|
+
rdf_construct-0.4.0.dist-info/METADATA,sha256=PzNRNxOgohZAJS2Ow_PpIws154KJ_04f5qMRTgBGgKE,15741
|
|
121
|
+
rdf_construct-0.4.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
122
|
+
rdf_construct-0.4.0.dist-info/entry_points.txt,sha256=L4Mh7BDMt2BUHq_x9BwyPVZmZ-j_wifbD574Zm3qXZY,55
|
|
123
|
+
rdf_construct-0.4.0.dist-info/licenses/LICENSE,sha256=Fh-f4K2IlA0QH5XThePUIoG6_J_UqDkQyihGfvHcvpk,1061
|
|
124
|
+
rdf_construct-0.4.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|