diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 31e17f2..0c1c105 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -17,21 +17,22 @@ 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: | + mkdir -p docs/source/media + cp media/* docs/source/media/ + mkdir -p docs/source/tests + cp tests/test_rendering_example*.py docs/source/tests/ + cp LICENSE docs/source/LICENSE.md cd docs sphinx-apidoc -o source/ ../src/ -M --no-toc rm source/*.rst make html touch build/html/.nojekyll - mkdir -p build/html/media - cp ../media/output_example.png build/html/media/ - name: Deploy to GitHub Pages uses: JamesIves/github-pages-deploy-action@v4 diff --git a/.gitignore b/.gitignore index a5843fb..17c7ff0 100644 --- a/.gitignore +++ b/.gitignore @@ -69,7 +69,8 @@ instance/ .scrapy # Sphinx documentation -docs/_build/ +docs/build/ +docs/source/_autogenerated/ # PyBuilder .pybuilder/ @@ -132,6 +133,3 @@ pyModbusTCP_old/ test.py test_*.ipynb settings.json - -# Autogenerated doc file -docs/source/modules.md diff --git a/docs/source/conf.py b/docs/source/conf.py index 14c537d..6187a6f 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' \ No newline at end of file diff --git a/docs/source/generate_class_list.py b/docs/source/generate_class_list.py index c7306dc..65c0548 100644 --- a/docs/source/generate_class_list.py +++ b/docs/source/generate_class_list.py @@ -2,10 +2,11 @@ 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 = [ @@ -15,47 +16,64 @@ def write_classes(f: TextIOWrapper, patterns: list[str], module_name: str, title obj.__doc__ and '(Automatic generated stub)' 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: - f.write('```{eval-rst}\n') - f.write(f'.. autoclass:: {module_name}.{cls}\n') - f.write(' :members:\n') - f.write(' :undoc-members:\n') - f.write(' :show-inheritance:\n') - f.write(' :inherited-members:\n') - if title != 'Base classes': - f.write(' :exclude-members: select\n') - f.write('```\n\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(' :undoc-members:\n') + f2.write(' :show-inheritance:\n') + f2.write(' :inherited-members:\n') + f2.write('```\n\n') def write_functions(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 = [ + functions = [ name for name, obj in inspect.getmembers(module, inspect.isfunction) if (obj.__module__ == module_name and any(fnmatch.fnmatch(name, pat) for pat in patterns if pat not in exclude)) ] - """Write the classes to the file.""" - f.write(f'## {title}\n\n') if description: f.write(f'{description}\n\n') - for func in classes: + write_dochtree(f, title, functions) + + for func in functions: if not func.startswith('_'): - f.write('```{eval-rst}\n') - f.write(f'.. autofunction:: {module_name}.{func}\n') - f.write('```\n\n') + with open(f'docs/source/_autogenerated/{func}.md', 'w') as f2: + f2.write(f'# {module_name}.{func}\n') + f2.write('```{eval-rst}\n') + f2.write(f'.. autofunction:: {module_name}.{func}\n') + f2.write('```\n\n') -with open('docs/source/modules.md', 'w') as f: - f.write('# Pyladoc classes, functions and submodules\n\n') - write_classes(f, ['DocumentWriter'], 'pyladoc', title='DocumentWriter Class') - write_functions(f, ['*'], 'pyladoc', title='Functions') - write_functions(f, ['*'], 'pyladoc.latex', title='Submodule latex') +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 functions\n\n') + write_classes(f, ['DocumentWriter'], 'pyladoc', title='DocumentWriter Class') + write_functions(f, ['*'], 'pyladoc', title='Functions') + write_functions(f, ['*'], 'pyladoc.latex', title='Submodule latex') 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 eddee4c..111bf91 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,6 +24,12 @@ dev = [ "matplotlib>=3.1.1", "pandas>=2.0.0", "Jinja2", ] +doc_build = [ + "sphinx", + "pydata_sphinx_theme", + "sphinx-autodoc-typehints", + "myst-parser" +] [project.urls] Homepage = "https://github.com/Nonannet/pyladoc" diff --git a/src/pyladoc/latex.py b/src/pyladoc/latex.py index 77d6669..e3ff9d8 100644 --- a/src/pyladoc/latex.py +++ b/src/pyladoc/latex.py @@ -18,10 +18,6 @@ else: LatexEngine = Literal['pdflatex', 'lualatex', 'xelatex', 'tectonic'] -def basic_formatter(value: Any) -> str: - return escape_text(str(value)) - - def to_ascii(text: str) -> str: """ Replaces/escapes often used unicode characters in LaTeX code or text @@ -321,6 +317,17 @@ def compile(latex_code: str, output_file: str = '', encoding: str = 'utf-8', eng def inject_latex_command(text: str, command: str) -> str: + """ + Injects a provided LaTeX code under the last line + starting with \\usepackage. + + Args: + text: input LaTeX code + command: code to inject + + Returns: + LaTeX code with injected command + """ lines = text.splitlines() last_package_index = -1