Use Text cells to add explanations, notes, and summaries alongside your code and results. Write plain text when you want to show the source verbatim, or use Markdown for formatted headings, lists, links, and live values from the notebook session.

Plain text

Plain Text cells display exactly what you write. Double braces such as {{ revenue }} remain literal text. Use Markdown when you want an expression to resolve to its current value.

Markdown

Markdown cells render formatted prose. You can combine that prose with values computed by Python or SQL cells, as the order summary below demonstrates.

Template interpolation in Markdown

Every {{ expression }} site in the prose is evaluated against the same Python session the code cells use and rendered in place, so narrative text stays consistent with the data beside it.

There is no separate templating language. What sits between the braces is ordinary Python: a variable, an attribute, an index, or a call. Result variables are in scope under their own names, so {{ my_sql_result["col"][0] }} works with no namespace prefix. Three forms cover the syntax:

  • {{ expression }} renders the value.
  • {{ expression:format_spec }} applies a Python format spec, exactly like an f-string: {{ ratio:.1% }} renders 12.3%, and {{ total:,.2f }} renders 1,234,567.89. Only the first colon at the top level of the site splits expression from format spec, so colons inside brackets or string literals (a slice like {{ xs[0:2] }}, for instance) are left alone.
  • \{{ escapes a literal {{, for prose that needs double braces verbatim.

This Markdown cell uses completed and revenue from the Python example. The saved output substitutes the order count and formats revenue to two decimal places.

Scalars render inline, DataFrames render as a bounded preview table, and an expression that raises renders an inline error marker at its own site while the rest of the document still renders. A site in a cell that has not run yet shows its source as inline code. Resolved values are saved with the cell’s output, so a shared notebook renders its interpolated values without a live session — you only need one to refresh them. Two limits are worth knowing: only Markdown cells render resolved values, since plain Text cells show their source verbatim, and chart objects are not rendered at a template site, so display those from a Python cell.

Dependencies and refresh

Markdown cells with template sites take part as pure consumers. The names their expressions read become dependencies on the cells that produce those names, so Auto mode re-renders prose when its upstream cells re-run, Cell + upstream on a Markdown cell runs the producers it reads from before rendering, and editing an upstream cell marks the prose stale like any other dependent. The expressions never bind names, so nothing can depend on a Markdown cell in turn.

See Running cells and shortcuts for the notebook’s run modes.