Use templates to generate rst documentation

Using Jinja2 to generate ReSTructured text documents. Additional templates
could be added to generate emails using this approach.

Change-Id: I384971732166fbeb123d572d3ccbcde6bad39dfc
This commit is contained in:
Grant Murphy 2014-12-10 14:27:33 -08:00
parent ea154bc92d
commit b8c839fa3d
6 changed files with 154 additions and 2 deletions

View File

@ -8,7 +8,7 @@ These pages contain published OpenStack Security Advisories.
:maxdepth: 2
:glob:
ossa/index
./ossa/*
.. seealso::

79
render.py Normal file
View File

@ -0,0 +1,79 @@
import argparse
from jinja2 import FileSystemLoader
from jinja2.environment import Environment
import os
import sys
import yaml
def to_snake_case(d):
for k in d:
v = d[k]
del d[k]
d[k.replace('-', '_')] = v
if type(k) == dict:
to_snake_case(d)
def wrap_text(text, width=80):
out = ""
i = 0
for word in text.split():
i += len(word)
if len(word) > width:
out += word
out += "\n"
i = 0
if i > width:
out += "\n"
out += word
i = len(word)
else:
out += word
out += " "
i += 1
return out
def to_paragraphs(d, *args):
for k in args:
if type(d[k]) == str:
d[k] = wrap_text(d[k])
def ossa_date_formatter(value):
return "{:%B %d, %Y}".format(value)
def csv_list_formatter(value):
return ", ".join(value)
def render_template(template, data):
loader = FileSystemLoader(os.getcwd())
env = Environment(trim_blocks=True, loader=loader)
env.filters["ossa_date"] = ossa_date_formatter
env.filters["csv_list"] = csv_list_formatter
template = env.get_template(template)
return template.render(**data)
def render(source, template):
vals = yaml.safe_load(open(source).read())
to_snake_case(vals)
to_paragraphs(vals, 'description')
return render_template(template, vals)
def main():
parser = argparse.ArgumentParser(description="Convert YAML to RST")
parser.add_argument("--source", required=True, help="YAML source file")
parser.add_argument("--template", required=True,
help="Jinja2 template file")
args = parser.parse_args()
print(render(args.source, args.template))
if __name__ == "__main__":
main()

50
rst.jinja Normal file
View File

@ -0,0 +1,50 @@
=============
{{ id }}
=============
{{ title }}
--------------------------------------------------------------------------------
:Date: {{ date | ossa_date }}
:Description:
{{ description | indent(4, true) }}
{% if reference is defined %}
:Announcement:
- `{{ reference}} <{{ reference }}>`_
{% endif %}
:Affects:
{% for affected in affected_products %}
- {{ affected['product'] }}: {{ affected['version'] }}
{% endfor %}
:Credits:
{% for reporter in reporters %}
{% if 'affiliation' in reporter and reporter['affiliation'] and reporter['affiliation'] != 'UNKNOWN' %}
- {{ reporter['name'] | trim | indent }} from {{ reporter ['affiliation'] }} ({{ reporter['reported'] | csv_list }})
{% else %}
- {{ reporter['name'] | trim | indent }} ({{ reporter['reported'] | csv_list }})
{% endif %}
{% endfor %}
:Bug reports:
{% for link in issues['links'] %}
- `{{ link }} <{{ link }}>`_
{% endfor %}
:Reviews:
{% for release in reviews %}
{% if release != 'type' %}
{% for link in reviews[release] %}
- `{{ link | trim }} ({{ release | trim }}) <{{link | trim }}>`_
{% endfor %}
{% endif %}
{% endfor %}

View File

@ -1,3 +1,5 @@
# needed for doc build
Jinja2>=2.7.3
PyYAML==3.11
sphinx>=1.1.2,!=1.2.0,<1.3
oslosphinx>=2.2.0 # Apache-2.0

View File

@ -13,4 +13,7 @@ deps = -r{toxinidir}/test-requirements.txt
commands = {posargs}
[testenv:docs]
commands = python setup.py build_sphinx
deps = -r{toxinidir}/test-requirements.txt
commands =
python yaml2rst.py
python setup.py build_sphinx

18
yaml2rst.py Normal file
View File

@ -0,0 +1,18 @@
#!/usr/bin/env python
import render
import glob
import os
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
def main():
input_files = glob.glob(os.path.join(".", "ossa", "*.yaml"))
output_files = [x.replace(".yaml", ".rst") for x in input_files]
for old, new in zip(input_files, output_files):
with open(new, "w") as out:
out.write(render.render(old, "rst.jinja"))
if __name__ == '__main__':
main()