Start of public OpenTitan development history
Code contributors:
Alex Bradbury <asb@lowrisc.org>
Cindy Chen <chencindy@google.com>
Eunchan Kim <eunchan@google.com>
Gaurang Chitroda <gaurangg@google.com>
Mark Hayter <mark.hayter@gmail.com>
Michael Schaffner <msf@google.com>
Miguel Osorio <miguelosorio@google.com>
Nils Graf <nilsg@google.com>
Philipp Wagner <phw@lowrisc.org>
Pirmin Vogel <vogelpi@lowrisc.org>
Ram Babu Penugonda <rampenugonda@google.com>
Scott Johnson <scottdj@google.com>
Shail Kushwah <kushwahs@google.com>
Srikrishna Iyer <sriyer@google.com>
Steve Nelson <Steve.Nelson@wdc.com>
Tao Liu <taliu@google.com>
Timothy Chen <timothytim@google.com>
Tobias Wölfel <tobias.woelfel@mailbox.org>
Weicai Yang <weicai@google.com>
diff --git a/util/build_docs.py b/util/build_docs.py
new file mode 100755
index 0000000..b1fe566
--- /dev/null
+++ b/util/build_docs.py
@@ -0,0 +1,165 @@
+#!/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
+#
+# pip3 install --user livereload
+# Usage:
+# run './build_docs.py' to generate the documentation and keep it updated
+# open 'http://localhost:5500/' to check live update (this opens the top
+# level index page). you can also directly access a specific document by
+# accessing 'http://localhost:5500/path/to/doc.html',
+# e.g. http://localhost:5500/hw/ip/uart/doc/uart.html
+
+import argparse
+import logging
+import os
+import shutil
+from pathlib import Path
+
+import livereload
+
+import docgen.generate
+
+USAGE = """
+ build_docs [options]
+"""
+
+MARKDOWN_EXTENSIONS = [
+ '.md',
+ '.mkd',
+]
+STATIC_ASSET_EXTENSIONS = [
+ '.svg',
+ '.png',
+ '.jpg',
+ '.css',
+]
+HJSON_EXTENSIONS = ['.hjson']
+
+# Configurations
+# TODO(eunchan): Move to config.yaml
+SRCTREE_TOP = Path(__file__).parent.joinpath('..').resolve()
+config = {
+ # Toplevel source directory
+ "topdir": SRCTREE_TOP,
+
+ # A list of directories containing documentation within topdir. To ensure
+ # the top-level sitemap doesn't have broken links, this should be kept
+ # in-sync with the doctree tag in sitemap.md.
+ "incdirs": ['./doc', './hw', './sw', './util'],
+
+ # Output directory for documents
+ "outdir": SRCTREE_TOP.joinpath('opentitan-docs'),
+ "verbose": False,
+}
+
+
+def get_doc_files(extensions=MARKDOWN_EXTENSIONS + STATIC_ASSET_EXTENSIONS):
+ """Get the absolute path of files containing documentation
+ """
+ file_list = []
+ # doc files on toplevel
+ for ext in extensions:
+ file_list += config["topdir"].glob('*' + ext)
+ # doc files in include dirs
+ for incdir in config['incdirs']:
+ for ext in extensions:
+ file_list += config["topdir"].joinpath(incdir).rglob('*' + ext)
+ return file_list
+
+
+def ensure_dest_dir(dest_pathname):
+ os.makedirs(dest_pathname.parent, exist_ok=True)
+
+
+def path_src_to_dest(src_pathname, dest_filename_suffix=None):
+ """Get the destination pathname from a source pathname
+ """
+ src_relpath = Path(src_pathname).relative_to(config["topdir"])
+ dest_pathname = Path(config["outdir"]).joinpath(src_relpath)
+ if dest_filename_suffix:
+ dest_pathname = dest_pathname.with_suffix(dest_filename_suffix)
+ return dest_pathname
+
+
+def process_file_markdown(src_pathname):
+ """Process a markdown file and copy it to the destination
+ """
+ dest_pathname = path_src_to_dest(src_pathname, '.html')
+
+ logging.info("Processing Markdown file: %s -> %s" %
+ (str(src_pathname), str(dest_pathname)))
+
+ ensure_dest_dir(dest_pathname)
+
+ with open(dest_pathname, 'w', encoding='UTF-8') as f:
+ outstr = docgen.generate.generate_doc(str(src_pathname),
+ verbose=config['verbose'],
+ inlinecss=True,
+ inlinewave=True,
+ asdiv=False)
+ f.write(outstr)
+
+ return dest_pathname
+
+
+def process_file_copytodest(src_pathname):
+ """Copy a file to the destination directory with no further processing
+ """
+ dest_pathname = path_src_to_dest(src_pathname)
+
+ logging.info("Copying %s -> %s" % (str(src_pathname), str(dest_pathname)))
+
+ ensure_dest_dir(dest_pathname)
+ shutil.copy(src_pathname, dest_pathname)
+
+
+def process_all_files():
+ """Process all files
+
+ The specific processing action depends on the file type.
+ """
+ src_files = get_doc_files()
+
+ for src_pathname in src_files:
+ if src_pathname.suffix in MARKDOWN_EXTENSIONS:
+ process_file_markdown(src_pathname)
+ elif src_pathname.suffix in STATIC_ASSET_EXTENSIONS:
+ process_file_copytodest(src_pathname)
+
+
+def main():
+ logging.basicConfig(level=logging.INFO,
+ format="%(asctime)s - %(message)s",
+ datefmt="%Y-%m-%d %H:%M")
+
+ parser = argparse.ArgumentParser(
+ prog="build_docs",
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ usage=USAGE)
+ parser.add_argument(
+ '--preview',
+ action='store_true',
+ help="""starts a local server with live reload (updates triggered upon
+ changes in the documentation files). this feature is intended
+ to preview the documentation locally.""")
+
+ args = parser.parse_args()
+
+ # Initial processing of all files
+ process_all_files()
+
+ if args.preview:
+ # Setup livereload watcher
+ server = livereload.Server()
+ exts_to_watch = MARKDOWN_EXTENSIONS + \
+ STATIC_ASSET_EXTENSIONS + \
+ HJSON_EXTENSIONS
+ for src_pathname in get_doc_files(exts_to_watch):
+ server.watch(str(src_pathname), process_all_files)
+ server.serve(root=config['topdir'].joinpath(config['outdir']))
+
+
+if __name__ == "__main__":
+ main()