zcbot/skills/ppt/scripts/svg_to_pptx/pptx_slide_xml.py

137 lines
4.6 KiB
Python

"""Slide XML and slide relationship XML generation."""
from __future__ import annotations
# Import animation module (optional)
try:
from pptx_animations import create_transition_xml, TRANSITIONS
ANIMATIONS_AVAILABLE = True
except ImportError:
ANIMATIONS_AVAILABLE = False
TRANSITIONS = {}
def create_slide_xml_with_svg(
slide_num: int,
png_rid: str,
svg_rid: str,
width_emu: int,
height_emu: int,
transition: str | None = 'fade',
transition_duration: float = 0.5,
auto_advance: float | None = None,
use_compat_mode: bool = True,
) -> str:
"""Create slide XML containing an SVG image.
Args:
slide_num: Slide number.
png_rid: PNG fallback image relationship ID.
svg_rid: SVG relationship ID.
width_emu: Width in EMU.
height_emu: Height in EMU.
transition: Transition effect name.
transition_duration: Transition duration in seconds.
auto_advance: Auto-advance interval in seconds.
use_compat_mode: Whether to use compatibility mode (PNG + SVG dual format).
"""
transition_xml = ''
if transition and ANIMATIONS_AVAILABLE:
transition_xml = '\n' + create_transition_xml(
effect=transition,
duration=transition_duration,
advance_after=auto_advance,
)
if use_compat_mode:
blip_xml = f'''<a:blip r:embed="{png_rid}">
<a:extLst>
<a:ext uri="{{96DAC541-7B7A-43D3-8B79-37D633B846F1}}">
<asvg:svgBlip xmlns:asvg="http://schemas.microsoft.com/office/drawing/2016/SVG/main" r:embed="{svg_rid}"/>
</a:ext>
</a:extLst>
</a:blip>'''
else:
blip_xml = f'<a:blip r:embed="{svg_rid}"/>'
return f'''<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<p:sld xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main">
<p:cSld>
<p:spTree>
<p:nvGrpSpPr>
<p:cNvPr id="1" name=""/>
<p:cNvGrpSpPr/>
<p:nvPr/>
</p:nvGrpSpPr>
<p:grpSpPr>
<a:xfrm>
<a:off x="0" y="0"/>
<a:ext cx="0" cy="0"/>
<a:chOff x="0" y="0"/>
<a:chExt cx="0" cy="0"/>
</a:xfrm>
</p:grpSpPr>
<p:pic>
<p:nvPicPr>
<p:cNvPr id="2" name="SVG Image {slide_num}"/>
<p:cNvPicPr>
<a:picLocks noChangeAspect="1"/>
</p:cNvPicPr>
<p:nvPr/>
</p:nvPicPr>
<p:blipFill>
{blip_xml}
<a:stretch>
<a:fillRect/>
</a:stretch>
</p:blipFill>
<p:spPr>
<a:xfrm>
<a:off x="0" y="0"/>
<a:ext cx="{width_emu}" cy="{height_emu}"/>
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst/>
</a:prstGeom>
</p:spPr>
</p:pic>
</p:spTree>
</p:cSld>
<p:clrMapOvr>
<a:masterClrMapping/>
</p:clrMapOvr>{transition_xml}
</p:sld>'''
def create_slide_rels_xml(
png_rid: str,
png_filename: str,
svg_rid: str,
svg_filename: str,
use_compat_mode: bool = True,
) -> str:
"""Create slide relationship file XML.
Args:
png_rid: PNG image relationship ID.
png_filename: PNG filename.
svg_rid: SVG relationship ID.
svg_filename: SVG filename.
use_compat_mode: Whether to use compatibility mode.
"""
if use_compat_mode:
return f'''<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout" Target="../slideLayouts/slideLayout1.xml"/>
<Relationship Id="{png_rid}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="../media/{png_filename}"/>
<Relationship Id="{svg_rid}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="../media/{svg_filename}"/>
</Relationships>'''
else:
return f'''<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout" Target="../slideLayouts/slideLayout1.xml"/>
<Relationship Id="{svg_rid}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="../media/{svg_filename}"/>
</Relationships>'''