summaryrefslogtreecommitdiff
path: root/api-docs/cppdocs/build_min_docs.py
diff options
context:
space:
mode:
authorkat <katherine@vector35.com>2022-10-23 05:27:30 -0400
committerPeter LaFosse <peter@vector35.com>2022-11-10 16:19:13 -0500
commit2e74d0a19579c8f5dee38c5b8a7660549746146b (patch)
treedb478b838d1d02bfce2d0cdac19150e1f42fccfe /api-docs/cppdocs/build_min_docs.py
parentef840b45be92f50fc9e708977efd6b2dcc259ba0 (diff)
Several documentation improvements and fixes
- Reduce file count, add minifier script - Group UI and group Core C - Add more items to groups - Add Tranform docs
Diffstat (limited to 'api-docs/cppdocs/build_min_docs.py')
-rw-r--r--api-docs/cppdocs/build_min_docs.py162
1 files changed, 162 insertions, 0 deletions
diff --git a/api-docs/cppdocs/build_min_docs.py b/api-docs/cppdocs/build_min_docs.py
new file mode 100644
index 00000000..455c1376
--- /dev/null
+++ b/api-docs/cppdocs/build_min_docs.py
@@ -0,0 +1,162 @@
+#!/usr/bin/env python3
+
+# =-=--
+# This script builds the documentation with doxygen and runs minification routines.
+# This allows shipping a few thousand fewer files in updates including C++ documentation.
+#
+# Usage:
+# install doxygen 1.9.4 (or this script will not work. running minification on a different version can cause
+# real issues.)
+# python3 build_min_docs.py
+# =-=--
+
+__DOXYGEN_REQUIRED_VERSION__ = "1.9.4"
+
+import os
+import sys
+import json
+from collections import namedtuple
+from typing import List
+import subprocess
+import shutil
+
+
+def system_with_output(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE):
+ proc = subprocess.Popen("" + cmd,
+ stdout=stdout,
+ stderr=stderr,
+ shell=True,
+ universal_newlines=True)
+ std_out, std_err = proc.communicate()
+ return proc.returncode, std_out, std_err
+
+
+deletion_queue = []
+
+
+NavItemEntry = namedtuple("NavItemEntry", ["dName", "htmlLink", "vName"])
+
+
+# Load the singular variable in a file as a list of navitems
+def pop_var(filename):
+ """
+ Load in the file data and entries within a file.
+
+ File is in the format `var varName = <json valid array>`
+ if <json_valid_array>[n][2] is a list, item[n][2] is a subfile, and we want to
+ load the entry and return it.
+
+ :param filename: Filename to load the entries and data from.
+ :return: Tuple containing a list of NavItemEntrys and the data in the file.
+ """
+ fp = open(filename)
+ file_data = fp.read()
+ fp.close()
+ data_string = file_data.split(' =', 1)[1][:-1]
+ data = json.loads(data_string)
+ items = []
+ for entry in data:
+ if not isinstance(entry[2], list):
+ items.append(NavItemEntry(entry[0], entry[1], entry[2]))
+ return items, file_data
+
+
+def load_items_in_file(filename):
+ """
+ Recursively load in the text of file {filename} and all subfiles referenced by it.
+
+ :param filename: Target root filename. e.g. 'modules.js'
+ :return: Combined text of javascript file tree.
+ """
+ items = []
+ sub_items, file_data = pop_var(filename)
+ items.append(file_data)
+ deletion_queue.append(filename)
+ for item in sub_items:
+ if item.vName is not None:
+ items += load_items_in_file("html/" + item.vName + ".js")
+ return items
+
+
+def minifier():
+
+ # Typically, doxygen's navbar will lazy load the data in all of these variables.
+ # While this has miniscule performance benefits, it generates thousands of js files.
+ # Here, we take all js variables that the navbar will ever be able to load, and
+ # add them to the top of the navbar.js file itself.
+
+ navtree_built_data = ""
+ for mod in load_items_in_file("html/modules.js"):
+ navtree_built_data += mod + "\n"
+ for mod in load_items_in_file("html/namespaces.js"):
+ navtree_built_data += mod + "\n"
+ for mod in load_items_in_file("html/annotated.js"):
+ navtree_built_data += mod + "\n"
+
+ # The navtree indices also need to be loaded in since we're modifying how navbar.js::getScript works.
+ # This also saves another ~60 files.
+ for nav_tree_index_file in os.listdir("html"):
+ if 'navtreeindex' in nav_tree_index_file:
+ with open("html/" + nav_tree_index_file, "r") as fp:
+ navtree_built_data += fp.read() + "\n"
+ deletion_queue.append("html/" + nav_tree_index_file)
+
+ while "\n\n" in navtree_built_data:
+ navtree_built_data = navtree_built_data.replace("\n\n", "\n")
+
+ navtree_built_data = navtree_built_data.replace("\n", "")
+
+ fp = open("html/navtree.js", "r")
+ navtree_orig = fp.read()
+ fp.close()
+
+ # getScript(scriptName,func,show) here originally loads the js file and calls func once that is complete
+ # Here, we just want to skip the whole process and immediately call the callback.
+ nav_tree_fixed_get_script = "function getScript(scriptName,func,show) { func(); }"
+
+ navtree_before_get_script = navtree_orig.split("function getScript(scriptName,func,show)")[0]
+ navtree_after_get_script = navtree_orig.split("function getScript(scriptName,func,show)")[1].split('}', 1)[1]
+
+ nav_tree_fixed = navtree_before_get_script + nav_tree_fixed_get_script + navtree_after_get_script
+ navtree = navtree_built_data + "\n" + nav_tree_fixed
+
+ fp = open("html/navtree.js", "w")
+ fp.write(navtree)
+ fp.close()
+
+
+def build_doxygen():
+ if not os.path.exists('./Doxyfile'):
+ print('No Doxyfile found. Are you in the right directory?')
+ sys.exit(1)
+ _, vers, _ = system_with_output("doxygen -V")
+ if __DOXYGEN_REQUIRED_VERSION__ not in vers.strip():
+ print(f'Please use Doxygen {__DOXYGEN_REQUIRED_VERSION__} to build documentation')
+ sys.exit(1)
+
+ if os.path.exists('./html/'):
+ print('Clearing ./html/')
+ try:
+ shutil.rmtree("./html/")
+ except OSError:
+ # doing it twice works (on macOS) ¯\_(ツ)_/¯
+ shutil.rmtree("./html/")
+ print(f'Building doxygen docs...')
+ stat, out, err = system_with_output("doxygen Doxyfile")
+ print(f"Built Doxygen with status code {stat}")
+ print("Output dir is ./html/")
+
+
+def main():
+ build_doxygen()
+ print("Minifying Output")
+ minifier()
+ for file in deletion_queue:
+ file = "./" + file
+ os.remove(file)
+ print(f'Was able to clear {len(deletion_queue)} "redundant" files')
+ print(f'Done. Output is in ./html/')
+
+
+if __name__ == "__main__":
+ main()