pptx/theme-color-scheme

Every PresentationML package carries at least one theme part (ppt/theme/theme1.xml) whose <a:clrScheme> child defines the twelve standard colour slots (dk1, lt1, dk2, lt2, accent1..accent6, hlink, folHlink). These slots are referenced by <a:schemeClr val="..."/> throughout the package wherever a shape, run, or background fill inherits its colour from the theme. python-pptx's default Presentation() template ships the Office 2007 'Office' theme, which populates all twelve slots.

Library verdicts: python-pptx: — pptxjs: —

Metadata

Feature idpptx/theme-color-scheme
Formatpptx
Categorytheme
Spececma-376-5-part-1 § 20.1.6.2 a:clrScheme

XPath assertions

ID / partPredicateXPathpython-pptxpptxjs
clr-scheme-present
ppt/theme/theme1.xml
match = ^1(\.0)?$
The theme must carry exactly one <a:clrScheme> element.
count(//a:clrScheme)
clr-scheme-name-nonempty
ppt/theme/theme1.xml
match = ^.+$
<a:clrScheme> must carry a non-empty @name attribute.
string(//a:clrScheme/@name)
clr-scheme-has-twelve-slots
ppt/theme/theme1.xml
match = ^12(\.0)?$
<a:clrScheme> must carry exactly twelve colour-slot children (dk1, lt1, dk2, lt2, accent1..6, hlink, folHlink).
count(//a:clrScheme/*)
clr-scheme-slot-dk1
ppt/theme/theme1.xml
exist
The dk1 (dark 1) colour slot must be present.
//a:clrScheme/a:dk1
clr-scheme-slot-lt1
ppt/theme/theme1.xml
exist
The lt1 (light 1) colour slot must be present.
//a:clrScheme/a:lt1
clr-scheme-slot-dk2
ppt/theme/theme1.xml
exist
The dk2 (dark 2) colour slot must be present.
//a:clrScheme/a:dk2
clr-scheme-slot-lt2
ppt/theme/theme1.xml
exist
The lt2 (light 2) colour slot must be present.
//a:clrScheme/a:lt2
clr-scheme-slot-accent1
ppt/theme/theme1.xml
exist
The accent1 colour slot must be present.
//a:clrScheme/a:accent1
clr-scheme-slot-accent2
ppt/theme/theme1.xml
exist
The accent2 colour slot must be present.
//a:clrScheme/a:accent2
clr-scheme-slot-accent3
ppt/theme/theme1.xml
exist
The accent3 colour slot must be present.
//a:clrScheme/a:accent3
clr-scheme-slot-accent4
ppt/theme/theme1.xml
exist
The accent4 colour slot must be present.
//a:clrScheme/a:accent4
clr-scheme-slot-accent5
ppt/theme/theme1.xml
exist
The accent5 colour slot must be present.
//a:clrScheme/a:accent5
clr-scheme-slot-accent6
ppt/theme/theme1.xml
exist
The accent6 colour slot must be present.
//a:clrScheme/a:accent6
clr-scheme-slot-hlink
ppt/theme/theme1.xml
exist
The hlink (hyperlink) colour slot must be present.
//a:clrScheme/a:hlink
clr-scheme-slot-folHlink
ppt/theme/theme1.xml
exist
The folHlink (followed hyperlink) colour slot must be present.
//a:clrScheme/a:folHlink

Render assertions

No render assertions declared.

Generator source

scripts/gen_theme_color_scheme.py

#!/usr/bin/env python3
"""Generate ``fixtures/pptx/theme-color-scheme.pptx``.

Literal (single-case) fixture that exercises the default Office theme
shipped by python-pptx. The generator does nothing exotic: it creates
a fresh ``Presentation()`` (which includes the bundled ``ppt/theme/
theme1.xml`` with the Office 2007 colour scheme) and adds a single
title-only slide so the rendered reference has a text anchor.

The ``features/pptx/theme-color-scheme.json`` manifest asserts that
the theme part carries exactly one ``<a:clrScheme>`` with twelve
colour-slot children (dk1, lt1, dk2, lt2, accent1..6, hlink,
folHlink) and a non-empty ``@name``.
"""

from __future__ import annotations

import argparse
import datetime as _dt
from pathlib import Path

from pptx import Presentation

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


def _write(out: Path) -> None:
    prs = Presentation()
    # "Title Only" layout — one title placeholder on an otherwise plain slide.
    slide = prs.slides.add_slide(prs.slide_layouts[5])
    if slide.shapes.title is not None:
        slide.shapes.title.text = "Default Office theme"

    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(
        "--out",
        default=str(_REPO_ROOT / "fixtures" / "pptx" / "theme-color-scheme.pptx"),
        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(out_path)
    print(out_path)
    return 0


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

Manifest (expanded)

{
  "$schema": "../manifest.schema.json",
  "id": "pptx/theme-color-scheme",
  "kind": "literal",
  "title": "Theme colour scheme",
  "format": "pptx",
  "category": "theme",
  "summary": "Every PresentationML package carries at least one theme part (ppt/theme/theme1.xml) whose <a:clrScheme> child defines the twelve standard colour slots (dk1, lt1, dk2, lt2, accent1..accent6, hlink, folHlink). These slots are referenced by <a:schemeClr val=\"...\"/> throughout the package wherever a shape, run, or background fill inherits its colour from the theme. python-pptx's default Presentation() template ships the Office 2007 'Office' theme, which populates all twelve slots.",
  "spec": {
    "source": "ecma-376-5-part-1",
    "clause": "20.1.6.2",
    "element": "a:clrScheme",
    "rnc_reference": "spec/ecma-376-5/part-1/rnc/dml-main.rnc",
    "xsd_reference": "spec/ecma-376-5/part-1/xsd/dml-main.xsd",
    "notes": "ECMA-376 Part 1 clause 20.1.6 defines <a:clrScheme> as the colour-scheme element of the theme. Its content model is fixed: exactly twelve children in the order dk1, lt1, dk2, lt2, accent1..accent6, hlink, folHlink, each wrapping a single colour choice (srgbClr, sysClr, schemeClr, etc.). This family asserts the twelve slots exist on the default Office theme shipped by python-pptx and that <a:clrScheme> carries a non-empty @name attribute."
  },
  "fixtures": {
    "machine": "pptx/theme-color-scheme"
  },
  "generator": {
    "python": "scripts/gen_theme_color_scheme.py"
  },
  "assertions": [
    {
      "id": "clr-scheme-present",
      "part": "ppt/theme/theme1.xml",
      "namespaces": {
        "a": "http://schemas.openxmlformats.org/drawingml/2006/main"
      },
      "xpath": "count(//a:clrScheme)",
      "must": "match",
      "value": "^1(\\.0)?$",
      "description": "The theme must carry exactly one <a:clrScheme> element."
    },
    {
      "id": "clr-scheme-name-nonempty",
      "part": "ppt/theme/theme1.xml",
      "namespaces": {
        "a": "http://schemas.openxmlformats.org/drawingml/2006/main"
      },
      "xpath": "string(//a:clrScheme/@name)",
      "must": "match",
      "value": "^.+$",
      "description": "<a:clrScheme> must carry a non-empty @name attribute."
    },
    {
      "id": "clr-scheme-has-twelve-slots",
      "part": "ppt/theme/theme1.xml",
      "namespaces": {
        "a": "http://schemas.openxmlformats.org/drawingml/2006/main"
      },
      "xpath": "count(//a:clrScheme/*)",
      "must": "match",
      "value": "^12(\\.0)?$",
      "description": "<a:clrScheme> must carry exactly twelve colour-slot children (dk1, lt1, dk2, lt2, accent1..6, hlink, folHlink)."
    },
    {
      "id": "clr-scheme-slot-dk1",
      "part": "ppt/theme/theme1.xml",
      "namespaces": {
        "a": "http://schemas.openxmlformats.org/drawingml/2006/main"
      },
      "xpath": "//a:clrScheme/a:dk1",
      "must": "exist",
      "description": "The dk1 (dark 1) colour slot must be present."
    },
    {
      "id": "clr-scheme-slot-lt1",
      "part": "ppt/theme/theme1.xml",
      "namespaces": {
        "a": "http://schemas.openxmlformats.org/drawingml/2006/main"
      },
      "xpath": "//a:clrScheme/a:lt1",
      "must": "exist",
      "description": "The lt1 (light 1) colour slot must be present."
    },
    {
      "id": "clr-scheme-slot-dk2",
      "part": "ppt/theme/theme1.xml",
      "namespaces": {
        "a": "http://schemas.openxmlformats.org/drawingml/2006/main"
      },
      "xpath": "//a:clrScheme/a:dk2",
      "must": "exist",
      "description": "The dk2 (dark 2) colour slot must be present."
    },
    {
      "id": "clr-scheme-slot-lt2",
      "part": "ppt/theme/theme1.xml",
      "namespaces": {
        "a": "http://schemas.openxmlformats.org/drawingml/2006/main"
      },
      "xpath": "//a:clrScheme/a:lt2",
      "must": "exist",
      "description": "The lt2 (light 2) colour slot must be present."
    },
    {
      "id": "clr-scheme-slot-accent1",
      "part": "ppt/theme/theme1.xml",
      "namespaces": {
        "a": "http://schemas.openxmlformats.org/drawingml/2006/main"
      },
      "xpath": "//a:clrScheme/a:accent1",
      "must": "exist",
      "description": "The accent1 colour slot must be present."
    },
    {
      "id": "clr-scheme-slot-accent2",
      "part": "ppt/theme/theme1.xml",
      "namespaces": {
        "a": "http://schemas.openxmlformats.org/drawingml/2006/main"
      },
      "xpath": "//a:clrScheme/a:accent2",
      "must": "exist",
      "description": "The accent2 colour slot must be present."
    },
    {
      "id": "clr-scheme-slot-accent3",
      "part": "ppt/theme/theme1.xml",
      "namespaces": {
        "a": "http://schemas.openxmlformats.org/drawingml/2006/main"
      },
      "xpath": "//a:clrScheme/a:accent3",
      "must": "exist",
      "description": "The accent3 colour slot must be present."
    },
    {
      "id": "clr-scheme-slot-accent4",
      "part": "ppt/theme/theme1.xml",
      "namespaces": {
        "a": "http://schemas.openxmlformats.org/drawingml/2006/main"
      },
      "xpath": "//a:clrScheme/a:accent4",
      "must": "exist",
      "description": "The accent4 colour slot must be present."
    },
    {
      "id": "clr-scheme-slot-accent5",
      "part": "ppt/theme/theme1.xml",
      "namespaces": {
        "a": "http://schemas.openxmlformats.org/drawingml/2006/main"
      },
      "xpath": "//a:clrScheme/a:accent5",
      "must": "exist",
      "description": "The accent5 colour slot must be present."
    },
    {
      "id": "clr-scheme-slot-accent6",
      "part": "ppt/theme/theme1.xml",
      "namespaces": {
        "a": "http://schemas.openxmlformats.org/drawingml/2006/main"
      },
      "xpath": "//a:clrScheme/a:accent6",
      "must": "exist",
      "description": "The accent6 colour slot must be present."
    },
    {
      "id": "clr-scheme-slot-hlink",
      "part": "ppt/theme/theme1.xml",
      "namespaces": {
        "a": "http://schemas.openxmlformats.org/drawingml/2006/main"
      },
      "xpath": "//a:clrScheme/a:hlink",
      "must": "exist",
      "description": "The hlink (hyperlink) colour slot must be present."
    },
    {
      "id": "clr-scheme-slot-folHlink",
      "part": "ppt/theme/theme1.xml",
      "namespaces": {
        "a": "http://schemas.openxmlformats.org/drawingml/2006/main"
      },
      "xpath": "//a:clrScheme/a:folHlink",
      "must": "exist",
      "description": "The folHlink (followed hyperlink) colour slot must be present."
    }
  ]
}

Fixture

Download theme-color-scheme.pptx (27.4 KB)

Reference preview

No rendered reference is available for this case.

Spec notes

ECMA-376 Part 1 clause 20.1.6 defines <a:clrScheme> as the colour-scheme element of the theme. Its content model is fixed: exactly twelve children in the order dk1, lt1, dk2, lt2, accent1..accent6, hlink, folHlink, each wrapping a single colour choice (srgbClr, sysClr, schemeClr, etc.). This family asserts the twelve slots exist on the default Office theme shipped by python-pptx and that <a:clrScheme> carries a non-empty @name attribute.