quarto-marimo

repository·main·Indexed 41 days ago

https://github.com/marimo-team/quarto-marimo

A Quarto extension that enables reactive Python, SQL, and Markdown cells within Quarto documents by compiling them into a single marimo application. It supports interactive HTML output and static exports, allowing variables defined in one cell to drive reactivity in others via the `engine: marimo` configuration.

Tokens
3.4K
Snippets
12
Records
14
Agent score
52%

What's inside quarto-marimo

  1. Upgrade from version 0.4

    main

    When migrating from version 0.4 to newer versions, you must replace the old Lua filter configuration with the new engine declaration and remove the old filters entry.

    Steps:

    1. Add engine: marimo to your YAML.
    2. Remove filters: marimo-team/marimo from your document or project YAML.
    engine: marimo
  2. Quick start with reactive Quarto pages

    main

    To create a reactive document, set the engine to marimo in your YAML header and use the {.marimo} class on your code fences. Cells within the same document share a single marimo app, allowing variables defined in one cell to drive reactivity in others.

    Note: HTML output remains interactive in the browser. For formats like PDF, cells receive server-rendered output.

    ---
    title: Reactive Quarto page
    engine: marimo
    format: html
    ---
    
    ```python {.marimo}
    import marimo as mo
    
    slider = mo.ui.slider(1, 10, 1, label="Items")
    slider
    mo.md(f"The slider is set to **{slider.value}**.")
  3. Install quarto-marimo

    main

    To use reactive Python, SQL, and Markdown cells in Quarto, install uv and Quarto, then add the extension using the Quarto CLI.

    Requirements:

    • Quarto 1.9.20 or newer
    • Python 3.10 or newer
    • marimo 0.23.16 or newer
    quarto add marimo-team/quarto-marimo
  4. Understand MarimoExecution output types

    main

    The runMarimoCompiler function returns one of two execution types:

    1. Page Execution

    Used for interactive or full-page rendering.

    • kind: "page"
    • page: A CompiledMarimoPage object.

    2. Static Execution

    Used for extracting specific content blocks.

    • kind: "static"
    • outputs: An array of StaticMarimoOutput objects. Each output contains:
      • type: One of "html", "figure", "para", "plain", or "blockquote".
      • value: The rendered string content.
      • displayCode: Boolean indicating if code should be shown.
      • code: The raw source code.
      • language: The programming language identifier.
  5. Configure interactive vs static exports in Quarto marimo

    main

    The conversion engine supports two distinct modes of operation based on the output_mode argument:

    1. Interactive Export (html):

      • Creates a kind: "page" JSON object.
      • Designed for live marimo environments where the user can interact with cells.
      • Uses compile_page to generate the interactive page structure.
    2. Static Export (non-html):

      • Creates a kind: "static" JSON object.
      • Contains an outputs field generated by render_static_page.
      • Designed for pre-rendered, non-interactive viewing.
      • Sets MARIMO_NO_JS=true to ensure the output is optimized for a static context.
  6. Configure the Python environment and dependencies

    main

    You can manage dependencies and environment settings via the document YAML:

    • pyproject: Declare browser and build dependencies using PEP 621 format.
    • header: Provide Python source that runs as a setup cell before all authored cells.
    • external-env: true: Execute the build using the active Python environment.
    • QUARTO_PYTHON: (Env Var) Choose the Python executable (defaults to python on PATH).
    • QUARTO_MARIMO_VERSION: (Env Var) Select the marimo runtime version embedded in HTML output.
    pyproject: |
      requires-python = ">=3.10"
      dependencies = ["pandas"]
    
    header: |
      import polars as pl
    
    external-env: true
  7. Use reactive SQL and Markdown cells

    main

    SQL cells use the same {.marimo} class as Python cells and can accept query and engine options. Markdown cells can also be made reactive by using the {markdown .marimo} syntax to join the page app.

    ```{sql .marimo}
    #| echo: true
    #| query: result
    
    SELECT 1 AS value
    # This markdown is now part of the reactive app
  8. Configure the marimo compiler timeout

    main

    You can control how long the marimo compiler is allowed to run by setting the QUARTO_MARIMO_TIMEOUT_SECONDS environment variable.

    • The value is interpreted as seconds.
    • If the variable is not set, not a finite number, or is less than or equal to 0, it defaults to 300,000 milliseconds (5 minutes).
    • If a timeout occurs, the process is killed with SIGTERM and an error is thrown indicating the command that timed out.
    # Example: Set timeout to 60 seconds
    export QUARTO_MARIMO_TIMEOUT_SECONDS=60
  9. Configure marimo cell options

    main

    You can control the behavior of individual reactive cells using Quarto #| options at the start of the cell. Both python {.marimo} and {python .marimo} fence forms are supported.

    Supported options for Python, SQL, and Markdown cells:

    | Option          | Default | Behavior                                                           |
    | --------------- | ------- | ------------------------------------------------------------------ |
    | `eval`          | `true`  | Execute the cell                                                   |
    | `echo`          | `false` | Render the authored source                                         |
    | `output`        | `true`  | Render the cell output                                              |
    | `server-output` | `true`  | Include build-time output before browser hydration                  |
    | `error`         | `true`  | Render execution errors. `false` stops the build                   |
    | `include`       | `true`  | Include the cell in the document                                   |
    | `editor`        | `false` | Render the marimo editor for the Python cell                       |
    | `hide-code`     | `false` | Hide source and the editor                                         |
    | `hide-output`   | `false` | Hide rendered output                                               |
    | `disabled`      | `false` | Disable the cell and its dependents                                |
    | `unparsable`    | `false` | Preserve source as a non-reactive cell                             |
    | `name`          | `_`     | Set the marimo cell name                                           |
    | `column`        | none    | Set the marimo layout column                                       |
  10. Run the marimo compiler with runMarimoCompiler()

    main

    The runMarimoCompiler function executes the marimo compilation process. It can operate in two modes:

    1. External Environment (externalEnv: true): Uses the Python interpreter specified by the QUARTO_PYTHON environment variable (defaults to python).
    2. Managed Environment (externalEnv: false): Uses uv to manage dependencies and run the compiler via a temporary environment constructed from a pyproject file.

    Options

    • moduleUrl: The URL of the module.
    • source: The source content to be processed.
    • input: The input string.
    • interactive: If true, requests html output; otherwise requests static output.
    • globalEval: If true, enables global evaluation (yes); otherwise no.
    • externalEnv: Whether to use the system/environment Python or a managed uv environment.
    • pyproject: Path to the pyproject.toml file (required when externalEnv is false).

    Return Value

    A MarimoExecution object, which is either:

    • { kind: "page"; page: CompiledMarimoPage }
    • { kind: "static"; outputs: StaticMarimoOutput[] }
    const execution = await runMarimoCompiler(quarto, {
      moduleUrl: 'file:///path/to/module',
      source: '...', 
      input: '...',
      interactive: false,
      globalEval: true,
      externalEnv: false,
      pyproject: 'pyproject.toml'
    });
  11. Identify marimo cells in markdown using containsMarimoFence

    main

    The containsMarimoFence function determines if a markdown string contains a marimo cell by scanning for specific fence patterns. It correctly handles nested markdown fences (like code blocks) to ensure that a marimo cell pattern is only matched if it is not contained within another markdown code block.

    import { containsMarimoFence } from './engine/authoring';
    
    const markdown = "```python\n# This is a normal python block\n```\n\n```python.marimo\n# This is a marimo cell\n```";
    
    const hasMarimo = containsMarimoFence(markdown);
    console.log(hasMarimo); // true
  12. Validate a QuartoMdCell as a marimo cell with isMarimoCell

    main

    The isMarimoCell function checks if a QuartoMdCell object represents a marimo cell. It validates two conditions:

    1. The cell_type.language must be one of the supported marimo languages: python, sql, markdown, marimo, python.marimo, sql.marimo, or markdown.marimo.
    2. The first line of the cell's sourceVerbatim.value must match the MARIMO_CELL_REGEX pattern.

    This is useful when processing Quarto documents to distinguish between standard code cells and marimo-specific cells.

    import { isMarimoCell } from './engine/authoring';
    import type { QuartoMdCell } from '@quarto/types';
    
    const cell: QuartoMdCell = {
      cell_type: { language: 'python.marimo' },
      sourceVerbatim: { value: '```python.marimo\nprint("hello")\n```' }
    };
    
    if (isMarimoCell(cell)) {
      // Handle as a marimo cell
    }