Skip to content

Instantly share code, notes, and snippets.

@algal
Last active August 30, 2025 21:28
Show Gist options
  • Save algal/ab60aa0ee2b546068b4e7ee0589399be to your computer and use it in GitHub Desktop.
Save algal/ab60aa0ee2b546068b4e7ee0589399be to your computer and use it in GitHub Desktop.
notebook formats and converters

Notebook Formats & Conversion Tools

This document summarizes some popular, public notebook formats (Org, Jupyter, Markdown, Python variants) and the tools which interconvert them.

Notable omissions:

  • Wolfram notebooks. My impression is the proprietary platform offer mature export to many formats but not ipynb. There is no mature, widely used too for export to ipynb, not are there great import tools afaict.
  • SolveIt platform. Not publicly released yet. But I suspect it will support excellent ipynb interop. 😉

Epistemic status: Moderate confidence. This is based mostly on AI research on 2025-08-30 but it passes spot checks and matches my prior background knowledge, which covers many of these technologies.)

Formats

  • ipynb: Jupyter Notebook JSON, supports code cells, markdown cells, outputs.
  • Org-mode: Emacs Org with #+BEGIN_SRC blocks (optionally with org-babel headers for sessions).
  • Markdown with fenced code blocks: Standard Markdown, plus ``` fences with language tags.
  • py:percent: Jupytext’s Python format with # %% cell markers (and # %% [markdown]).
  • Marimo-compatible Python: Structured .py notebooks using marimo.App() and @app.cell.
  • Plain Python: Conventional Python script with top-level statements and functions.

Tools and Packages

Tool / Package Converts From / To Strengths Limitations
Pandoc Org ↔ ipynb; Org ↔ Markdown; ipynb ↔ Markdown Broad format support; CLI-friendly; integrates with Emacs No execution; outputs not included; limited fidelity for complex Org
Jupytext ipynb ↔ py:percent; ipynb ↔ Markdown; ipynb ↔ Org (via Pandoc) Round-trip editing; pairing with notebooks; CLI Org support relies on Pandoc; outputs not included
ox-ipynb (Emacs) Org → ipynb Preserves Org formatting; can embed outputs from executed Org Babel; runs inside Emacs One-way only; single kernel language; not all Org features supported
code-cells.el (Emacs) ipynb ↔ script (py:percent by default; configurable to Org via Pandoc) Edit notebooks as text in Emacs; configurable backend By default strips outputs; configuration required for Org
Marimo CLI ipynb ↔ marimo .py; py:percent ↔ marimo .py; export marimo .py → flat Python script Notebooks as Python modules; reactive DAG execution; exports clean scripts Marimo .py is “eccentric” Python; less natural for direct script editing
Plain Emacs Org Export Org → Markdown, LaTeX, etc. (not ipynb) Stable, built into Org Not tailored for Jupyter integration

Notes

  • Outputs: Only ox-ipynb (and Marimo, when exporting) include execution outputs. Pandoc/Jupytext focus on source only.
  • Round-trip editing: Jupytext and code-cells support keeping text files and ipynb in sync.
  • CLI integration: Pandoc, Jupytext, and Marimo all provide command-line tools callable from Emacs.
  • Paradigms: Org and py:percent are closer to linear script styles; Marimo defines a DAG of cells with decorators, better for reactive notebooks but less natural as a plain CLI script.

Diagram

graph LR
  %% Nodes
  Org["Org-mode (.org)"]
  IPYNB["Jupyter Notebook (.ipynb)"]
  MD["Markdown (fenced code)"]
  PYPCT["Python py:percent"]
  MARIMO["Marimo-compatible Python"]
  PY["Plain Python script"]

  %% Pandoc
  Org -- Pandoc --> IPYNB
  IPYNB -- Pandoc --> Org
  Org -- Pandoc --> MD
  MD -- Pandoc --> Org
  IPYNB -- Pandoc --> MD
  MD -- Pandoc --> IPYNB

  %% Jupytext
  IPYNB -- Jupytext --> PYPCT
  PYPCT -- Jupytext --> IPYNB
  IPYNB -- Jupytext --> MD
  MD -- Jupytext --> IPYNB
  IPYNB -. Jupytext+Pandoc .-> Org
  Org -. Jupytext+Pandoc .-> IPYNB

  %% Emacs: ox-ipynb (one-way)
  Org -- ox-ipynb --> IPYNB

  %% Emacs: code-cells
  IPYNB -- code-cells --> PYPCT
  PYPCT -- code-cells --> IPYNB
  IPYNB -. code-cells+Pandoc .-> Org
  Org -. code-cells+Pandoc .-> IPYNB

  %% Marimo
  IPYNB -- marimo convert --> MARIMO
  MARIMO -- marimo export ipynb --> IPYNB
  PYPCT -- marimo convert --> MARIMO
  MARIMO -- export flat script --> PY
  PY -. convert (single-cell) .-> MARIMO
Loading

Legend:

  • Solid arrows: native/typical conversions. Dashed arrows: supported but indirect or config-dependent.

  • Includes outputs when exporting:

    • ox-ipynb (Org → ipynb) can include Org-Babel results.
    • marimo export ipynb includes executed outputs.
  • Round-trip text workflows:

    • Jupytext (ipynb ↔ py:percent / Markdown) and code-cells (ipynb ↔ py:percent; configurable ipynb ↔ Org via Pandoc).
  • Paradigm note:

    • Marimo .py is structured (cells as @app.cell); use “export flat script” to produce conventional Python for CLIs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment