[doc] Created dashboard pre-processor Signed-off-by: Hugo McNally <hugo.mcnally@gmail.com> Co-authored-by: Harry Callahan <hcallahan@lowrisc.org>
diff --git a/book.toml b/book.toml index ede0c0f..2e102a3 100644 --- a/book.toml +++ b/book.toml
@@ -45,6 +45,9 @@ [preprocessor.otbn] command = "./util/mdbook_otbn.py" +[preprocessor.dashboard] +command = "./util/mdbook_dashboard.py" + [preprocessor.doxygen] command = "./util/mdbook_doxygen.py" out-dir = "docs/"
diff --git a/hw/README.md b/hw/README.md index a5336f2..58a0851 100644 --- a/hw/README.md +++ b/hw/README.md
@@ -26,7 +26,7 @@ ## Comportable IPs -{{< dashboard "comportable" >}} +{{#dashboard comportable }} ## Processor cores @@ -50,7 +50,7 @@ ### Earl Grey-specific comportable IPs -{{< dashboard "top_earlgrey" >}} +{{#dashboard top_earlgrey }} ## Hardware documentation overview
diff --git a/util/mdbook_dashboard.py b/util/mdbook_dashboard.py new file mode 100755 index 0000000..6fa54f4 --- /dev/null +++ b/util/mdbook_dashboard.py
@@ -0,0 +1,119 @@ +#!/usr/bin/env python3 +# Copyright lowRISC contributors. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +import json +import sys +import io +import re +from pathlib import Path + +import dashboard.gen_dashboard_entry as dashboard +from mdbook import utils as md_utils + +# We are looking to match on the following example strings +# {{#dashboard comportable }} +DASHBOARD_PATTERN = re.compile(r'\{\{#dashboard\s+?(.+?)\s*\}\}') +IP_CFG_PATTERN = re.compile(r'.+/data/(?!.+(_testplan|example)).+\.hjson') +REPO_TOP = Path(__file__).resolve().parents[1] + +# FIXME: It would be nice if this isn't hard coded. +DASHBOARDS = { + 'comportable': [ + "hw/ip/aes/data/aes.hjson", + "hw/ip/aon_timer/data/aon_timer.hjson", + "hw/ip/entropy_src/data/entropy_src.hjson", + "hw/ip/csrng/data/csrng.hjson", + "hw/ip/adc_ctrl/data/adc_ctrl.hjson", + "hw/ip/edn/data/edn.hjson", + "hw/ip/flash_ctrl/data/flash_ctrl.hjson", + "hw/ip/gpio/data/gpio.hjson", + "hw/ip/hmac/data/hmac.hjson", + "hw/ip/i2c/data/i2c.hjson", + "hw/ip/keymgr/data/keymgr.hjson", + "hw/ip/kmac/data/kmac.hjson", + "hw/ip/lc_ctrl/data/lc_ctrl.hjson", + "hw/ip/otbn/data/otbn.hjson", + "hw/ip/otp_ctrl/data/otp_ctrl.hjson", + "hw/ip/pattgen/data/pattgen.hjson", + "hw/ip/pwm/data/pwm.hjson", + "hw/ip/rom_ctrl/data/rom_ctrl.hjson", + "hw/ip/rv_dm/data/rv_dm.hjson", + "hw/ip/rv_core_ibex/data/rv_core_ibex.hjson", + "hw/ip/rv_timer/data/rv_timer.hjson", + "hw/ip/spi_host/data/spi_host.hjson", + "hw/ip/spi_device/data/spi_device.hjson", + "hw/ip/sram_ctrl/data/sram_ctrl.hjson", + "hw/ip/sysrst_ctrl/data/sysrst_ctrl.hjson", + "hw/ip/uart/data/uart.hjson", + "hw/ip/usbdev/data/usbdev.hjson", + ], + 'top_earlgrey': [ + "hw/top_earlgrey/ip_autogen/alert_handler/data/alert_handler.hjson", + "hw/top_earlgrey/ip/pinmux/data/autogen/pinmux.hjson", + "hw/top_earlgrey/ip/clkmgr/data/autogen/clkmgr.hjson", + "hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr.hjson", + "hw/top_earlgrey/ip/rstmgr/data/autogen/rstmgr.hjson", + "hw/top_earlgrey/ip/sensor_ctrl/data/sensor_ctrl.hjson", + "hw/top_earlgrey/ip_autogen/rv_plic/data/rv_plic.hjson", + ], +} + +DASHBOARD_TEMPLATE = """ +<table class="hw-project-dashboard"> + <thead> + <tr> + <th>Design Spec</th> + <th>DV Document</th> + <th><a href="/doc/project_governance/development_stages.html#versioning">Spec Version</a></th> + <th colspan="4"> + <a href="/doc/project_governance/development_stages.html#life-stages"> + Development Stage + </a> + </th> + <th>Notes</th> + </tr> + </thead> + <tbody> +{} + </tbody> +</table> +""" + + +def main() -> None: + md_utils.supports_html_only() + + # Generate the dashboards + # gen_dashboards() + + # load both the context and the book from stdin + context, book = json.load(sys.stdin) + + for chapter in md_utils.chapters(book["sections"]): + # Add in the generated dashboard html + chapter['content'] = DASHBOARD_PATTERN.sub( + replace_with_dashboard, + chapter['content']) + + # dump the book into stdout + print(json.dumps(book)) + + +def replace_with_dashboard(m: re.Match) -> str: + name = m.group(1) + + try: + cfg_files = DASHBOARDS[name] + except KeyError: + sys.exit("A dashboard with name {}, {{#dashboard {} }}, doesn't exist".format(name, name)) + + buffer = io.StringIO() + for cfg_file in sorted(cfg_files): + dashboard.gen_dashboard_html(REPO_TOP / cfg_file, buffer) + + return DASHBOARD_TEMPLATE.format(buffer.getvalue()) + + +if __name__ == "__main__": + main()