diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index d219f84..82b71ab 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -17,15 +17,13 @@ jobs: uses: actions/setup-python@v3 with: python-version: "3.x" - - name: Install dependencies - run: pip install sphinx sphinx_rtd_theme sphinx-autodoc-typehints myst-parser + - name: Install package and dependencies + run: pip install .[doc_build] - name: Generate Class List - run: | - pip install . - python ./docs/source/generate_class_list.py + run: python ./docs/source/generate_class_list.py - name: Build Docs run: | - cp LICENSE docs/source/ + cp LICENSE docs/source/LICENSE.md cd docs sphinx-apidoc -o ./source/ ../src/ -M --no-toc rm ./source/*.rst diff --git a/.gitignore b/.gitignore index 2c5332d..68d7d8d 100644 --- a/.gitignore +++ b/.gitignore @@ -70,6 +70,7 @@ instance/ # Sphinx documentation docs/_build/ +docs/source/_autogenerated/ # Autogenerated documentation docs/source/modules.md diff --git a/docs/source/conf.py b/docs/source/conf.py index 7347e96..a37ba42 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -26,7 +26,8 @@ exclude_patterns = [] # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output # html_theme = 'alabaster' -html_theme = 'sphinx_rtd_theme' +html_theme = 'pydata_sphinx_theme' html_static_path = ['_static'] autodoc_inherit_docstrings = True +autoclass_content = 'both' diff --git a/docs/source/generate_class_list.py b/docs/source/generate_class_list.py index 526f1e4..982255d 100644 --- a/docs/source/generate_class_list.py +++ b/docs/source/generate_class_list.py @@ -2,48 +2,64 @@ import importlib import inspect import fnmatch from io import TextIOWrapper +import os def write_classes(f: TextIOWrapper, patterns: list[str], module_name: str, title: str, description: str = '', exclude: list[str] = []) -> None: - + """Write the classes to the file.""" module = importlib.import_module(module_name) classes = [ name for name, obj in inspect.getmembers(module, inspect.isclass) if (obj.__module__ == module_name and - any(fnmatch.fnmatch(name, pat) for pat in patterns) and - obj.__doc__ and - # '(Automatic generated stub)' not in obj.__doc__ and - '(no I/O function)' not in obj.__doc__) + any(fnmatch.fnmatch(name, pat) for pat in patterns if pat not in exclude) and + (obj.__doc__ and ('(Automatic generated stub)' not in obj.__doc__ or ' digital ' in obj.__doc__)) and + obj.__doc__ and '(no I/O function)' not in obj.__doc__ + ) ] - """Write the classes to the file.""" - f.write(f'## {title}\n\n') if description: f.write(f'{description}\n\n') + write_dochtree(f, title, classes) + for cls in classes: - if cls not in exclude: - f.write('```{eval-rst}\n') - f.write(f'.. autoclass:: {module_name}.{cls}\n') - f.write(' :members:\n') - f.write(' :show-inheritance:\n') - f.write(' :inherited-members: object\n') + with open(f'docs/source/_autogenerated/{cls}.md', 'w') as f2: + f2.write(f'# {module_name}.{cls}\n') + f2.write('```{eval-rst}\n') + f2.write(f'.. autoclass:: {module_name}.{cls}\n') + f2.write(' :members:\n') + f2.write(' :show-inheritance:\n') + f2.write(' :inherited-members:\n') if title not in ['Base classes', 'Bus coupler']: - f.write(' :exclude-members: select, parameters\n') - else: - print('* ', cls) - f.write('```\n\n') + f2.write(' :exclude-members: select, parameters\n') + f2.write('```\n\n') -with open('docs/source/modules.md', 'w') as f: - f.write('# Classes and Modules\n\n') - write_classes(f, ['BK*', 'WAGO_750_352'], 'pyhoff.devices', title='Bus coupler', - description='These classes are bus couplers and are used to connect the IO bus terminals to a Ethernet interface.') - write_classes(f, ['KL*'], 'pyhoff.devices', title='Beckhoff bus terminals') - write_classes(f, ['WAGO*'], 'pyhoff.devices', title='WAGO bus terminals', exclude=['WAGO_750_352']) - write_classes(f, ['*Terminal*'], 'pyhoff.devices', title='Generic bus terminals') - write_classes(f, ['*'], 'pyhoff', title='Base classes', - description='These classes are base classes for devices and are typically not used directly.') - write_classes(f, ['*'], 'pyhoff.modbus', title='Modbus', - description='This modbus implementation is used internally.') +def write_dochtree(f: TextIOWrapper, title: str, items: list[str]): + f.write('```{toctree}\n') + f.write(':maxdepth: 1\n') + f.write(f':caption: {title}:\n') + #f.write(':hidden:\n') + for text in items: + if not text.startswith('_'): + f.write(f"{text}\n") + f.write('```\n\n') + + +if __name__ == "__main__": + # Ensure the output directory exists + os.makedirs('docs/source/_autogenerated', exist_ok=True) + + with open('docs/source/_autogenerated/index.md', 'w') as f: + f.write('# Classes and Modules\n\n') + + write_classes(f, ['BK*', 'WAGO_750_352'], 'pyhoff.devices', title='Bus coupler', + description='These classes are bus couplers and are used to connect the IO bus terminals to a Ethernet interface.') + write_classes(f, ['KL*'], 'pyhoff.devices', title='Beckhoff bus terminals') + write_classes(f, ['WAGO*'], 'pyhoff.devices', title='WAGO bus terminals', exclude=['WAGO_750_352']) + write_classes(f, ['*Terminal*'], 'pyhoff.devices', title='Generic bus terminals') + write_classes(f, ['*'], 'pyhoff', title='Base classes', + description='These classes are base classes for devices and are typically not used directly.') + write_classes(f, ['*'], 'pyhoff.modbus', title='Modbus', + description='This modbus implementation is used internally.') diff --git a/docs/source/index.md b/docs/source/index.md index 7232e27..20d99c4 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -1,9 +1,7 @@ ```{toctree} -:maxdepth: 2 -:caption: Contents: - -readme -modules +:maxdepth: 1 +:hidden: +_autogenerated/index ``` ```{include} ../../README.md diff --git a/docs/source/readme.md b/docs/source/readme.md deleted file mode 100644 index 060259b..0000000 --- a/docs/source/readme.md +++ /dev/null @@ -1,2 +0,0 @@ -```{include} ../../README.md -``` \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 8762c6b..47b5ced 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,6 +29,12 @@ where = ["src"] dev = [ "pytest", "flake8", "mypy" ] +doc_build = [ + "sphinx", + "pydata_sphinx_theme", + "sphinx-autodoc-typehints", + "myst-parser" +] [tool.mypy] files = ["src"]