Skip to content

Commit 65e4429

Browse files
dmadisettipre-commit-ci[bot]mscolnick
authored
feat: enforce markdown formatting on save (#6969)
Fixes #6458 ## 📝 Summary Adds lint rule and codegen change that enforces markdown dedent. Following front end convention, the following markdown is expected: ```python mo.md( """ A multiline statement. """ ) ``` ```python mo.md("A single liner (can also be triple)") ``` ```python mo.md( "A very very very very very very very very very very very very very long single liner (can also be triple)" ) ``` **note**: This is a noisy PR since examples are formatted. Look at commits standalone: [test: Add in tests for md check](fba4a46) [feat: Add markdown tidy rule and auto formatting](b4a4360) [tidy: refresh examples](6985ebd) [docs: update documentation rules](6aaaa4a) --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Myles Scolnick <[email protected]>
1 parent a810dac commit 65e4429

File tree

125 files changed

+2427
-2233
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

125 files changed

+2427
-2233
lines changed

.github/workflows/test_cli.yaml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,22 @@ jobs:
166166
uv add pytest pytest-asyncio
167167
uv pip install marimo*whl
168168
169-
- name: Check notebook quality with marimo check
169+
- name: Check example quality with marimo check
170170
shell: bash
171171
run: |
172172
echo "Checking examples directory..."
173173
uv run marimo check --ignore-scripts --strict examples/**.py
174+
175+
- name: Check tutorial quality with marimo check
176+
shell: bash
177+
run: |
178+
echo "Checking tutorials..."
179+
uv run marimo check --ignore-scripts --fix \
180+
marimo/_tutorials/**.py >> /dev/null \
181+
|| echo "Errors expected"
182+
# Fail if there's a git diff
183+
if [[ -n "$(git status --porcelain marimo/_tutorials)" ]]; then
184+
echo "marimo check found issues in tutorials."
185+
git --no-pager diff marimo/_tutorials
186+
exit 1
187+
fi

development_docs/adding_lint_rules.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ if __name__ == "__main__":
183183

184184
#### b) Add snapshot test
185185

186-
Add to `tests/_lint/test_runtime_errors_snapshot.py`:
186+
Add to `tests/_lint/test_snapshot.py`:
187187

188188
```python
189189
def test_your_rule_snapshot():
@@ -280,7 +280,7 @@ uv run hatch run test:test tests/_lint
280280
uv run hatch run test:test tests/_lint/test_your_rule.py
281281

282282
# Update snapshots if needed
283-
uv run hatch run test:test tests/_lint/test_runtime_errors_snapshot.py --snapshot-update
283+
uv run hatch run test:test tests/_lint/test_snapshots.py --snapshot-update
284284
```
285285

286286
## Rule Implementation Guidelines
@@ -359,7 +359,7 @@ tests/_lint/
359359
├── snapshots/ # Expected outputs
360360
│ └── your_rule_name_errors.txt
361361
├── test_your_rule.py # Unit tests
362-
└── test_runtime_errors_snapshot.py # Snapshot tests
362+
└── test_snapshots.py # Snapshot tests
363363
```
364364

365365
## Documentation Requirements

docs/guides/lint_rules/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ These are style and formatting issues.
5353
| [MF004](rules/empty_cells.md) | empty-cells | Empty cells that can be safely removed. | ⚠️ |
5454
| [MF005](rules/sql_parse_error.md) | sql-parse-error | SQL parsing errors during dependency analysis ||
5555
| [MF006](rules/misc_log_capture.md) | misc-log-capture | Miscellaneous log messages during processing ||
56+
| [MF007](rules/markdown_indentation.md) | markdown-indentation | Markdown cells in `mo.md()` should be dedented. | 🛠️ |
5657

5758
## Legend
5859

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# MF007: markdown-indentation
2+
3+
**Formatting** 🛠️ Fixable
4+
5+
MF007: Markdown strings in `mo.md()` should be dedented.
6+
7+
## What it does
8+
9+
Checks cells containing `mo.md()` calls to see if the markdown string
10+
content has unnecessary leading whitespace that should be removed.
11+
12+
## Why is this bad?
13+
14+
Indented markdown strings:
15+
16+
- Are harder to read when viewing the source code
17+
- Produce larger diffs when making changes
18+
- Don't match the standard marimo formatting style
19+
- Can be confusing when the indentation doesn't reflect the markdown structure
20+
21+
## Examples
22+
23+
**Problematic:**
24+
25+
```python
26+
mo.md(
27+
r"""
28+
# Title
29+
30+
Some content here.
31+
"""
32+
)
33+
```
34+
35+
**Solution:**
36+
37+
```python
38+
mo.md(r"""
39+
# Title
40+
41+
Some content here.
42+
""")
43+
```
44+
45+
**Note:** This fix is automatically applied with `marimo check --fix`.
46+
47+
## References
48+
49+
- [Understanding Errors](https://docs.marimo.io/guides/understanding_errors/)
50+
- [Best Practices](https://docs.marimo.io/guides/best_practices/)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# MF007: markdown-indentation
2+
3+
**Formatting** 🛠️ Fixable
4+
5+
MF007: Markdown strings in `mo.md()` should be properly indented.
6+
7+
## What it does
8+
9+
Checks cells containing `mo.md()` calls to see if the markdown string
10+
content has unnecessary leading whitespace that should be removed.
11+
12+
## Why is this bad?
13+
14+
Indented markdown strings:
15+
- Are harder to read when viewing the source code
16+
- Produce larger diffs when making changes
17+
- Don't match the standard marimo formatting style
18+
- Can be confusing when the indentation doesn't reflect the markdown structure
19+
20+
## Examples
21+
22+
**Problematic:**
23+
```python
24+
mo.md(
25+
r"""
26+
# Title
27+
28+
Some content here.
29+
"""
30+
)
31+
```
32+
33+
**Solution:**
34+
```python
35+
mo.md(r"""
36+
# Title
37+
38+
Some content here.
39+
""")
40+
```
41+
42+
**Note:** This fix is automatically applied with `marimo check --fix`.
43+
44+
## References
45+
46+
- [Understanding Errors](https://docs.marimo.io/guides/understanding_errors/)
47+
- [Best Practices](https://docs.marimo.io/guides/best_practices/)
48+

examples/ai/chat/anthropic_example.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import marimo
1010

11-
__generated_with = "0.15.5"
11+
__generated_with = "0.17.2"
1212
app = marimo.App(width="medium")
1313

1414

@@ -20,13 +20,11 @@ def _():
2020

2121
@app.cell
2222
def _(mo):
23-
mo.md(
24-
r"""
23+
mo.md(r"""
2524
# Using Anthropic
2625
2726
This example shows how to use [`mo.ui.chat`](https://docs.marimo.io/api/inputs/chat.html#marimo.ui.chat) to make a chatbot backed by Anthropic.
28-
"""
29-
)
27+
""")
3028
return
3129

3230

@@ -76,7 +74,9 @@ def _(key, mo):
7674

7775
@app.cell
7876
def _(mo):
79-
mo.md("""Access the chatbot's historical messages with [`chatbot.value`](https://docs.marimo.io/api/inputs/chat.html#accessing-chat-history).""")
77+
mo.md(
78+
"""Access the chatbot's historical messages with [`chatbot.value`](https://docs.marimo.io/api/inputs/chat.html#accessing-chat-history)."""
79+
)
8080
return
8181

8282

examples/ai/chat/bedrock_example.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
import marimo
1111

12-
__generated_with = "0.15.5"
12+
__generated_with = "0.17.2"
1313
app = marimo.App(width="medium")
1414

1515

@@ -21,17 +21,15 @@ def _():
2121

2222
@app.cell(hide_code=True)
2323
def _(mo):
24-
mo.md(
25-
r"""
24+
mo.md(r"""
2625
# AWS Bedrock Chat Example
2726
2827
This example demonstrates using AWS Bedrock with marimo's chat interface.
2928
3029
AWS Bedrock provides access to foundation models from leading AI companies like Anthropic, Meta, and others.
3130
3231
⚠️ **Note:** You'll need an AWS account with access to the AWS Bedrock service and the specific model you want to use.
33-
"""
34-
)
32+
""")
3533
return
3634

3735

@@ -227,8 +225,7 @@ def create_chat(config_form):
227225

228226
@app.cell
229227
def _(mo):
230-
mo.md(
231-
r"""
228+
mo.md(r"""
232229
## Notes on AWS Bedrock Usage
233230
234231
1. **Model Access**: You need to request access to the specific models you want to use in the AWS Bedrock console.
@@ -243,8 +240,7 @@ def _(mo):
243240
- That your AWS credentials are configured correctly
244241
- That you have requested model access in the AWS Bedrock console
245242
- That you're using a region where the selected model is available
246-
"""
247-
)
243+
""")
248244
return
249245

250246

examples/ai/chat/custom.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import marimo
99

10-
__generated_with = "0.15.5"
10+
__generated_with = "0.17.2"
1111
app = marimo.App(width="medium")
1212

1313

@@ -19,15 +19,13 @@ def _():
1919

2020
@app.cell(hide_code=True)
2121
def _(mo):
22-
mo.md(
23-
"""
24-
# Custom chatbot
25-
26-
This example shows how to make a custom chatbot: just supply a function that takes two arguments,
27-
`messages` and `config`, and returns the chatbot's response. This response can be any object; it
28-
doesn't have to be a string!
29-
"""
30-
)
22+
mo.md("""
23+
# Custom chatbot
24+
25+
This example shows how to make a custom chatbot: just supply a function that takes two arguments,
26+
`messages` and `config`, and returns the chatbot's response. This response can be any object; it
27+
doesn't have to be a string!
28+
""")
3129
return
3230

3331

examples/ai/chat/dagger_code_interpreter.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
import marimo
1313

14-
__generated_with = "0.15.5"
14+
__generated_with = "0.17.2"
1515
app = marimo.App(width="medium")
1616

1717

@@ -25,15 +25,13 @@ def _():
2525

2626
@app.cell(hide_code=True)
2727
def _(mo):
28-
mo.md(
29-
"""
30-
# Chatbot code-interpreter with [Dagger](https://dagger.io/)
28+
mo.md("""
29+
# Chatbot code-interpreter with [Dagger](https://dagger.io/)
3130
32-
This example shows how to create a code-interpreter that executes code using [Dagger](https://dagger.io/) so the code is run in an isolated container.
31+
This example shows how to create a code-interpreter that executes code using [Dagger](https://dagger.io/) so the code is run in an isolated container.
3332
34-
This example requires Docker running on your computer.
35-
"""
36-
)
33+
This example requires Docker running on your computer.
34+
""")
3735
return
3836

3937

examples/ai/chat/deepseek_example.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import marimo
1010

11-
__generated_with = "0.15.5"
11+
__generated_with = "0.17.2"
1212
app = marimo.App(width="medium")
1313

1414

@@ -20,13 +20,11 @@ def _():
2020

2121
@app.cell(hide_code=True)
2222
def _(mo):
23-
mo.md(
24-
r"""
25-
# Using DeepSeek
23+
mo.md(r"""
24+
# Using DeepSeek
2625
27-
This example shows how to use [`mo.ui.chat`](https://docs.marimo.io/api/inputs/chat/?h=mo.ui.chat) to make a chatbot backed by [Deepseek](https://deepseek.com/).
28-
"""
29-
)
26+
This example shows how to use [`mo.ui.chat`](https://docs.marimo.io/api/inputs/chat/?h=mo.ui.chat) to make a chatbot backed by [Deepseek](https://deepseek.com/).
27+
""")
3028
return
3129

3230

@@ -88,7 +86,9 @@ def _(key, mo):
8886

8987
@app.cell(hide_code=True)
9088
def _(mo):
91-
mo.md("""Access the chatbot's historical messages with [`chatbot.value`](https://docs.marimo.io/api/inputs/chat.html#accessing-chat-history).""")
89+
mo.md(
90+
"""Access the chatbot's historical messages with [`chatbot.value`](https://docs.marimo.io/api/inputs/chat.html#accessing-chat-history)."""
91+
)
9292
return
9393

9494

0 commit comments

Comments
 (0)