Skip to content

API

imprenta.Project is the public surface; the command line and the manager are thin layers over it. Catalogs and targets are what it hands back.

from imprenta import Project

project = Project.find()               # the repo that holds catalog.*.yaml
for target in project.targets():       # (catalog, product, variant)
    project.build(target)
errors, warnings = project.check()

imprenta.Project

A folder holding content/, templates/ and one or more catalog.<name>.yaml.

Everything the command line and the manager do goes through one of these: find the catalogs, list targets, build them, check the rules.

find classmethod

find(start: Path | str | None = None) -> Project

The nearest ancestor of start (default: the cwd) holding a catalog.*.yaml.

rel

rel(path: Path) -> str

A path relative to the project root when it is inside it, else as given.

catalog_path

catalog_path(name: str) -> Path

Where catalog.<name>.yaml lives, whether or not it exists.

catalog_names

catalog_names() -> list[str]

The <name> of every catalog.<name>.yaml in the root, sorted.

catalog

catalog(name: str) -> Catalog

One catalog, parsed (cached on the file's mtime); empty if absent.

catalogs

catalogs() -> dict[str, Catalog]

Every catalog, parsed, by name.

content_path

content_path(name: str) -> Path

Where a content file lives; a name is its path under content/ without .md.

content_names

content_names() -> list[str]

Every content file's name, sorted (hidden folders such as .obsidian/ skipped).

content_label

content_label(name: str) -> str

The short name a glossary prints for a content file: its label, or one derived from the name.

word_count

word_count(name: str) -> int

Words in a content file's prose, ignoring front matter and author notes.

product_words

product_words(cat: Catalog, product: str) -> int

Words across every content file a product's parts resolve to.

theme_template

theme_template(theme: str) -> Path

templates/<theme>.html; raises FileNotFoundError if the theme has none.

targets

targets(only=None, tag: str | None = None) -> list[Target]

Every target the catalogs subscribe, narrowed by a variant filter and/or a tag.

targets_since

targets_since(
    commit: str | None, only=None, tag: str | None = None
) -> list[Target]

Targets a change set since commit affects; everything if the commit is unknown.

affected

affected(
    changed, only=None, tag=None, old_cats=None
) -> list[Target]

Targets a set of changed paths affects, judged against the current catalogs (and old_cats, if given).

spec_targets

spec_targets(spec: str) -> list[Target]

Targets a spec names: <catalog>, <product> or <catalog>/<product>, each optionally .<variant>.

build

build(
    target: Target,
    *,
    pdf=True,
    preview=False,
    force=False,
    log=print,
) -> Path

Build one target and return its output path; skipped when up to date unless force.

pdf=False stops at the HTML; preview adds the Paged.js polyfill to it for a live browser preview.

build_many

build_many(
    targets,
    *,
    force=False,
    jobs: int | None = None,
    log=print,
) -> list[Path]

Build several targets in parallel; returns their output paths in order.

check

check() -> tuple[list[str], list[str]]

Validate content and catalogs against the rules: (errors, warnings), each a list of messages.

doctor

doctor()

[(tool, where it was found or None, how to get it)] for every external tool.

Pandoc, node, pagedjs-cli, Chrome or Chromium, and the theme fonts.

imprenta.Catalog

One parsed catalog. Pure over its data plus the project's content folder.

defaults property

defaults: dict

The defaults section: publishing fields every product inherits.

products property

products: dict

The products section: name to definition, as written.

groups property

groups: dict

The groups section: name to ordered list of content names.

recipes property

recipes: dict

The recipes section: name to the shape (theme, parts) products share.

strings property

strings: dict

The strings section: reader-facing labels for the generated parts and templates.

term_columns property

term_columns: dict[str, list[str]]

Role -> header aliases for the glossary, the catalog's over the defaults.

rendering property

rendering: dict

The rendering section with variants and bundles always present.

products is accepted as the old name of bundles.

variants property

variants: dict

Render variants by name: {renderer, size, palette}.

bundles property

bundles: dict

Named groups of variants a sales channel ships together.

default_variant property

default_variant: str | None

The variant a bare target name means, if the catalog sets one.

resolve_variant

resolve_variant(name: str | None = None) -> str

name, else the catalog's default; raises KeyError for an unknown one.

variant_renderer

variant_renderer(variant: str) -> str

pdf or epub for a variant (pdf when unstated).

variant_layers

variant_layers(variant: str) -> list[Path]

The css layers a variant adds: size + palette for pdf, optional palette for epub.

variant_meta

variant_meta(variant: str) -> dict

Pandoc metadata the HTML templates use to link the variant's css layers.

variant_filter

variant_filter(
    variant: str | None = None, bundle: str | None = None
) -> list[str] | None

Variant names selected by a --variant / --bundle option, or None for all.

product_def

product_def(product: str) -> dict | None

A product's full definition: its recipe's fields (with $name filled in) under its own. None if the product does not exist.

plan

plan(product: str) -> dict

A product's publishing plan: defaults with the product's fields on top. variants falls back to every rendering variant; tags to [].

theme

theme(product: str) -> str

The product's theme name, from its definition or recipe, else the default.

part_entries

part_entries(product: str) -> list[tuple[str, dict]]

The product's parts list as (name, settings) pairs, before groups are expanded.

resolve_parts

resolve_parts(product: str) -> list[tuple[str, dict]]

Expand a product's parts: groups in place, generated parts kept, content names dropped when their file is missing or is an empty placeholder (only comments), since an empty part would still start a page of its own.

content_names

content_names(product: str) -> list[str]

The content files a product renders, in order (generated parts left out).

render_row

render_row(
    product: str, variant: str | None = None
) -> dict

Everything in the catalog that changes one rendered file (not whether it exists): the resolved parts with settings, the theme, strings, glossary columns, the product's status/version, and the variant's definition. Content (and its front matter) is tracked by file mtime instead.

output_path

output_path(product: str, variant: str) -> Path

Flat output: output/....

imprenta.Target

Bases: NamedTuple

One thing to build: a product of a catalog in one render variant.

key property

key: str

catalog/product/variant, the stable id a manifest or stamp records.