Modern Authoring Workflows
Carry a strong web design into editable slides with measured components, explicit HTML annotations, and a review bundle for every page.
Measured native components
from power_pptx import BBox
from power_pptx.design import Card, Column, MetricTile, Row, TextBlock
from power_pptx.util import Inches, Pt
Column([
TextBlock("A calmer operating rhythm.", font="DejaVu Sans",
size_pt=34, min_size_pt=30, max_lines=1, bold=True),
Row([
MetricTile("94%", "Adoption", font="DejaVu Sans"),
Card([TextBlock("Make the next move clear.", font="DejaVu Sans")]),
], gap=Pt(18), height=Inches(3)),
], gap=Pt(24)).render(slide, BBox.from_inches(.65, .6, 12, 6), strict_fonts=True)Rows distribute flexible width; columns measure natural heights and distribute spare height using grow weights. Padding and gaps use Pt/Inches lengths. Font sizes use integer points. Badges have intrinsic width. Trees are checked before shapes are created; impossible layouts raise LayoutOverflowError. Text and shapes stay editable, with measured line breaks saved.
Use NativeContent(builder, height=...) to reserve a chart or table slot. It receives (slide, bbox); the builder’s own behavior is outside layout preflight. Give components unique names to retrieve their first shape from the result. Container overlap declarations preserve sibling collision checks.
Bundled fonts, tracked labels, and tables
from power_pptx.design import Column, DataTable, TextBlock
from power_pptx.text import register_font_dir
register_font_dir("assets/fonts") # or POWER_PPTX_FONT_DIRS=assets/fonts
Column([
TextBlock("Active customers", font="Inter", size_pt=9, min_size_pt=9,
case="upper", letter_spacing=Pt(1.4), weight="semibold"),
DataTable(rows, columns=[1, 1, 2], font="Inter", max_lines=1, truncate=True),
], fill_last=True)register_font_dir makes fonts shipped with your project measurable without installing them, so strict_fonts=True behaves the same on a laptop, in Docker, and in CI. Each style is looked up separately; register_font_family pins explicit files per style and weight. TextBlock measures letter_spacing, weight, and case, so a tracked label that no longer fits raises LayoutOverflowError. Medium and SemiBold faces are written by their legacy family name, which is how PowerPoint selects them.
A column stretched by its row leaves spare height under its last card. Preflight warns with LayoutWarning; Column(fill_last=True) or grow on the last child fixes it, and slide.lint() reports the same problem as RaggedEdge. DataTable measures row heights from cell text and can truncate cells with an ellipsis. Set SOURCE_DATE_EPOCH for byte-identical builds.
Typography constraints
TextFrame.fit_text accepts min_size, max_lines, preserve_breaks, and line_spacing. preserve_breaks forbids additional wrapping; an impossible fit leaves formatting unchanged. power_pptx.text.measure_text provides read-only line and size measurements. Use installed fonts and strict metrics for final output; metric files do not embed fonts.
Annotated HTML to editable slides
from power_pptx.compose import from_html
prs = from_html("brief.html", mode="hybrid", reference_dir="browser-reference")| Annotation | Result |
|---|---|
| data-pptx="text" | Editable rich text with browser-measured line breaks |
| data-pptx="chart" | Native chart and workbook from data-pptx-chart JSON |
| data-pptx="table" | Editable table cells, merges, basic fills and borders |
| data-pptx="capture" | Independent captured visual |
Unmarked CSS stays in the background image. Annotated descendants are removed from the base and become foreground layers ordered by z-index and DOM order. Annotations cannot nest, overflow the section, or depend on arbitrary CSS stacking. Hybrid requires contain fitting and installed native fonts; font_map supports deliberate substitutions.
Native text supports basic rich runs, color, opacity, alignment, and padding. Put backgrounds and decoration on unmarked parents. Transforms, mixed sizes, RTL/vertical text, text-transform, letter spacing, and shadow/gradient text need separate text annotations or capture. Tables use plain cell text. Charts use a minimal native style and explicit data; supported types are column, bar, line, area, pie, and doughnut. Browser chart styling is not translated.
Browser figure export
add_plotly_figure(..., backend="browser", format="svg") uses self-contained Plotly.js and embeds SVG plus a browser PNG fallback. Install Plotly and the HTML extra with Chromium. backend="auto" tries Kaleido then the browser; backend="kaleido" disables fallback. figure_slide forwards options through plotly_options. Matplotlib keeps its direct exporter.
Review every saved slide
pip install 'power-pptx[embedding,review]'
python -m playwright install chromium
# Install LibreOffice separately; use Poppler or the PDFium review extra.
power-pptx review deck.pptx --out-dir review
power-pptx review brief.html --mode hybrid --out-dir review
power-pptx review one.pptx two.pptx --out-dir batch
power-pptx review deck.pptx --font-dir assets/fonts --out-dir reviewThe installed command accepts PPTX, HTML, JSON, and YAML. It saves PPTX, PDF, all PNGs, contact sheets, bundled schema/package checks, round-trip checks, font availability, an audit, and a local gallery. HTML inputs retain original browser references. --reference-html or --reference-dir enables comparisons; --max-error makes pixel differences a gate. --font-policy error gates missing explicit native fonts. Theme fonts are outside that inventory. --font-dir registers a font folder and hands it to LibreOffice, so previews use the real face instead of a fallback.
Inspect every rendered page for wrapping, clipping, contrast, and composition, then record findings in REVIEW.md. Automated reports mark visual review pending. Structural checks and pixel differences do not certify appearance or Microsoft PowerPoint playback.
The source examples/authoring_workflows/ directory builds three decks and nine slides using these public APIs. The bundled skill’s authoring-workflows.md documents the full contract.