# Copyright 2024-2025 XMOS LIMITED. # This Software is subject to the terms of the XMOS Public Licence: Version 1. """ Generate includes for all the APIs in this repo """ import os import ast import re import yaml from mako.template import Template from pathlib import Path # Load folders #TOOLS_USER_GUIDE_DIR = "01_tool_user_guide" #DESIGN_GUIDE_DIR = "02_design_guide" DSP_COMP_DIR = "03_dsp_components" #RUNTIME_CTRL_DIR = "04_run_time_control_guide" API_REFERENCE_DIR = "05_api_reference" # Define paths ROOT_DIR = Path(__file__).parents[1] PYTHON_ROOT = ROOT_DIR / "python" STAGES_LIST_PATH = Path(__file__).parent / "rst"/ DSP_COMP_DIR / "gen" / "stages.rst" DSP_GEN_DIR = Path(__file__).parent / "rst" / API_REFERENCE_DIR / "stages" / "gen" PY_STAGE_MAKO = ROOT_DIR / "python" / "audio_dsp" / "design" / "templates" / "py_stage_doc.mako" YAML_DIR = ROOT_DIR / "stage_config" API_REF_GEN_DIR = Path(__file__).parent / "rst"/ API_REFERENCE_DIR / "gen" def get_module_from_path(paths): # ex: manipulates path to get a module, ex: a/b/c.py -> a.b.c for path in paths: if not path.name.startswith("_"): path = path.with_suffix("").relative_to(PYTHON_ROOT) yield '.'.join(path.parts) def get_file_info(fname): class_list = [] with open(fname) as fp: node = ast.parse(fp.read()) docstring = ast.get_docstring(node) if docstring == None: assert 0, f"{fname} does not have a docstring" docstring = docstring.replace('\n', ' ') for i in node.body: if isinstance(i, ast.ClassDef): if i.name.startswith("_"): continue class_list.append(i.name) return docstring, class_list def python_doc(src_dir, dst_dir): p_design = sorted(src_dir.glob("*.py")) p_design_modules = list(get_module_from_path(p_design)) gen = Template(""" % for module in modules: ${module} ${"="*len(module)} .. automodule:: ${module} :noindex: :members: %endfor""" ).render(modules=p_design_modules) (dst_dir / f"{src_dir.parts[-2]}.{src_dir.parts[-1]}.inc").write_text(gen) def python_doc_stages(src_dir, dst_dir, list_file): p_design = sorted(src_dir.glob("*.py")) all_classes = [] all_files = [] all_docstrings = [] for file in p_design: if file.name.startswith("_"): continue module = ".".join(file.parts[-3:])[:-3] module_name = (file.parts[-1])[:-3] title = module_name.replace("_", " ") # Sorry title = title.title().replace("Rms", "RMS").replace("Fir", "FIR").replace("Eq", "EQ") docstring, classes = get_file_info(file) all_docstrings.append(docstring) all_classes.append(classes) all_files.append(title) class_data = {} for class_name in classes: safe_name = class_name.replace("RMS", "Rms") snake_name = re.sub(r'(?