diff --git a/conda_dev_env.yaml b/conda_dev_env.yaml
index 5176c78..4812fd9 100644
--- a/conda_dev_env.yaml
+++ b/conda_dev_env.yaml
@@ -47,4 +47,5 @@ dependencies:
- jupyter
- matplotlib
- pandas
+- recommonmark
- sympy <1.3
diff --git a/docs/Makefile b/docs/Makefile
index 7eb2e53..08d5409 100755
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -15,27 +15,24 @@ endif
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS = -n -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
.PHONY: all help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext customdefault
-## Runs with nitty-pick and converting warnings into errors to
+## Runs with nitty-pick and converting warnings into errors to
## make sure the documentation is properly written
customdefault:
$(SPHINXBUILD) -b html -nW $(ALLSPHINXOPTS) $(BUILDDIR)/html
-
-all: html
-
-clean:
- rm -r $(BUILDDIR)
-
-html:
- $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+# same as customdefault, but echo's warnings without raising them as errors
+debug:
+ $(SPHINXBUILD) -b html -n $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
-view:
- xdg-open $(BUILDDIR)/html/index.html
+clean:
+ rm -r $(BUILDDIR)
diff --git a/docs/source/api/ipypublish.schema.rst b/docs/source/api/ipypublish.schema.rst
deleted file mode 100644
index 24e197c..0000000
--- a/docs/source/api/ipypublish.schema.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-ipypublish.schema package
-=========================
-
-Module contents
----------------
-
-.. automodule:: ipypublish.schema
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/docs/source/code_cells.ipynb b/docs/source/code_cells.ipynb
index 547b149..102f6c3 100644
--- a/docs/source/code_cells.ipynb
+++ b/docs/source/code_cells.ipynb
@@ -1,517 +1,523 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- ".. _code_cells:\n",
- "\n",
- "# Writing Code and Formatting Output\n",
- "\n",
- "IPyPublish utilises metadata to mark-up the notebook with information on\n",
- "how output should be represented in the converted notebook,\n",
- "as shown in :numref:`fig:mpl1`."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "ipub": {
- "figure": {
- "caption": "This is a Matplotlib figure, with a caption, a label and a set width",
- "label": "fig:mpl1",
- "width": 0.4
- }
- }
- },
- "outputs": [],
- "source": [
- "%matplotlib inline\n",
- "import matplotlib.pyplot as plt\n",
- "import numpy as np\n",
- "plt.plot(np.sin(np.linspace(0, 6)))\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- ".. seealso::\n",
- "\n",
- " [The PDF representation of this notebook](_static/code_cells.pdf)\n",
- "\n",
- " :ref:`metadata_tags`, for a full description and list of ipypublish metadata\n",
- "\n",
- ".. _jupytext_python:\n",
- "\n",
- "## Converting Notebooks to Pure Python\n",
- "\n",
- "To write code, we can work in the conventional Jupyter Notebook environment,\n",
- "or we can use [jupytext](https://github.com/mwouts/jupytext),\n",
- "to convert between a notebook and the pure python\n",
- "[percent format](https://github.com/mwouts/jupytext#the-percent-format)\n",
- "\n",
- "```console\n",
- "$ jupytext --to py:percent notebook.ipynb\n",
- "$ jupytext --to notebook notebook.py # overwrite notebook.ipynb\n",
- "$ jupytext --to notebook --update notebook.py # update notebook.ipynb\n",
- "```\n",
- "\n",
- "This will produce a standard python file,\n",
- "with commented notebook level metadata commented at the top (in YAML format),\n",
- "and each cell beginning with ``#%%`` (known as the percent format):\n",
- "\n",
- "The percent format can be utilised in IDEs, such as\n",
- "[Spyder](https://docs.spyder-ide.org/editor.html#defining-code-cells),\n",
- "[Atom](https://atom.io/packages/hydrogen),\n",
- "[PyCharm](https://www.jetbrains.com/pycharm/), and\n",
- "[VS Code](https://code.visualstudio.com/docs/python/jupyter-support),\n",
- "to run individual cells:\n",
- "\n",
- "![Running Notebooks in VS Code](_static/vscode_python.png){#fig:vscode_py width=60%}\n",
- "\n",
- ".. important::\n",
- "\n",
- " To preserve ipypublish notebook metadata, you must add:\n",
- " `\"jupytext\": {\"metadata_filter\": {\"notebook\": \"ipub\"}}` to\n",
- " your notebooks metadata before conversion.\n",
- "\n",
- ".. seealso::\n",
- "\n",
- " :ref:`jupytext_rmarkdown`\n",
- "\n",
- " [Using YAML metadata blocks in Pandoc](https://pandoc.org/MANUAL.html#extension-yaml_metadata_block).\n",
- "\n",
- "## NB Setup Helper Functions\n",
- "\n",
- ":py:mod:`ipypublish.scripts.nb_setup` offers a number of useful functions,\n",
- "to setup common packages (matplotlib, pandas, etc) for outputting content\n",
- "in high quality formats."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "init_cell": true,
- "slideshow": {
- "slide_type": "skip"
- }
- },
- "outputs": [],
- "source": [
- "from ipypublish import nb_setup"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- ".. note::\n",
- "\n",
- " `ipypublish.scripts.ipynb_latex_setup` is deprecated in v0.9\n",
- "\n",
- "## Text Output"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "ipub": {
- "text": {
- "format": {
- "backgroundcolor": "\\color{blue!10}"
- }
- }
- }
- },
- "outputs": [],
- "source": [
- "print(\"\"\"\n",
- "This is some printed text,\n",
- "with a nicely formatted output.\n",
- "\"\"\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Images (with PIL)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "init_cell": true,
- "slideshow": {
- "slide_type": "skip"
- }
- },
- "outputs": [],
- "source": [
- "import os\n",
- "from ipypublish.tests import TEST_PIC_PATH\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "ipub": {
- "figure": {
- "caption": "Horizontally aligned images.",
- "label": "fig:example_h",
- "widefigure": false
- }
- }
- },
- "outputs": [],
- "source": [
- "nb_setup.images_hconcat([TEST_PIC_PATH, TEST_PIC_PATH],\n",
- " width=600, gap=10)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "ipub": {
- "figure": {
- "caption": "Vertically aligned images.",
- "label": "fig:example_v",
- "widefigure": false
- },
- "slide": "new"
- }
- },
- "outputs": [],
- "source": [
- "nb_setup.images_vconcat([TEST_PIC_PATH, TEST_PIC_PATH],\n",
- " height=400, gap=10)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "ipub": {
- "figure": {
- "caption": "Images aligned in a grid.",
- "label": "fig:example_grid",
- "widefigure": false
- },
- "slide": "new"
- }
- },
- "outputs": [],
- "source": [
- "nb_setup.images_gridconcat([[_,_] for _ in [TEST_PIC_PATH, TEST_PIC_PATH]],\n",
- " height=300, vgap=10,hgap=20)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Plots (with Matplotlib)\n",
- "\n",
- "A matplotlib figure (+@fig:example_mpl{}), and its code (+@code:example_mpl{})."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "ipub": {
- "code": {
- "asfloat": true,
- "caption": "The plotting code for a matplotlib figure (\\cref{fig:example_mpl}).",
- "label": "code:example_mpl",
- "widefigure": false
- },
- "figure": {
- "caption": "A matplotlib figure",
- "label": "fig:example_mpl",
- "widefigure": false,
- "width": 0.7
- }
- }
- },
- "outputs": [],
- "source": [
- "plt = nb_setup.setup_matplotlib(output=('pdf','svg'))\n",
- "plt.scatter(np.random.rand(10), np.random.rand(10),\n",
- " label='data label')\n",
- "plt.ylabel(r'a y label with latex $\\alpha$')\n",
- "plt.legend();"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- ".. note::\n",
- "\n",
- " If outputting the Matplotlib figures in a PDF format.\n",
- " See [usetex tutorial](https://matplotlib.org/users/usetex.html#usetex-tutorial), \n",
- " and [Stackoverflow question](https://stackoverflow.com/questions/38731201/latex-escaping-in-matplotlib).\n",
- "\n",
- "## Tables (with pandas)\n",
- "\n",
- "A pandas table (+@tbl:example_pd{}), and its code (+@code:example_pd{})."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "ipub": {
- "code": {
- "asfloat": true,
- "caption": "The plotting code for a pandas Dataframe table (\\cref{tbl:example_pd}).",
- "label": "code:example_pd",
- "placement": "H",
- "widefigure": false
- },
- "table": {
- "alternate": "gray!20",
- "caption": "An example of a table created with a pandas dataframe.",
- "label": "tbl:example_pd",
- "placement": "H"
- }
- }
- },
- "outputs": [],
- "source": [
- "pd = nb_setup.setup_pandas(escape_latex=False)\n",
- "df = pd.DataFrame(np.random.rand(3,4),columns=['a','b','c','d'])\n",
- "df.a = ['$\\delta$','x','y']\n",
- "df.b = ['l','m','n']\n",
- "df.set_index(['a','b'])\n",
- "df.round(3)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- ".. note::\n",
- "\n",
- " If using `escape_latex=False`, then PDF conversion will throw an error \n",
- " if there are e.g. `_`'s in your column names. You either need to escape\n",
- " these manually (`\\_`) or use `escape_latex=True`. But note that, \n",
- " `escape_latex=True` will also escape math (e.g. `$\\delta$`) causing it not\n",
- " to render.\n",
- "\n",
- "## Equations (with ipython or sympy)\n",
- "\n",
- "An ipython and sympy equation =[@eqn:example_ipy;@eqn:example_sympy]."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "ipub": {
- "equation": {
- "label": "eqn:example_ipy"
- }
- }
- },
- "outputs": [],
- "source": [
- "from IPython.display import Latex\n",
- "Latex('$$ a = b+c $$')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "ipub": {
- "code": {
- "asfloat": true,
- "caption": "The plotting code for a sympy equation \\eqref{eqn:example_sympy}.",
- "label": "code:example_sym",
- "placement": "H",
- "widefigure": false
- },
- "equation": {
- "environment": "equation",
- "label": "eqn:example_sympy"
- }
- }
- },
- "outputs": [],
- "source": [
- "sym = nb_setup.setup_sympy()\n",
- "f = sym.Function('f')\n",
- "y,n = sym.symbols(r'y \\alpha')\n",
- "f = y(n)-2*y(n-1/sym.pi)-5*y(n-2)\n",
- "sym.rsolve(f,y(n),[1,4])"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Object Output Formats\n",
- "\n",
- "The format of the Jupyter Notebook file allows for the storage\n",
- "of a single output in multiple formats. This is taken advantage of by\n",
- "packages such as matplotlib and pandas, etc to store a figure/table in\n",
- "both latex and html formats, which can then be selected by ipypublish\n",
- "based on the document type required.\n",
- "\n",
- "Sometimes a user may wish to have greater control over the output format\n",
- "and/or which output types are to be stored. It it possible to achieve\n",
- "this *via* the Jupyter `display` function. For example, if we wanted\n",
- "to display a pandas.DataFrame table without the index column, such that\n",
- "it can be output to both a pdf and html document:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from IPython.display import display\n",
- "df = pd.DataFrame(np.random.random((3, 3)))\n",
- "latex = df.to_latex(index=False)\n",
- "html = df.to_html(index=False)\n",
- "display({'text/latex': latex,\n",
- " 'text/html': html}, raw=True)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "If you wish to create your own object with multiple output formats, you\n",
- "should create a class with multiple `_repr_*_()` methods:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "ipub": {
- "equation": false,
- "table": false
- }
- },
- "outputs": [],
- "source": [
- "class MyObject(object):\n",
- " def __init__(self, text):\n",
- " self.text = text\n",
- "\n",
- " def _repr_latex_(self):\n",
- " return \"\\\\textbf{LaTex: \" + self.text + \"}\"\n",
- "\n",
- " def _repr_html_(self):\n",
- " return \"HTML: \" + self.text + \"\"\n",
- "\n",
- "MyObject('hallo')"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- ".. seealso::\n",
- "\n",
- " :ref:`nbformat:notebook_file_format`\n",
- "\n",
- " [IPython Rich Display](http://ipython.readthedocs.io/en/stable/config/integrating.html#rich-display)\n",
- "\n",
- ".. _multiple_outputs:\n",
- "\n",
- "## Multiple Outputs from a Single Code Cell\n",
- "\n",
- "Similarly, with the Jupyter `display` functionality, you can control the output\n",
- "metadata for multiple outputs in a single code cell:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from IPython.display import display\n",
- "from IPython.display import display_latex\n",
- "from IPython.display import display_markdown\n",
- "\n",
- "x = np.linspace(0, 3.42)\n",
- "\n",
- "for i in range(1,3):\n",
- "\n",
- " display_markdown(\n",
- " '### Code Created Heading {0}'.format(i), raw=True)\n",
- "\n",
- " fig, ax = plt.subplots()\n",
- " ax.plot(x, np.sin(x*i))\n",
- " metadata={'ipub': {\n",
- " 'figure': {\n",
- " 'caption': 'Code Created Heading {0}'.format(i)}}}\n",
- " display(fig, metadata=metadata)\n",
- " plt.close()\n"
- ]
- }
- ],
- "metadata": {
- "ipub": {
- "language": "british",
- "listcode": true,
- "listfigures": true,
- "listtables": true,
- "pandoc": {
- "at_notation": true,
- "convert_raw": true,
- "use_numref": true
- },
- "titlepage": {
- "author": "Chris Sewell",
- "email": "chrisj\\_sewell@hotmail.com",
- "institution": [
- "Institution1",
- "Institution2"
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ ".. _code_cells:\n",
+ "\n",
+ "# Writing Code and Formatting Output\n",
+ "\n",
+ "IPyPublish utilises metadata to mark-up the notebook with information on\n",
+ "how output should be represented in the converted notebook,\n",
+ "as shown in :numref:`fig:mpl1`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "ipub": {
+ "figure": {
+ "caption": "This is a Matplotlib figure, with a caption, a label and a set width",
+ "label": "fig:mpl1",
+ "width": 0.4
+ }
+ }
+ },
+ "outputs": [],
+ "source": [
+ "%matplotlib inline\n",
+ "import matplotlib.pyplot as plt\n",
+ "import numpy as np\n",
+ "plt.plot(np.sin(np.linspace(0, 6)))\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ ".. seealso::\n",
+ "\n",
+ " [The PDF representation of this notebook](_static/code_cells.pdf)\n",
+ "\n",
+ " :ref:`metadata_tags`, for a full description and list of ipypublish metadata\n",
+ "\n",
+ ".. _jupytext_python:\n",
+ "\n",
+ "## Converting Notebooks to Pure Python\n",
+ "\n",
+ "To write code, we can work in the conventional Jupyter Notebook environment,\n",
+ "or we can use [jupytext](https://github.com/mwouts/jupytext),\n",
+ "to convert between a notebook and the pure python\n",
+ "[percent format](https://github.com/mwouts/jupytext#the-percent-format)\n",
+ "\n",
+ "```console\n",
+ "$ jupytext --to py:percent notebook.ipynb\n",
+ "$ jupytext --to notebook notebook.py # overwrite notebook.ipynb\n",
+ "$ jupytext --to notebook --update notebook.py # update notebook.ipynb\n",
+ "```\n",
+ "\n",
+ "This will produce a standard python file,\n",
+ "with commented notebook level metadata commented at the top (in YAML format),\n",
+ "and each cell beginning with ``#%%`` (known as the percent format):\n",
+ "\n",
+ "The percent format can be utilised in IDEs, such as\n",
+ "[Spyder](https://docs.spyder-ide.org/editor.html#defining-code-cells),\n",
+ "[Atom](https://atom.io/packages/hydrogen),\n",
+ "[PyCharm](https://www.jetbrains.com/pycharm/), and\n",
+ "[VS Code](https://code.visualstudio.com/docs/python/jupyter-support),\n",
+ "to run individual cells:\n",
+ "\n",
+ "![Running Notebooks in VS Code](_static/vscode_python.png){#fig:vscode_py width=60%}\n",
+ "\n",
+ ".. important::\n",
+ "\n",
+ " To preserve ipypublish notebook metadata, you must add:\n",
+ " `\"jupytext\": {\"metadata_filter\": {\"notebook\": \"ipub\"}}` to\n",
+ " your notebooks metadata before conversion.\n",
+ "\n",
+ ".. seealso::\n",
+ "\n",
+ " :ref:`jupytext_rmarkdown`\n",
+ "\n",
+ " [Using YAML metadata blocks in Pandoc](https://pandoc.org/MANUAL.html#extension-yaml_metadata_block).\n",
+ "\n",
+ "## NB Setup Helper Functions\n",
+ "\n",
+ ":py:mod:`ipypublish.scripts.nb_setup` offers a number of useful functions,\n",
+ "to setup common packages (matplotlib, pandas, etc) for outputting content\n",
+ "in high quality formats."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "init_cell": true,
+ "slideshow": {
+ "slide_type": "skip"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "from ipypublish import nb_setup"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ ".. note::\n",
+ "\n",
+ " `ipypublish.scripts.ipynb_latex_setup` is deprecated in v0.9\n",
+ "\n",
+ "## Text Output"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "ipub": {
+ "text": {
+ "format": {
+ "backgroundcolor": "\\color{blue!10}"
+ }
+ }
+ }
+ },
+ "outputs": [],
+ "source": [
+ "print(\"\"\"\n",
+ "This is some printed text,\n",
+ "with a nicely formatted output.\n",
+ "\"\"\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Images (with PIL)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "init_cell": true,
+ "slideshow": {
+ "slide_type": "skip"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from ipypublish.tests import TEST_PIC_PATH\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "ipub": {
+ "figure": {
+ "caption": "Horizontally aligned images.",
+ "label": "fig:example_h",
+ "widefigure": false
+ }
+ }
+ },
+ "outputs": [],
+ "source": [
+ "nb_setup.images_hconcat([TEST_PIC_PATH, TEST_PIC_PATH],\n",
+ " width=600, gap=10)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "ipub": {
+ "figure": {
+ "caption": "Vertically aligned images.",
+ "label": "fig:example_v",
+ "widefigure": false
+ },
+ "slide": "new"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "nb_setup.images_vconcat([TEST_PIC_PATH, TEST_PIC_PATH],\n",
+ " height=400, gap=10)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "ipub": {
+ "figure": {
+ "caption": "Images aligned in a grid.",
+ "label": "fig:example_grid",
+ "widefigure": false
+ },
+ "slide": "new"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "nb_setup.images_gridconcat([[_,_] for _ in [TEST_PIC_PATH, TEST_PIC_PATH]],\n",
+ " height=300, vgap=10,hgap=20)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Plots (with Matplotlib)\n",
+ "\n",
+ "A matplotlib figure (+@fig:example_mpl{}), and its code (+@code:example_mpl{})."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "ipub": {
+ "code": {
+ "asfloat": true,
+ "caption": "The plotting code for a matplotlib figure (\\cref{fig:example_mpl}).",
+ "label": "code:example_mpl",
+ "widefigure": false
+ },
+ "figure": {
+ "caption": "A matplotlib figure",
+ "label": "fig:example_mpl",
+ "widefigure": false,
+ "width": 0.7
+ }
+ }
+ },
+ "outputs": [],
+ "source": [
+ "plt = nb_setup.setup_matplotlib(output=('pdf','svg'))\n",
+ "plt.scatter(np.random.rand(10), np.random.rand(10),\n",
+ " label='data label')\n",
+ "plt.ylabel(r'a y label with latex $\\alpha$')\n",
+ "plt.legend();"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ ".. note::\n",
+ "\n",
+ " If outputting the Matplotlib figures in a PDF format.\n",
+ " See [usetex tutorial](https://matplotlib.org/users/usetex.html#usetex-tutorial), \n",
+ " and [Stackoverflow question](https://stackoverflow.com/questions/38731201/latex-escaping-in-matplotlib).\n",
+ "\n",
+ "## Tables (with pandas)\n",
+ "\n",
+ "A pandas table (+@tbl:example_pd{}), and its code (+@code:example_pd{})."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "ipub": {
+ "code": {
+ "asfloat": true,
+ "caption": "The plotting code for a pandas Dataframe table (\\cref{tbl:example_pd}).",
+ "label": "code:example_pd",
+ "placement": "H",
+ "widefigure": false
+ },
+ "table": {
+ "alternate": "gray!20",
+ "caption": "An example of a table created with a pandas dataframe.",
+ "label": "tbl:example_pd",
+ "placement": "H"
+ }
+ }
+ },
+ "outputs": [],
+ "source": [
+ "pd = nb_setup.setup_pandas(escape_latex=False)\n",
+ "df = pd.DataFrame(np.random.rand(3,4),columns=['a','b','c','d'])\n",
+ "df.a = ['$\\delta$','x','y']\n",
+ "df.b = ['l','m','n']\n",
+ "df.set_index(['a','b'])\n",
+ "df.round(3)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ ".. note::\n",
+ "\n",
+ " If using `escape_latex=False`, then PDF conversion will throw an error \n",
+ " if there are e.g. `_`'s in your column names. You either need to escape\n",
+ " these manually (`\\_`) or use `escape_latex=True`. But note that, \n",
+ " `escape_latex=True` will also escape math (e.g. `$\\delta$`) causing it not\n",
+ " to render.\n",
+ "\n",
+ "## Equations (with ipython or sympy)\n",
+ "\n",
+ "An ipython and sympy equation =[@eqn:example_ipy;@eqn:example_sympy]."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "ipub": {
+ "equation": {
+ "label": "eqn:example_ipy"
+ }
+ }
+ },
+ "outputs": [],
+ "source": [
+ "from IPython.display import Latex\n",
+ "Latex('$$ a = b+c $$')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "ipub": {
+ "code": {
+ "asfloat": true,
+ "caption": "The plotting code for a sympy equation \\eqref{eqn:example_sympy}.",
+ "label": "code:example_sym",
+ "placement": "H",
+ "widefigure": false
+ },
+ "equation": {
+ "environment": "equation",
+ "label": "eqn:example_sympy"
+ }
+ }
+ },
+ "outputs": [],
+ "source": [
+ "sym = nb_setup.setup_sympy()\n",
+ "f = sym.Function('f')\n",
+ "y,n = sym.symbols(r'y \\alpha')\n",
+ "f = y(n)-2*y(n-1/sym.pi)-5*y(n-2)\n",
+ "sym.rsolve(f,y(n),[1,4])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Object Output Formats\n",
+ "\n",
+ "The format of the Jupyter Notebook file allows for the storage\n",
+ "of a single output in multiple formats. This is taken advantage of by\n",
+ "packages such as matplotlib and pandas, etc to store a figure/table in\n",
+ "both latex and html formats, which can then be selected by ipypublish\n",
+ "based on the document type required.\n",
+ "\n",
+ "Sometimes a user may wish to have greater control over the output format\n",
+ "and/or which output types are to be stored. It it possible to achieve\n",
+ "this *via* the Jupyter `display` function. For example, if we wanted\n",
+ "to display a pandas.DataFrame table without the index column, such that\n",
+ "it can be output to both a pdf and html document:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from IPython.display import display\n",
+ "df = pd.DataFrame(np.random.random((3, 3)))\n",
+ "latex = df.to_latex(index=False)\n",
+ "html = df.to_html(index=False)\n",
+ "display({'text/latex': latex,\n",
+ " 'text/html': html}, raw=True)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "If you wish to create your own object with multiple output formats, you\n",
+ "should create a class with multiple `_repr_*_()` methods:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "ipub": {
+ "equation": false,
+ "table": false
+ }
+ },
+ "outputs": [],
+ "source": [
+ "class MyObject(object):\n",
+ " def __init__(self, text):\n",
+ " self.text = text\n",
+ "\n",
+ " def _repr_latex_(self):\n",
+ " return \"\\\\textbf{LaTex: \" + self.text + \"}\"\n",
+ "\n",
+ " def _repr_html_(self):\n",
+ " return \"HTML: \" + self.text + \"\"\n",
+ "\n",
+ "MyObject('hallo')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ ".. seealso::\n",
+ "\n",
+ " :ref:`nbformat:notebook_file_format`\n",
+ "\n",
+ " [IPython Rich Display](http://ipython.readthedocs.io/en/stable/config/integrating.html#rich-display)\n",
+ "\n",
+ ".. _multiple_outputs:\n",
+ "\n",
+ "## Multiple Outputs from a Single Code Cell\n",
+ "\n",
+ "Similarly, with the Jupyter `display` functionality, you can control the output\n",
+ "metadata for multiple outputs in a single code cell:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from IPython.display import display\n",
+ "from IPython.display import display_latex\n",
+ "from IPython.display import display_markdown\n",
+ "\n",
+ "x = np.linspace(0, 3.42)\n",
+ "\n",
+ "for i in range(1,3):\n",
+ "\n",
+ " display_markdown(\n",
+ " '### Code Created Heading {0}'.format(i), raw=True)\n",
+ "\n",
+ " fig, ax = plt.subplots()\n",
+ " ax.plot(x, np.sin(x*i))\n",
+ " metadata={'ipub': {\n",
+ " 'figure': {\n",
+ " 'caption': 'Code Created Heading {0}'.format(i)}}}\n",
+ " display(fig, metadata=metadata)\n",
+ " plt.close()\n"
+ ]
+ }
],
- "logo": "_static/logo_example.png",
- "subtitle": "Formatting Code Cells",
- "supervisors": [
- "First Supervisor",
- "Second Supervisor"
- ],
- "tagline": "Converted using IPyPublish ('latex\\_ipypublish\\_all.exec').",
- "title": "Example of Converted Jupyter Notebook"
- },
- "toc": true
- },
- "jupytext": {
- "metadata_filter": {
- "notebook": "ipub"
- },
- "text_representation": {
- "extension": ".Rmd",
- "format_name": "rmarkdown",
- "format_version": "1.0",
- "jupytext_version": "0.8.6"
- }
- },
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
+ "metadata": {
+ "ipub": {
+ "language": "british",
+ "listcode": true,
+ "listfigures": true,
+ "listtables": true,
+ "pandoc": {
+ "at_notation": true,
+ "convert_raw": true,
+ "use_numref": true
+ },
+ "sphinx": {
+ "toggle_input": true,
+ "toggle_input_all": true,
+ "toggle_output": true,
+ "toggle_output_all": true
+ },
+ "titlepage": {
+ "author": "Chris Sewell",
+ "email": "chrisj\\_sewell@hotmail.com",
+ "institution": [
+ "Institution1",
+ "Institution2"
+ ],
+ "logo": "_static/logo_example.png",
+ "subtitle": "Formatting Code Cells",
+ "supervisors": [
+ "First Supervisor",
+ "Second Supervisor"
+ ],
+ "tagline": "Converted using IPyPublish ('latex\\_ipypublish\\_all.exec').",
+ "title": "Example of Converted Jupyter Notebook"
+ },
+ "toc": true
+ },
+ "jupytext": {
+ "metadata_filter": {
+ "notebook": "ipub"
+ },
+ "text_representation": {
+ "extension": ".Rmd",
+ "format_name": "rmarkdown",
+ "format_version": "1.0",
+ "jupytext_version": "0.8.6"
+ }
+ },
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
}
diff --git a/docs/source/releases.rst b/docs/source/releases.rst
index 6236c44..2ccc9e7 100644
--- a/docs/source/releases.rst
+++ b/docs/source/releases.rst
@@ -13,11 +13,11 @@ Releases
Version 0.10
------------
-v0.10.6
-~~~~~~~
+v0.10.6 & v0.10.7
+~~~~~~~~~~~~~~~~~
-Added sphinx option for toggling code cells;
-see :ref:`sphinx_ext_notebook_toggle_in` example.
+Added sphinx option for toggling notebook input and output cells.
+For examples see :ref:`sphinx_ext_notebook_toggle_in` and :ref:`code_cells`.
v0.10.5
~~~~~~~
diff --git a/docs/source/sphinx_ext_notebook.rst b/docs/source/sphinx_ext_notebook.rst
index d36ed4b..e5062e5 100644
--- a/docs/source/sphinx_ext_notebook.rst
+++ b/docs/source/sphinx_ext_notebook.rst
@@ -120,8 +120,8 @@ setup by adding to the conf.py:
ipysphinx_show_prompts False show cell prompts
ipysphinx_input_prompt "[{count}]:" format of input prompts
ipysphinx_output_prompt "[{count}]:" format of output prompts
- ipysphinx_code_toggle False add a button at the right side of input cells, to toggle show/hide
- ipysphinx_code_hide False for input cells with a toggle, whether to initialise them as hidden
+ ipysphinx_input_toggle False add a button at the right side of input cells, to toggle show/hide
+ ipysphinx_output_toggle False add a button at the right side of output cells, to toggle show/hide
ipysphinx_preconverters {} a mapping of additional file extensions to preconversion functions
============================= =========================== ===================================================================
@@ -165,11 +165,15 @@ Basic output
.. _sphinx_ext_notebook_toggle_in:
-Toggle input
-~~~~~~~~~~~~
+Toggle inputs/outputs
+~~~~~~~~~~~~~~~~~~~~~
.. code-block:: rst
+ .. nbinput-toggle-all:: NbInput Toggle All
+
+ .. nboutput-toggle-all:: NbOutput Toggle All
+
.. nbinput:: python
:add-toggle:
:execution-count: 3
@@ -180,6 +184,17 @@ Toggle input
j += i
print(j)
+ .. nboutput::
+ :add-toggle:
+ :execution-count: 3
+
+ hallo
+ there
+
+.. nbinput-toggle-all:: NbInput Toggle All
+
+.. nboutput-toggle-all:: NbOutput Toggle All
+
.. nbinput:: python
:add-toggle:
:execution-count: 3
@@ -190,6 +205,13 @@ Toggle input
j += i
print(j)
+.. nboutput::
+ :add-toggle:
+ :execution-count: 3
+
+ hallo
+ there
+
Information and Warnings
~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/ipypublish/__init__.py b/ipypublish/__init__.py
index b8dd118..865f4a6 100644
--- a/ipypublish/__init__.py
+++ b/ipypublish/__init__.py
@@ -1,3 +1,3 @@
from ipypublish.scripts import nb_setup # noqa: F401
-__version__ = '0.10.6'
+__version__ = '0.10.7'
diff --git a/ipypublish/schema/doc_metadata.schema.json b/ipypublish/schema/doc_metadata.schema.json
index 44ad436..8316370 100644
--- a/ipypublish/schema/doc_metadata.schema.json
+++ b/ipypublish/schema/doc_metadata.schema.json
@@ -179,7 +179,7 @@
"altlisthypergroup"
],
"default": "list"
- }
+ }
}
},
"pandoc": {
@@ -260,10 +260,30 @@
"description": "created as '.. rubric:: glossary_title'",
"type": "string",
"default": "Glossary"
+ },
+ "toggle_input": {
+ "description": "add toggle buttons to the right of all nbinput cells, to hide/show their content",
+ "type": "boolean",
+ "default": false
+ },
+ "toggle_input_all": {
+ "description": "add a toggle button at the top of the top of the document (using `:toggle-input-all:`), which will show/hide all nbinput cell's content",
+ "type": "boolean",
+ "default": false
+ },
+ "toggle_output": {
+ "description": "add toggle buttons to the right of all nboutput cells, to hide/show their content",
+ "type": "boolean",
+ "default": false
+ },
+ "toggle_output_all": {
+ "description": "add a toggle button at the top of the top of the document (using `:toggle-output-all:`), which will show/hide all nboutput cell's content",
+ "type": "boolean",
+ "default": false
}
}
}
}
}
}
-}
\ No newline at end of file
+}
diff --git a/ipypublish/sphinx/notebook/css/nb_cells.css b/ipypublish/sphinx/notebook/css/nb_cells.css
index e78dd5e..2914066 100644
--- a/ipypublish/sphinx/notebook/css/nb_cells.css
+++ b/ipypublish/sphinx/notebook/css/nb_cells.css
@@ -202,21 +202,50 @@ div.rendered_html tbody tr:hover {
background: rgba(66, 165, 245, 0.2);
}
-.toggle-nbinput {
+div.toggle-nbinput,
+div.toggle-nboutput {
+ cursor: pointer;
min-width: 2ex;
padding-top: 0.4em;
padding-left: 0.1em;
text-align: right;
flex: 0;
- margin-left:auto;
- margin-right:0;
+ margin-left: auto;
+ margin-right: 0;
}
-.toggle-nbinput p {
+div.toggle-nbinput p,
+div.toggle-nboutput p {
overflow: hidden;
}
-.toggle-nbinput:after {
+div.toggle-nbinput:after,
+div.toggle-nboutput:after,
+div.nbinput-toggle-all :after,
+div.nboutput-toggle-all :after {
content: " ▼";
}
-.toggle-nbinput.open:after {
+div.toggle-nbinput.open:after,
+div.toggle-nboutput.open:after,
+div.nbinput-toggle-all.open :after,
+div.nboutput-toggle-all.open :after {
content: " ▲";
}
+
+div.nbinput-toggle-all,
+div.nboutput-toggle-all {
+ display: inline-block;
+ cursor: pointer;
+ min-width: 7ex;
+ padding: 0.2em 0.4em 0.2em 0.4em;
+ margin-bottom: 2ex;
+ border: 1px solid #000;
+ border-radius: 15px;
+}
+div.nbinput-toggle-all p,
+div.nboutput-toggle-all p {
+ overflow: hidden;
+ margin: 0 auto;
+}
+div.nbinput-toggle-all:hover,
+div.nboutput-toggle-all:hover{
+ background: rgb(158, 210, 230);
+}
diff --git a/ipypublish/sphinx/notebook/directives.py b/ipypublish/sphinx/notebook/directives.py
index 85e10d8..0a96ca1 100644
--- a/ipypublish/sphinx/notebook/directives.py
+++ b/ipypublish/sphinx/notebook/directives.py
@@ -37,6 +37,36 @@ class NbInfo(NbAdmonition):
_class = 'note'
+class NBInputToggle(rst.Directive):
+ """ a toggle button for nbinput cells """
+ _class = 'nbinput-toggle-all'
+ _default_text = 'Toggle Input Cells'
+
+ required_arguments = 0
+ optional_arguments = 0
+ option_spec = {}
+ has_content = True # button text
+
+ def run(self):
+ """This is called by the reST parser."""
+ node = nodes.container()
+ node['classes'].append(self._class)
+ if self.content:
+ self.state.nested_parse(self.content, self.content_offset, node)
+ else:
+ text = self.arguments[0] if self.arguments and self.arguments[0] else self._default_text
+ paragraph = nodes.paragraph(text=text)
+ node += paragraph
+
+ return [node]
+
+
+class NBOutputToggle(NBInputToggle):
+ """ a toggle button for nboutput cells """
+ _class = 'nboutput-toggle-all'
+ _default_text = 'Toggle Output Cells'
+
+
class NbInput(rst.Directive):
"""A notebook input cell with prompt and code area."""
@@ -72,6 +102,7 @@ class NbOutput(rst.Directive):
'empty-lines-before': rst.directives.nonnegative_int,
'empty-lines-after': rst.directives.nonnegative_int,
'class': rst.directives.unchanged,
+ 'add-toggle': rst.directives.flag
}
has_content = True
@@ -160,10 +191,16 @@ def _create_nbcell_nodes(directive):
else:
outer_node += codearea_node
- if isinstance(directive, NbInput) and (config.ipysphinx_code_toggle or 'add-toggle' in directive.options):
+ if isinstance(directive, NbInput) and (config.ipysphinx_input_toggle or 'add-toggle' in directive.options):
+ directive.state.document['ipysphinx_include_js'] = True
outer_node += sphinx.addnodes.only(
'', docutils.nodes.container(classes=['toggle-nbinput', 'empty']), expr='html')
+ if isinstance(directive, NbOutput) and (config.ipysphinx_output_toggle or 'add-toggle' in directive.options):
+ directive.state.document['ipysphinx_include_js'] = True
+ outer_node += sphinx.addnodes.only(
+ '', docutils.nodes.container(classes=['toggle-nboutput', 'empty']), expr='html')
+
return [outer_node]
diff --git a/ipypublish/sphinx/notebook/extension.py b/ipypublish/sphinx/notebook/extension.py
index 40a3389..2570e4e 100644
--- a/ipypublish/sphinx/notebook/extension.py
+++ b/ipypublish/sphinx/notebook/extension.py
@@ -6,8 +6,8 @@
from ipypublish import __version__
from ipypublish.sphinx.utils import import_sphinx
-from ipypublish.sphinx.notebook.directives import (NbInfo, NbInput, NbOutput, NbWarning, AdmonitionNode, CodeAreaNode,
- FancyOutputNode)
+from ipypublish.sphinx.notebook.directives import (NbInfo, NbInput, NbOutput, NbWarning, AdmonitionNode, NBInputToggle,
+ NBOutputToggle, CodeAreaNode, FancyOutputNode)
from ipypublish.sphinx.notebook.transforms import (CreateDomainObjectLabels, CreateSectionLabels, RewriteLocalLinks)
from ipypublish.sphinx.notebook.parser import NBParser
@@ -76,9 +76,9 @@ def add_transform(transform, post=False):
app.add_config_value('ipysphinx_input_prompt', '[{count}]:', rebuild='env')
app.add_config_value('ipysphinx_output_prompt', '[{count}]:', rebuild='env')
- # config for input cell toggling
- app.add_config_value('ipysphinx_code_toggle', False, rebuild='env')
- app.add_config_value('ipysphinx_code_hide', False, rebuild='env')
+ # config for cell toggling
+ app.add_config_value('ipysphinx_input_toggle', False, rebuild='env')
+ app.add_config_value('ipysphinx_output_toggle', False, rebuild='env')
# config for html css
app.add_config_value('ipysphinx_responsive_width', '540px', rebuild='html')
@@ -104,6 +104,8 @@ def add_transform(transform, post=False):
app.add_directive('nboutput', NbOutput)
app.add_directive('nbinfo', NbInfo)
app.add_directive('nbwarning', NbWarning)
+ app.add_directive('nbinput-toggle-all', NBInputToggle)
+ app.add_directive('nboutput-toggle-all', NBOutputToggle)
# add docutils nodes and visit/depart wraps
app.add_node(
@@ -289,9 +291,8 @@ def copy_javascript(name):
def html_add_javascript(app, pagename, templatename, context, doctree):
"""Add JavaScript string to HTML pages that contain code cells."""
- if doctree and doctree.get('ipysphinx_include_css'):
- if app.config.ipysphinx_code_hide:
- code = copy_javascript('toggle_code_hide')
- else:
- code = copy_javascript('toggle_code_show')
+ if doctree and doctree.get('ipysphinx_include_js'):
+ code = copy_javascript('toggle_code')
+ context['body'] = '\n\n' + context['body']
+ code = copy_javascript('toggle_output')
context['body'] = '\n\n' + context['body']
diff --git a/ipypublish/sphinx/notebook/js/toggle_code.js b/ipypublish/sphinx/notebook/js/toggle_code.js
new file mode 100644
index 0000000..2c3c477
--- /dev/null
+++ b/ipypublish/sphinx/notebook/js/toggle_code.js
@@ -0,0 +1,24 @@
+
+$(function () {
+
+ $(".input_area").show();
+ $(".toggle-nbinput").addClass("open");
+ $(".nbinput-toggle-all").addClass("open");
+
+ $(".toggle-nbinput").click(function () {
+ $(this).toggleClass("open");
+ $(this).prev(".input_area").toggle("400");
+ });
+
+ $(".nbinput-toggle-all").click(function () {
+ $(this).toggleClass("open");
+ if ($(this).hasClass("open")) {
+ $(".toggle-nbinput").addClass("open");
+ $(".input_area").show("400");
+ } else {
+ $(".toggle-nbinput").removeClass("open");
+ $(".input_area").hide("400");
+ }
+ });
+
+});
diff --git a/ipypublish/sphinx/notebook/js/toggle_code_hide.js b/ipypublish/sphinx/notebook/js/toggle_code_hide.js
deleted file mode 100644
index cb8812f..0000000
--- a/ipypublish/sphinx/notebook/js/toggle_code_hide.js
+++ /dev/null
@@ -1,9 +0,0 @@
-$(function() {
-
- $(".input_area").hide();
- $(".toggle-nbinput").click(function () {
- $(this).toggleClass("open");
- $(this).prev(".input_area").toggle("400");
- });
-
-});
diff --git a/ipypublish/sphinx/notebook/js/toggle_code_show.js b/ipypublish/sphinx/notebook/js/toggle_code_show.js
deleted file mode 100644
index aa8da32..0000000
--- a/ipypublish/sphinx/notebook/js/toggle_code_show.js
+++ /dev/null
@@ -1,10 +0,0 @@
-
-$(function () {
-
- $(".input_area").show();
- $(".toggle-nbinput").click(function () {
- $(this).toggleClass("open");
- $(this).prev(".input_area").toggle("400");
- });
-
-});
diff --git a/ipypublish/sphinx/notebook/js/toggle_output.js b/ipypublish/sphinx/notebook/js/toggle_output.js
new file mode 100644
index 0000000..cd67f98
--- /dev/null
+++ b/ipypublish/sphinx/notebook/js/toggle_output.js
@@ -0,0 +1,24 @@
+
+$(function () {
+
+ $(".output_area").show();
+ $(".toggle-nboutput").addClass("open");
+ $(".nboutput-toggle-all").addClass("open");
+
+ $(".toggle-nboutput").click(function () {
+ $(this).toggleClass("open");
+ $(this).prev(".output_area").toggle("400");
+ });
+
+ $(".nboutput-toggle-all").click(function () {
+ $(this).toggleClass("open");
+ if ($(this).hasClass("open")) {
+ $(".toggle-nboutput").addClass("open");
+ $(".output_area").show("400");
+ } else {
+ $(".toggle-nboutput").removeClass("open");
+ $(".output_area").hide("400");
+ }
+ });
+
+});
diff --git a/ipypublish/sphinx/tests/sourcedirs/notebook_cell_decor/conf.py b/ipypublish/sphinx/tests/sourcedirs/notebook_cell_decor/conf.py
index 5bfe1a0..1133f68 100644
--- a/ipypublish/sphinx/tests/sourcedirs/notebook_cell_decor/conf.py
+++ b/ipypublish/sphinx/tests/sourcedirs/notebook_cell_decor/conf.py
@@ -4,5 +4,5 @@
exclude_patterns = ['_build']
master_doc = 'contents'
ipysphinx_show_prompts = True
-ipysphinx_code_toggle = True
-ipysphinx_code_hide = True
+ipysphinx_input_toggle = True
+ipysphinx_output_toggle = True
diff --git a/ipypublish/sphinx/tests/sourcedirs/notebook_cell_decor/contents.rst b/ipypublish/sphinx/tests/sourcedirs/notebook_cell_decor/contents.rst
index 462942d..25551f6 100644
--- a/ipypublish/sphinx/tests/sourcedirs/notebook_cell_decor/contents.rst
+++ b/ipypublish/sphinx/tests/sourcedirs/notebook_cell_decor/contents.rst
@@ -1,3 +1,7 @@
+.. nbinput-toggle-all:: NbInput Toggle All
+
+.. nboutput-toggle-all:: NbOutput Toggle All
+
.. nbinput:: ipython3
:execution-count: 3
:no-output:
diff --git a/ipypublish/sphinx/tests/test_notebook/test_cell_decoration_v1.yml b/ipypublish/sphinx/tests/test_notebook/test_cell_decoration_v1.yml
index e4e915c..7291e15 100644
--- a/ipypublish/sphinx/tests/test_notebook/test_cell_decoration_v1.yml
+++ b/ipypublish/sphinx/tests/test_notebook/test_cell_decoration_v1.yml
@@ -26,6 +26,24 @@
- body
role: main
4_children:
+ - 1_tag: div
+ 2_data:
+ - ''
+ - NbInput Toggle All
+ 3_attributes:
+ class:
+ - container
+ - docutils
+ - nbinput-toggle-all
+ - 1_tag: div
+ 2_data:
+ - ''
+ - NbOutput Toggle All
+ 3_attributes:
+ class:
+ - container
+ - docutils
+ - nboutput-toggle-all
- 1_tag: div
3_attributes:
class:
@@ -264,6 +282,13 @@
- 1_tag: td
2_data:
- '0.116'
+ - 1_tag: div
+ 3_attributes:
+ class:
+ - container
+ - docutils
+ - empty
+ - toggle-nboutput
- 1_tag: div
3_attributes:
class:
@@ -298,3 +323,10 @@
- This is some printed text,
- with a nicely formatted output.
- ''
+ - 1_tag: div
+ 3_attributes:
+ class:
+ - container
+ - docutils
+ - empty
+ - toggle-nboutput
diff --git a/ipypublish/sphinx/tests/test_notebook/test_cell_decoration_v2.yml b/ipypublish/sphinx/tests/test_notebook/test_cell_decoration_v2.yml
index 58ec628..136b6a7 100644
--- a/ipypublish/sphinx/tests/test_notebook/test_cell_decoration_v2.yml
+++ b/ipypublish/sphinx/tests/test_notebook/test_cell_decoration_v2.yml
@@ -26,6 +26,26 @@
- body
role: main
4_children:
+ - 1_tag: div
+ 3_attributes:
+ class:
+ - container
+ - docutils
+ - nbinput-toggle-all
+ 4_children:
+ - 1_tag: p
+ 2_data:
+ - NbInput Toggle All
+ - 1_tag: div
+ 3_attributes:
+ class:
+ - container
+ - docutils
+ - nboutput-toggle-all
+ 4_children:
+ - 1_tag: p
+ 2_data:
+ - NbOutput Toggle All
- 1_tag: div
3_attributes:
class:
@@ -290,6 +310,13 @@
- 1_tag: p
2_data:
- '0.116'
+ - 1_tag: div
+ 3_attributes:
+ class:
+ - container
+ - docutils
+ - empty
+ - toggle-nboutput
- 1_tag: div
3_attributes:
class:
@@ -324,3 +351,10 @@
- This is some printed text,
- with a nicely formatted output.
- ''
+ - 1_tag: div
+ 3_attributes:
+ class:
+ - container
+ - docutils
+ - empty
+ - toggle-nboutput
diff --git a/ipypublish/templates/segments/ipy-sphinx.yaml.j2 b/ipypublish/templates/segments/ipy-sphinx.yaml.j2
index ddfd57f..73031ea 100644
--- a/ipypublish/templates/segments/ipy-sphinx.yaml.j2
+++ b/ipypublish/templates/segments/ipy-sphinx.yaml.j2
@@ -18,6 +18,11 @@
{% if "sphinx" in nb.metadata.ipub %}
{% set output_bib = not nb.metadata.ipub.sphinx.no_bib %}
{% set output_gloss = not nb.metadata.ipub.sphinx.no_glossary %}
+ {% set orphan = nb.metadata.ipub.sphinx.orphan %}
+ {% set toggle_input = nb.metadata.ipub.sphinx.toggle_input %}
+ {% set toggle_input_all = nb.metadata.ipub.sphinx.toggle_input_all %}
+ {% set toggle_output = nb.metadata.ipub.sphinx.toggle_output %}
+ {% set toggle_output_all = nb.metadata.ipub.sphinx.toggle_output_all %}
{% if nb.metadata.ipub.sphinx.bib_title %}
{% set bib_title = nb.metadata.ipub.sphinx.bib_title %}
@@ -35,6 +40,11 @@
{% set output_bib = True %}
{% set output_gloss = True %}
+ {% set orphan = False %}
+ {% set toggle_input = False %}
+ {% set toggle_input_all = False %}
+ {% set toggle_output = False %}
+ {% set toggle_output_all = False %}
{% set bib_title = "Bibliography" %}
{% set glossary_title = "Glossary" %}
@@ -42,8 +52,17 @@
{% endif %}
"header": |
- {% if sphinx_opts and sphinx_opts.orphan %}
+ {% if orphan %}
{{':orphan:'}}
+
+ {% endif %}
+ {% if toggle_input_all %}
+ {{'.. nbinput-toggle-all::'}}
+
+ {% endif %}
+ {% if toggle_input_all %}
+ {{'.. nboutput-toggle-all::'}}
+
{% endif %}
"notebook_input_all": |
@@ -73,6 +92,9 @@
{%- if cell.execution_count %}
:execution-count: {{ cell.execution_count }}
{%- endif %}
+ {%- if toggle_input %}
+ :add-toggle:
+ {%- endif -%}
{%- if not cell.outputs %}
:no-output:
{%- endif -%}
@@ -160,7 +182,7 @@
{{ insert_nboutput(latex_datatype, output, cell) | indent }}
{% endif %}
- {% endblock nboutput %}
+ {% endblock nboutput %}
"notebook_output_error": |
{%- if "ipub" in cell.metadata and cell.metadata.ipub.error -%}
@@ -184,7 +206,7 @@
"notebook_output_data_all": |
{{ self.nboutput() }}
-
+
"footer": |
{# output a bibglossary if there is one #}
{%- if nb.metadata.ipub and nb.metadata.ipub.bibglossary: -%}
@@ -196,7 +218,7 @@
{%- endif -%}
{%- endif %}
- {# output a bibligraphy if there is one
+ {# output a bibligraphy if there is one
(see https://sphinxcontrib-bibtex.readthedocs.io/en/latest/usage.html) #}
{%- if nb.metadata.ipub: -%}
{%- if nb.metadata.ipub.bibliography and output_bib: -%}
@@ -257,11 +279,11 @@
{# find captions #}
{%- set ipubfigcaption = "figure" | get_caption(cell.metadata, resources) %}
{% if ipubfigcaption %}
- {%- set ipubfigcaption = ipubfigcaption | ipypandoc('rst', nb.metadata, cell.metadata) %}
+ {%- set ipubfigcaption = ipubfigcaption | ipypandoc('rst', nb.metadata, cell.metadata) %}
{% endif %}
{%- set ipubtblcaption = "table" | get_caption(cell.metadata, resources) %}
{% if ipubtblcaption %}
- {%- set ipubtblcaption = ipubtblcaption | ipypandoc('rst', nb.metadata, cell.metadata) %}
+ {%- set ipubtblcaption = ipubtblcaption | ipypandoc('rst', nb.metadata, cell.metadata) %}
{% endif %}
{# create the output directive and supply it with the type of data #}
.. nboutput::
@@ -273,6 +295,9 @@
{%- if output.output_type == 'execute_result' and output.execution_count %}
:execution-count: {{ output.execution_count }}
{%- endif %}
+ {%- if toggle_output %}
+ :add-toggle:
+ {%- endif %}
{%- if output != cell.outputs[-1] %}
:more-to-come:
{%- endif %}
@@ -287,7 +312,7 @@
{{ output.data[datatype].strip('\n') | indent }}
{# output figure type outputs # TODO set width of figures from ipub metadata (need to convert fraction -> percentage) #}
{%- elif datatype in ['image/svg+xml', 'image/png', 'image/jpeg', 'application/pdf'] and ipub.get('figure', False) %}
-
+
.. figure:: {{ output.metadata.filenames[datatype] | posix_path }}
:alt: {{ output.metadata.filenames[datatype] | posix_path | basename }}
:align: center
@@ -411,4 +436,4 @@
{%- endif %}
{% endmacro %}
-# END
\ No newline at end of file
+# END