Adding quickstart page and updating README with the same content (#174)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Josh Karpel <josh.karpel@gmail.com>
pull/185/head
Eric 1 year ago committed by GitHub
parent 09278d75cc
commit 29c5138253
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -21,6 +21,7 @@ jobs:
PLATFORM: ${{ matrix.platform }}
PYTHON_VERSION: ${{ matrix.python-version }}
PYTHONUTF8: 1 # https://peps.python.org/pep-0540/
COLORTERM: truecolor
steps:
- name: Check out repository
uses: actions/checkout@v3.2.0

@ -1,7 +1,8 @@
# Spiel
[![PyPI](https://img.shields.io/pypi/v/spiel)](https://pypi.org/project/spiel/)
[![PyPI - License](https://img.shields.io/pypi/l/spiel)](https://pypi.org/project/spiel/)
[![PyPI](https://img.shields.io/pypi/v/spiel)](https://pypi.org/project/spiel)
[![PyPI - License](https://img.shields.io/pypi/l/spiel)](https://pypi.org/project/spiel)
[![Docs](https://img.shields.io/badge/docs-exist-brightgreen)](https://www.spiel.how)
[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/JoshKarpel/spiel/main.svg)](https://results.pre-commit.ci/latest/github/JoshKarpel/spiel/main)
[![codecov](https://codecov.io/gh/JoshKarpel/spiel/branch/main/graph/badge.svg?token=2sjP4V0AfY)](https://codecov.io/gh/JoshKarpel/spiel)
@ -24,6 +25,37 @@ $ spiel demo present
![The first slide of the demo deck](https://raw.githubusercontent.com/JoshKarpel/spiel/main/docs/assets/demo.svg)
![The demo deck in "deck view"](https://raw.githubusercontent.com/JoshKarpel/spiel/main/docs/assets/deck.svg)
## Quick Start
If you want to jump right in,
install Spiel (`pip install spiel`),
create a file called `deck.py`,
and copy this code into it:
```python
from rich.console import RenderableType
from spiel import Deck, present
deck = Deck(name="Your Deck Name")
@deck.slide(title="Slide 1 Title")
def slide_1() -> RenderableType:
return "Your content here!"
if __name__ == "__main__":
present(__file__)
```
That is the most basic Spiel presentation you can make.
To present the deck, run `python deck.py`.
You should see:
![Barebones slide](https://raw.githubusercontent.com/JoshKarpel/spiel/main/docs/assets/quickstart_basic.svg)
Check out the [Quick Start tutorial](https://www.spiel.how/quickstart) to continue!
## Documentation
To learn more about Spiel, take a look at the [documentation](https://www.spiel.how).

@ -0,0 +1,136 @@
<svg class="rich-terminal" viewBox="0 0 750 538.0" xmlns="http://www.w3.org/2000/svg">
<!-- Generated with Rich https://www.textualize.io -->
<style>
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Regular"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff") format("woff");
font-style: normal;
font-weight: 400;
}
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Bold"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff") format("woff");
font-style: bold;
font-weight: 700;
}
.spieldocs-matrix {
font-family: Fira Code, monospace;
font-size: 20px;
line-height: 24.4px;
font-variant-east-asian: full-width;
}
.spieldocs-title {
font-size: 18px;
font-weight: bold;
font-family: arial;
}
.spieldocs-r1 { fill: #e1e1e1 }
.spieldocs-r2 { fill: #c5c8c6 }
.spieldocs-r3 { fill: #939393 }
.spieldocs-r4 { fill: #e1e1e1;font-weight: bold }
</style>
<defs>
<clipPath id="spieldocs-clip-terminal">
<rect x="0" y="0" width="731.0" height="487.0" />
</clipPath>
<clipPath id="spieldocs-line-0">
<rect x="0" y="1.5" width="732" height="24.65"/>
</clipPath>
<clipPath id="spieldocs-line-1">
<rect x="0" y="25.9" width="732" height="24.65"/>
</clipPath>
<clipPath id="spieldocs-line-2">
<rect x="0" y="50.3" width="732" height="24.65"/>
</clipPath>
<clipPath id="spieldocs-line-3">
<rect x="0" y="74.7" width="732" height="24.65"/>
</clipPath>
<clipPath id="spieldocs-line-4">
<rect x="0" y="99.1" width="732" height="24.65"/>
</clipPath>
<clipPath id="spieldocs-line-5">
<rect x="0" y="123.5" width="732" height="24.65"/>
</clipPath>
<clipPath id="spieldocs-line-6">
<rect x="0" y="147.9" width="732" height="24.65"/>
</clipPath>
<clipPath id="spieldocs-line-7">
<rect x="0" y="172.3" width="732" height="24.65"/>
</clipPath>
<clipPath id="spieldocs-line-8">
<rect x="0" y="196.7" width="732" height="24.65"/>
</clipPath>
<clipPath id="spieldocs-line-9">
<rect x="0" y="221.1" width="732" height="24.65"/>
</clipPath>
<clipPath id="spieldocs-line-10">
<rect x="0" y="245.5" width="732" height="24.65"/>
</clipPath>
<clipPath id="spieldocs-line-11">
<rect x="0" y="269.9" width="732" height="24.65"/>
</clipPath>
<clipPath id="spieldocs-line-12">
<rect x="0" y="294.3" width="732" height="24.65"/>
</clipPath>
<clipPath id="spieldocs-line-13">
<rect x="0" y="318.7" width="732" height="24.65"/>
</clipPath>
<clipPath id="spieldocs-line-14">
<rect x="0" y="343.1" width="732" height="24.65"/>
</clipPath>
<clipPath id="spieldocs-line-15">
<rect x="0" y="367.5" width="732" height="24.65"/>
</clipPath>
<clipPath id="spieldocs-line-16">
<rect x="0" y="391.9" width="732" height="24.65"/>
</clipPath>
<clipPath id="spieldocs-line-17">
<rect x="0" y="416.3" width="732" height="24.65"/>
</clipPath>
<clipPath id="spieldocs-line-18">
<rect x="0" y="440.7" width="732" height="24.65"/>
</clipPath>
</defs>
<rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="748" height="536" rx="8"/><text class="spieldocs-title" fill="#c5c8c6" text-anchor="middle" x="374" y="27">Your&#160;Deck&#160;Name</text>
<g transform="translate(26,22)">
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
<circle cx="44" cy="0" r="7" fill="#28c840"/>
</g>
<g transform="translate(9, 41)" clip-path="url(#spieldocs-clip-terminal)">
<rect fill="#1e1e1e" x="0" y="1.5" width="219.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="219.6" y="1.5" width="512.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="25.9" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="50.3" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="74.7" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="99.1" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="123.5" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="147.9" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="172.3" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="196.7" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="221.1" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="245.5" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="269.9" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="294.3" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="318.7" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="343.1" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="367.5" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="391.9" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="416.3" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="440.7" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="465.1" width="366" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="366" y="465.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="378.2" y="465.1" width="353.8" height="24.65" shape-rendering="crispEdges"/>
<g class="spieldocs-matrix">
<text class="spieldocs-r1" x="0" y="20" textLength="219.6" clip-path="url(#spieldocs-line-0)">Your&#160;content&#160;here!</text><text class="spieldocs-r2" x="732" y="20" textLength="12.2" clip-path="url(#spieldocs-line-0)">
</text><text class="spieldocs-r2" x="732" y="44.4" textLength="12.2" clip-path="url(#spieldocs-line-1)">
</text><text class="spieldocs-r2" x="732" y="68.8" textLength="12.2" clip-path="url(#spieldocs-line-2)">
</text><text class="spieldocs-r2" x="732" y="93.2" textLength="12.2" clip-path="url(#spieldocs-line-3)">
</text><text class="spieldocs-r2" x="732" y="117.6" textLength="12.2" clip-path="url(#spieldocs-line-4)">
</text><text class="spieldocs-r2" x="732" y="142" textLength="12.2" clip-path="url(#spieldocs-line-5)">
</text><text class="spieldocs-r2" x="732" y="166.4" textLength="12.2" clip-path="url(#spieldocs-line-6)">
</text><text class="spieldocs-r2" x="732" y="190.8" textLength="12.2" clip-path="url(#spieldocs-line-7)">
</text><text class="spieldocs-r2" x="732" y="215.2" textLength="12.2" clip-path="url(#spieldocs-line-8)">
</text><text class="spieldocs-r2" x="732" y="239.6" textLength="12.2" clip-path="url(#spieldocs-line-9)">
</text><text class="spieldocs-r2" x="732" y="264" textLength="12.2" clip-path="url(#spieldocs-line-10)">
</text><text class="spieldocs-r2" x="732" y="288.4" textLength="12.2" clip-path="url(#spieldocs-line-11)">
</text><text class="spieldocs-r2" x="732" y="312.8" textLength="12.2" clip-path="url(#spieldocs-line-12)">
</text><text class="spieldocs-r2" x="732" y="337.2" textLength="12.2" clip-path="url(#spieldocs-line-13)">
</text><text class="spieldocs-r2" x="732" y="361.6" textLength="12.2" clip-path="url(#spieldocs-line-14)">
</text><text class="spieldocs-r2" x="732" y="386" textLength="12.2" clip-path="url(#spieldocs-line-15)">
</text><text class="spieldocs-r2" x="732" y="410.4" textLength="12.2" clip-path="url(#spieldocs-line-16)">
</text><text class="spieldocs-r2" x="732" y="434.8" textLength="12.2" clip-path="url(#spieldocs-line-17)">
</text><text class="spieldocs-r3" x="0" y="459.2" textLength="732" clip-path="url(#spieldocs-line-18)">────────────────────────────────────────────────────────────</text><text class="spieldocs-r2" x="732" y="459.2" textLength="12.2" clip-path="url(#spieldocs-line-18)">
</text><text class="spieldocs-r3" x="0" y="483.6" textLength="366" clip-path="url(#spieldocs-line-19)">Your&#160;Deck&#160;Name&#160;|&#160;Slide&#160;1&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="spieldocs-r3" x="378.2" y="483.6" textLength="353.8" clip-path="url(#spieldocs-line-19)">2022-12-17&#160;03:31&#160;PM&#160;&#160;&#160;[1&#160;/&#160;1]</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.0 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 100 KiB

@ -0,0 +1,14 @@
from rich.console import RenderableType
from spiel import Deck, present
deck = Deck(name="Your Deck Name")
@deck.slide(title="Slide 1 Title")
def slide_1() -> RenderableType:
return "Your content here!"
if __name__ == "__main__":
present(__file__)

@ -1,5 +1,6 @@
#!/usr/bin/env python
import os
from collections.abc import Iterable
from datetime import datetime
from functools import partial
@ -15,7 +16,9 @@ from spiel.app import SpielApp
ROOT_DIR = Path(__file__).resolve().parent.parent
ASSETS_DIR = ROOT_DIR / "docs" / "assets"
DECK_FILE = ROOT_DIR / "spiel" / "demo" / "demo.py"
# lie to Rich to make sure the screenshots are always generated in full color
os.environ["TERMCOLOR"] = "truecolor"
def take_reproducible_screenshot(app: App[object]) -> str:
@ -46,10 +49,10 @@ async def auto_pilot(pilot: Pilot, name: str, keys: Iterable[str]) -> None:
await pilot.app.action_quit()
def take_screenshot(name: str, size: tuple[int, int], keys: Iterable[str]) -> None:
def take_screenshot(name: str, deck_file: Path, size: tuple[int, int], keys: Iterable[str]) -> None:
SpielApp(
deck_path=DECK_FILE,
watch_path=DECK_FILE.parent,
deck_path=deck_file,
watch_path=deck_file.parent,
show_messages=False,
fixed_time=datetime(year=2022, month=12, day=17, hour=15, minute=31, second=42),
).run(
@ -59,6 +62,11 @@ def take_screenshot(name: str, size: tuple[int, int], keys: Iterable[str]) -> No
)
take_screenshot(name="demo", size=(130, 35), keys=())
take_screenshot(name="deck", size=(130, 35), keys=("d", "right", "down"))
take_screenshot(name="help", size=(110, 35), keys=("?",))
demo_deck = ROOT_DIR / "spiel" / "demo" / "demo.py"
quickstart_deck = ROOT_DIR / "docs" / "examples" / "quickstart.py"
take_screenshot(name="demo", deck_file=demo_deck, size=(130, 35), keys=())
take_screenshot(name="deck", deck_file=demo_deck, size=(130, 35), keys=("d", "right", "down"))
take_screenshot(name="help", deck_file=demo_deck, size=(110, 35), keys=("?",))
take_screenshot(name="quickstart_basic", deck_file=quickstart_deck, size=(60, 20), keys=())
take_screenshot(name="quickstart_code", deck_file=demo_deck, size=(140, 45), keys=("right",))

@ -0,0 +1,133 @@
# Quick Start
## The Most Basic Deck
After installing Spiel (`pip install spiel`),
create a file called `deck.py` and copy this code into it:
```python
from rich.console import RenderableType
from spiel import Deck, present
deck = Deck(name="Your Deck Name")
@deck.slide(title="Slide 1 Title")
def slide_1() -> RenderableType:
return "Your content here!"
if __name__ == "__main__":
present(__file__)
```
That is the most basic Spiel presentation you can make.
To present the deck, run `python deck.py`.
You should see:
![Barebones slide](./assets/quickstart_basic.svg)
In the example above, you first create a `Deck` and provide the name of your presentation.
Then you create slides by decorating functions with `@deck.slide()`, providing the title of the slide.
The slide function can return anything that
[Rich can render](https://rich.readthedocs.io/en/stable/console.html#printing);
that return value will be displayed as the slide's content when you present it.
The order of the `@deck.slide()`-decorated functions in your file is the order in which they will appear in your presentation.
Running `python deck.py` started the presentation because of the call to `present()` in the
[`if __name__ == "__main__"` block](https://stackoverflow.com/questions/419163/what-does-if-name-main-do).
To see available keybindings for doing things like moving between slides,
press `?` to open the help view, which should look like this:
![Help view](./assets/help.svg)
## Making Richer Slides
You can make your slides a lot prettier, of course.
As mentioned above, Spiel renders its slides using Rich, so you can bring in Rich functionality to spruce up your slides.
Let's explore some advanced features by recreating one of the slides from the demo deck.
Update your `deck.py` file with these imports and utility definitions:
``` python
import inspect
from textwrap import dedent
from rich.box import SQUARE
from rich.console import RenderableType
from rich.layout import Layout
from rich.markdown import Markdown
from rich.padding import Padding
from rich.panel import Panel
from rich.style import Style
from rich.syntax import Syntax
from spiel import Deck, Slide, present
from spiel.deck import Deck
SPIEL = "[Spiel](https://github.com/JoshKarpel/spiel)"
RICH = "[Rich](https://rich.readthedocs.io/)"
def pad_markdown(markup: str) -> RenderableType:
return Padding(Markdown(dedent(markup), justify="center"), pad=(0, 5))
```
And then paste this code in to your `deck.py` file below your first slide:
```python
@deck.slide(title="Decks and Slides")
def code() -> RenderableType:
markup = f"""\
## Decks are made of Slides
Here's the code for `Deck` and `Slide`!
The source code is pulled directly from the definitions via [inspect.getsource](https://docs.python.org/3/library/inspect.html#inspect.getsource).
({RICH} supports syntax highlighting, so {SPIEL} does too!)
"""
root = Layout()
upper = Layout(pad_markdown(markup), size=len(markup.split("\n")) + 1)
lower = Layout()
root.split_column(upper, lower)
def make_code_panel(obj: type) -> RenderableType:
lines, line_number = inspect.getsourcelines(obj)
return Panel(
Syntax(
"".join(lines),
lexer="python",
line_numbers=True,
start_line=line_number,
),
box=SQUARE,
border_style=Style(dim=True),
height=len(lines) + 2,
)
lower.split_row(
Layout(make_code_panel(Deck)),
Layout(make_code_panel(Slide)),
)
return root
```
We start out by creating our text content and setting up some `Layout`s, which will let us divide the slide space into chunks.
Then, we create the `make_code_panel` function to take some lines of code from the `Deck` and `Slide` classes
and put them in a syntax-highlighted `Panel` (with some additional fancy Rich styling).
Finally, we add the code panels to our layout side-by-side and return `root`, the top-level `Layout`, from the function.
Run `python deck.py` again and go to the second slide (press `?` if you're not sure how to navigate!):
![Demo Code Slide](./assets/quickstart_code.svg)
Check out the source code of the [demo deck](https://github.com/JoshKarpel/spiel/blob/main/spiel/demo/demo.py)
for more inspiration on ways to use Rich to make your slides beautiful!
Spiel provides a `spiel` CLI tool to make this easy:
- Present the demo deck in your terminal by running `spiel demo present`.
- View the source in your terminal with `spiel demo source`.
- Copy it to use as a starting point with `spiel demo copy <destination>`.

@ -70,6 +70,7 @@ extra:
nav:
- Introduction: index.md
- quickstart.md
- presenting.md
- gallery.md
- contributing.md

Loading…
Cancel
Save