Skip to content

Template reference

このページはまだ日本語になっていません。本文は英語のままですが、内容は同じものです。

このページの本文は docs/engine/README.md.生成されているのは the page index below.

ソースを見る

The complete authorable surface of the Shojiku engine, one page per feature (MDN-style): what you can write in templates.yml, what each key means, its defaults, and the diagnostics it can produce. This is the human- and machine-readable source for "what syntax exists"; keep it accurate against the code (see the curation rules in ../README.md).

These pages are not on the MCP wire. An agent talking to shojiku-mcp gets the initialize instructions, the bundled examples (list_examples / get_example / resources), capabilities, and validate's diagnostics — working documents and machine-checkable answers, not this reference. Serving the reference itself is open work.

Feature availability per engine build is machine-checkable: shojiku capabilities prints the key list, and each page notes its capability keys. Template authors targeting one engine build can ignore them — they exist so GUIs/SDKs can gate features across engine versions.

The development-facing companion features.md carries the implemented-capability inventory and the decision log — that a feature exists and why it is shaped that way; the pages here carry only how to author it. It lives in the repository only and is not part of this rendered reference; the reader-facing tour of what the engine does is the site's own Features page.

A minimal template

yaml
page: { size: A4, margin: 25 }
sections:
  body:
    type: flow
    items:
      - type: text
        text: "Hello {customer.name}"

Full file structure (bands, bodies, styles registry): template.md.

Rendering a template

bash
# PDF (the core command)
shojiku render --templates templates.yml --params params.json \
  --definitions definitions.yml --output out.pdf     # --output - writes to stdout

# Static + data checks, diagnostics as JSON (definitions/params optional)
shojiku validate --templates templates.yml --params params.json

# Per-page preview PNGs ({page} is replaced by the 1-based page number)
shojiku preview --templates templates.yml --params params.json \
  --output "page-{page}.png" --scale 2.0            # 2.0 px/pt ≈ 144 dpi

# The resolved layout tree + box index as JSON (GUI/AI surface)
shojiku inspect --templates templates.yml --params params.json

# This build's feature keys (no inputs needed)
shojiku capabilities

Useful defaults on render / preview / inspect:

  • --lang <id> selects the locale (default: the template defaults.locale, then ja-JP); --locale-dir / --font-dir (repeatable) locate the packs, adding to $SHOJIKU_LOCALE_DIR / $SHOJIKU_FONT_DIR then ./packs/{locale,fonts}. See fonts.md.
  • --font-pack <id> (repeatable) loads a font pack in addition to the locale's own fonts.uses — how a pack made by shojiku font add is used without rewriting the locale. See fonts.md.
  • A font pack whose faces are pinned (sha256 + url:) but absent is downloaded into $SHOJIKU_CACHE_DIR before rendering; --offline refuses instead, and --font-fetch-allow <host> trusts an extra source. Rendering itself never uses the network. See fonts.md.
  • --assets-dir is what image src: paths resolve against (default: the template file's directory). Asset policy: --asset-mode open|bundled-only, --allow/deny-dynamic-image <id>.
  • Diagnostics print to stderr; validate exits non-zero on errors.

Try the bundled example:

bash
shojiku render --templates examples/business/receipt-ja/templates.yml \
  --params examples/business/receipt-ja/params.json \
  --definitions examples/business/receipt-ja/definitions.yml --output receipt.pdf
# or via the Docker image (`make docker-build` builds the local
# `shojiku-ci:local` tag; its default command renders exactly this example):
docker run --rm shojiku-ci:local > receipt.pdf
# your own files: mount them and pass normal CLI arguments
docker run --rm -v "$PWD:/work" shojiku-ci:local render \
  --templates /work/templates.yml --params /work/params.json \
  --output /work/out.pdf

Getting the binaries in the first place (source build or Docker, plus MCP-server registration for AI agents) is covered in the quickstart.

Item types

Every items: entry is a map with a type:. Where an item may appear depends on which part of the page holds it. A page (template.md) is made of optional bandsheader and footer, repeated at the top/bottom of every page — and one body between them, which is either type: flow (items stack top-to-bottom and paginate onto new pages as they run out of room — the usual choice, flow.md) or type: absolute (every item pinned at its own box.x/box.y, single page). The placement column below uses:

  • F — in a flow body
  • A — in an absolute body
  • B — in a band (header/footer)
  • C — inside a container item, wherever that container sits
  • cell — inside a repeat cell / repeat_flow card
type:What it drawsAllowed placementPage
textstatic / interpolated / bound text; rich spans:F A B C celltext.md
rectrectangle (border/fill)F A B C cellrect.md
linestroked segment; Length endpoints (to: { x: "100%" }) or an anchor to another item (to: { item: total })F A B C cellline.md
imagePNG/JPEG/GIF/WebP/SVG assetF A B C cellimage.md
qr_codelayout-time vector QRF A B C cellqr_code.md
listone line per array entry + overflow clampF A B C celllist.md
containernestable box: origin, size, style cascadeF A B C cellcontainer.md
tablepaginating data-driven rows; a column binds a value or hosts a cell: sub-template; box: narrows it in flow or places it as one bounded block elsewhereF A B C (not cell)table.md
repeatimposition / n-up grid of data-scoped cellsF onlyrepeat.md
repeat_flowflowing card list, one card per elementF onlyrepeat_flow.md
page_breakstart a fresh pageF onlypage_break.md
char_gridmanuscript-paper / workbook character cells (+ruby)F A B C cellchar_grid.md
ellipsebox-inscribed oval, or anchor: to circle another item's glyph band; circled-option mark or decorationF A B C cellform_marks.md
checkboxalways-drawn frame + params-driven checkF A B C cellform_marks.md
page_number{page} / {pages}B onlypage_number.md

Every type in this table also takes visible:, which binds whether the item is shown to a params field — reserving its box by default, or removing it from layout with collapse: true. See visible.md.

Disallowed placements warn and skip (never a hard failure) — codes in diagnostics.md.

Concepts

PageCovers
template.mdfile structure: page / styles / defaults / formats / sections, bands, bodies, common item keys
defaults.mddocument presentation defaults: root style (rem root), per-type format defaults, the formats: registry
page.mdpage size, orientation, margin; the margin box as coordinate origin
document.mddocument: metadata: title / description / keywords / language / authors → the PDF's document properties (PDF only)
length.mdunits: pt, %, mm/cm/in, em/rem; round-trip; guards
box.mdbox: geometry — x/y/w/h, margin/padding, minWidth/maxWidth/minHeight/maxHeight
flex.mddefault child placement: direction, gap, alignItems, justifyContent, auto margins
grid.mdbox.type: grid — column/row tracks, fill order
flow.mdstacking, gap, pagination, what splits and what moves whole
style.mdevery style property, the cascade, named styles, box decoration
text.mdwrapping, kinsoku, textOverflow, long-text pagination
vertical_text.mdwritingMode: vertical_rl / textOrientation — vertical text (plain, spans, list, table cells, page_number)
link.mdlink: { url } hyperlinks on text/image/spans → PDF annotations
data-binding.mddata: bindings, {key:format} interpolation, bindings: named declarations, params, format types
visible.mdvisible: — show an item only for some data; the reserve-box default and the collapse: true opt-in
definitions.mddefinitions.yml: the OpenAPI-shaped schema (properties/items, format hints, constraints, display variants, params validation)
fonts.mdlocales, lang packs, valid fontFamily face ids
layout-model.mdthe resolve invariant, box tree, caps, box index
diagnostics.mdevery diagnostic code by stage

The box: keys at a glance

KeyMeaningPage
x yoffset from the parent origin (authoring either opts a container child out of flex)box.md
w hborder-box size; omitted = fill width / auto heightbox.md
minWidth maxWidth minHeight maxHeightCSS-order size clampsbox.md
marginouter spacing; per-side map; auto sidesbox.md
paddinginner spacing (non-negative)box.md
typechild layout mode: flex (default) | gridflex.md / grid.md
direction gap alignItems justifyContentflex keys (grid reuses some)flex.md
flexGrowchild's weighted share of leftover row widthflex.md
columns rows columnGap rowGapgrid tracks & gapsgrid.md
columnSpan rowSpangrid child's track span (≥ 1)grid.md

Style properties at a glance

Inherited: fontSize fontFamily fontWeight fontStyleletterSpacing lineHeight color textAlign lineBreaktextSpacingTrim hangingPunctuation writingMode textOrientationtextCombineUpright. Not inherited: verticalAlign backgroundColor borderWidthborderColor borderStyle borderRadius textOverflow overflowtextDecorationopacity. Full table with defaults and value sets: style.md.

Not supported yet

The cross-cutting list, gathered from the per-feature pages. Where a diagnostic reports the restriction, the entry names its code, so the claim is checkable against diagnostics.md; a structural limit that nothing reports carries a dash instead. A restriction stated here is stated on its own page's Limitations section too.

Not supportedReported as
A table inside a repeat cell, a repeat_flow card, or a table column's cell:table_in_cell
Body-cell spanning (colspan). headerGroups spans the header row onlyheader_group_span_clamped
repeat / repeat_flow / page_break outside a flow bodyrepeat_in_band, repeat_flow_in_container, page_break_in_absolute_body, …
page_number outside a bandpage_number_in_body, page_number_in_container
A text mark: in vertical writingvertical_text_unsupported
textOverflow: shrink / ellipsis on a rich spans blockspan_overflow_unsupported
Per-corner border radii; any radius on a per-side or double border, a table, or a form markborder_radius_ignored
SVG constructs outside the subset parsersvg_unsupported
Remote image sources — the render path has no network I/O, by designremote_asset_unsupported
Flex wrapping: a row is one lineflex_row_overflow
Justified text and hyphenation (textAlign is left/center/right)
Barcode symbologies other than QR
Arithmetic in bindings: totals and tax are computed by the host
Per-section page geometry: one page block per document

Reading order for new authors

  1. template.md — the file skeleton
  2. box.md + length.md — placing things
  3. style.md + fonts.md — making them look right
  4. flow.md + table.md — variable-length content
  5. data-binding.md — wiring in params

AI agents authoring a template end-to-end (three files → validate → preview loop) should also load the step-by-step playbook in skills/shojiku-template-author/ (AI-only — written as instructions to the agent).

Runnable examples live in the repository source (examples/ at the repo root) — a docs-only distribution (e.g. what an MCP consumer sees) does not include them; the snippets on each feature page are the self-contained fallback. Each example directory commits its rendered output (output.pdf + preview-<n>.png) next to the sources, so you can see what a template produces without rendering anything; make examples regenerates them all. The set (gallery order and one-line pitches: README.md § Gallery): examples/business/invoice-ja (a multi-page A4 invoice: paginating table with repeating header, pre-computed totals, QR + link; params-short.json renders the single-page variant), examples/business/estimate-ja (the invoice's sibling: single-rate one-pager, estimate-terms box, a negative discount row), examples/business/delivery-note-ja (a delivery note: headerGroups spanning band, data-driven row.conditionalStyles, a receipt-stamp field — partial ↔ complete delivery as two params files), examples/business/pickup-slip-ja (the Thinreports-migration worked example — the migration walkthrough's result, with the legacy .tlf + Ruby host beside it), examples/forms/application-form-ja (an A4 application form: form marks, 〒 entry cells, wareki placeholder — a blank ↔ filled-sample params pair), examples/business/event-tickets-ja (2×4 n-up event tickets with per-element QR; params-few.json = one sheet), examples/business/catalog-ja (a product catalog: repeat_flow variable-height cards, dynamic images, fit: cover), examples/business/shipping-labels-ja (2×3 n-up shipping labels: 〒 cells, list + an overflow-count line, per-order QR), examples/forms/certificate-ja (an A4 landscape certificate: double border, mincho + letter spacing, seal/medal SVGs, wareki), examples/typography/kokugo-print-ja (a kokugo worksheet: kanji practice cells + ruby, a vertical copying grid, answer cells), examples/typography/novel-ja (a B5 vertical paperback booklet: ruby-paginating vertical body, strict kinsoku + hanging punctuation, a tate-chu-yoko colophon, vertical page numbers), examples/business/restaurant-menu-us (a US Japanese-restaurant menu: English menu + USD prices with vertical Japanese accents — writingMode: vertical_rl brand column + per-dish dish names, double border, mincho), examples/business/invoice-en (Letter US-style invoice: USD cents, plural-aware quantities, Net-30 terms block), examples/forms/certificate-en (Letter-landscape certificate: real italics, en-US dates), examples/business/receipt-ja (an A4 receipt: containers, %, named styles), examples/business/receipt-us (80mm thermal, custom page size), examples/business/receipt-zh-tw / examples/business/receipt-zh-cn (the same receipt geometry under zh locale packs), examples/business/receipt-hi-in (Devanagari conjuncts + lakh/crore digit grouping) / examples/business/receipt-fil-ph (Latin face + the Philippine peso) / examples/business/receipt-th-th (Thai wrapped at word boundaries, dated in the Buddhist era), examples/typography/genkoyoshi-ja (a B5 vertical 200-cell genkoyoshi: char_grid + aozora ruby) and its horizontal twin examples/typography/genkoyoshi-yoko-ja, examples/forms/rirekisho-ja (an A3 landscape JIS-style rirekisho: custom page size, 2-column header, full-width tables), and examples/dev/layout-showcase — the component-showcase document (rich spans, hyperlinks, flex/grid, overflow policies, zebra table, list, QR, SVG gradient, repeat_flow, repeat imposition starting in place with trim guides and a document-scoped cell value (breakBefore: auto, cutMarks, scope: document), page_break), one labeled section per feature family, each demo followed by a code panel showing the YAML that produces it. The showcase is the visual index of the engine, Bootstrap-docs style: its rendered pages show the look and the syntax side by side; open the feature's reference page for the full key table. It grows with the engine — every new authorable feature adds a showcase section (demo + code panel) in the cycle that ships it.

Every page

PageCovers
box — position, size, spacing, boundsPosition, size, margin, padding and min/max bounds — the border-box every item is placed by.
char_grid — manuscript-paper / workbook / form character cellsOne character per cell: manuscript paper, practice sheets, and form entry boxes.
type: containerAn origin and a resolved size: children position, resolve %, and inherit against it.
Data binding & formattingHow templates bind runtime params and how the locale pack formats them for display.
Template defaults & the format registryDocument-wide presentation defaults and the named format registry — the CSS :root analog.
definitions.yml — the data dictionaryThe data dictionary: the engineer-to-author seam that enriches validation and formatting.
Diagnostics referenceThe complete registry of every code the engine can emit, with severity and meaning.
document: — document metadataDocument metadata written into the PDF's properties: title, description, keywords, language, authors.
Flex layout (box.type: flex, the default)The default container mode: CSS-flex semantics down to the defaults, keyed on box.type.
Flow — stacking & paginationA flow body stacks items top-down and paginates when content passes the region bottom.
Locales & fonts (packs)Locale packs and font packs: where formatting data and typefaces come from.
type: ellipse / type: checkbox — form marksChoice marks drawn as vector paths — circling a printed option, or a checkbox.
Static grid (box.type: grid)Explicit column tracks — fr weights and auto sizing — instead of a flex stack.
type: imageA raster or SVG image from a template-time source or a params-bound value.
The layout modelHow a template plus params becomes the resolved layout tree every backend draws.
Lengths & unitsEvery geometry value: absolute units, %, em/rem, and where each has no basis.
type: lineA stroked segment between two points — no box, its own style shape.
link: — hyperlinksA clickable URL emitted as a PDF link annotation over the item's drawn geometry.
type: listA bounded per-element list: one entry per line, clamped with an overflow line.
page — size, orientation, marginSheet geometry: paper size, orientation, and the margin box every coordinate resolves against.
type: page_breakAn explicit break: the next flow item starts on a fresh page.
type: page_numberThe current page number — band-only, because the count is known at assembly.
type: qr_codeA QR code encoded at layout time into vector modules — static text or a bound value.
type: rectA rectangle: pure decoration painted by the unified style properties.
type: repeat — imposition / n-upImposition / n-up: N data-scoped copies of one cell laid onto each page.
type: repeat_flow — flow repeat (card list)One auto-height card per array element, in normal flow — a vertical card list.
style — appearance properties & the cascadeEvery appearance property and the three-surface cascade that resolves them per item.
type: tableA data-driven table: bound or container columns, spanning headers, conditional rows, row-by-row pagination.
Template file structureThe file's own shape: top-level keys, the header/body/footer sections, and what every item shares.
type: textStatic, interpolated, or bound text — inline spans, ruby, wrapping, and overflow.
Vertical writingVertical writing: characters fill a column top-to-bottom, columns lay out right-to-left.
visible: — show an item only for some dataShow an item only for some data: the form-mark presence predicate on any item, reserving its box or removing it from layout.