Skip to content

Commit

Permalink
Demo: more documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
jankatins committed Dec 10, 2015
1 parent d18a4dc commit e339052
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 6 deletions.
73 changes: 68 additions & 5 deletions docs/source/demo_mode.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,81 @@ Demo mode

.. currentmodule:: ipyext.demo

As a User
---------

There are currently two possible sources of demos:

* plain (self contained) functions included in modules
of libraries you use.
* the matplotlib examples in their github repository

``demo(...)`` has two modes:

* for a imported module or a directory on github, it will list the available demos.
* for a function or a file on github, it will show the demo.

Example:

.. ipython:: python
from ipyext.demo import demo
import ipyext.demo
demo(ipyext.demo)
demo("<gh_matplotlib>/statistics/")
# stops an already running demo
demo("STOP")
demo(ipyext.demo) # lists all demos
demo(ipyext.demo.demo_example) # runs the demo_example
demo("STOP") # stops an already running demo
demo("<gh_matplotlib>/statistics/") # lists demos from matplotlibs' examples
Hiere is the API documentation of ``demo()``

.. autosummary::
:toctree: generated/

demo

As a developer
--------------

You can create demos by adding a new module which should contain two things:

* One or more *self contained functions* which take *no arguments*. The
functions can have two types of *comments*: ``"# "`` (fence + space) are
interpreted as markdown (e.g. write ``"# # headline"``) and result in
markdown cells in the notebook and normal comments in the console.
Comments without a space are interpreted as code comments and added
directly to the following code input. You can add a *one line docstring*
which will be shown as description of the demo in the list of available
demos. Using *IPython magic methods* are also possible but must be
commented.
* A ``__demos__`` field in the module which *lists all demo functions* (direct
reference, not strings like in ``__all__``!).

Example:

.. code-block:: python
def demo_example():
"""An example how to write a demo."""
# ## Comments
# Comments are interpreted as markdown syntax, removing the
# initial `# `. If a comment starts only with `#`, it is interpreted
# as a code comment, which will end up together with the code.
#change your name:
name = "Jan"
print("Hello {0}!".format(name))
# ## Magics
# Using magics would result in not compiling code, so magics
# have to be commented out. The demo will remove the comment
# and insert it into the cell as code.
#%%time
_sum = 0
for x in range(10000):
_sum += x
# Print the sum:
print(_sum)
# This lets the `demo(ipyext.demo)` find only the `demo_example`.
# Only modues with that variable will display an overview of
# the available demos.
__demos__ = [demo_example]
54 changes: 53 additions & 1 deletion ipyext/demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
from textwrap import dedent, wrap
import re
import sys
import os


def w(txt):
return "\n".join(wrap(txt))
Expand Down Expand Up @@ -88,6 +90,9 @@ def demo(content, frontend=None):
# use a singleton to make stopping demos possible...
if frontend is None:
frontend = nb_frontend
# special case for Sphinx, to show the stuff...
if "SPHINXBUILD" in os.environ:
frontend = PrintFrontend()
elif frontend == "ipython":
frontend = ipy_frontend
elif frontend == "notebook":
Expand Down Expand Up @@ -286,8 +291,12 @@ class IPythonFrontend(Frontend):

def __init__(self):
self._buffer = []


@property
def ip(self):
try:
self.ip = get_ipython()
return get_ipython()
except:
raise Exception("Not running in an IPython environment")

Expand Down Expand Up @@ -394,6 +403,49 @@ def _build(self, cells):

js.append('var self = this; setTimeout(function() { self.clear_output(); }, 0);')


class PrintFrontend(Frontend):

def __init__(self):
self.buffer = []

def _publish(self):
"""Publishes the content of the demo to the frontend"""
md_buffer = None
printouts = []
for cell in self.buffer:
source = cell['source'].strip()
if cell['cell_type'] == 'markdown':
lines = source.split("\n")
lines = ["# " + line for line in lines]
#lines.append("pass # do not remove") # to make even comment only cells to run
# something
commented = "\n".join(lines)
md_buffer = commented
elif cell['cell_type'] == 'code':
if md_buffer is not None:
# cell magics need to be at the start of a cell
if source[0:2] == "%%":
printouts.append(md_buffer)
else:
source = md_buffer + "\n" + source
md_buffer = None
printouts.append(source)
if md_buffer is not None:
printouts.append(md_buffer)
print("\n--- new demo step ---\n".join(printouts))


def _build(self, cells):
"""Builds the to be published content from the cells"""
self.buffer.extend(cells)

def is_running(self):
if self.buffer:
return True
return False


nb_frontend = NotebookFrontend()
ipy_frontend = IPythonFrontend()

Expand Down

0 comments on commit e339052

Please sign in to comment.