pptx/slide-background

A slide can override its master/layout-inherited background via <p:cSld>/<p:bg>. python-pptx exposes this via slide.background.fill; setting it solid with a colour emits <p:bg>/<p:bgPr>/<a:solidFill>/<a:srgbClr val="HEX6"/>, while leaving it at its default inherits from the layout and emits no <p:bg>. This manifest is a parameterised family over 3 cases: solid red, solid blue, and default (none). One manifest file expands into 3 cases, each backed by a distinct fixture pptx/slide-background--<id>.pptx generated from the same gen_slide_background.py script parameterised by --kind and --rgb.

Cases (3)

Feature IDAxis bindingspython-pptxpptxjs
pptx/slide-background--nonekind=none
pptx/slide-background--solid-bluekind=solid-blue
pptx/slide-background--solid-redkind=solid-red

Aggregate

LibraryPassFailPending
python-pptx003
pptxjs003

Parameter axes

Spec notes

PresentationML <p:cSld> (common slide data) may contain an optional <p:bg> child that overrides the master/layout-inherited background. <p:bg> wraps either <p:bgPr> (direct properties — solidFill, gradFill, blipFill, pattFill, noFill) or <p:bgRef> (theme reference). python-pptx's ``slide.background.fill.solid()`` + ``fore_color.rgb = RGBColor(...)`` writes <p:bg>/<p:bgPr>/<a:solidFill>/<a:srgbClr val="..."/>. Leaving ``slide.background`` untouched does not emit <p:bg> at all — the slide inherits from its layout.

Generator source

scripts/gen_slide_background.py — runs with --arg_template --kind {kind.kind} --rgb {kind.rgb} --out fixtures/pptx/slide-background--{kind.id}.pptx

#!/usr/bin/env python3
"""Generate a single ``fixtures/pptx/slide-background--<id>.pptx`` fixture.

Parameterised generator for the ``pptx/slide-background`` manifest
family. The conformance runner invokes this script once per case with
``--kind <KIND> [--rgb <HEX6>] --out <path>``.

Each invocation produces a single-slide presentation whose slide-level
background is set via ``slide.background.fill.solid()`` +
``slide.background.fill.fore_color.rgb = RGBColor(...)`` for solid
cases, or left at the default (no ``p:bg`` element) for the ``none`` case.

The underlying XML is ``<p:cSld>/<p:bg>/<p:bgPr>/<a:solidFill>/<a:srgbClr val="HEX6"/>``
for solid cases; the assertion checks this path. For the ``none`` case
the assertion instead confirms ``<p:bg>`` is absent.
"""

from __future__ import annotations

import argparse
import datetime as _dt
from pathlib import Path

from pptx import Presentation
from pptx.dml.color import RGBColor

_REPO_ROOT = Path(__file__).resolve().parent.parent
_REPRODUCIBLE_DT = _dt.datetime(2000, 1, 1, 0, 0, 0)


def _write(kind: str, rgb_hex: str | None, out: Path) -> None:
    prs = Presentation()
    # "Blank" layout (idx 6) — no placeholders, focus on the background.
    slide = prs.slides.add_slide(prs.slide_layouts[6])
    if kind == "solid":
        assert rgb_hex is not None, "--rgb required for kind=solid"
        slide.background.fill.solid()
        slide.background.fill.fore_color.rgb = RGBColor.from_string(rgb_hex)
    elif kind == "none":
        pass  # leave default — no <p:bg>
    else:
        raise SystemExit(f"Unknown --kind {kind!r}")
    out.parent.mkdir(parents=True, exist_ok=True)
    prs.save(out, zip_date_time=_REPRODUCIBLE_DT)


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--kind",
        required=True,
        choices=("solid", "none"),
        help="'solid' for a slide-level solid-fill bg, 'none' for default (no p:bg).",
    )
    parser.add_argument(
        "--rgb",
        default=None,
        help="Six-hex-digit RGB value for solid-fill bg (required when --kind=solid).",
    )
    parser.add_argument(
        "--out",
        required=True,
        help="Output fixture path (absolute or repo-relative).",
    )
    args = parser.parse_args()

    out_path = Path(args.out)
    if not out_path.is_absolute():
        out_path = _REPO_ROOT / out_path
    _write(args.kind, args.rgb, out_path)
    print(out_path)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())

Manifest (parent, unexpanded)

{
  "$schema": "../manifest.schema.json",
  "id": "pptx/slide-background",
  "kind": "parameterised",
  "title": "Slide-level background fill",
  "format": "pptx",
  "category": "slide-layout",
  "summary": "A slide can override its master/layout-inherited background via <p:cSld>/<p:bg>. python-pptx exposes this via slide.background.fill; setting it solid with a colour emits <p:bg>/<p:bgPr>/<a:solidFill>/<a:srgbClr val=\"HEX6\"/>, while leaving it at its default inherits from the layout and emits no <p:bg>. This manifest is a parameterised family over 3 cases: solid red, solid blue, and default (none). One manifest file expands into 3 cases, each backed by a distinct fixture pptx/slide-background--<id>.pptx generated from the same gen_slide_background.py script parameterised by --kind and --rgb.",
  "spec": {
    "source": "ecma-376-5-part-1",
    "clause": "19.3.1.1",
    "element": "p:bg",
    "rnc_reference": "spec/ecma-376-5/part-1/rnc/PresentationML.rnc",
    "xsd_reference": "spec/ecma-376-5/part-1/xsd/pml.xsd",
    "notes": "PresentationML <p:cSld> (common slide data) may contain an optional <p:bg> child that overrides the master/layout-inherited background. <p:bg> wraps either <p:bgPr> (direct properties — solidFill, gradFill, blipFill, pattFill, noFill) or <p:bgRef> (theme reference). python-pptx's ``slide.background.fill.solid()`` + ``fore_color.rgb = RGBColor(...)`` writes <p:bg>/<p:bgPr>/<a:solidFill>/<a:srgbClr val=\"...\"/>. Leaving ``slide.background`` untouched does not emit <p:bg> at all — the slide inherits from its layout."
  },
  "fixtures": {
    "machine": "pptx/slide-background"
  },
  "generator": {
    "python": "scripts/gen_slide_background.py",
    "arg_template": "--kind {kind.kind} --rgb {kind.rgb} --out fixtures/pptx/slide-background--{kind.id}.pptx"
  },
  "parameters": {
    "kind": [
      {
        "id": "solid-red",
        "kind": "solid",
        "rgb": "FF0000",
        "xpath": "//p:cSld/p:bg/p:bgPr/a:solidFill/a:srgbClr/@val",
        "must": "equal",
        "value": "FF0000"
      },
      {
        "id": "solid-blue",
        "kind": "solid",
        "rgb": "0000FF",
        "xpath": "//p:cSld/p:bg/p:bgPr/a:solidFill/a:srgbClr/@val",
        "must": "equal",
        "value": "0000FF"
      },
      {
        "id": "none",
        "kind": "none",
        "rgb": "000000",
        "xpath": "//p:cSld/p:bg",
        "must": "absent",
        "value": ""
      }
    ]
  },
  "assertions_template": [
    {
      "id": "slide-background-{kind.id}",
      "part": "ppt/slides/slide1.xml",
      "namespaces": {
        "p": "http://schemas.openxmlformats.org/presentationml/2006/main",
        "a": "http://schemas.openxmlformats.org/drawingml/2006/main"
      },
      "xpath": "{kind.xpath}",
      "must": "{kind.must}",
      "value": "{kind.value}",
      "description": "Slide background {kind.id}: xpath {kind.xpath} must {kind.must} '{kind.value}'."
    }
  ]
}