# Text and Markdown cells
source: https://docs.chalk.ai/docs/notebook-text

## Write notebook narrative as plain text or Markdown and interpolate values from other cells.

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.





