print("hi!")
pax_global_header 0000666 0000000 0000000 00000000064 14560702311 0014511 g ustar 00root root 0000000 0000000 52 comment=60aa219f0a69939337510776b12fb3e54c444454 sphinx-thebe-0.3.1/ 0000775 0000000 0000000 00000000000 14560702311 0014110 5 ustar 00root root 0000000 0000000 sphinx-thebe-0.3.1/.git_archival.txt 0000664 0000000 0000000 00000000175 14560702311 0017366 0 ustar 00root root 0000000 0000000 node: $Format:%H$ node-date: $Format:%cI$ describe-name: $Format:%(describe:tags=true,match=*[0-9]*)$ ref-names: $Format:%D$ sphinx-thebe-0.3.1/.github/ 0000775 0000000 0000000 00000000000 14560702311 0015450 5 ustar 00root root 0000000 0000000 sphinx-thebe-0.3.1/.github/workflows/ 0000775 0000000 0000000 00000000000 14560702311 0017505 5 ustar 00root root 0000000 0000000 sphinx-thebe-0.3.1/.github/workflows/release.yml 0000664 0000000 0000000 00000002742 14560702311 0021655 0 ustar 00root root 0000000 0000000 # This will run every time a tag is created and pushed to the repository. # It calls our tests workflow via a `workflow_call`, and if tests pass # then it triggers our upload to PyPI for a new release. name: Make a new release on: push: tags: - "v[0-9]+.[0-9]+.[0-9]+" - "v[0-9]+.[0-9]+.[0-9]+-rc[0-9]+" jobs: tests: uses: ./.github/workflows/tests.yml dist: name: publish needs: [tests] # require tests to pass before deploy runs runs-on: ubuntu-latest steps: - name: Checkout source uses: actions/checkout@v3 - name: Set up Python 3.11 uses: actions/setup-python@v4 with: python-version: 3.11 - name: Build package run: pipx run build - uses: actions/upload-artifact@v3 with: path: dist/* upload_pypi: name: publish needs: [dist] runs-on: ubuntu-latest steps: - uses: actions/download-artifact@v3 with: name: artifact path: dist - name: Publish uses: pypa/gh-action-pypi-publish@v1.6.4 with: user: __token__ password: ${{ secrets.PYPI_KEY }} release: needs: [ upload_pypi ] name: Create release runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: softprops/action-gh-release@v1 with: name: Sphinx thebe ${{ github.ref_name }} prerelease: ${{ contains(github.ref, 'rc') }} generate_release_notes: true sphinx-thebe-0.3.1/.github/workflows/tests.yml 0000664 0000000 0000000 00000001445 14560702311 0021376 0 ustar 00root root 0000000 0000000 name: continuous-integration on: push: branches: [main] tags: - 'v*' pull_request: workflow_call: jobs: docs: runs-on: ubuntu-latest strategy: fail-fast: false matrix: python-version: ["3.8", "3.9", "3.10", "3.11"] # Latest and 2 major releases earlier sphinx: [ "~=5.0", "~=7.0" ] steps: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} cache: pip - name: Install sphinx-thebe with sphinx ${{ matrix.sphinx }} run: | pip install --upgrade pip pip install --upgrade "Sphinx${{ matrix.sphinx }}" -e .[testing] - name: Run tests run: | pytest sphinx-thebe-0.3.1/.gitignore 0000664 0000000 0000000 00000003465 14560702311 0016110 0 ustar 00root root 0000000 0000000 # 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/ pip-wheel-metadata/ 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/ # 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 target/ # Jupyter Notebook .ipynb_checkpoints # IPython profile_default/ ipython_config.py # pyenv .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/ ### Project specific docs/_build _version.py sphinx-thebe-0.3.1/CHANGELOG.md 0000664 0000000 0000000 00000004274 14560702311 0015730 0 ustar 00root root 0000000 0000000 # Changelog ## v0.2.1 - 2023-01-27 - FIX: Add name to the kernelOptions [#60](https://github.com/executablebooks/sphinx-thebe/pull/60) (@joergbrech) ## v0.2.0 - 2023-01-05 Minor improvements to support up to Sphinx 6. See https://github.com/executablebooks/sphinx-thebe/pull/57 for more details. ## v0.1.2 - 2022-04-29 This is a minor patch release to fix a JSON metadata bug with myst-nb notebooks. ## v0.1.1 - 2022-02-06 A minor feature addition release to add default CSS selectors for MyST-NB cells. ([full changelog](https://github.com/executablebooks/sphinx-thebe/compare/v0.1.0...ff1fd4b40615c32e6c9d0a60b98434cc1fe2f084)) - ENH: Add defaults for MyST-NB [#48](https://github.com/executablebooks/sphinx-thebe/pull/48) ([@choldgraf](https://github.com/choldgraf)) ## v0.1.0 - 2022-02-05 ([full changelog](https://github.com/executablebooks/sphinx-thebe/compare/v0.0.10...4d1a60c5126ce633b1a36de43b4990b2f4d08730)) **Lazy load thebe javascript** [#41](https://github.com/executablebooks/sphinx-thebe/pull/41) ([@choldgraf](https://github.com/choldgraf)) `thebe` will now "lazily load" its javascript only when a bootstrap button is pressed, rather than loading the Javascript on each page. This saves on bandwidth and pageload speed, since Thebe is generally _not_ used on a page even if it _could_ be used. ## v0.0.10 - 2021-08-24 ([full changelog](https://github.com/executablebooks/sphinx-thebe/compare/v0.0.9...e18d1bf94a8fa79476f035a349bd63d03bba83e7)) This is a minor release to conditionally load the JS on pages that have a "launch button". This will save some load time on non-interactive pages. ### Enhancements made - Option to conditionally load on pages, see [documentation for details](https://sphinx-thebe.readthedocs.io/en/latest/configure.html#only-load-js-on-certain-pages) [#30](https://github.com/executablebooks/sphinx-thebe/pull/30) ([@choldgraf](https://github.com/choldgraf)) ### Other merged PRs - PIN: thebe v0.5.1 [#31](https://github.com/executablebooks/sphinx-thebe/pull/31) ([@choldgraf](https://github.com/choldgraf)) ## v0.0.9 - 2021-08-21 ### Updates - `sphinx-thebe` now uses the correct and latest version of thebe, since it has been renamed from `thebelab` to `thebe`. sphinx-thebe-0.3.1/LICENSE 0000664 0000000 0000000 00000002057 14560702311 0015121 0 ustar 00root root 0000000 0000000 MIT License Copyright (c) 2018 Chris Holdgraf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. sphinx-thebe-0.3.1/README.md 0000664 0000000 0000000 00000001377 14560702311 0015377 0 ustar 00root root 0000000 0000000 # sphinx-thebe [](https://sphinx-thebe.readthedocs.io/en/latest/?badge=latest) [](https://pypi.org/project/sphinx-thebe) Integrate interactive code blocks into your documentation with Thebe and Binder. See [the sphinx-thebe documentation](https://sphinx-thebe.readthedocs.io/en/latest/) for more details! ## Install To install `sphinx-thebe` first clonse and install it: ``` pip install sphinx-thebe ``` Then, add it to your Sphinx site's `conf.py` file: ``` extensions = [ ... "sphinx_thebe" ... ] ``` See [the sphinx-thebe documentation](https://sphinx-thebe.readthedocs.io/en/latest/) for more details! sphinx-thebe-0.3.1/RELEASES.md 0000664 0000000 0000000 00000003056 14560702311 0015641 0 ustar 00root root 0000000 0000000 # Instructions for creating a new release Spinx-Copybutton is [hosted on the pypi repository](https://pypi.org/project/sphinx-thebe/). To create a new release of sphinx-thebe, you need to do these things: ## Before you start 1. Ensure that you have push access to the [sphinx-thebe pypi repository](https://pypi.org/project/sphinx-thebe/) 2. Install [the twine package](https://twine.readthedocs.io/en/latest/). This is a package that helps you bundle and push new Python package distributions to pip. ## To create the release To create a new release, [open an issue](https://github.com/executablebooks/sphinx-thebe/issues/new) to keep track of the to-do list for the release. Copy/paste the following markdown into the issue and check off the boxes as you complete items: ``` - [ ] Ensure that the [sphinx-thebe version number](https://github.com/executablebooks/sphinx-thebe/blob/master/jupyter_book/__init__.py) is correct, and remove the `dev0` part of the version number. Make a PR with the new number and merge into master. - [ ] Create a new distribution for sphinx-thebe by [following the twine release instructions](https://twine.readthedocs.io/en/latest/#using-twine) - [ ] Confirm that the new version of sphinx-thebe [is posted to pypi](https://pypi.org/project/sphinx-thebe/) - [ ] Bump the [sphinx-thebe version number](https://github.com/executablebooks/sphinx-thebe/blob/master/jupyter_book/__init__.py) to the next minor (or major) release and append `dev0` to the end. - [ ] Celebrate! You've just released a new version of sphinx-thebe! ``` sphinx-thebe-0.3.1/docs/ 0000775 0000000 0000000 00000000000 14560702311 0015040 5 ustar 00root root 0000000 0000000 sphinx-thebe-0.3.1/docs/Makefile 0000664 0000000 0000000 00000001145 14560702311 0016501 0 ustar 00root root 0000000 0000000 # Minimal makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build SPHINXPROJ = SphinxCopybutton SOURCEDIR = . 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) sphinx-thebe-0.3.1/docs/changelog.md 0000664 0000000 0000000 00000000040 14560702311 0017303 0 ustar 00root root 0000000 0000000 ```{include} ../CHANGELOG.md ``` sphinx-thebe-0.3.1/docs/conf.py 0000664 0000000 0000000 00000011337 14560702311 0016344 0 ustar 00root root 0000000 0000000 # -- Project information ----------------------------------------------------- project = "Sphinx Thebe" copyright = "2020, Executable Book Project" author = "Executable Book Project" # The short X.Y version version = "" # The full version, including alpha/beta/rc tags release = "" # -- General configuration --------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. # # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = ["myst_nb", "sphinx_copybutton", "sphinx_design", "sphinx_thebe"] thebe_config = { "repository_url": "https://github.com/binder-examples/jupyter-stacks-datascience", "path_to_docs": "docs", # "repository_branch": "master", # "selector": ".thebe", # "selector_input": "", # "selector_output": "", # "codemirror-theme": "blackboard", # Doesn't currently work # "always_load": True, # To load thebe on every page } myst_enable_extensions = ["colon_fence"] # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] source_suffix = ".rst" # The master toctree document. master_doc = "index" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. # language = None # Not recommended sphinx >=5. https://github.com/sphinx-doc/sphinx/issues/10474 # 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 = ["_build", "Thumbs.db", ".DS_Store"] # The name of the Pygments (syntax highlighting) style to use. pygments_style = "sphinx" # -- 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_book_theme" html_title = "sphinx-thebe" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # html_theme_options = { "repository_url": "https://github.com/executablebooks/sphinx-thebe", "path_to_docs": "docs", "use_repository_button": True, "use_issues_button": True, "launch_buttons": {"thebelab": True}, "navigation_with_keys": False, # To prevent an unnecessary warning } # CopyButton configuration copybutton_prompt_text = ">>> " # Switches for testing but shouldn't be activated in the live docs # copybutton_only_copy_prompt_lines = False # copybutton_remove_prompts = False # copybutton_image_path = "test/TEST_COPYBUTTON.png" # copybutton_selector = "div" # -- Options for HTMLHelp output --------------------------------------------- # Output file base name for HTML help builder. htmlhelp_basename = "SphinxCopybuttondoc" # -- Options for LaTeX output ------------------------------------------------ latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). # # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. # # 'preamble': '', # Latex figure (float) alignment # # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ ( master_doc, "SphinxCopybutton.tex", "Sphinx Copybutton Documentation", "Chris Holdgraf", "manual", ), ] # -- Options for manual page output ------------------------------------------ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ (master_doc, "sphinxcopybutton", "Sphinx Copybutton Documentation", [author], 1) ] # -- Options for Texinfo output ---------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ( master_doc, "SphinxCopybutton", "Sphinx Copybutton Documentation", author, "SphinxCopybutton", "One line description of project.", "Miscellaneous", ), ] sphinx-thebe-0.3.1/docs/configure.md 0000664 0000000 0000000 00000014172 14560702311 0017350 0 ustar 00root root 0000000 0000000 --- thebe-kernel: ir --- # Configuration (configure:selector)= ## Change the HTML selector to mark interactive cells By default, `sphinx-thebe` will be run on any cells with the `thebe` class. However, you can customize the HTML selector to use other classes, elements, etc. For example, if you wanted to convert **all code cells**, you could use the following selector: ```python thebe_config = { "selector": "div.highlight" } ``` ```{note} `sphinx-thebe` will subsequently look for any `pre` blocks inside of elements it finds with the `selector` configuration value. These are the blocks that will be converted to interactive with `thebe`. ``` ## Including outputs with your code If you'd like to include outputs in the *static* version of your page, and only overwrite them once the user has run that Thebe cell, you can configure `sphinx-thebe` to detect and keep the outputs associated with some code. To do so, use the `selector_output` configuration. This is a selector that is searched for *within* any items discovered by `selector`. If an output is found, it will be placed just after the code and Thebe will detect it. For example, the following code: ``````{tab-set} `````{tab-item} Myst Markdown ````{container} thebe ```{code-block} r print("hi") ``` ```{container} output "hi" ``` ```` ````` `````{tab-item} reStructuredText ```{code-block} rst .. container:: thebe .. code-block:: r print("hi") .. container:: output "hi" ``` ````` `````` Defines a *parent container* in which we'll put both code and the output of the code. We'll use a `code-block` for the code, and another `container` node with our `output` class for the output. `sphinx-gallery` will detect the parent container because it has a `thebe` class. It will detect the `pre` block inside the container as the code, and it will detect the `
element underneath them. You can add code blocks like so: ```` ```{code-block} python :class: thebe print("hello world!") ``` ```` By default, `sphinx-thebe` will look for any HTML `` element *inside* the code block. Thebe will run on that element. ### Add an activate button to your page Next, insert an "activate" button in your documentation with the following directive: ```` ```{thebe-button} ``` ```` ### An example Here is what it looks like when you add the two snippets above in one example: First the code block: ```{code-block} python :class: thebe print("hello world!") ``` And now the Thebe button: ```{thebe-button} ``` Clicking this button will activate Thebe on the page. If you'd like to manually add your own button (e.g. with your own extension or theme), see [](add-custom-button). ### Customize your environment By default, `sphinx-thebe` will serve the Binder environment for the [jupyter-stacks-datascience repository](https://github.com/binder-examples/jupyter-stacks-datascience). See [](configure.md) for information on choosing your own environment. ## A few examples For example, click the button below (if you have not already clicked the button at the top of the page) and see the sections underneath to watch `sphinx-thebe` in action: ```{thebe-button} Launch examples below! ``` ### Code outputs ```{code-block} :class: thebe, thebe-init import numpy as np np.random.seed(1337) data = np.random.randn(2, 100) print(data[1, :10]) ``` ### DataFrames ```{code-block} :class: thebe import pandas as pd df = pd.DataFrame(data.T, columns=["a", "b"]) df.head(5) ``` ### PNG outputs ```{code-block} :class: thebe import matplotlib.pyplot as plt plt.scatter(*data, c=data[0], s=200) ``` ## Structure of a `thebe` cell `sphinx-thebe` can work with two basic code cell structures: 1. **A single code cell**. In this case, there is just a single code cell that has content that should be made executable, like so: ```html``` 2. **An input/output cell**. Jupyter tools define code cells as a combination of inputs and outputs. For example: ```htmlprint("hi!")``` In this case, `sphinx-thebe` will treat the `cell_output` in a special fashion, so that it is cleared when you first run its corresponding input code. (use:selectors)= ## Selectors `sphinx-thebe` looks for by default By default `sphinx-thebe` will look for two types of code blocks to turn into interactive cells: - Cells that match a custom class you can add manually. It will match: - Whole cells: match `.thebe` - Cell inputs: match `pre` - Cell outputs: match `.output` - Cells that match [MyST-NB code cells](https://myst-nb.readthedocs.io/). It will match: - Whole cells: match `.cell` - Cell inputs: match `.cell_input` - Cell outputs: match `.cell_output` To customize the selectors that `sphinx-thebe` looks for, see [](configure:selector). ## Interactive outputs Interactive outputs work with `sphinx-thebe` **if their web dependencies are loaded**. Many interactive libraries assume that some javascript packages are pre-loaded in a notebook environment. For example, both Jupyter Lab and Notebook come bundled with `require.js`. To use visualization libraries that depend on this, **you must load these libraries on your own in Sphinx**. To do so, you can add the following to your `conf.py`: ```python def setup(app): app.add_js_file("url-of-package.js") ``` Note that some visualization libraries output *bundles of JavaScript/HTML* that will work out-of-the-box. You should consult the documentation of the library you wish to use in order to figure out how to configure it properly. See [the `thebe` examples](https://thebe.readthedocs.io/en/latest/) for examples of some popular visualization libraries. sphinx-thebe-0.3.1/pyproject.toml 0000664 0000000 0000000 00000003513 14560702311 0017026 0 ustar 00root root 0000000 0000000 [build-system] requires = ["hatchling", "hatch-vcs"] build-backend = "hatchling.build" [project] name = "sphinx-thebe" authors = [ { name = "Executable Books Team", email = "executablebooks@gmail.com" }, ] maintainers = [ # TODO: Add an actual maintainer { name = "Executable Books Team", email = "executablebooks@gmail.com" }, ] description = "Integrate interactive code blocks into your documentation with Thebe and Binder." readme = "README.md" license = "MIT" license-files = { paths = ["LICENSE"] } requires-python = ">=3.8" classifiers = [ "Development Status :: 4 - Beta", "Framework :: Sphinx :: Extension", "Intended Audience :: Developers", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development :: Libraries :: Python Modules", ] dynamic = ["version"] keywords = [ "development", "docutils", "sphinx", ] dependencies = [ "sphinx>=4", ] [project.urls] Homepage = "https://github.com/executablebooks/sphinx-thebe" [project.optional-dependencies] sphinx = [ "myst-nb", "sphinx-book-theme", "sphinx-copybutton", "sphinx-design", ] testing = [ "myst-nb>=1.0.0rc0", "sphinx-copybutton", "sphinx-design", "matplotlib", "pytest", "pytest-regressions", "beautifulsoup4", ] # TODO: Add pre-commits dev = [ "sphinx-thebe[testing]", ] [tool.hatch] version.source = "vcs" build.hooks.vcs.version-file = "src/sphinx_thebe/_version.py" [tool.pytest.ini_options] testpaths = [ "tests", ] sphinx-thebe-0.3.1/readthedocs.yml 0000664 0000000 0000000 00000000251 14560702311 0017116 0 ustar 00root root 0000000 0000000 version: 2 build: os: "ubuntu-22.04" tools: python: "3.12" python: install: - method: pip path: . extra_requirements: - sphinx sphinx-thebe-0.3.1/src/ 0000775 0000000 0000000 00000000000 14560702311 0014677 5 ustar 00root root 0000000 0000000 sphinx-thebe-0.3.1/src/sphinx_thebe/ 0000775 0000000 0000000 00000000000 14560702311 0017357 5 ustar 00root root 0000000 0000000 sphinx-thebe-0.3.1/src/sphinx_thebe/__init__.py 0000664 0000000 0000000 00000017755 14560702311 0021507 0 ustar 00root root 0000000 0000000 """A sphinx extension to enable interactive computations using thebe.""" import json import os from pathlib import Path from textwrap import dedent from docutils.parsers.rst import Directive, directives from docutils import nodes from sphinx.util import logging from ._version import version as __version__ logger = logging.getLogger(__name__) THEBE_VERSION = "0.8.2" def st_static_path(app): static_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "_static")) app.config.html_static_path.append(static_path) def init_thebe_default_config(app, env, docnames): """Create a default config for fields that aren't given by the user.""" thebe_config = app.config.thebe_config defaults = { "always_load": False, "selector": ".thebe,.cell", "selector_input": "pre", "selector_output": ".output, .cell_output", } for key, val in defaults.items(): if key not in thebe_config: thebe_config[key] = val # Standardize types for certain values BOOL_KEYS = ["always_load"] for key in BOOL_KEYS: thebe_config[key] = _bool(thebe_config[key]) def _bool(b): if isinstance(b, bool): return b else: return b in ["true", "True"] def _do_load_thebe(doctree, config_thebe): """Decide whether to load thebe based on the page's context.""" # No doctree means there's no page content at all if not doctree: return False # If we aren't properly configured if not config_thebe: logger.warning( "[sphinx-thebe]: Didn't find `thebe_config` in conf.py, add to use thebe" ) return False return True def init_thebe_core(app, env, docnames): """Add scripts to configure thebe, and optionally add thebe itself. By default, defer loading the `thebe` JS bundle until bootstrap is called in order to speed up page load times. """ config_thebe = app.config["thebe_config"] # Add configuration variables THEBE_JS_URL = f"https://unpkg.com/thebe@{THEBE_VERSION}/lib/index.js" thebe_config_lines = [ f"const THEBE_JS_URL = \"{ THEBE_JS_URL }\"", f"const thebe_selector = \"{ app.config.thebe_config['selector'] }\"", f"const thebe_selector_input = \"{ app.config.thebe_config['selector_input'] }\"", f"const thebe_selector_output = \"{ app.config.thebe_config['selector_output'] }\"" ] app.add_js_file(None, body='; '.join(thebe_config_lines)) app.add_js_file(filename="sphinx-thebe.js", **{"async": "async"}) if config_thebe.get("always_load") is True: # If we've got `always load` on, then load thebe on every page. app.add_js_file(THEBE_JS_URL, **{"async": "async"}) def update_thebe_context(app, doctree, docname): """Add thebe config nodes to this doctree using page-dependent information.""" config_thebe = app.config["thebe_config"] # Skip modifying the doctree if we don't need to load thebe if not _do_load_thebe(doctree, config_thebe): return # Thebe configuration if config_thebe is True: config_thebe = {} if not isinstance(config_thebe, dict): raise ValueError( "thebe configuration must be `True` or a dictionary for configuration." ) codemirror_theme = config_thebe.get("codemirror-theme", "abcdef") # Choose the kernel we'll use meta = app.env.metadata.get(docname, {}) kernel_name = meta.get("thebe-kernel") if kernel_name is None: if meta.get("kernelspec"): if isinstance(meta.get("kernelspec"), str): kernel_name = json.loads(meta["kernelspec"]).get("name") else: kernel_name = meta["kernelspec"].get("name") else: kernel_name = "python3" # Codemirror syntax cm_language = kernel_name if "python" in cm_language: cm_language = "python" elif cm_language == "ir": cm_language = "r" # Create the URL for the kernel request repo_url = config_thebe.get( "repository_url", "https://github.com/binder-examples/jupyter-stacks-datascience", ) branch = config_thebe.get("repository_branch", "master") path_to_docs = config_thebe.get("path_to_docs", ".").strip("/") + "/" org, repo = _split_repo_url(repo_url) # Update the doctree with some nodes for the thebe configuration thebe_html_config = f""" """ # Append to the docutils doctree so it makes it into the build outputs doctree.append(nodes.raw(text=thebe_html_config, format="html")) doctree.append( nodes.raw(text=f"", format="html") ) def _split_repo_url(url): """Split a repository URL into an org / repo combination.""" if "github.com/" in url: end = url.split("github.com/")[-1] org, repo = end.split("/")[:2] else: logger.warning( f"[sphinx-thebe]: Currently Thebe repositories must be on GitHub, got {url}" ) org = repo = None return org, repo class ThebeButtonNode(nodes.Element): """Appended to the doctree by the ThebeButton directive Renders as a button to enable thebe on the page. If no ThebeButton directive is found in the document but thebe is enabled, the node is added at the bottom of the document. """ def __init__(self, rawsource="", *children, text="Run code", **attributes): super().__init__("", text=text) def html(self): text = self["text"] return ( ''.format(text=text) ) class ThebeButton(Directive): """Specify a button to activate thebe on the page Arguments --------- text : str (optional) If provided, the button text to display Content ------- None """ optional_arguments = 1 final_argument_whitespace = True has_content = False def run(self): kwargs = {"text": self.arguments[0]} if self.arguments else {} return [ThebeButtonNode(**kwargs)] # Used to render an element node as HTML def visit_element_html(self, node): self.body.append(node.html()) raise nodes.SkipNode # Used for nodes that do not need to be rendered def skip(self, node): raise nodes.SkipNode def setup(app): logger.verbose("Adding copy buttons to code blocks...") # Add our static path app.connect("builder-inited", st_static_path) # Set default values for the configuration app.connect("env-before-read-docs", init_thebe_default_config) # Load the JS/CSS assets for thebe if needed app.connect("env-before-read-docs", init_thebe_core) # Update the doctree with thebe-specific information if needed app.connect("doctree-resolved", update_thebe_context) # configuration for this tool app.add_config_value("thebe_config", {}, "html") # override=True in case Jupyter Sphinx has already been loaded app.add_directive("thebe-button", ThebeButton, override=True) # Add relevant code to headers app.add_css_file("sphinx-thebe.css") # ThebeButtonNode is the button that activates thebe # and is only rendered for the HTML builder app.add_node( ThebeButtonNode, html=(visit_element_html, None), latex=(skip, None), textinfo=(skip, None), text=(skip, None), man=(skip, None), override=True, ) return { "version": __version__, "parallel_read_safe": True, "parallel_write_safe": True, } sphinx-thebe-0.3.1/src/sphinx_thebe/_static/ 0000775 0000000 0000000 00000000000 14560702311 0021005 5 ustar 00root root 0000000 0000000 sphinx-thebe-0.3.1/src/sphinx_thebe/_static/play-solid.svg 0000664 0000000 0000000 00000000523 14560702311 0023603 0 ustar 00root root 0000000 0000000print("hi!")...outputs here...