marimo/_tutorials/markdown_format.md
By default, marimo notebooks are stored as pure Python files. However,
you can also store and edit marimo notebooks as .md files, letting you
work on prose-heavy marimo notebooks in your editor of choice.
Make sure to look at the markdown source code of this tutorial!
To edit a markdown notebook, use
$ marimo edit notebook.md
To run it as an app, use
$ marimo run notebook.md
You can export marimo notebooks that are stored as Python to the markdown format by running the following command:
$ marimo export md notebook.py > notebook.md
When you do need to create a Python cell in the markdown format, you can use a special code block:
```python {.marimo}
import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4])
```
This will create the following cell:
import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4])
plt.gca()
As long as your code block contains the word marimo in a brace, like
{marimo}, or {.marimo note="Whatever you want"}, marimo will treat it as a Python cell.
mo tricks and tipsYou can break up markdown into multiple cells by using an empty html tag <!---->:
View the source of this notebook to see how this cell was created.
<!---->You can still hide cell code in markdown notebooks:
```python {.marimo hide_code="true"}
form = (
# ...
# Just something a bit more complicated
# you might not want to see in the editor.
# ...
)
form
```
form = (
mo.md('''
**Just how great is markdown?.**
{markdown_is_awesome}
{marimo_is_amazing}
''')
.batch(
markdown_is_awesome=mo.ui.text(label="How much do you like markdown?", placeholder="It is pretty swell 🌊"),
marimo_is_amazing=mo.ui.slider(label="How much do you like marimo?", start=0, stop=11, value=11),
)
.form(show_clear_button=True, bordered=False)
)
form
and disable cells too:
```python {.marimo disabled="true"}
print("This code cell is disabled, there should be no output!")
```
print("This code cell is disabled, there should be no output!")
Additionally, marimo knows when your code has a syntax issue:
```python {.marimo}
print("This code cell has a syntax error"
```
and on notebook save, will annotate the cell for you:
```python {.marimo unparseable="true"}
print("This code cell has a syntax error"
```
print("This code cell has a syntax error"
marimo's markdown support treats markdown as just plain old markdown. This
means that trying to use string interpolation (like this f"{'🍃' * 7}") will
just give you the raw string. This lets you clearly delineate what values are
supposed to be computed, and what values are static. To interpolate Python
values, just use a Python cell:
mo.md(f"""Like so: {"🍃" * 7}""")
mo.md(r"""
### Limitations on conversion
Whenever you try to implement a cell block like this:
````md
```python {.marimo}
mo.md("This is a markdown cell")
```
````
The markdown format will know to automatically keep this as markdown. However,
some ambiguous cases can't be converted to markdown like this:
""")
mo.md("""
This is a markdown cell with an execution block in it
```python {.marimo}
# Too ambiguous to convert
```
""")
It's not likely that you'll run into this issue, but rest assured that marimo is working behind the scenes to keep your notebooks unambiguous and clean as possible.
<!---->Multicolumn mode works, but the first cell in a column must be a python cell in order to specify column start and to save correctly:
```python {.marimo column="1"}
print("First cell in column 1")
```
Since the markdown notebook really is just markdown, you can't import from a markdown notebook cells like you can in a python notebook; but you can still give your cells a name:
```python {.marimo name="maybe"}
# 🎵 Hey, I just met you, and this is crazy
```
# But here's my `cell_id`, so call me, `maybe` 🎶
You can also run SQL queries in markdown cells through marimo, using a sql code block. For instance:
```sql {.marimo}
SELECT GREATEST(x, y), SQRT(z) from uniformly_random_numbers
```
The resultant distribution may be surprising! 🎲1
SELECT GREATEST(a, b), SQRT(c) from uniformly_random_numbers
In this SQL format, Python variable interpolation in SQL queries occurs automatically. Additionally, query results can be assigned to a dataframe with the query attribute.
For instance, here's how to create a random uniform distribution and assign it to the dataframe uniformly_random_numbers used above:
```sql {.marimo query="uniformly_random_numbers" hide_output="true"}
SELECT i.range::text AS id,
random() AS x,
random() AS y,
random() AS z
FROM
-- Note sample_count comes from the slider below!
range(1, {sample_count.value + 1}) i;
```
You can learn more about other SQL use in the SQL tutorial (marimo tutorial sql)
sample_count = mo.ui.slider(1, 1000, value=1000, label="Sample Count")
sample_count
SELECT i.range::text AS id,
random() AS a,
random() AS b,
random() AS c
FROM range(1, {sample_count.value + 1}) i;
The markdown format is supposed to lower the barrier for writing text heavy documents, it's not meant to be a full replacement for the Python notebook format. You can always convert back to a Python notebook if you need to:
$ marimo convert my_marimo.md > my_marimo.py
Be sure to checkout the markdown.py tutorial (marimo tutorial markdown) for
more information on to type-set and render markdown in marimo.
import marimo as mo
The general distributions should be the same ↩