Skip to content

Commit

Permalink
Merge pull request #67 from spdx/feature/jinja2
Browse files Browse the repository at this point in the history
  • Loading branch information
zvr committed Sep 6, 2023
2 parents c1c645b + 53218f4 commit 1c7804e
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 157 deletions.
22 changes: 22 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/python
{
"name": "Python 3",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/python:1-3.11-bullseye",

// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},

// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],

// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "pip3 install --user -r requirements.txt",

// Configure tool-specific properties.
// "customizations": {},

// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}
14 changes: 4 additions & 10 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
#
# These requirements were autogenerated by pipenv
# To regenerate from the project's Pipfile, run:
#
# pipenv lock --requirements
#

-i https://pypi.org/simple
isodate==0.6.0
pyparsing==2.4.7; python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'
Jinja2==3.1.2
MarkupSafe==2.1.3
pyparsing==2.4.7
rdflib==6.0.0
six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
six==1.16.0
sly==0.4
48 changes: 48 additions & 0 deletions spec_parser/templates/default/class.md.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<!-- Auto generated markdown by Spec-parser {{__version__}} -->

<!-- SPDX-License-Identifier: {{license_name}} -->

# {{name}}

## Summary
{{summary}}

## Description
{{description}}

## Metadata
{% for name, vals in metadata | dictsort %}
- {{name}}: {{vals | list | join(" ")}}
{% endfor %}

## Properties
{% if args.get("use_table", False) %}
header_list = ["type", "minCount", "maxCount"]

# print the header
f.write("|" + "|".join(["property"] + header_list) + "|\n")
f.write("|" + "---|" * (len(header_list) + 1) + "\n")

{% for name, subprops in properties | dictsort %}
|{{name}}
{% for subprop in header_list %}
|{{subprops.get(subprop, ["NA"]) | join(" ")}}
{% endfor %}
|
{% endfor %}
{% else %}
{% for name, subprops in properties | dictsort %}
- {{name}}
{% for _key, subprop in subprops | dictsort %}
- {{_key}}: {{subprop | list | join(" ")}}
{% endfor %}
{% endfor %}
{% endif %}

{% if format_pattern %}
## Format

{% for name, vals in format_pattern | dictsort %}
- {{name}}: {{vals | list | join(" ")}}
{% endfor %}
{% endif %}
23 changes: 23 additions & 0 deletions spec_parser/templates/default/property.md.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!-- Auto generated markdown by Spec-parser v{{__version__}} -->

<!-- SPDX-License-Identifier: {{license_name}} -->

# {{name}}

## Summary
{{summary}}

## Description
{{description}}

## Metadata
{% for name, vals in metadata | dictsort %}
- {{name}}: {{vals | list | join(" ")}}
{% endfor %}

{% if args.get("gen_refs", False) %}
## References
{% for name in spec.dataprop_refs.get(self.name, []) | dictsort %}
- {{name}}
{% endfor %}
{% endif %}
21 changes: 21 additions & 0 deletions spec_parser/templates/default/vocab.md.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!-- Auto generated markdown by Spec-parser v{{__version__}} -->

<!-- SPDX-License-Identifier: {{license_name}} -->

# {{name}}

## Summary
{{summary}}

## Description
{{description}}

## Metadata
{% for name, vals in metadata | dictsort %}
- {{name}}: {{vals | list | join(" ")}}
{% endfor %}

## Entries
{% for name, val in entries | dictsort %}
- {{name}}: {{val}}
{% endfor %}
172 changes: 25 additions & 147 deletions spec_parser/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
from os import path
from typing import List

from jinja2 import Environment, PackageLoader, select_autoescape

import rdflib
from rdflib import URIRef, Literal, BNode, SH
from rdflib.extras.infixowl import EnumeratedClass
Expand Down Expand Up @@ -115,20 +117,25 @@ def gen_md(self) -> None:
if path.isdir(self.args["out_dir"]):
self.logger.warning(f"Overwriting out_dir `{self.args['out_dir']}`")

env = Environment(
loader=PackageLoader("spec_parser", package_path="templates/default"),
autoescape=False
)

for namespace in self.namespaces.values():

classes = namespace["classes"]
properties = namespace["properties"]
vocabs = namespace["vocabs"]

for class_obj in classes.values():
class_obj._gen_md(self.args)
class_obj._gen_md(env, self.args)

for prop_obj in properties.values():
prop_obj._gen_md(self.args)
prop_obj._gen_md(env, self.args)

for vocab_obj in vocabs.values():
vocab_obj._gen_md(self.args)
vocab_obj._gen_md(env, self.args)

def _get_defined_class_types(self) -> List[URIRef]:
class_types = []
Expand Down Expand Up @@ -386,78 +393,17 @@ def _extract_format(self, format_list):

self.format_pattern[_key] = _values

def _gen_md(self, args: dict) -> None:
def _gen_md(self, env, args: dict) -> None:

fname = path.join(
args["out_dir"], self.namespace_name, "Classes", f"{self.name}.md"
)

with safe_open(fname, "w") as f:

# write the header
f.write(
f"<!-- Auto generated markdown by Spec-parser v{__version__} -->\n\n"
)

# write the license name
f.write(
f"<!-- SPDX-License-Identifier: {self.license_name} -->\n\n"
)
template = env.get_template("class.md.j2")
result = template.render({'__version__': __version__, 'args': args} | vars(self))

# write the topheadline
f.write(f"# {self.name}\n\n")

# write the summary
f.write("## Summary\n\n")
f.write(f"{self.summary}\n")
f.write("\n")

# write the description
f.write("## Description\n\n")
f.write(f"{self.description}\n")
f.write("\n")

# write the metadata
f.write("## Metadata\n\n")
for name, vals in sorted(self.metadata.items()):
if isinstance(vals, list):
f.write(f'- {name}: {" ".join(vals)}\n')
else:
f.write(f'- {name}: {vals}\n')
f.write("\n")

# write the data_props
f.write("## Properties\n\n")
if args.get("use_table", False):
# generate markdown-table from properties
header_list = ["type", "minCount", "maxCount"]

# print the header
f.write("|" + "|".join(["property"] + header_list) + "|\n")
f.write("|" + "---|" * (len(header_list) + 1) + "\n")

for name, subprops in sorted(self.properties.items()):
f.write(f"|{name}")
for subprop in header_list:
f.write(f'|{" ".join(subprops.get(subprop, ["NA"]))}')
f.write("|\n")
else:
# generate markdown-list from properties
for name, subprops in sorted(self.properties.items()):
f.write(f"- {name}\n")
for _key, subprop in sorted(subprops.items()):
if isinstance(subprop, list):
f.write(f' - {_key}: {" ".join(subprop)}\n')
else:
f.write(f' - {_key}: {subprop}\n')
f.write("\n")
if self.format_pattern:
f.write("## Format\n\n")
for name, vals in sorted(self.format_pattern.items()):
if isinstance(vals, list):
f.write(f'- {name}: {" ".join(vals)}\n')
else:
f.write(f'- {name}: {vals}\n')
with safe_open(fname, "w") as f:
f.write(result)


def _gen_rdf(self, g: rdflib.Graph, class_types: List[URIRef]) -> None:
Expand Down Expand Up @@ -540,51 +486,17 @@ def __init__(
self.logger = logging.getLogger(self.__class__.__name__)
self._extract_metadata(metadata)

def _gen_md(self, args: dict) -> None:
def _gen_md(self, env, args: dict) -> None:

fname = path.join(
args["out_dir"], self.namespace_name, "Properties", f"{self.name}.md"
)

with safe_open(fname, "w") as f:
template = env.get_template("property.md.j2")
result = template.render({'__version__': __version__, 'args': args} | vars(self))

# write the header
f.write(
f"<!-- Auto generated markdown by Spec-parser v{__version__} -->\n\n"
)

# write the license name
f.write(
f"<!-- SPDX-License-Identifier: {self.license_name} -->\n\n"
)

# write the topheadline
f.write(f"# {self.name}\n\n")

# write the summary
f.write("## Summary\n\n")
f.write(f"{self.summary}\n")
f.write("\n")

# write the description
f.write("## Description\n\n")
f.write(f"{self.description}\n")
f.write("\n")

# write the metadata
f.write("## Metadata\n\n")
for name, vals in sorted(self.metadata.items()):
if isinstance(vals, list):
f.write(f'- {name}: {" ".join(vals)}\n')
else:
f.write(f'- {name}: {vals}\n')
f.write("\n")

if args.get("gen_refs", False):
# Class references
f.write("## References\n\n")
for name in sorted(self.spec.dataprop_refs.get(self.name, [])):
f.write(f"- {name}\n")
with safe_open(fname, "w") as f:
f.write(result)


def _gen_rdf(self, g: rdflib.Graph) -> None:
Expand Down Expand Up @@ -662,51 +574,17 @@ def __init__(
self._extract_metadata(metadata)
self._extract_entries(entries)

def _gen_md(self, args: dict) -> None:
def _gen_md(self, env, args: dict) -> None:

fname = path.join(
args["out_dir"], self.namespace_name, "Vocabularies", f"{self.name}.md"
)

with safe_open(fname, "w") as f:

# write the header
f.write(
f"<!-- Auto generated markdown by Spec-parser v{__version__} -->\n\n"
)

# write the license name
f.write(
f"<!-- SPDX-License-Identifier: {self.license_name} -->\n\n"
)

# write the topheadline
f.write(f"# {self.name}\n\n")

# write the summary
f.write("## Summary\n\n")
f.write(f"{self.summary}\n")
f.write("\n")

# write the description
f.write("## Description\n\n")
f.write(f"{self.description}\n")
f.write("\n")

# write the metadata
f.write("## Metadata\n\n")
for name, vals in sorted(self.metadata.items()):
if isinstance(vals, list):
f.write(f'- {name}: {" ".join(vals)}\n')
else:
f.write(f'- {name}: {vals}\n')
f.write("\n")

# write the entries
f.write("## Entries\n\n")
for name, val in sorted(self.entries.items()):
f.write(f"- {name}: {val}\n")
template = env.get_template("vocab.md.j2")
result = template.render({'__version__': __version__, 'args': args} | vars(self))

with safe_open(fname, "w") as f:
f.write(result)

def _gen_rdf(self, g: rdflib.Graph):

Expand Down

0 comments on commit 1c7804e

Please sign in to comment.