Reworked docs rendering using jinja2.
This commit is contained in:
parent
1e723e6647
commit
69e9c80ec3
12 changed files with 70 additions and 94 deletions
7
data/templates/xap/docs/docs.md.j2
Normal file
7
data/templates/xap/docs/docs.md.j2
Normal file
|
@ -0,0 +1,7 @@
|
|||
{%- for item in xap.documentation.order -%}
|
||||
{%- if not item[0:1] == '!' -%}
|
||||
{{ xap.documentation.get(item) }}
|
||||
{% else %}
|
||||
{%- include item[1:] %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
9
data/templates/xap/docs/response_flags.md.j2
Normal file
9
data/templates/xap/docs/response_flags.md.j2
Normal file
|
@ -0,0 +1,9 @@
|
|||
|{% for bitnum, bitinfo in xap.response_flags.bits | dictsort | reverse %} Bit {{ bitnum }} |{% endfor %}
|
||||
|{% for bitnum, bitinfo in xap.response_flags.bits | dictsort | reverse %} -- |{% endfor %}
|
||||
|{% for bitnum, bitinfo in xap.response_flags.bits | dictsort | reverse %} `{{ bitinfo.define }}` |{%- endfor %}
|
||||
|
||||
{% for bitnum, bitinfo in xap.response_flags.bits | dictsort | reverse %}
|
||||
{%- if bitinfo.define != "-" -%}
|
||||
* Bit {{ bitnum }} (`{{ bitinfo.define }}`): {{ bitinfo.description }}
|
||||
{% endif %}
|
||||
{%- endfor %}
|
5
data/templates/xap/docs/term_definitions.md.j2
Normal file
5
data/templates/xap/docs/term_definitions.md.j2
Normal file
|
@ -0,0 +1,5 @@
|
|||
| Name | Definition |
|
||||
| -- | -- |
|
||||
{%- for type, definition in xap.term_definitions | dictsort %}
|
||||
| _{{ type }}_ | {{ definition }} |
|
||||
{%- endfor %}
|
5
data/templates/xap/docs/type_docs.md.j2
Normal file
5
data/templates/xap/docs/type_docs.md.j2
Normal file
|
@ -0,0 +1,5 @@
|
|||
| Name | Definition |
|
||||
| -- | -- |
|
||||
{%- for type, definition in xap.type_docs | dictsort %}
|
||||
| _{{ type }}_ | {{ definition }} |
|
||||
{%- endfor %}
|
|
@ -9,13 +9,13 @@
|
|||
order: [
|
||||
page_header
|
||||
type_docs
|
||||
!type_docs!
|
||||
!type_docs.md.j2
|
||||
term_definitions
|
||||
!term_definitions!
|
||||
!term_definitions.md.j2
|
||||
request_response
|
||||
reserved_tokens
|
||||
response_flags
|
||||
!response_flags!
|
||||
!response_flags.md.j2
|
||||
example_conversation
|
||||
]
|
||||
|
||||
|
|
|
@ -41,10 +41,11 @@ This token is followed by a `u8` signifying the length of data in the request.
|
|||
Response messages will always be prefixed by the originating request _token_, directly followed by that request's _response flags_, then the response payload length:
|
||||
|
||||
| Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
|
||||
|--|--|--|--|--|--|--|--|
|
||||
| - | - | - | - | - | - | - | Success |
|
||||
| -- | -- | -- | -- | -- | -- | -- | -- |
|
||||
| `-` | `-` | `-` | `-` | `-` | `-` | `-` | `SUCCESS` |
|
||||
|
||||
* Bit 0 (`SUCCESS`): When this bit is set, the request was successfully handled. If not set, all payload data should be disregarded, and the request retried if appropriate (with a new token).
|
||||
|
||||
* `Bit 0`: When this bit is set, the request was successfully handled. If not set, all payload data should be disregarded, and the request retried if appropriate (with a new token).
|
||||
|
||||
### Example "conversation":
|
||||
|
||||
|
|
|
@ -50,13 +50,14 @@ Any request will generate at least one corresponding response, with the exceptio
|
|||
Response messages will always be prefixed by the originating request _token_, directly followed by that request's _response flags_, then the response payload length:
|
||||
|
||||
| Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
|
||||
|--|--|--|--|--|--|--|--|
|
||||
| Unlocked | Unlocking | - | - | - | - | Secure Failure | Success |
|
||||
| -- | -- | -- | -- | -- | -- | -- | -- |
|
||||
| `UNLOCKED` | `UNLOCK_IN_PROGRESS` | `-` | `-` | `-` | `-` | `SECURE_FAILURE` | `SUCCESS` |
|
||||
|
||||
* Bit 7 (`UNLOCKED`): When this bit is set, an _unlock sequence_ has completed, and _secure routes_ may be invoked.
|
||||
* Bit 6 (`UNLOCK_IN_PROGRESS`): When this bit is set, an _unlock sequence_ is in progress.
|
||||
* Bit 1 (`SECURE_FAILURE`): When this bit is set, the requested _route_ was marked _secure_ but an _unlock sequence_ has not completed.
|
||||
* Bit 0 (`SUCCESS`): When this bit is set, the request was successfully handled. If not set, all payload data should be disregarded, and the request retried if appropriate (with a new token).
|
||||
|
||||
* `Bit 7`: When this bit is set, an _unlock sequence_ has completed, and _secure routes_ may be invoked.
|
||||
* `Bit 6`: When this bit is set, an _unlock sequence_ is in progress.
|
||||
* `Bit 1`: When this bit is set, the requested _route_ was marked _secure_ but an _unlock sequence_ has not completed.
|
||||
* `Bit 0`: When this bit is set, the request was successfully handled. If not set, all payload data should be disregarded, and the request retried if appropriate (with a new token).
|
||||
|
||||
### Example "conversation":
|
||||
|
||||
|
|
|
@ -50,13 +50,14 @@ Any request will generate at least one corresponding response, with the exceptio
|
|||
Response messages will always be prefixed by the originating request _token_, directly followed by that request's _response flags_, then the response payload length:
|
||||
|
||||
| Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
|
||||
|--|--|--|--|--|--|--|--|
|
||||
| Unlocked | Unlocking | - | - | - | - | Secure Failure | Success |
|
||||
| -- | -- | -- | -- | -- | -- | -- | -- |
|
||||
| `UNLOCKED` | `UNLOCK_IN_PROGRESS` | `-` | `-` | `-` | `-` | `SECURE_FAILURE` | `SUCCESS` |
|
||||
|
||||
* Bit 7 (`UNLOCKED`): When this bit is set, an _unlock sequence_ has completed, and _secure routes_ may be invoked.
|
||||
* Bit 6 (`UNLOCK_IN_PROGRESS`): When this bit is set, an _unlock sequence_ is in progress.
|
||||
* Bit 1 (`SECURE_FAILURE`): When this bit is set, the requested _route_ was marked _secure_ but an _unlock sequence_ has not completed.
|
||||
* Bit 0 (`SUCCESS`): When this bit is set, the request was successfully handled. If not set, all payload data should be disregarded, and the request retried if appropriate (with a new token).
|
||||
|
||||
* `Bit 7`: When this bit is set, an _unlock sequence_ has completed, and _secure routes_ may be invoked.
|
||||
* `Bit 6`: When this bit is set, an _unlock sequence_ is in progress.
|
||||
* `Bit 1`: When this bit is set, the requested _route_ was marked _secure_ but an _unlock sequence_ has not completed.
|
||||
* `Bit 0`: When this bit is set, the request was successfully handled. If not set, all payload data should be disregarded, and the request retried if appropriate (with a new token).
|
||||
|
||||
### Example "conversation":
|
||||
|
||||
|
|
|
@ -16,7 +16,8 @@ import_names = {
|
|||
# A mapping of package name to importable name
|
||||
'pep8-naming': 'pep8ext_naming',
|
||||
'pyusb': 'usb.core',
|
||||
'qmk-dotty-dict': 'dotty_dict'
|
||||
'qmk-dotty-dict': 'dotty_dict',
|
||||
'Jinja2': 'jinja2'
|
||||
}
|
||||
|
||||
safe_commands = [
|
||||
|
|
|
@ -1,10 +1,21 @@
|
|||
"""This script handles the XAP protocol data files.
|
||||
"""
|
||||
import re
|
||||
import os
|
||||
import hjson
|
||||
from jinja2 import Environment, FileSystemLoader, select_autoescape
|
||||
from qmk.constants import QMK_FIRMWARE
|
||||
from typing import OrderedDict
|
||||
|
||||
from qmk.constants import QMK_FIRMWARE
|
||||
|
||||
def _get_jinja2_env(data_templates_xap_subdir: str):
|
||||
templates_dir = os.path.join(QMK_FIRMWARE, 'data', 'templates', 'xap', data_templates_xap_subdir)
|
||||
j2 = Environment(loader=FileSystemLoader(templates_dir), autoescape=select_autoescape())
|
||||
return j2
|
||||
|
||||
|
||||
def render_xap_output(data_templates_xap_subdir, file_to_render, defs):
|
||||
j2 = _get_jinja2_env(data_templates_xap_subdir)
|
||||
return j2.get_template(file_to_render).render(xap=defs, xap_str=hjson.dumps(defs))
|
||||
|
||||
|
||||
def _merge_ordered_dicts(dicts):
|
||||
|
|
|
@ -2,64 +2,7 @@
|
|||
"""
|
||||
import hjson
|
||||
from qmk.constants import QMK_FIRMWARE
|
||||
from qmk.xap.common import get_xap_definition_files, update_xap_definitions
|
||||
|
||||
|
||||
def _update_type_docs(overall):
|
||||
defs = overall['type_docs']
|
||||
|
||||
type_docs = []
|
||||
for (k, v) in sorted(defs.items(), key=lambda x: x[0]):
|
||||
type_docs.append(f'| _{k}_ | {v} |')
|
||||
|
||||
desc_str = "\n".join(type_docs)
|
||||
|
||||
overall['documentation']['!type_docs!'] = f'''\
|
||||
| Name | Definition |
|
||||
| -- | -- |
|
||||
{desc_str}
|
||||
'''
|
||||
|
||||
|
||||
def _update_term_definitions(overall):
|
||||
defs = overall['term_definitions']
|
||||
|
||||
term_descriptions = []
|
||||
for (k, v) in sorted(defs.items(), key=lambda x: x[0]):
|
||||
term_descriptions.append(f'| _{k}_ | {v} |')
|
||||
|
||||
desc_str = "\n".join(term_descriptions)
|
||||
|
||||
overall['documentation']['!term_definitions!'] = f'''\
|
||||
| Name | Definition |
|
||||
| -- | -- |
|
||||
{desc_str}
|
||||
'''
|
||||
|
||||
|
||||
def _update_response_flags(overall):
|
||||
flags = overall['response_flags']['bits']
|
||||
for n in range(0, 8):
|
||||
if str(n) not in flags:
|
||||
flags[str(n)] = {"name": "-", "description": "-"}
|
||||
|
||||
header = '| ' + " | ".join([f'Bit {n}' for n in range(7, -1, -1)]) + ' |'
|
||||
dividers = '|' + "|".join(['--' for n in range(7, -1, -1)]) + '|'
|
||||
bit_names = '| ' + " | ".join([flags[str(n)]['name'] for n in range(7, -1, -1)]) + ' |'
|
||||
|
||||
bit_descriptions = ''
|
||||
for n in range(7, -1, -1):
|
||||
bit_desc = flags[str(n)]
|
||||
if bit_desc['name'] != '-':
|
||||
desc = bit_desc['description']
|
||||
bit_descriptions = bit_descriptions + f'\n* `Bit {n}`: {desc}'
|
||||
|
||||
overall['documentation']['!response_flags!'] = f'''\
|
||||
{header}
|
||||
{dividers}
|
||||
{bit_names}
|
||||
{bit_descriptions}
|
||||
'''
|
||||
from qmk.xap.common import get_xap_definition_files, update_xap_definitions, render_xap_output
|
||||
|
||||
|
||||
def generate_docs():
|
||||
|
@ -69,27 +12,18 @@ def generate_docs():
|
|||
|
||||
overall = None
|
||||
for file in get_xap_definition_files():
|
||||
|
||||
overall = update_xap_definitions(overall, hjson.load(file.open(encoding='utf-8')))
|
||||
|
||||
try:
|
||||
if 'type_docs' in overall:
|
||||
_update_type_docs(overall)
|
||||
if 'term_definitions' in overall:
|
||||
_update_term_definitions(overall)
|
||||
if 'response_flags' in overall:
|
||||
_update_response_flags(overall)
|
||||
except:
|
||||
print(hjson.dumps(overall))
|
||||
exit(1)
|
||||
# Inject dummy bits for unspecified response flags
|
||||
for n in range(0, 8):
|
||||
if str(n) not in overall['response_flags']['bits']:
|
||||
overall['response_flags']['bits'][str(n)] = {'name': '', 'description': '', 'define': '-'}
|
||||
|
||||
output_doc = QMK_FIRMWARE / "docs" / f"{file.stem}.md"
|
||||
docs_list.append(output_doc)
|
||||
|
||||
output = render_xap_output('docs', 'docs.md.j2', overall)
|
||||
with open(output_doc, "w", encoding='utf-8') as out_file:
|
||||
for e in overall['documentation']['order']:
|
||||
out_file.write(overall['documentation'][e].strip())
|
||||
out_file.write('\n\n')
|
||||
out_file.write(output)
|
||||
|
||||
output_doc = QMK_FIRMWARE / "docs" / f"xap_protocol.md"
|
||||
with open(output_doc, "w", encoding='utf-8') as out_file:
|
||||
|
|
|
@ -5,6 +5,7 @@ colorama
|
|||
fnvhash
|
||||
hid
|
||||
hjson
|
||||
Jinja2
|
||||
jsonschema>=3
|
||||
milc>=1.4.2
|
||||
pygments
|
||||
|
|
Loading…
Reference in a new issue