Quickstart¶
TypTable builds Typst table markup from DataFrame-like data. The usual
workflow is:
- Create a
TypTablefrom your data. - Add labels, formatting, styling, and table options with chained method calls.
- Call
to_typst()to render the final Typst string.
Most configuration methods return the current table instance, so calls can be chained fluently.
Basic Table¶
import polars as pl
from typ_tables import TypTable
df = pl.DataFrame(
{
"product": ["Apples", "Bananas", "Pears"],
"region": ["North", "South", "North"],
"revenue": [1200.5, 950.0, 1432.25],
"margin": [0.42, 0.38, 0.45],
"units": [105, 98, 121],
}
)
typst = (
TypTable(df, rowname_col="product")
.tab_header("Sales by Product", subtitle="2026")
.tab_stubhead("Product")
.cols_label(
revenue="Revenue",
margin="Margin",
units="Units",
)
.fmt_currency(columns="revenue", currency="USD")
.fmt_percentage(columns="margin", decimals=1)
.fmt_integer(columns="units")
.to_typst()
)
typst is a string containing Typst markup. Write it to a .typ file and
include that file from your Typst document.
Selecting Columns¶
Many methods accept a columns argument. You can select columns by name, index,
list, or Narwhals selector.
from narwhals import selectors as ncs
from typ_tables import TypTable, locators, style
table = TypTable(df, rowname_col="product")
# Select one column by name.
table = table.fmt_currency(columns="revenue", currency="USD")
# Select multiple columns by name.
table = table.cols_label({"revenue": "Revenue", "margin": "Margin"})
# Select one column by position.
table = table.cols_hide(columns=1)
# Select multiple columns by position.
table = table.fmt_number(columns=[2, 3], decimals=2)
# Select columns by dtype using Narwhals selectors.
table = table.tab_style(
locator=locators.LocBody(columns=ncs.numeric()),
cell=style.CellStyle(align="right"),
)
Column positions refer to the source data columns. Column labels set with
cols_label() do not change the source column names used by selectors.
Column Spanners¶
Use tab_spanner() to add grouped header cells above one or more columns. By
default, directly selected columns are moved together so the spanner can cover a
contiguous block.
table = (
TypTable(df, rowname_col="product")
.tab_spanner("Financials", columns=["revenue", "margin"])
.fmt_currency(columns="revenue", currency="USD")
.fmt_percentage(columns="margin", decimals=1)
)
Set id_ when you want to reference a spanner later. Existing spanners can be
selected with the spanners argument to create a higher-level grouped header.
table = (
TypTable(df, rowname_col="product")
.tab_spanner("Financials", columns=["revenue", "margin"], id_="financials")
.tab_spanner("Activity", columns="units", id_="activity")
.tab_spanner("Sales", spanners=["financials", "activity"])
)
Pass gather=False if you want to preserve the current column order.
Selecting Rows¶
Formatting and body/stub styling methods can also accept a rows argument. You
can select rows by index, a list of indices, or a Narwhals expression.
import narwhals as nw
from typ_tables import TypTable, locators, style
table = TypTable(df, rowname_col="product")
# Select one row by position.
table = table.fmt_number(columns="revenue", rows=0, decimals=0)
# Select multiple rows by position.
table = table.fmt_number(columns="revenue", rows=[0, 2], decimals=0)
# Select rows with a Narwhals expression.
table = table.tab_style(
locator=locators.LocBody(rows=nw.col("margin") > 0.4),
text=style.TextStyle(weight="bold"),
)
Row selectors are evaluated against the original data. This means you can style or format based on values before formatting changes how those values are shown.
Combining Row and Column Selectors¶
Use both rows and columns when you want to target specific cells.
import narwhals as nw
from typ_tables import TypTable, locators, style
table = (
TypTable(df, rowname_col="product")
.tab_style(
locator=locators.LocBody(
columns="revenue",
rows=nw.col("region") == "North",
),
cell=style.CellStyle(fill="rgb(240, 248, 255)"),
)
)
This targets only the revenue cells for rows where region is "North".
Table Options¶
Table options change defaults for the whole rendered Typst table. Use them for
layout-level settings such as cell padding, table stroke, and row/column
gutters. Use tab_style() when you need to style a specific table region
instead.
from typ_tables import Sides, TypTable
table = (
TypTable(df, rowname_col="product")
.set_table_inset(Sides(x="8pt", y="4pt"))
.set_table_stroke("0.6pt + gray")
.set_gutter(row_gutter="3pt", column_gutter="10pt")
)
If you want to start from Typst's baseline table styling instead of
typ-tables' defaults, call clear_defaults() before applying your own table
options and style rules.