pylode 3.0.0__tar.gz → 3.0.1__tar.gz
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.
- {pyLODE-3.0.0 → pyLODE-3.0.1}/PKG-INFO +12 -7
- {pyLODE-3.0.0 → pyLODE-3.0.1}/README.rst +10 -5
- {pyLODE-3.0.0 → pyLODE-3.0.1}/pyLODE.egg-info/PKG-INFO +12 -7
- {pyLODE-3.0.0 → pyLODE-3.0.1}/pyLODE.egg-info/SOURCES.txt +0 -1
- {pyLODE-3.0.0 → pyLODE-3.0.1}/pylode/cli.py +9 -4
- {pyLODE-3.0.0 → pyLODE-3.0.1}/pylode/ontdoc.py +78 -64
- {pyLODE-3.0.0 → pyLODE-3.0.1}/pylode/rdf_elements.py +6 -11
- {pyLODE-3.0.0 → pyLODE-3.0.1}/pylode/utils.py +183 -115
- pyLODE-3.0.1/pylode/version.py +1 -0
- pyLODE-3.0.0/pylode/extra.py +0 -6
- pyLODE-3.0.0/pylode/version.py +0 -1
- {pyLODE-3.0.0 → pyLODE-3.0.1}/LICENSE +0 -0
- {pyLODE-3.0.0 → pyLODE-3.0.1}/pyLODE.egg-info/dependency_links.txt +0 -0
- {pyLODE-3.0.0 → pyLODE-3.0.1}/pyLODE.egg-info/entry_points.txt +0 -0
- {pyLODE-3.0.0 → pyLODE-3.0.1}/pyLODE.egg-info/requires.txt +0 -0
- {pyLODE-3.0.0 → pyLODE-3.0.1}/pyLODE.egg-info/top_level.txt +0 -0
- {pyLODE-3.0.0 → pyLODE-3.0.1}/pylode/__init__.py +0 -0
- {pyLODE-3.0.0 → pyLODE-3.0.1}/pylode/__main__.py +0 -0
- {pyLODE-3.0.0 → pyLODE-3.0.1}/pylode/pylode.css +0 -0
- {pyLODE-3.0.0 → pyLODE-3.0.1}/setup.cfg +0 -0
- {pyLODE-3.0.0 → pyLODE-3.0.1}/setup.py +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pyLODE
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.1
|
|
4
4
|
Summary: An OWL ontology documentation tool using Python and templating, based on LODE.
|
|
5
5
|
Home-page: https://github.com/rdflib/pyLODE
|
|
6
6
|
Author: Nicholas J. Car
|
|
7
7
|
Author-email: nicholas.car@surroundaustralia.com
|
|
8
8
|
License: LICENSE
|
|
9
|
-
Download-URL: https://github.com/RDFLib/pyLODE/releases/tag/3.0.
|
|
9
|
+
Download-URL: https://github.com/RDFLib/pyLODE/releases/tag/3.0.1
|
|
10
10
|
Project-URL: Bug Reports, https://github.com/rdflib/pyLODE/issues
|
|
11
11
|
Project-URL: Source, https://github.com/rdflib/pyLODE/
|
|
12
12
|
Keywords: Semantic Web,OWL,ontology,template,HTML,documentation
|
|
@@ -41,12 +41,17 @@ In addition to making web page, human-readable forms of ontologies, pyLODE encou
|
|
|
41
41
|
practice* by only producing good results for well documented inputs! pyLODE defines what it considers 'well documented'
|
|
42
42
|
in sections below, e.g. `What pyLODE understands`_.
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
----
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
**A note on the v 3.x change**
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
*This is pyLODE version 3.0.1 and it's vastly different from pyLODE 2.x. It doesn't yet handle all the various "profiles" that pyLODE 2.13.2 does, such as SKOS 'vocabularies' & Profiles Vocabulary 'profiles', it only handles OWL 'ontologies', nor all the special data types, such as JSON literals, BUT, it generates HTML in a much more straightforward manner and the code is both more efficient and much more maintainable, which is why it's been made.*
|
|
49
49
|
|
|
50
|
+
*v 3.x will eventually catch up to all of v 2.13.2's features.*
|
|
51
|
+
|
|
52
|
+
*To access v 2.13.2 of pyLODE, either `download it from PyPI <https://pypi.org/project/pyLODE/2.13.2/>`_, `check it out from GitHub <https://github.com/RDFLib/pyLODE/releases/tag/2.13.2>`_ or access it via the `online service <http://pylode.surroundaustralia.com/>`_.*
|
|
53
|
+
|
|
54
|
+
----
|
|
50
55
|
|
|
51
56
|
Contents
|
|
52
57
|
========
|
|
@@ -257,7 +262,7 @@ and change/add development priorities.
|
|
|
257
262
|
Current Release
|
|
258
263
|
---------------
|
|
259
264
|
|
|
260
|
-
The current release, as of
|
|
265
|
+
The current release, as of January, 2022, is **3.0.1**.
|
|
261
266
|
|
|
262
267
|
Release Schedule
|
|
263
268
|
----------------
|
|
@@ -266,7 +271,7 @@ Release Schedule
|
|
|
266
271
|
:header: "Version", "Date", "Description"
|
|
267
272
|
:widths: 15, 10, 30
|
|
268
273
|
|
|
269
|
-
**3.0.
|
|
274
|
+
**3.0.1**, **6 Jan 2022**, "**Direct HTML generation using dominate; easier to maintain and extend**"
|
|
270
275
|
2.13.2, 21 December 2021, "Updated RDFlib to 6.1.1, improved test to properly use pytest"
|
|
271
276
|
2.10.0, 24 May 2021, "Update Windows EXE build process, simplified versioning"
|
|
272
277
|
2.9.1, 28 Apr 2021, "Support for ASCIIDOC format (OntDoc profile only)"
|
|
@@ -11,12 +11,17 @@ In addition to making web page, human-readable forms of ontologies, pyLODE encou
|
|
|
11
11
|
practice* by only producing good results for well documented inputs! pyLODE defines what it considers 'well documented'
|
|
12
12
|
in sections below, e.g. `What pyLODE understands`_.
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
----
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
**A note on the v 3.x change**
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
*This is pyLODE version 3.0.1 and it's vastly different from pyLODE 2.x. It doesn't yet handle all the various "profiles" that pyLODE 2.13.2 does, such as SKOS 'vocabularies' & Profiles Vocabulary 'profiles', it only handles OWL 'ontologies', nor all the special data types, such as JSON literals, BUT, it generates HTML in a much more straightforward manner and the code is both more efficient and much more maintainable, which is why it's been made.*
|
|
19
19
|
|
|
20
|
+
*v 3.x will eventually catch up to all of v 2.13.2's features.*
|
|
21
|
+
|
|
22
|
+
*To access v 2.13.2 of pyLODE, either `download it from PyPI <https://pypi.org/project/pyLODE/2.13.2/>`_, `check it out from GitHub <https://github.com/RDFLib/pyLODE/releases/tag/2.13.2>`_ or access it via the `online service <http://pylode.surroundaustralia.com/>`_.*
|
|
23
|
+
|
|
24
|
+
----
|
|
20
25
|
|
|
21
26
|
Contents
|
|
22
27
|
========
|
|
@@ -227,7 +232,7 @@ and change/add development priorities.
|
|
|
227
232
|
Current Release
|
|
228
233
|
---------------
|
|
229
234
|
|
|
230
|
-
The current release, as of
|
|
235
|
+
The current release, as of January, 2022, is **3.0.1**.
|
|
231
236
|
|
|
232
237
|
Release Schedule
|
|
233
238
|
----------------
|
|
@@ -236,7 +241,7 @@ Release Schedule
|
|
|
236
241
|
:header: "Version", "Date", "Description"
|
|
237
242
|
:widths: 15, 10, 30
|
|
238
243
|
|
|
239
|
-
**3.0.
|
|
244
|
+
**3.0.1**, **6 Jan 2022**, "**Direct HTML generation using dominate; easier to maintain and extend**"
|
|
240
245
|
2.13.2, 21 December 2021, "Updated RDFlib to 6.1.1, improved test to properly use pytest"
|
|
241
246
|
2.10.0, 24 May 2021, "Update Windows EXE build process, simplified versioning"
|
|
242
247
|
2.9.1, 28 Apr 2021, "Support for ASCIIDOC format (OntDoc profile only)"
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pyLODE
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.1
|
|
4
4
|
Summary: An OWL ontology documentation tool using Python and templating, based on LODE.
|
|
5
5
|
Home-page: https://github.com/rdflib/pyLODE
|
|
6
6
|
Author: Nicholas J. Car
|
|
7
7
|
Author-email: nicholas.car@surroundaustralia.com
|
|
8
8
|
License: LICENSE
|
|
9
|
-
Download-URL: https://github.com/RDFLib/pyLODE/releases/tag/3.0.
|
|
9
|
+
Download-URL: https://github.com/RDFLib/pyLODE/releases/tag/3.0.1
|
|
10
10
|
Project-URL: Bug Reports, https://github.com/rdflib/pyLODE/issues
|
|
11
11
|
Project-URL: Source, https://github.com/rdflib/pyLODE/
|
|
12
12
|
Keywords: Semantic Web,OWL,ontology,template,HTML,documentation
|
|
@@ -41,12 +41,17 @@ In addition to making web page, human-readable forms of ontologies, pyLODE encou
|
|
|
41
41
|
practice* by only producing good results for well documented inputs! pyLODE defines what it considers 'well documented'
|
|
42
42
|
in sections below, e.g. `What pyLODE understands`_.
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
----
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
**A note on the v 3.x change**
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
*This is pyLODE version 3.0.1 and it's vastly different from pyLODE 2.x. It doesn't yet handle all the various "profiles" that pyLODE 2.13.2 does, such as SKOS 'vocabularies' & Profiles Vocabulary 'profiles', it only handles OWL 'ontologies', nor all the special data types, such as JSON literals, BUT, it generates HTML in a much more straightforward manner and the code is both more efficient and much more maintainable, which is why it's been made.*
|
|
49
49
|
|
|
50
|
+
*v 3.x will eventually catch up to all of v 2.13.2's features.*
|
|
51
|
+
|
|
52
|
+
*To access v 2.13.2 of pyLODE, either `download it from PyPI <https://pypi.org/project/pyLODE/2.13.2/>`_, `check it out from GitHub <https://github.com/RDFLib/pyLODE/releases/tag/2.13.2>`_ or access it via the `online service <http://pylode.surroundaustralia.com/>`_.*
|
|
53
|
+
|
|
54
|
+
----
|
|
50
55
|
|
|
51
56
|
Contents
|
|
52
57
|
========
|
|
@@ -257,7 +262,7 @@ and change/add development priorities.
|
|
|
257
262
|
Current Release
|
|
258
263
|
---------------
|
|
259
264
|
|
|
260
|
-
The current release, as of
|
|
265
|
+
The current release, as of January, 2022, is **3.0.1**.
|
|
261
266
|
|
|
262
267
|
Release Schedule
|
|
263
268
|
----------------
|
|
@@ -266,7 +271,7 @@ Release Schedule
|
|
|
266
271
|
:header: "Version", "Date", "Description"
|
|
267
272
|
:widths: 15, 10, 30
|
|
268
273
|
|
|
269
|
-
**3.0.
|
|
274
|
+
**3.0.1**, **6 Jan 2022**, "**Direct HTML generation using dominate; easier to maintain and extend**"
|
|
270
275
|
2.13.2, 21 December 2021, "Updated RDFlib to 6.1.1, improved test to properly use pytest"
|
|
271
276
|
2.10.0, 24 May 2021, "Update Windows EXE build process, simplified versioning"
|
|
272
277
|
2.9.1, 28 Apr 2021, "Support for ASCIIDOC format (OntDoc profile only)"
|
|
@@ -10,7 +10,10 @@ from pylode import OntDoc, PylodeError
|
|
|
10
10
|
parser = argparse.ArgumentParser()
|
|
11
11
|
|
|
12
12
|
parser.add_argument(
|
|
13
|
-
"-v",
|
|
13
|
+
"-v",
|
|
14
|
+
"--version",
|
|
15
|
+
action="version",
|
|
16
|
+
version="{version}".format(version=__version__)
|
|
14
17
|
)
|
|
15
18
|
|
|
16
19
|
parser.add_argument(
|
|
@@ -21,15 +24,17 @@ parser.add_argument(
|
|
|
21
24
|
parser.add_argument(
|
|
22
25
|
"-o",
|
|
23
26
|
"--outputfile",
|
|
24
|
-
help="A name you wish to assign to the output file. Will be postfixed
|
|
25
|
-
|
|
27
|
+
help="A name you wish to assign to the output file. Will be postfixed "
|
|
28
|
+
"with .html if not already added. If no output file is given, "
|
|
29
|
+
"output will be printed to screen",
|
|
26
30
|
default=None,
|
|
27
31
|
)
|
|
28
32
|
|
|
29
33
|
parser.add_argument(
|
|
30
34
|
"-c",
|
|
31
35
|
"--css",
|
|
32
|
-
help="Whether (true) or not (false) to include CSS within an output
|
|
36
|
+
help="Whether (true) or not (false) to include CSS within an output "
|
|
37
|
+
"HTML file.",
|
|
33
38
|
choices=["true", "false"],
|
|
34
39
|
default="true",
|
|
35
40
|
)
|
|
@@ -56,7 +56,12 @@ try:
|
|
|
56
56
|
prop_obj_pair_html,
|
|
57
57
|
section_html,
|
|
58
58
|
)
|
|
59
|
-
|
|
59
|
+
|
|
60
|
+
from .rdf_elements import ONTDOC, AGENT_PROPS, \
|
|
61
|
+
ONT_PROPS, CLASS_PROPS, PROP_PROPS
|
|
62
|
+
|
|
63
|
+
from .version import __version__
|
|
64
|
+
except ImportError:
|
|
60
65
|
from utils import (
|
|
61
66
|
load_ontology,
|
|
62
67
|
load_background_onts,
|
|
@@ -67,14 +72,9 @@ except:
|
|
|
67
72
|
section_html,
|
|
68
73
|
)
|
|
69
74
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
except:
|
|
73
|
-
from rdf_elements import ONTDOC, AGENT_PROPS, ONT_PROPS, CLASS_PROPS, PROP_PROPS
|
|
75
|
+
from rdf_elements import ONTDOC, AGENT_PROPS, \
|
|
76
|
+
ONT_PROPS, CLASS_PROPS, PROP_PROPS
|
|
74
77
|
|
|
75
|
-
try:
|
|
76
|
-
from .version import __version__
|
|
77
|
-
except:
|
|
78
78
|
from version import __version__
|
|
79
79
|
|
|
80
80
|
RDF_FOLDER = Path(__file__).parent / "rdf"
|
|
@@ -85,7 +85,8 @@ class PylodeError(Exception):
|
|
|
85
85
|
|
|
86
86
|
|
|
87
87
|
class OntDoc:
|
|
88
|
-
"""Ontology Document class used to create HTML documentation
|
|
88
|
+
"""Ontology Document class used to create HTML documentation
|
|
89
|
+
from OWL Ontologies.
|
|
89
90
|
|
|
90
91
|
Use:
|
|
91
92
|
# initialise
|
|
@@ -120,7 +121,8 @@ class OntDoc:
|
|
|
120
121
|
t = str(o2)
|
|
121
122
|
if t is None:
|
|
122
123
|
raise PylodeError(
|
|
123
|
-
"You MUST supply a title property
|
|
124
|
+
"You MUST supply a title property "
|
|
125
|
+
"(dcterms:title, rdf:label or sdo:name) for your ontology"
|
|
124
126
|
)
|
|
125
127
|
self.doc = dominate.document(title=t)
|
|
126
128
|
|
|
@@ -132,7 +134,9 @@ class OntDoc:
|
|
|
132
134
|
|
|
133
135
|
Either writes to a file or returns a string"""
|
|
134
136
|
self._make_head(
|
|
135
|
-
self._make_schema_org(),
|
|
137
|
+
self._make_schema_org(),
|
|
138
|
+
include_css=include_css,
|
|
139
|
+
destination=destination
|
|
136
140
|
)
|
|
137
141
|
self._make_body()
|
|
138
142
|
|
|
@@ -188,12 +192,12 @@ class OntDoc:
|
|
|
188
192
|
g.add((s_, RDF.type, OWL.Restriction))
|
|
189
193
|
|
|
190
194
|
for s_ in chain(
|
|
191
|
-
g.subjects(OWL.unionOf, None),
|
|
192
|
-
g.subjects(OWL.intersectionOf, None)
|
|
195
|
+
g.subjects(OWL.unionOf, None), g.subjects(OWL.intersectionOf, None)
|
|
193
196
|
):
|
|
194
197
|
g.add((s_, RDF.type, OWL.Class))
|
|
195
198
|
|
|
196
|
-
# we do these next few so we only need to loop through
|
|
199
|
+
# we do these next few so we only need to loop through
|
|
200
|
+
# Class & Property properties once: single subject
|
|
197
201
|
for s_, o in g.subject_objects(RDFS.subClassOf):
|
|
198
202
|
g.add((o, ONTDOC.superClassOf, s_))
|
|
199
203
|
|
|
@@ -222,7 +226,7 @@ class OntDoc:
|
|
|
222
226
|
for s_, o in chain(
|
|
223
227
|
g.subject_objects(DC.creator),
|
|
224
228
|
g.subject_objects(SDO.creator),
|
|
225
|
-
g.subject_objects(SDO.author),
|
|
229
|
+
g.subject_objects(SDO.author),
|
|
226
230
|
):
|
|
227
231
|
g.remove((s_, DC.creator, o))
|
|
228
232
|
g.remove((s_, SDO.creator, o))
|
|
@@ -265,7 +269,10 @@ class OntDoc:
|
|
|
265
269
|
g.add((s_, SDO.affiliation, o))
|
|
266
270
|
|
|
267
271
|
def _make_head(
|
|
268
|
-
self,
|
|
272
|
+
self,
|
|
273
|
+
schema_org: Graph,
|
|
274
|
+
include_css: bool = True,
|
|
275
|
+
destination: Path = None
|
|
269
276
|
):
|
|
270
277
|
"""Healper function for make_html(). Makes <head>???</head> content"""
|
|
271
278
|
with self.doc.head:
|
|
@@ -280,7 +287,9 @@ class OntDoc:
|
|
|
280
287
|
)
|
|
281
288
|
else:
|
|
282
289
|
link(href="pylode.css", rel="stylesheet", type="text/css")
|
|
283
|
-
shutil.copy(
|
|
290
|
+
shutil.copy(
|
|
291
|
+
Path("pylode.css"),
|
|
292
|
+
destination.parent / "pylode.css")
|
|
284
293
|
link(
|
|
285
294
|
rel="icon",
|
|
286
295
|
type="image/png",
|
|
@@ -297,7 +306,7 @@ class OntDoc:
|
|
|
297
306
|
script(
|
|
298
307
|
raw("\n" + schema_org.serialize(format="json-ld") + "\n\t"),
|
|
299
308
|
type="application/ld+json",
|
|
300
|
-
id="schema.org"
|
|
309
|
+
id="schema.org",
|
|
301
310
|
)
|
|
302
311
|
|
|
303
312
|
def _make_body(self):
|
|
@@ -321,7 +330,8 @@ class OntDoc:
|
|
|
321
330
|
span("LODE")
|
|
322
331
|
a(
|
|
323
332
|
__version__,
|
|
324
|
-
href="https://github.com/rdflib/pyLODE/release/"
|
|
333
|
+
href="https://github.com/rdflib/pyLODE/release/"
|
|
334
|
+
+ __version__,
|
|
325
335
|
id="version",
|
|
326
336
|
)
|
|
327
337
|
|
|
@@ -339,7 +349,10 @@ class OntDoc:
|
|
|
339
349
|
this_onts_props[p_].append(o)
|
|
340
350
|
|
|
341
351
|
# make HTML for all props in order of ONT_PROPS
|
|
342
|
-
sec = div(
|
|
352
|
+
sec = div(
|
|
353
|
+
h1(this_onts_props[DCTERMS.title]),
|
|
354
|
+
id="metadata",
|
|
355
|
+
_class="section")
|
|
343
356
|
sec.appendChild(h2("Metadata"))
|
|
344
357
|
d = dl(div(dt(strong("IRI")), dd(code(str(iri)))))
|
|
345
358
|
for prop in ONT_PROPS:
|
|
@@ -369,38 +382,38 @@ class OntDoc:
|
|
|
369
382
|
self.ont.subjects(predicate=RDF.type, object=PROF.Profile),
|
|
370
383
|
):
|
|
371
384
|
sdo.add((ont_iri, RDF.type, SDO.DefinedTermSet))
|
|
372
|
-
for
|
|
373
|
-
if
|
|
385
|
+
for p_, o in self.ont.predicate_objects(ont_iri):
|
|
386
|
+
if p_ == DCTERMS.title:
|
|
374
387
|
sdo.add((ont_iri, SDO.name, o))
|
|
375
|
-
elif
|
|
388
|
+
elif p_ == DCTERMS.description:
|
|
376
389
|
sdo.add((ont_iri, SDO.description, o))
|
|
377
|
-
elif
|
|
390
|
+
elif p_ == DCTERMS.publisher:
|
|
378
391
|
sdo.add((ont_iri, SDO.publisher, o))
|
|
379
392
|
if not isinstance(o, Literal):
|
|
380
393
|
for p2, o2 in self.ont.predicate_objects(o):
|
|
381
394
|
if p2 in AGENT_PROPS:
|
|
382
395
|
sdo.add((o, p2, o2))
|
|
383
|
-
elif
|
|
396
|
+
elif p_ == DCTERMS.creator:
|
|
384
397
|
sdo.add((ont_iri, SDO.creator, o))
|
|
385
398
|
if not isinstance(o, Literal):
|
|
386
399
|
for p2, o2 in self.ont.predicate_objects(o):
|
|
387
400
|
if p2 in AGENT_PROPS:
|
|
388
401
|
sdo.add((o, p2, o2))
|
|
389
|
-
elif
|
|
402
|
+
elif p_ == DCTERMS.contributor:
|
|
390
403
|
sdo.add((ont_iri, SDO.contributor, o))
|
|
391
404
|
if not isinstance(o, Literal):
|
|
392
405
|
for p2, o2 in self.ont.predicate_objects(o):
|
|
393
406
|
if p2 in AGENT_PROPS:
|
|
394
407
|
sdo.add((o, p2, o2))
|
|
395
|
-
elif
|
|
408
|
+
elif p_ == DCTERMS.created:
|
|
396
409
|
sdo.add((ont_iri, SDO.dateCreated, o))
|
|
397
|
-
elif
|
|
410
|
+
elif p_ == DCTERMS.modified:
|
|
398
411
|
sdo.add((ont_iri, SDO.dateModified, o))
|
|
399
|
-
elif
|
|
412
|
+
elif p_ == DCTERMS.issued:
|
|
400
413
|
sdo.add((ont_iri, SDO.dateIssued, o))
|
|
401
|
-
elif
|
|
414
|
+
elif p_ == DCTERMS.license:
|
|
402
415
|
sdo.add((ont_iri, SDO.license, o))
|
|
403
|
-
elif
|
|
416
|
+
elif p_ == DCTERMS.rights:
|
|
404
417
|
sdo.add((ont_iri, SDO.copyrightNotice, o))
|
|
405
418
|
|
|
406
419
|
return sdo
|
|
@@ -505,7 +518,10 @@ class OntDoc:
|
|
|
505
518
|
|
|
506
519
|
if self.toc.get("classes") is not None:
|
|
507
520
|
with tr():
|
|
508
|
-
td(sup(
|
|
521
|
+
td(sup(
|
|
522
|
+
"c",
|
|
523
|
+
_class="sup-c",
|
|
524
|
+
title="OWL/RDFS Class"))
|
|
509
525
|
td("Classes")
|
|
510
526
|
if self.toc.get("properties") is not None:
|
|
511
527
|
with tr():
|
|
@@ -513,7 +529,10 @@ class OntDoc:
|
|
|
513
529
|
td("Properties")
|
|
514
530
|
if self.toc.get("objectproperties") is not None:
|
|
515
531
|
with tr():
|
|
516
|
-
td(sup(
|
|
532
|
+
td(sup(
|
|
533
|
+
"op",
|
|
534
|
+
_class="sup-op",
|
|
535
|
+
title="OWL Object Property"))
|
|
517
536
|
td("Object Properties")
|
|
518
537
|
if self.toc.get("datatypeproperties") is not None:
|
|
519
538
|
with tr():
|
|
@@ -547,13 +566,21 @@ class OntDoc:
|
|
|
547
566
|
td("Functional Properties")
|
|
548
567
|
if self.toc.get("named_individuals") is not None:
|
|
549
568
|
with tr():
|
|
550
|
-
td(sup(
|
|
569
|
+
td(sup(
|
|
570
|
+
"ni",
|
|
571
|
+
_class="sup-ni",
|
|
572
|
+
title="OWL Named Individual"
|
|
573
|
+
))
|
|
551
574
|
td("Named Individuals")
|
|
552
575
|
|
|
553
576
|
def _make_namespaces(self):
|
|
554
577
|
# get only namespaces used in ont
|
|
555
578
|
nses = {}
|
|
556
|
-
for n in chain(
|
|
579
|
+
for n in chain(
|
|
580
|
+
self.ont.subjects(),
|
|
581
|
+
self.ont.predicates(),
|
|
582
|
+
self.ont.objects()
|
|
583
|
+
):
|
|
557
584
|
for prefix, ns in self.ont.namespaces():
|
|
558
585
|
if str(n).startswith(ns):
|
|
559
586
|
nses[prefix] = ns
|
|
@@ -602,7 +629,10 @@ class OntDoc:
|
|
|
602
629
|
and len(self.toc["objectproperties"]) > 0
|
|
603
630
|
):
|
|
604
631
|
with li():
|
|
605
|
-
h4(a(
|
|
632
|
+
h4(a(
|
|
633
|
+
"Object Properties",
|
|
634
|
+
href="#objectproperties"
|
|
635
|
+
))
|
|
606
636
|
with ul(_class="second"):
|
|
607
637
|
for c in self.toc["objectproperties"]:
|
|
608
638
|
li(a(c[1], href=c[0]))
|
|
@@ -612,7 +642,10 @@ class OntDoc:
|
|
|
612
642
|
and len(self.toc["datatypeproperties"]) > 0
|
|
613
643
|
):
|
|
614
644
|
with li():
|
|
615
|
-
h4(a(
|
|
645
|
+
h4(a(
|
|
646
|
+
"Datatype Properties",
|
|
647
|
+
href="#datatypeproperties"
|
|
648
|
+
))
|
|
616
649
|
with ul(_class="second"):
|
|
617
650
|
for c in self.toc["datatypeproperties"]:
|
|
618
651
|
li(a(c[1], href=c[0]))
|
|
@@ -622,7 +655,10 @@ class OntDoc:
|
|
|
622
655
|
and len(self.toc["annotationproperties"]) > 0
|
|
623
656
|
):
|
|
624
657
|
with li():
|
|
625
|
-
h4(a(
|
|
658
|
+
h4(a(
|
|
659
|
+
"Annotation Properties",
|
|
660
|
+
href="#annotationproperties"
|
|
661
|
+
))
|
|
626
662
|
with ul(_class="second"):
|
|
627
663
|
for c in self.toc["annotationproperties"]:
|
|
628
664
|
li(a(c[1], href=c[0]))
|
|
@@ -632,7 +668,10 @@ class OntDoc:
|
|
|
632
668
|
and len(self.toc["functionalproperties"]) > 0
|
|
633
669
|
):
|
|
634
670
|
with li():
|
|
635
|
-
h4(a(
|
|
671
|
+
h4(a(
|
|
672
|
+
"Functional Properties",
|
|
673
|
+
href="#functionalproperties"
|
|
674
|
+
))
|
|
636
675
|
with ul(_class="second"):
|
|
637
676
|
for c in self.toc["functionalproperties"]:
|
|
638
677
|
li(a(c[1], href=c[0]))
|
|
@@ -644,28 +683,3 @@ class OntDoc:
|
|
|
644
683
|
li(a(n[1], href="#" + n[1]))
|
|
645
684
|
|
|
646
685
|
li(h4(a("Legend", href="#legend")), ul(_class="second"))
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
if __name__ == "__main__":
|
|
650
|
-
# TODO: schema.org generation from ont
|
|
651
|
-
# TODO: move background ont into Dataset
|
|
652
|
-
# TODO: cli UI
|
|
653
|
-
|
|
654
|
-
logging.basicConfig(
|
|
655
|
-
level=logging.INFO,
|
|
656
|
-
format="%(asctime)s [%(levelname)s] %(message)s",
|
|
657
|
-
handlers=[logging.StreamHandler()],
|
|
658
|
-
)
|
|
659
|
-
|
|
660
|
-
od = OntDoc(ontology="https://data.surroundaustralia.com/def/exem")
|
|
661
|
-
od.make_html(destination="some.html")
|
|
662
|
-
|
|
663
|
-
# import cProfile
|
|
664
|
-
#
|
|
665
|
-
# pr = cProfile.Profile()
|
|
666
|
-
# pr.enable()
|
|
667
|
-
#
|
|
668
|
-
# check_all_props_are_known()
|
|
669
|
-
#
|
|
670
|
-
# pr.disable()
|
|
671
|
-
# pr.print_stats(sort='time')
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
from rdflib import Namespace
|
|
2
2
|
from rdflib.namespace import (
|
|
3
|
-
DC,
|
|
4
3
|
DCTERMS,
|
|
5
|
-
FOAF,
|
|
6
|
-
ORG,
|
|
7
4
|
OWL,
|
|
8
|
-
PROF,
|
|
9
|
-
PROV,
|
|
10
5
|
RDF,
|
|
11
6
|
RDFS,
|
|
12
7
|
SDO,
|
|
@@ -62,7 +57,8 @@ CLASS_PROPS = [
|
|
|
62
57
|
ONTDOC.superClassOf,
|
|
63
58
|
]
|
|
64
59
|
|
|
65
|
-
# properties for instances of RDF Property and OWL specialised
|
|
60
|
+
# properties for instances of RDF Property and OWL specialised
|
|
61
|
+
# forms, such as ObjectProperty etc.
|
|
66
62
|
PROP_PROPS = [
|
|
67
63
|
RDFS.isDefinedBy,
|
|
68
64
|
DCTERMS.title,
|
|
@@ -106,7 +102,9 @@ RESTRICTION_PROPS = [
|
|
|
106
102
|
]
|
|
107
103
|
|
|
108
104
|
# all known properties
|
|
109
|
-
PROPS = set(
|
|
105
|
+
PROPS = set(
|
|
106
|
+
ONT_PROPS + CLASS_PROPS + PROP_PROPS +
|
|
107
|
+
AGENT_PROPS + RESTRICTION_PROPS)
|
|
110
108
|
|
|
111
109
|
ONT_TYPES = {
|
|
112
110
|
OWL.Class: ("c", "OWL/RDFS Class"),
|
|
@@ -131,7 +129,4 @@ RESTRICTION_TYPES = [
|
|
|
131
129
|
OWL.hasValue,
|
|
132
130
|
]
|
|
133
131
|
|
|
134
|
-
OWL_SET_TYPES = [
|
|
135
|
-
OWL.unionOf,
|
|
136
|
-
OWL.intersectionOf
|
|
137
|
-
]
|
|
132
|
+
OWL_SET_TYPES = [OWL.unionOf, OWL.intersectionOf]
|
|
@@ -26,24 +26,37 @@ from dominate.tags import (
|
|
|
26
26
|
dd,
|
|
27
27
|
h2,
|
|
28
28
|
)
|
|
29
|
-
from dominate.util import raw
|
|
29
|
+
from dominate.util import raw
|
|
30
30
|
from rdflib import BNode, Literal, Graph, URIRef
|
|
31
31
|
from rdflib.paths import ZeroOrMore
|
|
32
|
-
from rdflib.
|
|
33
|
-
|
|
32
|
+
from rdflib.namespace import (
|
|
33
|
+
DC,
|
|
34
|
+
DCTERMS,
|
|
35
|
+
PROF,
|
|
36
|
+
PROV,
|
|
37
|
+
OWL,
|
|
38
|
+
RDF,
|
|
39
|
+
RDFS,
|
|
40
|
+
SDO,
|
|
41
|
+
SKOS,
|
|
42
|
+
VANN
|
|
43
|
+
)
|
|
34
44
|
|
|
35
45
|
try:
|
|
36
|
-
from .rdf_elements import
|
|
37
|
-
|
|
38
|
-
|
|
46
|
+
from .rdf_elements import AGENT_PROPS, ONTDOC, ONT_TYPES, \
|
|
47
|
+
OWL_SET_TYPES, PROPS, RESTRICTION_TYPES
|
|
48
|
+
except ImportError:
|
|
49
|
+
from rdf_elements import AGENT_PROPS, ONTDOC, ONT_TYPES, \
|
|
50
|
+
OWL_SET_TYPES, PROPS, RESTRICTION_TYPES
|
|
39
51
|
|
|
40
52
|
RDF_FOLDER = Path(__file__).parent / "rdf"
|
|
41
53
|
|
|
42
54
|
|
|
43
55
|
def check_all_props_are_known():
|
|
44
|
-
"""Check all properties listed in the combined property lists in
|
|
45
|
-
their titles and descriptions are present in the
|
|
46
|
-
Run after performing labelling
|
|
56
|
+
"""Check all properties listed in the combined property lists in
|
|
57
|
+
properties.py to see if their titles and descriptions are present in the
|
|
58
|
+
background ontologies in the folder rdf/. Run after performing labelling
|
|
59
|
+
inferencing."""
|
|
47
60
|
bg = load_background_onts()
|
|
48
61
|
for prop in PROPS:
|
|
49
62
|
if (prop, RDF.type, None) not in bg:
|
|
@@ -84,9 +97,11 @@ def get_ns(ont: Graph) -> Tuple[str, str]:
|
|
|
84
97
|
if prefix is not None:
|
|
85
98
|
return prefix, default_iri
|
|
86
99
|
else:
|
|
87
|
-
# can't find either a declared or default namespace
|
|
100
|
+
# can't find either a declared or default namespace
|
|
101
|
+
# so we have an error
|
|
88
102
|
raise Exception(
|
|
89
|
-
"pyLODE can't detect a URI for an owl:Ontology,
|
|
103
|
+
"pyLODE can't detect a URI for an owl:Ontology, "
|
|
104
|
+
"a skos:ConceptScheme or a prof:Profile"
|
|
90
105
|
)
|
|
91
106
|
|
|
92
107
|
|
|
@@ -126,7 +141,8 @@ def make_title_from_iri(iri: URIRef):
|
|
|
126
141
|
|
|
127
142
|
|
|
128
143
|
def generate_fid(title_: Union[Literal, None], iri: URIRef, fids: dict):
|
|
129
|
-
"""Makes an HTML fragment ID for an RDF resource,
|
|
144
|
+
"""Makes an HTML fragment ID for an RDF resource,
|
|
145
|
+
based on title (preferred) or IRI"""
|
|
130
146
|
s_iri = str(iri) if iri is not None else None
|
|
131
147
|
s_title_ = str(title_) if title_ is not None else None
|
|
132
148
|
|
|
@@ -149,7 +165,8 @@ def generate_fid(title_: Union[Literal, None], iri: URIRef, fids: dict):
|
|
|
149
165
|
fids[s_iri] = fid
|
|
150
166
|
return fid
|
|
151
167
|
|
|
152
|
-
# this fid is already present
|
|
168
|
+
# this fid is already present
|
|
169
|
+
# so generate a new one from the URI instead
|
|
153
170
|
|
|
154
171
|
# split URI for last slash segment
|
|
155
172
|
segments = s_iri.split("/")
|
|
@@ -158,7 +175,8 @@ def generate_fid(title_: Union[Literal, None], iri: URIRef, fids: dict):
|
|
|
158
175
|
if len(segments[-1]) < 1:
|
|
159
176
|
return None
|
|
160
177
|
|
|
161
|
-
# return None for domains, i.e. ['http:', '', '{domain}']
|
|
178
|
+
# return None for domains, i.e. ['http:', '', '{domain}'],
|
|
179
|
+
# no path segments
|
|
162
180
|
if len(segments) < 4:
|
|
163
181
|
return None
|
|
164
182
|
|
|
@@ -180,13 +198,16 @@ def generate_fid(title_: Union[Literal, None], iri: URIRef, fids: dict):
|
|
|
180
198
|
fids[s_iri] = fid
|
|
181
199
|
return fid
|
|
182
200
|
else:
|
|
183
|
-
# since it's in use but we've exhausted generation options,
|
|
201
|
+
# since it's in use but we've exhausted generation options,
|
|
202
|
+
# just add 1 to existing fid name
|
|
184
203
|
fids[s_iri] = fid + "1"
|
|
185
|
-
return fid + "1"
|
|
204
|
+
return fid + "1"
|
|
205
|
+
# yeah yeah, there could be more than one but unlikely
|
|
186
206
|
|
|
187
207
|
|
|
188
208
|
def back_onts_label_props(back_onts: Graph):
|
|
189
|
-
"""Gets titles and descriptions for all properties
|
|
209
|
+
"""Gets titles and descriptions for all properties
|
|
210
|
+
in the background ontologies"""
|
|
190
211
|
back_onts_titles = load_background_onts_titles(back_onts)
|
|
191
212
|
|
|
192
213
|
def _get_prop_label(prop_iri: URIRef, back_onts: Graph) -> dict:
|
|
@@ -234,9 +255,9 @@ def load_ontology(ontology: Union[Graph, Path, str]) -> Graph:
|
|
|
234
255
|
if ontology.startswith("[") or ontology.startswith("{"):
|
|
235
256
|
input_format = "json-ld"
|
|
236
257
|
elif (
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
258
|
+
ontology.startswith("<?xml")
|
|
259
|
+
or ontology.startswith("<!--")
|
|
260
|
+
or ontology.startswith("<rdf:RDF")
|
|
240
261
|
):
|
|
241
262
|
input_format = "xml"
|
|
242
263
|
else:
|
|
@@ -248,21 +269,21 @@ def load_ontology(ontology: Union[Graph, Path, str]) -> Graph:
|
|
|
248
269
|
return Graph().parse(ontology)
|
|
249
270
|
else:
|
|
250
271
|
raise ValueError(
|
|
251
|
-
"The ontology you supply to OntDoc must be either
|
|
252
|
-
"
|
|
272
|
+
"The ontology you supply to OntDoc must be either "
|
|
273
|
+
"an RDFlib Graph, a Path (to an RDF file) or a string "
|
|
274
|
+
"(of RDF data)"
|
|
253
275
|
)
|
|
254
276
|
except Exception as e:
|
|
255
277
|
print(f"{type(e).__name__} Error {e}")
|
|
256
278
|
exit()
|
|
257
|
-
# raise ParserError(f"Could not parse supplied ontology.\n\n {type(e).__name__} error with message: {str(e)}")
|
|
258
279
|
|
|
259
280
|
|
|
260
281
|
def load_background_onts():
|
|
261
|
-
"""Loads background ontology files into an RDFLib graph from either
|
|
262
|
-
files or a pickled Graph.
|
|
282
|
+
"""Loads background ontology files into an RDFLib graph from either
|
|
283
|
+
RDF source files or a pickled Graph.
|
|
263
284
|
|
|
264
|
-
Performs title and description inference and stores a pickle if
|
|
265
|
-
RDF source files."""
|
|
285
|
+
Performs title and description inference and stores a pickle if
|
|
286
|
+
generating from RDF source files."""
|
|
266
287
|
|
|
267
288
|
def _parse_background_onts():
|
|
268
289
|
g_ = Graph()
|
|
@@ -274,19 +295,19 @@ def load_background_onts():
|
|
|
274
295
|
def _expand_background_onts_graph(back_ont: Graph):
|
|
275
296
|
# make regular titles
|
|
276
297
|
for s_, o in chain(
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
298
|
+
back_ont.subject_objects(DC.title),
|
|
299
|
+
back_ont.subject_objects(RDFS.label),
|
|
300
|
+
back_ont.subject_objects(SKOS.prefLabel),
|
|
301
|
+
back_ont.subject_objects(SDO.name),
|
|
281
302
|
):
|
|
282
303
|
back_ont.add((s_, DCTERMS.title, o))
|
|
283
304
|
|
|
284
305
|
# make regular descriptions
|
|
285
306
|
for s_, o in chain(
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
307
|
+
back_ont.subject_objects(DC.description),
|
|
308
|
+
back_ont.subject_objects(RDFS.comment),
|
|
309
|
+
back_ont.subject_objects(SKOS.definition),
|
|
310
|
+
back_ont.subject_objects(SDO.description),
|
|
290
311
|
):
|
|
291
312
|
back_ont.add((s_, DCTERMS.description, o))
|
|
292
313
|
|
|
@@ -295,7 +316,7 @@ def load_background_onts():
|
|
|
295
316
|
with open(RDF_FOLDER / "refs.pickle", "wb") as f_:
|
|
296
317
|
pickle.dump(back_ont, f_)
|
|
297
318
|
except FileNotFoundError:
|
|
298
|
-
|
|
319
|
+
logging.warning("Could not cache background ontologies graph")
|
|
299
320
|
|
|
300
321
|
if Path(RDF_FOLDER / "refs.pickle").is_file():
|
|
301
322
|
logging.info("Loading background ontologies from a pickle file")
|
|
@@ -310,7 +331,8 @@ def load_background_onts():
|
|
|
310
331
|
|
|
311
332
|
|
|
312
333
|
def load_background_onts_titles(ont: Graph):
|
|
313
|
-
"""Loads the titles of background ontologies
|
|
334
|
+
"""Loads the titles of background ontologies
|
|
335
|
+
into a dictionary of Ontology IRI / title"""
|
|
314
336
|
|
|
315
337
|
def _get_background_ontology_titles(back_ont: Graph):
|
|
316
338
|
onts_titles = {}
|
|
@@ -318,14 +340,22 @@ def load_background_onts_titles(ont: Graph):
|
|
|
318
340
|
for o in back_ont.objects(subject=s_, predicate=DCTERMS.title):
|
|
319
341
|
onts_titles[str(s_)] = str(o)
|
|
320
342
|
|
|
321
|
-
return {
|
|
343
|
+
return {
|
|
344
|
+
k: v
|
|
345
|
+
for k, v
|
|
346
|
+
in sorted(
|
|
347
|
+
onts_titles.items(),
|
|
348
|
+
key=lambda item: item[1]
|
|
349
|
+
)
|
|
350
|
+
}
|
|
322
351
|
|
|
323
352
|
def _pickle_background_onts_titles(ont_titles: dict):
|
|
324
353
|
try:
|
|
325
354
|
with open(RDF_FOLDER / "refs_titles.pickle", "wb") as f_:
|
|
326
355
|
pickle.dump(ont_titles, f_)
|
|
327
356
|
except FileNotFoundError:
|
|
328
|
-
|
|
357
|
+
logging.warning(
|
|
358
|
+
"Could not cache background ontologies' titles graph")
|
|
329
359
|
|
|
330
360
|
if Path(RDF_FOLDER / "refs_titles.pickle").is_file():
|
|
331
361
|
with open(RDF_FOLDER / "refs_titles.pickle", "rb") as f:
|
|
@@ -337,24 +367,24 @@ def load_background_onts_titles(ont: Graph):
|
|
|
337
367
|
|
|
338
368
|
|
|
339
369
|
def rdf_obj_html(
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
370
|
+
ont: Graph,
|
|
371
|
+
back_onts: Graph,
|
|
372
|
+
ns: Tuple[str, str],
|
|
373
|
+
obj: List[Union[URIRef, BNode, Literal]],
|
|
374
|
+
fids,
|
|
375
|
+
rdf_type=None,
|
|
346
376
|
):
|
|
347
377
|
"""Makes a sensible HTML rendering of an RDF resource.
|
|
348
378
|
|
|
349
379
|
Can handle IRIs, Blank Nodes of Agents or OWL Restrictions or Literals"""
|
|
350
380
|
|
|
351
381
|
def _rdf_obj_single_html(
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
382
|
+
ont_: Graph,
|
|
383
|
+
back_onts_: Graph,
|
|
384
|
+
ns_: Tuple[str, str],
|
|
385
|
+
obj_: Union[URIRef, BNode, Literal],
|
|
386
|
+
fids_,
|
|
387
|
+
rdf_type_=None,
|
|
358
388
|
):
|
|
359
389
|
def _hyperlink_html(
|
|
360
390
|
ont__: Graph,
|
|
@@ -391,17 +421,18 @@ def rdf_obj_html(
|
|
|
391
421
|
if x_ in this_objects_types:
|
|
392
422
|
return x_
|
|
393
423
|
|
|
424
|
+
# find type
|
|
425
|
+
if rdf_type__ is None:
|
|
426
|
+
rdf_type__ = _get_ont_type(ont__, back_onts__, iri__)
|
|
427
|
+
|
|
394
428
|
try:
|
|
395
429
|
qname = ont__.compute_qname(iri__, True)
|
|
396
430
|
except ValueError:
|
|
397
431
|
qname = iri__
|
|
398
432
|
|
|
399
|
-
# find type
|
|
400
|
-
if rdf_type__ is None:
|
|
401
|
-
rdf_type__ = _get_ont_type(ont__, back_onts__, iri__)
|
|
402
|
-
|
|
403
433
|
prefix = "" if qname[0] == "" else f"{qname[0]}:"
|
|
404
|
-
|
|
434
|
+
|
|
435
|
+
if ns__ is not None and str(iri__).startswith(ns__):
|
|
405
436
|
fid = generate_fid(None, iri__, fids__)
|
|
406
437
|
if fid is not None:
|
|
407
438
|
iri__ = "#" + fid
|
|
@@ -424,7 +455,9 @@ def rdf_obj_html(
|
|
|
424
455
|
|
|
425
456
|
def _literal_html(obj__):
|
|
426
457
|
if str(obj__).startswith("http"):
|
|
427
|
-
return _hyperlink_html(
|
|
458
|
+
return _hyperlink_html(
|
|
459
|
+
ont_, back_onts_, ns_, cast(URIRef, obj__), fids_
|
|
460
|
+
)
|
|
428
461
|
else:
|
|
429
462
|
return raw(markdown.markdown(str(obj__)))
|
|
430
463
|
|
|
@@ -516,7 +549,8 @@ def rdf_obj_html(
|
|
|
516
549
|
|
|
517
550
|
if email is not None:
|
|
518
551
|
email = email.replace("mailto:", "")
|
|
519
|
-
sp.appendChild(
|
|
552
|
+
sp.appendChild(
|
|
553
|
+
span("(", a(email, href="mailto:" + email), ")"))
|
|
520
554
|
|
|
521
555
|
if affiliation is not None:
|
|
522
556
|
sp.appendChild(_affiliation_html(ont__, affiliation))
|
|
@@ -530,7 +564,13 @@ def rdf_obj_html(
|
|
|
530
564
|
for px, o in ont__.predicate_objects(obj__):
|
|
531
565
|
if px != RDF.type:
|
|
532
566
|
if px == OWL.onProperty:
|
|
533
|
-
prop = _hyperlink_html(
|
|
567
|
+
prop = _hyperlink_html(
|
|
568
|
+
ont__,
|
|
569
|
+
back_onts_,
|
|
570
|
+
ns__,
|
|
571
|
+
o,
|
|
572
|
+
fids_
|
|
573
|
+
)
|
|
534
574
|
elif px in RESTRICTION_TYPES + OWL_SET_TYPES:
|
|
535
575
|
if px in [
|
|
536
576
|
OWL.minCardinality,
|
|
@@ -540,14 +580,25 @@ def rdf_obj_html(
|
|
|
540
580
|
OWL.cardinality,
|
|
541
581
|
OWL.qualifiedCardinality,
|
|
542
582
|
]:
|
|
543
|
-
if px in [
|
|
583
|
+
if px in [
|
|
584
|
+
OWL.minCardinality,
|
|
585
|
+
OWL.minQualifiedCardinality
|
|
586
|
+
]:
|
|
544
587
|
card = "min"
|
|
545
|
-
elif px in [
|
|
588
|
+
elif px in [
|
|
589
|
+
OWL.maxCardinality,
|
|
590
|
+
OWL.maxQualifiedCardinality,
|
|
591
|
+
]:
|
|
546
592
|
card = "max"
|
|
547
|
-
elif px in [
|
|
593
|
+
elif px in [
|
|
594
|
+
OWL.cardinality,
|
|
595
|
+
OWL.qualifiedCardinality
|
|
596
|
+
]:
|
|
548
597
|
card = "exactly"
|
|
549
598
|
|
|
550
|
-
card = span(
|
|
599
|
+
card = span(
|
|
600
|
+
span(card, _class="cardinality"),
|
|
601
|
+
span(str(o)))
|
|
551
602
|
else:
|
|
552
603
|
if px == OWL.allValuesFrom:
|
|
553
604
|
card = "only"
|
|
@@ -560,20 +611,29 @@ def rdf_obj_html(
|
|
|
560
611
|
elif px == OWL.intersectionOf:
|
|
561
612
|
card = "intersection"
|
|
562
613
|
|
|
563
|
-
card = span(
|
|
614
|
+
card = span(
|
|
615
|
+
span(card, _class="cardinality"),
|
|
616
|
+
raw(_rdf_obj_single_html),
|
|
617
|
+
)
|
|
564
618
|
else:
|
|
565
619
|
card = span(
|
|
566
620
|
span(card, _class="cardinality"),
|
|
567
621
|
span(
|
|
568
622
|
_hyperlink_html(
|
|
569
|
-
ont__,
|
|
623
|
+
ont__,
|
|
624
|
+
back_onts_,
|
|
625
|
+
ns__,
|
|
626
|
+
o,
|
|
627
|
+
fids_,
|
|
628
|
+
OWL.Class
|
|
570
629
|
)
|
|
571
630
|
),
|
|
572
631
|
)
|
|
573
632
|
|
|
574
633
|
restriction = span(prop, card, br()) if card is not None else prop
|
|
575
634
|
restriction = (
|
|
576
|
-
span(restriction, cls, br())
|
|
635
|
+
span(restriction, cls, br())
|
|
636
|
+
if cls is not None else restriction
|
|
577
637
|
)
|
|
578
638
|
|
|
579
639
|
return span(restriction) if restriction is not None else "None"
|
|
@@ -589,17 +649,21 @@ def rdf_obj_html(
|
|
|
589
649
|
joining_word = ' <span class="cardinality">,</span> '
|
|
590
650
|
|
|
591
651
|
class_set = set()
|
|
592
|
-
for o in ont__.objects(obj__, OWL.unionOf|OWL.intersectionOf):
|
|
652
|
+
for o in ont__.objects(obj__, OWL.unionOf | OWL.intersectionOf):
|
|
593
653
|
for o2 in ont__.objects(o, RDF.rest * ZeroOrMore / RDF.first):
|
|
594
|
-
class_set.add(
|
|
654
|
+
class_set.add(
|
|
655
|
+
_rdf_obj_single_html(
|
|
656
|
+
ont__, back_onts__, ns__, o2, fids__, OWL.Class
|
|
657
|
+
)
|
|
658
|
+
)
|
|
595
659
|
|
|
596
660
|
return raw(joining_word.join([mem.render() for mem in class_set]))
|
|
597
661
|
|
|
598
662
|
def _bn_html(ont__, back_onts__, ns__, fids__, obj__: BNode):
|
|
599
663
|
# TODO: remove back_onts and fids if not needed by subfunctions
|
|
600
664
|
# What kind of BN is it?
|
|
601
|
-
# An Agent, a Restriction or a Set Class (union/intersection)
|
|
602
|
-
# all typing added in OntDoc inferencing
|
|
665
|
+
# An Agent, a Restriction or a Set Class (union/intersection)
|
|
666
|
+
# handled all typing added in OntDoc inferencing
|
|
603
667
|
if (obj__, RDF.type, PROV.Agent) in ont__:
|
|
604
668
|
return _agent_html(ont__, obj__)
|
|
605
669
|
elif (obj__, RDF.type, OWL.Restriction) in ont__:
|
|
@@ -608,44 +672,52 @@ def rdf_obj_html(
|
|
|
608
672
|
return _setclass_html(ont__, obj__, back_onts__, ns__, fids__)
|
|
609
673
|
|
|
610
674
|
if isinstance(obj_, URIRef):
|
|
611
|
-
ret = _hyperlink_html(
|
|
675
|
+
ret = _hyperlink_html(
|
|
676
|
+
ont_, back_onts_, ns_, obj_, fids_, rdf_type__=rdf_type_
|
|
677
|
+
)
|
|
612
678
|
elif isinstance(obj_, BNode):
|
|
613
679
|
ret = _bn_html(ont_, back_onts_, ns_, fids_, obj_)
|
|
614
680
|
else: # isinstance(obj, Literal):
|
|
615
681
|
ret = _literal_html(obj_)
|
|
616
682
|
|
|
617
|
-
|
|
618
|
-
return ret if ret is not None else span("xxx")
|
|
683
|
+
return ret if ret is not None else span()
|
|
619
684
|
|
|
620
685
|
if len(obj) == 1:
|
|
621
|
-
return _rdf_obj_single_html(
|
|
686
|
+
return _rdf_obj_single_html(
|
|
687
|
+
ont, back_onts, ns, obj[0], fids, rdf_type_=rdf_type
|
|
688
|
+
)
|
|
622
689
|
else:
|
|
623
690
|
u_ = ul()
|
|
624
691
|
for x in obj:
|
|
625
692
|
u_.appendChild(
|
|
626
|
-
li(
|
|
693
|
+
li(
|
|
694
|
+
_rdf_obj_single_html(
|
|
695
|
+
ont, back_onts, ns, x, fids, rdf_type_=rdf_type
|
|
696
|
+
)
|
|
697
|
+
)
|
|
627
698
|
)
|
|
628
699
|
return u_
|
|
629
700
|
|
|
630
701
|
|
|
631
702
|
def prop_obj_pair_html(
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
703
|
+
ont: Graph,
|
|
704
|
+
back_onts: Graph,
|
|
705
|
+
ns: Tuple[str, str],
|
|
706
|
+
table_or_dl: str,
|
|
707
|
+
prop_iri: URIRef,
|
|
708
|
+
property_title: Literal,
|
|
709
|
+
property_description: Literal,
|
|
710
|
+
ont_title: Literal,
|
|
711
|
+
fids,
|
|
712
|
+
obj: List[Union[URIRef, BNode, Literal]],
|
|
713
|
+
obj_type: Optional[str] = None,
|
|
643
714
|
):
|
|
644
715
|
"""Makes an HTML Definition list dt & dd pair or a Table tr, th & td set,
|
|
645
716
|
for a given RDF property & resource pair"""
|
|
646
717
|
prop = a(
|
|
647
718
|
str(property_title).title(),
|
|
648
|
-
title=str(property_description).rstrip(".") +
|
|
719
|
+
title=str(property_description).rstrip(".") +
|
|
720
|
+
". Defined in " + str(ont_title),
|
|
649
721
|
_class="hover_property",
|
|
650
722
|
href=str(prop_iri),
|
|
651
723
|
)
|
|
@@ -660,32 +732,32 @@ def prop_obj_pair_html(
|
|
|
660
732
|
|
|
661
733
|
|
|
662
734
|
def section_html(
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
735
|
+
section_title: str,
|
|
736
|
+
ont: Graph,
|
|
737
|
+
back_onts: Graph,
|
|
738
|
+
ns: Tuple[str, str],
|
|
739
|
+
obj_class: URIRef,
|
|
740
|
+
prop_list: list,
|
|
741
|
+
toc,
|
|
742
|
+
toc_ul_id: str,
|
|
743
|
+
fids: dict,
|
|
744
|
+
props_labeled,
|
|
673
745
|
):
|
|
674
746
|
"""Makes all the HTML (div, title & table) for all instances of a
|
|
675
747
|
given RDF class, e.g. owl:Class or owl:ObjectProperty"""
|
|
676
748
|
|
|
677
749
|
def _element_html(
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
750
|
+
ont_: Graph,
|
|
751
|
+
back_onts_: Graph,
|
|
752
|
+
ns_: Tuple[str, str],
|
|
753
|
+
iri: URIRef,
|
|
754
|
+
fid: str,
|
|
755
|
+
title_: str,
|
|
756
|
+
ont_type: URIRef,
|
|
757
|
+
props_list,
|
|
758
|
+
this_props_,
|
|
759
|
+
fids_: dict,
|
|
760
|
+
props_labeled_,
|
|
689
761
|
):
|
|
690
762
|
"""Makes all the HTML (div, title & table) for one instance of a
|
|
691
763
|
given RDF class, e.g. owl:Class or owl:ObjectProperty"""
|
|
@@ -743,14 +815,15 @@ def section_html(
|
|
|
743
815
|
if any(x in ont for x in specialised_props):
|
|
744
816
|
continue
|
|
745
817
|
if isinstance(
|
|
746
|
-
|
|
818
|
+
s_, URIRef
|
|
747
819
|
): # ignore blank nodes for things like [ owl:unionOf ( ... ) ]
|
|
748
820
|
this_props = defaultdict(list)
|
|
749
821
|
# get all properties of this object
|
|
750
822
|
for p_, o in ont.predicate_objects(subject=s_):
|
|
751
823
|
# ... in the property list for this class
|
|
752
824
|
if p_ in prop_list:
|
|
753
|
-
if p_ == RDFS.subClassOf
|
|
825
|
+
if p_ == RDFS.subClassOf \
|
|
826
|
+
and (o, RDF.type, OWL.Restriction) in ont:
|
|
754
827
|
this_props[ONTDOC.restriction].append(o)
|
|
755
828
|
else:
|
|
756
829
|
this_props[p_].append(o)
|
|
@@ -788,8 +861,3 @@ def section_html(
|
|
|
788
861
|
|
|
789
862
|
def de_space_html(html):
|
|
790
863
|
return "".join([l_.strip().replace("\n", "") for l_ in html.split("\n")])
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
if __name__ == "__main__":
|
|
794
|
-
# ("http://example.com/thing/FiveFive", "Five 5", "Five5"),
|
|
795
|
-
print(generate_fid("Five 5", "http://example.com/thing/FiveFive", {}))
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "3.0.1"
|
pyLODE-3.0.0/pylode/extra.py
DELETED
pyLODE-3.0.0/pylode/version.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "3.0.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|