Skip to content

Commit

Permalink
feat: add pymdown blocks support to embed with marimo playground (#24)
Browse files Browse the repository at this point in the history
* feat: add pymdown blocks support to embed with marimo playground

* release docs
  • Loading branch information
mscolnick authored Jan 31, 2025
1 parent 9bd2143 commit af38d82
Show file tree
Hide file tree
Showing 11 changed files with 697 additions and 50 deletions.
6 changes: 6 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,9 @@ Serve the documentation:
```bash
pixi run docs
```

Lint and format:

```bash
pixi run -e lint ruff format
```
57 changes: 57 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ pixi add mkdocs-marimo

Create reactive and interactive Python blocks in your markdown files using [marimo](https://github.com/marimo-team/marimo).

### Embedding inline HTML components

This uses code fences to embed marimo components as [marimo islands](https://docs.marimo.io/guides/exporting/?h=#embed-marimo-outputs-in-html-using-islands).

````markdown
```python {marimo}
import marimo as mo
Expand All @@ -33,6 +37,59 @@ mo.md(f"Hello, **{name.value or '__'}**!")
```
````

### Embedding the marimo playground

For an easy way to embed marimo notebooks or applications, we recommend embedding the marimo playground. This feature uses `pymdownx.blocks` to embed marimo notebooks in your MkDocs documentation, creating iframes that render the marimo playground.

````markdown
/// marimo-embed
height: 400px
mode: run

```python
@app.cell
def __():
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y = np.sin(x)

plt.figure(figsize=(8, 4))
plt.plot(x, y)
plt.title('Sine Wave')
plt.xlabel('x')
plt.ylabel('sin(x)')
plt.grid(True)
plt.gca()
return
///
````

Available options for `marimo-embed`:

- `height`: Named sizes (`small`, `medium`, `large`, `xlarge`, `xxlarge`) or custom pixel values (e.g. `500px`) (default: medium)
- `mode`: read, edit (default: read)
- `app_width`: wide, full, compact (default: wide)

You can also embed marimo files directly:

````markdown
/// marimo-embed-file
filepath: path/to/your/file.py
height: 400px
mode: read
show_source: true
///
````

Additional options for `marimo-embed-file`:

- `filepath`: path to the marimo file to embed (required)
- `show_source`: true, false (default: true) - whether to show the source code below the embed

## Examples

Checkout the [documentation](https://marimo-team.github.io/mkdocs-marimo) for more examples.

## Contributions welcome
Expand Down
204 changes: 204 additions & 0 deletions docs/getting-started/blocks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
# Embedding marimo Notebooks with the Playground

This guide covers the second approach to using marimo in your documentation: embedding full marimo notebooks using the marimo playground, [like in our own documentation](https://docs.marimo.io/api/inputs/button/). This approach is ideal when you want to:

- Show complete, multi-cell notebooks
- Allow users to edit and experiment with the code
- Embed existing .py notebooks

If you're looking for simpler, inline code examples, check out the [Quick Start](quick-start.md) guide's section on inline code.

This feature uses `pymdownx.blocks` to embed marimo notebooks in your MkDocs documentation, creating iframes that render the marimo playground.

## Setup

To use the marimo playground, you need to install the `pymdown-extensions` package.

```bash
pip install mkdocs-marimo pymdown-extensions
```

## Basic Example

Here's a simple example of embedding a marimo notebook using blocks:

````markdown
/// marimo-embed
height: 400px
mode: read
app_width: wide

```python
@app.cell
def __():
import marimo as mo

name = mo.ui.text(placeholder="Enter your name", debounce=False)
name
return

@app.cell
def __():
mo.md(f"Hello, **{name.value or '__'}**!")
return
```

///
````

/// marimo-embed
height: 400px
mode: read
app_width: wide

```python
@app.cell
def __():
import marimo as mo

name = mo.ui.text(placeholder="Enter your name", debounce=False)
name
return

@app.cell
def __():
mo.md(f"Hello, **{name.value or '__'}**!")
return
```

///

## Interactive Plot Example

Here's an example with an interactive plot:

````markdown
/// marimo-embed
height: 800px
mode: read
app_width: wide

```python
@app.cell
def __():
import marimo as mo
import numpy as np
import matplotlib.pyplot as plt

# Create interactive sliders
freq = mo.ui.slider(1, 10, value=2, label="Frequency")
amp = mo.ui.slider(0.1, 2, value=1, label="Amplitude")

mo.hstack([freq, amp])
return

@app.cell
def __():
# Plot the sine wave
x = np.linspace(0, 10, 1000)
y = amp.value * np.sin(freq.value * x)

plt.figure(figsize=(10, 6))
plt.plot(x, y)
plt.title('Interactive Sine Wave')
plt.xlabel('x')
plt.ylabel('y')
plt.grid(True)
plt.gca()
return
```

///
````

/// marimo-embed
height: 800px
mode: read
app_width: wide

```python
@app.cell
def __():
import marimo as mo
import numpy as np
import matplotlib.pyplot as plt

# Create interactive sliders
freq = mo.ui.slider(1, 10, value=2, label="Frequency")
amp = mo.ui.slider(0.1, 2, value=1, label="Amplitude")

mo.hstack([freq, amp])
return

@app.cell
def __():
# Plot the sine wave
x = np.linspace(0, 10, 1000)
y = amp.value * np.sin(freq.value * x)

plt.figure(figsize=(10, 6))
plt.plot(x, y)
plt.title('Interactive Sine Wave')
plt.xlabel('x')
plt.ylabel('y')
plt.grid(True)
plt.gca()
return
```

///

## Example with Hidden Code

Here's an example that hides the code:

/// marimo-embed
height: 400px
mode: read
app_width: wide
include_code: false

```python
@app.cell
def __():
import marimo as mo
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 10, 100)
y = np.sin(x)
plt.plot(x, y)
plt.title('Simple Sine Wave')
plt.gca()
return
```

///

## Configuration Options

### marimo-embed

| Option | Description | Values |
| --- | --- | --- |
| `height` | Controls the height of the embed | - Named sizes: `small` (300px), `medium` (400px), `large` (600px),<br> `xlarge` (800px), `xxlarge` (1000px)<br>- Custom size: Any pixel value (e.g. `500px`) |
| `mode` | Controls the interaction mode | - `read`: Read-only view (default)<br>- `edit`: Allows editing the code |
| `app_width` | Controls the width of the marimo app | - `wide`: Standard width (default)<br>- `full`: Full width<br>- `compact`: Narrow width |
| `include_code` | Controls whether code is included in the embed | - `true`: Show code (default)<br>- `false`: Hide code |

### marimo-embed-file

The `marimo-embed-file` block is used to embed existing marimo files:

/// marimo-embed-file
filepath: getting-started/inlined.py
height: 600px
mode: read
show_source: true
///

| Option | Description | Default |
| --- | --- | --- |
| `filepath` | Path to the marimo file to embed | Required |
| `show_source` | Whether to show the source code below the embed | `true` |
| `include_code` | Controls whether code is included in the embed | `true` |
22 changes: 22 additions & 0 deletions docs/getting-started/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,25 @@ mo.md(f"Change the slider value: {slider}")
This will render a marimo cell that displays the source code and shows the output, but is not interactive in the browser (overriding the global `is_reactive` setting).

Remember that options specified in individual code fences will override the global settings for that specific cell.

## Releasing (for maintainers)

To release a new version:

1. Bump the version:

```bash
hatch version patch # or minor/major
git add pyproject.toml
git commit -m "chore: bump version to $(hatch version --no-color)"
git push origin main
```

2. Create and push a tag:

```bash
git tag $(hatch version --no-color)
git push origin $(hatch version --no-color)
```

This will trigger the GitHub Actions workflow to build and publish the package to PyPI.
Loading

0 comments on commit af38d82

Please sign in to comment.