pylode 3.4.4__tar.gz → 3.5.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.4.4 → pylode-3.5.1}/PKG-INFO +28 -37
- {pylode-3.4.4 → pylode-3.5.1}/README.md +26 -35
- {pylode-3.4.4 → pylode-3.5.1}/pylode/cli.py +1 -1
- {pylode-3.4.4 → pylode-3.5.1}/pylode/profiles/ontpub.py +60 -2
- {pylode-3.4.4 → pylode-3.5.1}/pylode/profiles/vocpub.py +7 -49
- {pylode-3.4.4 → pylode-3.5.1}/pylode/pylode.css +76 -65
- {pylode-3.4.4 → pylode-3.5.1}/pylode/rdf/sdo-mod.ttl +1 -1
- {pylode-3.4.4 → pylode-3.5.1}/pylode/rdf_elements.py +9 -9
- {pylode-3.4.4 → pylode-3.5.1}/pylode/utils.py +163 -18
- {pylode-3.4.4 → pylode-3.5.1}/pyproject.toml +2 -2
- {pylode-3.4.4 → pylode-3.5.1}/pylode/__init__.py +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/__main__.py +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/profiles/__init__.py +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/profiles/supermodel/__init__.py +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/profiles/supermodel/component/__init__.py +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/profiles/supermodel/component/example.py +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/profiles/supermodel/component/heading.py +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/profiles/supermodel/component/link.py +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/profiles/supermodel/component/preamble.py +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/profiles/supermodel/component/properties_table.py +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/profiles/supermodel/component/tooltip.py +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/profiles/supermodel/dataset.py +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/profiles/supermodel/fragment.py +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/profiles/supermodel/html.py +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/profiles/supermodel/loader.py +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/profiles/supermodel/model.py +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/profiles/supermodel/namespace.py +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/profiles/supermodel/query/__init__.py +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/profiles/supermodel/query/common.py +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/profiles/supermodel/query/property_shape.py +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/profiles/supermodel/random.py +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/profiles/supermodel/state.py +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/rdf/dcterms-mod.ttl +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/rdf/licenses.ttl +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/rdf/ontdoc.ttl +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/rdf/owl.ttl +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/rdf/prov.ttl +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/rdf/rdf.ttl +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/rdf/rdfs-mod.ttl +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/rdf/skos.ttl +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/rdf/void.ttl +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/server.py +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/static/asciidoc.css +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/static/hierarchy.css +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/static/hierarchy.js +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/static/property-table-row.js +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/static/pylode.css +0 -0
- {pylode-3.4.4 → pylode-3.5.1}/pylode/version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pylode
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.5.1
|
|
4
4
|
Summary: An OWL ontology documentation tool using Python, based on LODE.
|
|
5
5
|
Author: Nicholas Car
|
|
6
6
|
Author-email: Nicholas Car <nick@kurrawong.ai>
|
|
@@ -13,7 +13,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.14
|
|
14
14
|
Requires-Dist: rdflib>=7.6.0,<8.0.0
|
|
15
15
|
Requires-Dist: markdown>=3.3.7,<4
|
|
16
|
-
Requires-Dist: dominate>=2.
|
|
16
|
+
Requires-Dist: dominate>=2.9.1,<3
|
|
17
17
|
Requires-Dist: html5lib>=1.1,<2
|
|
18
18
|
Requires-Dist: httpx>=0.25.0,<1.0.0
|
|
19
19
|
Requires-Dist: tqdm>=4.67.3
|
|
@@ -38,25 +38,7 @@ An OWL ontology documentation tool using Python, based on LODE.
|
|
|
38
38
|
|
|
39
39
|
In addition to making web page, human-readable forms of ontologies, pyLODE encourages ontology annotation *best practice* by only producing good results for well documented inputs! pyLODE defines what it considers “well documented” in sections below, e.g. [What pyLODE understands](#what-pylode-understands).
|
|
40
40
|
|
|
41
|
-
**New mode**: In v3.1.0, pyLODE now has a new mode called `supermodel`, in addition to the existing `ontpub`
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
## A note on the v 3.x change
|
|
46
|
-
|
|
47
|
-
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.
|
|
48
|
-
|
|
49
|
-
However, 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.
|
|
50
|
-
|
|
51
|
-
v 3.x will eventually catch up to all of v 2.13.2’s features.
|
|
52
|
-
|
|
53
|
-
To access v 2.13.2 of pyLODE, either:
|
|
54
|
-
|
|
55
|
-
- [Download it from PyPI](https://pypi.org/project/pylode/2.13.2/)
|
|
56
|
-
- [Check it out from GitHub](https://github.com/RDFLib/pyLODE/releases/tag/2.13.2)
|
|
57
|
-
- Access it via the [online service](http://tools.kurrawong.ai/pylode)
|
|
58
|
-
|
|
59
|
-
---
|
|
41
|
+
**New mode**: In v3.1.0, pyLODE now has a new mode called `supermodel`, in addition to the existing `ontpub` & `vocpub` modes. This new mode allows for documenting **profiles and modules** of multipart models. See [supermodel.md](supermodel.md) for more information.
|
|
60
42
|
|
|
61
43
|
## Contents
|
|
62
44
|
|
|
@@ -101,20 +83,23 @@ The tool can be used in multiple ways:
|
|
|
101
83
|
### Command line arguments
|
|
102
84
|
|
|
103
85
|
```text
|
|
104
|
-
usage:
|
|
86
|
+
usage: pylode [-h] [-v] [-o OUTPUTFILE] [-c {true,false}] [-s] [-p {ontpub,vocpub,supermodel}] [-l {error,warning,info,debug}] input
|
|
105
87
|
|
|
106
88
|
positional arguments:
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
89
|
+
input Input file location or URL
|
|
90
|
+
|
|
91
|
+
options:
|
|
92
|
+
-h, --help show this help message and exit
|
|
93
|
+
-v, --version show program's version number and exit
|
|
94
|
+
-o, --outputfile OUTPUTFILE
|
|
95
|
+
A name you wish to assign to the output file. Will be postfixed with .html if not already added. If no output file is given, output will be printed to screen
|
|
96
|
+
-c, --css {true,false}
|
|
97
|
+
Whether (true) or not (false) to include CSS within an output HTML file.
|
|
98
|
+
-s, --sort Enables sorting of the subjects in the ontology in the output
|
|
99
|
+
-p, --profile {ontpub,vocpub,supermodel}
|
|
100
|
+
Which profile to use to generate HTML. Must be one of 'ontpub' (https://linked.data.gov.au/def/ontpub) - for ontologies, 'vocpub' (https://linked.data.gov.au/def/vocpub) - for SKOS vocabularies, 'supermodel' - for profiles of profiles
|
|
101
|
+
-l, --loglevel {error,warning,info,debug}
|
|
102
|
+
Set the logging level
|
|
118
103
|
```
|
|
119
104
|
|
|
120
105
|
### Basic Use
|
|
@@ -125,6 +110,12 @@ optional arguments:
|
|
|
125
110
|
python pylode examples/ontpub/minimal.ttl -o minimal.html
|
|
126
111
|
```
|
|
127
112
|
|
|
113
|
+
for a SKOS vocabulary, indicate the `vocpub` profile:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
python pylode examples/vocpub/GeologicSpecimenMaterialTypes.ttl -o GeologicSpecimenMaterialTypes.html -p vocpub
|
|
117
|
+
```
|
|
118
|
+
|
|
128
119
|
#### As a Docker container
|
|
129
120
|
|
|
130
121
|
```bash
|
|
@@ -246,6 +237,9 @@ pyLODE deliberately does **not** translate everything in RDF to HTML, enforcing
|
|
|
246
237
|
pyLODE supports simple and complex Agent objects, including ORCIDs, affiliations, and contact details.
|
|
247
238
|
|
|
248
239
|
```turtle
|
|
240
|
+
PREFIX schema: <https://schema.org/>
|
|
241
|
+
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
|
|
242
|
+
|
|
249
243
|
<ontology_x>
|
|
250
244
|
schema:creator [
|
|
251
245
|
schema:name "Nicholas J. Car" ;
|
|
@@ -302,9 +296,6 @@ Older releases
|
|
|
302
296
|
|
|
303
297
|
| Version | Date | Description |
|
|
304
298
|
|---------|------------------|---------------------------------------------------------------------------------|
|
|
305
|
-
| 3.0.5 | 27 April 2023 | Minor patching |
|
|
306
|
-
| 3.0.4 | 24 May 2022 | Use of Poetry |
|
|
307
|
-
| 3.0.2 | 24 May 2022 | Support for preformatted skos:example literals |
|
|
308
299
|
| 3.0.1 | 6 Jan 2022 | Direct HTML generation using dominate; easier to maintain and extend |
|
|
309
300
|
| 2.13.2 | 21 December 2021 | Updated RDFlib to 6.1.1, improved test to properly use pytest |
|
|
310
301
|
| 2.10.0 | 24 May 2021 | Update Windows EXE build process, simplified versioning |
|
|
@@ -355,7 +346,7 @@ Nicholas Car
|
|
|
355
346
|
5. tag with version number: `$git tag ...`
|
|
356
347
|
6. push changes `$ git push`
|
|
357
348
|
7. push version `git push --tags`
|
|
358
|
-
|
|
349
|
+
8. make a GitHub release
|
|
359
350
|
* PyPI release is automated from this in `pypi.yml`
|
|
360
351
|
9. increment version number to next release alpha in `pyproject.toml`
|
|
361
352
|
10. commit all changes `$ git commit -a "..."`
|
|
@@ -7,25 +7,7 @@ An OWL ontology documentation tool using Python, based on LODE.
|
|
|
7
7
|
|
|
8
8
|
In addition to making web page, human-readable forms of ontologies, pyLODE encourages ontology annotation *best practice* by only producing good results for well documented inputs! pyLODE defines what it considers “well documented” in sections below, e.g. [What pyLODE understands](#what-pylode-understands).
|
|
9
9
|
|
|
10
|
-
**New mode**: In v3.1.0, pyLODE now has a new mode called `supermodel`, in addition to the existing `ontpub`
|
|
11
|
-
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
## A note on the v 3.x change
|
|
15
|
-
|
|
16
|
-
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.
|
|
17
|
-
|
|
18
|
-
However, 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
|
-
|
|
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:
|
|
23
|
-
|
|
24
|
-
- [Download it from PyPI](https://pypi.org/project/pylode/2.13.2/)
|
|
25
|
-
- [Check it out from GitHub](https://github.com/RDFLib/pyLODE/releases/tag/2.13.2)
|
|
26
|
-
- Access it via the [online service](http://tools.kurrawong.ai/pylode)
|
|
27
|
-
|
|
28
|
-
---
|
|
10
|
+
**New mode**: In v3.1.0, pyLODE now has a new mode called `supermodel`, in addition to the existing `ontpub` & `vocpub` modes. This new mode allows for documenting **profiles and modules** of multipart models. See [supermodel.md](supermodel.md) for more information.
|
|
29
11
|
|
|
30
12
|
## Contents
|
|
31
13
|
|
|
@@ -70,20 +52,23 @@ The tool can be used in multiple ways:
|
|
|
70
52
|
### Command line arguments
|
|
71
53
|
|
|
72
54
|
```text
|
|
73
|
-
usage:
|
|
55
|
+
usage: pylode [-h] [-v] [-o OUTPUTFILE] [-c {true,false}] [-s] [-p {ontpub,vocpub,supermodel}] [-l {error,warning,info,debug}] input
|
|
74
56
|
|
|
75
57
|
positional arguments:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
58
|
+
input Input file location or URL
|
|
59
|
+
|
|
60
|
+
options:
|
|
61
|
+
-h, --help show this help message and exit
|
|
62
|
+
-v, --version show program's version number and exit
|
|
63
|
+
-o, --outputfile OUTPUTFILE
|
|
64
|
+
A name you wish to assign to the output file. Will be postfixed with .html if not already added. If no output file is given, output will be printed to screen
|
|
65
|
+
-c, --css {true,false}
|
|
66
|
+
Whether (true) or not (false) to include CSS within an output HTML file.
|
|
67
|
+
-s, --sort Enables sorting of the subjects in the ontology in the output
|
|
68
|
+
-p, --profile {ontpub,vocpub,supermodel}
|
|
69
|
+
Which profile to use to generate HTML. Must be one of 'ontpub' (https://linked.data.gov.au/def/ontpub) - for ontologies, 'vocpub' (https://linked.data.gov.au/def/vocpub) - for SKOS vocabularies, 'supermodel' - for profiles of profiles
|
|
70
|
+
-l, --loglevel {error,warning,info,debug}
|
|
71
|
+
Set the logging level
|
|
87
72
|
```
|
|
88
73
|
|
|
89
74
|
### Basic Use
|
|
@@ -94,6 +79,12 @@ optional arguments:
|
|
|
94
79
|
python pylode examples/ontpub/minimal.ttl -o minimal.html
|
|
95
80
|
```
|
|
96
81
|
|
|
82
|
+
for a SKOS vocabulary, indicate the `vocpub` profile:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
python pylode examples/vocpub/GeologicSpecimenMaterialTypes.ttl -o GeologicSpecimenMaterialTypes.html -p vocpub
|
|
86
|
+
```
|
|
87
|
+
|
|
97
88
|
#### As a Docker container
|
|
98
89
|
|
|
99
90
|
```bash
|
|
@@ -215,6 +206,9 @@ pyLODE deliberately does **not** translate everything in RDF to HTML, enforcing
|
|
|
215
206
|
pyLODE supports simple and complex Agent objects, including ORCIDs, affiliations, and contact details.
|
|
216
207
|
|
|
217
208
|
```turtle
|
|
209
|
+
PREFIX schema: <https://schema.org/>
|
|
210
|
+
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
|
|
211
|
+
|
|
218
212
|
<ontology_x>
|
|
219
213
|
schema:creator [
|
|
220
214
|
schema:name "Nicholas J. Car" ;
|
|
@@ -271,9 +265,6 @@ Older releases
|
|
|
271
265
|
|
|
272
266
|
| Version | Date | Description |
|
|
273
267
|
|---------|------------------|---------------------------------------------------------------------------------|
|
|
274
|
-
| 3.0.5 | 27 April 2023 | Minor patching |
|
|
275
|
-
| 3.0.4 | 24 May 2022 | Use of Poetry |
|
|
276
|
-
| 3.0.2 | 24 May 2022 | Support for preformatted skos:example literals |
|
|
277
268
|
| 3.0.1 | 6 Jan 2022 | Direct HTML generation using dominate; easier to maintain and extend |
|
|
278
269
|
| 2.13.2 | 21 December 2021 | Updated RDFlib to 6.1.1, improved test to properly use pytest |
|
|
279
270
|
| 2.10.0 | 24 May 2021 | Update Windows EXE build process, simplified versioning |
|
|
@@ -324,7 +315,7 @@ Nicholas Car
|
|
|
324
315
|
5. tag with version number: `$git tag ...`
|
|
325
316
|
6. push changes `$ git push`
|
|
326
317
|
7. push version `git push --tags`
|
|
327
|
-
|
|
318
|
+
8. make a GitHub release
|
|
328
319
|
* PyPI release is automated from this in `pypi.yml`
|
|
329
320
|
9. increment version number to next release alpha in `pyproject.toml`
|
|
330
321
|
10. commit all changes `$ git commit -a "..."`
|
|
@@ -46,7 +46,7 @@ parser.add_argument(
|
|
|
46
46
|
"--profile",
|
|
47
47
|
help="Which profile to use to generate HTML. Must be one of "
|
|
48
48
|
"'ontpub' (https://linked.data.gov.au/def/ontpub) - for ontologies, "
|
|
49
|
-
"'vocpub' (https://linked.data.gov.au/def/vocpub) - for SKOS vocabularies"
|
|
49
|
+
"'vocpub' (https://linked.data.gov.au/def/vocpub) - for SKOS vocabularies, "
|
|
50
50
|
"'supermodel' - for profiles of profiles",
|
|
51
51
|
choices=["ontpub", "vocpub", "supermodel"],
|
|
52
52
|
default="ontpub",
|
|
@@ -16,10 +16,12 @@ from dominate.tags import (
|
|
|
16
16
|
h2,
|
|
17
17
|
h3,
|
|
18
18
|
h4,
|
|
19
|
+
h5,
|
|
19
20
|
li,
|
|
20
21
|
link,
|
|
21
22
|
meta,
|
|
22
23
|
script,
|
|
24
|
+
section,
|
|
23
25
|
strong,
|
|
24
26
|
style,
|
|
25
27
|
sup,
|
|
@@ -132,6 +134,9 @@ class OntPub:
|
|
|
132
134
|
for s_ in g.subjects(RDF.type, OWL.Class):
|
|
133
135
|
g.add((s_, RDF.type, RDFS.Class))
|
|
134
136
|
|
|
137
|
+
for s_ in g.subjects(RDF.type, RDFS.Class):
|
|
138
|
+
g.add((s_, RDF.type, OWL.Class))
|
|
139
|
+
|
|
135
140
|
# # property types
|
|
136
141
|
# for s_ in chain(
|
|
137
142
|
# g.subjects(RDF.type, OWL.ObjectProperty),
|
|
@@ -474,6 +479,21 @@ class OntPub:
|
|
|
474
479
|
)
|
|
475
480
|
d.render()
|
|
476
481
|
|
|
482
|
+
if (None, RDF.type, RDFS.Datatype) in self.ont:
|
|
483
|
+
d = section_html(
|
|
484
|
+
"Custom Datatypes",
|
|
485
|
+
self.ont,
|
|
486
|
+
self.back_onts,
|
|
487
|
+
self.ns,
|
|
488
|
+
RDFS.Datatype,
|
|
489
|
+
PROP_PROPS,
|
|
490
|
+
self.toc,
|
|
491
|
+
"datatypes",
|
|
492
|
+
self.fids,
|
|
493
|
+
self.props_labeled,
|
|
494
|
+
)
|
|
495
|
+
d.render()
|
|
496
|
+
|
|
477
497
|
def _make_legend(self):
|
|
478
498
|
with self.content:
|
|
479
499
|
with div(id="legend"):
|
|
@@ -573,9 +593,23 @@ class OntPub:
|
|
|
573
593
|
):
|
|
574
594
|
with li():
|
|
575
595
|
h4(a("Classes", href="#classes"))
|
|
596
|
+
h5(
|
|
597
|
+
a(
|
|
598
|
+
"Class Hierarchy",
|
|
599
|
+
href="#class-hierarchy",
|
|
600
|
+
style="margin-left:10px;",
|
|
601
|
+
)
|
|
602
|
+
)
|
|
603
|
+
h5(
|
|
604
|
+
a(
|
|
605
|
+
"Class Definitions",
|
|
606
|
+
href="#class-definitions",
|
|
607
|
+
style="margin-left:10px;",
|
|
608
|
+
)
|
|
609
|
+
)
|
|
576
610
|
with ul(_class="second"):
|
|
577
611
|
for c in self.toc["classes"]:
|
|
578
|
-
li(a(c[1], href=c[0]))
|
|
612
|
+
li(a(c[1], href=c[0]), style="margin-left:10px;")
|
|
579
613
|
|
|
580
614
|
if (
|
|
581
615
|
self.toc.get("properties") is not None
|
|
@@ -593,9 +627,23 @@ class OntPub:
|
|
|
593
627
|
):
|
|
594
628
|
with li():
|
|
595
629
|
h4(a("Object Properties", href="#objectproperties"))
|
|
630
|
+
h5(
|
|
631
|
+
a(
|
|
632
|
+
"Object Property Hierarchy",
|
|
633
|
+
href="#object-property-hierarchy",
|
|
634
|
+
style="margin-left:10px;",
|
|
635
|
+
)
|
|
636
|
+
)
|
|
637
|
+
h5(
|
|
638
|
+
a(
|
|
639
|
+
"Object Property Definitions",
|
|
640
|
+
href="#object-property-definitions",
|
|
641
|
+
style="margin-left:10px;",
|
|
642
|
+
)
|
|
643
|
+
)
|
|
596
644
|
with ul(_class="second"):
|
|
597
645
|
for c in self.toc["objectproperties"]:
|
|
598
|
-
li(a(c[1], href=c[0]))
|
|
646
|
+
li(a(c[1], href=c[0]), style="margin-left:10px;")
|
|
599
647
|
|
|
600
648
|
if (
|
|
601
649
|
self.toc.get("datatypeproperties") is not None
|
|
@@ -627,6 +675,16 @@ class OntPub:
|
|
|
627
675
|
for c in self.toc["functionalproperties"]:
|
|
628
676
|
li(a(c[1], href=c[0]))
|
|
629
677
|
|
|
678
|
+
if (
|
|
679
|
+
self.toc.get("datatypes") is not None
|
|
680
|
+
and len(self.toc["datatypes"]) > 0
|
|
681
|
+
):
|
|
682
|
+
with li():
|
|
683
|
+
h4(a("Custom Datatypes", href="#datatypes"))
|
|
684
|
+
with ul(_class="second"):
|
|
685
|
+
for c in self.toc["datatypes"]:
|
|
686
|
+
li(a(c[1], href=c[0]))
|
|
687
|
+
|
|
630
688
|
with li():
|
|
631
689
|
h4(a("Namespaces", href="#namespaces"))
|
|
632
690
|
with ul(_class="second"):
|
|
@@ -50,7 +50,7 @@ from rdflib.namespace import (
|
|
|
50
50
|
|
|
51
51
|
from pylode.rdf_elements import AGENT_PROPS, CONCEPT_SCHEME_PROPS, ONT_PROPS, ONTDOC
|
|
52
52
|
from pylode.utils import (
|
|
53
|
-
|
|
53
|
+
_make_hierarchy_html,
|
|
54
54
|
back_onts_label_props,
|
|
55
55
|
get_ns,
|
|
56
56
|
load_background_onts,
|
|
@@ -302,7 +302,7 @@ class VocPub:
|
|
|
302
302
|
)
|
|
303
303
|
|
|
304
304
|
def _make_body(self):
|
|
305
|
-
"""
|
|
305
|
+
"""Helper function for make_html(). Makes <body>???</body> content.
|
|
306
306
|
|
|
307
307
|
Just calls other helper functions in order"""
|
|
308
308
|
make_pylode_logo(
|
|
@@ -450,53 +450,11 @@ class VocPub:
|
|
|
450
450
|
def _make_concept_hierarchy(self):
|
|
451
451
|
with self.content:
|
|
452
452
|
if (None, RDF.type, SKOS.Concept) in self.ont:
|
|
453
|
-
concepts = []
|
|
454
|
-
for s in self.ont.subjects(RDF.type, SKOS.Concept):
|
|
455
|
-
for o in self.ont.objects(s, SDO.name):
|
|
456
|
-
c = {"iri": str(s), "prefLabel": str(o)}
|
|
457
|
-
for o2 in self.ont.objects(s, SKOS.broader):
|
|
458
|
-
c["broader"] = str(o2)
|
|
459
|
-
concepts.append(c)
|
|
460
|
-
|
|
461
|
-
def build_html_tree(items):
|
|
462
|
-
# Index items by id
|
|
463
|
-
by_id = {item["iri"]: dict(item, children=[]) for item in items}
|
|
464
|
-
|
|
465
|
-
roots = []
|
|
466
|
-
|
|
467
|
-
# Build tree structure
|
|
468
|
-
for item in by_id.values():
|
|
469
|
-
broader = item.get("broader")
|
|
470
|
-
if broader and broader in by_id:
|
|
471
|
-
by_id[broader]["children"].append(item)
|
|
472
|
-
else:
|
|
473
|
-
roots.append(item)
|
|
474
|
-
|
|
475
|
-
# Recursive renderer
|
|
476
|
-
def render_nodes(nodes):
|
|
477
|
-
container = ul()
|
|
478
|
-
for node in nodes:
|
|
479
|
-
node_li = li(
|
|
480
|
-
a(
|
|
481
|
-
node["prefLabel"],
|
|
482
|
-
href="#"
|
|
483
|
-
+ str(
|
|
484
|
-
self.ont.namespace_manager.qname(
|
|
485
|
-
node["iri"]
|
|
486
|
-
).replace(":", "_")
|
|
487
|
-
),
|
|
488
|
-
)
|
|
489
|
-
)
|
|
490
|
-
if node["children"]:
|
|
491
|
-
node_li.add(render_nodes(node["children"]))
|
|
492
|
-
container.add(node_li)
|
|
493
|
-
return container
|
|
494
|
-
|
|
495
|
-
return render_nodes(roots)
|
|
496
|
-
|
|
497
453
|
d = div(
|
|
498
454
|
h2("Concept Hierarchy"),
|
|
499
|
-
|
|
455
|
+
_make_hierarchy_html(
|
|
456
|
+
self.ont, SKOS.Concept, SKOS.broader, self.fids
|
|
457
|
+
),
|
|
500
458
|
id="concept-hierarchy",
|
|
501
459
|
)
|
|
502
460
|
|
|
@@ -516,7 +474,7 @@ class VocPub:
|
|
|
516
474
|
remaining = {k: v for k, v in d.items() if k not in ordered}
|
|
517
475
|
return ordered | remaining
|
|
518
476
|
|
|
519
|
-
d = div(h2("
|
|
477
|
+
d = div(h2("Concept Definitions"), id="concepts")
|
|
520
478
|
for iri, concept in dict(
|
|
521
479
|
sorted(concepts.items(), key=lambda item: item[1][SDO.name])
|
|
522
480
|
).items(): # order by Concept's label
|
|
@@ -601,7 +559,7 @@ class VocPub:
|
|
|
601
559
|
|
|
602
560
|
li(h4(a("Concepts Hierarchy", href="#concept-hierarchy")))
|
|
603
561
|
|
|
604
|
-
li(h4(a("
|
|
562
|
+
li(h4(a("Concept Definitions", href="#concepts")))
|
|
605
563
|
|
|
606
564
|
with li():
|
|
607
565
|
h4(a("Namespaces", href="#namespaces"))
|
|
@@ -51,17 +51,18 @@
|
|
|
51
51
|
padding-top: 7px;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
#classes ul {
|
|
54
|
+
ul.pylodelitlist {
|
|
56
55
|
list-style-type: none;
|
|
56
|
+
margin-left: -40px;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
#metadata ul li,
|
|
60
60
|
#classes ul li {
|
|
61
|
-
margin-
|
|
61
|
+
margin-bottom: 10px;
|
|
62
62
|
}
|
|
63
|
+
|
|
63
64
|
#metadata dd p {
|
|
64
|
-
margin: 0;
|
|
65
|
+
margin: 0 0 1em 0;
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
ul.hlist {
|
|
@@ -71,12 +72,19 @@
|
|
|
71
72
|
background-color: #F4FFFF;
|
|
72
73
|
}
|
|
73
74
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
padding: 5px 25px 5px 25px;
|
|
75
|
+
div.hierarchy {
|
|
76
|
+
margin-bottom: 30px;
|
|
77
77
|
background-color: #F4FFFF;
|
|
78
|
+
padding: 10px;
|
|
78
79
|
}
|
|
79
80
|
|
|
81
|
+
ul.hierarchy {=
|
|
82
|
+
padding: 5px 25px 5px 25px;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
ul.hierarchy li {
|
|
86
|
+
margin-top:5px;
|
|
87
|
+
}
|
|
80
88
|
|
|
81
89
|
ul.hlist li {
|
|
82
90
|
display: inline;
|
|
@@ -128,7 +136,10 @@
|
|
|
128
136
|
border-bottom: 1px solid navy;
|
|
129
137
|
}
|
|
130
138
|
h4 { font: bold 100% sans-serif }
|
|
131
|
-
h5 {
|
|
139
|
+
h5 {
|
|
140
|
+
font: italic 100% sans-serif;
|
|
141
|
+
margin-bottom: 10px;
|
|
142
|
+
}
|
|
132
143
|
h6 { font: small-caps 100% sans-serif }
|
|
133
144
|
|
|
134
145
|
body {
|
|
@@ -217,60 +228,60 @@
|
|
|
217
228
|
text-decoration: none;
|
|
218
229
|
}
|
|
219
230
|
|
|
220
|
-
#toc {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
}
|
|
232
|
-
#toc h3 {
|
|
233
|
-
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
#toc ul {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
#toc .first > li {
|
|
242
|
-
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
#toc .second,
|
|
246
|
-
#toc .third {
|
|
247
|
-
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
#content {
|
|
251
|
-
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
.hover_property {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
.setclass {
|
|
261
|
-
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
code{
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
table {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
}
|
|
271
|
-
td {
|
|
272
|
-
|
|
273
|
-
}
|
|
274
|
-
#legend table.entity {
|
|
275
|
-
|
|
276
|
-
}
|
|
231
|
+
#toc {
|
|
232
|
+
position: fixed;
|
|
233
|
+
top: 0;
|
|
234
|
+
right: 0;
|
|
235
|
+
z-index: 2;
|
|
236
|
+
height: 100%;
|
|
237
|
+
overflow-y: auto;
|
|
238
|
+
padding: 10px;
|
|
239
|
+
border: solid 1px navy;
|
|
240
|
+
font-size: small;
|
|
241
|
+
width: 180px;
|
|
242
|
+
}
|
|
243
|
+
#toc h3 {
|
|
244
|
+
margin-top: 5px;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
#toc ul {
|
|
248
|
+
list-style: none;
|
|
249
|
+
padding-left: 0;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
#toc .first > li {
|
|
253
|
+
margin-top: 5px;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
#toc .second,
|
|
257
|
+
#toc .third {
|
|
258
|
+
padding-left: 10px;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
#content {
|
|
262
|
+
width: calc(100% - 150px);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.hover_property {
|
|
266
|
+
cursor: help;
|
|
267
|
+
text-decoration: none;
|
|
268
|
+
border-bottom: dashed 1px;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.setclass {
|
|
272
|
+
list-style-type: none;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
code{
|
|
276
|
+
word-wrap: break-word;
|
|
277
|
+
}
|
|
278
|
+
table {
|
|
279
|
+
table-layout: fixed;
|
|
280
|
+
width: 100%;
|
|
281
|
+
}
|
|
282
|
+
td {
|
|
283
|
+
word-wrap: break-word;
|
|
284
|
+
}
|
|
285
|
+
#legend table.entity {
|
|
286
|
+
width: 25%;
|
|
287
|
+
}
|
|
@@ -1715,7 +1715,7 @@ schema:code a rdf:Property ;
|
|
|
1715
1715
|
schema:rangeIncludes schema:MedicalCode .
|
|
1716
1716
|
|
|
1717
1717
|
schema:codeRepository a rdf:Property ;
|
|
1718
|
-
rdfs:label "
|
|
1718
|
+
rdfs:label "code repository" ;
|
|
1719
1719
|
rdfs:comment "Link to the repository where the un-compiled, human readable code and related code is located (SVN, github, CodePlex)." ;
|
|
1720
1720
|
schema:domainIncludes schema:SoftwareSourceCode ;
|
|
1721
1721
|
schema:rangeIncludes schema:URL .
|
|
@@ -1,13 +1,5 @@
|
|
|
1
1
|
from rdflib import Namespace
|
|
2
|
-
from rdflib.namespace import
|
|
3
|
-
DCTERMS,
|
|
4
|
-
OWL,
|
|
5
|
-
RDF,
|
|
6
|
-
RDFS,
|
|
7
|
-
SDO,
|
|
8
|
-
SKOS,
|
|
9
|
-
VANN,
|
|
10
|
-
)
|
|
2
|
+
from rdflib.namespace import DCTERMS, OWL, RDF, RDFS, SDO, SKOS, VANN, XSD
|
|
11
3
|
|
|
12
4
|
ONTDOC = Namespace("https://w3id.org/profile/ontdoc/")
|
|
13
5
|
|
|
@@ -160,6 +152,7 @@ ONT_TYPES = {
|
|
|
160
152
|
OWL.AnnotationProperty: ("ap", "OWL Annotation Property"),
|
|
161
153
|
OWL.FunctionalProperty: ("fp", "OWL Functional Property"),
|
|
162
154
|
OWL.InverseFunctionalProperty: ("ifp", "OWL Inverse Functional Property"),
|
|
155
|
+
RDFS.Datatype: ("dt", "RDFS Datatypes"),
|
|
163
156
|
OWL.NamedIndividual: ("ni", "OWL Named Individual"),
|
|
164
157
|
}
|
|
165
158
|
|
|
@@ -176,3 +169,10 @@ RESTRICTION_TYPES = [
|
|
|
176
169
|
]
|
|
177
170
|
|
|
178
171
|
OWL_SET_TYPES = [OWL.unionOf, OWL.intersectionOf]
|
|
172
|
+
|
|
173
|
+
DATATYPE_CARDINALITIES = {
|
|
174
|
+
XSD.minInclusive: ">=",
|
|
175
|
+
XSD.minExclusive: ">",
|
|
176
|
+
XSD.maxInclusive: "<=",
|
|
177
|
+
XSD.maxExclusive: "<",
|
|
178
|
+
}
|
|
@@ -36,6 +36,7 @@ from rdflib.paths import ZeroOrMore
|
|
|
36
36
|
try:
|
|
37
37
|
from .rdf_elements import (
|
|
38
38
|
AGENT_PROPS,
|
|
39
|
+
DATATYPE_CARDINALITIES,
|
|
39
40
|
ONT_TYPES,
|
|
40
41
|
ONTDOC,
|
|
41
42
|
OWL_SET_TYPES,
|
|
@@ -410,9 +411,9 @@ def rdf_obj_html(
|
|
|
410
411
|
):
|
|
411
412
|
def _hyperlink_html(
|
|
412
413
|
ont__: Graph,
|
|
414
|
+
iri__: URIRef,
|
|
413
415
|
back_onts__: Graph,
|
|
414
416
|
ns__: Tuple[str, str],
|
|
415
|
-
iri__: URIRef,
|
|
416
417
|
fids__,
|
|
417
418
|
rdf_type__: Optional[URIRef] = None,
|
|
418
419
|
):
|
|
@@ -470,8 +471,6 @@ def rdf_obj_html(
|
|
|
470
471
|
else:
|
|
471
472
|
try:
|
|
472
473
|
qname = ont__.compute_qname(iri__, False)
|
|
473
|
-
if "ASGS" in qname[2]:
|
|
474
|
-
print(qname)
|
|
475
474
|
except Exception:
|
|
476
475
|
qname = iri__
|
|
477
476
|
prefix = "" if qname[0] == "" else f"{qname[0]}:"
|
|
@@ -503,11 +502,13 @@ def rdf_obj_html(
|
|
|
503
502
|
def _literal_html(obj__):
|
|
504
503
|
if str(obj__).startswith("http"):
|
|
505
504
|
return _hyperlink_html(
|
|
506
|
-
ont_,
|
|
505
|
+
ont_, cast(URIRef, obj__), back_onts_, ns_, fids_
|
|
507
506
|
)
|
|
508
507
|
else:
|
|
509
508
|
if prop == SKOS.example:
|
|
510
509
|
return pre(str(obj__))
|
|
510
|
+
elif obj__.datatype == RDF.HTML:
|
|
511
|
+
return raw(str(obj__))
|
|
511
512
|
else:
|
|
512
513
|
return raw(markdown.markdown(str(obj__)))
|
|
513
514
|
|
|
@@ -559,18 +560,47 @@ def rdf_obj_html(
|
|
|
559
560
|
</g>
|
|
560
561
|
</svg>"""
|
|
561
562
|
|
|
563
|
+
def _ror_logo_svg(id):
|
|
564
|
+
id = id if ("http" in id) else f"https://ror.org/{id}"
|
|
565
|
+
return f"""
|
|
566
|
+
<svg
|
|
567
|
+
width="20px"
|
|
568
|
+
height="20px"
|
|
569
|
+
viewBox="0 0 164 118"
|
|
570
|
+
version="1.1"
|
|
571
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
572
|
+
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
573
|
+
xml:space="preserve"
|
|
574
|
+
xmlns:serif="http://www.serif.com/"
|
|
575
|
+
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
|
576
|
+
<title>{id}</title>
|
|
577
|
+
<g transform="matrix(0.994301,0,0,0.989352,0,0)">
|
|
578
|
+
<rect x="0" y="0" width="164.94" height="119.27" style="fill:white;"/>
|
|
579
|
+
</g>
|
|
580
|
+
<g transform="matrix(1,0,0,1,-0.945,-0.815)">
|
|
581
|
+
<path d="M68.65,4.16L56.52,22.74L44.38,4.16L68.65,4.16Z" style="fill:rgb(83,186,161);fill-rule:nonzero;"/>
|
|
582
|
+
<path d="M119.41,4.16L107.28,22.74L95.14,4.16L119.41,4.16Z" style="fill:rgb(83,186,161);fill-rule:nonzero;"/>
|
|
583
|
+
<path d="M44.38,115.47L56.52,96.88L68.65,115.47L44.38,115.47Z" style="fill:rgb(83,186,161);fill-rule:nonzero;"/>
|
|
584
|
+
<path d="M95.14,115.47L107.28,96.88L119.41,115.47L95.14,115.47Z" style="fill:rgb(83,186,161);fill-rule:nonzero;"/>
|
|
585
|
+
<path d="M145.53,63.71C149.83,62.91 153.1,61 155.33,57.99C157.57,54.98 158.68,51.32 158.68,47.03C158.68,43.47 158.06,40.51 156.83,38.13C155.6,35.75 153.93,33.86 151.84,32.45C149.75,31.05 147.31,30.04 144.53,29.44C141.75,28.84 138.81,28.54 135.72,28.54L112.16,28.54L112.16,47.37C111.97,46.82 111.77,46.28 111.55,45.74C109.92,41.79 107.64,38.42 104.71,35.64C101.78,32.86 98.32,30.72 94.3,29.23C90.29,27.74 85.9,26.99 81.14,26.99C76.38,26.99 72,27.74 67.98,29.23C63.97,30.72 60.5,32.86 57.57,35.64C54.95,38.13 52.85,41.1 51.27,44.54C51.04,42.07 50.46,39.93 49.53,38.13C48.3,35.75 46.63,33.86 44.54,32.45C42.45,31.05 40.01,30.04 37.23,29.44C34.45,28.84 31.51,28.54 28.42,28.54L4.87,28.54L4.87,89.42L18.28,89.42L18.28,65.08L24.9,65.08L37.63,89.42L53.71,89.42L38.24,63.71C42.54,62.91 45.81,61 48.04,57.99C48.14,57.85 48.23,57.7 48.33,57.56C48.31,58.03 48.3,58.5 48.3,58.98C48.3,63.85 49.12,68.27 50.75,72.22C52.38,76.17 54.66,79.54 57.59,82.32C60.51,85.1 63.98,87.24 68,88.73C72.01,90.22 76.4,90.97 81.16,90.97C85.92,90.97 90.3,90.22 94.32,88.73C98.33,87.24 101.8,85.1 104.73,82.32C107.65,79.54 109.93,76.17 111.57,72.22C111.79,71.69 111.99,71.14 112.18,70.59L112.18,89.42L125.59,89.42L125.59,65.08L132.21,65.08L144.94,89.42L161.02,89.42L145.53,63.71ZM36.39,50.81C35.67,51.73 34.77,52.4 33.68,52.83C32.59,53.26 31.37,53.52 30.03,53.6C28.68,53.69 27.41,53.73 26.2,53.73L18.29,53.73L18.29,39.89L27.06,39.89C28.26,39.89 29.5,39.98 30.76,40.15C32.02,40.32 33.14,40.65 34.11,41.14C35.08,41.63 35.89,42.33 36.52,43.25C37.15,44.17 37.47,45.4 37.47,46.95C37.47,48.6 37.11,49.89 36.39,50.81ZM98.74,66.85C97.85,69.23 96.58,71.29 94.91,73.04C93.25,74.79 91.26,76.15 88.93,77.13C86.61,78.11 84.01,78.59 81.15,78.59C78.28,78.59 75.69,78.1 73.37,77.13C71.05,76.16 69.06,74.79 67.39,73.04C65.73,71.29 64.45,69.23 63.56,66.85C62.67,64.47 62.23,61.85 62.23,58.98C62.23,56.17 62.67,53.56 63.56,51.15C64.45,48.74 65.72,46.67 67.39,44.92C69.05,43.17 71.04,41.81 73.37,40.83C75.69,39.86 78.28,39.37 81.15,39.37C84.02,39.37 86.61,39.86 88.93,40.83C91.25,41.8 93.24,43.17 94.91,44.92C96.57,46.67 97.85,48.75 98.74,51.15C99.63,53.56 100.07,56.17 100.07,58.98C100.07,61.85 99.63,64.47 98.74,66.85ZM143.68,50.81C142.96,51.73 142.06,52.4 140.97,52.83C139.88,53.26 138.66,53.52 137.32,53.6C135.97,53.69 134.7,53.73 133.49,53.73L125.58,53.73L125.58,39.89L134.35,39.89C135.55,39.89 136.79,39.98 138.05,40.15C139.31,40.32 140.43,40.65 141.4,41.14C142.37,41.63 143.18,42.33 143.81,43.25C144.44,44.17 144.76,45.4 144.76,46.95C144.76,48.6 144.4,49.89 143.68,50.81Z" style="fill:rgb(32,40,38);fill-rule:nonzero;"/>
|
|
586
|
+
</g>
|
|
587
|
+
</svg>"""
|
|
588
|
+
|
|
562
589
|
if isinstance(obj__, Literal):
|
|
563
590
|
return span(str(obj__))
|
|
564
591
|
honorific_prefix = None
|
|
565
592
|
name = None
|
|
566
593
|
identifier = None
|
|
567
594
|
orcid = None
|
|
595
|
+
ror = None
|
|
568
596
|
url = None
|
|
569
597
|
email = None
|
|
570
598
|
affiliation = None
|
|
571
599
|
|
|
572
600
|
if "orcid.org" in str(obj__):
|
|
573
601
|
orcid = True
|
|
602
|
+
elif "ror.org" in str(obj__):
|
|
603
|
+
ror = True
|
|
574
604
|
|
|
575
605
|
for px, o in ont__.predicate_objects(obj__):
|
|
576
606
|
if px in AGENT_PROPS:
|
|
@@ -607,6 +637,13 @@ def rdf_obj_html(
|
|
|
607
637
|
sp.appendChild(
|
|
608
638
|
a(raw(_orcid_logo_svg(identifier)), href=identifier)
|
|
609
639
|
)
|
|
640
|
+
elif ror:
|
|
641
|
+
if "ror.org" in obj__:
|
|
642
|
+
sp.appendChild(a(raw(_ror_logo_svg(obj__)), href=obj__))
|
|
643
|
+
else:
|
|
644
|
+
sp.appendChild(
|
|
645
|
+
a(raw(_ror_logo_svg(identifier)), href=identifier)
|
|
646
|
+
)
|
|
610
647
|
elif identifier is not None:
|
|
611
648
|
sp.appendChild(a(identifier, href=identifier))
|
|
612
649
|
if email is not None:
|
|
@@ -629,10 +666,15 @@ def rdf_obj_html(
|
|
|
629
666
|
for px, o in ont__.predicate_objects(obj__):
|
|
630
667
|
if px != RDF.type:
|
|
631
668
|
if px == OWL.onProperty:
|
|
632
|
-
prop = _hyperlink_html(ont__, back_onts_, ns__,
|
|
633
|
-
#Added the onClass restriction otherwise the class name is ignored in the HTML output.
|
|
669
|
+
prop = _hyperlink_html(ont__, o, back_onts_, ns__, fids_)
|
|
670
|
+
# Added the onClass restriction otherwise the class name is ignored in the HTML output.
|
|
634
671
|
elif px == OWL.onClass:
|
|
635
|
-
|
|
672
|
+
if (o, OWL.unionOf | OWL.intersectionOf, None) in ont__:
|
|
673
|
+
cls = _setclass_html(ont__, o, back_onts_, ns__, fids_)
|
|
674
|
+
else:
|
|
675
|
+
cls = _hyperlink_html(
|
|
676
|
+
ont__, o, back_onts_, ns__, fids_, OWL.Class
|
|
677
|
+
)
|
|
636
678
|
elif px in RESTRICTION_TYPES + OWL_SET_TYPES:
|
|
637
679
|
if px in [
|
|
638
680
|
OWL.minCardinality,
|
|
@@ -674,12 +716,35 @@ def rdf_obj_html(
|
|
|
674
716
|
span(card, _class="cardinality"),
|
|
675
717
|
span(
|
|
676
718
|
_hyperlink_html(
|
|
677
|
-
ont__, back_onts_, ns__,
|
|
719
|
+
ont__, o, back_onts_, ns__, fids_, OWL.Class
|
|
678
720
|
)
|
|
679
721
|
),
|
|
680
722
|
)
|
|
681
|
-
|
|
682
|
-
|
|
723
|
+
elif px == ONTDOC.inRangeOf: # rdfs:range
|
|
724
|
+
for o2 in ont__.objects(o, RDFS.range):
|
|
725
|
+
for rp, ro in ont__.predicate_objects(o2):
|
|
726
|
+
if rp == OWL.onDatatype:
|
|
727
|
+
prop = _hyperlink_html(
|
|
728
|
+
ont__, ro, back_onts_, ns__, fids_
|
|
729
|
+
)
|
|
730
|
+
if rp == OWL.withRestrictions:
|
|
731
|
+
cards = []
|
|
732
|
+
for ro2 in ont__.objects(o2, OWL.withRestrictions):
|
|
733
|
+
for ro3 in ont__.objects(
|
|
734
|
+
ro2, RDF.rest * ZeroOrMore / RDF.first
|
|
735
|
+
):
|
|
736
|
+
for rp4, ro4 in ont__.predicate_objects(
|
|
737
|
+
ro3
|
|
738
|
+
):
|
|
739
|
+
if rp4 in DATATYPE_CARDINALITIES.keys():
|
|
740
|
+
cards.append(
|
|
741
|
+
f"{DATATYPE_CARDINALITIES[rp4]}{ro4}"
|
|
742
|
+
)
|
|
743
|
+
if len(cards) > 0:
|
|
744
|
+
card = " [" + ", ".join(cards) + "]"
|
|
745
|
+
# XXX
|
|
746
|
+
|
|
747
|
+
# Combined the check for card and cls so that only one br is added.
|
|
683
748
|
if card is not None and cls is not None:
|
|
684
749
|
restriction = span(prop, card, cls, br())
|
|
685
750
|
elif card is not None:
|
|
@@ -699,18 +764,18 @@ def rdf_obj_html(
|
|
|
699
764
|
else:
|
|
700
765
|
joining_word = span(",", _class="cardinality")
|
|
701
766
|
|
|
702
|
-
class_set =
|
|
767
|
+
class_set = []
|
|
703
768
|
for o in ont__.objects(obj__, OWL.unionOf | OWL.intersectionOf):
|
|
704
769
|
for o2 in ont__.objects(o, RDF.rest * ZeroOrMore / RDF.first):
|
|
705
|
-
class_set.
|
|
770
|
+
class_set.append(
|
|
706
771
|
_rdf_obj_single_html(
|
|
707
|
-
ont__, back_onts__, ns__, o2, fids__, OWL.Class
|
|
772
|
+
ont__, back_onts__, ns__, o2, fids__, OWL.Class, prop=prop
|
|
708
773
|
)
|
|
709
774
|
)
|
|
710
775
|
|
|
711
776
|
return intersperse(class_set, joining_word)
|
|
712
777
|
|
|
713
|
-
def _bn_html(ont__, back_onts__, ns__, fids__
|
|
778
|
+
def _bn_html(ont__, obj__, back_onts__, ns__, fids__: BNode):
|
|
714
779
|
# TODO: remove back_onts and fids if not needed by subfunctions
|
|
715
780
|
# What kind of BN is it?
|
|
716
781
|
# An Agent, a Restriction or a Set Class (union/intersection)
|
|
@@ -719,15 +784,17 @@ def rdf_obj_html(
|
|
|
719
784
|
return _agent_html(ont__, obj__)
|
|
720
785
|
elif (obj__, RDF.type, OWL.Restriction) in ont__:
|
|
721
786
|
return _restriction_html(ont__, obj__, ns__)
|
|
787
|
+
elif (obj__, RDF.type, RDFS.Datatype) in ont__:
|
|
788
|
+
return _restriction_html(ont__, obj__, ns__)
|
|
722
789
|
else: # (obj, RDF.type, OWL.Class) in ont: # Set Class
|
|
723
790
|
return _setclass_html(ont__, obj__, back_onts__, ns__, fids__)
|
|
724
791
|
|
|
725
792
|
if isinstance(obj_, Tuple) or isinstance(obj_, URIRef):
|
|
726
793
|
ret = _hyperlink_html(
|
|
727
|
-
ont_, back_onts_, ns_,
|
|
794
|
+
ont_, obj_, back_onts_, ns_, fids_, rdf_type__=rdf_type_
|
|
728
795
|
)
|
|
729
796
|
elif isinstance(obj_, BNode):
|
|
730
|
-
ret = _bn_html(ont_, back_onts_, ns_, fids_
|
|
797
|
+
ret = _bn_html(ont_, obj_, back_onts_, ns_, fids_)
|
|
731
798
|
else: # isinstance(obj, Literal):
|
|
732
799
|
ret = _literal_html(obj_)
|
|
733
800
|
|
|
@@ -738,7 +805,7 @@ def rdf_obj_html(
|
|
|
738
805
|
ont, back_onts, ns, obj[0], fids, rdf_type_=rdf_type, prop=prop
|
|
739
806
|
)
|
|
740
807
|
else:
|
|
741
|
-
u_ = ul()
|
|
808
|
+
u_ = ul(_class="pylodelitlist")
|
|
742
809
|
for x in obj:
|
|
743
810
|
u_.appendChild(
|
|
744
811
|
li(
|
|
@@ -781,6 +848,68 @@ def prop_obj_pair_html(
|
|
|
781
848
|
return t
|
|
782
849
|
|
|
783
850
|
|
|
851
|
+
def _make_hierarchy_html(
|
|
852
|
+
ont: Graph, obj_class: URIRef, parent_indicator: URIRef, fids: dict
|
|
853
|
+
):
|
|
854
|
+
if (None, RDF.type, obj_class) in ont:
|
|
855
|
+
items = []
|
|
856
|
+
for s in ont.subjects(RDF.type, obj_class):
|
|
857
|
+
if not isinstance(s, BNode):
|
|
858
|
+
name = ont.value(s, DCTERMS.title | SDO.name)
|
|
859
|
+
if name is None:
|
|
860
|
+
name = make_title_from_iri(s)
|
|
861
|
+
c = {
|
|
862
|
+
"iri": str(s),
|
|
863
|
+
"name": str(
|
|
864
|
+
name
|
|
865
|
+
), # need 2 x for OntPub (title) and VocPub (prefLabel) profiles
|
|
866
|
+
}
|
|
867
|
+
for o2 in ont.objects(s, parent_indicator):
|
|
868
|
+
if not isinstance(o2, BNode):
|
|
869
|
+
c["parent"] = str(o2)
|
|
870
|
+
items.append(c)
|
|
871
|
+
|
|
872
|
+
def build_html_tree(items):
|
|
873
|
+
# Index items by id
|
|
874
|
+
by_id = {item["iri"]: dict(item, children=[]) for item in items}
|
|
875
|
+
|
|
876
|
+
roots = []
|
|
877
|
+
|
|
878
|
+
# Build tree structure
|
|
879
|
+
for item in by_id.values():
|
|
880
|
+
parent = item.get("parent")
|
|
881
|
+
if parent and parent in by_id:
|
|
882
|
+
by_id[parent]["children"].append(item)
|
|
883
|
+
else:
|
|
884
|
+
roots.append(item)
|
|
885
|
+
|
|
886
|
+
# Recursive renderer
|
|
887
|
+
def render_nodes(nodes):
|
|
888
|
+
container = ul(_class="hierarchy")
|
|
889
|
+
for node in sorted(
|
|
890
|
+
nodes,
|
|
891
|
+
key=lambda node: (
|
|
892
|
+
node["name"].casefold(),
|
|
893
|
+
node["name"],
|
|
894
|
+
node["iri"],
|
|
895
|
+
),
|
|
896
|
+
):
|
|
897
|
+
node_li = li(
|
|
898
|
+
a(
|
|
899
|
+
node["name"],
|
|
900
|
+
href="#" + generate_fid(None, node["iri"], fids),
|
|
901
|
+
)
|
|
902
|
+
)
|
|
903
|
+
if node["children"]:
|
|
904
|
+
node_li.add(render_nodes(node["children"]))
|
|
905
|
+
container.add(node_li)
|
|
906
|
+
return container
|
|
907
|
+
|
|
908
|
+
return render_nodes(roots)
|
|
909
|
+
|
|
910
|
+
return div(build_html_tree(items), _class="hierarchy")
|
|
911
|
+
|
|
912
|
+
|
|
784
913
|
def section_html(
|
|
785
914
|
section_title: str,
|
|
786
915
|
ont: Graph,
|
|
@@ -853,6 +982,22 @@ def section_html(
|
|
|
853
982
|
|
|
854
983
|
elems = div(id=toc_ul_id, _class="section")
|
|
855
984
|
elems.appendChild(h2(section_title))
|
|
985
|
+
|
|
986
|
+
if obj_class == OWL.Class:
|
|
987
|
+
elems.appendChild(h3("Class Hierarchy", id="class-hierarchy"))
|
|
988
|
+
elems.appendChild(_make_hierarchy_html(ont, OWL.Class, RDFS.subClassOf, fids))
|
|
989
|
+
elems.appendChild(h3("Class Definitions", id="class-definitions"))
|
|
990
|
+
elif obj_class == OWL.ObjectProperty:
|
|
991
|
+
elems.appendChild(
|
|
992
|
+
h3("Object Property Hierarchy", id="object-property-hierarchy")
|
|
993
|
+
)
|
|
994
|
+
elems.appendChild(
|
|
995
|
+
_make_hierarchy_html(ont, OWL.ObjectProperty, RDFS.subPropertyOf, fids)
|
|
996
|
+
)
|
|
997
|
+
elems.appendChild(
|
|
998
|
+
h3("Object Property Definitions", id="object-property-definitions")
|
|
999
|
+
)
|
|
1000
|
+
|
|
856
1001
|
# get all objects of this class
|
|
857
1002
|
for s_ in ont.subjects(predicate=RDF.type, object=obj_class):
|
|
858
1003
|
if obj_class == RDF.Property:
|
|
@@ -918,7 +1063,7 @@ def de_space_html(html):
|
|
|
918
1063
|
# s = "".join([l_.strip().replace("\n", " ") for l_ in html.split("\n")])
|
|
919
1064
|
# return re.sub(" +", " ", s)
|
|
920
1065
|
s = re.sub(r">\s+<", "><", html)
|
|
921
|
-
return re.sub(r"\s+", " ", s)
|
|
1066
|
+
return re.sub(r"\s+", " ", s).strip()
|
|
922
1067
|
|
|
923
1068
|
|
|
924
1069
|
def make_pylode_logo(doc, version, profile_name, profile_iri):
|
|
@@ -7,7 +7,7 @@ Changelog = "https://github.com/RDFLib/pyLODE/releases"
|
|
|
7
7
|
|
|
8
8
|
[project]
|
|
9
9
|
name = "pylode"
|
|
10
|
-
version = "3.
|
|
10
|
+
version = "3.5.1"
|
|
11
11
|
description = "An OWL ontology documentation tool using Python, based on LODE."
|
|
12
12
|
authors = [{ name = "Nicholas Car", email = "nick@kurrawong.ai" }]
|
|
13
13
|
requires-python = ">=3.12,<4"
|
|
@@ -24,7 +24,7 @@ classifiers = [
|
|
|
24
24
|
dependencies = [
|
|
25
25
|
"rdflib>=7.6.0,<8.0.0",
|
|
26
26
|
"Markdown>=3.3.7,<4",
|
|
27
|
-
"dominate>=2.
|
|
27
|
+
"dominate>=2.9.1,<3",
|
|
28
28
|
"html5lib>=1.1,<2",
|
|
29
29
|
"httpx>=0.25.0,<1.0.0",
|
|
30
30
|
"tqdm>=4.67.3",
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|