Skip to content

tppt

🐍 🛡️ Typed Python PowerPoint Tool 🛡️ 🐍

import tppt ( ... tppt.Presentation.builder() ... .slide( ... lambda slide: slide.BlankLayout() ... .builder() ... .text( ... "Hello, World!", ... left=(1, "in"), ... top=(1, "in"), ... width=(5, "in"), ... height=(2, "in"), ... ) ... ) ... .build() ... .save("simple.pptx") ... )

Attributes

__version__ = importlib.metadata.version('tppt') module-attribute

T = TypeVar('T') module-attribute

P = ParamSpec('P') module-attribute

Classes

Functions

apply(func: Callable[Concatenate[T, P], T], *args: P.args, **kwargs: P.kwargs) -> Callable[[T], T]

Partially applies the given function func with arguments args and keyword arguments kwargs, returning a new function that takes only the first argument.

Parameters:

Name Type Description Default
func Callable[Concatenate[T, P], T]

A function that takes a first argument of type T and variable arguments P, returning T

required
*args args

Variable positional arguments to partially apply to func

()
**kwargs kwargs

Variable keyword arguments to partially apply to func

{}

Returns:

Type Description
Callable[[T], T]

A function that takes a single argument x and calls func(x, *args, **kwargs)

Source code in src/tppt/__init__.py
def apply(
    func: Callable[Concatenate[T, P], T], *args: P.args, **kwargs: P.kwargs
) -> Callable[[T], T]:
    """
    Partially applies the given function `func` with arguments `args` and keyword arguments `kwargs`,
    returning a new function that takes only the first argument.

    Args:
        func: A function that takes a first argument of type `T` and variable arguments `P`, returning `T`
        *args: Variable positional arguments to partially apply to `func`
        **kwargs: Variable keyword arguments to partially apply to `func`

    Returns:
        A function that takes a single argument `x` and calls `func(x, *args, **kwargs)`
    """

    def wrapper(x: T) -> T:
        return func(x, *args, **kwargs)

    return wrapper

Modules

exception

Classes
TpptException

Bases: Exception

Base exception for tppt.

Source code in src/tppt/exception.py
class TpptException(Exception):
    """Base exception for tppt."""

    @property
    @abstractmethod
    def message(self) -> str: ...

    @property
    def extra(self) -> dict[str, Any]:
        return {}

    def __str__(self) -> str:
        return self.message
Attributes
message: str abstractmethod property
extra: dict[str, Any] property
Functions
__str__() -> str
Source code in src/tppt/exception.py
def __str__(self) -> str:
    return self.message
ColorInvalidFormatError

Bases: TpptException, ValueError

Color format is invalid.

Source code in src/tppt/exception.py
class ColorInvalidFormatError(TpptException, ValueError):
    """Color format is invalid."""

    def __init__(self, color: str) -> None:
        self.color = color

    @property
    def message(self) -> str:
        return f"Invalid color format: {self.color}"
Attributes
color = color instance-attribute
message: str property
Functions
__init__(color: str) -> None
Source code in src/tppt/exception.py
def __init__(self, color: str) -> None:
    self.color = color
ColorInvalidTupleSizeError

Bases: TpptException, ValueError

Color tuple size is invalid.

Source code in src/tppt/exception.py
class ColorInvalidTupleSizeError(TpptException, ValueError):
    """Color tuple size is invalid."""

    def __init__(self, color: tuple[Any, ...]) -> None:
        self.color = color

    @property
    def message(self) -> str:
        return f"Invalid color tuple size: {self.color}, expected 3(RGB) or 4(RGBA) elements."
Attributes
color = color instance-attribute
message: str property
Functions
__init__(color: tuple[Any, ...]) -> None
Source code in src/tppt/exception.py
def __init__(self, color: tuple[Any, ...]) -> None:
    self.color = color
SlideLayoutIndexError

Bases: TpptException, IndexError

Slide layout index is out of range.

Source code in src/tppt/exception.py
class SlideLayoutIndexError(TpptException, IndexError):
    """Slide layout index is out of range."""

    def __init__(self, index: int, slide_layouts: "PptxSlideLayouts") -> None:
        self.index = index
        self.slide_layouts = slide_layouts

    @property
    def message(self) -> str:
        return f"Slide layout index {self.index} is out of range. Available slide layouts: {[layout.name for layout in self.slide_layouts]}"
Attributes
index = index instance-attribute
slide_layouts = slide_layouts instance-attribute
message: str property
Functions
__init__(index: int, slide_layouts: PptxSlideLayouts) -> None
Source code in src/tppt/exception.py
def __init__(self, index: int, slide_layouts: "PptxSlideLayouts") -> None:
    self.index = index
    self.slide_layouts = slide_layouts
SlideMasterAttributeMustBeSlideLayoutError

Bases: TpptException, ValueError

Slide master attribute must be a slide layout.

Source code in src/tppt/exception.py
class SlideMasterAttributeMustBeSlideLayoutError(TpptException, ValueError):
    """Slide master attribute must be a slide layout."""

    def __init__(self, slide_layout_name: str) -> None:
        self.slide_layout_name = slide_layout_name

    @property
    def message(self) -> str:
        return f"The slide master attribute must be a slide layout. The {self.slide_layout_name} layout is not a slide layout."
Attributes
slide_layout_name = slide_layout_name instance-attribute
message: str property
Functions
__init__(slide_layout_name: str) -> None
Source code in src/tppt/exception.py
def __init__(self, slide_layout_name: str) -> None:
    self.slide_layout_name = slide_layout_name
SlideMasterDoesNotHaveAttributesError

Bases: TpptException, AttributeError

Slide master does not have an attribute.

Source code in src/tppt/exception.py
class SlideMasterDoesNotHaveAttributesError(TpptException, AttributeError):
    """Slide master does not have an attribute."""

    @property
    def message(self) -> str:
        return "The slide master does not have an attributes"
Attributes
message: str property
SlideMasterAttributeNotFoundError

Bases: TpptException, AttributeError

Slide master attribute not found.

Source code in src/tppt/exception.py
class SlideMasterAttributeNotFoundError(TpptException, AttributeError):
    """Slide master attribute not found."""

    def __init__(self, attribute_name: str) -> None:
        self.attribute_name = attribute_name

    @property
    def message(self) -> str:
        return (
            f"The slide master does not have an attribute of the {self.attribute_name}"
        )
Attributes
attribute_name = attribute_name instance-attribute
message: str property
Functions
__init__(attribute_name: str) -> None
Source code in src/tppt/exception.py
def __init__(self, attribute_name: str) -> None:
    self.attribute_name = attribute_name
InvalidSetterTypeError

Bases: TpptException, TypeError

Invalid setter type.

Source code in src/tppt/exception.py
class InvalidSetterTypeError(TpptException, TypeError):
    """Invalid setter type."""

    def __init__(
        self, expected_type: type | tuple[type, ...], actual_type: type
    ) -> None:
        self.expected_type = expected_type
        self.actual_type = actual_type

    @property
    def message(self) -> str:
        return f"Invalid setter type. Expected type: {self.expected_type}, but got: {self.actual_type}."
Attributes
expected_type = expected_type instance-attribute
actual_type = actual_type instance-attribute
message: str property
Functions
__init__(expected_type: type | tuple[type, ...], actual_type: type) -> None
Source code in src/tppt/exception.py
def __init__(
    self, expected_type: type | tuple[type, ...], actual_type: type
) -> None:
    self.expected_type = expected_type
    self.actual_type = actual_type
InvalidColorValueError

Bases: TpptException, ValueError

Invalid color value.

Source code in src/tppt/exception.py
class InvalidColorValueError(TpptException, ValueError):
    """Invalid color value."""

    def __init__(
        self, type: Literal["red", "green", "blue", "alpha"], value: int
    ) -> None:
        self.type = type
        self.value = value

    @property
    def message(self) -> str:
        return f"Invalid {self.type} value: {self.value}. It must be between 0 and 255."
Attributes
type = type instance-attribute
value = value instance-attribute
message: str property
Functions
__init__(type: Literal['red', 'green', 'blue', 'alpha'], value: int) -> None
Source code in src/tppt/exception.py
def __init__(
    self, type: Literal["red", "green", "blue", "alpha"], value: int
) -> None:
    self.type = type
    self.value = value

pptx

📊 python-pptx wrapper implementation 📊

This module provides a wrapper for the python-pptx library.

In addition, the Presentation and SlideLayout classes have a builder() method, which allows you to create a PowerPoint declaratively.

Classes
Modules
action
Classes
Hyperlink

Bases: SubShape[Hyperlink]

Source code in src/tppt/pptx/action.py
class Hyperlink(SubShape[_PptxHyperlink]):
    @property
    def address(self) -> str | None:
        return self._pptx.address

    @address.setter
    def address(self, value: str | None):
        self._pptx.address = value

    def set_address(self, value: str | None) -> Self:
        self.address = value
        return self
Attributes
address: str | None property writable
Functions
set_address(value: str | None) -> Self
Source code in src/tppt/pptx/action.py
def set_address(self, value: str | None) -> Self:
    self.address = value
    return self
ActionSetting

Bases: PptxConvertible[ActionSetting]

Source code in src/tppt/pptx/action.py
class ActionSetting(PptxConvertible[_PptxActionSetting]):
    @property
    def action(self) -> PP_ACTION_TYPE:
        return self._pptx.action

    @property
    def hyperlink(self) -> Hyperlink:
        return Hyperlink(self._pptx.hyperlink)

    @property
    def target_slide(self) -> Slide | None:
        if target_slide := self._pptx.target_slide:
            return Slide(target_slide)
        return None

    @target_slide.setter
    def target_slide(self, value: Slide | None):
        if value is None:
            self._pptx.target_slide = None
        else:
            self._pptx.target_slide = value._pptx

    def set_target_slide(self, value: Slide | None) -> Self:
        self.target_slide = value
        return self
Attributes
action: PP_ACTION_TYPE property
hyperlink: Hyperlink property
target_slide: Slide | None property writable
Functions
set_target_slide(value: Slide | None) -> Self
Source code in src/tppt/pptx/action.py
def set_target_slide(self, value: Slide | None) -> Self:
    self.target_slide = value
    return self
chart
Modules
chart
Attributes
LiteralChartType = Literal['3D Area', '3D Stacked Area', '3D 100% Stacked Area', '3D Clustered Bar', '3D Stacked Bar', '3D 100% Stacked Bar', '3D Column', '3D Clustered Column', '3D Stacked Column', '3D 100% Stacked Column', '3D Line', '3D Pie', '3D Exploded Pie', 'Area', 'Stacked Area', '100% Stacked Area', 'Clustered Bar', 'Bar of Pie', 'Stacked Bar', '100% Stacked Bar', 'Bubble', 'Bubble with 3D effects', 'Clustered Column', 'Stacked Column', '100% Stacked Column', 'Clustered Cone Bar', 'Stacked Cone Bar', '100% Stacked Cone Bar', '3D Cone Column', 'Clustered Cone Column', 'Stacked Cone Column', '100% Stacked Cone Column', 'Clustered Cylinder Bar', 'Stacked Cylinder Bar', '100% Stacked Cylinder Bar', '3D Cylinder Column', 'Clustered Cylinder Column', 'Stacked Cylinder Column', '100% Stacked Cylinder Column', 'Doughnut', 'Exploded Doughnut', 'Line', 'Line with Markers', 'Stacked Line with Markers', '100% Stacked Line with Markers', 'Stacked Line', '100% Stacked Line', 'Pie', 'Exploded Pie', 'Pie of Pie', 'Clustered Pyramid Bar', 'Stacked Pyramid Bar', '100% Stacked Pyramid Bar', '3D Pyramid Column', 'Clustered Pyramid Column', 'Stacked Pyramid Column', '100% Stacked Pyramid Column', 'Radar', 'Filled Radar', 'Radar with Data Markers', 'High-Low-Close', 'Open-High-Low-Close', 'Volume-High-Low-Close', 'Volume-Open-High-Low-Close', '3D Surface', 'Surface (Top View)', 'Surface (Top View wireframe)', '3D Surface (wireframe)', 'Scatter', 'Scatter with Lines', 'Scatter with Lines and No Data Markers', 'Scatter with Smoothed Lines', 'Scatter with Smoothed Lines and No Data Markers'] module-attribute
Classes
ChartProps

Bases: TypedDict

Chart properties.

Source code in src/tppt/pptx/chart/chart.py
class ChartProps(TypedDict):
    """Chart properties."""

    chart_type: LiteralChartType | XL_CHART_TYPE
    x: Length | LiteralLength
    y: Length | LiteralLength
    cx: Length | LiteralLength
    cy: Length | LiteralLength
    chart_data: PptxChartData
Attributes
chart_type: LiteralChartType | XL_CHART_TYPE instance-attribute
x: Length | LiteralLength instance-attribute
y: Length | LiteralLength instance-attribute
cx: Length | LiteralLength instance-attribute
cy: Length | LiteralLength instance-attribute
chart_data: PptxChartData instance-attribute
ChartData

Bases: ChartProps

Chart data.

Source code in src/tppt/pptx/chart/chart.py
class ChartData(ChartProps):
    """Chart data."""

    type: Literal["chart"]
Attributes
type: Literal['chart'] instance-attribute
Chart

Bases: PptxConvertible[Chart]

Chart data class.

Source code in src/tppt/pptx/chart/chart.py
class Chart(PptxConvertible[PptxChart]):
    """Chart data class."""

    def __init__(self, pptx_obj: PptxChart, /) -> None:
        super().__init__(pptx_obj)
Functions
__init__(pptx_obj: PptxChart) -> None
Source code in src/tppt/pptx/chart/chart.py
def __init__(self, pptx_obj: PptxChart, /) -> None:
    super().__init__(pptx_obj)
Functions
to_pptx_chart_type(chart_type: XL_CHART_TYPE | LiteralChartType) -> XL_CHART_TYPE
Source code in src/tppt/pptx/chart/chart.py
def to_pptx_chart_type(chart_type: XL_CHART_TYPE | LiteralChartType) -> XL_CHART_TYPE:
    match chart_type:
        case XL_CHART_TYPE():
            return chart_type
        case "3D Area":
            return XL_CHART_TYPE.THREE_D_AREA
        case "3D Stacked Area":
            return XL_CHART_TYPE.THREE_D_AREA_STACKED
        case "3D 100% Stacked Area":
            return XL_CHART_TYPE.THREE_D_AREA_STACKED_100
        case "3D Clustered Bar":
            return XL_CHART_TYPE.THREE_D_BAR_CLUSTERED
        case "3D Stacked Bar":
            return XL_CHART_TYPE.THREE_D_BAR_STACKED
        case "3D 100% Stacked Bar":
            return XL_CHART_TYPE.THREE_D_BAR_STACKED_100
        case "3D Column":
            return XL_CHART_TYPE.THREE_D_COLUMN
        case "3D Clustered Column":
            return XL_CHART_TYPE.THREE_D_COLUMN_CLUSTERED
        case "3D Stacked Column":
            return XL_CHART_TYPE.THREE_D_COLUMN_STACKED
        case "3D 100% Stacked Column":
            return XL_CHART_TYPE.THREE_D_COLUMN_STACKED_100
        case "3D Line":
            return XL_CHART_TYPE.THREE_D_LINE
        case "3D Pie":
            return XL_CHART_TYPE.THREE_D_PIE
        case "3D Exploded Pie":
            return XL_CHART_TYPE.THREE_D_PIE_EXPLODED
        case "Area":
            return XL_CHART_TYPE.AREA
        case "Stacked Area":
            return XL_CHART_TYPE.AREA_STACKED
        case "100% Stacked Area":
            return XL_CHART_TYPE.AREA_STACKED_100
        case "Clustered Bar":
            return XL_CHART_TYPE.BAR_CLUSTERED
        case "Bar of Pie":
            return XL_CHART_TYPE.BAR_OF_PIE
        case "Stacked Bar":
            return XL_CHART_TYPE.BAR_STACKED
        case "100% Stacked Bar":
            return XL_CHART_TYPE.BAR_STACKED_100
        case "Bubble":
            return XL_CHART_TYPE.BUBBLE
        case "Bubble with 3D effects":
            return XL_CHART_TYPE.BUBBLE_THREE_D_EFFECT
        case "Clustered Column":
            return XL_CHART_TYPE.COLUMN_CLUSTERED
        case "Stacked Column":
            return XL_CHART_TYPE.COLUMN_STACKED
        case "100% Stacked Column":
            return XL_CHART_TYPE.COLUMN_STACKED_100
        case "Clustered Cone Bar":
            return XL_CHART_TYPE.CONE_BAR_CLUSTERED
        case "Stacked Cone Bar":
            return XL_CHART_TYPE.CONE_BAR_STACKED
        case "100% Stacked Cone Bar":
            return XL_CHART_TYPE.CONE_BAR_STACKED_100
        case "3D Cone Column":
            return XL_CHART_TYPE.CONE_COL
        case "Clustered Cone Column":
            return XL_CHART_TYPE.CONE_COL_CLUSTERED
        case "Stacked Cone Column":
            return XL_CHART_TYPE.CONE_COL_STACKED
        case "100% Stacked Cone Column":
            return XL_CHART_TYPE.CONE_COL_STACKED_100
        case "Clustered Cylinder Bar":
            return XL_CHART_TYPE.CYLINDER_BAR_CLUSTERED
        case "Stacked Cylinder Bar":
            return XL_CHART_TYPE.CYLINDER_BAR_STACKED
        case "100% Stacked Cylinder Bar":
            return XL_CHART_TYPE.CYLINDER_BAR_STACKED_100
        case "3D Cylinder Column":
            return XL_CHART_TYPE.CYLINDER_COL
        case "Clustered Cylinder Column":
            return XL_CHART_TYPE.CYLINDER_COL_CLUSTERED
        case "Stacked Cylinder Column":
            return XL_CHART_TYPE.CYLINDER_COL_STACKED
        case "100% Stacked Cylinder Column":
            return XL_CHART_TYPE.CYLINDER_COL_STACKED_100
        case "Doughnut":
            return XL_CHART_TYPE.DOUGHNUT
        case "Exploded Doughnut":
            return XL_CHART_TYPE.DOUGHNUT_EXPLODED
        case "Line":
            return XL_CHART_TYPE.LINE
        case "Line with Markers":
            return XL_CHART_TYPE.LINE_MARKERS
        case "Stacked Line with Markers":
            return XL_CHART_TYPE.LINE_MARKERS_STACKED
        case "100% Stacked Line with Markers":
            return XL_CHART_TYPE.LINE_MARKERS_STACKED_100
        case "Stacked Line":
            return XL_CHART_TYPE.LINE_STACKED
        case "100% Stacked Line":
            return XL_CHART_TYPE.LINE_STACKED_100
        case "Pie":
            return XL_CHART_TYPE.PIE
        case "Exploded Pie":
            return XL_CHART_TYPE.PIE_EXPLODED
        case "Pie of Pie":
            return XL_CHART_TYPE.PIE_OF_PIE
        case "Clustered Pyramid Bar":
            return XL_CHART_TYPE.PYRAMID_BAR_CLUSTERED
        case "Stacked Pyramid Bar":
            return XL_CHART_TYPE.PYRAMID_BAR_STACKED
        case "100% Stacked Pyramid Bar":
            return XL_CHART_TYPE.PYRAMID_BAR_STACKED_100
        case "3D Pyramid Column":
            return XL_CHART_TYPE.PYRAMID_COL
        case "Clustered Pyramid Column":
            return XL_CHART_TYPE.PYRAMID_COL_CLUSTERED
        case "Stacked Pyramid Column":
            return XL_CHART_TYPE.PYRAMID_COL_STACKED
        case "100% Stacked Pyramid Column":
            return XL_CHART_TYPE.PYRAMID_COL_STACKED_100
        case "Radar":
            return XL_CHART_TYPE.RADAR
        case "Filled Radar":
            return XL_CHART_TYPE.RADAR_FILLED
        case "Radar with Data Markers":
            return XL_CHART_TYPE.RADAR_MARKERS
        case "High-Low-Close":
            return XL_CHART_TYPE.STOCK_HLC
        case "Open-High-Low-Close":
            return XL_CHART_TYPE.STOCK_OHLC
        case "Volume-High-Low-Close":
            return XL_CHART_TYPE.STOCK_VHLC
        case "Volume-Open-High-Low-Close":
            return XL_CHART_TYPE.STOCK_VOHLC
        case "3D Surface":
            return XL_CHART_TYPE.SURFACE
        case "Surface (Top View)":
            return XL_CHART_TYPE.SURFACE_TOP_VIEW
        case "Surface (Top View wireframe)":
            return XL_CHART_TYPE.SURFACE_TOP_VIEW_WIREFRAME
        case "3D Surface (wireframe)":
            return XL_CHART_TYPE.SURFACE_WIREFRAME
        case "Scatter":
            return XL_CHART_TYPE.XY_SCATTER
        case "Scatter with Lines":
            return XL_CHART_TYPE.XY_SCATTER_LINES
        case "Scatter with Lines and No Data Markers":
            return XL_CHART_TYPE.XY_SCATTER_LINES_NO_MARKERS
        case "Scatter with Smoothed Lines":
            return XL_CHART_TYPE.XY_SCATTER_SMOOTH
        case "Scatter with Smoothed Lines and No Data Markers":
            return XL_CHART_TYPE.XY_SCATTER_SMOOTH_NO_MARKERS
        case _:
            assert_never(chart_type)
converter

Type definitions for pptx wrapper.

Attributes
PT = TypeVar('PT') module-attribute
PptxAngle: TypeAlias = float module-attribute
Classes
PptxConvertible

Bases: Generic[PT]

Protocol for objects that can be converted to and from pptx objects.

Source code in src/tppt/pptx/converter.py
class PptxConvertible(Generic[PT]):
    """Protocol for objects that can be converted to and from pptx objects."""

    def __init__(self, pptx_obj: PT, /) -> None:
        self._pptx: PT = pptx_obj

    def to_pptx(self) -> PT:
        """Convert to pptx object."""
        return self._pptx

    @classmethod
    def from_pptx(cls, pptx_obj: PT) -> Self:
        """Create from pptx object."""
        return cls(pptx_obj)
Functions
__init__(pptx_obj: PT) -> None
Source code in src/tppt/pptx/converter.py
def __init__(self, pptx_obj: PT, /) -> None:
    self._pptx: PT = pptx_obj
to_pptx() -> PT

Convert to pptx object.

Source code in src/tppt/pptx/converter.py
def to_pptx(self) -> PT:
    """Convert to pptx object."""
    return self._pptx
from_pptx(pptx_obj: PT) -> Self classmethod

Create from pptx object.

Source code in src/tppt/pptx/converter.py
@classmethod
def from_pptx(cls, pptx_obj: PT) -> Self:
    """Create from pptx object."""
    return cls(pptx_obj)
Functions
to_pptx_length(length: Length | LiteralLength | PptxLength | None) -> PptxLength | None
to_pptx_length(
    length: Length | LiteralLength | PptxLength,
) -> PptxLength
to_pptx_length(
    length: Length | LiteralLength | PptxLength | None,
) -> PptxLength | None
Source code in src/tppt/pptx/converter.py
def to_pptx_length(
    length: Length | LiteralLength | PptxLength | None,
) -> PptxLength | None:
    if isinstance(length, tuple):
        length = to_length(length)

    match length:
        case Inches():
            return PptxInches(length.value)
        case CentiMeters():
            return PptxCm(length.value)
        case Points():
            return PptxPt(length.value)
        case MilliMeters():
            return PptxMm(length.value)
        case EnglishMetricUnits():
            return PptxEmu(length.value)
        case PptxLength():
            return length
        case None:
            return None
        case _:
            assert_never(length)
to_tppt_length(length: PptxLength | None) -> Length | None
to_tppt_length(length: PptxLength) -> Length
to_tppt_length(length: PptxLength | None) -> Length | None
Source code in src/tppt/pptx/converter.py
def to_tppt_length(length: PptxLength | None) -> Length | None:
    return to_length((length.emu, "emu")) if length else None
to_pptx_rgb_color(color: Color | LiteralColor | PptxRGBColor | None) -> tuple[PptxRGBColor, int | None] | None
to_pptx_rgb_color(
    color: Color | LiteralColor | PptxRGBColor,
) -> tuple[PptxRGBColor, int | None]
to_pptx_rgb_color(
    color: Color | LiteralColor | PptxRGBColor | None,
) -> tuple[PptxRGBColor, int | None] | None
Source code in src/tppt/pptx/converter.py
def to_pptx_rgb_color(
    color: Color | LiteralColor | PptxRGBColor | None,
) -> (
    tuple[
        PptxRGBColor,
        int | None,
    ]
    | None
):
    if color is None:
        return None

    color = to_color(color)

    return PptxRGBColor(color.r, color.g, color.b), color.a
to_tppt_rgb_color(color: PptxRGBColor | None, alpha: int | None) -> Color | None
to_tppt_rgb_color(
    color: PptxRGBColor, alpha: int | None
) -> Color
to_tppt_rgb_color(
    color: PptxRGBColor | None, alpha: int | None
) -> Color | None
Source code in src/tppt/pptx/converter.py
def to_tppt_rgb_color(color: PptxRGBColor | None, alpha: int | None) -> Color | None:
    return Color(color[0], color[1], color[2], alpha) if color else None
to_pptx_angle(angle: Angle | LiteralAngle | None) -> PptxAngle | None
to_pptx_angle(angle: Angle | LiteralAngle) -> PptxAngle
to_pptx_angle(
    angle: Angle | LiteralAngle | None,
) -> PptxAngle | None
Source code in src/tppt/pptx/converter.py
def to_pptx_angle(angle: Angle | LiteralAngle | None) -> PptxAngle | None:
    match angle:
        case Degrees():
            return angle._value
        case tuple():
            return angle[0]
        case None:
            return None
        case _:
            assert_never(angle)
to_tppt_angle(angle: PptxAngle | None) -> Angle | None
to_tppt_angle(angle: PptxAngle) -> Angle
to_tppt_angle(angle: PptxAngle | None) -> Angle | None
Source code in src/tppt/pptx/converter.py
def to_tppt_angle(angle: PptxAngle | None) -> Angle | None:
    return Degrees(angle) if angle else None
dml

Drawing Markup Language wrapper implementation.

Modules
color
Attributes
LiteralThemeColor = Literal['accent1', 'accent2', 'accent3', 'accent4', 'accent5', 'accent6', 'background1', 'background2', 'dark1', 'dark2', 'followed_hyperlink', 'hyperlink', 'light1', 'light2', 'text1', 'text2', 'mixed'] module-attribute
Classes
ColorFormat

Bases: PptxConvertible[ColorFormat]

Source code in src/tppt/pptx/dml/color.py
class ColorFormat(PptxConvertible[PptxColorFormat]):
    @property
    def brightness(self) -> float:
        """
        Read/write float value between -1.0 and 1.0 indicating the brightness
        adjustment for this color, e.g. -0.25 is 25% darker and 0.4 is 40%
        lighter. 0 means no brightness adjustment.
        """
        return self._pptx.brightness

    @brightness.setter
    def brightness(self, value: float) -> None:
        self._pptx.brightness = value

    def set_brightness(self, value: float) -> Self:
        """Set brightness value and return self for method chaining."""
        self.brightness = value
        return self

    @property
    def rgb(self) -> Color:
        solid_fill = cast(
            _Element, self._pptx._xFill.solidFill.get_or_change_to_srgbClr()
        )

        if alpha := solid_fill.find("a:alpha", namespace):
            alpha = alpha.attrib["val"]
        else:
            alpha = None

        return to_tppt_rgb_color(cast(PptxRGBColor, self._pptx.rgb), alpha=alpha)

    @rgb.setter
    def rgb(self, color: Color | LiteralColor | PptxRGBColor):
        pptx_color, alpha = to_pptx_rgb_color(color)
        self._pptx.rgb = pptx_color
        srgbClr = cast(_Element, cast(_SRgbColor, self._pptx._color)._srgbClr)
        if alpha is not None:
            element = OxmlElement("a:alpha")
            element.attrib["val"] = str(int(100000 * (alpha / 255)))
            srgbClr.append(element)
        else:
            if alpha := srgbClr.find("a:alpha", namespace):
                srgbClr.remove(alpha)

    def set_rgb(self, color: Color | LiteralColor | PptxRGBColor) -> Self:
        """Set RGB color value and return self for method chaining."""
        self.rgb = color
        return self

    @property
    def theme_color(self) -> MSO_THEME_COLOR | None:
        """Theme color value of this color.

        Value is a member of :ref:`MsoThemeColorIndex`, e.g.
        ``MSO_THEME_COLOR.ACCENT_1``. Raises AttributeError on access if the
        color is not type ``MSO_COLOR_TYPE.SCHEME``. Assigning a member of
        :ref:`MsoThemeColorIndex` causes the color's type to change to
        ``MSO_COLOR_TYPE.SCHEME``.
        """
        return self._pptx.theme_color

    @theme_color.setter
    def theme_color(self, value: LiteralThemeColor | MSO_THEME_COLOR | None) -> None:
        self._pptx.theme_color = to_pptx_theme_color(value)

    def set_theme_color(
        self, value: LiteralThemeColor | MSO_THEME_COLOR | None
    ) -> Self:
        """Set theme color value and return self for method chaining."""
        self.theme_color = value
        return self
Attributes
brightness: float property writable

Read/write float value between -1.0 and 1.0 indicating the brightness adjustment for this color, e.g. -0.25 is 25% darker and 0.4 is 40% lighter. 0 means no brightness adjustment.

rgb: Color property writable
theme_color: MSO_THEME_COLOR | None property writable

Theme color value of this color.

Value is a member of :ref:MsoThemeColorIndex, e.g. MSO_THEME_COLOR.ACCENT_1. Raises AttributeError on access if the color is not type MSO_COLOR_TYPE.SCHEME. Assigning a member of :ref:MsoThemeColorIndex causes the color's type to change to MSO_COLOR_TYPE.SCHEME.

Functions
set_brightness(value: float) -> Self

Set brightness value and return self for method chaining.

Source code in src/tppt/pptx/dml/color.py
def set_brightness(self, value: float) -> Self:
    """Set brightness value and return self for method chaining."""
    self.brightness = value
    return self
set_rgb(color: Color | LiteralColor | PptxRGBColor) -> Self

Set RGB color value and return self for method chaining.

Source code in src/tppt/pptx/dml/color.py
def set_rgb(self, color: Color | LiteralColor | PptxRGBColor) -> Self:
    """Set RGB color value and return self for method chaining."""
    self.rgb = color
    return self
set_theme_color(value: LiteralThemeColor | MSO_THEME_COLOR | None) -> Self

Set theme color value and return self for method chaining.

Source code in src/tppt/pptx/dml/color.py
def set_theme_color(
    self, value: LiteralThemeColor | MSO_THEME_COLOR | None
) -> Self:
    """Set theme color value and return self for method chaining."""
    self.theme_color = value
    return self
Functions
to_pptx_theme_color(value: LiteralThemeColor | MSO_THEME_COLOR | None) -> MSO_THEME_COLOR
Source code in src/tppt/pptx/dml/color.py
def to_pptx_theme_color(
    value: LiteralThemeColor | MSO_THEME_COLOR | None,
) -> MSO_THEME_COLOR:
    match value:
        case MSO_THEME_COLOR():
            return value
        case None:
            return MSO_THEME_COLOR.NOT_THEME_COLOR
        case "accent1":
            return MSO_THEME_COLOR.ACCENT_1
        case "accent2":
            return MSO_THEME_COLOR.ACCENT_2
        case "accent3":
            return MSO_THEME_COLOR.ACCENT_3
        case "accent4":
            return MSO_THEME_COLOR.ACCENT_4
        case "accent5":
            return MSO_THEME_COLOR.ACCENT_5
        case "accent6":
            return MSO_THEME_COLOR.ACCENT_6
        case "background1":
            return MSO_THEME_COLOR.BACKGROUND_1
        case "background2":
            return MSO_THEME_COLOR.BACKGROUND_2
        case "dark1":
            return MSO_THEME_COLOR.DARK_1
        case "dark2":
            return MSO_THEME_COLOR.DARK_2
        case "followed_hyperlink":
            return MSO_THEME_COLOR.FOLLOWED_HYPERLINK
        case "hyperlink":
            return MSO_THEME_COLOR.HYPERLINK
        case "light1":
            return MSO_THEME_COLOR.LIGHT_1
        case "light2":
            return MSO_THEME_COLOR.LIGHT_2
        case "text1":
            return MSO_THEME_COLOR.TEXT_1
        case "text2":
            return MSO_THEME_COLOR.TEXT_2
        case "mixed":
            return MSO_THEME_COLOR.MIXED
        case _:
            assert_never(value)
effect
Classes
ShadowFormat

Bases: PptxConvertible[ShadowFormat]

Source code in src/tppt/pptx/dml/effect.py
class ShadowFormat(PptxConvertible[_PptxShadowFormat]):
    @property
    def inherit(self) -> bool:
        return self._pptx.inherit

    @inherit.setter
    def inherit(self, value: bool) -> None:
        self._pptx.inherit = value

    def set_inherit(self, value: bool) -> Self:
        self._pptx.inherit = value
        return self
Attributes
inherit: bool property writable
Functions
set_inherit(value: bool) -> Self
Source code in src/tppt/pptx/dml/effect.py
def set_inherit(self, value: bool) -> Self:
    self._pptx.inherit = value
    return self
fill
Attributes Classes
FillFormat

Bases: PptxConvertible[FillFormat]

Fill format.

Source code in src/tppt/pptx/dml/fill.py
class FillFormat(PptxConvertible[PptxFillFormat]):
    """Fill format."""

    @property
    def fore_color(self) -> ColorFormat:
        """Fore color."""
        return ColorFormat(self._pptx.fore_color)

    @property
    def back_color(self) -> ColorFormat:
        """Back color."""
        return ColorFormat(self._pptx.back_color)

    @property
    def pattern(self) -> MSO_PATTERN_TYPE:
        """Pattern."""
        return self._pptx.pattern

    @pattern.setter
    def pattern(self, value: MSO_PATTERN_TYPE) -> None:
        self._pptx.pattern = value

    def set_pattern(self, value: MSO_PATTERN_TYPE) -> "FillFormat":
        """Set pattern."""
        self.pattern = value
        return self

    def patterned(self) -> "PattFill":
        """Set the fill type to patterned."""
        self._pptx.patterned()
        return PattFill(cast(PptxPattFill, self._pptx._fill))

    def background(self) -> "NoFill":
        """Set the fill type to noFill, i.e. transparent."""
        self._pptx.background()
        return NoFill(cast(PptxNoFill, self._pptx._fill))

    def solid(self) -> "SolidFill":
        """Set the fill type to solid."""
        self._pptx.solid()
        return SolidFill(cast(PptxSolidFill, self._pptx._fill))

    def gradient(self) -> "GradFill":
        """Sets the fill type to gradient."""
        self._pptx.gradient()
        return GradFill(cast(PptxGradFill, self._pptx._fill))
Attributes
fore_color: ColorFormat property

Fore color.

back_color: ColorFormat property

Back color.

pattern: MSO_PATTERN_TYPE property writable

Pattern.

Functions
set_pattern(value: MSO_PATTERN_TYPE) -> FillFormat

Set pattern.

Source code in src/tppt/pptx/dml/fill.py
def set_pattern(self, value: MSO_PATTERN_TYPE) -> "FillFormat":
    """Set pattern."""
    self.pattern = value
    return self
patterned() -> PattFill

Set the fill type to patterned.

Source code in src/tppt/pptx/dml/fill.py
def patterned(self) -> "PattFill":
    """Set the fill type to patterned."""
    self._pptx.patterned()
    return PattFill(cast(PptxPattFill, self._pptx._fill))
background() -> NoFill

Set the fill type to noFill, i.e. transparent.

Source code in src/tppt/pptx/dml/fill.py
def background(self) -> "NoFill":
    """Set the fill type to noFill, i.e. transparent."""
    self._pptx.background()
    return NoFill(cast(PptxNoFill, self._pptx._fill))
solid() -> SolidFill

Set the fill type to solid.

Source code in src/tppt/pptx/dml/fill.py
def solid(self) -> "SolidFill":
    """Set the fill type to solid."""
    self._pptx.solid()
    return SolidFill(cast(PptxSolidFill, self._pptx._fill))
gradient() -> GradFill

Sets the fill type to gradient.

Source code in src/tppt/pptx/dml/fill.py
def gradient(self) -> "GradFill":
    """Sets the fill type to gradient."""
    self._pptx.gradient()
    return GradFill(cast(PptxGradFill, self._pptx._fill))
Fill

Bases: PptxConvertible[_GenericPptxFill]

Source code in src/tppt/pptx/dml/fill.py
class Fill(PptxConvertible[_GenericPptxFill]):
    pass
GradFill

Bases: Fill[_GradFill]

Gradient fill.

Source code in src/tppt/pptx/dml/fill.py
class GradFill(Fill[PptxGradFill]):
    """Gradient fill."""

    @property
    def gradient_angle(self) -> Angle | None:
        """Angle in float degrees of line of a linear gradient."""
        return to_tppt_angle(cast(float | None, self._pptx.gradient_angle))

    @gradient_angle.setter
    def gradient_angle(self, value: Angle) -> None:
        self._pptx.gradient_angle = to_pptx_angle(value)

    def set_gradient_angle(self, value: Angle) -> "GradFill":
        """Set gradient angle."""
        self.gradient_angle = value
        return self

    @property
    def gradient_stops(self) -> "GradientStops":
        """Gradient stops."""
        return GradientStops(self._pptx.gradient_stops)
Attributes
gradient_angle: Angle | None property writable

Angle in float degrees of line of a linear gradient.

gradient_stops: GradientStops property

Gradient stops.

Functions
set_gradient_angle(value: Angle) -> GradFill

Set gradient angle.

Source code in src/tppt/pptx/dml/fill.py
def set_gradient_angle(self, value: Angle) -> "GradFill":
    """Set gradient angle."""
    self.gradient_angle = value
    return self
NoFill

Bases: Fill[_NoFill]

No fill.

Source code in src/tppt/pptx/dml/fill.py
class NoFill(Fill[PptxNoFill]):
    """No fill."""
PattFill

Bases: Fill[_PattFill]

Pattern fill.

Source code in src/tppt/pptx/dml/fill.py
class PattFill(Fill[PptxPattFill]):
    """Pattern fill."""

    @property
    def back_color(self) -> ColorFormat:
        """Back color."""
        return ColorFormat(self._pptx.back_color)

    @property
    def fore_color(self) -> ColorFormat:
        """Fore color."""
        return ColorFormat(self._pptx.fore_color)

    @property
    def pattern(self) -> MSO_PATTERN_TYPE:
        """Pattern."""
        return self._pptx.pattern

    @pattern.setter
    def pattern(self, value: LiteralPatternType | MSO_PATTERN_TYPE) -> None:
        self._pptx.pattern = to_pptx_pattern_type(value)

    def set_pattern(self, value: LiteralPatternType | MSO_PATTERN_TYPE) -> "PattFill":
        """Set pattern."""
        self.pattern = value
        return self
Attributes
back_color: ColorFormat property

Back color.

fore_color: ColorFormat property

Fore color.

pattern: MSO_PATTERN_TYPE property writable

Pattern.

Functions
set_pattern(value: LiteralPatternType | MSO_PATTERN_TYPE) -> PattFill

Set pattern.

Source code in src/tppt/pptx/dml/fill.py
def set_pattern(self, value: LiteralPatternType | MSO_PATTERN_TYPE) -> "PattFill":
    """Set pattern."""
    self.pattern = value
    return self
SolidFill

Bases: Fill[_SolidFill]

Solid fill.

Source code in src/tppt/pptx/dml/fill.py
class SolidFill(Fill[PptxSolidFill]):
    """Solid fill."""

    @property
    def fore_color(self) -> ColorFormat:
        """Fore color."""
        return ColorFormat(self._pptx.fore_color)
Attributes
fore_color: ColorFormat property

Fore color.

GradientStops

Bases: PptxConvertible[_GradientStops]

Gradient stops.

Source code in src/tppt/pptx/dml/fill.py
class GradientStops(PptxConvertible[PptxGradientStops]):
    """Gradient stops."""

    def __getitem__(self, idx: int) -> "GradientStop":
        return GradientStop(self._pptx[idx])

    def __len__(self) -> int:
        return len(self._pptx)
Functions
__getitem__(idx: int) -> GradientStop
Source code in src/tppt/pptx/dml/fill.py
def __getitem__(self, idx: int) -> "GradientStop":
    return GradientStop(self._pptx[idx])
__len__() -> int
Source code in src/tppt/pptx/dml/fill.py
def __len__(self) -> int:
    return len(self._pptx)
GradientStop

Bases: PptxConvertible[_GradientStop]

Gradient stop.

Source code in src/tppt/pptx/dml/fill.py
class GradientStop(PptxConvertible[PptxGradientStop]):
    """Gradient stop."""

    @property
    def color(self) -> ColorFormat:
        """Color."""
        return ColorFormat(self._pptx.color)

    @property
    def position(self) -> float:
        """Location of stop in gradient path as float between 0.0 and 1.0.

        The value represents a percentage, where 0.0 (0%) represents the
        start of the path and 1.0 (100%) represents the end of the path. For
        a linear gradient, these would represent opposing extents of the
        filled area.
        """
        return self._pptx.position

    @position.setter
    def position(self, value: float) -> None:
        self._pptx.position = value

    def set_position(self, value: float) -> "GradientStop":
        """Set position."""
        self.position = value
        return self
Attributes
color: ColorFormat property

Color.

position: float property writable

Location of stop in gradient path as float between 0.0 and 1.0.

The value represents a percentage, where 0.0 (0%) represents the start of the path and 1.0 (100%) represents the end of the path. For a linear gradient, these would represent opposing extents of the filled area.

Functions
set_position(value: float) -> GradientStop

Set position.

Source code in src/tppt/pptx/dml/fill.py
def set_position(self, value: float) -> "GradientStop":
    """Set position."""
    self.position = value
    return self
Functions
line
Attributes Classes
LineFormat

Bases: PptxConvertible[LineFormat]

Line format.

Source code in src/tppt/pptx/dml/line.py
class LineFormat(PptxConvertible[_PptxLineFormat]):
    """Line format."""

    @property
    def color(self) -> ColorFormat:
        return ColorFormat(self._pptx.color)

    @property
    def dash_style(self) -> MSO_LINE_DASH_STYLE | None:
        return self._pptx.dash_style

    @dash_style.setter
    def dash_style(
        self, value: MSO_LINE_DASH_STYLE | LiteralLineDashStyle | None
    ) -> None:
        self._pptx.dash_style = to_pptx_line_dash_style(value)

    def set_dash_style(
        self, value: MSO_LINE_DASH_STYLE | LiteralLineDashStyle | None
    ) -> "LineFormat":
        self.dash_style = value
        return self

    @property
    def fill(self) -> FillFormat:
        return FillFormat(self._pptx.fill)

    @property
    def width(self) -> EnglishMetricUnits | None:
        return EnglishMetricUnits(self._pptx.width)

    @width.setter
    def width(self, value: EnglishMetricUnits | _PptxEmu) -> None:
        self._pptx.width = to_english_metric_units(value)

    def set_width(self, value: EnglishMetricUnits | _PptxEmu) -> "LineFormat":
        self.width = value
        return self
Attributes
color: ColorFormat property
dash_style: MSO_LINE_DASH_STYLE | None property writable
fill: FillFormat property
width: EnglishMetricUnits | None property writable
Functions
set_dash_style(value: MSO_LINE_DASH_STYLE | LiteralLineDashStyle | None) -> LineFormat
Source code in src/tppt/pptx/dml/line.py
def set_dash_style(
    self, value: MSO_LINE_DASH_STYLE | LiteralLineDashStyle | None
) -> "LineFormat":
    self.dash_style = value
    return self
set_width(value: EnglishMetricUnits | _PptxEmu) -> LineFormat
Source code in src/tppt/pptx/dml/line.py
def set_width(self, value: EnglishMetricUnits | _PptxEmu) -> "LineFormat":
    self.width = value
    return self
Functions
enum
Modules
dml
Attributes
LiteralLineDashStyle = Literal['dash', 'dash_dot', 'dash_dot_dot', 'long_dash', 'long_dash_dot', 'round_dot', 'solid', 'square_dot', 'mixed'] module-attribute
LiteralPatternType = Literal['cross', 'dark_downward_diagonal', 'dark_horizontal', 'dark_upward_diagonal', 'dark_vertical', 'dashed_downward_diagonal', 'dashed_horizontal', 'dashed_upward_diagonal', 'dashed_vertical', 'diagonal_brick', 'diagonal_cross', 'divot', 'dotted_grid', 'downward_diagonal', 'horizontal', 'horizontal_brick', 'large_checker_board', 'large_confetti', 'large_grid', 'light_downward_diagonal', 'light_horizontal', 'light_upward_diagonal', 'light_vertical', 'narrow_horizontal', 'narrow_vertical', 'outlined_diamond', '5%_of_the_foreground_color', '10%_of_the_foreground_color', '20%_of_the_foreground_color', '25%_of_the_foreground_color', '30%_of_the_foreground_color', '40%_of_the_foreground_color', '50%_of_the_foreground_color', '60%_of_the_foreground_color', '70%_of_the_foreground_color', '75%_of_the_foreground_color', '80%_of_the_foreground_color', '90%_of_the_foreground_color', 'plaid', 'shingle', 'small_checker_board', 'small_confetti', 'small_grid', 'solid_diamond', 'sphere', 'trellis', 'upward_diagonal', 'vertical', 'wave', 'weave', 'wide_downward_diagonal', 'wide_upward_diagonal', 'zig_zag', 'mixed'] module-attribute
Functions
to_pptx_line_dash_style(dash_style: LiteralLineDashStyle | MSO_LINE_DASH_STYLE | None) -> MSO_LINE_DASH_STYLE | None
to_pptx_line_dash_style(
    dash_style: LiteralLineDashStyle | MSO_LINE_DASH_STYLE,
) -> MSO_LINE_DASH_STYLE
to_pptx_line_dash_style(
    dash_style: LiteralLineDashStyle
    | MSO_LINE_DASH_STYLE
    | None,
) -> MSO_LINE_DASH_STYLE | None
Source code in src/tppt/pptx/enum/dml.py
def to_pptx_line_dash_style(
    dash_style: LiteralLineDashStyle | MSO_LINE_DASH_STYLE | None,
) -> MSO_LINE_DASH_STYLE | None:
    match dash_style:
        case None:
            return None
        case MSO_LINE_DASH_STYLE():
            return dash_style
        case "dash":
            return MSO_LINE_DASH_STYLE.DASH
        case "dash_dot":
            return MSO_LINE_DASH_STYLE.DASH_DOT
        case "dash_dot_dot":
            return MSO_LINE_DASH_STYLE.DASH_DOT_DOT
        case "long_dash":
            return MSO_LINE_DASH_STYLE.LONG_DASH
        case "long_dash_dot":
            return MSO_LINE_DASH_STYLE.LONG_DASH_DOT
        case "round_dot":
            return MSO_LINE_DASH_STYLE.ROUND_DOT
        case "solid":
            return MSO_LINE_DASH_STYLE.SOLID
        case "square_dot":
            return MSO_LINE_DASH_STYLE.SQUARE_DOT
        case "mixed":
            return MSO_LINE_DASH_STYLE.DASH_STYLE_MIXED
        case _:
            assert_never(dash_style)
to_pptx_pattern_type(pattern_type: LiteralPatternType | MSO_PATTERN_TYPE) -> MSO_PATTERN_TYPE
Source code in src/tppt/pptx/enum/dml.py
def to_pptx_pattern_type(
    pattern_type: LiteralPatternType | MSO_PATTERN_TYPE,
) -> MSO_PATTERN_TYPE:
    match pattern_type:
        case MSO_PATTERN_TYPE():
            return pattern_type
        case "cross":
            return MSO_PATTERN_TYPE.CROSS
        case "dark_downward_diagonal":
            return MSO_PATTERN_TYPE.DARK_DOWNWARD_DIAGONAL
        case "dark_horizontal":
            return MSO_PATTERN_TYPE.DARK_HORIZONTAL
        case "dark_upward_diagonal":
            return MSO_PATTERN_TYPE.DARK_UPWARD_DIAGONAL
        case "dark_vertical":
            return MSO_PATTERN_TYPE.DARK_VERTICAL
        case "dashed_downward_diagonal":
            return MSO_PATTERN_TYPE.DASHED_DOWNWARD_DIAGONAL
        case "dashed_horizontal":
            return MSO_PATTERN_TYPE.DASHED_HORIZONTAL
        case "dashed_upward_diagonal":
            return MSO_PATTERN_TYPE.DASHED_UPWARD_DIAGONAL
        case "dashed_vertical":
            return MSO_PATTERN_TYPE.DASHED_VERTICAL
        case "diagonal_brick":
            return MSO_PATTERN_TYPE.DIAGONAL_BRICK
        case "diagonal_cross":
            return MSO_PATTERN_TYPE.DIAGONAL_CROSS
        case "divot":
            return MSO_PATTERN_TYPE.DIVOT
        case "dotted_grid":
            return MSO_PATTERN_TYPE.DOTTED_GRID
        case "downward_diagonal":
            return MSO_PATTERN_TYPE.DOWNWARD_DIAGONAL
        case "horizontal":
            return MSO_PATTERN_TYPE.HORIZONTAL
        case "horizontal_brick":
            return MSO_PATTERN_TYPE.HORIZONTAL_BRICK
        case "large_checker_board":
            return MSO_PATTERN_TYPE.LARGE_CHECKER_BOARD
        case "large_confetti":
            return MSO_PATTERN_TYPE.LARGE_CONFETTI
        case "large_grid":
            return MSO_PATTERN_TYPE.LARGE_GRID
        case "light_downward_diagonal":
            return MSO_PATTERN_TYPE.LIGHT_DOWNWARD_DIAGONAL
        case "light_horizontal":
            return MSO_PATTERN_TYPE.LIGHT_HORIZONTAL
        case "light_upward_diagonal":
            return MSO_PATTERN_TYPE.LIGHT_UPWARD_DIAGONAL
        case "light_vertical":
            return MSO_PATTERN_TYPE.LIGHT_VERTICAL
        case "narrow_horizontal":
            return MSO_PATTERN_TYPE.NARROW_HORIZONTAL
        case "narrow_vertical":
            return MSO_PATTERN_TYPE.NARROW_VERTICAL
        case "outlined_diamond":
            return MSO_PATTERN_TYPE.OUTLINED_DIAMOND
        case "5%_of_the_foreground_color":
            return MSO_PATTERN_TYPE.PERCENT_5
        case "10%_of_the_foreground_color":
            return MSO_PATTERN_TYPE.PERCENT_10
        case "20%_of_the_foreground_color":
            return MSO_PATTERN_TYPE.PERCENT_20
        case "25%_of_the_foreground_color":
            return MSO_PATTERN_TYPE.PERCENT_25
        case "30%_of_the_foreground_color":
            return MSO_PATTERN_TYPE.PERCENT_30
        case "40%_of_the_foreground_color":
            return MSO_PATTERN_TYPE.ERCENT_40
        case "50%_of_the_foreground_color":
            return MSO_PATTERN_TYPE.PERCENT_50
        case "60%_of_the_foreground_color":
            return MSO_PATTERN_TYPE.PERCENT_60
        case "70%_of_the_foreground_color":
            return MSO_PATTERN_TYPE.PERCENT_70
        case "75%_of_the_foreground_color":
            return MSO_PATTERN_TYPE.PERCENT_75
        case "80%_of_the_foreground_color":
            return MSO_PATTERN_TYPE.PERCENT_80
        case "90%_of_the_foreground_color":
            return MSO_PATTERN_TYPE.PERCENT_90
        case "plaid":
            return MSO_PATTERN_TYPE.PLAID
        case "shingle":
            return MSO_PATTERN_TYPE.SHINGLE
        case "small_checker_board":
            return MSO_PATTERN_TYPE.SMALL_CHECKER_BOARD
        case "small_confetti":
            return MSO_PATTERN_TYPE.SMALL_CONFETTI
        case "small_grid":
            return MSO_PATTERN_TYPE.SMALL_GRID
        case "solid_diamond":
            return MSO_PATTERN_TYPE.SOLID_DIAMOND
        case "sphere":
            return MSO_PATTERN_TYPE.SPHERE
        case "trellis":
            return MSO_PATTERN_TYPE.TRELLIS
        case "upward_diagonal":
            return MSO_PATTERN_TYPE.UPWARD_DIAGONAL
        case "vertical":
            return MSO_PATTERN_TYPE.VERTICAL
        case "wave":
            return MSO_PATTERN_TYPE.WAVE
        case "weave":
            return MSO_PATTERN_TYPE.WEAVE
        case "wide_downward_diagonal":
            return MSO_PATTERN_TYPE.WIDE_DOWNWARD_DIAGONAL
        case "wide_upward_diagonal":
            return MSO_PATTERN_TYPE.WIDE_UPWARD_DIAGONAL
        case "zig_zag":
            return MSO_PATTERN_TYPE.ZIG_ZAG
        case "mixed":
            return MSO_PATTERN_TYPE.MIXED
        case _:
            assert_never(pattern_type)
notes_slide
Classes
NotesSlide

Bases: PptxConvertible[NotesSlide]

Notes slide.

Source code in src/tppt/pptx/notes_slide.py
class NotesSlide(PptxConvertible[PptxNotesSlide]):
    """Notes slide."""
presentation

Presentation wrapper implementation.

Attributes Classes
Presentation

Bases: PptxConvertible[Presentation]

Presentation wrapper with type safety.

Source code in src/tppt/pptx/presentation.py
class Presentation(PptxConvertible[_PptxPresentation]):
    """Presentation wrapper with type safety."""

    def __init__(
        self,
        pptx: _PptxPresentation | FilePath,
    ) -> None:
        """Initialize presentation."""
        if isinstance(pptx, (os.PathLike, str)):
            from pptx import Presentation

            pptx = Presentation(os.fspath(pptx))
        super().__init__(pptx)

    @property
    def core_properties(self) -> _PptxCorePropertiesPart:
        """Get the core properties."""
        return self._pptx.core_properties

    @property
    def notes_master(self) -> "NotesMaster":
        """Get the notes master."""
        return NotesMaster.from_pptx(self._pptx.notes_master)

    @property
    def slides(self) -> "list[Slide]":
        """Get the slides."""
        from tppt.pptx.slide import Slide

        return [Slide.from_pptx(slide) for slide in self._pptx.slides]

    @property
    def slide_master(self) -> "SlideMaster":
        """
        Get the slide master.

        This tool supports only one slide master.
        """
        from .slide_master import SlideMaster

        return SlideMaster.from_pptx(self._pptx.slide_masters[0])

    @property
    def slide_width(self) -> Length | None:
        return to_tppt_length(self._pptx.slide_width)

    @slide_width.setter
    def slide_width(self, value: Length | LiteralLength) -> None:
        self._pptx.slide_width = to_pptx_length(value)

    def set_slide_width(self, value: Length | LiteralLength) -> Self:
        self.slide_width = value
        return self

    @property
    def slide_height(self) -> Length | None:
        return to_tppt_length(self._pptx.slide_height)

    @slide_height.setter
    def slide_height(self, value: Length | LiteralLength) -> None:
        self._pptx.slide_height = to_pptx_length(value)

    def set_slide_height(self, value: Length | LiteralLength) -> Self:
        self.slide_height = value
        return self

    @property
    def tree(self) -> dict[str, Any]:
        """Get the node tree of the presentation."""
        return ppt2tree(self._pptx)

    @overload
    @classmethod
    def builder(
        cls,
    ) -> "PresentationBuilder[DefaultSlideMaster]": ...

    @overload
    @classmethod
    def builder(
        cls,
        slide_master: "type[GenericTpptSlideMaster]",
    ) -> "PresentationBuilder[GenericTpptSlideMaster]": ...

    @classmethod
    def builder(
        cls,
        slide_master=None,
    ):
        """Get a builder for the presentation."""

        if slide_master is None:
            slide_master = DefaultSlideMaster
        return PresentationBuilder(slide_master)

    def save(self, file: FilePath | IO[bytes]) -> None:
        """Save presentation to file."""
        if isinstance(file, os.PathLike):
            file = os.fspath(file)
        self._pptx.save(file)
Attributes
core_properties: _PptxCorePropertiesPart property

Get the core properties.

notes_master: NotesMaster property

Get the notes master.

slides: list[Slide] property

Get the slides.

slide_master: SlideMaster property

Get the slide master.

This tool supports only one slide master.

slide_width: Length | None property writable
slide_height: Length | None property writable
tree: dict[str, Any] property

Get the node tree of the presentation.

Functions
__init__(pptx: _PptxPresentation | FilePath) -> None

Initialize presentation.

Source code in src/tppt/pptx/presentation.py
def __init__(
    self,
    pptx: _PptxPresentation | FilePath,
) -> None:
    """Initialize presentation."""
    if isinstance(pptx, (os.PathLike, str)):
        from pptx import Presentation

        pptx = Presentation(os.fspath(pptx))
    super().__init__(pptx)
set_slide_width(value: Length | LiteralLength) -> Self
Source code in src/tppt/pptx/presentation.py
def set_slide_width(self, value: Length | LiteralLength) -> Self:
    self.slide_width = value
    return self
set_slide_height(value: Length | LiteralLength) -> Self
Source code in src/tppt/pptx/presentation.py
def set_slide_height(self, value: Length | LiteralLength) -> Self:
    self.slide_height = value
    return self
builder(slide_master=None) classmethod
builder() -> PresentationBuilder[DefaultSlideMaster]
builder(
    slide_master: type[GenericTpptSlideMaster],
) -> PresentationBuilder[GenericTpptSlideMaster]

Get a builder for the presentation.

Source code in src/tppt/pptx/presentation.py
@classmethod
def builder(
    cls,
    slide_master=None,
):
    """Get a builder for the presentation."""

    if slide_master is None:
        slide_master = DefaultSlideMaster
    return PresentationBuilder(slide_master)
save(file: FilePath | IO[bytes]) -> None

Save presentation to file.

Source code in src/tppt/pptx/presentation.py
def save(self, file: FilePath | IO[bytes]) -> None:
    """Save presentation to file."""
    if isinstance(file, os.PathLike):
        file = os.fspath(file)
    self._pptx.save(file)
PresentationBuilder

Bases: Generic[GenericTpptSlideMaster]

Builder for presentations.

Source code in src/tppt/pptx/presentation.py
class PresentationBuilder(Generic[GenericTpptSlideMaster]):
    """Builder for presentations."""

    def __init__(
        self,
        slide_master: "type[GenericTpptSlideMaster]",
    ) -> None:
        """Initialize the builder."""
        import pptx

        if (
            slide_master_source := slide_master.__slide_master_source__
        ) and slide_master_source != "default":
            self._pptx = pptx.Presentation(os.fspath(slide_master_source))
        else:
            self._pptx = pptx.Presentation()

        self._slide_master = slide_master

    def slide_width(self, value: Length | LiteralLength) -> Self:
        """Set the slide width."""
        self._pptx.slide_width = to_pptx_length(value)
        return self

    def slide_height(self, value: Length | LiteralLength) -> Self:
        """Set the slide height."""
        self._pptx.slide_height = to_pptx_length(value)
        return self

    def slide(
        self,
        slide: Callable[[type[GenericTpptSlideMaster]], SlideLayout | SlideBuilder],
        /,
    ) -> Self:
        """Add a slide to the presentation."""
        slide_master = SlideMasterProxy(self._slide_master, Presentation(self._pptx))
        template_slide_layout = cast(
            SlideLayoutProxy,
            slide(cast(type[GenericTpptSlideMaster], slide_master)),
        )

        slide_builder = cast(
            SlideBuilder,
            template_slide_layout.builder()
            if isinstance(template_slide_layout, SlideLayoutProxy)
            else template_slide_layout,
        )

        slide_layout = slide_builder._slide_layout.to_pptx()
        new_slide = self._pptx.slides.add_slide(slide_layout)

        slide_builder._build(new_slide)

        return self

    def build(self) -> Presentation:
        """Build the presentation."""

        return Presentation(self._pptx)

    def save(self, file: FilePath | IO[bytes]) -> None:
        """Save the presentation to a file."""
        self.build().save(file)
Functions
__init__(slide_master: type[GenericTpptSlideMaster]) -> None

Initialize the builder.

Source code in src/tppt/pptx/presentation.py
def __init__(
    self,
    slide_master: "type[GenericTpptSlideMaster]",
) -> None:
    """Initialize the builder."""
    import pptx

    if (
        slide_master_source := slide_master.__slide_master_source__
    ) and slide_master_source != "default":
        self._pptx = pptx.Presentation(os.fspath(slide_master_source))
    else:
        self._pptx = pptx.Presentation()

    self._slide_master = slide_master
slide_width(value: Length | LiteralLength) -> Self

Set the slide width.

Source code in src/tppt/pptx/presentation.py
def slide_width(self, value: Length | LiteralLength) -> Self:
    """Set the slide width."""
    self._pptx.slide_width = to_pptx_length(value)
    return self
slide_height(value: Length | LiteralLength) -> Self

Set the slide height.

Source code in src/tppt/pptx/presentation.py
def slide_height(self, value: Length | LiteralLength) -> Self:
    """Set the slide height."""
    self._pptx.slide_height = to_pptx_length(value)
    return self
slide(slide: Callable[[type[GenericTpptSlideMaster]], SlideLayout | SlideBuilder]) -> Self

Add a slide to the presentation.

Source code in src/tppt/pptx/presentation.py
def slide(
    self,
    slide: Callable[[type[GenericTpptSlideMaster]], SlideLayout | SlideBuilder],
    /,
) -> Self:
    """Add a slide to the presentation."""
    slide_master = SlideMasterProxy(self._slide_master, Presentation(self._pptx))
    template_slide_layout = cast(
        SlideLayoutProxy,
        slide(cast(type[GenericTpptSlideMaster], slide_master)),
    )

    slide_builder = cast(
        SlideBuilder,
        template_slide_layout.builder()
        if isinstance(template_slide_layout, SlideLayoutProxy)
        else template_slide_layout,
    )

    slide_layout = slide_builder._slide_layout.to_pptx()
    new_slide = self._pptx.slides.add_slide(slide_layout)

    slide_builder._build(new_slide)

    return self
build() -> Presentation

Build the presentation.

Source code in src/tppt/pptx/presentation.py
def build(self) -> Presentation:
    """Build the presentation."""

    return Presentation(self._pptx)
save(file: FilePath | IO[bytes]) -> None

Save the presentation to a file.

Source code in src/tppt/pptx/presentation.py
def save(self, file: FilePath | IO[bytes]) -> None:
    """Save the presentation to a file."""
    self.build().save(file)
NotesMaster

Bases: _BaseMaster

Notes master.

Source code in src/tppt/pptx/presentation.py
class NotesMaster(_BaseMaster):
    """Notes master."""

    def __init__(self, pptx_obj: _PptxNotesMaster) -> None:
        """Initialize the notes master."""
        super().__init__(pptx_obj)
Functions
__init__(pptx_obj: _PptxNotesMaster) -> None

Initialize the notes master.

Source code in src/tppt/pptx/presentation.py
def __init__(self, pptx_obj: _PptxNotesMaster) -> None:
    """Initialize the notes master."""
    super().__init__(pptx_obj)
Functions
shape

Shape wrapper implementation.

Attributes
GenericPptxBaseShape = TypeVar('GenericPptxBaseShape', bound=PptxBaseShape, default=PptxBaseShape) module-attribute
GenericPptxShape = TypeVar('GenericPptxShape', bound=PptxShape, default=PptxShape) module-attribute
Classes
BaseShape

Bases: PptxConvertible[GenericPptxBaseShape]

Source code in src/tppt/pptx/shape/__init__.py
class BaseShape(PptxConvertible[GenericPptxBaseShape]):
    def __eq__(self, other: object) -> bool:
        if not isinstance(other, BaseShape):
            return False
        return self._pptx is other._pptx

    def __ne__(self, other: object) -> bool:
        if not isinstance(other, BaseShape):
            return True
        return self._pptx is not other._pptx

    @property
    def click_action(self) -> "ActionSetting":
        from tppt.pptx.action import ActionSetting

        return ActionSetting(self._pptx.click_action)

    @property
    def element(self) -> "PptxShapeElement":
        return self._pptx.element

    @property
    def height(self) -> Length:
        return to_length(self._pptx.height)

    @height.setter
    def height(self, value: Length | LiteralLength | PptxLength) -> None:
        self._pptx.height = to_pptx_length(value)

    def set_height(self, value: Length | LiteralLength | PptxLength) -> Self:
        """Set height value and return self for method chaining."""
        self.height = value
        return self

    @property
    def left(self) -> Length:
        return to_length(self._pptx.left)

    @left.setter
    def left(self, value: Length | LiteralLength | PptxLength) -> None:
        self._pptx.left = to_pptx_length(value)

    def set_left(self, value: Length | LiteralLength | PptxLength) -> Self:
        """Set left position value and return self for method chaining."""
        self.left = value
        return self

    @property
    def name(self) -> str:
        return self._pptx.name

    @name.setter
    def name(self, value: str) -> None:
        self._pptx.name = value

    def set_name(self, value: str) -> Self:
        """Set name value and return self for method chaining."""
        self.name = value
        return self

    @property
    def part(self) -> "PptxBaseSlidePart":
        return self._pptx.part

    @property
    def placeholder_format(self) -> "PptxPlaceholderFormat":
        return self._pptx.placeholder_format

    @property
    def rotation(self) -> float:
        return self._pptx.rotation

    @rotation.setter
    def rotation(self, value: float) -> None:
        self._pptx.rotation = value

    def set_rotation(self, value: float) -> Self:
        """Set rotation value and return self for method chaining."""
        self.rotation = value
        return self

    @property
    def shadow(self) -> "ShadowFormat":
        from tppt.pptx.dml.effect import ShadowFormat

        return ShadowFormat(self._pptx.shadow)

    @property
    def shape_id(self) -> int:
        return self._pptx.shape_id

    @property
    def shape_type(self) -> "MSO_SHAPE_TYPE":
        return self._pptx.shape_type

    @property
    def top(self) -> Length:
        return to_length(self._pptx.top)

    @top.setter
    def top(self, value: Length | LiteralLength | PptxLength) -> None:
        self._pptx.top = to_pptx_length(value)

    def set_top(self, value: Length | LiteralLength | PptxLength) -> Self:
        """Set top position value and return self for method chaining."""
        self.top = value
        return self

    @property
    def width(self) -> Length:
        return to_length(self._pptx.width)

    @width.setter
    def width(self, value: Length | LiteralLength | PptxLength) -> None:
        self._pptx.width = to_pptx_length(value)

    def set_width(self, value: Length | LiteralLength | PptxLength) -> Self:
        """Set width value and return self for method chaining."""
        self.width = value
        return self
Attributes
click_action: ActionSetting property
element: PptxShapeElement property
height: Length property writable
left: Length property writable
name: str property writable
part: PptxBaseSlidePart property
placeholder_format: PptxPlaceholderFormat property
rotation: float property writable
shadow: ShadowFormat property
shape_id: int property
shape_type: MSO_SHAPE_TYPE property
top: Length property writable
width: Length property writable
Functions
__eq__(other: object) -> bool
Source code in src/tppt/pptx/shape/__init__.py
def __eq__(self, other: object) -> bool:
    if not isinstance(other, BaseShape):
        return False
    return self._pptx is other._pptx
__ne__(other: object) -> bool
Source code in src/tppt/pptx/shape/__init__.py
def __ne__(self, other: object) -> bool:
    if not isinstance(other, BaseShape):
        return True
    return self._pptx is not other._pptx
set_height(value: Length | LiteralLength | PptxLength) -> Self

Set height value and return self for method chaining.

Source code in src/tppt/pptx/shape/__init__.py
def set_height(self, value: Length | LiteralLength | PptxLength) -> Self:
    """Set height value and return self for method chaining."""
    self.height = value
    return self
set_left(value: Length | LiteralLength | PptxLength) -> Self

Set left position value and return self for method chaining.

Source code in src/tppt/pptx/shape/__init__.py
def set_left(self, value: Length | LiteralLength | PptxLength) -> Self:
    """Set left position value and return self for method chaining."""
    self.left = value
    return self
set_name(value: str) -> Self

Set name value and return self for method chaining.

Source code in src/tppt/pptx/shape/__init__.py
def set_name(self, value: str) -> Self:
    """Set name value and return self for method chaining."""
    self.name = value
    return self
set_rotation(value: float) -> Self

Set rotation value and return self for method chaining.

Source code in src/tppt/pptx/shape/__init__.py
def set_rotation(self, value: float) -> Self:
    """Set rotation value and return self for method chaining."""
    self.rotation = value
    return self
set_top(value: Length | LiteralLength | PptxLength) -> Self

Set top position value and return self for method chaining.

Source code in src/tppt/pptx/shape/__init__.py
def set_top(self, value: Length | LiteralLength | PptxLength) -> Self:
    """Set top position value and return self for method chaining."""
    self.top = value
    return self
set_width(value: Length | LiteralLength | PptxLength) -> Self

Set width value and return self for method chaining.

Source code in src/tppt/pptx/shape/__init__.py
def set_width(self, value: Length | LiteralLength | PptxLength) -> Self:
    """Set width value and return self for method chaining."""
    self.width = value
    return self
Shape

Bases: BaseShape[GenericPptxShape]

Source code in src/tppt/pptx/shape/__init__.py
class Shape(BaseShape[GenericPptxShape]):
    @property
    def adjustments(self) -> list[float]:
        return [self._pptx.adjustments[i] for i in range(len(self._pptx.adjustments))]

    @property
    def auto_shape_type(self) -> "MSO_AUTO_SHAPE_TYPE | None":
        return self._pptx.auto_shape_type

    @property
    def fill(self) -> "FillFormat":
        from tppt.pptx.dml.fill import FillFormat

        return FillFormat(self._pptx.fill)

    @property
    def line(self) -> "LineFormat":
        from tppt.pptx.dml.line import LineFormat

        return LineFormat(self._pptx.line)

    @property
    def text(self) -> str:
        return self._pptx.text

    @text.setter
    def text(self, text: str) -> None:
        self._pptx.text = text

    def set_text(self, text: str) -> Self:
        """Set text value and return self for method chaining."""
        self.text = text
        return self

    @property
    def text_frame(self) -> "TextFrame":
        from tppt.pptx.text.text_frame import TextFrame

        return TextFrame(self._pptx.text_frame)
Attributes
adjustments: list[float] property
auto_shape_type: MSO_AUTO_SHAPE_TYPE | None property
fill: FillFormat property
line: LineFormat property
text: str property writable
text_frame: TextFrame property
Functions
set_text(text: str) -> Self

Set text value and return self for method chaining.

Source code in src/tppt/pptx/shape/__init__.py
def set_text(self, text: str) -> Self:
    """Set text value and return self for method chaining."""
    self.text = text
    return self
SubShape

Bases: PptxConvertible[_GenericPptxSubshape]

Source code in src/tppt/pptx/shape/__init__.py
class SubShape(PptxConvertible[_GenericPptxSubshape]):
    pass
RangeProps

Bases: TypedDict

Range properties.

Source code in src/tppt/pptx/shape/__init__.py
class RangeProps(TypedDict):
    """Range properties."""

    left: Length | LiteralLength
    top: Length | LiteralLength
    width: Length | LiteralLength
    height: Length | LiteralLength
Attributes
left: Length | LiteralLength instance-attribute
top: Length | LiteralLength instance-attribute
width: Length | LiteralLength instance-attribute
height: Length | LiteralLength instance-attribute
Functions Modules
background
Classes
Background

Bases: PptxConvertible[_Background]

Background of the slide.

Source code in src/tppt/pptx/shape/background.py
class Background(PptxConvertible[PptxBackground]):
    """Background of the slide."""
picture
Attributes
MOVIE_MIME_TYPE = Literal['video/x-ms-asf', 'video/avi', 'video/quicktime', 'video/mp4', 'video/mpeg', 'video/msvideo', 'video/x-ms-wmv', 'video/x-msvideo'] module-attribute
Classes
PictureProps

Bases: TypedDict

Picture properties.

Source code in src/tppt/pptx/shape/picture.py
class PictureProps(TypedDict):
    """Picture properties."""

    left: Length | LiteralLength
    top: Length | LiteralLength
    width: NotRequired[Length | LiteralLength]
    height: NotRequired[Length | LiteralLength]
Attributes
left: Length | LiteralLength instance-attribute
top: Length | LiteralLength instance-attribute
width: NotRequired[Length | LiteralLength] instance-attribute
height: NotRequired[Length | LiteralLength] instance-attribute
PictureData

Bases: PictureProps

Picture data.

Source code in src/tppt/pptx/shape/picture.py
class PictureData(PictureProps):
    """Picture data."""

    type: Literal["picture"]

    image_file: FilePath | IO[bytes]
Attributes
type: Literal['picture'] instance-attribute
image_file: FilePath | IO[bytes] instance-attribute
Picture

Bases: BaseShape[Picture]

Picture data class.

Source code in src/tppt/pptx/shape/picture.py
class Picture(BaseShape[PptxPicture]):
    """Picture data class."""

    def __init__(
        self,
        pptx_obj: PptxPicture,
        data: PictureData | None = None,
        /,
    ) -> None:
        self._pptx = pptx_obj
Functions
__init__(pptx_obj: PptxPicture, data: PictureData | None = None) -> None
Source code in src/tppt/pptx/shape/picture.py
def __init__(
    self,
    pptx_obj: PptxPicture,
    data: PictureData | None = None,
    /,
) -> None:
    self._pptx = pptx_obj
MovieProps

Bases: RangeProps

Movie properties.

Source code in src/tppt/pptx/shape/picture.py
class MovieProps(RangeProps):
    """Movie properties."""

    poster_frame_image: NotRequired[FilePath | IO[bytes]]

    mime_type: MOVIE_MIME_TYPE
    """
    Mime type of the movie.

    NOTE: The Movie shape is an experimental feature of python-pptx, and specifying the mime_type is recommended.
    """
Attributes
poster_frame_image: NotRequired[FilePath | IO[bytes]] instance-attribute
mime_type: MOVIE_MIME_TYPE instance-attribute

Mime type of the movie.

NOTE: The Movie shape is an experimental feature of python-pptx, and specifying the mime_type is recommended.

MovieData

Bases: MovieProps

Movie data.

Source code in src/tppt/pptx/shape/picture.py
class MovieData(MovieProps):
    """Movie data."""

    type: Literal["movie"]

    movie_file: FilePath | IO[bytes]
Attributes
type: Literal['movie'] instance-attribute
movie_file: FilePath | IO[bytes] instance-attribute
Movie

Bases: BaseShape[Movie]

Movie data class.

Source code in src/tppt/pptx/shape/picture.py
class Movie(BaseShape[PptxMovie]):
    """Movie data class."""

    def __init__(
        self,
        pptx_obj: PptxMovie,
        data: MovieData | None = None,
        /,
    ) -> None:
        self._pptx = pptx_obj
Functions
__init__(pptx_obj: PptxMovie, data: MovieData | None = None) -> None
Source code in src/tppt/pptx/shape/picture.py
def __init__(
    self,
    pptx_obj: PptxMovie,
    data: MovieData | None = None,
    /,
) -> None:
    self._pptx = pptx_obj
Functions
to_pptx_movie_mime_type(mime_type: MOVIE_MIME_TYPE) -> str

Convert movie mime type to pptx movie mime type.

Source code in src/tppt/pptx/shape/picture.py
def to_pptx_movie_mime_type(mime_type: MOVIE_MIME_TYPE) -> str:
    """Convert movie mime type to pptx movie mime type."""
    match mime_type:
        case "video/x-ms-asf":
            return CONTENT_TYPE.ASF
        case "video/avi":
            return CONTENT_TYPE.AVI
        case "video/quicktime":
            return CONTENT_TYPE.MOV
        case "video/mp4":
            return CONTENT_TYPE.MP4
        case "video/mpeg":
            return CONTENT_TYPE.MPG
        case "video/msvideo":
            return CONTENT_TYPE.MS_VIDEO
        case "video/x-ms-wmv":
            return CONTENT_TYPE.WMV
        case "video/x-msvideo":
            return CONTENT_TYPE.X_MS_VIDEO
        case _:
            assert_never(mime_type)
placeholder
Classes
LayoutPlaceholder

Bases: Shape[LayoutPlaceholder]

Source code in src/tppt/pptx/shape/placeholder.py
class LayoutPlaceholder(Shape[_PptxLayoutPlaceholder]): ...
MasterPlaceholder

Bases: Shape[MasterPlaceholder]

Source code in src/tppt/pptx/shape/placeholder.py
class MasterPlaceholder(Shape[_PptxMasterPlaceholder]): ...
SlidePlaceholder

Bases: Shape[SlidePlaceholder]

Source code in src/tppt/pptx/shape/placeholder.py
class SlidePlaceholder(Shape[_PptxSlidePlaceholder]): ...
text
Attributes Classes
TextProps

Bases: RangeProps

Text properties.

Source code in src/tppt/pptx/shape/text.py
class TextProps(RangeProps):
    """Text properties."""

    size: NotRequired[Length | LiteralLength]
    bold: NotRequired[bool]
    italic: NotRequired[bool]
    color: NotRequired[Color | LiteralColor]
    margin_bottom: NotRequired[Length | LiteralLength]
    margin_left: NotRequired[Length | LiteralLength]
    vertical_anchor: NotRequired[MSO_ANCHOR]
    word_wrap: NotRequired[bool]
    auto_size: NotRequired[MSO_AUTO_SIZE]
    alignment: NotRequired[PP_ALIGN]
    level: NotRequired[int]
Attributes
size: NotRequired[Length | LiteralLength] instance-attribute
bold: NotRequired[bool] instance-attribute
italic: NotRequired[bool] instance-attribute
color: NotRequired[Color | LiteralColor] instance-attribute
margin_bottom: NotRequired[Length | LiteralLength] instance-attribute
margin_left: NotRequired[Length | LiteralLength] instance-attribute
vertical_anchor: NotRequired[MSO_ANCHOR] instance-attribute
word_wrap: NotRequired[bool] instance-attribute
auto_size: NotRequired[MSO_AUTO_SIZE] instance-attribute
alignment: NotRequired[PP_ALIGN] instance-attribute
level: NotRequired[int] instance-attribute
TextData

Bases: TextProps

Text data.

Source code in src/tppt/pptx/shape/text.py
class TextData(TextProps):
    """Text data."""

    type: Literal["text"]

    text: str
Attributes
type: Literal['text'] instance-attribute
text: str instance-attribute
Text

Bases: Shape

Text data class.

Source code in src/tppt/pptx/shape/text.py
class Text(Shape):
    """Text data class."""

    def __init__(self, pptx_obj: PptxShape, data: TextData | None = None, /) -> None:
        if data and data["text"] != "":
            text_frame = TextFrame(pptx_obj.text_frame)
            p = text_frame.paragraphs[0]
            run = p.add_run()
            run.text = data["text"]
            font = run.font
            if size := data.get("size"):
                font.size = to_length(size)
            if (bold := data.get("bold")) is not None:
                font.bold = bold
            if (italic := data.get("italic")) is not None:
                font.italic = italic
            if (color := data.get("color")) is not None:
                font.color.rgb = to_color(color)
            if (margin_bottom := data.get("margin_bottom")) is not None:
                p.space_after = to_length(margin_bottom)
            if (margin_left := data.get("margin_left")) is not None:
                p.space_before = to_length(margin_left)
            if (vertical_anchor := data.get("vertical_anchor")) is not None:
                text_frame.vertical_anchor = vertical_anchor
            if (word_wrap := data.get("word_wrap")) is not None:
                text_frame.word_wrap = word_wrap
            if (auto_size := data.get("auto_size")) is not None:
                text_frame.auto_size = auto_size
            if (alignment := data.get("alignment")) is not None:
                p.alignment = alignment
            if (level := data.get("level")) is not None:
                p.level = level

        self._pptx = pptx_obj

    @property
    def text_frame(self) -> TextFrame:
        return TextFrame(self._pptx.text_frame)
Attributes
text_frame: TextFrame property
Functions
__init__(pptx_obj: PptxShape, data: TextData | None = None) -> None
Source code in src/tppt/pptx/shape/text.py
def __init__(self, pptx_obj: PptxShape, data: TextData | None = None, /) -> None:
    if data and data["text"] != "":
        text_frame = TextFrame(pptx_obj.text_frame)
        p = text_frame.paragraphs[0]
        run = p.add_run()
        run.text = data["text"]
        font = run.font
        if size := data.get("size"):
            font.size = to_length(size)
        if (bold := data.get("bold")) is not None:
            font.bold = bold
        if (italic := data.get("italic")) is not None:
            font.italic = italic
        if (color := data.get("color")) is not None:
            font.color.rgb = to_color(color)
        if (margin_bottom := data.get("margin_bottom")) is not None:
            p.space_after = to_length(margin_bottom)
        if (margin_left := data.get("margin_left")) is not None:
            p.space_before = to_length(margin_left)
        if (vertical_anchor := data.get("vertical_anchor")) is not None:
            text_frame.vertical_anchor = vertical_anchor
        if (word_wrap := data.get("word_wrap")) is not None:
            text_frame.word_wrap = word_wrap
        if (auto_size := data.get("auto_size")) is not None:
            text_frame.auto_size = auto_size
        if (alignment := data.get("alignment")) is not None:
            p.alignment = alignment
        if (level := data.get("level")) is not None:
            p.level = level

    self._pptx = pptx_obj
Functions
slide

Slide wrapper implementation.

Attributes Classes
Slide

Bases: _BaseSlide[Slide]

Slide wrapper with type safety.

Source code in src/tppt/pptx/slide.py
class Slide(_BaseSlide[PptxSlide]):
    """Slide wrapper with type safety."""

    @property
    def follow_master_background(self) -> bool:
        return self._pptx.follow_master_background

    @property
    def notes_slide(self) -> "NotesSlide | None":
        """Get the notes slide."""
        if not self._pptx.has_notes_slide:
            return None

        from .notes_slide import NotesSlide

        return NotesSlide(self._pptx.notes_slide)

    @property
    def placeholders(self) -> list[SlidePlaceholder]:
        """Get all placeholders in the slide."""
        return [
            SlidePlaceholder(
                placeholder,  # type: ignore
            )
            for placeholder in self._pptx.placeholders
        ]

    @property
    def shapes(self) -> list[BaseShape]:
        """Get all shapes in the slide."""
        return [BaseShape(shape) for shape in self._pptx.shapes]

    @property
    def slide_id(self) -> int:
        """Get the slide id."""
        return self._pptx.slide_id

    @property
    def slide_layout(self) -> SlideLayout:
        """Get the slide layout."""
        return SlideLayout.from_pptx(self._pptx.slide_layout)
Attributes
follow_master_background: bool property
notes_slide: NotesSlide | None property

Get the notes slide.

placeholders: list[SlidePlaceholder] property

Get all placeholders in the slide.

shapes: list[BaseShape] property

Get all shapes in the slide.

slide_id: int property

Get the slide id.

slide_layout: SlideLayout property

Get the slide layout.

SlideBuilder

Slide builder.

Source code in src/tppt/pptx/slide.py
class SlideBuilder:
    """Slide builder."""

    def __init__(
        self,
        slide_layout: SlideLayout,
        placeholder_registry: Callable[[Slide], None],
    ) -> None:
        self._slide_layout = slide_layout
        self._shape_registry: list[Callable[[Slide], Any]] = []
        self._placeholder_registry = placeholder_registry

    @overload
    def text(self, text: str, /, **kwargs: Unpack[TextProps]) -> Self: ...

    @overload
    def text(
        self, text: Callable[[Text], Text], /, **kwargs: Unpack[RangeProps]
    ) -> Self: ...

    def text(
        self,
        text: str | Callable[[Text], Text],
        /,
        **kwargs: Unpack[TextProps],
    ) -> Self:
        def _register(slide: Slide) -> Text:
            data = TextData(
                type="text",
                text=text if isinstance(text, str) else "",
                **kwargs,
            )

            text_obj = Text(
                slide.to_pptx().shapes.add_textbox(
                    to_pptx_length(data["left"]),
                    to_pptx_length(data["top"]),
                    to_pptx_length(data["width"]),
                    to_pptx_length(data["height"]),
                ),
                data,
            )
            if isinstance(text, Callable):
                return text(text_obj)
            else:
                return text_obj

        self._shape_registry.append(_register)

        return self

    @overload
    def picture(
        self, image: FilePath | IO[bytes], /, **kwargs: Unpack[PictureProps]
    ) -> Self: ...

    @overload
    def picture(
        self,
        image: Callable[[Picture], Picture],
        /,
        image_file: FilePath | IO[bytes],
        **kwargs: Unpack[PictureProps],
    ) -> Self: ...

    def picture(
        self,
        image: FilePath | IO[bytes] | Callable[[Picture], Picture],
        image_file: FilePath | IO[bytes] | None = None,
        **kwargs: Unpack[PictureProps],
    ) -> Self:
        if not isinstance(image, Callable):
            image_file = image

        assert image_file
        if isinstance(image_file, os.PathLike):
            image_file = os.fspath(image_file)

        def _register(slide: Slide) -> Picture:
            data = PictureData(type="picture", image_file=image_file, **kwargs)
            picture_obj = Picture(
                slide.to_pptx().shapes.add_picture(
                    image_file,
                    to_pptx_length(data["left"]),
                    to_pptx_length(data["top"]),
                    to_pptx_length(data.get("width")),
                    to_pptx_length(data.get("height")),
                ),
                data,
            )
            if isinstance(image, Callable):
                return image(picture_obj)
            else:
                return picture_obj

        self._shape_registry.append(_register)

        return self

    @overload
    def movie(
        self, movie: FilePath | IO[bytes], /, **kwargs: Unpack[MovieProps]
    ) -> Self: ...

    @overload
    def movie(
        self,
        movie: Callable[[Movie], Movie],
        /,
        movie_file: FilePath | IO[bytes],
        **kwargs: Unpack[MovieProps],
    ) -> Self: ...

    def movie(
        self,
        movie: FilePath | IO[bytes] | Callable[[Movie], Movie],
        /,
        movie_file: FilePath | IO[bytes] | None = None,
        **kwargs: Unpack[MovieProps],
    ) -> Self:
        if not isinstance(movie, Callable):
            movie_file = movie

        assert movie_file
        if isinstance(movie_file, os.PathLike):
            movie_file = os.fspath(movie_file)

        poster_frame_image = kwargs.get("poster_frame_image")
        if isinstance(poster_frame_image, os.PathLike):
            poster_frame_image = os.fspath(poster_frame_image)

        mime_type = to_pptx_movie_mime_type(kwargs["mime_type"])

        def _register(slide: Slide) -> Movie:
            data = MovieData(type="movie", movie_file=movie_file, **kwargs)
            movie_obj = Movie(
                cast(
                    # NOTE: Type hint of python-pptx is incorrect. Expected Movie, but GraphicFrame is returned.
                    # Ref: https://github.com/scanny/python-pptx/pull/1057/commits/56338fa314d2c5bceb8b1756a50ed64ea8984abe
                    PptxMovie,
                    slide.to_pptx().shapes.add_movie(
                        movie_file,
                        to_pptx_length(data["left"]),
                        to_pptx_length(data["top"]),
                        to_pptx_length(data.get("width")),
                        to_pptx_length(data.get("height")),
                        poster_frame_image=poster_frame_image,
                        mime_type=mime_type,
                    ),
                ),
                data,
            )
            if isinstance(movie, Callable):
                return movie(movie_obj)
            else:
                return movie_obj

        self._shape_registry.append(_register)

        return self

    @overload
    def table(self, data: DataFrame, /, **kwargs: Unpack[TableProps]) -> Self: ...

    @overload
    def table(
        self,
        data: Callable[[Table], Table],
        /,
        rows: int,
        cols: int,
        **kwargs: Unpack[TableProps],
    ) -> Self: ...

    def table(
        self,
        data: DataFrame | Callable[[Table], Table],
        /,
        rows: int | None = None,
        cols: int | None = None,
        **kwargs: Unpack[TableProps],
    ) -> Self:
        if isinstance(data, Callable):
            assert rows is not None
            assert cols is not None
            table_data: TableData = {"type": "table", "data": [], **kwargs}
        else:
            data = dataframe2list(data)
            rows, cols = len(data), len(data[0])

            table_data: TableData = {
                "type": "table",
                "data": data,
                **kwargs,
            }

        def _register(slide: Slide) -> Table:
            table_obj = Table(
                slide.to_pptx()
                .shapes.add_table(
                    rows,
                    cols,
                    to_pptx_length(table_data["left"]),
                    to_pptx_length(table_data["top"]),
                    to_pptx_length(table_data["width"]),
                    to_pptx_length(table_data["height"]),
                )
                .table,
                table_data,
            )

            if isinstance(data, Callable):
                return data(table_obj)
            else:
                return table_obj

        self._shape_registry.append(_register)

        return self

    def chart(
        self,
        data: Callable[[Chart], Chart] | None = None,
        /,
        **kwargs: Unpack[ChartProps],
    ) -> Self:
        chart_type = to_pptx_chart_type(kwargs["chart_type"])

        def _register(slide: Slide) -> Chart:
            data: ChartData = {
                "type": "chart",
                **kwargs,
            }

            chart_obj = Chart(
                slide.to_pptx().shapes.add_chart(
                    chart_type=chart_type,
                    x=to_pptx_length(data["x"]),
                    y=to_pptx_length(data["y"]),
                    cx=to_pptx_length(data["cx"]),
                    cy=to_pptx_length(data["cy"]),
                    chart_data=data["chart_data"],
                )
            )
            if isinstance(data, Callable):
                return data(chart_obj)
            else:
                return chart_obj

        self._shape_registry.append(_register)

        return self

    @overload
    def add_shape(
        self,
        shape_type: "MSO_AUTO_SHAPE_TYPE",
        /,
        **kwargs: Unpack[RangeProps],
    ) -> Self: ...

    @overload
    def add_shape(
        self,
        shape_type: "MSO_AUTO_SHAPE_TYPE",
        shape: Callable[[Shape], Shape],
        /,
        **kwargs: Unpack[RangeProps],
    ) -> Self: ...

    def add_shape(
        self,
        shape_type: "MSO_AUTO_SHAPE_TYPE",
        shape: Callable[[Shape], Shape] | None = None,
        /,
        **kwargs: Unpack[RangeProps],
    ) -> Self:
        """Add a shape to the slide."""

        def _register(slide: Slide) -> Shape:
            shape_obj = Shape(
                slide.to_pptx().shapes.add_shape(
                    shape_type,
                    to_pptx_length(kwargs["left"]),
                    to_pptx_length(kwargs["top"]),
                    to_pptx_length(kwargs["width"]),
                    to_pptx_length(kwargs["height"]),
                )
            )
            if shape is not None:
                return shape(shape_obj)
            else:
                return shape_obj

        self._shape_registry.append(_register)
        return self

    def _build(self, slide: PptxSlide) -> Slide:
        tppt_slide = Slide(slide)

        self._placeholder_registry(tppt_slide)
        for register in self._shape_registry:
            register(tppt_slide)

        return tppt_slide
Functions
__init__(slide_layout: SlideLayout, placeholder_registry: Callable[[Slide], None]) -> None
Source code in src/tppt/pptx/slide.py
def __init__(
    self,
    slide_layout: SlideLayout,
    placeholder_registry: Callable[[Slide], None],
) -> None:
    self._slide_layout = slide_layout
    self._shape_registry: list[Callable[[Slide], Any]] = []
    self._placeholder_registry = placeholder_registry
text(text: str | Callable[[Text], Text], /, **kwargs: Unpack[TextProps]) -> Self
text(text: str, /, **kwargs: Unpack[TextProps]) -> Self
text(
    text: Callable[[Text], Text],
    /,
    **kwargs: Unpack[RangeProps],
) -> Self
Source code in src/tppt/pptx/slide.py
def text(
    self,
    text: str | Callable[[Text], Text],
    /,
    **kwargs: Unpack[TextProps],
) -> Self:
    def _register(slide: Slide) -> Text:
        data = TextData(
            type="text",
            text=text if isinstance(text, str) else "",
            **kwargs,
        )

        text_obj = Text(
            slide.to_pptx().shapes.add_textbox(
                to_pptx_length(data["left"]),
                to_pptx_length(data["top"]),
                to_pptx_length(data["width"]),
                to_pptx_length(data["height"]),
            ),
            data,
        )
        if isinstance(text, Callable):
            return text(text_obj)
        else:
            return text_obj

    self._shape_registry.append(_register)

    return self
picture(image: FilePath | IO[bytes] | Callable[[Picture], Picture], image_file: FilePath | IO[bytes] | None = None, **kwargs: Unpack[PictureProps]) -> Self
picture(
    image: FilePath | IO[bytes],
    /,
    **kwargs: Unpack[PictureProps],
) -> Self
picture(
    image: Callable[[Picture], Picture],
    /,
    image_file: FilePath | IO[bytes],
    **kwargs: Unpack[PictureProps],
) -> Self
Source code in src/tppt/pptx/slide.py
def picture(
    self,
    image: FilePath | IO[bytes] | Callable[[Picture], Picture],
    image_file: FilePath | IO[bytes] | None = None,
    **kwargs: Unpack[PictureProps],
) -> Self:
    if not isinstance(image, Callable):
        image_file = image

    assert image_file
    if isinstance(image_file, os.PathLike):
        image_file = os.fspath(image_file)

    def _register(slide: Slide) -> Picture:
        data = PictureData(type="picture", image_file=image_file, **kwargs)
        picture_obj = Picture(
            slide.to_pptx().shapes.add_picture(
                image_file,
                to_pptx_length(data["left"]),
                to_pptx_length(data["top"]),
                to_pptx_length(data.get("width")),
                to_pptx_length(data.get("height")),
            ),
            data,
        )
        if isinstance(image, Callable):
            return image(picture_obj)
        else:
            return picture_obj

    self._shape_registry.append(_register)

    return self
movie(movie: FilePath | IO[bytes] | Callable[[Movie], Movie], /, movie_file: FilePath | IO[bytes] | None = None, **kwargs: Unpack[MovieProps]) -> Self
movie(
    movie: FilePath | IO[bytes],
    /,
    **kwargs: Unpack[MovieProps],
) -> Self
movie(
    movie: Callable[[Movie], Movie],
    /,
    movie_file: FilePath | IO[bytes],
    **kwargs: Unpack[MovieProps],
) -> Self
Source code in src/tppt/pptx/slide.py
def movie(
    self,
    movie: FilePath | IO[bytes] | Callable[[Movie], Movie],
    /,
    movie_file: FilePath | IO[bytes] | None = None,
    **kwargs: Unpack[MovieProps],
) -> Self:
    if not isinstance(movie, Callable):
        movie_file = movie

    assert movie_file
    if isinstance(movie_file, os.PathLike):
        movie_file = os.fspath(movie_file)

    poster_frame_image = kwargs.get("poster_frame_image")
    if isinstance(poster_frame_image, os.PathLike):
        poster_frame_image = os.fspath(poster_frame_image)

    mime_type = to_pptx_movie_mime_type(kwargs["mime_type"])

    def _register(slide: Slide) -> Movie:
        data = MovieData(type="movie", movie_file=movie_file, **kwargs)
        movie_obj = Movie(
            cast(
                # NOTE: Type hint of python-pptx is incorrect. Expected Movie, but GraphicFrame is returned.
                # Ref: https://github.com/scanny/python-pptx/pull/1057/commits/56338fa314d2c5bceb8b1756a50ed64ea8984abe
                PptxMovie,
                slide.to_pptx().shapes.add_movie(
                    movie_file,
                    to_pptx_length(data["left"]),
                    to_pptx_length(data["top"]),
                    to_pptx_length(data.get("width")),
                    to_pptx_length(data.get("height")),
                    poster_frame_image=poster_frame_image,
                    mime_type=mime_type,
                ),
            ),
            data,
        )
        if isinstance(movie, Callable):
            return movie(movie_obj)
        else:
            return movie_obj

    self._shape_registry.append(_register)

    return self
table(data: DataFrame | Callable[[Table], Table], /, rows: int | None = None, cols: int | None = None, **kwargs: Unpack[TableProps]) -> Self
table(
    data: DataFrame, /, **kwargs: Unpack[TableProps]
) -> Self
table(
    data: Callable[[Table], Table],
    /,
    rows: int,
    cols: int,
    **kwargs: Unpack[TableProps],
) -> Self
Source code in src/tppt/pptx/slide.py
def table(
    self,
    data: DataFrame | Callable[[Table], Table],
    /,
    rows: int | None = None,
    cols: int | None = None,
    **kwargs: Unpack[TableProps],
) -> Self:
    if isinstance(data, Callable):
        assert rows is not None
        assert cols is not None
        table_data: TableData = {"type": "table", "data": [], **kwargs}
    else:
        data = dataframe2list(data)
        rows, cols = len(data), len(data[0])

        table_data: TableData = {
            "type": "table",
            "data": data,
            **kwargs,
        }

    def _register(slide: Slide) -> Table:
        table_obj = Table(
            slide.to_pptx()
            .shapes.add_table(
                rows,
                cols,
                to_pptx_length(table_data["left"]),
                to_pptx_length(table_data["top"]),
                to_pptx_length(table_data["width"]),
                to_pptx_length(table_data["height"]),
            )
            .table,
            table_data,
        )

        if isinstance(data, Callable):
            return data(table_obj)
        else:
            return table_obj

    self._shape_registry.append(_register)

    return self
chart(data: Callable[[Chart], Chart] | None = None, /, **kwargs: Unpack[ChartProps]) -> Self
Source code in src/tppt/pptx/slide.py
def chart(
    self,
    data: Callable[[Chart], Chart] | None = None,
    /,
    **kwargs: Unpack[ChartProps],
) -> Self:
    chart_type = to_pptx_chart_type(kwargs["chart_type"])

    def _register(slide: Slide) -> Chart:
        data: ChartData = {
            "type": "chart",
            **kwargs,
        }

        chart_obj = Chart(
            slide.to_pptx().shapes.add_chart(
                chart_type=chart_type,
                x=to_pptx_length(data["x"]),
                y=to_pptx_length(data["y"]),
                cx=to_pptx_length(data["cx"]),
                cy=to_pptx_length(data["cy"]),
                chart_data=data["chart_data"],
            )
        )
        if isinstance(data, Callable):
            return data(chart_obj)
        else:
            return chart_obj

    self._shape_registry.append(_register)

    return self
add_shape(shape_type: MSO_AUTO_SHAPE_TYPE, shape: Callable[[Shape], Shape] | None = None, /, **kwargs: Unpack[RangeProps]) -> Self
add_shape(
    shape_type: MSO_AUTO_SHAPE_TYPE,
    /,
    **kwargs: Unpack[RangeProps],
) -> Self
add_shape(
    shape_type: MSO_AUTO_SHAPE_TYPE,
    shape: Callable[[Shape], Shape],
    /,
    **kwargs: Unpack[RangeProps],
) -> Self

Add a shape to the slide.

Source code in src/tppt/pptx/slide.py
def add_shape(
    self,
    shape_type: "MSO_AUTO_SHAPE_TYPE",
    shape: Callable[[Shape], Shape] | None = None,
    /,
    **kwargs: Unpack[RangeProps],
) -> Self:
    """Add a shape to the slide."""

    def _register(slide: Slide) -> Shape:
        shape_obj = Shape(
            slide.to_pptx().shapes.add_shape(
                shape_type,
                to_pptx_length(kwargs["left"]),
                to_pptx_length(kwargs["top"]),
                to_pptx_length(kwargs["width"]),
                to_pptx_length(kwargs["height"]),
            )
        )
        if shape is not None:
            return shape(shape_obj)
        else:
            return shape_obj

    self._shape_registry.append(_register)
    return self
Functions
slide_layout
Classes
SlideLayout

Bases: PptxConvertible[SlideLayout]

Slide layout data class.

Source code in src/tppt/pptx/slide_layout.py
class SlideLayout(PptxConvertible[PptxSlideLayout]):
    """Slide layout data class."""

    @property
    def name(self) -> str | None:
        """String representing the internal name of this slide.

        Returns an empty string if no name is assigned.
        """
        if name := self._pptx.name:
            return name

        return None

    @property
    def background(self) -> Background:
        """Get the background."""
        return Background.from_pptx(self._pptx.background)

    @property
    def placeholders(self) -> list[LayoutPlaceholder]:
        """Get the placeholders."""
        return [
            LayoutPlaceholder.from_pptx(placeholder)
            for placeholder in self._pptx.placeholders.__iter__()
        ]

    @property
    def shapes(self) -> list[BaseShape]:
        """Get the shapes."""
        return [BaseShape.from_pptx(shape) for shape in self._pptx.shapes]
Attributes
name: str | None property

String representing the internal name of this slide.

Returns an empty string if no name is assigned.

background: Background property

Get the background.

placeholders: list[LayoutPlaceholder] property

Get the placeholders.

shapes: list[BaseShape] property

Get the shapes.

slide_master
Classes
SlideMaster

Bases: PptxConvertible[SlideMaster]

Slide master data class.

Source code in src/tppt/pptx/slide_master.py
class SlideMaster(PptxConvertible[PptxSlideMaster]):
    """Slide master data class."""

    @property
    def slide_layouts(self) -> list[SlideLayout]:
        return [SlideLayout.from_pptx(layout) for layout in self._pptx.slide_layouts]
Attributes
slide_layouts: list[SlideLayout] property
table
Classes Modules
cell
Attributes Classes
Cell

Bases: PptxConvertible[_Cell]

Cell data class.

Source code in src/tppt/pptx/table/cell.py
class Cell(PptxConvertible[PptxCell]):
    """Cell data class."""

    @property
    def fill(self) -> FillFormat:
        """Fill format."""
        return FillFormat(self._pptx.fill)

    @property
    def is_merge_origin(self) -> bool:
        """True if this cell is the top-left grid cell in a merged cell."""
        return self._pptx.is_merge_origin

    @property
    def is_spanned(self) -> bool:
        """True if this cell is spanned by a merge-origin cell."""
        return self._pptx.is_spanned

    @property
    def margin_left(self) -> Length:
        """Left margin of cells."""
        return to_tppt_length(self._pptx.margin_left)

    @margin_left.setter
    def margin_left(self, value: Length) -> None:
        self._pptx.margin_left = to_pptx_length(value)

    @property
    def margin_right(self) -> Length:
        """Right margin of cell."""
        return to_tppt_length(self._pptx.margin_right)

    @margin_right.setter
    def margin_right(self, value: Length) -> None:
        self._pptx.margin_right = to_pptx_length(value)

    @property
    def margin_top(self) -> Length:
        """Top margin of cell."""
        return to_tppt_length(self._pptx.margin_top)

    @margin_top.setter
    def margin_top(self, value: Length) -> None:
        self._pptx.margin_top = to_pptx_length(value)

    @property
    def margin_bottom(self) -> Length:
        """Bottom margin of cell."""
        return to_tppt_length(self._pptx.margin_bottom)

    @margin_bottom.setter
    def margin_bottom(self, value: Length) -> None:
        self._pptx.margin_bottom = to_pptx_length(value)

    def merge(self, other_cell: "Cell") -> None:
        """Create merged cell from this cell to `other_cell`."""
        self._pptx.merge(other_cell._pptx)

    @property
    def span_height(self) -> int:
        """int count of rows spanned by this cell."""
        return self._pptx.span_height

    @property
    def span_width(self) -> int:
        """int count of columns spanned by this cell."""
        return self._pptx.span_width

    def split(self) -> None:
        """Remove merge from this (merge-origin) cell."""
        self._pptx.split()

    @property
    def text(self) -> str:
        """Textual content of cell as a single string."""
        return self._pptx.text

    @text.setter
    def text(self, value: str) -> None:
        self._pptx.text = value

    @property
    def text_frame(self) -> TextFrame:
        """Text frame of cell."""
        return TextFrame(self._pptx.text_frame)

    @property
    def vertical_anchor(self) -> MSO_VERTICAL_ANCHOR | None:
        """Vertical alignment of this cell."""
        return self._pptx.vertical_anchor

    @vertical_anchor.setter
    def vertical_anchor(self, value: MSO_VERTICAL_ANCHOR | None) -> None:
        self._pptx.vertical_anchor = value
Attributes
fill: FillFormat property

Fill format.

is_merge_origin: bool property

True if this cell is the top-left grid cell in a merged cell.

is_spanned: bool property

True if this cell is spanned by a merge-origin cell.

margin_left: Length property writable

Left margin of cells.

margin_right: Length property writable

Right margin of cell.

margin_top: Length property writable

Top margin of cell.

margin_bottom: Length property writable

Bottom margin of cell.

span_height: int property

int count of rows spanned by this cell.

span_width: int property

int count of columns spanned by this cell.

text: str property writable

Textual content of cell as a single string.

text_frame: TextFrame property

Text frame of cell.

vertical_anchor: MSO_VERTICAL_ANCHOR | None property writable

Vertical alignment of this cell.

Functions
merge(other_cell: Cell) -> None

Create merged cell from this cell to other_cell.

Source code in src/tppt/pptx/table/cell.py
def merge(self, other_cell: "Cell") -> None:
    """Create merged cell from this cell to `other_cell`."""
    self._pptx.merge(other_cell._pptx)
split() -> None

Remove merge from this (merge-origin) cell.

Source code in src/tppt/pptx/table/cell.py
def split(self) -> None:
    """Remove merge from this (merge-origin) cell."""
    self._pptx.split()
Functions
table

Table wrapper implementation.

Attributes
logger = logging.getLogger(__name__) module-attribute
DataFrame: TypeAlias = list[list[str]] | list[Dataclass] | list[PydanticModel] | PandasDataFrame | PolarsDataFrame | PolarsLazyFrame module-attribute
Classes
TableCellStyle

Bases: TypedDict

Table cell style properties.

Source code in src/tppt/pptx/table/table.py
class TableCellStyle(TypedDict):
    """Table cell style properties."""

    text_align: NotRequired[Literal["left", "center", "right", "justify"]]
    vertical_align: NotRequired[Literal["top", "middle", "bottom"]]
    bold: NotRequired[bool]
    italic: NotRequired[bool]
    font_size: NotRequired[Points | LiteralPoints]
    font_name: NotRequired[str]
Attributes
text_align: NotRequired[Literal['left', 'center', 'right', 'justify']] instance-attribute
vertical_align: NotRequired[Literal['top', 'middle', 'bottom']] instance-attribute
bold: NotRequired[bool] instance-attribute
italic: NotRequired[bool] instance-attribute
font_size: NotRequired[Points | LiteralPoints] instance-attribute
font_name: NotRequired[str] instance-attribute
TableProps

Bases: RangeProps

Table properties.

Source code in src/tppt/pptx/table/table.py
class TableProps(RangeProps):
    """Table properties."""

    cell_styles: NotRequired[list[list[TableCellStyle]]]
    first_row_header: NotRequired[bool]
Attributes
cell_styles: NotRequired[list[list[TableCellStyle]]] instance-attribute
first_row_header: NotRequired[bool] instance-attribute
TableData

Bases: TableProps

Table data.

Source code in src/tppt/pptx/table/table.py
class TableData(TableProps):
    """Table data."""

    type: Literal["table"]

    data: list[list[str]]
Attributes
type: Literal['table'] instance-attribute
data: list[list[str]] instance-attribute
Table

Bases: PptxConvertible[Table]

Table data class.

Source code in src/tppt/pptx/table/table.py
class Table(PptxConvertible[PptxTable]):
    """Table data class."""

    def __init__(
        self,
        pptx_obj: PptxTable,
        props: TableData | None = None,
        /,
    ) -> None:
        self._pptx = pptx_obj

        if not props:
            return

        table = pptx_obj

        # Apply first row as header if specified
        if (first_row := props.get("first_row_header")) is not None:
            table.first_row = first_row

        # Apply table data if provided
        if data := props.get("data"):
            # Now apply the data to the table
            for i, row in enumerate(data):
                if i < len(table.rows):
                    for j, cell_text in enumerate(row):
                        if j < len(table.columns):
                            table.cell(i, j).text = str(cell_text)

        # Apply cell styles if provided
        if (cell_styles := props.get("cell_styles")) is not None:
            for i, row_styles in enumerate(cell_styles):
                if i < len(table.rows):
                    for j, cell_style in enumerate(row_styles):
                        if j < len(table.columns):
                            cell = table.cell(i, j)

                            if (text_align := cell_style.get("text_align")) is not None:
                                align_map = {
                                    "left": PP_ALIGN.LEFT,
                                    "center": PP_ALIGN.CENTER,
                                    "right": PP_ALIGN.RIGHT,
                                    "justify": PP_ALIGN.JUSTIFY,
                                }
                                paragraph = cell.text_frame.paragraphs[0]
                                paragraph.alignment = align_map[text_align]

                            if (
                                vertical_align := cell_style.get("vertical_align")
                            ) is not None:
                                valign_map = {
                                    "top": MSO_VERTICAL_ANCHOR.TOP,
                                    "middle": MSO_VERTICAL_ANCHOR.MIDDLE,
                                    "bottom": MSO_VERTICAL_ANCHOR.BOTTOM,
                                }
                                cell.text_frame.vertical_anchor = valign_map[
                                    vertical_align
                                ]

                            # Apply text formatting
                            if any(
                                key in cell_style
                                for key in ["bold", "italic", "font_size", "font_name"]
                            ):
                                paragraph = cell.text_frame.paragraphs[0]
                                run = (
                                    paragraph.runs[0]
                                    if paragraph.runs
                                    else paragraph.add_run()
                                )

                                if "bold" in cell_style:
                                    run.font.bold = cell_style["bold"]

                                if "italic" in cell_style:
                                    run.font.italic = cell_style["italic"]

                                if "font_size" in cell_style:
                                    run.font.size = to_pptx_length(
                                        cell_style["font_size"]
                                    )

                                if "font_name" in cell_style:
                                    run.font.name = cell_style["font_name"]

    def cell(self, row_idx: int, col_idx: int) -> Cell:
        """Get cell at row_idx and col_idx."""
        return Cell(self._pptx.cell(row_idx, col_idx))
Functions
__init__(pptx_obj: PptxTable, props: TableData | None = None) -> None
Source code in src/tppt/pptx/table/table.py
def __init__(
    self,
    pptx_obj: PptxTable,
    props: TableData | None = None,
    /,
) -> None:
    self._pptx = pptx_obj

    if not props:
        return

    table = pptx_obj

    # Apply first row as header if specified
    if (first_row := props.get("first_row_header")) is not None:
        table.first_row = first_row

    # Apply table data if provided
    if data := props.get("data"):
        # Now apply the data to the table
        for i, row in enumerate(data):
            if i < len(table.rows):
                for j, cell_text in enumerate(row):
                    if j < len(table.columns):
                        table.cell(i, j).text = str(cell_text)

    # Apply cell styles if provided
    if (cell_styles := props.get("cell_styles")) is not None:
        for i, row_styles in enumerate(cell_styles):
            if i < len(table.rows):
                for j, cell_style in enumerate(row_styles):
                    if j < len(table.columns):
                        cell = table.cell(i, j)

                        if (text_align := cell_style.get("text_align")) is not None:
                            align_map = {
                                "left": PP_ALIGN.LEFT,
                                "center": PP_ALIGN.CENTER,
                                "right": PP_ALIGN.RIGHT,
                                "justify": PP_ALIGN.JUSTIFY,
                            }
                            paragraph = cell.text_frame.paragraphs[0]
                            paragraph.alignment = align_map[text_align]

                        if (
                            vertical_align := cell_style.get("vertical_align")
                        ) is not None:
                            valign_map = {
                                "top": MSO_VERTICAL_ANCHOR.TOP,
                                "middle": MSO_VERTICAL_ANCHOR.MIDDLE,
                                "bottom": MSO_VERTICAL_ANCHOR.BOTTOM,
                            }
                            cell.text_frame.vertical_anchor = valign_map[
                                vertical_align
                            ]

                        # Apply text formatting
                        if any(
                            key in cell_style
                            for key in ["bold", "italic", "font_size", "font_name"]
                        ):
                            paragraph = cell.text_frame.paragraphs[0]
                            run = (
                                paragraph.runs[0]
                                if paragraph.runs
                                else paragraph.add_run()
                            )

                            if "bold" in cell_style:
                                run.font.bold = cell_style["bold"]

                            if "italic" in cell_style:
                                run.font.italic = cell_style["italic"]

                            if "font_size" in cell_style:
                                run.font.size = to_pptx_length(
                                    cell_style["font_size"]
                                )

                            if "font_name" in cell_style:
                                run.font.name = cell_style["font_name"]
cell(row_idx: int, col_idx: int) -> Cell

Get cell at row_idx and col_idx.

Source code in src/tppt/pptx/table/table.py
def cell(self, row_idx: int, col_idx: int) -> Cell:
    """Get cell at row_idx and col_idx."""
    return Cell(self._pptx.cell(row_idx, col_idx))
Functions
dataframe2list(data: DataFrame) -> list[list[str]]

Convert different DataFrame types to list of lists.

Source code in src/tppt/pptx/table/table.py
def dataframe2list(data: DataFrame) -> list[list[str]]:
    """Convert different DataFrame types to list of lists."""
    if USE_POLARS:
        if isinstance(data, PolarsLazyFrame):
            # For LazyFrame, collect it first
            polars_df = cast(PolarsLazyFrame, data).collect()
            columns = list(polars_df.columns)
            rows = polars_df.to_numpy().tolist()
            return [columns] + rows
        elif isinstance(data, PolarsDataFrame):
            polars_df = cast(PolarsDataFrame, data)
            columns = list(polars_df.columns)
            rows = polars_df.to_numpy().tolist()
            return [columns] + rows

    if USE_PANDAS and isinstance(data, PandasDataFrame):  # type: ignore
        # Convert pandas DataFrame to list of lists
        pandas_df = cast(PandasDataFrame, data)
        columns = pandas_df.columns.tolist()
        rows = pandas_df.values.tolist()
        return [columns] + rows

    if isinstance(data, list):
        if len(data) != 0:
            # Convert list of dataclass instances to list of lists
            first_instance = data[0]
            if is_dataclass(first_instance):
                columns = [field.name for field in fields(first_instance)]
                rows = []
                for instance in data:
                    instance = cast(Any, instance)
                    row = [
                        str(getattr(instance, field.name)) for field in fields(instance)
                    ]
                    rows.append(row)
                return [columns] + rows
            # Convert list of Pydantic model instances to list of lists
            elif USE_PYDANTIC and isinstance(first_instance, PydanticModel):
                columns = list(first_instance.__class__.model_fields.keys())  # type: ignore
                rows = []
                for instance in data:
                    instance = cast(Any, instance)
                    row = [str(getattr(instance, field)) for field in columns]
                    rows.append(row)
                return [columns] + rows
        else:
            logger.warning("Empty data of table")
            return []

    # Assume it's a list of lists
    return cast(list[list[str]], data)
text
Modules
font
Attributes Classes
Font

Bases: PptxConvertible[Font]

Source code in src/tppt/pptx/text/font.py
class Font(PptxConvertible[PptxFont]):
    @property
    def name(self) -> str | None:
        return self._pptx.name

    @name.setter
    def name(self, name: str) -> None:
        self._pptx.name = name

    def set_name(self, name: str) -> "Font":
        self.name = name
        return self

    @property
    def size(self) -> Length | None:
        return to_tppt_length(self._pptx.size)

    @size.setter
    def size(self, size: Length) -> None:
        self._pptx.size = to_pptx_length(size)

    def set_size(self, size: Length) -> "Font":
        self.size = size
        return self

    @property
    def bold(self) -> bool | None:
        return self._pptx.bold

    @bold.setter
    def bold(self, bold: bool) -> None:
        self._pptx.bold = bold

    def set_bold(self, bold: bool) -> "Font":
        self.bold = bold
        return self

    @property
    def italic(self) -> bool | None:
        return self._pptx.italic

    @italic.setter
    def italic(self, italic: bool) -> None:
        self._pptx.italic = italic

    def set_italic(self, italic: bool) -> "Font":
        self.italic = italic
        return self

    @property
    def underline(self) -> bool | MSO_TEXT_UNDERLINE_TYPE | None:
        return self._pptx.underline

    @underline.setter
    def underline(self, underline: bool | MSO_TEXT_UNDERLINE_TYPE) -> None:
        self._pptx.underline = underline

    def set_underline(self, underline: bool | MSO_TEXT_UNDERLINE_TYPE) -> "Font":
        self.underline = underline
        return self

    @property
    def color(self) -> ColorFormat:
        return ColorFormat(self._pptx.color)

    @color.setter
    def color(self, color: ColorFormat) -> None:
        self._pptx.color = color.to_pptx()

    def set_color(self, color: ColorFormat) -> "Font":
        self.color = color
        return self
Attributes
name: str | None property writable
size: Length | None property writable
bold: bool | None property writable
italic: bool | None property writable
underline: bool | MSO_TEXT_UNDERLINE_TYPE | None property writable
color: ColorFormat property writable
Functions
set_name(name: str) -> Font
Source code in src/tppt/pptx/text/font.py
def set_name(self, name: str) -> "Font":
    self.name = name
    return self
set_size(size: Length) -> Font
Source code in src/tppt/pptx/text/font.py
def set_size(self, size: Length) -> "Font":
    self.size = size
    return self
set_bold(bold: bool) -> Font
Source code in src/tppt/pptx/text/font.py
def set_bold(self, bold: bool) -> "Font":
    self.bold = bold
    return self
set_italic(italic: bool) -> Font
Source code in src/tppt/pptx/text/font.py
def set_italic(self, italic: bool) -> "Font":
    self.italic = italic
    return self
set_underline(underline: bool | MSO_TEXT_UNDERLINE_TYPE) -> Font
Source code in src/tppt/pptx/text/font.py
def set_underline(self, underline: bool | MSO_TEXT_UNDERLINE_TYPE) -> "Font":
    self.underline = underline
    return self
set_color(color: ColorFormat) -> Font
Source code in src/tppt/pptx/text/font.py
def set_color(self, color: ColorFormat) -> "Font":
    self.color = color
    return self
Functions
hyperlink
Classes
Hyperlink

Bases: PptxConvertible[_Hyperlink]

Source code in src/tppt/pptx/text/hyperlink.py
class Hyperlink(PptxConvertible[PptxHyperlink]):
    @property
    def address(self) -> str | None:
        return self._pptx.address

    @address.setter
    def address(self, address: str | None) -> None:
        self._pptx.address = address

    def set_address(self, address: str | None) -> Self:
        self._pptx.address = address
        return self
Attributes
address: str | None property writable
Functions
set_address(address: str | None) -> Self
Source code in src/tppt/pptx/text/hyperlink.py
def set_address(self, address: str | None) -> Self:
    self._pptx.address = address
    return self
paragraph
Attributes Classes
Paragraph

Bases: PptxConvertible[_Paragraph]

Source code in src/tppt/pptx/text/paragraph.py
class Paragraph(PptxConvertible[PptxParagraph]):
    def add_line_break(self) -> None:
        self._pptx.add_line_break()

    def add_run(self) -> Run:
        return Run(self._pptx.add_run())

    @property
    def alignment(self) -> PP_PARAGRAPH_ALIGNMENT | None:
        return self._pptx.alignment

    @alignment.setter
    def alignment(self, value: PP_PARAGRAPH_ALIGNMENT | None) -> None:
        self._pptx.alignment = value

    def set_alignment(self, value: PP_PARAGRAPH_ALIGNMENT | None) -> Self:
        self.alignment = value
        return self

    def clear(self) -> None:
        self._pptx.clear()

    @property
    def font(self) -> Font:
        return Font(self._pptx.font)

    @property
    def level(self) -> int:
        return self._pptx.level

    @level.setter
    def level(self, value: int) -> None:
        self._pptx.level = value

    def set_level(self, value: int) -> Self:
        self.level = value
        return self

    @property
    def line_spacing(self) -> int | float | Length | None:
        match self._pptx.line_spacing:
            case PptxLength():
                return to_length(self._pptx.line_spacing)
            case _:
                return self._pptx.line_spacing

    @line_spacing.setter
    def line_spacing(self, value: int | float | Length | PptxLength | None) -> None:
        match value:
            case int() | float() | PptxLength() | None:
                self._pptx.line_spacing = value
            case _:
                self._pptx.line_spacing = to_pptx_length(value)

    def set_line_spacing(self, value: int | float | Length | PptxLength | None) -> Self:
        self.line_spacing = value
        return self

    @property
    def runs(self) -> tuple[Run, ...]:
        return tuple(Run(run) for run in self._pptx.runs)

    @property
    def space_after(self) -> Length | None:
        match self._pptx.space_after:
            case PptxLength():
                return to_length(self._pptx.space_after)
            case _:
                return self._pptx.space_after

    @space_after.setter
    def space_after(self, value: Length | PptxLength | None) -> None:
        match value:
            case PptxLength() | None:
                self._pptx.space_after = value
            case _:
                self._pptx.space_after = to_pptx_length(value)

    def set_space_after(self, value: Length | PptxLength | None) -> Self:
        self.space_after = value
        return self

    @property
    def space_before(self) -> Length | None:
        match self._pptx.space_before:
            case PptxLength():
                return to_length(self._pptx.space_before)
            case _:
                return self._pptx.space_before

    @space_before.setter
    def space_before(self, value: Length | PptxLength | None) -> None:
        match value:
            case PptxLength() | None:
                self._pptx.space_before = value
            case _:
                self._pptx.space_before = to_pptx_length(value)

    def set_space_before(self, value: Length | PptxLength | None) -> Self:
        self.space_before = value
        return self

    @property
    def text(self) -> str:
        return self._pptx.text

    @text.setter
    def text(self, value: str) -> None:
        self._pptx.text = value

    def set_text(self, value: str) -> Self:
        self.text = value
        return self
Attributes
alignment: PP_PARAGRAPH_ALIGNMENT | None property writable
font: Font property
level: int property writable
line_spacing: int | float | Length | None property writable
runs: tuple[Run, ...] property
space_after: Length | None property writable
space_before: Length | None property writable
text: str property writable
Functions
add_line_break() -> None
Source code in src/tppt/pptx/text/paragraph.py
def add_line_break(self) -> None:
    self._pptx.add_line_break()
add_run() -> Run
Source code in src/tppt/pptx/text/paragraph.py
def add_run(self) -> Run:
    return Run(self._pptx.add_run())
set_alignment(value: PP_PARAGRAPH_ALIGNMENT | None) -> Self
Source code in src/tppt/pptx/text/paragraph.py
def set_alignment(self, value: PP_PARAGRAPH_ALIGNMENT | None) -> Self:
    self.alignment = value
    return self
clear() -> None
Source code in src/tppt/pptx/text/paragraph.py
def clear(self) -> None:
    self._pptx.clear()
set_level(value: int) -> Self
Source code in src/tppt/pptx/text/paragraph.py
def set_level(self, value: int) -> Self:
    self.level = value
    return self
set_line_spacing(value: int | float | Length | PptxLength | None) -> Self
Source code in src/tppt/pptx/text/paragraph.py
def set_line_spacing(self, value: int | float | Length | PptxLength | None) -> Self:
    self.line_spacing = value
    return self
set_space_after(value: Length | PptxLength | None) -> Self
Source code in src/tppt/pptx/text/paragraph.py
def set_space_after(self, value: Length | PptxLength | None) -> Self:
    self.space_after = value
    return self
set_space_before(value: Length | PptxLength | None) -> Self
Source code in src/tppt/pptx/text/paragraph.py
def set_space_before(self, value: Length | PptxLength | None) -> Self:
    self.space_before = value
    return self
set_text(value: str) -> Self
Source code in src/tppt/pptx/text/paragraph.py
def set_text(self, value: str) -> Self:
    self.text = value
    return self
Functions
run
Classes
Run

Bases: PptxConvertible[_Run]

Source code in src/tppt/pptx/text/run.py
class Run(PptxConvertible[PptxRun]):
    @property
    def font(self) -> Font:
        return Font(self._pptx.font)

    @property
    def hyperlink(self) -> Hyperlink:
        return Hyperlink(self._pptx.hyperlink)

    @property
    def text(self) -> str:
        return self._pptx.text

    @text.setter
    def text(self, text: str) -> None:
        self._pptx.text = text

    def set_text(self, text: str) -> Self:
        self.text = text
        return self
Attributes
font: Font property
hyperlink: Hyperlink property
text: str property writable
Functions
set_text(text: str) -> Self
Source code in src/tppt/pptx/text/run.py
def set_text(self, text: str) -> Self:
    self.text = text
    return self
text_frame
Attributes Classes
TextFrame

Bases: SubShape[TextFrame]

Source code in src/tppt/pptx/text/text_frame.py
class TextFrame(SubShape[PptxTextFrame]):
    def __init__(self, pptx_obj: PptxTextFrame) -> None:
        super().__init__(pptx_obj)

    def add_paragraph(self) -> Paragraph:
        return Paragraph(self._pptx.add_paragraph())

    @property
    def auto_size(self) -> MSO_AUTO_SIZE | None:
        return self._pptx.auto_size

    @auto_size.setter
    def auto_size(self, value: MSO_AUTO_SIZE | None) -> None:
        self._pptx.auto_size = value

    def set_auto_size(self, value: MSO_AUTO_SIZE | None) -> Self:
        self.auto_size = value
        return self

    def clear(self) -> None:
        self._pptx.clear()

    def fit_text(
        self,
        font_family: str = "Calibri",
        max_size: int = 18,
        bold: bool = False,
        italic: bool = False,
        font_file: str | None = None,
    ) -> None:
        self._pptx.fit_text(font_family, max_size, bold, italic, font_file)

    @property
    def margin_bottom(self) -> EnglishMetricUnits:
        return to_english_metric_units(self._pptx.margin_bottom)

    @margin_bottom.setter
    def margin_bottom(self, value: Length | LiteralLength | PptxLength) -> None:
        self._pptx.margin_bottom = to_pptx_length(value)

    def set_margin_bottom(self, value: Length | LiteralLength | PptxLength) -> Self:
        self.margin_bottom = value
        return self

    @property
    def margin_left(self) -> EnglishMetricUnits:
        return to_english_metric_units(self._pptx.margin_left)

    @margin_left.setter
    def margin_left(self, value: Length | LiteralLength | PptxLength) -> None:
        self._pptx.margin_left = to_pptx_length(value)

    def set_margin_left(self, value: Length | LiteralLength | PptxLength) -> Self:
        self.margin_left = value
        return self

    @property
    def margin_right(self) -> EnglishMetricUnits:
        return to_english_metric_units(self._pptx.margin_right)

    @margin_right.setter
    def margin_right(self, value: Length | LiteralLength | PptxLength) -> None:
        self._pptx.margin_right = to_pptx_length(value)

    def set_margin_right(self, value: Length | LiteralLength | PptxLength) -> Self:
        self.margin_right = value
        return self

    @property
    def margin_top(self) -> EnglishMetricUnits:
        return to_english_metric_units(self._pptx.margin_top)

    @margin_top.setter
    def margin_top(self, value: Length | LiteralLength | PptxLength) -> None:
        self._pptx.margin_top = to_pptx_length(value)

    def set_margin_top(self, value: Length | LiteralLength | PptxLength) -> Self:
        self.margin_top = value
        return self

    @property
    def paragraphs(self) -> tuple[Paragraph, ...]:
        return tuple(Paragraph(paragraph) for paragraph in self._pptx.paragraphs)

    @property
    def text(self) -> str:
        return self._pptx.text

    @text.setter
    def text(self, text: str) -> None:
        self._pptx.text = text

    def set_text(self, text: str) -> Self:
        self.text = text
        return self

    @property
    def vertical_anchor(self) -> MSO_VERTICAL_ANCHOR | None:
        return self._pptx.vertical_anchor

    @vertical_anchor.setter
    def vertical_anchor(self, value: MSO_VERTICAL_ANCHOR | None) -> None:
        self._pptx.vertical_anchor = value

    def set_vertical_anchor(self, value: MSO_VERTICAL_ANCHOR | None) -> Self:
        self.vertical_anchor = value
        return self

    @property
    def word_wrap(self) -> bool | None:
        return self._pptx.word_wrap

    @word_wrap.setter
    def word_wrap(self, value: bool | None) -> None:
        self._pptx.word_wrap = value

    def set_word_wrap(self, value: bool | None) -> Self:
        self.word_wrap = value
        return self
Attributes
auto_size: MSO_AUTO_SIZE | None property writable
margin_bottom: EnglishMetricUnits property writable
margin_left: EnglishMetricUnits property writable
margin_right: EnglishMetricUnits property writable
margin_top: EnglishMetricUnits property writable
paragraphs: tuple[Paragraph, ...] property
text: str property writable
vertical_anchor: MSO_VERTICAL_ANCHOR | None property writable
word_wrap: bool | None property writable
Functions
__init__(pptx_obj: PptxTextFrame) -> None
Source code in src/tppt/pptx/text/text_frame.py
def __init__(self, pptx_obj: PptxTextFrame) -> None:
    super().__init__(pptx_obj)
add_paragraph() -> Paragraph
Source code in src/tppt/pptx/text/text_frame.py
def add_paragraph(self) -> Paragraph:
    return Paragraph(self._pptx.add_paragraph())
set_auto_size(value: MSO_AUTO_SIZE | None) -> Self
Source code in src/tppt/pptx/text/text_frame.py
def set_auto_size(self, value: MSO_AUTO_SIZE | None) -> Self:
    self.auto_size = value
    return self
clear() -> None
Source code in src/tppt/pptx/text/text_frame.py
def clear(self) -> None:
    self._pptx.clear()
fit_text(font_family: str = 'Calibri', max_size: int = 18, bold: bool = False, italic: bool = False, font_file: str | None = None) -> None
Source code in src/tppt/pptx/text/text_frame.py
def fit_text(
    self,
    font_family: str = "Calibri",
    max_size: int = 18,
    bold: bool = False,
    italic: bool = False,
    font_file: str | None = None,
) -> None:
    self._pptx.fit_text(font_family, max_size, bold, italic, font_file)
set_margin_bottom(value: Length | LiteralLength | PptxLength) -> Self
Source code in src/tppt/pptx/text/text_frame.py
def set_margin_bottom(self, value: Length | LiteralLength | PptxLength) -> Self:
    self.margin_bottom = value
    return self
set_margin_left(value: Length | LiteralLength | PptxLength) -> Self
Source code in src/tppt/pptx/text/text_frame.py
def set_margin_left(self, value: Length | LiteralLength | PptxLength) -> Self:
    self.margin_left = value
    return self
set_margin_right(value: Length | LiteralLength | PptxLength) -> Self
Source code in src/tppt/pptx/text/text_frame.py
def set_margin_right(self, value: Length | LiteralLength | PptxLength) -> Self:
    self.margin_right = value
    return self
set_margin_top(value: Length | LiteralLength | PptxLength) -> Self
Source code in src/tppt/pptx/text/text_frame.py
def set_margin_top(self, value: Length | LiteralLength | PptxLength) -> Self:
    self.margin_top = value
    return self
set_text(text: str) -> Self
Source code in src/tppt/pptx/text/text_frame.py
def set_text(self, text: str) -> Self:
    self.text = text
    return self
set_vertical_anchor(value: MSO_VERTICAL_ANCHOR | None) -> Self
Source code in src/tppt/pptx/text/text_frame.py
def set_vertical_anchor(self, value: MSO_VERTICAL_ANCHOR | None) -> Self:
    self.vertical_anchor = value
    return self
set_word_wrap(value: bool | None) -> Self
Source code in src/tppt/pptx/text/text_frame.py
def set_word_wrap(self, value: bool | None) -> Self:
    self.word_wrap = value
    return self
Functions
tree
Functions
color_format_to_dict(color_format: Any) -> dict[str, Any]

Convert color format to dictionary

Source code in src/tppt/pptx/tree.py
def color_format_to_dict(color_format: Any) -> dict[str, Any]:
    """Convert color format to dictionary"""
    data = {}

    try:
        if rgb := getattr(color_format, "rgb", None):
            data["rgb"] = str(rgb)

        if theme_color := getattr(color_format, "theme_color", None):
            data["theme_color"] = str(theme_color)

        if brightness := getattr(color_format, "brightness", None):
            data["brightness"] = brightness
    except Exception:
        pass

    return data
text_frame_to_dict(text_frame: Any) -> dict[str, Any]

Convert text frame to dictionary

Source code in src/tppt/pptx/tree.py
def text_frame_to_dict(text_frame: Any) -> dict[str, Any]:
    """Convert text frame to dictionary"""
    if not hasattr(text_frame, "paragraphs"):
        return {"text": str(text_frame) if text_frame else ""}

    result = {"text": text_frame.text, "paragraphs": []}

    for p in text_frame.paragraphs:
        paragraph = {"text": p.text, "level": p.level, "runs": []}

        for run in p.runs:
            run_data = {"text": run.text}

            if font := getattr(run, "font", None):
                font_data = {}
                if name := getattr(font, "name", None):
                    font_data["name"] = name
                if size := getattr(font, "size", None):
                    font_data["size"] = size.pt if hasattr(size, "pt") else size
                if bold := getattr(font, "bold", None):
                    font_data["bold"] = bold
                if italic := getattr(font, "italic", None):
                    font_data["italic"] = italic
                if underline := getattr(font, "underline", None):
                    font_data["underline"] = underline

                if color := getattr(font, "color", None):
                    font_data["color"] = color_format_to_dict(color)

                run_data["font"] = font_data

            paragraph["runs"].append(run_data)

        result["paragraphs"].append(paragraph)

    return result
shape_to_dict(shape: BaseShape) -> dict[str, Any]

Convert Shape object to dictionary

Source code in src/tppt/pptx/tree.py
def shape_to_dict(shape: BaseShape) -> dict[str, Any]:
    """Convert Shape object to dictionary"""
    shape_data = {
        "name": shape.name,
        "shape_id": shape.shape_id,
        "shape_type": str(shape.shape_type),
        "has_text_frame": shape.has_text_frame,
        "has_table": shape.has_table,
        "has_chart": shape.has_chart,
        "width": shape.width.pt if hasattr(shape.width, "pt") else shape.width,
        "height": shape.height.pt if hasattr(shape.height, "pt") else shape.height,
        "rotation": shape.rotation,
        "left": shape.left.pt if hasattr(shape.left, "pt") else shape.left,
        "top": shape.top.pt if hasattr(shape.top, "pt") else shape.top,
    }

    # In case of a placeholder
    if shape.shape_type == MSO_SHAPE_TYPE.PLACEHOLDER:
        try:
            shape_data["placeholder_type"] = (
                shape.placeholder_format.type
                if hasattr(shape.placeholder_format, "type")
                else None
            )
            shape_data["placeholder_idx"] = (
                shape.placeholder_format.idx
                if hasattr(shape.placeholder_format, "idx")
                else None
            )
        except Exception:
            pass

    # If there is a text frame
    if shape.has_text_frame:
        shape = cast(Shape, shape)
        shape_data["text_frame"] = text_frame_to_dict(shape.text_frame)

    # If there is a table
    if shape.has_table:
        shape = cast(GraphicFrame, shape)
        table_data = {
            "rows": len(shape.table.rows),
            "columns": len(shape.table.columns),
            "cells": [],
        }

        for row_idx in range(len(shape.table.rows)):
            for col_idx in range(len(shape.table.columns)):
                cell = shape.table.cell(row_idx, col_idx)
                cell_data = {
                    "row": row_idx,
                    "column": col_idx,
                    "text_frame": text_frame_to_dict(cell.text_frame),
                }
                table_data["cells"].append(cell_data)

        shape_data["table"] = table_data

    # In case of a group shape
    if shape.shape_type == MSO_SHAPE_TYPE.GROUP:
        shape = cast(GroupShape, shape)
        shape_data["shapes"] = [shape_to_dict(subshape) for subshape in shape.shapes]

    return shape_data
placeholder_to_dict(placeholder: Any) -> dict[str, Any]

Convert placeholder to dictionary

Source code in src/tppt/pptx/tree.py
def placeholder_to_dict(placeholder: Any) -> dict[str, Any]:
    """Convert placeholder to dictionary"""
    placeholder_data = shape_to_dict(placeholder)

    # Add placeholder-specific information
    try:
        placeholder_data["placeholder_type"] = getattr(
            placeholder.placeholder_format, "type", None
        )
        placeholder_data["placeholder_idx"] = getattr(
            placeholder.placeholder_format, "idx", None
        )
    except Exception:
        pass

    return placeholder_data
slide_layout_to_dict(slide_layout: Any) -> dict[str, Any]

Convert slide layout to dictionary

Source code in src/tppt/pptx/tree.py
def slide_layout_to_dict(slide_layout: Any) -> dict[str, Any]:
    """Convert slide layout to dictionary"""
    layout_data = {
        "name": slide_layout.name,
        "shapes": [shape_to_dict(shape) for shape in slide_layout.shapes],
        "placeholders": [
            placeholder_to_dict(placeholder)
            for placeholder in slide_layout.placeholders
        ],
    }

    return layout_data
slide_master_to_dict(slide_master: Any) -> dict[str, Any]

Convert slide master to dictionary

Source code in src/tppt/pptx/tree.py
def slide_master_to_dict(slide_master: Any) -> dict[str, Any]:
    """Convert slide master to dictionary"""
    master_data = {
        "shapes": [shape_to_dict(shape) for shape in slide_master.shapes],
        "placeholders": [
            placeholder_to_dict(placeholder)
            for placeholder in slide_master.placeholders
        ],
        "slide_layouts": [],
    }

    # Add slide layout information
    for layout in slide_master.slide_layouts:
        layout_dict = slide_layout_to_dict(layout)
        master_data["slide_layouts"].append(layout_dict)

    return master_data
slide_to_dict(slide: Slide) -> dict[str, Any]

Convert slide to dictionary

Source code in src/tppt/pptx/tree.py
def slide_to_dict(slide: Slide) -> dict[str, Any]:
    """Convert slide to dictionary"""
    slide_data = {
        "slide_id": slide.slide_id,
        "slide_layout_name": slide.slide_layout.name
        if hasattr(slide.slide_layout, "name")
        else None,
        "shapes": [shape_to_dict(shape) for shape in slide.shapes],
        "placeholders": [],
    }

    # Add placeholder information
    if placeholders := getattr(slide, "placeholders", None):
        slide_data["placeholders"] = [
            placeholder_to_dict(placeholder) for placeholder in placeholders
        ]

    # Add notes information
    if notes_slide := getattr(slide, "notes_slide", None):
        notes_placeholders = []
        if placeholders := getattr(notes_slide, "placeholders", None):
            notes_placeholders = [
                placeholder_to_dict(placeholder) for placeholder in placeholders
            ]

        slide_data["notes_slide"] = {
            "shapes": [shape_to_dict(shape) for shape in slide.notes_slide.shapes],
            "placeholders": notes_placeholders,
        }

    return slide_data
ppt2tree(ppt: PptxPresentation) -> dict[str, Any]

Convert presentation information to dictionary

Source code in src/tppt/pptx/tree.py
def ppt2tree(ppt: PptxPresentation) -> dict[str, Any]:
    """Convert presentation information to dictionary"""

    # Safely get the slide size
    slide_width = None
    slide_height = None

    if slide_width := ppt.slide_width:
        slide_width = slide_width.pt
    else:
        slide_width = None

    if slide_height := ppt.slide_height:
        slide_height = slide_height.pt
    else:
        slide_height = None

    prs_data = {
        "slides_count": len(ppt.slides),
        "slide_masters_count": len(ppt.slide_masters),
        "slide_layouts_count": len(ppt.slide_layouts),
        "slide_width": slide_width,
        "slide_height": slide_height,
        "slides": [slide_to_dict(slide) for slide in ppt.slides],
        "slide_masters": [slide_master_to_dict(master) for master in ppt.slide_masters],
    }

    # Add note master information
    if notes_master := getattr(ppt, "notes_master", None):
        notes_placeholders = []
        if placeholders := getattr(notes_master, "placeholders", None):
            notes_placeholders = [
                placeholder_to_dict(placeholder) for placeholder in placeholders
            ]

        prs_data["notes_master"] = {
            "shapes": [shape_to_dict(shape) for shape in ppt.notes_master.shapes],
            "placeholders": notes_placeholders,
        }

    return prs_data

template

Modules
default
Attributes Classes
DefaultTitleSlideLayout

Bases: SlideLayout

Title slide layout.

Source code in src/tppt/template/default.py
class DefaultTitleSlideLayout(SlideLayout):
    """Title slide layout."""

    title: Placeholder[str]
    subtitle: Placeholder[str | None] = None
    date: Placeholder[datetime.date | None] = None
    footer: Placeholder[str | None] = None
    slide_number: Placeholder[Literal["‹#›"] | int | None] = None
Attributes
title: Placeholder[str] instance-attribute
subtitle: Placeholder[str | None] = None class-attribute instance-attribute
date: Placeholder[datetime.date | None] = None class-attribute instance-attribute
footer: Placeholder[str | None] = None class-attribute instance-attribute
slide_number: Placeholder[Literal['‹#›'] | int | None] = None class-attribute instance-attribute
DefaultTitleAndContentSlideLayout

Bases: SlideLayout

Title and content slide layout.

Source code in src/tppt/template/default.py
class DefaultTitleAndContentSlideLayout(SlideLayout):
    """Title and content slide layout."""

    title: Placeholder[str]
    content: Placeholder[str]
    date: Placeholder[datetime.date | None] = None
    footer: Placeholder[str | None] = None
    slide_number: Placeholder[Literal["‹#›"] | int | None] = None
Attributes
title: Placeholder[str] instance-attribute
content: Placeholder[str] instance-attribute
date: Placeholder[datetime.date | None] = None class-attribute instance-attribute
footer: Placeholder[str | None] = None class-attribute instance-attribute
slide_number: Placeholder[Literal['‹#›'] | int | None] = None class-attribute instance-attribute
DefaultSectionHeaderSlideLayout

Bases: SlideLayout

Section header slide layout.

Source code in src/tppt/template/default.py
class DefaultSectionHeaderSlideLayout(SlideLayout):
    """Section header slide layout."""

    title: Placeholder[str]
    text: Placeholder[str]
    date: Placeholder[datetime.date | None] = None
    footer: Placeholder[str | None] = None
    slide_number: Placeholder[Literal["‹#›"] | int | None] = None
Attributes
title: Placeholder[str] instance-attribute
text: Placeholder[str] instance-attribute
date: Placeholder[datetime.date | None] = None class-attribute instance-attribute
footer: Placeholder[str | None] = None class-attribute instance-attribute
slide_number: Placeholder[Literal['‹#›'] | int | None] = None class-attribute instance-attribute
DefaultTwoContentSlideLayout

Bases: SlideLayout

Two content slide layout.

Source code in src/tppt/template/default.py
class DefaultTwoContentSlideLayout(SlideLayout):
    """Two content slide layout."""

    title: Placeholder[str]
    left_content: Placeholder[str]
    right_content: Placeholder[str]
    date: Placeholder[datetime.date | None] = None
    footer: Placeholder[str | None] = None
    slide_number: Placeholder[Literal["‹#›"] | int | None] = None
Attributes
title: Placeholder[str] instance-attribute
left_content: Placeholder[str] instance-attribute
right_content: Placeholder[str] instance-attribute
date: Placeholder[datetime.date | None] = None class-attribute instance-attribute
footer: Placeholder[str | None] = None class-attribute instance-attribute
slide_number: Placeholder[Literal['‹#›'] | int | None] = None class-attribute instance-attribute
DefaultComparisonSlideLayout

Bases: SlideLayout

Comparison slide layout.

Source code in src/tppt/template/default.py
class DefaultComparisonSlideLayout(SlideLayout):
    """Comparison slide layout."""

    title: Placeholder[str]
    left_title: Placeholder[str]
    left_content: Placeholder[str]
    right_title: Placeholder[str]
    right_content: Placeholder[str]
    date: Placeholder[datetime.date | None] = None
    footer: Placeholder[str | None] = None
    slide_number: Placeholder[Literal["‹#›"] | int | None] = None
Attributes
title: Placeholder[str] instance-attribute
left_title: Placeholder[str] instance-attribute
left_content: Placeholder[str] instance-attribute
right_title: Placeholder[str] instance-attribute
right_content: Placeholder[str] instance-attribute
date: Placeholder[datetime.date | None] = None class-attribute instance-attribute
footer: Placeholder[str | None] = None class-attribute instance-attribute
slide_number: Placeholder[Literal['‹#›'] | int | None] = None class-attribute instance-attribute
DefaultTitleOnlySlideLayout

Bases: SlideLayout

Title only slide layout.

Source code in src/tppt/template/default.py
class DefaultTitleOnlySlideLayout(SlideLayout):
    """Title only slide layout."""

    title: Placeholder[str]
    date: Placeholder[datetime.date | None] = None
    footer: Placeholder[str | None] = None
    slide_number: Placeholder[Literal["‹#›"] | int | None] = None
Attributes
title: Placeholder[str] instance-attribute
date: Placeholder[datetime.date | None] = None class-attribute instance-attribute
footer: Placeholder[str | None] = None class-attribute instance-attribute
slide_number: Placeholder[Literal['‹#›'] | int | None] = None class-attribute instance-attribute
DefaultBlankSlideLayout

Bases: SlideLayout

Blank slide layout.

Source code in src/tppt/template/default.py
class DefaultBlankSlideLayout(SlideLayout):
    """Blank slide layout."""

    date: Placeholder[datetime.date | None] = None
    footer: Placeholder[str | None] = None
    slide_number: Placeholder[Literal["‹#›"] | int | None] = None
Attributes
date: Placeholder[datetime.date | None] = None class-attribute instance-attribute
footer: Placeholder[str | None] = None class-attribute instance-attribute
slide_number: Placeholder[Literal['‹#›'] | int | None] = None class-attribute instance-attribute
DefaultContentWithCaptionSlideLayout

Bases: SlideLayout

Content with caption slide layout.

Source code in src/tppt/template/default.py
class DefaultContentWithCaptionSlideLayout(SlideLayout):
    """Content with caption slide layout."""

    title: Placeholder[str]
    content: Placeholder[str]
    date: Placeholder[datetime.date | None] = None
    footer: Placeholder[str | None] = None
    slide_number: Placeholder[Literal["‹#›"] | int | None] = None
Attributes
title: Placeholder[str] instance-attribute
content: Placeholder[str] instance-attribute
date: Placeholder[datetime.date | None] = None class-attribute instance-attribute
footer: Placeholder[str | None] = None class-attribute instance-attribute
slide_number: Placeholder[Literal['‹#›'] | int | None] = None class-attribute instance-attribute
DefaultPictureWithCaptionSlideLayout

Bases: SlideLayout

Picture with caption slide layout.

Source code in src/tppt/template/default.py
class DefaultPictureWithCaptionSlideLayout(SlideLayout):
    """Picture with caption slide layout."""

    title: Placeholder[str]
    picture_path: Placeholder[FilePath]
    date: Placeholder[datetime.date | None] = None
    footer: Placeholder[str | None] = None
    slide_number: Placeholder[Literal["‹#›"] | int | None] = None
Attributes
title: Placeholder[str] instance-attribute
picture_path: Placeholder[FilePath] instance-attribute
date: Placeholder[datetime.date | None] = None class-attribute instance-attribute
footer: Placeholder[str | None] = None class-attribute instance-attribute
slide_number: Placeholder[Literal['‹#›'] | int | None] = None class-attribute instance-attribute
DefaultTitleAndVerticalTextSlideLayout

Bases: SlideLayout

Title and vertical text slide layout.

Source code in src/tppt/template/default.py
class DefaultTitleAndVerticalTextSlideLayout(SlideLayout):
    """Title and vertical text slide layout."""

    title: Placeholder[str]
    vertical_text: Placeholder[str]
    date: Placeholder[datetime.date | None] = None
    footer: Placeholder[str | None] = None
    slide_number: Placeholder[Literal["‹#›"] | int | None] = None
Attributes
title: Placeholder[str] instance-attribute
vertical_text: Placeholder[str] instance-attribute
date: Placeholder[datetime.date | None] = None class-attribute instance-attribute
footer: Placeholder[str | None] = None class-attribute instance-attribute
slide_number: Placeholder[Literal['‹#›'] | int | None] = None class-attribute instance-attribute
DefaultVerticalTitleAndTextSlideLayout

Bases: SlideLayout

Vertical title and text slide layout.

Source code in src/tppt/template/default.py
class DefaultVerticalTitleAndTextSlideLayout(SlideLayout):
    """Vertical title and text slide layout."""

    vertical_title: Placeholder[str]
    text: Placeholder[str]
    date: Placeholder[datetime.date | None]
    footer: Placeholder[str | None]
    slide_number: Placeholder[Literal["‹#›"] | int | None] = None
Attributes
vertical_title: Placeholder[str] instance-attribute
text: Placeholder[str] instance-attribute
date: Placeholder[datetime.date | None] instance-attribute
footer: Placeholder[str | None] instance-attribute
slide_number: Placeholder[Literal['‹#›'] | int | None] = None class-attribute instance-attribute
DefaultSlideMaster

Bases: SlideMaster

Source code in src/tppt/template/default.py
@slide_master("default")
class DefaultSlideMaster(SlideMaster):
    TitleLayout: Layout[DefaultTitleSlideLayout]
    TitleAndContentLayout: Layout[DefaultTitleAndContentSlideLayout]
    SectionHeaderLayout: Layout[DefaultSectionHeaderSlideLayout]
    TwoContentLayout: Layout[DefaultTwoContentSlideLayout]
    ComparisonLayout: Layout[DefaultComparisonSlideLayout]
    TitleOnlyLayout: Layout[DefaultTitleOnlySlideLayout]
    BlankLayout: Layout[DefaultBlankSlideLayout]
    ContentWithCaptionLayout: Layout[DefaultContentWithCaptionSlideLayout]
    PictureWithCaptionLayout: Layout[DefaultPictureWithCaptionSlideLayout]
    TitleAndVerticalTextLayout: Layout[DefaultTitleAndVerticalTextSlideLayout]
    VerticalTitleAndTextLayout: Layout[DefaultVerticalTitleAndTextSlideLayout]
Attributes
TitleLayout: Layout[DefaultTitleSlideLayout] instance-attribute
TitleAndContentLayout: Layout[DefaultTitleAndContentSlideLayout] instance-attribute
SectionHeaderLayout: Layout[DefaultSectionHeaderSlideLayout] instance-attribute
TwoContentLayout: Layout[DefaultTwoContentSlideLayout] instance-attribute
ComparisonLayout: Layout[DefaultComparisonSlideLayout] instance-attribute
TitleOnlyLayout: Layout[DefaultTitleOnlySlideLayout] instance-attribute
BlankLayout: Layout[DefaultBlankSlideLayout] instance-attribute
ContentWithCaptionLayout: Layout[DefaultContentWithCaptionSlideLayout] instance-attribute
PictureWithCaptionLayout: Layout[DefaultPictureWithCaptionSlideLayout] instance-attribute
TitleAndVerticalTextLayout: Layout[DefaultTitleAndVerticalTextSlideLayout] instance-attribute
VerticalTitleAndTextLayout: Layout[DefaultVerticalTitleAndTextSlideLayout] instance-attribute
Functions
slide_layout
Attributes
AnyType = TypeVar('AnyType') module-attribute
Classes
Placeholder
Source code in src/tppt/template/slide_layout.py
class Placeholder:
    @classmethod
    def __class_getitem__(cls, item: AnyType) -> AnyType:
        return Annotated[item, cls()]
Functions
__class_getitem__(item: AnyType) -> AnyType classmethod
Source code in src/tppt/template/slide_layout.py
@classmethod
def __class_getitem__(cls, item: AnyType) -> AnyType:
    return Annotated[item, cls()]
SlideLayout

Base class for slide layouts

Source code in src/tppt/template/slide_layout.py
@dataclass_transform(
    eq_default=True,
    order_default=False,
    field_specifiers=(),
)
class SlideLayout(metaclass=_SlideLayoutMeta):
    """Base class for slide layouts"""

    def __init__(self, **kwargs) -> None:
        # Set values for all fields
        for field_name, field_value in kwargs.items():
            if field_name in self.__class__.__placeholders__:
                # For placeholder fields
                setattr(self, field_name, field_value)
            elif field_name in self.__class__.__annotations__:
                setattr(self, field_name, field_value)
            else:
                raise TypeError(
                    f"'{self.__class__.__name__}' got an unexpected keyword argument '{field_name}'"
                )

    @overload
    def __get__(self, instance: None, objtype: type[Any]) -> type[Self]: ...

    @overload
    def __get__(self, instance: object, objtype: type[Any]) -> Self: ...

    def __get__(self, instance: object | None, objtype: type[Any]) -> type[Self] | Self:
        if instance is None:
            return type(self)

        else:
            return self

    def builder(self) -> "SlideBuilder":
        raise NotImplementedError(
            "SlideLayout is not instantiable. Use SlideLayoutProxy instead."
        )
Functions
__init__(**kwargs) -> None
Source code in src/tppt/template/slide_layout.py
def __init__(self, **kwargs) -> None:
    # Set values for all fields
    for field_name, field_value in kwargs.items():
        if field_name in self.__class__.__placeholders__:
            # For placeholder fields
            setattr(self, field_name, field_value)
        elif field_name in self.__class__.__annotations__:
            setattr(self, field_name, field_value)
        else:
            raise TypeError(
                f"'{self.__class__.__name__}' got an unexpected keyword argument '{field_name}'"
            )
__get__(instance: object | None, objtype: type[Any]) -> type[Self] | Self
__get__(instance: None, objtype: type[Any]) -> type[Self]
__get__(instance: object, objtype: type[Any]) -> Self
Source code in src/tppt/template/slide_layout.py
def __get__(self, instance: object | None, objtype: type[Any]) -> type[Self] | Self:
    if instance is None:
        return type(self)

    else:
        return self
builder() -> SlideBuilder
Source code in src/tppt/template/slide_layout.py
def builder(self) -> "SlideBuilder":
    raise NotImplementedError(
        "SlideLayout is not instantiable. Use SlideLayoutProxy instead."
    )
SlideLayoutProxy
Source code in src/tppt/template/slide_layout.py
class SlideLayoutProxy:
    def __init__(
        self,
        slide_layout: type[SlideLayout],
        convertible_slide_layout: "PptxConvertibleSlideLayout",
    ) -> None:
        self._slide_layout_type = slide_layout
        self._convertible_slide_layout = convertible_slide_layout

    def __call__(self, *args: Any, **kwargs: Any) -> Any:
        self._slide_layout = self._slide_layout_type(*args, **kwargs)

        return self

    def __getattr__(self, item: str) -> Any:
        return getattr(self._slide_layout, item)

    def builder(self) -> "SlideBuilder":
        from ..pptx.slide import Slide, SlideBuilder

        def placeholder_registry(slide: Slide):
            for placeholder, value in zip(
                slide.placeholders, get_placeholders(self._slide_layout).values()
            ):
                match value:
                    case None:
                        continue
                    case str():
                        placeholder.text = value
                    case datetime.date():
                        placeholder.text = value.strftime("%Y%m/%d")
                    case Callable():
                        value(placeholder)
                    case _:
                        assert_never(value)

        return SlideBuilder(
            self._convertible_slide_layout,
            placeholder_registry,
        )
Functions
__init__(slide_layout: type[SlideLayout], convertible_slide_layout: PptxConvertibleSlideLayout) -> None
Source code in src/tppt/template/slide_layout.py
def __init__(
    self,
    slide_layout: type[SlideLayout],
    convertible_slide_layout: "PptxConvertibleSlideLayout",
) -> None:
    self._slide_layout_type = slide_layout
    self._convertible_slide_layout = convertible_slide_layout
__call__(*args: Any, **kwargs: Any) -> Any
Source code in src/tppt/template/slide_layout.py
def __call__(self, *args: Any, **kwargs: Any) -> Any:
    self._slide_layout = self._slide_layout_type(*args, **kwargs)

    return self
__getattr__(item: str) -> Any
Source code in src/tppt/template/slide_layout.py
def __getattr__(self, item: str) -> Any:
    return getattr(self._slide_layout, item)
builder() -> SlideBuilder
Source code in src/tppt/template/slide_layout.py
def builder(self) -> "SlideBuilder":
    from ..pptx.slide import Slide, SlideBuilder

    def placeholder_registry(slide: Slide):
        for placeholder, value in zip(
            slide.placeholders, get_placeholders(self._slide_layout).values()
        ):
            match value:
                case None:
                    continue
                case str():
                    placeholder.text = value
                case datetime.date():
                    placeholder.text = value.strftime("%Y%m/%d")
                case Callable():
                    value(placeholder)
                case _:
                    assert_never(value)

    return SlideBuilder(
        self._convertible_slide_layout,
        placeholder_registry,
    )
Functions
get_placeholders(slide_layout: SlideLayout) -> OrderedDict[str, str | datetime.date | None | Callable[[SlidePlaceholder], SlidePlaceholder]]
Source code in src/tppt/template/slide_layout.py
def get_placeholders(
    slide_layout: SlideLayout,
) -> "OrderedDict[str, str | datetime.date | None | Callable[[SlidePlaceholder], SlidePlaceholder]]":
    return OrderedDict(
        (key, getattr(slide_layout, key))
        for key in slide_layout.__class__.__placeholders__
    )
slide_master
Attributes
GenericSlideMaster = TypeVar('GenericSlideMaster', bound='type[SlideMaster]') module-attribute
GenericTpptSlideMaster = TypeVar('GenericTpptSlideMaster', bound=SlideMaster) module-attribute
Classes
SlideMaster
Source code in src/tppt/template/slide_master.py
@dataclass_transform(
    eq_default=True,
    order_default=False,
    field_specifiers=(),
)
class SlideMaster(metaclass=_SlideMasterMeta): ...
Layout
Source code in src/tppt/template/slide_master.py
class Layout:
    @classmethod
    def __class_getitem__(cls, item: AnyType) -> AnyType:
        return Annotated[item, cls()]
Functions
__class_getitem__(item: AnyType) -> AnyType classmethod
Source code in src/tppt/template/slide_master.py
@classmethod
def __class_getitem__(cls, item: AnyType) -> AnyType:
    return Annotated[item, cls()]
SlideMasterProxy
Source code in src/tppt/template/slide_master.py
class SlideMasterProxy:
    def __init__(self, origin: type[SlideMaster], presentation: "Presentation") -> None:
        self._slide_master = origin
        self._presentation = presentation

    def __getattr__(self, key: str) -> SlideLayoutProxy:
        for i, (key2, slide_layout) in enumerate(
            get_slide_layouts(self._slide_master).items()
        ):
            if key2 == key:
                return SlideLayoutProxy(
                    slide_layout, self._presentation.slide_master.slide_layouts[i]
                )
        else:
            raise SlideMasterAttributeNotFoundError(key)
Functions
__init__(origin: type[SlideMaster], presentation: Presentation) -> None
Source code in src/tppt/template/slide_master.py
def __init__(self, origin: type[SlideMaster], presentation: "Presentation") -> None:
    self._slide_master = origin
    self._presentation = presentation
__getattr__(key: str) -> SlideLayoutProxy
Source code in src/tppt/template/slide_master.py
def __getattr__(self, key: str) -> SlideLayoutProxy:
    for i, (key2, slide_layout) in enumerate(
        get_slide_layouts(self._slide_master).items()
    ):
        if key2 == key:
            return SlideLayoutProxy(
                slide_layout, self._presentation.slide_master.slide_layouts[i]
            )
    else:
        raise SlideMasterAttributeNotFoundError(key)
Functions
slide_master(source: Literal['default'] | FilePath) -> Callable[[GenericSlideMaster], GenericSlideMaster]

Decorator that sets the slide master source.

Parameters:

Name Type Description Default
source Literal['default'] | FilePath

Either "default" or a path to a PowerPoint file containing the slide master

required
Source code in src/tppt/template/slide_master.py
def slide_master(
    source: Literal["default"] | FilePath,
) -> Callable[[GenericSlideMaster], GenericSlideMaster]:
    """Decorator that sets the slide master source.

    Args:
        source: Either "default" or a path to a PowerPoint file containing the slide master
    """

    def decorator(cls: GenericSlideMaster) -> GenericSlideMaster:
        # If the source is a relative path, convert it to an absolute path
        nonlocal source
        if source != "default":
            if isinstance(source, str):
                source = Path(source)
            if not source.is_absolute():
                import inspect

                # Get the caller's frame (where the decorator was called)
                caller_frame = inspect.stack()[1]
                caller_file = caller_frame.filename
                caller_path = Path(caller_file).parent
                source = caller_path / source

        setattr(cls, "__slide_master_source__", source)
        return cls

    return decorator
get_slide_layouts(slide_master: type[SlideMaster]) -> OrderedDict[str, type[SlideLayout]]

Get an array of slides tagged with Layout.

Source code in src/tppt/template/slide_master.py
def get_slide_layouts(
    slide_master: type[SlideMaster],
) -> OrderedDict[str, type[SlideLayout]]:
    """Get an array of slides tagged with Layout."""
    layouts = OrderedDict()

    for attr_name, annotation in slide_master.__annotations__.items():
        origin = get_origin(annotation)
        if origin is Annotated:
            args = get_args(annotation)
            # Identify Layout using class comparison instead of string name
            if len(args) > 1:
                if args[1].__class__ is Layout:
                    layouts[attr_name] = getattr(slide_master, attr_name)

    return layouts

tool

Tool module for TPPT.

Modules
ppt2template

Tool to generate slide master and layout type definitions from PowerPoint.

Attributes
formatter_class = RichHelpFormatter module-attribute
parser = argparse.ArgumentParser(description='Generate slide master and layout type definitions from PowerPoint', formatter_class=formatter_class) module-attribute
args = parser.parse_args() module-attribute
Classes
PlaceholderInfo dataclass

Information about a placeholder.

Source code in src/tppt/tool/ppt2template.py
@dataclass
class PlaceholderInfo:
    """Information about a placeholder."""

    name: str
    type: int
    field_name: str | None = None
    field_type: str | None = None
    required: bool = False
    idx: int | None = None
Attributes
name: str instance-attribute
type: int instance-attribute
field_name: str | None = None class-attribute instance-attribute
field_type: str | None = None class-attribute instance-attribute
required: bool = False class-attribute instance-attribute
idx: int | None = None class-attribute instance-attribute
Functions
__init__(name: str, type: int, field_name: str | None = None, field_type: str | None = None, required: bool = False, idx: int | None = None) -> None
LayoutInfo dataclass

Information about a slide layout.

Source code in src/tppt/tool/ppt2template.py
@dataclass
class LayoutInfo:
    """Information about a slide layout."""

    name: str
    placeholders: list[PlaceholderInfo]
    class_name: str | None = None
Attributes
name: str instance-attribute
placeholders: list[PlaceholderInfo] instance-attribute
class_name: str | None = None class-attribute instance-attribute
Functions
__init__(name: str, placeholders: list[PlaceholderInfo], class_name: str | None = None) -> None
MasterInfo dataclass

Information about a slide master.

Source code in src/tppt/tool/ppt2template.py
@dataclass
class MasterInfo:
    """Information about a slide master."""

    name: str
    layouts: list[LayoutInfo]
    class_name: str | None = None
Attributes
name: str instance-attribute
layouts: list[LayoutInfo] instance-attribute
class_name: str | None = None class-attribute instance-attribute
Functions
__init__(name: str, layouts: list[LayoutInfo], class_name: str | None = None) -> None
Functions
extract_master_info(tree: dict[str, Any]) -> MasterInfo

Extract information about the slide master and its layouts.

Source code in src/tppt/tool/ppt2template.py
def extract_master_info(tree: dict[str, Any]) -> MasterInfo:
    """Extract information about the slide master and its layouts."""

    master_name = Path(tree.get("name", "custom_template")).stem

    layouts_info = []

    # Extract layout information from slide masters
    if "slide_masters" in tree and tree["slide_masters"]:
        slide_master = tree["slide_masters"][0]
        if "slide_layouts" in slide_master:
            for layout in slide_master["slide_layouts"]:
                layout_name = layout.get("name", "")
                if layout_name:
                    placeholders = [
                        PlaceholderInfo(
                            name=p.get("name", ""),
                            type=p.get("placeholder_type", 0),
                            idx=i,
                        )
                        for i, p in enumerate(layout.get("placeholders", []))
                        if p.get("name")
                    ]
                    layouts_info.append(
                        LayoutInfo(name=layout_name, placeholders=placeholders)
                    )

    # Fallback if no layouts were extracted
    if not layouts_info:
        layout_map = {}
        for slide in tree.get("slides", []):
            layout_name = slide.get("slide_layout_name", "")
            if layout_name and layout_name not in layout_map:
                placeholders = [
                    PlaceholderInfo(
                        name=p.get("name", ""), type=p.get("placeholder_type", 0), idx=i
                    )
                    for i, p in enumerate(slide.get("placeholders", []))
                    if p.get("name")
                ]
                layout_map[layout_name] = LayoutInfo(
                    name=layout_name, placeholders=placeholders
                )
        layouts_info = list(layout_map.values())

    return MasterInfo(name=master_name, layouts=layouts_info)
clean_field_name(name: str) -> str

Clean a field name to make it suitable for a Python identifier.

Removes numeric suffixes, converts to snake_case, and handles special characters.

Source code in src/tppt/tool/ppt2template.py
def clean_field_name(name: str) -> str:
    """Clean a field name to make it suitable for a Python identifier.

    Removes numeric suffixes, converts to snake_case, and handles special characters.
    """
    # Remove numeric suffixes (e.g., "Title 1" -> "Title")
    name = re.sub(r"\s+\d+$", "", name)

    # Convert to lowercase and replace spaces/special chars with underscores
    name = name.lower().replace(" ", "_").replace("-", "_").replace(".", "_")

    # Remove "placeholder" suffix if present
    name = name.replace("_placeholder", "")

    # Ensure the name is a valid Python identifier
    if not name or not name[0].isalpha() and name[0] != "_":
        name = f"placeholder_{name}"

    # Replace any remaining invalid characters
    name = re.sub(r"[^a-z0-9_]", "_", name)

    return name
analyze_layout(layout: LayoutInfo) -> LayoutInfo

Analyze layout and determine class name and field information.

Source code in src/tppt/tool/ppt2template.py
def analyze_layout(layout: LayoutInfo) -> LayoutInfo:
    """Analyze layout and determine class name and field information."""

    # Generate class name in PascalCase
    layout_name_parts = layout.name.replace("-", " ").split()
    class_name = (
        "Custom" + "".join(part.capitalize() for part in layout_name_parts) + "Layout"
    )

    # Process placeholders to ensure no duplicates and proper field names
    processed_placeholders = []
    seen_field_names = set()
    placeholder_type_map = {}
    layout_name_lower = layout.name.lower()

    # Count placeholder names of the same type (e.g., how many elements named "content")
    placeholder_base_name_counts = {}

    # First pass - identify placeholder types and count base names
    for ph in layout.placeholders:
        if ph.type not in placeholder_type_map:
            placeholder_type_map[ph.type] = []
        placeholder_type_map[ph.type].append(ph)

        # Count the cleaned base names
        base_name = clean_field_name(ph.name)
        if ph.type in [2, 7]:  # content/body type placeholders
            if "content" in layout_name_lower or "text" in layout_name_lower:
                base_name = "content"
            else:
                base_name = "body"

        placeholder_base_name_counts[base_name] = (
            placeholder_base_name_counts.get(base_name, 0) + 1
        )

    # Determine base names for placeholders of the same type
    type_base_names = {}
    for ph_type, phs in placeholder_type_map.items():
        # Determine base name for each type
        if len(phs) == 0:
            continue

        sample_ph = phs[0]
        base_name = ""

        # Determine base name based on placeholder type
        match ph_type:
            case PP_PLACEHOLDER_TYPE.TITLE:
                base_name = "title"
            case PP_PLACEHOLDER_TYPE.BODY:
                base_name = "body"
            case PP_PLACEHOLDER_TYPE.CENTER_TITLE:
                base_name = "title"
            case PP_PLACEHOLDER_TYPE.SUBTITLE:
                base_name = "subtitle"
            case PP_PLACEHOLDER_TYPE.CHART:
                base_name = "chart"
            case PP_PLACEHOLDER_TYPE.TABLE:
                base_name = "table"
            case PP_PLACEHOLDER_TYPE.SLIDE_NUMBER:
                base_name = "slide_number"
            case PP_PLACEHOLDER_TYPE.FOOTER:
                base_name = "footer"
            case PP_PLACEHOLDER_TYPE.DATE:
                base_name = "date"
            case PP_PLACEHOLDER_TYPE.PICTURE:
                base_name = "picture"
            case PP_PLACEHOLDER_TYPE.VERTICAL_TITLE:
                base_name = "vertical_title"
            case PP_PLACEHOLDER_TYPE.VERTICAL_BODY:
                base_name = "vertical_text"
            case _:
                # For other types, use the cleaned placeholder name
                base_name = clean_field_name(sample_ph.name)
        # Process all types of placeholders
        if ph_type not in [
            1,
            3,
            4,
            13,
            15,
            16,
            19,
            20,
        ]:  # Don't add indexes to title, subtitle, date, footer, etc.
            # Special handling for specific layout types
            if (
                "two content" in layout_name_lower
                and ph_type in [2, 7]
                and len(phs) == 2
            ):
                type_base_names[ph_type] = ["left_content", "right_content"]
            elif (
                "comparison" in layout_name_lower
                and ph_type in [2, 7]
                and len(phs) >= 4
            ):
                special_names = [
                    "left_title" if "title" in phs[0].name.lower() else "left_content",
                    "left_body" if "body" in phs[1].name.lower() else "left_content",
                    "right_title"
                    if "title" in phs[2].name.lower()
                    else "right_content",
                    "right_body" if "body" in phs[3].name.lower() else "right_content",
                ]
                type_base_names[ph_type] = special_names

                # For any remaining placeholders, use content5, content6...
                for i in range(4, len(phs)):
                    type_base_names[ph_type].append(f"content{i + 1}")
            else:
                # Only add indexes when there are multiple placeholders of the same type
                if len(phs) > 1:
                    base_name_without_numbers = re.sub(
                        r"\d+$", "", base_name
                    )  # Remove any trailing numbers from the base name
                    type_base_names[ph_type] = [
                        f"{base_name_without_numbers}{i + 1}" for i in range(len(phs))
                    ]
                else:
                    # For single placeholders, don't add indexes
                    type_base_names[ph_type] = [base_name]
        else:
            # Don't add indexes to date, footer, slide number etc.
            type_base_names[ph_type] = [base_name]

    # Second pass - assign field names to each placeholder
    processed_placeholders = []

    for ph in layout.placeholders:
        if not ph.name:
            continue

        placeholder_type = ph.type

        # Determine which index this placeholder has within its type
        same_type_phs = placeholder_type_map.get(placeholder_type, [])
        idx = same_type_phs.index(ph)

        # Determine field name
        if placeholder_type in type_base_names and idx < len(
            type_base_names[placeholder_type]
        ):
            field_name = type_base_names[placeholder_type][idx]
        else:
            # Fallback: use cleaned original name
            field_name = clean_field_name(ph.name)

        # Avoid duplicate names
        if field_name in seen_field_names:
            # Special handling for Content with Caption layout
            if layout.name == "Content with Caption" and placeholder_type == 2:
                # Do nothing (the correct name is already set above)
                pass
            else:
                counter = 1
                while f"{field_name}{counter}" in seen_field_names:
                    counter += 1
                field_name = f"{field_name}{counter}"

        seen_field_names.add(field_name)

        # Determine field type
        required = False
        match placeholder_type:
            case 16:
                field_type = "tppt.Placeholder[datetime.date | None]"
            case 13:
                field_type = 'tppt.Placeholder[Literal["‹#›"] | int | None]'
            case 1 | 3 | 19:
                field_type = "tppt.Placeholder[str]"
                required = True
            case 4:
                field_type = "tppt.Placeholder[str | None]"
            case 18:
                field_type = "tppt.Placeholder[tppt.types.FilePath | None]"
            case 7:
                field_type = "tppt.Placeholder[tppt.types.FilePath | None]"
            case 8:
                field_type = "tppt.Placeholder[str | None]"
            case 2 | 7 | 20:
                field_type = "tppt.Placeholder[str | None]"
            case 15:
                field_type = "tppt.Placeholder[str | None]"
            case _:
                field_type = "tppt.Placeholder[str | None]"

        new_ph = PlaceholderInfo(
            name=ph.name,
            type=ph.type,
            field_name=field_name,
            field_type=field_type,
            required=required,
            idx=ph.idx,
        )
        processed_placeholders.append(new_ph)

    return LayoutInfo(
        name=layout.name, placeholders=processed_placeholders, class_name=class_name
    )
generate_layout_class(layout: LayoutInfo) -> str

Generate Python code for a slide layout class.

Source code in src/tppt/tool/ppt2template.py
def generate_layout_class(layout: LayoutInfo) -> str:
    """Generate Python code for a slide layout class."""

    class_name = layout.class_name or f"Custom{layout.name.replace(' ', '')}Layout"
    class_docstring = f'"""{layout.name} layout."""'

    # Remove duplicate field names
    unique_fields = {}
    for ph in layout.placeholders:
        if not ph.field_name or not ph.field_type:
            continue

        # Overwrite if the same field name exists (use the last one)
        unique_fields[ph.field_name] = ph

    # Maintain original index order (do not sort)
    placeholder_definitions = []
    for ph in layout.placeholders:
        if not ph.field_name or not ph.field_type:
            continue

        # Only output the last processed field to avoid duplicates
        if unique_fields.get(ph.field_name) is not ph:
            continue

        if ph.required:
            placeholder_definitions.append(f"    {ph.field_name}: {ph.field_type}")
        else:
            placeholder_definitions.append(
                f"    {ph.field_name}: {ph.field_type} = None"
            )

    if not placeholder_definitions:
        placeholder_definitions = ["    # No placeholders found"]

    return (
        f"class {class_name}(tppt.SlideLayout):\n"
        f"    {class_docstring}\n\n" + "\n\n".join(placeholder_definitions)
    )
generate_master_class(master: MasterInfo) -> str

Generate Python code for a slide master class.

Source code in src/tppt/tool/ppt2template.py
def generate_master_class(master: MasterInfo) -> str:
    """Generate Python code for a slide master class."""

    # Convert master_name to PascalCase
    class_prefix = "".join(
        word.capitalize() for word in master.name.replace("-", "_").split("_")
    )
    class_name = f"{class_prefix}SlideMaster"

    layout_definitions = []
    for layout in master.layouts:
        layout_class_name = (
            layout.class_name or f"Custom{layout.name.replace(' ', '')}Layout"
        )
        layout_field_name = f"{layout.name.replace(' ', '')}Layout"
        layout_definitions.append(
            f"    {layout_field_name}: tppt.Layout[{layout_class_name}]"
        )

    if not layout_definitions:
        layout_definitions = ["    # No layouts found"]

    class_docstring = f'"""{master.name} slide master."""'

    return (
        f'@tppt.slide_master("{master.name}.pptx")\n'
        f"class {class_name}(tppt.SlideMaster):\n"
        f"    {class_docstring}\n\n" + "\n\n".join(layout_definitions)
    )
analyze_slide_structure(pptx_path: tppt.types.FilePath) -> dict[str, Any]

Analyzes slide master and layout information from a PowerPoint file.

Parameters:

Name Type Description Default
pptx_path FilePath

Path to the PowerPoint file

required
Source code in src/tppt/tool/ppt2template.py
def analyze_slide_structure(pptx_path: tppt.types.FilePath) -> dict[str, Any]:
    """Analyzes slide master and layout information from a PowerPoint file.

    Args:
        pptx_path: Path to the PowerPoint file
    """
    pptx_path = Path(pptx_path)

    if not pptx_path.exists():
        raise FileNotFoundError(f"PPTX file not found: {pptx_path}")

    # Load the presentation
    presentation = tppt.Presentation.from_pptx(PptxPresentation(os.fspath(pptx_path)))

    # Get the tree structure
    tree = presentation.tree
    return tree
generate_template_file(pptx_path: tppt.types.FilePath, *, output_path: tppt.types.FilePath | None = None) -> None

Generates slide master and layout definitions from a PowerPoint file and saves them as a Python file.

Parameters:

Name Type Description Default
pptx_path FilePath

Path to the PowerPoint file

required
output_path FilePath | None

Path to save the generated Python file (default: prints to standard output)

None
Source code in src/tppt/tool/ppt2template.py
def generate_template_file(
    pptx_path: tppt.types.FilePath,
    *,
    output_path: tppt.types.FilePath | None = None,
) -> None:
    """Generates slide master and layout definitions from a PowerPoint file and saves them as a Python file.

    Args:
        pptx_path: Path to the PowerPoint file
        output_path: Path to save the generated Python file (default: prints to standard output)
    """
    pptx_path = Path(pptx_path)

    # Analyze slide structure
    tree = analyze_slide_structure(pptx_path)
    tree["name"] = str(pptx_path)

    # Extract and analyze information
    master_info = extract_master_info(tree)

    # Analyze each layout
    analyzed_layouts = []
    for layout in master_info.layouts:
        analyzed_layout = analyze_layout(layout)
        analyzed_layouts.append(analyzed_layout)

    master_info.layouts = analyzed_layouts

    # Generate code for imports
    imports = [
        "import datetime",
        "from typing import Literal",
        "",
        "import tppt",
        "",
    ]

    # Generate code for layout classes
    layout_classes = []
    for layout in master_info.layouts:
        layout_class = generate_layout_class(layout)
        layout_classes.append(layout_class)

    # Generate master class
    master_class = generate_master_class(master_info)

    # Combine everything
    content = (
        "\n".join(imports)
        + "\n\n"
        + "\n\n\n".join(layout_classes)
        + "\n\n\n"
        + master_class
    )

    if output_path:
        with open(output_path, "w", encoding="utf-8") as f:
            f.write(content)
    else:
        print(content)
ppt2tree

Tool to convert PowerPoint to tree structure JSON.

Attributes
formatter_class = RichHelpFormatter module-attribute
parser = argparse.ArgumentParser(description='Convert PPTX to tree structure JSON', formatter_class=formatter_class) module-attribute
args = parser.parse_args() module-attribute
Functions
save_ppt_tree(pptx_path: tppt.types.FilePath, *, pretty: bool = False, output_path: tppt.types.FilePath | None = None) -> None

Convert PPTX file to tree structure and save as JSON.

Parameters:

Name Type Description Default
pptx_path FilePath

Path to the PPTX file

required
output_path FilePath | None

Path to save the JSON file (default: same as PPTX with .json extension)

None
Source code in src/tppt/tool/ppt2tree.py
def save_ppt_tree(
    pptx_path: tppt.types.FilePath,
    *,
    pretty: bool = False,
    output_path: tppt.types.FilePath | None = None,
) -> None:
    """Convert PPTX file to tree structure and save as JSON.

    Args:
        pptx_path: Path to the PPTX file
        output_path: Path to save the JSON file (default: same as PPTX with .json extension)
    """
    pptx_path = Path(pptx_path)

    if not pptx_path.exists():
        raise FileNotFoundError(f"PPTX file not found: {pptx_path}")

    # Load the presentation
    presentation = tppt.Presentation.from_pptx(PptxPresentation(os.fspath(pptx_path)))

    # Get the tree structure
    tree = presentation.tree

    options: dict[str, Any] = {"ensure_ascii": False}
    if pretty:
        options["indent"] = 2
        options["separators"] = (",", ":")
    else:
        options["indent"] = None
        options["separators"] = (",", ":")

    # Save to JSON file
    if output_path:
        with open(output_path, "w", encoding="utf-8") as f:
            print(json.dumps(tree, **options), file=f)
    else:
        print(json.dumps(tree, **options))

types

tppt types.

Attributes
FilePath = str | pathlib.Path module-attribute
Range: TypeAlias = _RangeProps module-attribute
Classes
Functions