Skip to content

Commit

Permalink
Merge pull request #7 from apiad/develop
Browse files Browse the repository at this point in the history
v0.3.0
  • Loading branch information
apiad authored Dec 10, 2019
2 parents cb51bfa + a846325 commit 100711b
Show file tree
Hide file tree
Showing 7 changed files with 195 additions and 12 deletions.
52 changes: 50 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ For example, you can generate an interactive graph that can be modified by movin

**And all of this without writing a single line of HTML or JavaScript.**

Alternatively, if you need little to no Python code, you can author your slideshow in pure Markdown and add some Python sprinkless here and there when necessary.

## Installation

Simply run:
Expand All @@ -31,7 +33,7 @@ To see a quick demo run:

And point your browser at [localhost:6789](http://localhost:6789).

## Quick start
## Quick Start - Python First

In `auditorium` you create a presentation via the `Show` class:

Expand Down Expand Up @@ -110,6 +112,48 @@ def pyplot():
show.pyplot(plt, fmt='png', height=350)
```

## Quick Start - Markdown First

Alternatively, if you need little to no Python, you can author your slideshow in pure Markdown. Every level-2 header (`##`) becomes a slide.

```markdown
## Static content

Static content can be added with pure markdown.

* Some _markdown_ content.
* More **markdown** content.
```

Pure Markdown can be used as long as all you need is static content. If you need more advanced features, you can add a Python code section anywhere in your slideshow and it will be executed.

```markdown
## Python content

If you need interaction or advanced `auditorium` features,
simply add a code section.

\```python
with show.columns(2) as cl:
text = show.text_input("World")

cl.tab()

with show.success("Message"):
show.markdown(f"Hello {text}")
\```
```

An instance named `show` will be magically available in every Python code section. Beware that **local variables are not persisted** between different code sections. This is a by-design decision to save you a bunch of headaches, believe me.

Once you finished authoring you slideshow, simply run it just like before:

```bash
auditorium run <file.md>
```

If you want to see and example, check [auditorium/static/md/demo.md](auditorium/static/md/demo.md)

## What's the catch

Auditorium covers a fairly simple use case that I haven't seen solved for a long time.
Expand Down Expand Up @@ -162,7 +206,11 @@ Staying away from `eval` and `exec` should keep you safe in most scenarios, but

## History

### v0.2.0 (latest release and branch `master`)
### v0.3.0 (latest release and branch `master`)

* Added support for running directly from Markdown files with `auditorium run <file.md>`.

### v0.2.0

* Added command `auditorium run <file.py>` for running a specific slideshow. This is now the preferred method.
* Added command `auditorium demo` for running the demo.
Expand Down
11 changes: 9 additions & 2 deletions auditorium/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,21 @@
import fire
import runpy

from auditorium.markdown import MarkdownLoader


class Auditorium:
@staticmethod
def run(path, host='localhost', port=6789, debug=False, instance_name='show'):
"Runs a custom Python script as a slideshow."

ns = runpy.run_path(path)
show = ns[instance_name]
if path.endswith('.py'):
ns = runpy.run_path(path)
show = ns[instance_name]
elif path.endswith('.md'):
loader = MarkdownLoader(path, instance_name=instance_name)
show = loader.parse()

show.run(host=host, port=port, debug=debug)

@staticmethod
Expand Down
89 changes: 89 additions & 0 deletions auditorium/markdown.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# coding: utf8

from auditorium import Show


class MarkdownLoader:
def __init__(self, path, instance_name='show'):
self.path = path
self.instance_name = instance_name

def parse(self):
slides = []
current_slide = []

with open(self.path) as fp:
for line in fp:
line = line.strip("\n")

if line.startswith("## ") and current_slide:
slides.append(current_slide)
current_slide = []

current_slide.append(line)

if current_slide:
slides.append(current_slide)

show = Show()

for i, slide in enumerate(slides):
show.slide(func=MarkdownSlide(show, slide), id='slide-%i' % (i+1))

return show


class MarkdownSlide:
def __init__(self, show: Show, content):
self.show = show
self.content = []

state = 'markdown' # or 'code'
split = []

for line in content:
if state == 'markdown':
if line.startswith('```python'):
if split:
self.content.append(MarkdownContent(split))

split = []
state = 'code'
else:
split.append(line)

elif state == 'code':
if line.startswith('```'):
if split:
self.content.append(PythonContent(split))

split = []
state = 'markdown'
else:
split.append(line)

if split:
if state == 'markdown':
self.content.append(MarkdownContent(split))
else:
raise ValueError("Didn't closed a Python line...")

def __call__(self):
for content in self.content:
content(self.show)


class MarkdownContent:
def __init__(self, lines):
self.lines = "\n".join(lines)

def __call__(self, show):
show.markdown(self.lines)


class PythonContent:
def __init__(self, lines):
self.lines = "\n".join(lines)

def __call__(self, show):
exec(self.lines, dict(show=show), dict())
19 changes: 15 additions & 4 deletions auditorium/show.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,21 @@ def show_title(self):

## @slide decorator

def slide(self, func):
self.slide_ids.append(func.__name__)
self.slides[func.__name__] = func
return func
def slide(self, func=None, id=None):
if func is not None:
slide_id = id or func.__name__
self.slide_ids.append(slide_id)
self.slides[slide_id] = func
return func

elif id is not None:
def wrapper(func):
slide_id = id or func.__name__
self.slide_ids.append(slide_id)
self.slides[slide_id] = func
return func

return wrapper

## Binding methods

Expand Down
27 changes: 27 additions & 0 deletions auditorium/static/md/demo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Auditorium

### A demo for the "pure markdown" mode

## Static content

Static content can be added with pure markdown.

* Some _markdown_ content.
* More **markdown** content.

## And some Python

If you need interaction or advanced `auditorium` features,
simply add a code section.

```python
with show.columns(2) as cl:
text = show.text_input("World")

cl.tab()

with show.success("Message"):
show.markdown(f"Hello {text}")
```

An instance named `show` will be magically available.
7 changes: 4 additions & 3 deletions auditorium/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

def fix_indent(content, tab_size=0):
lines = content.split("\n")
min_indent = 1e50
min_indent = 1000

for l in lines:
if not l or l.isspace():
Expand All @@ -19,9 +19,10 @@ def fix_indent(content, tab_size=0):

min_indent = min(indent_size, min_indent)

lines = [" " * tab_size + l[min_indent:] for l in lines]
if min_indent < 10000:
lines = [" " * tab_size + l[min_indent:] for l in lines]

while lines and not lines[0] or lines[0].isspace():
while lines and (not lines[0] or lines[0].isspace()):
lines.pop(0)

return "\n".join(lines)
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


# TODO: Update version whenever changes
VERSION = '0.2.0'
VERSION = '0.3.0'


def get_install_requirements():
Expand Down

0 comments on commit 100711b

Please sign in to comment.