Skip to content

Example notebook

This notebook serves as a proof of principle for marimo-md-export.

You can view the original notebook at examples/notebook.py. The command used to convert it to a docs page is the just docs command in justfile.

import marimo as mo
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import sys

Figures

x = np.linspace(0, 4 * np.pi, 300)
fig, ax = plt.subplots(figsize=(7, 3))
ax.plot(x, np.sin(x), label=r"$\sin(x)$")
ax.plot(x, np.exp(-x / 6) * np.sin(x), label=r"$e^{-x/6}\sin(x)$", ls="--")
ax.set_xlabel("x")
ax.legend()
fig

png

Tables

df = pd.DataFrame(
    {
        "Quantity": ["Mean", "Variance", "Skewness"],
        "sin(x)": [0.0, 0.5, 0.0],
        "damped": [
            round(float(np.mean(np.exp(-x / 6) * np.sin(x))), 4),
            round(float(np.var(np.exp(-x / 6) * np.sin(x))), 4),
            None,
        ],
    }
)
df
Quantity sin(x) damped
Mean 0.0 0.0677
Variance 0.5 0.1094
Skewness 0.0

Console output

print(f"Number of points: {len(x)}")
print(f"x range: [{x[0]:.4f}, {x[-1]:.4f}]")
print(f"Mean of sin(x): {np.mean(np.sin(x)):.6f}")
Number of points: 300
x range: [0.0000, 12.5664]
Mean of sin(x): -0.000000

String output

Returning a string from a cell preserves escape sequences like as actual newlines in the exported markdown.

"Line one\nLine two\nLine three"
Line one
Line two
Line three

JSON outputs

Returning a dict or list from a cell produces a Python-style formatted output using pprint.

{"name": "damped sinusoid", "amplitude": 1.0, "decay_rate": 0.167}
{'amplitude': 1.0, 'decay_rate': 0.167, 'name': 'damped sinusoid'}
[round(float(xi), 4) for xi in x[:5]]
[0.0, 0.042, 0.0841, 0.1261, 0.1681]
{
    "experiment": "damped sinusoid",
    "parameters": {
        "amplitude": 1.0,
        "decay_rate": 0.167,
        "frequency": 1.0,
    },
    "results": {
        "samples": 300,
        "range": [0.0, 12.5664],
        "statistics": {
            "mean": 0.0,
            "variance": 0.5,
            "converged": True,
        },
    },
    "tags": ["oscillation", "damping", "physics"],
}
{'experiment': 'damped sinusoid',
 'parameters': {'amplitude': 1.0, 'decay_rate': 0.167, 'frequency': 1.0},
 'results': {'range': [0.0, 12.5664],
             'samples': 300,
             'statistics': {'converged': True, 'mean': 0.0, 'variance': 0.5}},
 'tags': ['oscillation', 'damping', 'physics']}

Errors

Cells that raise exceptions produce error output with traceback.

raise ValueError("This cell demonstrates error output handling")
Traceback (most recent call last):
  File "/tmp/marimo_2348/__marimo__cell_ZHCJ_.py", line 1, in 
    raise ValueError("This cell demonstrates error output handling")
ValueError: This cell demonstrates error output handling

exception: This cell demonstrates error output handling

Output written to sys.stderr is captured separately from stdout.

sys.stderr.write(f"Warning: computing over {len(x)} points\n")
Warning: computing over 300 points
35

SVG graphics

Inline SVG rendered via mo.Html.

mo.Html("""<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100" viewBox="0 0 200 100">
<rect x="5" y="5" width="190" height="90" fill="#4a9eff" rx="10"/>
<text x="100" y="55" text-anchor="middle" fill="white" font-size="14">SVG Image</text>
</svg>""")

SVG Image

Graphviz graphs

Graphs created with the graphviz package render as SVG and display correctly in the exported markdown.

from graphviz import Digraph

dot = Digraph()
dot.node("A", "Start")
dot.node("B", "Process")
dot.node("C", "End")
dot.edges(["AB", "BC"])
dot
Traceback (most recent call last):
  File "/home/runner/work/marimo-md-export/marimo-md-export/.venv/lib/python3.12/site-packages/graphviz/backend/execute.py", line 76, in run_check
    proc = _run_input_lines(cmd, input_lines, kwargs=kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/runner/work/marimo-md-export/marimo-md-export/.venv/lib/python3.12/site-packages/graphviz/backend/execute.py", line 96, in _run_input_lines
    popen = subprocess.Popen(cmd, stdin=subprocess.PIPE, **kwargs)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/subprocess.py", line 1026, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/lib/python3.12/subprocess.py", line 1955, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: PosixPath('dot')

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/runner/work/marimo-md-export/marimo-md-export/.venv/lib/python3.12/site-packages/marimo/_output/formatting.py", line 238, in try_format
    mimetype, data = formatter(obj)
                     ^^^^^^^^^^^^^^
  File "/home/runner/work/marimo-md-export/marimo-md-export/.venv/lib/python3.12/site-packages/marimo/_output/formatters/repr_formatters.py", line 123, in f_repr
    contents = method(include=None, exclude=None)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/runner/work/marimo-md-export/marimo-md-export/.venv/lib/python3.12/site-packages/graphviz/jupyter_integration.py", line 98, in _repr_mimebundle_
    return {mimetype: getattr(self, method_name)()
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/runner/work/marimo-md-export/marimo-md-export/.venv/lib/python3.12/site-packages/graphviz/jupyter_integration.py", line 112, in _repr_image_svg_xml
    return self.pipe(format='svg', encoding=SVG_ENCODING)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/runner/work/marimo-md-export/marimo-md-export/.venv/lib/python3.12/site-packages/graphviz/piping.py", line 104, in pipe
    return self._pipe_legacy(format,
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/runner/work/marimo-md-export/marimo-md-export/.venv/lib/python3.12/site-packages/graphviz/_tools.py", line 185, in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/home/runner/work/marimo-md-export/marimo-md-export/.venv/lib/python3.12/site-packages/graphviz/piping.py", line 121, in _pipe_legacy
    return self._pipe_future(format,
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/runner/work/marimo-md-export/marimo-md-export/.venv/lib/python3.12/site-packages/graphviz/piping.py", line 149, in _pipe_future
    return self._pipe_lines_string(*args, encoding=encoding, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/runner/work/marimo-md-export/marimo-md-export/.venv/lib/python3.12/site-packages/graphviz/backend/piping.py", line 212, in pipe_lines_string
    proc = execute.run_check(cmd, capture_output=True, quiet=quiet, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/runner/work/marimo-md-export/marimo-md-export/.venv/lib/python3.12/site-packages/graphviz/backend/execute.py", line 81, in run_check
    raise ExecutableNotFound(cmd) from e
graphviz.backend.execute.ExecutableNotFound: failed to execute PosixPath('dot'), make sure the Graphviz executables are on your systems' PATH

Mermaid diagrams

Mermaid code fences inside mo.md() cells pass through to the exported markdown and render on platforms with mermaid support (GitHub, MkDocs with pymdownx, etc.).

```mermaid
graph TD
    A[Start] --> B[Process]
    B --> C[End]
```
graph TD
    A[Start] --> B[Process]
    B --> C[End]

Admonitions

Marimo admonitions using the /// type | title syntax are automatically converted to MkDocs/Zensical-compatible !!! type "title" format during export.

!!! note "Important Information"
    This is a note admonition. It supports **bold**, *italic*, and other
    markdown formatting inside the block.

Important Information

This is a note admonition. It supports bold, italic, and other markdown formatting inside the block.

!!! tip
    Admonitions without a title also work — the title is simply omitted.

Tip

Admonitions without a title also work — the title is simply omitted.

Multiple outputs

A cell with both console output and an expression result.

print(f"Computing statistics for {len(x)} points...")
np.mean(np.sin(x))
Computing statistics for 300 points...
np.float64(-2.3684757858670008e-17)

Long line outputs

This cell produces output with very long lines to demonstrate overflow wrapping.

print(
    "A very long line that exceeds the typical container width, stretching well beyond what fits on a single line. In this case the text should scroll, not wrap! "
)
A very long line that exceeds the typical container width, stretching well beyond what fits on a single line. In this case the text should scroll, not wrap! 

You can pass --overflow scroll to the CLI to switch the global behaviour from wrapping to scrolling. Note, however, that JSON outputs (lists, dicts, tuples) won't be affected by this.

You can also control overflow on a per-cell basis.

Add # @scroll to a cell to force horizontal scrolling for its output, regardless of the global --overflow setting.

# @scroll
print(
    "A very long line that exceeds the typical container width, stretching well beyond what fits on a single line. In this case the text should scroll, not wrap! "
)
A very long line that exceeds the typical container width, stretching well beyond what fits on a single line. In this case the text should scroll, not wrap! 

Suppressing outputs

Adding # @suppress to a cell prevents its output from appearing in the exported markdown.

# @suppress
print("This is just for debugging - no need to include in the docs!")