Source code for parselglossy.documentation
# -*- coding: utf-8 -*-
#
# parselglossy -- Generic input parsing library, speaking in tongues
# Copyright (C) 2020 Roberto Di Remigio, Radovan Bast, and contributors.
#
# This file is part of parselglossy.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# For information on the complete list of contributors to the
# parselglossy library, see: <http://parselglossy.readthedocs.io/>
#
"""Documentation generation."""
from typing import List # noqa: F401
from .utils import JSONDict
[docs]def documentation_generator(
template: JSONDict, *, header: str = "Input parameters"
) -> str:
"""Generates documentation from a valid template.
Parameters
----------
template : JSONDict
The template to generate documentation from.
We assume that the template is valid.
Returns
-------
documentation : str
"""
comment = (
".. raw:: html\n\n" # noqa: F541
" <style> .red {color:#aa0060; font-weight:bold; font-size:18px} </style>\n\n" # noqa: E501
".. role:: red\n\n"
f".. This documentation was autogenerated using parselglossy."
" Editing by hand is not recommended.\n"
)
header = (
f"{comment:s}\n{'=' * len(header):s}\n{header:s}\n{'=' * len(header):s}\n\n"
"- Keywords without a default value are **required**.\n"
"- Default values are either explicit or computed from the value of other keywords in the input.\n" # noqa: E501
"- Sections where all keywords have a default value can be omitted.\n"
"- Predicates, if present, are the functions run to validate user input.\n"
)
docs = _rec_documentation_generator(template=template)
documentation = header + docs
return documentation
def _document_keyword(keyword: JSONDict) -> str:
docstring = keyword["docstring"].replace("\n", " ")
doc = f"""
:{keyword['name']:s}: {docstring:s}
**Type** ``{keyword['type']:s}``
"""
if "default" in keyword.keys():
doc += f"""
**Default** ``{keyword['default']}``
"""
if "predicates" in keyword.keys():
preds = "\n ".join((f"- ``{x}``" for x in keyword["predicates"]))
doc += f"""
**Predicates**
{preds}
"""
return doc
def _rec_documentation_generator(template, *, level: int = 0) -> str:
"""Generates documentation from a valid template.
Parameters
----------
template : JSONDict
level : int
Returns
-------
docs : str
"""
docs = [] # type: List[str]
keywords = template["keywords"] if "keywords" in template.keys() else []
if keywords:
docs.append(_indent("\n:red:`Keywords`", level))
for k in keywords:
doc = _document_keyword(k)
docs.extend(_indent(doc, level))
sections = template["sections"] if "sections" in template.keys() else []
if sections:
docs.append(_indent("\n:red:`Sections`", level))
for s in sections:
docstring = s["docstring"].replace("\n", " ")
doc = f"\n :{s['name']:s}: {docstring:s}\n"
doc += _rec_documentation_generator(s, level=level + 1)
docs.extend(_indent(doc, level))
return "".join(docs)
def _indent(in_str: str, level: int = 0) -> str:
return in_str.replace("\n", "\n" + (" " * level))