From fd63ef40183e4517e84fde4b7eb932f9410db22b Mon Sep 17 00:00:00 2001 From: philipstarkey Date: Fri, 19 Jun 2020 17:08:29 +1000 Subject: [PATCH] Empty sphinx project following our template --- .gitignore | 26 ++- docs/Makefile | 20 ++ docs/make.bat | 35 ++++ docs/source/_static/custom.css | 63 ++++++ docs/source/_templates/components.rst | 47 +++++ docs/source/conf.py | 223 +++++++++++++++++++++ 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_32nx32n.svg | 267 +++++++++++++++++++++++++ docs/source/img/runvewer.ico | Bin 0 -> 103187 bytes docs/source/img/runviewer_32nx32n.svg | 223 +++++++++++++++++++++ docs/source/img/runviewer_64x64.svg | 51 +++++ docs/source/index.rst | 34 ++++ readthedocs.yaml | 27 +++ setup.cfg | 8 +- 16 files changed, 1642 insertions(+), 2 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/_templates/components.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_32nx32n.svg create mode 100644 docs/source/img/runvewer.ico create mode 100644 docs/source/img/runviewer_32nx32n.svg create mode 100644 docs/source/img/runviewer_64x64.svg create mode 100644 docs/source/index.rst create mode 100644 readthedocs.yaml diff --git a/.gitignore b/.gitignore index 6db9e50..85a021d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,10 @@ +# 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] @@ -20,7 +27,6 @@ parts/ sdist/ var/ wheels/ -pip-wheel-metadata/ share/python-wheels/ *.egg-info/ .installed.cfg @@ -50,6 +56,7 @@ coverage.xml *.py,cover .hypothesis/ .pytest_cache/ +cover/ # Translations *.mo @@ -72,6 +79,7 @@ instance/ docs/_build/ # PyBuilder +.pybuilder/ target/ # Jupyter Notebook @@ -82,6 +90,8 @@ 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 @@ -128,6 +138,16 @@ 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/ @@ -135,3 +155,7 @@ dmypy.json conda_build/ conda_packages/ +# Sphinx documentation +docs/html/ +docs/source/_build/ +docs/source/components.rst 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/_templates/components.rst b/docs/source/_templates/components.rst new file mode 100644 index 0000000..f966939 --- /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:: {{img_path}}/{{item.icon}} + :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:: {{img_path}}/{{item.icon}} + :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 new file mode 100644 index 0000000..3538348 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,223 @@ +# 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 +from jinja2 import FileSystemLoader, Environment + +# -- Project information (unique to each project) ------------------------------------- + +project = "runviewer" +copyright = "2020, labscript suite" +author = "labscript suite contributors" + +# The full version, including alpha/beta/rc tags +from runviewer import __version__ as version # noqa: E402 + +release = version + +# HTML icons +img_path = 'img' +html_logo = img_path + "/runviewer_64x64.svg" +html_favicon = img_path + "/runviewer.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', + 'icon': 'labscript_32nx32n.svg', + 'type': 'lib', + }, + 'labscript-devices': { + 'desc': 'Plugin architecture for controlling experiment hardware', + 'icon': 'labscript_32nx32n.svg', + 'type': 'lib', + }, + 'labscript-utils': { + 'desc': 'Shared modules used by the *labscript suite*', + 'icon': 'labscript_32nx32n.svg', + 'type': 'lib', + }, + 'runmanager': { + 'desc': 'Graphical and remote interface to parameterized experiments', + 'icon': 'runmanager_32nx32n.svg', + 'type': 'gui', + }, + 'blacs': { + 'desc': 'Graphical interface to scientific instruments and experiment supervision', + 'icon': 'blacs_32nx32n.svg', + 'type': 'gui', + }, + 'lyse': { + 'desc': 'Online analysis of live experiment data', + 'icon': 'lyse_32nx32n.svg', + 'type': 'gui', + }, + 'runviewer': { + 'desc': 'Visualize hardware-timed experiment instructions', + 'icon': '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} + +# 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 + 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( + template.render( + intersphinx_mapping=intersphinx_mapping, + programs=labscript_suite_programs, + current_project=project, + img_path=img_path + ) + ) 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_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/runvewer.ico b/docs/source/img/runvewer.ico new file mode 100644 index 0000000000000000000000000000000000000000..d0453596b1acd558f3b31bdc7935a552f7a758d0 GIT binary patch literal 103187 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 u4`qkp)E^x-cmordX1+|0^Bo5E1teIMn( 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 literal 0 HcmV?d00001 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/img/runviewer_64x64.svg b/docs/source/img/runviewer_64x64.svg new file mode 100644 index 0000000..e805db6 --- /dev/null +++ b/docs/source/img/runviewer_64x64.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000..37be3ba --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,34 @@ +.. runviewer 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. + +runviewer +========= + +.. toctree:: + :maxdepth: 2 + :hidden: + :caption: DOCUMENTATION + + + +.. toctree:: + :maxdepth: 2 + :hidden: + :caption: FURTHER DOCUMENTATION + + components + +.. toctree:: + :maxdepth: 2 + :hidden: + :caption: LINKS + + Home Page + Source Code + PyPI + Anaconda Cloud + BitBucket Archive + +.. todolist:: 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 f9d9e88..49d5367 100644 --- a/setup.cfg +++ b/setup.cfg @@ -28,7 +28,7 @@ install_requires = desktop-app>=0.1.2 importlib_metadata labscript_devices - labscript_utils>=2.15 + labscript_utils>=3.0.0rc1 labscript-c-extensions pyqtgraph>=0.11.0rc0 qtutils>=2.0.0 @@ -45,3 +45,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