scene

package
v0.0.0-...-2a9920d Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 12, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Overview

Package scene is Layer 2 of pptx-go: a typed scene IR and a Render entrypoint that composes the pptx builder (Layer 1). A caller builds a Scene — an ordered list of SceneSlides, each a list of typed SlideNodes — and Render turns it into a *pptx.Presentation.

scene composes pptx; it never reaches under the builder (P1). Its token enums are aliases of pptx's, so callers use one vocabulary.

This package provides the IR catalog, two-stage validation (structural plus token/asset/registry resolution), the AssetResolver seam, the per-node rendering-policy table, the curated icon/ornament/frame registries with per-render caller extension, and a fully implemented, internally parallel, deterministic Render that composes every node kind onto the builder and returns Stats.

Index

Constants

View Source
const (
	// FitFill stretches the image to fill its box (the zero value / default).
	FitFill = pptx.FitFill
	// FitNone places the image without a stretch fill mode.
	FitNone = pptx.FitNone
)
View Source
const (
	ColorCanvas     = pptx.ColorCanvas
	ColorSurface    = pptx.ColorSurface
	ColorSurfaceAlt = pptx.ColorSurfaceAlt
	ColorAccent     = pptx.ColorAccent
	ColorAccentAlt  = pptx.ColorAccentAlt
	ColorAccentWarm = pptx.ColorAccentWarm
	ColorSuccess    = pptx.ColorSuccess
	ColorWarning    = pptx.ColorWarning
	ColorError      = pptx.ColorError
	ColorInfo       = pptx.ColorInfo
)
View Source
const (
	TextPrimary   = pptx.TextPrimary
	TextSecondary = pptx.TextSecondary
	TextTertiary  = pptx.TextTertiary
	TextInverse   = pptx.TextInverse
	TextMuted     = pptx.TextMuted
	TextAccent    = pptx.TextAccent
	TextAccentAlt = pptx.TextAccentAlt
	TextSuccess   = pptx.TextSuccess
	TextWarning   = pptx.TextWarning
	TextError     = pptx.TextError
)
View Source
const (
	TypeDisplay   = pptx.TypeDisplay
	TypeH1        = pptx.TypeH1
	TypeH2        = pptx.TypeH2
	TypeH3        = pptx.TypeH3
	TypeH4        = pptx.TypeH4
	TypeH5        = pptx.TypeH5
	TypeBody      = pptx.TypeBody
	TypeBodySmall = pptx.TypeBodySmall
	TypeCaption   = pptx.TypeCaption
	TypeMono      = pptx.TypeMono
	TypeCode      = pptx.TypeCode
)
View Source
const (
	SpaceXS  = pptx.SpaceXS
	SpaceSM  = pptx.SpaceSM
	SpaceMD  = pptx.SpaceMD
	SpaceLG  = pptx.SpaceLG
	SpaceXL  = pptx.SpaceXL
	Space2XL = pptx.Space2XL
)
View Source
const (
	RadiusNone = pptx.RadiusNone
	RadiusSM   = pptx.RadiusSM
	RadiusMD   = pptx.RadiusMD
	RadiusLG   = pptx.RadiusLG
	RadiusFull = pptx.RadiusFull
)
View Source
const (
	ElevationFlat     = pptx.ElevationFlat
	ElevationRaised   = pptx.ElevationRaised
	ElevationElevated = pptx.ElevationElevated
)
View Source
const (
	AnchorTopLeft      = pptx.AnchorTopLeft
	AnchorTopCenter    = pptx.AnchorTopCenter
	AnchorTopRight     = pptx.AnchorTopRight
	AnchorCenterLeft   = pptx.AnchorCenterLeft
	AnchorCenter       = pptx.AnchorCenter
	AnchorCenterRight  = pptx.AnchorCenterRight
	AnchorBottomLeft   = pptx.AnchorBottomLeft
	AnchorBottomCenter = pptx.AnchorBottomCenter
	AnchorBottomRight  = pptx.AnchorBottomRight
)

Variables

View Source
var ErrAssetNotFound = errors.New("scene: asset not found")

ErrAssetNotFound is returned by a resolver when an id has no bytes.

Functions

func FormatNumber

func FormatNumber(v float64, f NumberFormat) string

FormatNumber renders v per f, deterministically (stdlib only; rounding is strconv's round-half-to-even, so output is byte-stable). The layout is Prefix · sign · [symbol if !SymbolAfter] · body · [%] · [symbol if SymbolAfter] · Suffix.

func LegibleTextOn

func LegibleTextOn(fg, bg pptx.RGB, minRatioX10 int) pptx.RGB

LegibleTextOn returns fg adjusted toward lighter or darker — preserving hue — until its WCAG contrast against bg clears minRatioX10 (a contrast ratio ×10, e.g. 45 = 4.5:1 for body text, 30 = 3:1 for large display), or the nearest endpoint (white on a dark background, black on a light one) when the target is unreachable. If fg already clears the ratio it is returned unchanged, so a caller that funnels every accent through this helper gets byte-identical output for the common legible case. A malformed fg or bg returns fg unchanged (fail-safe).

It is a deterministic MECHANISM, not a policy (D-026): the engine does not apply it automatically anywhere in the render path (so all existing output is byte-identical) — a soul calls it to derive a legible accent text color per variant and stores the result on the theme via WithDarkText / WithDarkSurface. It is the graded color analog of onCardSurface, reusing the same WCAG luminance math, so the engine and the soul agree on contrast. All steps are integer, so the result is identical regardless of worker count.

func ValidateIcon

func ValidateIcon(svg []byte) error

ValidateIcon reports whether svg satisfies the icon translator constraints, so a caller can validate at its own registration point. It re-exports pptx.ValidateIcon (scene never reaches under pptx — P1).

func ValidateScene

func ValidateScene(s Scene) error

ValidateScene runs Stage 1 structural validation over a scene.

Types

type Alignment

type Alignment struct {
	Vertical   VAlign
	Horizontal HAlign
}

Alignment is the combined body-stack alignment for a SceneSlide. The zero value {VAlignTop, HAlignLeft} reproduces the pre-Phase-13 top-left layout unchanged (backward-compatible zero value).

type Anchor

type Anchor = pptx.Anchor

Anchor is a reference point reused from the builder for decoration/connector placement.

type Arrow

type Arrow struct {
	Direction ArrowDirection
	Label     string
	// contains filtered or unexported fields
}

Arrow is an inline directional connector with an optional label.

func (Arrow) NodeKind

func (Arrow) NodeKind() NodeKind

type ArrowDirection

type ArrowDirection int

ArrowDirection selects an arrow's direction.

const (
	ArrowRight ArrowDirection = iota
	ArrowLeft
	ArrowUp
	ArrowDown
)

type AssetID

type AssetID string

AssetID is a free-form asset reference. pptx-go imposes no scheme; callers choose (pengui-slides uses asset://<uuid> — see URIAssetResolver). (D-024.)

type AssetResolver

type AssetResolver interface {
	Resolve(ctx context.Context, id AssetID) ([]byte, string, error)
}

AssetResolver maps an AssetID to bytes and a content-type hint (image/png, image/jpeg, image/svg+xml, …). A missing asset returns (nil, "", ErrAssetNotFound).

func URIAssetResolver

func URIAssetResolver(fn func(uuid string) ([]byte, string, error)) AssetResolver

URIAssetResolver returns an AssetResolver that accepts asset://<uuid> ids and delegates to fn with the bare uuid (D-024). A non-asset:// id is passed to fn unchanged.

type AssetSide

type AssetSide int

AssetSide selects where a Lockup's logo sits relative to its caption (R12.9, D-102). The zero value LeadCaption places the caption first (caption leads, logo trails); TrailCaption places the logo first.

const (
	LeadCaption  AssetSide = iota // caption then logo (zero value)
	TrailCaption                  // logo then caption
)

type Background

type Background struct {
	// Kind selects the fill type; zero (BackgroundNone) draws nothing.
	Kind BackgroundKind

	// Color is the surface color role for a solid-color background
	// (Kind == BackgroundColor). Resolves against the active theme.
	Color pptx.ColorRole

	// Gradient holds the two surface color roles for a linear gradient
	// (Kind == BackgroundGradient) when Stops is empty. Index 0 is the start
	// stop (Pos 0.0), index 1 is the end stop (Pos 1.0). Both resolve against
	// the active theme.
	Gradient [2]pptx.ColorRole

	// Stops is an optional multi-stop gradient (2..8 ascending stops in [0,1])
	// for Kind == BackgroundGradient. When non-empty it supersedes Gradient (the
	// legacy two-role pair); when empty, Gradient + Angle drive a two-stop linear
	// gradient (byte-identical to pre-D-105 output). Invalid stops (<2, >8, out
	// of [0,1], or not strictly ascending) record a LayoutWarning and skip the
	// fill (RFC §10.2 — degrade to a warning, no panic). The slice makes
	// Background non-comparable; compare with reflect.DeepEqual.
	Stops []GradientStop

	// Angle is the linear gradient angle in degrees clockwise from the positive
	// x-axis (used when Kind == BackgroundGradient). 0° = left-to-right,
	// 90° = top-to-bottom. Valid range [0, 360); values outside are normalized.
	Angle int

	// GradientName, when non-empty (Kind == BackgroundGradient), requests a named
	// brand gradient registered on the active theme (pptx.WithGradient, R8.5). It
	// supersedes Stops and the legacy Gradient pair; the named spec's Radial flag
	// picks a linear or radial fill, and its stops may pin exact brand hues (RGB,
	// variant-independent) or follow the theme (TokenColor). A name not found on
	// the theme, or a spec with invalid stops, records a LayoutWarning and skips
	// the fill (RFC §10.2). Empty (the zero value) runs the Stops / legacy path
	// unchanged (byte-identical).
	GradientName string

	// AssetID is the asset reference for a full-bleed picture background
	// (Kind == BackgroundAsset). Resolved via the render's AssetResolver.
	AssetID AssetID

	// Mesh holds the pooled radial glows for a BackgroundMesh (D-112), drawn over
	// the base canvas fill in slice order. Empty draws nothing (absent config).
	// Adds no comparability constraint beyond the Stops slice above.
	Mesh []MeshGlow

	// Scrim is an optional darkening/tinting overlay drawn over the background
	// fill for text legibility over a photo or busy background (R14.1). nil draws
	// nothing (byte-identical). It applies over any drawn background kind.
	Scrim *Scrim

	// Duotone is an optional two-tone recolor of a photographic background
	// (R14.1), applied only when Kind == BackgroundAsset. nil leaves the photo at
	// its natural colors (byte-identical).
	Duotone *Duotone
}

Background is a slide's full-bleed background specification. It is drawn before all body content and decorations — behind the bg-decoration layer and behind the body stack — so it forms the lowest layer in the slide's z-order. The zero value (Kind == BackgroundNone) draws nothing; all existing slides are byte-identical after this field is added to SceneSlide.

Color is the surface color role used when Kind == BackgroundColor; it resolves against the active theme so a theme swap re-paints the background (P2).

Gradient is a pair of ColorRole values; index 0 is at position 0 (the start of the gradient, Pos 0.0) and index 1 is at position 1 (the end, Pos 1.0). Angle is measured in degrees clockwise from the positive x-axis (0° = left-to-right, 90° = top-to-bottom).

AssetID is the asset reference passed to the render's AssetResolver when Kind == BackgroundAsset. A missing resolver or an unresolvable ID records a LayoutWarning and skips the fill; the slide renders without a background rather than failing (RFC §10.2 — no panics, degrade to warning).

Stops is an optional multi-stop gradient (D-105). When non-empty it supersedes Gradient for a BackgroundGradient; when empty the two-role Gradient + Angle path runs unchanged (byte-identical to pre-D-105 output).

type BackgroundKind

type BackgroundKind int

BackgroundKind selects a slide's full-bleed background fill. The zero value (BackgroundNone) draws nothing — the slide inherits the presentation's default background — preserving byte-identical output for all slides that do not set a background (RFC §10.1 backward-compatibility guarantee).

const (
	// BackgroundNone draws no explicit background; the slide inherits the
	// presentation's default. This is the zero value and pre-Phase-13 behavior.
	// For VariantDark slides a dark canvas rect is drawn automatically when this
	// is set (see renderBackground).
	BackgroundNone BackgroundKind = iota

	// BackgroundColor fills the entire slide canvas with a single solid color
	// resolved from the active theme via Background.Color.
	BackgroundColor

	// BackgroundGradient fills the slide canvas with a two-stop linear gradient
	// between the two roles in Background.Gradient at Background.Angle degrees.
	BackgroundGradient

	// BackgroundAsset fills the slide canvas with a full-bleed picture resolved
	// via Background.AssetID from the render's AssetResolver.
	BackgroundAsset

	// BackgroundRadial fills the slide canvas with a center-out radial gradient
	// (a spotlight/vignette) from Background.Stops, or the legacy two-role
	// Background.Gradient pair when Stops is empty. The focal point is centered
	// (a 50%-inset circle); a focal offset is not yet exposed (D-106). Appended
	// last so existing BackgroundKind values are unchanged (byte-identical).
	BackgroundRadial

	// BackgroundMesh draws a soft "mesh" wash: a base canvas fill plus the N
	// low-alpha radial glows in Background.Mesh, pooled at caller-chosen anchors
	// over the canvas (the cover/section mesh look — D-112). An empty Mesh draws
	// nothing (absent config). Appended last so existing values are unchanged.
	BackgroundMesh
)

func (BackgroundKind) String

func (k BackgroundKind) String() string

String returns the background kind's name.

type Banner struct {
	Lead      RichText
	Body      RichText
	Icon      string        // leading curated/extension icon; "" = none
	Fill      ColorRole     // strip fill; zero (ColorCanvas) = ColorAccent
	TextColor TextColorRole // lead/body color; zero (TextPrimary) = auto-contrast on Fill
	Trailing  []SlideNode   // right-aligned children (e.g. Stat/Button/Lockup); nil = none
	// contains filtered or unexported fields
}

Banner is a full-width filled "big takeaway / promo / CTA" strip (R12.6, D-097): a leading icon + a bold lead phrase + a supporting body on the left, with optional right-aligned Trailing children (a Stat and/or a Button). Distinct from the side-bar Callout — the banner is a wide, full-fill band.

Fill is the strip color; its zero value (ColorCanvas) is treated as ColorAccent (a banner is always a filled strip — a canvas-colored one would be invisible). TextColor colors the lead/body; its zero value (TextPrimary) auto-contrasts against Fill (light on a dark fill), and any explicit non-default value is honored. Trailing children render in a right region per their own policy. Additive: a deck with no Banner is byte-identical.

func (Banner) NodeKind

func (Banner) NodeKind() NodeKind

type Bento

type Bento struct {
	Columns int // shared column-unit count a row's spans are measured against (>= 1)
	Rows    []BentoRow
	// WeightedRows opts a bento into content-proportional row heights: each row
	// sizes to the preferred height of its tallest cell (at that cell's span
	// width), clamped by a single deterministic scale so the rows always fit the
	// region. The zero value (false) keeps equal-height rows — byte-identical to
	// the pre-R10.3 layout. (D-072.)
	WeightedRows bool
	// Fill opts the bento into claiming leftover body-stack height under
	// VAlignTop without enabling slide-wide VAlignFill (D-143). The taller slot is
	// then subdivided by bentoGeometry into taller rows/cells. Zero=false
	// preserves today's natural-height slot exactly. Under any slide VAlign other
	// than VAlignTop this field is inert in V1; slide-wide fill modes continue to
	// own slack distribution.
	Fill bool
	// contains filtered or unexported fields
}

Bento is a row-labeled grid (D-056): rows that each carry an optional left label and cells of variable column span, measured against Columns shared column units (a span-S cell occupies S units, so columns align across rows). A row's spans sum to <= Columns. It is a container — its cells render per their own policy — and is distinct from Grid (uniform columns, one child per cell).

func (Bento) NodeKind

func (Bento) NodeKind() NodeKind

type BentoCell

type BentoCell struct {
	Span int
	Node SlideNode
}

BentoCell is one cell of a BentoRow: its content and how many of the bento's column units it spans (>= 1).

type BentoRow

type BentoRow struct {
	Label string // "" = no label for this row
	Cells []BentoCell
}

BentoRow is one row of a Bento: an optional left-gutter label and a left-to- right sequence of span-weighted cells.

type BodyLayout

type BodyLayout int

BodyLayout selects how a card stacks its children.

const (
	BodyVertical BodyLayout = iota
	BodyHorizontal
)

type BorderStyle

type BorderStyle int

BorderStyle selects a card's border treatment (D-043). BorderDefault (zero) defers to the legacy Outline bool, so an existing Card{…, Outline:…} renders byte-identically; an explicit style overrides Outline.

const (
	BorderDefault BorderStyle = iota // defer to Outline
	BorderNone                       // no border (even if Outline is true)
	BorderSolid                      // neutral hairline border
	BorderAccent                     // accent-colored border
)

type Button

type Button struct {
	Label        string
	Tone         ButtonTone
	Size         ButtonSize
	LeadingIcon  string // closed-name curated/extension icon; "" = none
	TrailingIcon string // closed-name curated/extension icon; "" = none
	Align        HAlign // per-node horizontal alignment override; 0 = inherit slide
	// contains filtered or unexported fields
}

Button is a presentational CTA / action affordance (R12.1, D-094): a content-fit RadiusFull pill with a label and optional leading/trailing icons, droppable standalone (a closing slide), inside a card body (a pricing card), or inside a banner. It is a shape only — no hyperlink/action wiring (the deck is static).

Width is content-fit (label + icons + padding) clamped to its box; Align offsets the pill within the box (zero = inherit the slide's Content.Horizontal). Tone selects the token fill (ghost = outline); Size scales the geometry. LeadingIcon / TrailingIcon are closed-name curated/extension icons (Stage-1 validated); their zero value ("") renders no glyph. Additive: absent ⇒ byte-identical.

func (Button) NodeKind

func (Button) NodeKind() NodeKind

type ButtonSize

type ButtonSize int

ButtonSize scales a Button's height, interior padding, and icon size. The zero value ButtonMD is the default; SM/LG step it down/up. A pinned layout metric, not a theme token (it sizes geometry, not a visual property).

const (
	ButtonMD ButtonSize = iota // default
	ButtonSM
	ButtonLG
)

type ButtonTone

type ButtonTone int

ButtonTone selects a Button's fill treatment (R12.1, D-094). Each tone maps to theme color tokens (P2), so a theme swap re-skins every button. The zero value ButtonPrimary is a solid accent pill — the default "do this next" affordance.

const (
	ButtonPrimary   ButtonTone = iota // solid ColorAccent fill, inverse label (zero value)
	ButtonAccentAlt                   // solid ColorAccentAlt fill, inverse label
	ButtonGhost                       // no fill + an accent hairline outline, accent label
	ButtonNeutral                     // solid ColorSurfaceAlt fill, default label
)

type Callout

type Callout struct {
	Kind  CalloutKind
	Title string
	Body  RichText
	// contains filtered or unexported fields
}

Callout is a colored side-bar note.

func (Callout) NodeKind

func (Callout) NodeKind() NodeKind

type CalloutKind

type CalloutKind int

CalloutKind selects a callout's tone.

const (
	CalloutNote CalloutKind = iota
	CalloutWarning
	CalloutTip
	CalloutImportant
)

type Card

type Card struct {
	Header     string
	Eyebrow    string // kicker label above the header
	Icon       string // curated/extension icon name (closed-name; Stage-1 validated)
	HeaderPill string // pill badge text, right of the header row
	Body       []SlideNode
	BodyLayout BodyLayout
	Fill       ColorRole
	// FillGradient, when non-nil, replaces the solid Fill with a 2-stop linear
	// gradient surface (From→To at Angle degrees clockwise from +x) for a subtle
	// top-to-bottom depth shift (D-108). nil = solid Fill (byte-identical). Both
	// stops resolve against the active theme (P2); a darker-To auto-tint is the
	// soul's choice (D-026), not the engine's.
	FillGradient *GradientFill
	Outline      bool        // legacy border shorthand; see BorderStyle (D-043)
	BorderStyle  BorderStyle // explicit border; BorderDefault defers to Outline
	Size         CardSize    // interior padding scale
	Layout       CardLayout  // header arrangement
	Elevation    ElevationRole
	// Rich visuals (D-054). Optional; each zero value (nil / "") omits its
	// element, so a card that sets none renders byte-for-byte as before. The two
	// colors are *ColorRole, not ColorRole, because ColorRole's zero value is a
	// real color (ColorCanvas) and cannot signal "unset".
	HeaderFill *ColorRole // banded header region color (body keeps Fill); nil = no band
	StatusDot  *ColorRole // small status dot, top-right corner; nil = no dot
	Watermark  string     // large, low-opacity label drawn behind the body; "" = none
	// BodyVAlign selects the vertical distribution of the card body within the
	// card body region (the same VAlign modes as the slide body stack:
	// Center / Bottom / Justify / Fill / Fit). The zero value VAlignTop is
	// top-anchored — byte-identical to the pre-R10.4 render. Applies to the
	// vertical body layout only (BodyLayout != BodyHorizontal). (D-073.)
	BodyVAlign VAlign
	// PaddingScale is a basis-point multiplier on the card's size-resolved
	// interior padding (Size → SpaceSM/MD/XL): 0 and 10000 leave it unchanged
	// (byte-identical), a value below 10000 tightens a dense card (floored at a
	// pinned minimum so the inset never collapses), above 10000 loosens it. It
	// resolves through theme spacing tokens — no literals (P2). (D-076.)
	PaddingScale int
	// Ribbon is an optional pinned emphasis badge (R12.3, D-098) — a "MOST POPULAR"
	// top bar or a corner badge that singles this card out of a row. It sits outside
	// the header text flow (distinct from HeaderPill); a RibbonTopBar shifts the body
	// down. nil = no ribbon, byte-identical.
	Ribbon *Ribbon
	// Backdrop is an optional decoration drawn behind the card's computed box,
	// before its fill (D-113) — a focal glow/halo that tracks the card across any
	// layout. Typically a center-anchored, bleeding radial_glow. nil = none,
	// byte-identical. The card box is passed as the decoration's region, so the
	// glow centers on the card and (with Bleed) spills beyond it behind the fill.
	Backdrop *Decoration
	// ImageFill fills the card surface with a cover-fit photo (resolved via the
	// render's AssetResolver) instead of the solid Fill / FillGradient — the
	// image-as-surface treatment for photographic cards (R14.1, D-117). The card's
	// rounded corners still clip the image. "" = the solid/gradient Fill
	// (byte-identical). A missing resolver or unresolvable ID records a
	// LayoutWarning and falls back to the Fill (RFC §10.2 — degrade, no panic).
	// The field is named ImageFill, not AssetID, because the card still renders as
	// native chrome (not a pic), so its policy stays HasAsset:false.
	ImageFill AssetID
	// contains filtered or unexported fields
}

Card is an accent card: chrome (rounded rect + accent stripe + optional icon/eyebrow/header/header-pill) over a body of leaf children. All fields beyond Header/Body/BodyLayout/Fill/Outline/Elevation are additive (D-043): their zero values reproduce the pre-Phase-14 render byte-for-byte.

func (Card) NodeKind

func (Card) NodeKind() NodeKind

type CardLayout

type CardLayout int

CardLayout arranges a card's header region. CardLayoutDefault (zero) places the icon to the left of the eyebrow/header stack (a header row); IconTop stacks the icon above the text. (Further v4 header variants are deferred — RFC §11.3; plan §16.)

const (
	CardLayoutDefault CardLayout = iota // icon left of the eyebrow/header stack
	CardLayoutIconTop                   // icon above the eyebrow/header stack
)

type CardSection

type CardSection struct {
	Header string
	Body   []SlideNode
	// contains filtered or unexported fields
}

CardSection is a top-level card that accepts grid / two_column / nested cards.

func (CardSection) NodeKind

func (CardSection) NodeKind() NodeKind

type CardSize

type CardSize int

CardSize scales a card's interior padding. CardSizeMD (zero) preserves the default padding.

const (
	CardSizeMD CardSize = iota
	CardSizeSM
	CardSizeLG
)

type Chart

type Chart struct {
	AssetID AssetID
	Caption string
	// contains filtered or unexported fields
}

Chart is an image-shape chart in V1 (native c:chart is V2; D-004).

func (Chart) NodeKind

func (Chart) NodeKind() NodeKind

type CheckState

type CheckState int

CheckState selects a checklist item's status glyph (R12.2, D-095). The zero value CheckDone is a filled affirmative check (the common "you get this" row).

const (
	CheckDone    CheckState = iota // a filled check glyph (default), accent-tinted
	CheckNo                        // a filled cross glyph, muted
	CheckNeutral                   // a filled dot glyph, muted
)

type Checklist

type Checklist struct {
	Items     []ChecklistItem
	Columns   int        // 1..3 column reflow (row-major); 0 = 1 column
	GlyphTone *ColorRole // glyph color override; nil = per-state default
	Fill      bool       // distribute rows to fill the box height (like VAlignFill)
	// contains filtered or unexported fields
}

Checklist is a dense feature/"what you get" list (R12.2, D-095): rows of a filled status glyph (check / cross / dot) before rich text, reflowed row-major into 1–3 balanced columns, with the text hanging-indented from the glyph width. The glyph is a true filled custGeom (the curated check/x/dot icon), never an empty font checkbox.

GlyphTone overrides the per-state glyph color for every item; it is a *ColorRole so nil selects the per-state default (CheckDone → accent, others → muted) — ColorRole's zero value is a real color (ColorCanvas) and cannot signal "unset" (D-054 pattern). Fill distributes inter-row slack so a short list spans the box height (the last row meets the bottom); the zero value top-aligns the rows. Additive: a deck with no Checklist is byte-identical (the List/BulletCheckbox path is untouched).

func (Checklist) NodeKind

func (Checklist) NodeKind() NodeKind

type ChecklistItem

type ChecklistItem struct {
	Text  RichText
	State CheckState
	Icon  string // optional glyph override; "" = the state's default glyph
}

ChecklistItem is one row of a Checklist: rich text, a status, and an optional icon name that overrides the state's default glyph (a closed-name curated/extension icon, Stage-1 validated). The zero value renders a filled check glyph before the text.

type Chip

type Chip struct {
	Label string
	Tone  ChipTone
	Color ColorRole
	Align HAlign // per-node horizontal alignment override; 0 = inherit slide
	// contains filtered or unexported fields
}

Chip is an inline pill. Align overrides the slide's Content.Horizontal for this node; the zero value (HAlignLeft) inherits the slide default.

func (Chip) NodeKind

func (Chip) NodeKind() NodeKind

type ChipRow

type ChipRow struct {
	Label string
	Chips []ChipSpec
	Wrap  bool   // wrap chips onto new lines (zero = single line)
	Align HAlign // per-node horizontal alignment override; 0 = inherit slide
	// contains filtered or unexported fields
}

ChipRow is a horizontal, wrap-to-next-line row of content-fit chip pills with an optional leading label (R12.5, D-096): a tag / category / capability strip. Each chip sizes to its label (plus an optional leading icon); chips lay left-to-right and, when Wrap is set, reflow onto new lines when the row width is exceeded.

Wrap is the engine mechanism: the zero value lays all chips on a single line (the minimal behavior); a product that wants a reflowing strip sets Wrap true (D-026). A non-empty Label renders as a leading TypeCaption label before the first chip. Align offsets each line's chips (zero = inherit the slide's Content.Horizontal). Additive: a deck with no ChipRow is byte-identical.

func (ChipRow) NodeKind

func (ChipRow) NodeKind() NodeKind

type ChipSpec

type ChipSpec struct {
	Label string
	Tone  ChipTone
	Color ColorRole
	Icon  string // optional leading glyph; "" = none
}

ChipSpec is one chip in a ChipRow: a label, a tone, the tone's color role, and an optional leading icon (a closed-name curated/extension icon, Stage-1 validated). It mirrors the single Chip node's vocabulary (ChipTone / ColorRole). For ChipTint the Color is ignored (the chip uses ColorSurfaceAlt); ChipSolid/ChipOutline use Color.

type ChipTone

type ChipTone int

ChipTone selects a chip's fill treatment.

const (
	ChipTint ChipTone = iota
	ChipSolid
	ChipOutline
)

type Chrome

type Chrome struct {
	Enabled    bool    // master switch; false (zero value) = no chrome
	Brand      string  // footer-left brand text; used when BrandAsset is empty
	BrandAsset AssetID // footer-left brand image, resolved via the AssetResolver
	Total      int     // page-number denominator ("N / Total"); 0 = len(Scene.Slides)
}

Chrome configures optional, opt-in slide chrome (RFC §10.2): recurring per-slide furniture drawn outside the body region — a top section eyebrow and a bottom footer (brand slot + "N / total" page number). The zero value (Enabled == false) draws no chrome, so a chrome-free deck is byte-identical to one authored before this field existed.

Chrome is a mechanism, not a judgment (D-026): the engine draws the bands it is handed and composes the page-number string, but invents no brand and no section names. Colors resolve through theme tokens (TextMuted, ColorSurfaceAlt) so a theme swap re-skins chrome.

type CodeBlock

type CodeBlock struct {
	AssetID  AssetID
	Language string
	Caption  string
	// contains filtered or unexported fields
}

CodeBlock is block-level code, rendered as a caller-rasterized pic (D-014).

func (CodeBlock) NodeKind

func (CodeBlock) NodeKind() NodeKind

type ColorRole

type ColorRole = pptx.ColorRole

Surface color roles.

type ColumnJoin

type ColumnJoin int

ColumnJoin is the optional element a TwoColumn draws centered on its seam (D-055). JoinNone (zero value) draws nothing, so an existing TwoColumn renders byte-for-byte unchanged.

const (
	JoinNone  ColumnJoin = iota // default: nothing between the columns
	JoinBadge                   // a circular text badge (JoinLabel), e.g. "VS"
	JoinArrow                   // a right-arrow connector between the columns
)

type ColumnRatio

type ColumnRatio int

ColumnRatio selects a two_column split.

const (
	Ratio11 ColumnRatio = iota // 1:1
	Ratio12                    // 1:2
	Ratio21                    // 2:1
)

type ConnectorKind

type ConnectorKind int

ConnectorKind selects a flow's inter-step glyph (D-044). The zero value is ConnectorArrow, so an existing Flow with no Connector keeps a solid-arrow pipeline. Connectors compose preset shapes — no anchored AddConnector.

const (
	ConnectorArrow       ConnectorKind = iota // solid arrow (default)
	ConnectorArrowDashed                      // dashed line + chevron head
	ConnectorCycle                            // arrows + a trailing return arrow
	ConnectorPlus                             // a mathPlus glyph between steps
	ConnectorBiArrow                          // a bidirectional left-right / up-down arrow (R12.4)
)

type Crop

type Crop = pptx.Crop

Crop is a per-edge fractional image crop (0..1 trimmed from each edge), re-exported from the builder so the IR uses the same vocabulary (D-039). It drives the OOXML srcRect; the zero value is no crop.

type Cycle

type Cycle struct {
	Stages []CycleStage
	// contains filtered or unexported fields
}

Cycle is a closed-loop process diagram (R14.11, D-128): N stages placed evenly on a ring with directional connectors showing the loop. Native shapes; pure integer-EMU → byte-identical. A deck with no Cycle is byte-identical.

func (Cycle) NodeKind

func (Cycle) NodeKind() NodeKind

type CycleStage

type CycleStage struct {
	Label       string
	Icon        string
	AccentIndex int
}

CycleStage is one node on a Cycle ring (D-128).

type DataMark

type DataMark struct {

	// Kind selects the mark shape.
	Kind DataMarkKind
	// Value is the single fraction in [0,1] for DataMarkBar.
	Value float64
	// Values are the per-element fractions in [0,1] for DataMarkBars / Sparkline.
	Values []float64
	// Orientation selects a horizontal (default) or vertical DataMarkBar.
	Orientation FlowOrientation
	// Color overrides the mark color role; nil = ColorAccent (the track is always
	// ColorSurfaceAlt). The D-054 pointer pattern (ColorRole zero = a real color).
	Color *ColorRole
	// Label is an optional inline caption (drawn to the right of a horizontal bar).
	Label string
	// contains filtered or unexported fields
}

DataMark is a native (no-raster) micro-chart (R14.8, D-122): a crisp, brand-colored vector data mark drawn entirely from preset shapes — a progress bar, a small bar group, or a sparkline. It is driven by numeric values in [0,1] and theme colors, sizes to its box, and embeds in a Card/Bento cell. Pure integer-EMU geometry → byte-identical across renders/worker counts; no AssetResolver. A deck with no DataMark is byte-identical (a new node, absent until used).

func (DataMark) NodeKind

func (DataMark) NodeKind() NodeKind

type DataMarkKind

type DataMarkKind int

DataMarkKind selects a native micro-chart shape (R14.8, D-122). The bar-family marks (Bar, Bars, Sparkline) are pure rect/line geometry — crisp native vector, no rasterizer. Arc-based marks (donut, gauge) are a follow-up (Phase 88).

const (
	// DataMarkBar is a single progress/capacity bar: a track + a fill to Value.
	DataMarkBar DataMarkKind = iota
	// DataMarkBars is a small bar group, one bar per Values entry.
	DataMarkBars
	// DataMarkSparkline is a polyline through Values (a trend line).
	DataMarkSparkline
	// DataMarkDonut is a single-value ring (Value 0..1) with a centered label —
	// e.g. "92%" inside a 331° accent arc (R14.8 part 2, D-123).
	DataMarkDonut
	// DataMarkGauge is a single-value speedometer arc (Value 0..1) with a label.
	DataMarkGauge
)

type Decoration

type Decoration struct {
	Kind     DecorationKind
	Preset   string // curated ornament name (Kind == DecorationPreset)
	AssetID  AssetID
	Layer    Layer
	Anchor   Anchor
	Offset   Position // EMU shift from the anchor point
	Size     Size     // ornament box; zero = a default size
	Bleed    bool     // allow the box to extend past the slide edge
	Opacity  float64  // 0..1; 0 = fully opaque
	Rotation float64  // degrees clockwise
	// Color overrides the ornament's color role (D-107). nil = ColorAccent
	// (byte-identical to pre-D-107 output) — a pointer because ColorRole's zero
	// value is ColorCanvas, a real color (the D-054 pattern). Set it to render a
	// neutral-grey paper grain, an inverse-white starfield, or any brand-role
	// texture/glow. Applies to DecorationPreset; an asset decoration ignores it.
	// For DecorationText it colors the watermark glyph (nil = ColorAccent).
	Color *pptx.ColorRole
	// Text is the watermark string for DecorationText (an oversized ghost
	// number/word, e.g. "03"); ignored by other kinds. Empty fails validation
	// for DecorationText (D-109).
	Text string
	// FontSize is the watermark text size in points for DecorationText; 0 uses a
	// box-height "fill the box" default. Ignored by other kinds (D-109).
	FontSize float64
	// Pitch is the lattice spacing (EMU) for the pattern ornaments (grid_dots /
	// noise_overlay / starfield): their dot count derives from the box at this
	// pitch, so a full-bleed texture keeps a consistent visual density. 0 (the
	// zero value) keeps each pattern's legacy fixed count — byte-identical.
	// Ignored by non-pattern presets and other kinds (D-111).
	Pitch pptx.EMU
	// contains filtered or unexported fields
}

Decoration is an anchored ornament: a curated preset (native) or a caller-supplied asset (image). The AssetID is used only when Kind is DecorationAsset.

The placement box aligns the box's anchor-corresponding point (its top-left for a top-left Anchor, its center for a center Anchor, …) to that anchor point on the slide, shifted by Offset and sized by Size (a zero Size uses a default). Bleed permits the box to extend past the slide edge (negative offsets, RFC §14.2) without a warning. Opacity (0..1; 0 = opaque) dims the decoration and Rotation (degrees) rotates it — both honored for asset decorations and single-shape ornaments (chevron); a multi-shape ornament cannot rotate as a unit in V1 (no group transform — D-041). Layer selects z-order: background renders behind body content, foreground above it (RFC §10.2).

func (Decoration) NodeKind

func (Decoration) NodeKind() NodeKind

type DecorationKind

type DecorationKind int

DecorationKind selects how a Decoration is sourced.

const (
	// DecorationPreset renders a curated ornament natively (SVG → preset/path).
	DecorationPreset DecorationKind = iota
	// DecorationAsset renders caller-supplied bytes as a pic.
	DecorationAsset
	// DecorationText renders a large, low-opacity text watermark (an oversized
	// ghost number/word behind the body) from Decoration.Text (D-109). Appended
	// last so existing DecorationKind values are unchanged (byte-identical).
	DecorationText
)

type DeltaTone

type DeltaTone int

DeltaTone selects the color direction of a Stat's delta (D-057). The zero value DeltaNeutral is muted, so a delta with no tone set reads as neutral.

const (
	DeltaNeutral DeltaTone = iota // muted (zero value)
	DeltaUp                       // positive — success color
	DeltaDown                     // negative — error color
)

type Divider

type Divider struct {
	Spacing SpaceRole
	// contains filtered or unexported fields
}

Divider is a horizontal rule with surrounding spacing.

func (Divider) NodeKind

func (Divider) NodeKind() NodeKind

type Duotone

type Duotone struct {
	// Shadow is the role the photo's dark tones map to.
	Shadow pptx.ColorRole
	// Highlight is the role the photo's light tones map to.
	Highlight pptx.ColorRole
}

Duotone is an optional two-tone recolor applied to a photographic background (R14.1): the photo's shadows map to Shadow and its highlights to Highlight, producing an on-brand tint. Both are surface color roles resolved against the active theme (P2), so a theme swap re-tints the photo. A nil Background.Duotone leaves the photo at its natural colors (byte-identical). Applies only when Kind == BackgroundAsset.

type ElevationRole

type ElevationRole = pptx.ElevationRole

Elevation roles.

type Fit

type Fit = pptx.Fit

Fit is the image fill mode, re-exported from the builder (D-039). V1 ships FitFill (the default — stretches to fill the box) and FitNone; aspect-aware cover/contain are not in V1 (they need pixel dimensions, forbidden by §7).

type Flow

type Flow struct {
	Orientation FlowOrientation
	Steps       []FlowStep
	Connector   ConnectorKind
	// contains filtered or unexported fields
}

Flow is a sequential step pipeline. Connector is additive (D-044): its zero value (ConnectorArrow) preserves a solid-arrow flow.

func (Flow) NodeKind

func (Flow) NodeKind() NodeKind

type FlowOrientation

type FlowOrientation int

FlowOrientation selects a flow's direction.

const (
	FlowHorizontal FlowOrientation = iota
	FlowVertical
)

type FlowStep

type FlowStep struct {
	Label  RichText
	Detail RichText
	Icon   string
}

FlowStep is one step in a Flow: a label, optional detail line, and optional icon. Icon is a closed-name curated/extension icon (Stage-1 validated), like a card's (D-044); its zero value renders a plain pill.

type FrameKind

type FrameKind int

FrameKind selects optional device-frame chrome around an image.

const (
	FrameNone FrameKind = iota
	FrameBrowser
	FramePhone
	FrameDesktop
	FrameLaptop
)

type FrameRecipe

type FrameRecipe = frames.Recipe

FrameRecipe draws a device frame's bezel into a region and returns the interior Box the renderer inserts an image into, plus the number of bezel shapes emitted. It composes the public pptx builder only (P1). Register one under a name with WithFrameExtension (RFC §14.4, D-038).

type Funnel

type Funnel struct {
	Stages []FunnelStage
	// contains filtered or unexported fields
}

Funnel is a tapering N-stage process diagram (R14.11, D-128): stacked bands of decreasing width with an optional per-stage value label. Native rects; pure integer-EMU → byte-identical. A deck with no Funnel is byte-identical.

func (Funnel) NodeKind

func (Funnel) NodeKind() NodeKind

type FunnelStage

type FunnelStage struct {
	Label       string
	Value       string
	AccentIndex int
}

FunnelStage is one band of a Funnel (D-128): a label + optional value caption.

type GradientFill

type GradientFill struct {
	From  ColorRole
	To    ColorRole
	Angle int
}

GradientFill is an optional 2-stop linear surface fill for a Card (D-108): a From→To linear gradient at Angle degrees clockwise from the positive x-axis (0 = left→right, 90 = top→bottom). Both stops are surface color roles resolved against the active theme, so a theme swap re-paints both (P2). A nil *GradientFill leaves the card on its solid Fill (byte-identical).

type GradientStop

type GradientStop struct {
	// Pos is the stop position along the gradient axis, in [0,1].
	Pos float64
	// Color is the surface color role at this stop.
	Color pptx.ColorRole
}

GradientStop is one color stop in a multi-stop background gradient (D-105). Pos is the stop position in [0,1] (0 = start, 1 = end); Color is a surface role resolved against the active theme so a theme swap re-paints the stop (P2).

type Grid

type Grid struct {
	Columns    int
	Ratio      []int // per-column weights; empty = equal
	Gap        SpaceRole
	Cells      []SlideNode
	Connectors []GridConnector // inter-column gutter glyphs; empty = none
	// Fill opts the grid into claiming leftover body-stack height under
	// VAlignTop without enabling slide-wide VAlignFill (D-143). The taller slot is
	// then subdivided by layout.Grid into proportionally taller equal-height rows.
	// Zero=false preserves today's natural-height slot exactly. Under any slide
	// VAlign other than VAlignTop this field is inert in V1; slide-wide fill modes
	// (`VAlignFill` / `VAlignFillCapped`) continue to own slack distribution.
	Fill bool
	// contains filtered or unexported fields
}

Grid is a 2/3/4-column layout with weighted ratios and one child per cell. Connectors (additive, R12.4) draw glyphs in the gutters between adjacent columns; an empty Connectors slice renders byte-identically.

func (Grid) NodeKind

func (Grid) NodeKind() NodeKind

type GridConnector

type GridConnector struct {
	Between [2]int        // adjacent column indices, e.g. {0, 1}
	Kind    ConnectorKind // glyph; ConnectorBiArrow = a bidirectional arrow
	Label   string        // optional caption in the gutter; "" = none
}

GridConnector draws a connector glyph in the gutter between two adjacent columns of a Grid (R12.4, D-099), so an architecture / pipeline grid reads as data flow, not just adjacency. Between holds the two adjacent column indices ({c, c+1}); Kind reuses the Flow connector set (plus ConnectorBiArrow); Label is an optional caption.

type HAlign

type HAlign int

HAlign selects horizontal text alignment within the body region. The zero value HAlignLeft is the default (left-flush, full-width box). Per-node Align fields and the slide Content.Horizontal use this type.

const (
	// HAlignLeft (zero value) is the default: text leaf nodes span the full
	// body width and render left-aligned paragraphs. Backward-compatible.
	HAlignLeft HAlign = iota
	// HAlignCenter sets paragraph alignment to center on text leaf nodes
	// (Hero, Heading, Prose, Quote). The text box keeps its full body width;
	// each paragraph line is centered within that frame. For Chip nodes the
	// box is physically centered instead (the pill should move, not just its
	// text).
	HAlignCenter
	// HAlignRight sets paragraph alignment to right on text leaf nodes.
	// For Chip nodes the box is physically placed at the body right edge.
	HAlignRight
)

func (HAlign) String

func (h HAlign) String() string

String returns the horizontal alignment name.

type HeaderGroup

type HeaderGroup struct {
	// Label is the group heading (e.g. "Enterprise").
	Label string
	// Span is the number of columns the group covers (>= 1).
	Span int
}

HeaderGroup is one merged span in a Table's grouped header row (D-118).

type Heading

type Heading struct {
	Text  RichText
	Level int
	Align HAlign // per-node horizontal alignment override; 0 = inherit slide
	// AutoFit opts the heading text into shrink-to-fit: when its estimated width
	// exceeds the box, the engine downscales every run by one shared factor so it
	// fits one line, within a pinned minimum ratio. Zero = off, byte-identical.
	// (D-074.)
	AutoFit bool
	// contains filtered or unexported fields
}

Heading is a section heading at the given level (1–6). Align overrides the slide's Content.Horizontal for this node; the zero value (HAlignLeft) inherits the slide default.

func (Heading) NodeKind

func (Heading) NodeKind() NodeKind

type Hero

type Hero struct {
	Eyebrow  string
	Title    string
	Subtitle string
	Align    HAlign // per-node horizontal alignment override; 0 = inherit slide
	// AutoFit opts the Title (the display run) into shrink-to-fit: when its
	// estimated width exceeds the box, the engine downscales the Title font so it
	// fits one line, within a pinned minimum ratio. Zero = off, byte-identical.
	// (D-074.)
	AutoFit bool
	// contains filtered or unexported fields
}

Hero is a cover-slide title block: eyebrow + title + optional subtitle. Align overrides the slide's Content.Horizontal for this node; the zero value (HAlignLeft) inherits the slide default.

func (Hero) NodeKind

func (Hero) NodeKind() NodeKind

type IconRow

type IconRow struct {
	Icon  string
	Label RichText
	Meta  RichText // optional, right-aligned; nil = none
	Tone  RowTone
}

IconRow is one row of an IconRows: a leading icon, a rich label, and an optional right-aligned meta. Icon is a closed-name curated/extension icon (Stage-1 validated); "" renders no glyph (the label starts at the left).

type IconRows

type IconRows struct {
	Rows       []IconRow
	Fill       bool      // distribute rows to fill the box height
	GlyphColor ColorRole // icon tint; zero (ColorCanvas) = ColorAccent
	// contains filtered or unexported fields
}

IconRows is a vertical stack of [icon | label | optional meta] rows (R12.7, D-100): the "integrations / capabilities / sources" list that reads as designed rows rather than bullets. Fill distributes inter-row spacing so the rows span the box height (like VAlignFill); GlyphColor tints every row's icon (its zero value, ColorCanvas, defaults to ColorAccent — a canvas-colored glyph would be invisible). Additive: a deck with no IconRows is byte-identical.

func (IconRows) NodeKind

func (IconRows) NodeKind() NodeKind

type Image

type Image struct {
	AssetID   AssetID
	Alt       string
	Frame     FrameKind
	FrameName string
	Crop      Crop
	Fit       Fit
	// CornerRadius rounds the picture's corners from a theme radius token (D-114).
	// RadiusNone (the zero value) leaves the picture rectangular — byte-identical.
	CornerRadius RadiusRole
	// Elevation casts a soft drop shadow on the picture from a theme elevation
	// token (D-114). ElevationFlat (the zero value) emits no shadow —
	// byte-identical. Matches the card/surface finish.
	Elevation ElevationRole
	// Annotations overlay numbered pins, highlight boxes, and leader-line captions
	// on the image at fractional (0..1) coordinates of the image box (R14.17,
	// D-130). Native shapes; empty = no overlay (byte-identical).
	Annotations *ImageAnnotations
	// contains filtered or unexported fields
}

Image is an asset image with optional frame chrome (renders as a pic shape).

Frame selects one of the curated device frames by enum; FrameName selects a frame by name and, when non-empty, takes precedence over Frame — it is the seam for a caller frame registered via scene.WithFrameExtension (D-038). With both unset (FrameNone, "") the image renders without a bezel.

Crop trims the source image per edge; Fit selects the fill mode. Both are mechanism exposure of the builder's crop/fit (D-039); their zero values (Crop{}, FitFill) render the image uncropped and stretched.

func (Image) NodeKind

func (Image) NodeKind() NodeKind

type ImageAnnotations

type ImageAnnotations struct {
	Pins       []ImagePin
	Highlights []ImageHighlight
}

ImageAnnotations is an optional overlay on an Image (R14.17, D-130): numbered pins at fractional coordinates, highlight rectangles around regions, each soul-styled and drawn as native shapes over the picture.

type ImageHighlight

type ImageHighlight struct {
	X, Y, W, H  float64
	AccentIndex int
}

ImageHighlight is a rectangle (fractions of the image box) outlined to draw attention to a region.

type ImagePin

type ImagePin struct {
	X, Y        float64
	Label       string // the pin's number/letter (e.g. "1")
	Caption     string // optional off-pin caption; "" = no caption/leader
	AccentIndex int
}

ImagePin is a numbered callout marker at (X,Y) in [0,1] of the image box, with an optional caption drawn beside it and a leader line from the pin to it.

type JoinPosition

type JoinPosition int

JoinPosition selects where a TwoColumn's Join element sits (R12.8, D-101). The zero value JoinSeam centers it on the vertical seam between the columns (the D-055 default); JoinTopBridge / JoinBottomBridge draw a horizontal accent bracket spanning both columns' combined width at the top / bottom edge, with the JoinLabel as a centered pill on it — the "one X, two ways" header used on option/path slides.

const (
	JoinSeam         JoinPosition = iota // centered on the seam (zero value, D-055)
	JoinTopBridge                        // a bracket spanning both column tops
	JoinBottomBridge                     // a bracket spanning both column bottoms
)

type Layer

type Layer int

Layer selects whether a decoration renders behind or above body content.

const (
	LayerBackground Layer = iota
	LayerForeground
)

type LayoutKind

type LayoutKind int

LayoutKind names a slide's structural intent; it maps to a master layout at render time (RFC §10.1).

const (
	LayoutCover LayoutKind = iota
	LayoutTitleContent
	LayoutTwoColumn
	LayoutCardGrid
	LayoutFullBleed
	LayoutBlank
)

type LayoutMap

type LayoutMap map[LayoutKind]string

LayoutMap maps a scene LayoutKind (a structural intent) to a named layout in the active template's master (RFC §13.2). When a scene is rendered with WithLayoutMap, each slide's LayoutKind is resolved through the map to a layout name and the slide is related to that template layout; an entry whose name the template doesn't define falls back to the blank layout and records a LayoutWarning (the engine never errors on a layout miss — D-026).

func DefaultLayoutMap

func DefaultLayoutMap() LayoutMap

DefaultLayoutMap maps each LayoutKind to the conventional PowerPoint standard layout name. It is a convenience for callers ingesting a stock template whose layouts use PowerPoint's default English names; a brand kit with custom layout names needs a caller-supplied map. Unmapped kinds resolve to the blank layout.

type LayoutWarning

type LayoutWarning struct {
	SlideID string
	Node    string
	Message string
}

LayoutWarning is a non-fatal layout issue surfaced in Stats.Warnings (e.g. content overflow). A caller that wants warnings to be fatal inspects Stats.Warnings itself — pptx-go has no strict mode (RFC §10.2).

type List

type List struct {
	Kind  ListKind
	Items []ListItem
	// Indent selects the bullet hanging-indent density. IndentNormal (zero) is
	// byte-identical to the pre-R10.9 render; IndentTight tightens the
	// marker-to-text offset consistently across all items and levels. (D-078.)
	Indent ListIndent
	// contains filtered or unexported fields
}

List is a bullet / numbered / checklist block.

func (List) NodeKind

func (List) NodeKind() NodeKind

type ListIndent

type ListIndent int

ListIndent selects a list's bullet hanging-indent density (the marker-to-text offset). The zero value IndentNormal preserves the default; IndentTight packs the markers closer to their text for dense lists. (D-078.)

const (
	IndentNormal ListIndent = iota
	IndentTight
)

type ListItem

type ListItem struct {
	Text    RichText
	Level   int
	Checked bool // checklist items
}

ListItem is one entry in a List.

type ListKind

type ListKind int

ListKind selects a list's marker style.

const (
	ListBullet ListKind = iota
	ListNumber
	ListChecklist
)

type Lockup

type Lockup struct {
	Caption   string
	AssetID   AssetID   // the partner logo (resolved via AssetResolver); "" = use Icon
	Icon      string    // a curated/extension glyph instead of an asset; "" = use AssetID
	AssetSide AssetSide // logo before (TrailCaption) or after (LeadCaption) the caption
	MaxHeight pptx.EMU  // logo height bound; 0 = a pinned default
	Align     HAlign    // per-node horizontal alignment override; 0 = inherit slide
	// contains filtered or unexported fields
}

Lockup is a compact "powered by / in partnership with" attribution mark (R12.9, D-102): a caption paired with a small partner logo composed as one inline, centerable unit. The mark is either an AssetID (a partner logo, resolved via the AssetResolver — renders as a pic) or an Icon (a curated/extension glyph — media-free); exactly one is set. AssetSide places the logo before or after the caption; MaxHeight height-bounds the logo (a pinned default when 0); Align positions the whole group (zero = inherit the slide). Additive: a deck with no Lockup is byte-identical.

func (Lockup) NodeKind

func (Lockup) NodeKind() NodeKind

type LogoEntry

type LogoEntry struct {
	AssetID AssetID
	Alt     string
}

LogoEntry is one logo in a LogoWall (D-125): an asset reference + alt text.

type LogoToneKind

type LogoToneKind int

LogoToneKind selects a logo wall's uniform recolor treatment (R14.7, D-125).

const (
	// LogoToneNone keeps each logo's natural colors.
	LogoToneNone LogoToneKind = iota
	// LogoToneMono recolors every logo to a brand-neutral two-tone (TextPrimary →
	// Canvas) so a mixed set reads as one cohesive, monochrome wall.
	LogoToneMono
	// LogoToneBrand recolors every logo to the accent two-tone (Accent → Canvas).
	LogoToneBrand
)

type LogoWall

type LogoWall struct {
	Logos   []LogoEntry
	Columns int          // logos per row (>=1; 0 defaults to a pinned column count)
	Tone    LogoToneKind // uniform recolor (none / mono / brand)
	Caption string       // optional heading ("Trusted by", "Integrates with")
	// contains filtered or unexported fields
}

LogoWall is an N-up grid of logo assets normalized to a common cell, optionally recolored to a uniform tone so a mixed-style set reads as one cohesive wall (R14.7, D-125). Each logo is contained (not cropped) and centered in its cell. Asset-bearing (resolved via the AssetResolver); a missing logo warns and is skipped (RFC §10.2). A deck with no LogoWall is byte-identical.

func (LogoWall) NodeKind

func (LogoWall) NodeKind() NodeKind

type MeshGlow

type MeshGlow struct {
	// Anchor is where the glow pools on the slide (its center).
	Anchor Anchor
	// Color is the glow's surface color role (resolved against the active theme).
	Color pptx.ColorRole
	// Radius is the glow circle's radius in EMU; a non-positive radius is skipped.
	Radius pptx.EMU
	// Alpha is the glow center's OOXML opacity (0..100000); keep it low for a
	// subtle pool. The edge fades to fully transparent.
	Alpha int
}

MeshGlow is one pooled radial glow in a BackgroundMesh (D-112): a soft circle of light at Anchor, of the surface role Color, radius Radius (EMU), fading from the center alpha Alpha (OOXML 0..100000) to transparent at the edge.

type Metadata

type Metadata struct {
	Title   string
	Author  string
	Subject string
}

Metadata is deck-level core metadata.

type Milestone

type Milestone struct {
	Position    float64
	Label       string
	Detail      string
	Icon        string
	AccentIndex int
}

Milestone is one point on a Timeline axis (D-119). Position is the proportional location along the axis in [0,1]; Label is the marker heading, Detail an optional sub-line; Icon (optional, curated/extension) replaces the dot marker; AccentIndex selects the marker color from a pinned token cycle (0 = ColorAccent).

type NodeKind

type NodeKind int

NodeKind discriminates a SlideNode.

const (
	KindHero NodeKind = iota
	KindProse
	KindHeading
	KindList
	KindDivider
	KindQuote
	KindCallout
	KindImage
	KindChip
	KindArrow
	KindCodeBlock
	KindChart
	KindTable
	KindFlow
	KindDecoration
	KindSectionDivider
	KindTwoColumn
	KindGrid
	KindCard
	KindCardSection
	KindBento
	KindStat
	KindButton
	KindChecklist
	KindChipRow
	KindBanner
	KindIconRows
	KindLockup
	KindTimeline
	KindDataMark
	KindQuadrant
	KindLogoWall
	KindTree
	KindFunnel
	KindCycle
)

func (NodeKind) String

func (k NodeKind) String() string

String returns the node kind's IR name.

type NumberFormat

type NumberFormat struct {
	// Decimals is the fixed number of decimal places (0 = integer). For compact
	// notation, 0 is treated as 1 (so 1_200_000 → "1.2M", not "1M").
	Decimals int
	// GroupSep is the thousands separator ("," / "." / " "); "" = no grouping.
	GroupSep string
	// DecimalSep is the decimal point; "" defaults to ".".
	DecimalSep string
	// CurrencySymbol is prepended (or appended, see SymbolAfter); "" = none.
	CurrencySymbol string
	// SymbolAfter places the currency symbol after the number (e.g. "4.000 €").
	SymbolAfter bool
	// Percent multiplies the value by 100 and appends "%".
	Percent bool
	// Compact renders large magnitudes as K / M / B / T (e.g. 1_200_000 → "1.2M").
	Compact bool
	// CompactThreshold is the magnitude at/above which Compact applies; 0 = 1000.
	CompactThreshold float64
	// Prefix / Suffix are arbitrary affixes (e.g. a "+" suffix for "$4,000+").
	Prefix string
	Suffix string
}

NumberFormat is a deterministic number / currency / percent / locale format (R14.13, D-121). It is a caller-supplied mechanism (the soul's number token): the engine formats a numeric value with it, but never decides the format itself (D-026). FormatNumber applies it; a Stat carries an optional Number + NumberFormat that render through it (raw-string Stat.Value is unaffected).

The zero value formats a number with no grouping, no decimals, and no affixes (e.g. 4000 → "4000") — an identity-ish format. A en-US currency sets GroupSep "," and CurrencySymbol "$"; a de-DE locale sets GroupSep "." and DecimalSep ",".

type OrnamentRecipe

type OrnamentRecipe = ornaments.Recipe

OrnamentRecipe draws an ornament into a box at a caller opacity (OOXML alpha) and rotation, returning the shape count. It composes the public pptx builder only (P1). Register one under a name with WithOrnamentExtension.

type Policy

type Policy struct {
	// Image reports whether the node renders as a pic shape (vs native shapes).
	Image bool
	// HasAsset reports whether the node's IR carries an AssetID field.
	HasAsset bool
}

Policy is a node type's intrinsic rendering policy.

func PolicyFor

func PolicyFor(k NodeKind) Policy

PolicyFor returns the rendering policy for a node kind.

type Position

type Position = pptx.Position

Position and Size are EMU geometry types reused from the builder, carried on the Decoration node (offset + size).

type Prose

type Prose struct {
	Paragraphs []RichText
	Align      HAlign // per-node horizontal alignment override; 0 = inherit slide
	// contains filtered or unexported fields
}

Prose is one or more body paragraphs. Align overrides the slide's Content.Horizontal for this node; the zero value (HAlignLeft) inherits the slide default.

func (Prose) NodeKind

func (Prose) NodeKind() NodeKind

type Quadrant

type Quadrant struct {

	// AxisX / AxisY carry the low/high end captions for each axis.
	AxisX QuadrantAxis
	AxisY QuadrantAxis
	// Quadrants are optional per-cell tint + title, indexed 0=top-left, 1=top-right,
	// 2=bottom-left, 3=bottom-right. A nil Fill draws no tint.
	Quadrants [4]QuadrantCell
	// Items are plotted points; X/Y in [0,1] with the origin at the bottom-left.
	Items []QuadrantItem
	// contains filtered or unexported fields
}

Quadrant is a 2x2 positioning map (R14.9, D-124): labeled X/Y axes with low/high end captions, optional per-quadrant tint + title, and items plotted at caller (x,y) coordinates in [0,1] (origin bottom-left). Axes, dividers, item dots, and labels draw as native shapes; labels clamp/stagger to stay on-canvas. Pure integer-EMU layout → byte-identical; a deck with no Quadrant is byte-identical (a new node, absent until used).

func (Quadrant) NodeKind

func (Quadrant) NodeKind() NodeKind

type QuadrantAxis

type QuadrantAxis struct {
	LowLabel  string
	HighLabel string
}

QuadrantAxis is one axis's end captions (D-124).

type QuadrantCell

type QuadrantCell struct {
	Title string
	Fill  *ColorRole // nil = no tint
}

QuadrantCell is an optional per-quadrant tint + title (D-124).

type QuadrantItem

type QuadrantItem struct {
	X           float64
	Y           float64
	Label       string
	AccentIndex int
}

QuadrantItem is a plotted point (D-124): X/Y in [0,1] (origin bottom-left), a Label, and an AccentIndex selecting the dot color from a pinned token cycle.

type Quote

type Quote struct {
	Text        RichText
	Attribution string
	Align       HAlign // per-node horizontal alignment override; 0 = inherit slide
	// Testimonial enrichments (R14.5, D-120). Each zero value omits its element, so
	// a Quote with only Text+Attribution renders byte-for-byte as before. When any
	// of these is set the enriched testimonial layout runs: an optional oversized
	// quotation Mark behind the text, an optional rounded Avatar, a structured
	// attribution (Name / Role / Company), and an optional customer Logo.
	Mark bool // draw a large, low-emphasis quotation glyph behind the quote text
	// AvatarAssetID is the author's avatar (resolved via the AssetResolver, drawn
	// as a rounded picture); "" = no avatar.
	AvatarAssetID AssetID
	// AttributionName / Role / Company are the structured attribution; when Name
	// is set they supersede the flat Attribution string in the enriched layout.
	AttributionName    string
	AttributionRole    string
	AttributionCompany string
	// LogoAssetID is the customer/brand logo (resolved via the AssetResolver); ""
	// = no logo.
	LogoAssetID AssetID
	// contains filtered or unexported fields
}

Quote is a pull quote with optional attribution. Align overrides the slide's Content.Horizontal for this node; the zero value (HAlignLeft) inherits the slide default.

func (Quote) NodeKind

func (Quote) NodeKind() NodeKind

type RadiusRole

type RadiusRole = pptx.RadiusRole

Corner-radius roles.

type RenderOption

type RenderOption func(*renderConfig)

RenderOption configures a Render call.

func WithAssetResolver

func WithAssetResolver(r AssetResolver) RenderOption

WithAssetResolver registers the AssetResolver used to fetch asset bytes (§10.6).

func WithContext

func WithContext(ctx context.Context) RenderOption

WithContext sets the context Render uses: the AssetResolver receives it, and Render honors cancellation between slides (returning ctx.Err()). The default is context.Background(). (CLAUDE.md §5 — honor cancellation on I/O.)

func WithFrameExtension

func WithFrameExtension(name string, recipe FrameRecipe) RenderOption

WithFrameExtension registers a caller frame recipe under name for this render (RFC §14.4, D-038). The name joins the closed curated set {browser, phone, desktop, laptop}; registering a curated name overrides that frame for this render only. Extensions are per-render, not global state — concurrent renders with different extensions do not interfere. An Image whose resolved frame name is neither curated nor registered fails Stage-1 validation. A blank name or nil recipe is ignored.

func WithIconExtension

func WithIconExtension(name string, svg []byte) RenderOption

WithIconExtension registers a caller icon under name for this render (RFC §14.1/§14.4, D-005). The SVG is validated when the option is applied; an SVG that violates the icon translator constraints (single path, solid fill, no gradients, no elliptical arcs) fails the render with a Stage-1 error — at registration, not at compose. Registering a curated name overrides it for this render only. A blank name or nil SVG is ignored. The icon is placed by the nodes that accept one (card, flow) in later phases.

func WithLayoutMap

func WithLayoutMap(m LayoutMap) RenderOption

WithLayoutMap maps each slide's LayoutKind to a named layout in the active template's master (RFC §13.2). A slide whose mapped layout the template defines is related to it; an unmapped kind, or a name the template lacks, falls back to the blank layout (the latter records a LayoutWarning).

func WithLogger

func WithLogger(l *slog.Logger) RenderOption

WithLogger injects a structured logger for render diagnostics (no logger = no logs; D-016). When set, Render emits a render-boundary summary and a Warn event for every LayoutWarning (RFC §18); the handler's performance is the caller's concern (slog calls are synchronous).

func WithOrnamentExtension

func WithOrnamentExtension(name string, recipe OrnamentRecipe) RenderOption

WithOrnamentExtension registers a caller ornament recipe under name for this render (RFC §14.2/§14.4, D-038). The name joins the closed curated set; registering a curated name overrides it for this render only. Extensions are per-render, not global. A Decoration whose preset name is neither curated nor registered fails Stage-1 validation. A blank name or nil recipe is ignored.

func WithTheme

func WithTheme(t *pptx.Theme) RenderOption

WithTheme applies t as the active theme for the render — the brand-kit flow (RFC §13.1, §13.3): a scene authored against token roles re-renders in the brand's palette and fonts (P2). It takes precedence over the Scene's Theme field. A nil theme is ignored.

func WithWorkers

func WithWorkers(n int) RenderOption

WithWorkers sets the number of slides composed concurrently (D-015). The default (n <= 0) is runtime.GOMAXPROCS(0); n == 1 forces sequential rendering. Render stays idempotent (byte-identical output) regardless of n: slides are created in scene order before composition, and any slide that registers global media renders sequentially in scene order so media numbering is stable.

type Ribbon

type Ribbon struct {
	Text      string
	Position  RibbonPos
	Color     *ColorRole    // nil = ColorAccent
	TextColor TextColorRole // zero (TextPrimary) = auto-contrast on Color
}

Ribbon is a pinned emphasis badge on a Card (R12.3, D-098): a "MOST POPULAR" / "RECOMMENDED" / "NEW" marker that singles one card out of a row. It sits OUTSIDE the header text flow — distinct from Card.HeaderPill (an in-row pill). A RibbonTopBar reserves a band so the card body shifts down (cardHeaderBottom accounts for it); the corner positions are overlays.

Color is the badge fill; nil selects ColorAccent (ColorRole's zero value is the real color ColorCanvas, so the override is a pointer — the D-054 pattern). TextColor colors the label; its zero value (TextPrimary) auto-contrasts against Color.

type RibbonPos

type RibbonPos int

RibbonPos selects where a Card.Ribbon is pinned (R12.3, D-098). The zero value RibbonTopBar is a full-width tab across the card's top edge that reserves its own band (the card body shifts down below it); the corner positions are overlays that do not shift the body.

const (
	RibbonTopBar     RibbonPos = iota // full-width tab across the top (reserves a band)
	RibbonCornerTL                    // a text tab pinned in the top-left corner
	RibbonCornerTR                    // a text tab pinned in the top-right corner
	RibbonCornerStar                  // a star glyph in the top-right corner (Text ignored)
)

type RichText

type RichText []TextRun

RichText is an ordered list of styled text runs.

type RowTone

type RowTone int

RowTone selects an IconRow's framing (R12.7, D-100). The zero value RowPlain draws no frame; RowPill wraps the row in a SurfaceAlt rounded-rect.

const (
	RowPlain RowTone = iota // no frame (zero value)
	RowPill                 // a SurfaceAlt rounded-rect frame around the row
)

type RunStyle

type RunStyle struct {
	TypeRole  TypeRole
	Bold      bool
	Italic    bool
	Underline bool
	Strike    bool
	Code      bool
	Link      bool
	Href      string
	// Superscript raises the run above the baseline at a reduced size — a footnote
	// marker on a figure/stat (R14.12, D-126). Zero = on the baseline.
	Superscript bool
}

RunStyle is the inline styling of a TextRun. TypeRole selects the typography scale; the booleans are inline toggles. Code is inline code (mono + tint, D-013); Link marks the run as a hyperlink with Href as its target.

type Scene

type Scene struct {
	Theme  *pptx.Theme // optional; the builder's default theme if nil
	Slides []SceneSlide
	Meta   Metadata
	Chrome Chrome // optional opt-in slide chrome; zero value = disabled
}

Scene is the input to Render.

type SceneSlide

type SceneSlide struct {
	ID         string
	Layout     LayoutKind
	Nodes      []SlideNode
	Notes      RichText
	Variant    Variant
	Content    Alignment  // body-stack alignment; zero value = top-left (default)
	Background Background // full-bleed slide background; zero value = no background (BackgroundNone)
	Section    string     // chrome: top eyebrow label; empty = no eyebrow on this slide
	PageNumber int        // chrome: the N in "N / total"; 0 = scene position (1-based)
	// Footnotes are source/citation/disclaimer lines pinned to a reserved band at
	// the bottom of the slide (above the chrome footer), in the muted text role
	// (R14.12, D-126). The body region shrinks to reserve the band, so footnotes
	// never overlap the body or the page-number footer. Empty = no band
	// (byte-identical). Lines past a region cap are dropped with a warning.
	Footnotes []RichText
}

SceneSlide is one slide in a Scene: a layout intent, the top-level node list, optional speaker notes, a theme variant, body-stack alignment, and an optional full-bleed slide background. The zero value for Content ({VAlignTop, HAlignLeft}) reproduces the pre-Phase-13 layout unchanged — fully backward-compatible. A zero Background (BackgroundNone) draws nothing, so adding this field to existing call sites requires no change.

type Scrim

type Scrim struct {
	// Color is the overlay's surface color role.
	Color pptx.ColorRole
	// Opacity is the dense edge's OOXML opacity (0..100000).
	Opacity int
	// Gradient selects a transparent→Color linear gradient overlay when true,
	// else a flat solid wash at Opacity.
	Gradient bool
	// GradientAngle orients a gradient scrim in degrees; zero defaults to 90°.
	GradientAngle int
}

Scrim is an optional darkening (or tinting) overlay drawn over a slide's background fill so text reads legibly over a photographic or busy background (R14.1). It is a general mechanism: the engine draws it; the caller (soul) chooses the color and opacity that meet its contrast target (D-026). A nil Background.Scrim draws nothing (byte-identical).

Color is the overlay's surface color role (resolved against the active theme). The zero value (ColorCanvas) is a real color (white), so set it deliberately — a darkening scrim typically uses a dark surface or a literal-backed role.

Opacity is the overlay's OOXML opacity (0..100000); 0 draws an invisible overlay. For a solid scrim the whole overlay carries Opacity; for a gradient scrim the dense edge carries Opacity and the opposite edge is transparent.

Gradient, when true, draws a linear gradient scrim (transparent → Color at Opacity) instead of a flat wash — the classic bottom-heavy caption scrim. GradientAngle (degrees clockwise from the positive x-axis; 0° = left-to-right, 90° = top-to-bottom) orients it; the zero value defaults to 90° (top transparent, bottom dense). Gradient is ignored for a solid scrim.

type SectionDivider

type SectionDivider struct {
	Eyebrow string
	Label   string
	Align   HAlign // per-node horizontal alignment override; 0 = inherit slide
	// contains filtered or unexported fields
}

SectionDivider is a full-bleed chapter break (a whole slide). Align overrides the slide's Content.Horizontal for this node; the zero value (HAlignLeft) inherits the slide default.

func (SectionDivider) NodeKind

func (SectionDivider) NodeKind() NodeKind

type Size

type Size = pptx.Size

type SlideColors

type SlideColors struct {
	SlideID     string
	Canvas      pptx.RGB // resolved ColorCanvas (the slide's base background)
	Surface     pptx.RGB // resolved ColorSurface
	SurfaceAlt  pptx.RGB // resolved ColorSurfaceAlt (R8.10)
	Accent      pptx.RGB // resolved ColorAccent (R8.10)
	AccentAlt   pptx.RGB // resolved ColorAccentAlt (R8.10)
	PrimaryText pptx.RGB // resolved TextPrimary
	TextAccent  pptx.RGB // resolved TextAccent (R8.10)
}

SlideColors are the colors the engine actually resolved for one slide (D-058, extended R8.10): the canvas (base background), surface, alternate surface, accent + accent-alt, primary-text, and accent-text RGBs it rendered with — including a VariantDark slide's derived dark palette (so a soul's per-variant overrides are reflected). A caller uses them to verify soul→engine fidelity (resolved == the soul's intended token per role/variant) or to compute its own contrast; the engine performs no contrast logic (D-026), it only reports what it resolved. All fields are scalar RGB, so SlideColors stays comparable (==).

type SlideNode

type SlideNode interface {
	NodeKind() NodeKind
	// contains filtered or unexported methods
}

SlideNode is the sealed scene IR union. Construct one of the concrete node types in this package; the set is closed (isSlideNode is unexported).

type SlideTiming

type SlideTiming struct {
	SlideID  string
	Duration time.Duration
}

SlideTiming is the wall-clock time spent composing one slide, in scene order (D-015, D-016). Callers use it to detect render imbalance across a deck. It is never serialized into the PPTX, so it does not affect render idempotency.

type SpaceRole

type SpaceRole = pptx.SpaceRole

Spacing roles.

type Stat

type Stat struct {
	Value     string
	Label     string
	Delta     string    // "" = no delta line
	DeltaTone DeltaTone // color direction of Delta
	// AutoFit opts the Value (the display run) into shrink-to-fit: when its
	// estimated width exceeds the box, the engine downscales the Value font so a
	// long number/price fits one line, within a pinned minimum ratio. Zero = off,
	// byte-identical. (D-074.)
	AutoFit bool
	// Number + Format are the optional typed numeric path (R14.13, D-121): when
	// Number is non-nil it is formatted via Format (or the zero NumberFormat) and
	// supersedes the raw Value string, so a price/metric renders with correct
	// separators, currency, percent, or compact notation deterministically — then
	// the AutoFit shrink-to-fit keeps it on one line. nil Number = the raw Value
	// (byte-identical).
	Number *float64
	Format *NumberFormat
	// contains filtered or unexported fields
}

Stat is a hero big-number metric: a display-scale Value with a Label and an optional directional Delta (e.g. "$2,200" / "ARR" / "+12%"). A row of Stats inside a Grid forms a metric/pricing strip. The engine renders Value/Delta verbatim — it formats no numbers (D-026).

func (Stat) NodeKind

func (Stat) NodeKind() NodeKind

type Stats

type Stats struct {
	Slides   int
	Shapes   int
	Assets   int
	Warnings []LayoutWarning
	Timings  []SlideTiming
	Colors   []SlideColors // per-slide resolved colors, in scene order
}

Stats is the result of Render: per-render counts, per-slide timings, per-slide resolved colors, and non-fatal warnings (the library's observability surface — no event protocol, D-016).

func Render

func Render(pres *pptx.Presentation, s Scene, opts ...RenderOption) (Stats, error)

Render composes a Scene onto pres and returns render Stats (RFC §10.1). It applies the scene's theme (if any), validates (Stage 1), then lays out and composes each slide's nodes via the builder (P1). Render is deterministic given the same scene + theme: re-rendering produces byte-identical output.

Slides are created in scene order, then composed concurrently across a worker pool sized to runtime.GOMAXPROCS(0) (configurable via WithWorkers; D-015). A slide that may register global media renders sequentially in scene order so media part numbering — and therefore the bytes — stay deterministic; every other slide is independent and composes in parallel.

V1 renders the text-heavy leaf nodes (Phase 06); container and asset nodes not yet implemented surface a LayoutWarning and are skipped.

type Table

type Table struct {
	Headers []RichText
	Rows    [][]RichText
	Caption string
	// Style, when non-nil, applies comparison-matrix styling — a header band,
	// zebra body striping, a highlighted column, an emphasized row-label column,
	// and grouped header spans — all from theme tokens (R14.3, D-118). nil leaves
	// the plain banded table (byte-identical). A non-nil Style controls every cell
	// fill explicitly (it does not use the builder's default header/row banding).
	Style *TableStyle
	// contains filtered or unexported fields
}

Table is headered tabular data; every cell is RichText. A non-empty Caption renders as a separate text shape above the table.

func (Table) NodeKind

func (Table) NodeKind() NodeKind

type TableStyle

type TableStyle struct {
	// HeaderFill fills the header row with the accent band (contrast text).
	HeaderFill bool
	// Zebra alternates a subtle SurfaceAlt fill on odd body rows.
	Zebra bool
	// HighlightCol is the 1-based column to emphasize (accent tint + heavier
	// accent border) — e.g. a "recommended" plan column. 0 (the zero value) = none.
	HighlightCol int
	// RowLabelCol emphasizes the first column as row labels (SurfaceAlt fill + bold).
	RowLabelCol bool
	// HeaderGroups, when non-empty, adds a grouped header row above the headers:
	// each group's Label spans Span columns (merged), laid left-to-right from
	// column 0. The spans should sum to the column count.
	HeaderGroups []HeaderGroup
}

TableStyle is the additive visual styling for a comparison-matrix Table (R14.3, D-118). Every field's zero value reproduces an unstyled column, so a caller turns features on one at a time. Colors resolve from theme tokens (P2): the header band and highlighted column use ColorAccent, zebra and the row-label column use ColorSurfaceAlt. Cell-value glyphs (check / cross / dot / mini-bar) are intentionally not a Table feature — a native OOXML table cell holds only a text body (no shape children), so they are composed instead with a Bento of Checklist / IconRows cells (the glyph nodes already shipped — D-095/D-100).

type TextColor

type TextColor struct {
	// contains filtered or unexported fields
}

TextColor is a run color: a TextColorRole token (theme-bound, the default path) or a literal RGB (the escape hatch). The zero value is the token TextPrimary.

func LiteralColor

func LiteralColor(hex string) TextColor

LiteralColor returns an unbound literal color (a 6-hex string), bypassing the theme (RFC §9).

func TokenTextColor

func TokenTextColor(role TextColorRole) TextColor

TokenTextColor returns a token color bound to a semantic text role.

func (TextColor) IsLiteral

func (c TextColor) IsLiteral() bool

IsLiteral reports whether the color is a literal (vs a token).

func (TextColor) Literal

func (c TextColor) Literal() pptx.RGB

Literal returns the literal RGB (valid when IsLiteral is true).

func (TextColor) Role

func (c TextColor) Role() TextColorRole

Role returns the bound text-color role (valid when IsLiteral is false).

type TextColorRole

type TextColorRole = pptx.TextColorRole

Text color roles (inline runs).

type TextRun

type TextRun struct {
	Text  string
	Style RunStyle
	Color TextColor
}

TextRun is one styled span of text within a RichText.

type Timeline

type Timeline struct {

	// Milestones is the single-lane milestone list, used when Lanes is empty.
	Milestones []Milestone
	// Lanes are swimlanes (rows), each with its own milestones; supersedes
	// Milestones when non-empty.
	Lanes []TimelineLane
	// Bands are optional phase/horizon regions drawn behind the axis, each
	// spanning [From,To] of the timeline width.
	Bands []TimelineBand
	// contains filtered or unexported fields
}

Timeline is a roadmap / timeline node (R14.4, D-119): a horizontal axis with milestones placed at caller-specified proportional positions, optional phase bands behind them, and optional swimlanes (rows). Markers, the axis line, and labels compose from native preset shapes (no media). Labels stagger above / below the axis to avoid collision. Additive: a deck with no Timeline is byte-identical (it is a new node — unused means absent).

Either Milestones (a single implicit lane) or Lanes (explicit swimlanes) drives the markers; Lanes, when non-empty, supersedes Milestones. Bands span the full timeline width behind every lane.

func (Timeline) NodeKind

func (Timeline) NodeKind() NodeKind

type TimelineBand

type TimelineBand struct {
	From  float64
	To    float64
	Label string
	Fill  ColorRole
}

TimelineBand is a phase/horizon region behind a Timeline axis (D-119): it spans [From,To] (each in [0,1]) of the timeline width, filled with Fill (a surface role, low-alpha) and labeled at the top.

type TimelineLane

type TimelineLane struct {
	Label      string
	Milestones []Milestone
}

TimelineLane is one swimlane (row) of a Timeline (D-119): a left-gutter Label and its own milestones placed along the lane's axis.

type Tree

type Tree struct {
	Root        TreeNode
	Orientation FlowOrientation // FlowVertical = top-down (default); FlowHorizontal = left-right
	// contains filtered or unexported fields
}

Tree is a hierarchy / org-chart / taxonomy node (R14.10, D-127): a root with children laid out as a balanced top-down (or left-right) tidy tree, with elbow connector edges between parent and children and soul-styled nodes. Pure integer-EMU layout → byte-identical; depth/breadth past the safe area clamp + warn. A deck with no Tree is byte-identical (a new node, absent until used).

func (Tree) NodeKind

func (Tree) NodeKind() NodeKind

type TreeNode

type TreeNode struct {
	Label       string
	Detail      string
	Icon        string
	Children    []TreeNode
	AccentIndex int
}

TreeNode is one node in a Tree (D-127): a label + optional detail/icon, child nodes, and an AccentIndex selecting its border color from a pinned token cycle.

type TwoColumn

type TwoColumn struct {
	Ratio        ColumnRatio
	Left         []SlideNode
	Right        []SlideNode
	Join         ColumnJoin   // optional element centered on the column seam; JoinNone = none
	JoinLabel    string       // badge / bridge text when Join != JoinNone (e.g. "VS", "One agent")
	JoinPosition JoinPosition // JoinSeam (default) / JoinTopBridge / JoinBottomBridge (R12.8)
	// contains filtered or unexported fields
}

TwoColumn splits the body into left/right regions with leaf children. Join / JoinLabel / JoinPosition are additive (D-055, D-101): their zero values draw no inter-column element (or, for a non-None Join, the centered-seam element).

func (TwoColumn) NodeKind

func (TwoColumn) NodeKind() NodeKind

type TypeRole

type TypeRole = pptx.TypeRole

Typography roles.

type VAlign

type VAlign int

VAlign selects vertical alignment of the body stack within the body region. The zero value VAlignTop is the default (top-flush stack). The slide Content.Vertical field uses this type.

const (
	// VAlignTop (zero value) is the default: the body stack starts at the body
	// region's top edge. Backward-compatible.
	VAlignTop VAlign = iota
	// VAlignCenter distributes the remaining vertical space equally above and
	// below the body stack; the stack never starts above the top edge.
	VAlignCenter
	// VAlignBottom places the body stack flush with the body region's bottom
	// edge; the stack never starts above the top edge.
	VAlignBottom
	// VAlignJustify distributes the vertical slack evenly into the inter-node
	// gaps. Equivalent to VAlignTop for a single node or when slack ≤ 0.
	VAlignJustify
	// VAlignFill pins fixed leaves at the top (like VAlignTop) and grows the
	// flexible nodes (containers + Image/Chart) to consume the remaining body
	// height, so a sparse slide fills its frame instead of reading thin. With no
	// flexible node, or when slack ≤ 0, it is equivalent to VAlignTop.
	VAlignFill
	// VAlignFit is the compression inverse of VAlignFill: an opt-in fit-to-region
	// mode for over-full slides. When the body stack's preferred height exceeds
	// the region, the renderer applies a single deterministic compression pass —
	// it shrinks the inter-node gaps toward a pinned floor (SpaceXS) and, if still
	// overflowing, proportionally scales every node's slot height toward a pinned
	// ratio floor — so the last node's bottom lands inside the region instead of
	// clipping off-slide. When the content already fits, VAlignFit is
	// byte-identical to VAlignTop (top-pinned, standard gap). All math is integer
	// EMU / basis-point, so the result is deterministic regardless of worker
	// count. The card-interior-padding and display-type-scale sub-steps are
	// layered in by separate engine units.
	VAlignFit
	// VAlignFillCapped is VAlignFill with a ceiling: each flexible node grows by
	// at most a pinned factor of its preferred height, so a near-empty node cannot
	// balloon to consume all the slack. The leftover slack beyond the caps becomes
	// balanced spacing — an even top margin and widened inter-node gaps — instead
	// of inflating one node. With no flexible node, or when the stack already
	// fills the region, it is equivalent to VAlignTop. Deterministic integer EMU.
	VAlignFillCapped
	// VAlignBalanced distributes a sparse stack's slack as an even rhythm — a top
	// margin plus widened inter-node gaps (the slack split across the n+1 spaces of
	// the stack) — with an optical-center bias that seats the stack slightly above
	// geometric center. Unlike VAlignJustify (all slack into gaps, no margins) and
	// VAlignCenter (all slack into equal margins, fixed gaps), it spreads whitespace
	// across both, so a sparse cover or closing reads balanced rather than clustered
	// with a large void. With no slack it is equivalent to VAlignTop. Deterministic
	// integer EMU.
	VAlignBalanced
)

func (VAlign) String

func (v VAlign) String() string

String returns the vertical alignment name.

type Variant

type Variant int

Variant selects a named theme variant for a slide (RFC §13.3). VariantDark is implemented: it derives a per-slide dark theme and swaps the active theme for the duration of that slide's composition. VariantPrint is not yet implemented and surfaces a LayoutWarning rather than silently rendering with the active theme.

const (
	VariantLight Variant = iota
	VariantDark
	VariantPrint
)

func (Variant) String

func (v Variant) String() string

String returns the variant's name.

Directories

Path Synopsis
Package frames is the scene-side frame registry: it wires the curated device frames (assets/frames) to their reserved names and provides the per-render caller-extension overlay (RFC §14.4, D-038).
Package frames is the scene-side frame registry: it wires the curated device frames (assets/frames) to their reserved names and provides the per-render caller-extension overlay (RFC §14.4, D-038).
Package icons is the scene-side icon registry: it wires the curated icon set (assets/icons) to their names and provides the per-render caller-extension overlay (RFC §14.1/§14.4, D-005, D-040).
Package icons is the scene-side icon registry: it wires the curated icon set (assets/icons) to their names and provides the per-render caller-extension overlay (RFC §14.1/§14.4, D-005, D-040).
Package layout is the scene geometry engine (RFC §10.2): deterministic slot division of a parent box into columns and grids.
Package layout is the scene geometry engine (RFC §10.2): deterministic slot division of a parent box into columns and grids.
Package ornaments is the scene-side ornament registry: it wires the curated ornament recipes (assets/ornaments) to their names and provides the per-render caller-extension overlay (RFC §14.2/§14.4, D-005, D-038).
Package ornaments is the scene-side ornament registry: it wires the curated ornament recipes (assets/ornaments) to their names and provides the per-render caller-extension overlay (RFC §14.2/§14.4, D-005, D-038).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL