Skip to main content

overset

Status: alpha (0.1.0). Rule codes and config keys may still change. Render rules depend on LibreOffice and poppler, and thresholds are tuned on a limited set of decks. The vision rules are experimental, and "as PowerPoint shows it" is an emulation of PowerPoint's layout in LibreOffice, not PowerPoint itself.

A deck linter. It renders a .pptx and measures what each slide actually shows: text off the slide, text spilling out of its frame, frames colliding, type too small, text too faint, fonts and colours off the brand. It reports with ruff-style rule codes you can select, ignore, and configure.

$ overset product_overview.pptx --config examples/brand.toml
product_overview.pptx:slide 2: OVS002 text spills out of 'text105'
    Up 42% year over
product_overview.pptx:slide 3: OVS203 167 words, over 90
product_overview.pptx:slide 4: OVS203 99 words, over 90

3 findings in 1 deck (OVS203 ×2, OVS002 ×1).

Overset is the typesetter's word for text that doesn't fit its frame.

It is the companion to riff, which lints a deck's words. overset lints what the words look like on the slide.

Why measure

A model reviewing its own slides misses things. A generated deck that the model had inspected slide by slide still shipped with a title running off the top of the slide and a caption slid out of its highlight pill. Both are measurable: LibreOffice renders the deck, and poppler's pdftotext -bbox-layout reports every word's box, including words pushed past the slide edge, which come back with negative coordinates. overset compares those boxes with the frames in the file.

Install

uv tool install git+https://github.com/scale-venture-partners/overset
uv tool install "overset[vision] @ git+https://github.com/scale-venture-partners/overset"   # + vision rules

The render rules need LibreOffice and poppler on PATH (brew install --cask libreoffice && brew install poppler, or apt install libreoffice-impress poppler-utils). Without them, --no-render runs the file-only rules, and a failed render is reported: the render rules are listed as skipped, never as passed.

Usage

overset deck.pptx                         # every default rule
overset deck.pptx --no-render             # file-only rules, no LibreOffice
overset deck.pptx --vision                # add the vision-model review (OVS4xx)
overset *.pptx --select OVS0 --format json
overset deck.pptx --keep-render out/      # keep the PDF and slide PNGs
overset --list-rules
overset --explain OVS002

Exit codes: 0 clean, 1 findings, 2 usage or file error.

Rules

Code Kind Rule
OVS000 structure The file isn't a well-formed package: a part with no content type, a relationship to a missing part, XML that doesn't parse (what PowerPoint offers to "repair")
OVS001 render Rendered text runs past the slide edge
OVS002 render Rendered text spills out of its own frame
OVS003 render Text from two frames is drawn on top of each other
OVS004 structure A text frame extends past the slide edge
OVS101 structure Text set below the minimum size (after shrink-to-fit)
OVS102 structure A font outside the configured set
OVS103 structure A colour outside the configured palette
OVS104 render Text too close in tone to what is behind it (sampled from pixels)
OVS201 structure A placeholder left empty
OVS202 structure A picture stretched out of its aspect ratio
OVS203 structure More words on a slide than an audience will read
OVS301 structure Two consecutive slides use the same layout (off by default)
OVS401–406 vision Clutter, weak hierarchy, misalignment, text over busy images, monotonous sequences, a slide that doesn't belong (opt-in)

Three kinds, by what a rule needs:

  • structure reads the .pptx alone: offline, milliseconds.
  • render measures a LibreOffice render: offline, seconds, and deterministic.
  • vision asks a model to look at every slide plus a contact sheet of the whole deck: a judgement, reported with a confidence, opt-in. It's for the questions nothing can measure (is this slide cluttered, do three slides in a row look the same). Measured problems are explicitly kept out of its rubric.

Rendered as PowerPoint shows it

The audience opens the deck in PowerPoint, so that is the layout overset measures. The two renderers disagree about one thing that matters a lot: shrink text on overflow (<a:normAutofit>). PowerPoint applies the scale stored in the file when it opens a deck, and recomputes it only when someone edits the text. A bare <a:normAutofit/> therefore shows at 100%. LibreOffice recomputes the shrink on every render, so text that overflows in PowerPoint fits in LibreOffice, and in any preview LibreOffice made.

Before rendering, overset freezes every shrink-to-fit box at its stored fontScale and lnSpcReduction (100% and 0 when absent). LibreOffice then draws PowerPoint's layout: the same line breaks, and the same text running into the next box. render-as = "libreoffice" turns this off.

Seen in practice: a generated deck rendered cleanly in LibreOffice previews, yet its cover subtitle and closing questions overlapped when opened in PowerPoint. The generator wrote a bare normAutofit and sized its boxes by estimate, counting on a shrink that PowerPoint never applied.

Measurement notes

  • pdftotext boxes run from a font's ascender to its descender, not its ink. A correctly placed 80pt title sticks out of its frame's top by about a fifth of its height. Overflow allowances therefore scale with each word, and collisions compare approximate ink, not metric boxes.
  • Frames set to grow with their text are exempt from OVS002: their stored box is stale, not wrong. OVS001 and OVS003 still catch growth that runs off the slide or into something else.
  • Words no frame claims (text drawn by a chart or SmartArt) are left alone, not reported.
  • overset renders the deck itself rather than trusting someone else's preview images, which can be stale.
  • Contrast is sampled from the pixels under each block of words: the background is the commonest colour, and the ink is whichever candidate contrasts with it most -- every colour with a real share of the pixels, plus the farthest one in tone. That handles digits on a dot smaller than their box (paper around the dot is not the ink) and small thin type (whose ink is spread over many faint shades).
  • Words are attributed to frames by reading order and column: pdftotext reads a row of cards line by line across the columns, so a word continues a frame's sequence only if it sits in that frame's column.
  • The package is checked before the deck is read (OVS000). A deck python-pptx can't load is reported as that finding, not as overset failing; a file that isn't a zip at all (a ~$deck.pptx lock file) is a usage error.
  • Decks that embed their fonts render in those fonts. For others, font-dirs registers font folders with fontconfig.

Configuration

overset.toml (or .overset.toml, or [tool.overset] in pyproject.toml), found from the deck's folder upward. Flags override it.

select = ["OVS0", "OVS1"]           # omit for every default-on rule
ignore = ["OVS203"]
extend-select = ["OVS301"]
fonts = ["Inter"]                   # by family: "Inter Medium" is Inter
palette = ["20211B", "F7F5F2", "00C756"]
palette-tolerance = 12              # RGB distance
font-dirs = ["fonts/"]              # relative to this file
min-font-pt = 10
max-words = 90
min-contrast = 3.0
tolerance-pt = 2.0
render = true
render-as = "powerpoint"            # or "libreoffice": don't freeze shrink-to-fit
vision = false
vision-model = "anthropic:claude-sonnet-5-5"
vision-threshold = 0.7
vision-input = "both"               # "slides" | "sheet" | "both"
vision-brief = "House style the reviewer should know."

examples/brand.toml is a small example: one font, a five-colour palette, and a vision brief.

Development

uv sync
uv run pytest -q --cov     # integration tests skip without LibreOffice
uv run ruff format src tests
uv run ruff check src tests

See CONTRIBUTING.md. MIT licensed.

Metadata

Release files for overset 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for overset 0.1.0
File Size Uploaded
overset-0.1.0.tar.gz 105.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for overset 0.1.0
File Interpreter ABI Platform
overset-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 137.8 kB

Release files / overset-0.1.0.tar.gz

Download URL overset-0.1.0.tar.gz
Size 105.4 kB
Tags Source
SHA-256 checksum
How to use checksums
58d5db106ea6e46592af51015d3b87326be169c65889da77ab9a9550bc6afe38
BLAKE2b-256 checksum
How to use checksums
08be86ded2fdcaf63fca6d3e4d8c86e546a6603b4753c2de7bffa09c092dd714
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.

Transparency log

Release files / overset-0.1.0-py3-none-any.whl

Download URL overset-0.1.0-py3-none-any.whl
Size 32.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cba404f8efd0035b5557173d08f86a48f3187937b5782dc1bd49bb8d2a6685db
BLAKE2b-256 checksum
How to use checksums
2e9e3d73d8bc9ca1624e6e3914fb6ded1c2aaeaf52823e524664676474f81a14
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page