forked from spdx/spec-parser
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmkdocs.py
134 lines (111 loc) · 4.45 KB
/
mkdocs.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# saving the model as MkDocs input
# SPDX-License-Identifier: Apache-2.0
import logging
from pathlib import Path
from jinja2 import Environment, PackageLoader, select_autoescape
def gen_mkdocs(model, outdir, cfg):
p = Path(outdir)
if p.exists() and not cfg.opt_force:
logging.error(f"Destination for mkdocs {outdir} already exists, will not overwrite")
return
jinja = Environment(
loader=PackageLoader("spec_parser", package_path="templates/mkdocs"),
autoescape=select_autoescape(),
trim_blocks=True,
lstrip_blocks=True,
)
jinja.globals = cfg.all_as_dict
jinja.globals["class_link"] = class_link
jinja.globals["property_link"] = property_link
jinja.globals["type_link"] = lambda x: type_link(x, model)
jinja.globals["serialized_name"] = serialized_name
p.mkdir()
for ns in model.namespaces:
d = p / ns.name
d.mkdir()
f = d / f"{ns.name}.md"
template = jinja.get_template("namespace.md.j2")
page = template.render(vars(ns))
f.write_text(page)
def _generate_in_dir(dirname, group, tmplfname):
for s in group.values():
in_ns = s.ns
d = p / in_ns.name / dirname
d.mkdir(exist_ok=True)
f = d / f"{s.name}.md"
template = jinja.get_template(tmplfname)
page = template.render(vars(s))
f.write_text(page)
_generate_in_dir("Classes", model.classes, "class.md.j2")
_generate_in_dir("Properties", model.properties, "property.md.j2")
_generate_in_dir("Vocabularies", model.vocabularies, "vocabulary.md.j2")
_generate_in_dir("Individuals", model.individuals, "individual.md.j2")
_generate_in_dir("Datatypes", model.datatypes, "datatype.md.j2")
def _gen_filelist(nsname, itemslist, heading):
ret = []
nameslist = [c.name for c in itemslist.values()]
if nameslist:
ret.append(f" - {heading}:")
for n in sorted(nameslist):
ret.append(f" - model/{nsname}/{heading}/{n}.md")
return ret
files = dict()
for ns in model.namespaces:
nsn = ns.name
files[nsn] = []
files[nsn].append(f" - {nsn}:")
files[nsn].append(f" - 'Description': model/{nsn}/{nsn}.md")
files[nsn].extend(_gen_filelist(nsn, ns.classes, "Classes"))
files[nsn].extend(_gen_filelist(nsn, ns.properties, "Properties"))
files[nsn].extend(_gen_filelist(nsn, ns.vocabularies, "Vocabularies"))
files[nsn].extend(_gen_filelist(nsn, ns.individuals, "Individuals"))
files[nsn].extend(_gen_filelist(nsn, ns.datatypes, "Datatypes"))
filelines = []
filelines.append('- model:')
# hardwired order of namespaces
for nsname in ["Core", "Software", "Security",
"Licensing", "SimpleLicensing", "ExpandedLicensing",
"Dataset", "AI", "Build", "Lite", "Extension"]:
filelines.extend(files[nsname])
fn = p / "mkdocs-files.yml"
fn.write_text("\n".join(filelines))
def class_link(name):
if name.startswith("/"):
_, other_ns, name = name.split("/")
return f"[/{other_ns}/{name}](../../{other_ns}/Classes/{name}.md)"
else:
return f"[{name}](../Classes/{name}.md)"
def property_link(name):
if name.startswith("/"):
_, other_ns, name = name.split("/")
return f"[/{other_ns}/{name}](../../{other_ns}/Properties/{name}.md)"
else:
return f"[{name}](../Properties/{name}.md)"
def type_link(name, model):
if name.startswith("/"):
dirname = "Classes"
if name in model.vocabularies:
dirname = "Vocabularies"
elif name in model.datatypes:
dirname = "Datatypes"
_, other_ns, name = name.split("/")
return f"[/{other_ns}/{name}](../../{other_ns}/{dirname}/{name}.md)"
elif name[0].isupper():
dirname = "Classes"
p = [x for x in model.vocabularies if x.endswith("/" + name)]
if len(p) > 0:
dirname = "Vocabularies"
else:
p = [x for x in model.datatypes if x.endswith("/" + name)]
if len(p) > 0:
dirname = "Datatypes"
return f"[{name}](../{dirname}/{name}.md)"
else:
return f"{name}"
def serialized_name(name):
if name.startswith("/"):
_, ns, name = name.split("/")
if ns == "Core":
return name
return f"{ns.lower()}_{name}"
return name