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