Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revamp documentation #552

Merged
merged 29 commits into from
Jun 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
4fee76a
Use pydata sphinx scheme
padix-key Dec 24, 2023
401bcc6
Correct outdated information
padix-key Dec 25, 2023
0dae188
Refactor list of extension packages
padix-key Apr 12, 2024
1c3cfe7
Refactor homepage
padix-key Apr 14, 2024
bf4dfe0
Use Biotite themed colors
padix-key Apr 14, 2024
1412df5
Fix wrong date
padix-key Apr 14, 2024
c2cdcb6
Use jupyter-sphinx for building tutorial
padix-key Apr 19, 2024
c45b3b9
Add copy button to code blocks
padix-key Apr 19, 2024
0675dd8
Remove old tutorial source
padix-key Apr 19, 2024
5e78100
Update .gitignore for MacOS related files
padix-key Apr 19, 2024
5454e83
Restructure example gallery
padix-key Apr 19, 2024
4d7eade
Restructure API reference
padix-key Apr 19, 2024
61f27cc
Remove obsolete method
padix-key Apr 20, 2024
d5b9e69
Add 404 page
padix-key Apr 20, 2024
fbef899
Add version switcher
padix-key Apr 21, 2024
c07c139
Use SVG for navbar
padix-key Apr 21, 2024
9e21b6b
Rework the contributor guide
padix-key Apr 29, 2024
12ac4bd
Simplify installation instructions
padix-key Apr 30, 2024
6f65ff4
Migrate tutorials
padix-key May 4, 2024
faac69c
Fix citation
padix-key May 8, 2024
738ad53
Fix string conversion for arbitrary objects
padix-key May 13, 2024
4183719
Update Sphinx version
padix-key May 15, 2024
80ba7d3
Explain bibliography procedure
padix-key May 17, 2024
f4d86f8
Use method-based titles for examples
padix-key May 28, 2024
8f11ec6
Run molecular visualization always if Ammolite is installed
padix-key May 28, 2024
66aa195
Fix NCBI API key usage
padix-key Jun 10, 2024
e1bf2ae
Do not run tutorial code if gallery generation is disabled
padix-key Jun 10, 2024
7f9aef9
Fix typo
padix-key Jun 10, 2024
8125002
Remove git-related files from distribution
padix-key Jun 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ htmlcov
# Ignore version file created by hatch-vcs
/src/biotite/version.py

# Ignore autogenerated API reference
# Ignore autogenerated documentation files
/doc/static/switcher.json
/doc/apidoc

# Ignore autogenerated example gallery
/doc/examples/gallery
/doc/examples/backreferences
/doc/sg_execution_times.rst
Expand Down Expand Up @@ -58,8 +57,9 @@ biotite.egg-info
*.code-workspace
.vscode/*

# Ignore fuse_hidden files on Linux systems
# Ignore hidden OS related files
*.fuse_hidden*
.DS_Store

# Ignore temp files created via Jupyter
**/.ipynb_checkpoints/
29 changes: 29 additions & 0 deletions doc/404.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
:orphan:
:html_theme.sidebar_secondary.remove:

.. raw:: html

<style>
.bd-main .bd-content .bd-article-container {
text-align: center;
}
</style>

.. image:: /static/assets/general/biotite_icon_404.svg
:class: no-scaled-link
:width: 25%
:align: center

|
|

404 - Page not found
====================

This page does not exist (anymore).

.. button-link:: https://www.biotite-python.org
:color: primary
:shadow:

Back to homepage
181 changes: 102 additions & 79 deletions doc/apidoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
import types
import json
import enum
from textwrap import dedent
from collections import OrderedDict


_indent = " " * 3
_INDENT = " " * 4


# The categories for functions and classes on the module pages
Expand All @@ -39,9 +40,11 @@ def create_api_doc(src_path, doc_path):
# Create directory to store apidoc
if not isdir(doc_path):
makedirs(doc_path)
package_list = _create_package_doc("biotite",
join(src_path, "biotite"),
doc_path)
package_list = _create_package_doc(
"biotite",
join(src_path, "biotite"),
doc_path
)
_create_package_index(doc_path, package_list)


Expand All @@ -53,13 +56,13 @@ def _create_package_doc(pck, src_path, doc_path):
# Identify all subdirectories...
content = listdir(src_path)
dirs = [f for f in content if isdir(join(src_path, f))]
# ... and recursively create also the documentation for them
# ... and recursively create also the documentation for them
sub_pck = []
for directory in dirs:
sub_pck += _create_package_doc(
f"{pck}.{directory}", join(src_path, directory), doc_path
)

# Import package (__init__.py) and find all attribute names
module = import_module(pck)
attr_list = dir(module)
Expand All @@ -75,22 +78,22 @@ def _create_package_doc(pck, src_path, doc_path):
# All functions are callable...
and callable(getattr(module, attr))
# ...but classes are also callable
and attr not in class_list
and attr not in class_list
]
# Create *.rst files
_create_package_page(doc_path, pck, class_list, func_list, sub_pck)
for class_name in class_list:
_create_class_page(doc_path, pck, class_name)
for function_name in func_list:
_create_function_page(doc_path, pck, function_name)

return([pck] + sub_pck)


def _create_package_page(doc_path, package_name,
classes, functions, subpackages):
attributes = classes + functions

# Get categories for this package
try:
categories = _pck_categories[package_name]
Expand All @@ -110,109 +113,106 @@ def _create_package_page(doc_path, package_name,
# If no other categories exist, call the category 'Content'
misc_category_name = "Miscellaneous" if categories else "Content"
categories[misc_category_name] = misc_attributes


# String for categorized class and function enumeration
category_strings = []
for category, attrs in categories.items():
# Create string for each category
string = \
f"""
{category}
{"-"*len(category)}
string = dedent(f"""

{category}
{"-"*len(category)}

.. autosummary::
:nosignatures:
:toctree:
.. autosummary::
:nosignatures:
:toctree:

"""
string += "\n".join([_indent + attr for attr in attrs])
""")
string += "\n".join([_INDENT + attr for attr in attrs])
category_strings.append(string)
# Concatenate strings
attributes_string = "\n".join(category_strings)

# String for subpackage enumeration
subpackages_string = "\n".join(
[_indent + pck for pck in subpackages]
[_INDENT + pck for pck in subpackages]
)


# Assemble page
file_content = \
f"""
{package_name}
{"=" * len(package_name)}
.. currentmodule:: {package_name}
file_content = dedent(f"""

.. automodule:: {package_name}
``{package_name}``
{"=" * (len(package_name) + 4)}
.. currentmodule:: {package_name}

.. currentmodule:: {package_name}
.. automodule:: {package_name}

{attributes_string}
.. currentmodule:: {package_name}

"""
""") + attributes_string
if len(subpackages) > 0:
file_content += \
f"""
Subpackages
-----------
file_content += dedent(f"""

Subpackages
-----------

.. autosummary::
.. autosummary::

{subpackages_string}
"""
""") + subpackages_string
with open(join(doc_path, f"{package_name}.rst"), "w") as f:
f.write(file_content)


def _create_class_page(doc_path, package_name, class_name):
file_content = \
f"""
{package_name}.{class_name}
{"=" * (len(package_name)+len(class_name)+1)}
.. autoclass:: {package_name}.{class_name}
:show-inheritance:
:members:
:undoc-members:
:inherited-members:
.. minigallery:: {package_name}.{class_name}
:add-heading: Gallery
:heading-level: "
"""
file_content = dedent(f"""
:sd_hide_title: true

``{class_name}``
{"=" * (len(class_name) + 4)}
.. autoclass:: {package_name}.{class_name}
:show-inheritance:
:members:
:member-order: bysource
:undoc-members:
:inherited-members:
.. minigallery:: {package_name}.{class_name}
:add-heading: Gallery
:heading-level: "
""")
with open(join(doc_path, f"{package_name}.{class_name}.rst"), "w") as f:
f.write(file_content)


def _create_function_page(doc_path, package_name, function_name):
file_content = \
f"""
{package_name}.{function_name}
{"=" * (len(package_name)+len(function_name)+1)}
.. autofunction:: {package_name}.{function_name}
.. minigallery:: {package_name}.{function_name}
:add-heading: Gallery
:heading-level: "
"""
file_content = dedent(f"""
:sd_hide_title: true

``{function_name}``
{"=" * (len(function_name) + 4)}
.. autofunction:: {package_name}.{function_name}
.. minigallery:: {package_name}.{function_name}
:add-heading: Gallery
:heading-level: "
""")
with open(join(doc_path, f"{package_name}.{function_name}.rst"), "w") as f:
f.write(file_content)


def _create_package_index(doc_path, package_list):
# String for package enumeration
packages_string = "\n".join(
[_indent + pck for pck in package_list]
[_INDENT + pck for pck in sorted(package_list)]
)

file_content = \
f"""
API Reference
=============

.. autosummary::
:toctree:
file_content = dedent(f"""
API Reference
=============

{packages_string}
"""
.. autosummary::
:toctree:

""") + packages_string
with open(join(doc_path, "index.rst"), "w") as f:
f.write(file_content)

Expand All @@ -222,24 +222,47 @@ def _is_package(path):
return "__init__.py" in content



def skip_non_methods(app, what, name, obj, skip, options):
def skip_nonrelevant(app, what, name, obj, skip, options):
"""
Skip all class members, that are not methods, enum values or inner
classes, since other attributes are already documented in the class
docstring.

Furthermore, skip all class members, that are inherited from
non-Biotite base classes.
"""
if skip:
return True
if what == "class":
if not _is_relevant_type(obj):
return True
if obj.__module__ is None:
# Some built-in functions have '__module__' set to None
return True
package_name = obj.__module__.split(".")[0]
if package_name != "biotite":
return True
return False


def _is_relevant_type(obj):
if type(obj).__name__ == "method_descriptor":
# These are some special built-in Python methods
return False
return (
# Functions
if type(obj) in [
type(obj) in [
types.FunctionType, types.BuiltinFunctionType, types.MethodType
]
) | (
# Functions from C-extensions
] or type(obj).__name__ in [
"cython_function_or_method", "method_descriptor",
type(obj).__name__ in [
"cython_function_or_method",
"fused_cython_function"
# Enum Instance or inner class
] or isinstance(obj, enum.Enum) or isinstance(obj, type):
return False
return True
]
) | (
# Enum instance
isinstance(obj, enum.Enum)
) | (
# Inner class
isinstance(obj, type)
)
Loading
Loading