Release standalone PPT template workflow 0.5.0
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
"""In-memory flattening of positional ``<tspan>`` elements.
|
||||
|
||||
DrawingML's text-run model has no way to express "jump to a new x/y inside
|
||||
the same paragraph". Every ``<tspan>`` carrying ``x``, ``y`` or non-zero
|
||||
``dy`` is therefore a layout instruction this converter cannot honour
|
||||
inline — without flattening, a 4-line dy-stacked block collapses onto a
|
||||
single baseline and an x-anchored tspan jumps to the wrong column.
|
||||
|
||||
The on-disk ``finalize_svg`` pipeline solves this by promoting each
|
||||
positional tspan to an independent ``<text>`` element. This module
|
||||
performs the same transformation in memory so ``svg_to_pptx`` can consume
|
||||
``svg_output/`` directly without that disk step.
|
||||
|
||||
Public API:
|
||||
flatten_positional_tspans(tree) -> bool
|
||||
Walk the SVG element tree, replace every positional ``<tspan>``
|
||||
with an independent ``<text>``, and return whether anything
|
||||
changed.
|
||||
|
||||
Heavy lifting is delegated to ``svg_finalize.flatten_tspan`` so the two
|
||||
pipelines stay behaviourally aligned.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from xml.etree import ElementTree as ET
|
||||
|
||||
|
||||
def _flatten_module():
|
||||
"""Load the shared on-disk flattener after exposing the scripts root."""
|
||||
scripts_dir = Path(__file__).resolve().parent.parent
|
||||
if str(scripts_dir) not in sys.path:
|
||||
sys.path.insert(0, str(scripts_dir))
|
||||
from svg_finalize import flatten_tspan # type: ignore
|
||||
return flatten_tspan
|
||||
|
||||
|
||||
def flatten_positional_tspans(
|
||||
tree: ET.ElementTree,
|
||||
merge_paragraphs: bool = False,
|
||||
preserve_line_breaks: bool = False,
|
||||
) -> bool:
|
||||
"""Flatten positional ``<tspan>`` elements into independent ``<text>``.
|
||||
|
||||
Delegates to ``svg_finalize.flatten_tspan.flatten_text_with_tspans`` so
|
||||
the in-memory transform exactly matches the on-disk one. When
|
||||
``merge_paragraphs`` is True, mergeable paragraph blocks are preserved
|
||||
as a single <text>. ``preserve_line_breaks`` marks visual rows for hard
|
||||
DrawingML line breaks instead of reflow.
|
||||
|
||||
Returns True if any tspan was rewritten.
|
||||
"""
|
||||
return _flatten_module().flatten_text_with_tspans(
|
||||
tree,
|
||||
merge_paragraphs=merge_paragraphs,
|
||||
preserve_line_breaks=preserve_line_breaks,
|
||||
)
|
||||
|
||||
|
||||
def nested_positional_tspan_errors(root: ET.Element) -> list[str]:
|
||||
"""Return shared diagnostics for unsupported nested baseline jumps."""
|
||||
return _flatten_module().nested_positional_tspan_errors(root)
|
||||
Reference in New Issue
Block a user