pdg XML → PDF

Guide

Default layout

How containers lay out their contents without an explicit wrapper — bare text becomes a paragraph, text and blocks interleave, and a generic container collapses to a single child.

Most containers don't make you spell out how their contents are arranged. Drop text or elements inside and the container imposes a sensible default layout, the same way a block element in CSS lays out whatever it wraps.

Bare text becomes a paragraph

Text dropped straight into a container is built into a single <text>, so inline tags like <b>, <i>, <a>, and <font> work right away. This is why <box padding="10px">Just text</box> needs no inner <text>, and a table <cell>Total</cell> needs no wrapper either. A container with no text at all draws nothing.

Text and blocks interleave

You can mix text and elements freely. Each block element stands on its own, and each run of text (with its inline markup) between blocks becomes its own paragraph, in document order. A <box> holding Hello <b>World</b><rect/>Another line lays out as a paragraph (“Hello World”), then the rule, then a second paragraph (“Another line”) — the text beside the block is kept, not lost. The whitespace sitting between two block tags isn't content, so it never becomes an empty paragraph. (See the editable example below.)

Generic containers collapse to one child

A generic container — <box>, <padding>, <inline>, a table <cell>, the page body — reduces those flow children to a single element:

  • nothing → draws nothing;
  • one child → used as-is, unwrapped;
  • several → stacked in a plain column: no gap, and each child stretched to the container's width (the cross axis).

The layout containers don't collapse — they keep every child and arrange them by their own rules.

Where it applies

  • Interleaving (text and blocks side by side) happens in every container: <box>, <padding>, the page body, a <cell>, and the layout containers <vertical>, <horizontal>, and <stack>.
  • Collapsing to one child is what the generic wrappers above do; the layout containers instead keep their children as a list to position.

Bare text honours <defaults>

A synthesized paragraph is built as if you had written a <text>, so a <defaults><text font= size=/> block (see Defaults) flows into it — including one placed just before the text or wrapping its container. Set the document's default face once and every bare-text cell, box, and list item picks it up.

When to reach past it

The implicit column has no gap and stretches its children across the cross axis. The moment you need spacing between stacked items, a row instead of a column, or a different cross-axis alignment, use an explicit <vertical> or <horizontal> with gap, main, and cross — the default layout is the terse path, not a replacement for the layout containers.

Try it — edit the source Open in Playground
<document version="2.0">
  <config>
    <page size="A6" margin="22px" />
    <defaults>
      <text size="11" />
    </defaults>
  </config>
  <pages>
    <page>
      <vertical gap="12px">

        <!-- Text and a block interleave: two paragraphs around the rule. -->
        <box background="#f3f1ea" radius="6px" padding="10px">
          Bare text — no <b>&lt;text&gt;</b> wrapper needed.
          <rect height="2px" fill="#c4341f" style:margin="6px 0" />
          A second paragraph, after the divider.
        </box>

        <!-- The same interleaving in a layout container. An authored <vertical>
             shrinks to its content, so cross="stretch" makes the rule span it. -->
        <vertical gap="4px" cross="stretch">
          Intro line.
          <rect height="2px" fill="#1b1a17" />
          Body line, with <i>emphasis</i>.
        </vertical>

        <!-- Bare text drives table cells too. -->
        <table columns="2* 1*" border="0.5px" border-color="#d4cdbd" cell-padding="7px">
          <row><cell>Bare text in a cell</cell><cell>£40</cell></row>
          <row><cell>Another</cell><cell>£12</cell></row>
        </table>

      </vertical>
    </page>
  </pages>
</document>