Appearance
Document Structure
Every Press document follows a consistent structure: a root element, a document definition containing pages, and optional sections for flows, styles, data, and assets. This guide covers how to set up the skeleton of your document and configure pages.
The <press> Root Element
All Press documents begin with <press> and end with </press>. This is the top-level container for everything in your template.
xml
<press>
<!-- All other elements go here -->
</press>Inside <press>, you can place the following top-level elements in any order:
<document>-- the schematic of how pages are structured to create the output PDF<pages>-- reusable page definitions<flows>-- variable sized content which breaks across pages<styles>-- style rules and aliases<data>-- changeable data used to modify parts of the document or create figures, tables, etc.<assets>-- fonts, images, colors, and constant data<components>-- reusable custom elements
The <document> Element
The <document> element defines the sequence of pages in your PDF. At a minimum, it contains <page> elements (either inline or references to named definitions) and controls the order they appear.
xml
<press>
<document>
<page width="21cm" height="29.7cm" page-margin="2cm">
<h1>Quarterly Report</h1>
<p>Prepared by Greenfield Analytics Ltd.</p>
</page>
</document>
</press>Setting Defaults on <document>
You can set default attributes on <document> that all child pages will inherit. This avoids repeating the same dimensions and margins on every page.
xml
<press>
<document width="21cm" height="29.7cm" page-margin="2cm">
<page>
<h1>Cover Page</h1>
</page>
<page>
<h1>Chapter One</h1>
<p>The story begins here...</p>
</page>
</document>
</press>Both pages inherit the A4 dimensions and 2cm margin. Any page can override these defaults by specifying its own values:
xml
<document width="21cm" height="29.7cm" page-margin="2cm">
<page>
<p>This page uses the defaults (A4, 2cm margin).</p>
</page>
<page page-margin="1cm">
<p>This page overrides the margin to 1cm.</p>
</page>
</document>Page Formats
Press supports standard paper sizes through the format attribute, so you do not need to remember exact dimensions.
xml
<page format="A4" page-margin="2cm">
<p>Standard A4 page.</p>
</page>The supported formats and their dimensions are:
| Format | Dimensions |
|---|---|
| A0 | 84.1cm x 118.9cm |
| A1 | 59.4cm x 84.1cm |
| A2 | 42cm x 59.4cm |
| A3 | 29.7cm x 42cm |
| A4 | 21cm x 29.7cm |
| A5 | 14.85cm x 21cm |
| A6 | 10.5cm x 14.85cm |
| A7 | 7.4cm x 10.5cm |
| A8 | 5.2cm x 7.4cm |
| A9 | 3.7cm x 5.2cm |
| A10 | 2.6cm x 3.7cm |
Custom Dimensions
For non-standard page sizes, specify width and height directly. Values can be in points (pt), centimetres (cm), millimetres (mm) or inches (in). There are 72 points and 2.54 centimetres to the inch, so the same page can be written in whichever unit reads most naturally.
xml
<!-- US Letter size -->
<page width="8.5in" height="11in" page-margin="1in">
<p>US Letter page in inches.</p>
</page>
<!-- The same page in points -->
<page width="612pt" height="792pt" page-margin="72pt">
<p>US Letter page in points.</p>
</page>
<!-- Custom square page -->
<page width="15cm" height="15cm" page-margin="1cm">
<p>A square format, useful for social media or booklets.</p>
</page>Landscape Orientation
Press has three methods of switching orientation:
xml
<!-- Landscape A4 - switched width and height values -->
<page width="29.7cm" height="21cm" />
<!-- Landscape A4 -->
<page format="A4" orientation="landscape" />
<!-- Also Landscape A4 -->
<page format="A4-landscape" />Here is a complete example producing a landscape certificate:
xml
<press>
<document>
<page format="A4" orientation="landscape" page-margin="2cm">
<frame v-align="center" h-align="center" width="100%" height="100%">
<h1 text-align="center" font-size="36pt">Certificate of Completion</h1>
<p text-align="center" font-size="18pt">Awarded to Jane Doe</p>
<p text-align="center" font-size="14pt">For outstanding performance in Q3 2025</p>
<p text-align="center" font-size="12pt" font-color="grey">
Greenfield Analytics Ltd.
</p>
</frame>
</page>
</document>
</press>Page Margins
The page-margin attribute sets uniform spacing around the content area. You can also control individual sides:
xml
<!-- Uniform margin -->
<page format="A4" page-margin="2cm">
...
</page>
<!-- Different margins per side -->
<page format="A4"
page-margin-top="3cm"
page-margin-bottom="2cm"
page-margin-left="2.5cm"
page-margin-right="2.5cm">
...
</page>A page in Press is a special kind of frame, so you can also use padding instead of page-margin. However, page-margin is more intuitive when thinking about physical page layout.
Page Definitions with <pages>
When a page layout is used more than once, define it in the <pages> element and reference it by name from <document>. This keeps your document structure clean and avoids duplication.
xml
<press>
<pages>
<title-page>
<frame v-align="center" h-align="center" width="100%" height="100%">
<h1 text-align="center" font-size="fit">{{ data.title }}</h1>
<p text-align="center" font-color="grey">{{ data.subtitle }}</p>
</frame>
</title-page>
<body-page>
<frame margin-bottom="0.5cm" font-color="grey" font-size="9pt">
{{ data.title }}
</frame>
<flow name="body" />
</body-page>
</pages>
<document format="A4" page-margin="2cm">
<title-page />
<body-page repeat="true" flow="body" />
</document>
<flows>
<body>
<h2>Introduction</h2>
<p>This report examines trends in residential property values
across the northern region over the past five years.</p>
</body>
</flows>
<data>
<title>Regional Property Market Analysis</title>
<subtitle>Prepared by Northbrook Consulting Group</subtitle>
</data>
</press>The <pages> element can also specify default attributes, just like <document>:
xml
<pages format="A4" page-margin="2cm">
<cover-page>
...
</cover-page>
<content-page>
...
</content-page>
</pages>A page name must not be shared with a component — the same name would refer to a page inside <document> and to a component everywhere else. Built-in elements such as <p> and <h1> are components too, so they are unavailable as page names. Papermill rejects the document with message Page '…' has the same name as a component. Page and component names must be unique. A -page suffix keeps page names clear of both.
Dynamic Page Selection from Data
When generating documents from data, you may need to switch between different page layouts. Use a data reference in the name attribute of a <page> tag to select the page definition dynamically.
xml
<press>
<pages>
<summary-page format="A4" page-margin="2cm">
<h1>Summary</h1>
<flow name="body" />
</summary-page>
<detail-page format="A4" page-margin="1.5cm">
<h2>Detailed Findings</h2>
<flow name="body" />
</detail-page>
</pages>
<document>
<repeat data="data.sections" item="section">
<page name="{{ section['page-type'] }}" />
</repeat>
</document>
<data type="json">
{
"sections": [
{ "page-type": "summary-page" },
{ "page-type": "detail-page" },
{ "page-type": "detail-page" },
{ "page-type": "summary-page" }
]
}
</data>
</press>This produces four pages, alternating between the two layouts as the data dictates.
Required Flows
A page reference in <document> can specify required flows using the flow attribute. If any of the listed flows are empty, that page is skipped entirely.
xml
<document format="A4" page-margin="2cm">
<cover-page />
<appendix-page flow="appendix" />
<body-page repeat="true" flow="body" />
</document>In this example, appendix-page only appears if the appendix flow has content. The cover-page always appears, and body-page repeats until the body flow is exhausted.
Complete Example: Multi-Page Business Report
Here is a full document structure combining page definitions, defaults, and repeating pages:
xml
<press>
<document width="21cm" height="29.7cm" page-margin="2cm">
<cover-page />
<repeat flow="body">
<odd-page />
<even-page />
</repeat>
</document>
<pages>
<cover-page page-margin="3cm">
<frame v-align="center" width="100%" height="100%">
<h1 font-size="fit">{{ data['report-title'] }}</h1>
<frame height="1cm" />
<p font-size="14pt" font-color="#555555">{{ data.company }}</p>
<p font-size="12pt" font-color="#888888">{{ data.date }}</p>
</frame>
</cover-page>
<odd-page flow="body">
<frame direction="row" margin-bottom="0.5cm">
<frame width="fill" font-size="9pt" font-color="grey">
{{ data['report-title'] }}
</frame>
<frame font-size="9pt" font-color="grey" text-align="right">
<page-number />
</frame>
</frame>
<flow name="body" />
</odd-page>
<even-page flow="body">
<frame direction="row" margin-bottom="0.5cm">
<frame width="fill" font-size="9pt" font-color="grey">
<page-number />
</frame>
<frame font-size="9pt" font-color="grey" text-align="right">
{{ data.company }}
</frame>
</frame>
<flow name="body" />
</even-page>
</pages>
<flows>
<body>
<h2>Executive Summary</h2>
<p>This report provides a comprehensive analysis of operational
performance across all divisions for the fiscal year.</p>
<h2>Financial Overview</h2>
<p>Total revenue increased by 12% compared to the prior year,
driven primarily by growth in the consulting division.</p>
</body>
</flows>
<data>
<report-title>Annual Operations Report</report-title>
<company>Meridian Solutions Group</company>
<date>January 2026</date>
</data>
</press>This produces a cover page followed by alternating odd/even body pages, each with its own header layout and automatic page numbering.