diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 9bea19a5..29d3bdef 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -5,6 +5,13 @@ always_run: true pass_filenames: false +- id: colab-toc-visible + name: Show the TOC sidebar in Google Colab by default + entry: colab-toc-visible + language: python + types: + - jupyter + - id: fix-nbformat-version name: Set nbformat minor version to 4 and remove cell IDs entry: fix-nbformat-version diff --git a/setup.cfg b/setup.cfg index 3ef9f697..39be1cf1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -74,6 +74,7 @@ dev = [options.entry_points] console_scripts = check-dev-files = repoma.check_dev_files:main + colab-toc-visible = repoma.colab_toc_visible:main fix-nbformat-version = repoma.fix_nbformat_version:main format-setup-cfg = repoma.format_setup_cfg:main pin-nb-requirements = repoma.pin_nb_requirements:main diff --git a/src/repoma/colab_toc_visible.py b/src/repoma/colab_toc_visible.py new file mode 100644 index 00000000..3c35dd3b --- /dev/null +++ b/src/repoma/colab_toc_visible.py @@ -0,0 +1,54 @@ +"""Add notebook metadata to open the TOC sidebar on Google Colab. + +See `ComPWA/repo-maintenance#40 `_ +for more information. +""" + +import argparse +import sys +from typing import Optional, Sequence + +import nbformat +from nbformat import NotebookNode + +from .errors import PrecommitError +from .utilities.executor import Executor + + +def main(argv: Optional[Sequence[str]] = None) -> int: + parser = argparse.ArgumentParser(__doc__) + parser.add_argument( + "filenames", + nargs="*", + help="Paths to the notebooks of which the metadata should be updated.", + ) + args = parser.parse_args(argv) + executor = Executor() + for filename in args.filenames: + executor(_update_metadata, filename) + return executor.finalize(exception=False) + + +def _update_metadata(path: str) -> None: + notebook = open_notebook(path) + metadata = notebook["metadata"] + updated = False + if metadata.get("colab") is None: + updated = True + metadata["colab"] = {} + if not metadata["colab"].get("toc_visible"): + updated = True + metadata["colab"]["toc_visible"] = True + if not updated: + return + nbformat.write(notebook, path) + msg = f"Colab TOC is now visible for notebook {path}" + raise PrecommitError(msg) + + +def open_notebook(path: str) -> NotebookNode: + return nbformat.read(path, as_version=nbformat.NO_CONVERT) + + +if __name__ == "__main__": + sys.exit(main())