From 841840a4ee652008d2df72af01434886541b0214 Mon Sep 17 00:00:00 2001 From: philipstarkey Date: Thu, 18 Jun 2020 17:30:33 +1000 Subject: [PATCH 1/5] Initial commit of sphinx docs --- .gitignore | 167 +++++++++++++- docs/Makefile | 20 ++ docs/make.bat | 35 +++ docs/source/_static/custom.css | 63 +++++ docs/source/api-reference/index.rst | 10 + docs/source/conf.py | 303 +++++++++++++++++++++++++ docs/source/img/blacs_32nx32n.svg | 178 +++++++++++++++ docs/source/img/labscript_32nx32n.svg | 186 +++++++++++++++ docs/source/img/lyse_32nx32n.svg | 256 +++++++++++++++++++++ docs/source/img/runmanager.ico | Bin 0 -> 106126 bytes docs/source/img/runmanager_32nx32n.svg | 267 ++++++++++++++++++++++ docs/source/img/runmanager_64x64.svg | 50 ++++ docs/source/img/runviewer_32nx32n.svg | 223 ++++++++++++++++++ docs/source/index.rst | 25 ++ readthedocs.yaml | 27 +++ setup.cfg | 8 +- 16 files changed, 1811 insertions(+), 7 deletions(-) create mode 100644 docs/Makefile create mode 100644 docs/make.bat create mode 100644 docs/source/_static/custom.css create mode 100644 docs/source/api-reference/index.rst create mode 100644 docs/source/conf.py create mode 100644 docs/source/img/blacs_32nx32n.svg create mode 100644 docs/source/img/labscript_32nx32n.svg create mode 100644 docs/source/img/lyse_32nx32n.svg create mode 100644 docs/source/img/runmanager.ico create mode 100644 docs/source/img/runmanager_32nx32n.svg create mode 100644 docs/source/img/runmanager_64x64.svg create mode 100644 docs/source/img/runviewer_32nx32n.svg create mode 100644 docs/source/index.rst create mode 100644 readthedocs.yaml diff --git a/.gitignore b/.gitignore index 26cc7b7..70c27dc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,161 @@ -*.pyc -dist -*.egg-info -.eggs -conda_build -conda_packages \ No newline at end of file +# This gitignore file consists of 2 parts: +# * The standard Python .gitignore rules from GitHub +# * custom ignore rules for the labscript suite. +# +# These should be kept separate so that the generic rules can be updated with a +# copy/paste without having to worry about whether we are removing custom rules + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# +# Custom labscript suite .gitignore rules start below +# + +# Editors +.vscode/ + +# conda build results +conda_build/ +conda_packages/ + +# Sphinx documentation +docs/html/ +docs/source/_build/ +docs/source/components.rst \ No newline at end of file diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..d0c3cbf --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..9534b01 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/source/_static/custom.css b/docs/source/_static/custom.css new file mode 100644 index 0000000..d766bfa --- /dev/null +++ b/docs/source/_static/custom.css @@ -0,0 +1,63 @@ +/* Add space between collapsible details HTML tags */ +details { + margin-bottom: 1em; +} + +/* Darker pygment highlighing of console input/output */ +.highlight .go { + color: #404040; +} + +/* White captions in sidebar */ +.wy-nav-side p.caption { + color: #f5f5f5; +} + +/* labscript blue, alpha = 83% */ +.wy-side-nav-search { + background: #2946bbd3; +} + +.wy-nav-top { + background: #2946bbd3; +} + +/* labscript green, alpha = 75% */ +.rst-content .note .admonition-title { + background: #00804fbf; +} + +/* labscript green, alpha = 25% */ +.rst-content .note { + background: #00804f3f; +} + +/* labscript red, alpha = 75% */ +.rst-content .warning .admonition-title { + background: #bc294cbf +} + +/* labscript red, alpha = 25% */ +.rst-content .warning { + background: #bc294c3b; +} + +/* Elevation +* +* Style box-shadows using Material Design's idea of elevation. These particular numbers are taken from here: +* +* https://github.com/material-components/material-components-web +* https://material-components-web.appspot.com/elevation.html +*/ + +.rst-content img.screenshot { + border: none; + /* MD Elevation 8 */ + box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.2), + 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12); + margin-bottom: 24px; +} + +img.labscript-suite-icon { + min-width: 32px; +} \ No newline at end of file diff --git a/docs/source/api-reference/index.rst b/docs/source/api-reference/index.rst new file mode 100644 index 0000000..572e097 --- /dev/null +++ b/docs/source/api-reference/index.rst @@ -0,0 +1,10 @@ +============= +API Reference +============= + +.. automodule:: runmanager + :members: + :show-inheritance: + + + diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000..2082ccc --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,303 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +from pathlib import Path +from m2r import MdInclude +from recommonmark.transform import AutoStructify + +# -- Project information (unique to each project) ------------------------------------- + +project = "runmanager" +copyright = "2020, labscript suite" +author = "labscript suite contributors" + +# The full version, including alpha/beta/rc tags +from labscript_utils import __version__ as version # noqa: E402 + +release = version + +# HTML icons +img_path = 'img' +html_logo = img_path + "/runmanager_64x64.svg" +html_favicon = img_path + "/runmanager.ico" + +# -- General configuration (should be identical across all projects) ------------------ + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.autosectionlabel", + "sphinx.ext.intersphinx", + "sphinx.ext.napoleon", + "sphinx.ext.todo", + "sphinx.ext.viewcode", + "sphinx_rtd_theme", + "recommonmark", +] + +autodoc_typehints = 'description' + +# Prefix each autosectionlabel with the name of the document it is in and a colon +autosectionlabel_prefix_document = True + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + +# The suffix(es) of source filenames. +source_suffix = ['.rst', '.md'] + +# The master toctree document. +master_doc = 'index' + +# intersphinx allows us to link directly to other repos sphinxdocs. +# https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html +intersphinx_mapping = { + 'python': ('https://docs.python.org/3/', None), + 'numpy': ('https://numpy.org/doc/stable/', None), + 'scipy': ('https://docs.scipy.org/doc/scipy/reference/', None), + 'pandas': ('https://pandas.pydata.org/pandas-docs/stable/', None), + 'qtutils': ('https://qtutils.readthedocs.io/en/stable/', None), + 'pyqtgraph': ( + 'https://pyqtgraph.readthedocs.io/en/latest/', + None, + ), # change to stable once v0.11 is published + 'matplotlib': ('https://matplotlib.org/', None), + 'h5py': ('http://docs.h5py.org/en/stable/', None), + 'pydaqmx': ('https://pythonhosted.org/PyDAQmx/', None), + 'qt': ( + '', + 'pyqt5-modified-objects.inv', + ) # from https://github.com/MSLNZ/msl-qt/blob/master/docs/create_pyqt_objects.py + # under MIT License + # TODO + # desktop-app + # spinapi/pynivision/etc +} + +# list of all labscript suite components that have docs +labscript_suite_programs = { + 'labscript': { + 'desc': 'Expressive composition of hardware-timed experiments', + 'img': img_path + '/labscript_32nx32n.svg', + 'type': 'lib', + }, + 'labscript-devices': { + 'desc': 'Plugin architecture for controlling experiment hardware', + 'img': img_path + '/labscript_32nx32n.svg', + 'type': 'lib', + }, + 'labscript-utils': { + 'desc': 'Shared modules used by the *labscript suite*', + 'img': img_path + '/labscript_32nx32n.svg', + 'type': 'lib', + }, + 'runmanager': { + 'desc': 'Graphical and remote interface to parameterized experiments', + 'img': img_path + '/runmanager_32nx32n.svg', + 'type': 'gui', + }, + 'blacs': { + 'desc': 'Graphical interface to scientific instruments and experiment supervision', + 'img': img_path + '/blacs_32nx32n.svg', + 'type': 'gui', + }, + 'lyse': { + 'desc': 'Online analysis of live experiment data', + 'img': img_path + '/lyse_32nx32n.svg', + 'type': 'gui', + }, + 'runviewer': { + 'desc': 'Visualize hardware-timed experiment instructions', + 'img': img_path + '/runviewer_32nx32n.svg', + 'type': 'gui', + }, +} + +# whether to use stable or latest version +labscript_suite_doc_version = os.environ.get('READTHEDOCS_VERSION', 'latest') +if labscript_suite_doc_version not in ['stable', 'latest']: + labscript_suite_doc_version = 'stable' + +# add intersphinx references for each component +for ls_prog in labscript_suite_programs: + intersphinx_mapping[ls_prog] = ( + 'https://docs.labscriptsuite.org/projects/{}/en/{}/'.format( + ls_prog, labscript_suite_doc_version + ), + None, + ) + +# add intersphinx reference for the metapackage +if project != "the labscript suite": + intersphinx_mapping['labscript-suite'] = ( + 'https://docs.labscriptsuite.org/en/{}/'.format(labscript_suite_doc_version), + None, + ) + +# Make `some code` equivalent to :code:`some code` +default_role = 'code' + +# hide todo notes if on readthedocs and not building the latest +if os.environ.get('READTHEDOCS') and ( + os.environ.get('READTHEDOCS_VERSION') != 'latest' + or ( + os.environ.get('READTHEDOCS_PROJECT') == project + or os.environ.get('READTHEDOCS_PROJECT') == 'labscriptsuite' + ) +): + todo_include_todos = False +else: + todo_include_todos = True + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "sphinx_rtd_theme" +html_title = "labscript suite | {project}".format( + project=project + if project != "labscript-suite" + else "experiment control and automation" +) +html_short_title = "labscript suite" + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Customize the html_theme +html_theme_options = {'navigation_depth': 3} + +# Template for generating the components.rst file +# fmt:off +components_rst_template = \ +""" +{metapackage_toctree} + +*labscript suite* components +============================ + +The *labscript suite* is modular by design, and is comprised of: + +.. list-table:: Python libraries + :widths: 10 90 + :header-rows: 0 + +{lib} + +.. list-table:: Graphical applications + :widths: 10 90 + :header-rows: 0 + +{gui} + +.. toctree:: + :maxdepth: 2 + :hidden: + +{toctree_entires} + +{rst_defs} +""" + +components_rst_table_template = \ +""" * - .. image:: {img} + :target: {target} + :class: labscript-suite-icon + - |{prog}|_ --- {desc} +""" + +components_rst_link_template = \ +""".. |{prog}| replace:: **{prog}** +.. _{prog}: {target} +""" + +components_rst_metapackage_template = \ +""".. toctree:: + :maxdepth: 2 + :hidden: + + Metapackage documentation <{}> +""" +# fmt:on + +# Use m2r only for mdinclude and recommonmark for everything else +# https://github.com/readthedocs/recommonmark/issues/191#issuecomment-622369992 +def setup(app): + config = { + # 'url_resolver': lambda url: github_doc_root + url, + 'auto_toc_tree_section': 'Contents', + 'enable_eval_rst': True, + } + app.add_config_value('recommonmark_config', config, True) + app.add_transform(AutoStructify) + + # from m2r to make `mdinclude` work + app.add_config_value('no_underscore_emphasis', False, 'env') + app.add_config_value('m2r_parse_relative_links', False, 'env') + app.add_config_value('m2r_anonymous_references', False, 'env') + app.add_config_value('m2r_disable_inline_math', False, 'env') + app.add_directive('mdinclude', MdInclude) + app.add_stylesheet('custom.css') + + # generate the components.rst file dynamically so it points to stable/latest + # of subprojects correctly + components_rst_table = { + "lib": "", + "gui": "", + } + components_rst_link = "" + components_rst_toctree = "" + components_rst_metapackage = "" + if project != 'the labscript suite': + components_rst_metapackage = components_rst_metapackage_template.format( + intersphinx_mapping['labscript-suite'][0] + ) + metapackage_img = img_path + "/labscript-suite-rectangular-transparent_138nx70n.svg" + for ls_prog, data in labscript_suite_programs.items(): + components_rst_table[data['type']] += components_rst_table_template.format( + prog=ls_prog, + labscript_suite_doc_version=labscript_suite_doc_version, + target=intersphinx_mapping[ls_prog][0], + **data + ) + components_rst_link += components_rst_link_template.format( + prog=ls_prog, + labscript_suite_doc_version=labscript_suite_doc_version, + target=intersphinx_mapping[ls_prog][0], + ) + for ls_prog in sorted(labscript_suite_programs): + if ls_prog != project: + components_rst_toctree += " {} <{}>\n".format( + ls_prog, intersphinx_mapping[ls_prog][0] + ) + + components_rst = components_rst_template.format( + toctree_entires=components_rst_toctree, + rst_defs=components_rst_link, + labscript_suite_doc_version=labscript_suite_doc_version, + metapackage_toctree=components_rst_metapackage, + **components_rst_table + ) + + with open(Path(__file__).resolve().parent / 'components.rst', 'w') as f: + f.write(components_rst) diff --git a/docs/source/img/blacs_32nx32n.svg b/docs/source/img/blacs_32nx32n.svg new file mode 100644 index 0000000..d6a2b0e --- /dev/null +++ b/docs/source/img/blacs_32nx32n.svg @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/docs/source/img/labscript_32nx32n.svg b/docs/source/img/labscript_32nx32n.svg new file mode 100644 index 0000000..97272af --- /dev/null +++ b/docs/source/img/labscript_32nx32n.svg @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/docs/source/img/lyse_32nx32n.svg b/docs/source/img/lyse_32nx32n.svg new file mode 100644 index 0000000..1ddcdcc --- /dev/null +++ b/docs/source/img/lyse_32nx32n.svg @@ -0,0 +1,256 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/img/runmanager.ico b/docs/source/img/runmanager.ico new file mode 100644 index 0000000000000000000000000000000000000000..6d89394e6450925812a30f3c8c06c173e5bb2711 GIT binary patch literal 106126 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 z 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 Q^!RkRLCjbBd literal 0 HcmV?d00001 diff --git a/docs/source/img/runmanager_32nx32n.svg b/docs/source/img/runmanager_32nx32n.svg new file mode 100644 index 0000000..d9df689 --- /dev/null +++ b/docs/source/img/runmanager_32nx32n.svg @@ -0,0 +1,267 @@ + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/img/runmanager_64x64.svg b/docs/source/img/runmanager_64x64.svg new file mode 100644 index 0000000..0f06ea8 --- /dev/null +++ b/docs/source/img/runmanager_64x64.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/img/runviewer_32nx32n.svg b/docs/source/img/runviewer_32nx32n.svg new file mode 100644 index 0000000..ee5aa68 --- /dev/null +++ b/docs/source/img/runviewer_32nx32n.svg @@ -0,0 +1,223 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000..4f07601 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,25 @@ +.. runmanager documentation master file, created by + sphinx-quickstart on Thu Jun 18 17:05:42 2020. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +runmanager +========== + +.. toctree:: + :maxdepth: 2 + :hidden: + + api-reference/index + +.. toctree:: + :maxdepth: 2 + :hidden: + :caption: LINKS + + components + Home Page + Source Code + BitBucket Archive + + diff --git a/readthedocs.yaml b/readthedocs.yaml new file mode 100644 index 0000000..35084d6 --- /dev/null +++ b/readthedocs.yaml @@ -0,0 +1,27 @@ +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Build documentation in the docs/ directory with Sphinx +sphinx: + builder: dirhtml + configuration: docs/source/conf.py + fail_on_warning: false + +# Optionally build your docs in additional formats such as PDF +formats: + - pdf + - epub + +# Optionally set the version of Python and requirements required to build your docs +python: + version: 3.7 + install: + - method: pip + path: . + extra_requirements: + - docs + system_packages: true + \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index fe36836..d64d409 100644 --- a/setup.cfg +++ b/setup.cfg @@ -28,7 +28,7 @@ install_requires = desktop-app>=0.1.2 importlib_metadata labscript - labscript_utils>=2.12.5 + labscript_utils>=3.0.0rc1 pandas>=0.13 qtutils>=2.2.2 @@ -40,3 +40,9 @@ gui_scripts = [options.extras_require] pyqt = PyQt5 +docs = + PyQt5 + Sphinx==3.0.1 + sphinx-rtd-theme==0.4.3 + recommonmark==0.6.0 + m2r==0.2.1 \ No newline at end of file From 6466ff077d9303fda649fa3c80a131e15098d199 Mon Sep 17 00:00:00 2001 From: philipstarkey Date: Fri, 19 Jun 2020 11:10:29 +1000 Subject: [PATCH 2/5] Updated docs to use jinja template for component doc links --- docs/source/_templates/components.rst | 47 ++++++++++++ docs/source/conf.py | 103 +++----------------------- docs/source/index.rst | 12 ++- 3 files changed, 67 insertions(+), 95 deletions(-) create mode 100644 docs/source/_templates/components.rst diff --git a/docs/source/_templates/components.rst b/docs/source/_templates/components.rst new file mode 100644 index 0000000..c3e5b16 --- /dev/null +++ b/docs/source/_templates/components.rst @@ -0,0 +1,47 @@ +{% if current_project != 'the labscript suite' %} +.. toctree:: + :maxdepth: 2 + :hidden: + + The labscript suite <{{intersphinx_mapping['labscript-suite'][0]}}> + +{% endif %} +*labscript suite* components +============================ + +The *labscript suite* is modular by design, and is comprised of: + +.. list-table:: Python libraries + :widths: 10 90 + :header-rows: 0 + + {% for prog, item in programs.items() if item.type == 'lib' %} + * - .. image:: {{item.img}} + :target: {{intersphinx_mapping['%s' | format(prog)][0]}} + :class: labscript-suite-icon + - |{{prog}}|_ --- {{item.desc}} + {% endfor %} + +.. list-table:: Graphical applications + :widths: 10 90 + :header-rows: 0 + + {% for prog, item in programs.items() if item.type == 'gui' %} + * - .. image:: {{item.img}} + :target: {{intersphinx_mapping['%s' | format(prog)][0]}} + :class: labscript-suite-icon + - |{{prog}}|_ --- {{item.desc}} + {% endfor %} + +.. toctree:: + :maxdepth: 2 + :hidden: + + {% for prog in programs|sort if prog != current_project %} + {{prog}} <{{intersphinx_mapping['%s' | format(prog)][0]}}> + {% endfor %} + +{% for prog in programs %} +.. |{{prog}}| replace:: **{{prog}}** +.. _{{prog}}: {{intersphinx_mapping['%s' | format(prog)][0]}} +{% endfor %} \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py index 2082ccc..546cbca 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -14,6 +14,7 @@ from pathlib import Path from m2r import MdInclude from recommonmark.transform import AutoStructify +from jinja2 import FileSystemLoader, Environment # -- Project information (unique to each project) ------------------------------------- @@ -187,59 +188,6 @@ # Customize the html_theme html_theme_options = {'navigation_depth': 3} -# Template for generating the components.rst file -# fmt:off -components_rst_template = \ -""" -{metapackage_toctree} - -*labscript suite* components -============================ - -The *labscript suite* is modular by design, and is comprised of: - -.. list-table:: Python libraries - :widths: 10 90 - :header-rows: 0 - -{lib} - -.. list-table:: Graphical applications - :widths: 10 90 - :header-rows: 0 - -{gui} - -.. toctree:: - :maxdepth: 2 - :hidden: - -{toctree_entires} - -{rst_defs} -""" - -components_rst_table_template = \ -""" * - .. image:: {img} - :target: {target} - :class: labscript-suite-icon - - |{prog}|_ --- {desc} -""" - -components_rst_link_template = \ -""".. |{prog}| replace:: **{prog}** -.. _{prog}: {target} -""" - -components_rst_metapackage_template = \ -""".. toctree:: - :maxdepth: 2 - :hidden: - - Metapackage documentation <{}> -""" -# fmt:on - # Use m2r only for mdinclude and recommonmark for everything else # https://github.com/readthedocs/recommonmark/issues/191#issuecomment-622369992 def setup(app): @@ -261,43 +209,14 @@ def setup(app): # generate the components.rst file dynamically so it points to stable/latest # of subprojects correctly - components_rst_table = { - "lib": "", - "gui": "", - } - components_rst_link = "" - components_rst_toctree = "" - components_rst_metapackage = "" - if project != 'the labscript suite': - components_rst_metapackage = components_rst_metapackage_template.format( - intersphinx_mapping['labscript-suite'][0] - ) - metapackage_img = img_path + "/labscript-suite-rectangular-transparent_138nx70n.svg" - for ls_prog, data in labscript_suite_programs.items(): - components_rst_table[data['type']] += components_rst_table_template.format( - prog=ls_prog, - labscript_suite_doc_version=labscript_suite_doc_version, - target=intersphinx_mapping[ls_prog][0], - **data - ) - components_rst_link += components_rst_link_template.format( - prog=ls_prog, - labscript_suite_doc_version=labscript_suite_doc_version, - target=intersphinx_mapping[ls_prog][0], - ) - for ls_prog in sorted(labscript_suite_programs): - if ls_prog != project: - components_rst_toctree += " {} <{}>\n".format( - ls_prog, intersphinx_mapping[ls_prog][0] - ) - - components_rst = components_rst_template.format( - toctree_entires=components_rst_toctree, - rst_defs=components_rst_link, - labscript_suite_doc_version=labscript_suite_doc_version, - metapackage_toctree=components_rst_metapackage, - **components_rst_table - ) - + loader = FileSystemLoader(Path(__file__).resolve().parent / templates_path[0]) + env = Environment(loader=loader) + template = env.get_template('components.rst') with open(Path(__file__).resolve().parent / 'components.rst', 'w') as f: - f.write(components_rst) + f.write( + template.render( + intersphinx_mapping=intersphinx_mapping, + programs=labscript_suite_programs, + current_project=project, + ) + ) diff --git a/docs/source/index.rst b/docs/source/index.rst index 4f07601..3ed4594 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -15,11 +15,17 @@ runmanager .. toctree:: :maxdepth: 2 :hidden: - :caption: LINKS + :caption: FURTHER DOCUMENTATION components + +.. toctree:: + :maxdepth: 2 + :hidden: + :caption: LINKS + Home Page - Source Code - BitBucket Archive + Source Code + BitBucket Archive From 6c763e728096882d8dd85f758d4b27c09c7a1929 Mon Sep 17 00:00:00 2001 From: philipstarkey Date: Fri, 19 Jun 2020 11:18:36 +1000 Subject: [PATCH 3/5] Added missing todolist directive on index page --- docs/source/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/index.rst b/docs/source/index.rst index 3ed4594..41e344e 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -28,4 +28,4 @@ runmanager Source Code BitBucket Archive - +.. todolist:: From 859a44da08d406f36c811b4db939271abdcc8a73 Mon Sep 17 00:00:00 2001 From: philipstarkey Date: Fri, 19 Jun 2020 16:00:13 +1000 Subject: [PATCH 4/5] Addressing latest review comments --- docs/source/_templates/components.rst | 6 +++--- docs/source/conf.py | 15 ++++++++------- docs/source/index.rst | 3 +++ 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/docs/source/_templates/components.rst b/docs/source/_templates/components.rst index c3e5b16..f966939 100644 --- a/docs/source/_templates/components.rst +++ b/docs/source/_templates/components.rst @@ -3,7 +3,7 @@ :maxdepth: 2 :hidden: - The labscript suite <{{intersphinx_mapping['labscript-suite'][0]}}> + the labscript suite <{{intersphinx_mapping['labscript-suite'][0]}}> {% endif %} *labscript suite* components @@ -16,7 +16,7 @@ The *labscript suite* is modular by design, and is comprised of: :header-rows: 0 {% for prog, item in programs.items() if item.type == 'lib' %} - * - .. image:: {{item.img}} + * - .. image:: {{img_path}}/{{item.icon}} :target: {{intersphinx_mapping['%s' | format(prog)][0]}} :class: labscript-suite-icon - |{{prog}}|_ --- {{item.desc}} @@ -27,7 +27,7 @@ The *labscript suite* is modular by design, and is comprised of: :header-rows: 0 {% for prog, item in programs.items() if item.type == 'gui' %} - * - .. image:: {{item.img}} + * - .. image:: {{img_path}}/{{item.icon}} :target: {{intersphinx_mapping['%s' | format(prog)][0]}} :class: labscript-suite-icon - |{{prog}}|_ --- {{item.desc}} diff --git a/docs/source/conf.py b/docs/source/conf.py index 546cbca..bfce467 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -96,37 +96,37 @@ labscript_suite_programs = { 'labscript': { 'desc': 'Expressive composition of hardware-timed experiments', - 'img': img_path + '/labscript_32nx32n.svg', + 'icon': 'labscript_32nx32n.svg', 'type': 'lib', }, 'labscript-devices': { 'desc': 'Plugin architecture for controlling experiment hardware', - 'img': img_path + '/labscript_32nx32n.svg', + 'icon': 'labscript_32nx32n.svg', 'type': 'lib', }, 'labscript-utils': { 'desc': 'Shared modules used by the *labscript suite*', - 'img': img_path + '/labscript_32nx32n.svg', + 'icon': 'labscript_32nx32n.svg', 'type': 'lib', }, 'runmanager': { 'desc': 'Graphical and remote interface to parameterized experiments', - 'img': img_path + '/runmanager_32nx32n.svg', + 'icon': 'runmanager_32nx32n.svg', 'type': 'gui', }, 'blacs': { 'desc': 'Graphical interface to scientific instruments and experiment supervision', - 'img': img_path + '/blacs_32nx32n.svg', + 'icon': 'blacs_32nx32n.svg', 'type': 'gui', }, 'lyse': { 'desc': 'Online analysis of live experiment data', - 'img': img_path + '/lyse_32nx32n.svg', + 'icon': 'lyse_32nx32n.svg', 'type': 'gui', }, 'runviewer': { 'desc': 'Visualize hardware-timed experiment instructions', - 'img': img_path + '/runviewer_32nx32n.svg', + 'icon': 'runviewer_32nx32n.svg', 'type': 'gui', }, } @@ -218,5 +218,6 @@ def setup(app): intersphinx_mapping=intersphinx_mapping, programs=labscript_suite_programs, current_project=project, + img_path=img_path ) ) diff --git a/docs/source/index.rst b/docs/source/index.rst index 41e344e..f5165a1 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -9,6 +9,7 @@ runmanager .. toctree:: :maxdepth: 2 :hidden: + :caption: DOCUMENTATION api-reference/index @@ -26,6 +27,8 @@ runmanager Home Page Source Code + PyPI + Anaconda Cloud BitBucket Archive .. todolist:: From a27a239fd6733d09d526c5933d960cc9255fdd4e Mon Sep 17 00:00:00 2001 From: philipstarkey Date: Fri, 19 Jun 2020 17:07:02 +1000 Subject: [PATCH 5/5] Fixed incorrect component used for version --- docs/source/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index bfce467..12d0968 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -23,7 +23,7 @@ author = "labscript suite contributors" # The full version, including alpha/beta/rc tags -from labscript_utils import __version__ as version # noqa: E402 +from runmanager import __version__ as version # noqa: E402 release = version