athena-python-pptx 0.1.75__tar.gz → 0.1.76__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/CHANGELOG.md +17 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/PKG-INFO +1 -1
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/__init__.py +1 -1
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/commands.py +7 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/shapes/__init__.py +71 -7
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pyproject.toml +1 -1
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/.gitignore +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/API_PARITY_REPORT.md +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/CLAUDE.md +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/DEV-GUIDE.md +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/PARITY_QUESTIONS.md +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/PUBLISHING.md +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/README.md +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/docs/API_PARITY_EXCEPTIONS.md +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/docs/athena-api.json +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/docs/athena-api.md +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/_ptc.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/action.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/batching.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/chart/__init__.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/chart/axis.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/chart/category.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/chart/chart.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/chart/data.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/chart/datalabel.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/chart/legend.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/chart/marker.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/chart/plot.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/chart/point.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/chart/series.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/chart/xlsx.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/client.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/decorators.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/dml/__init__.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/dml/chtfmt.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/dml/color.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/dml/effect.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/dml/fill.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/dml/line.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/docgen.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/enum/__init__.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/enum/action.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/enum/chart.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/enum/dml.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/enum/lang.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/enum/shapes.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/enum/text.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/errors.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/exc.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/media.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/package.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/parts/__init__.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/parts/_base.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/parts/chart.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/parts/coreprops.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/parts/embeddedpackage.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/parts/image.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/parts/media.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/parts/presentation.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/parts/slide.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/presentation.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/shapes/autoshape.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/shapes/base.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/shapes/connector.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/shapes/freeform.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/shapes/graphfrm.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/shapes/group.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/shapes/picture.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/shapes/placeholder.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/shapes/shapetree.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/shared.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/slide.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/slides.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/spec.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/table.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/text/__init__.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/text/fonts.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/text/layout.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/text/text.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/types.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/typing.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/units.py +0 -0
- {athena_python_pptx-0.1.75 → athena_python_pptx-0.1.76}/pptx/util.py +0 -0
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `athena-python-pptx` are documented in this file.
|
|
4
4
|
|
|
5
|
+
## 0.1.76
|
|
6
|
+
|
|
7
|
+
**Table cell paragraph alignment now round-trips to OOXML (baseline-parity Gap A2).**
|
|
8
|
+
|
|
9
|
+
`cell.text_frame.paragraphs[0].alignment = PP_ALIGN.X` previously stored
|
|
10
|
+
the value locally for python-pptx parity but never reached the server.
|
|
11
|
+
The setter now translates `PP_PARAGRAPH_ALIGNMENT` enum members (and the
|
|
12
|
+
python-pptx lowercase string aliases) to the OOXML short form
|
|
13
|
+
(`l` / `ctr` / `r` / `just` / `dist` / `thaiDist` / `justLow`) and emits
|
|
14
|
+
a `SetTableCell` command carrying `paragraphAlignment`. The applier
|
|
15
|
+
writes it to every paragraph in the cell's text body; the export worker
|
|
16
|
+
emits a `SetTableCellText` intent whose paragraph alignment lands on
|
|
17
|
+
`<a:pPr algn="…">` in the exported PPTX.
|
|
18
|
+
|
|
19
|
+
Closes ~52 baseline-parity XML diffs against the 33 fixtures in
|
|
20
|
+
`pptx-studio/tests/baseline-parity/`.
|
|
21
|
+
|
|
5
22
|
## 0.1.75
|
|
6
23
|
|
|
7
24
|
**Critical bug fix — invisible text from `font.size = Pt(X)`.**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: athena-python-pptx
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.76
|
|
4
4
|
Summary: Drop-in replacement for python-pptx that connects to PPTX Studio for real-time collaboration
|
|
5
5
|
Project-URL: Homepage, https://github.com/pptx-studio/python-sdk
|
|
6
6
|
Project-URL: Documentation, https://docs.pptx-studio.com/sdk/python
|
|
@@ -476,6 +476,12 @@ class SetTableCell(Command):
|
|
|
476
476
|
col: Column index (0-based)
|
|
477
477
|
text: Cell text content
|
|
478
478
|
fill_color_hex: Cell background color
|
|
479
|
+
paragraph_alignment: Horizontal alignment of the cell's text body.
|
|
480
|
+
Mirrors python-pptx ``cell.text_frame.paragraphs[0].alignment``.
|
|
481
|
+
Accepts the OOXML short forms ``l``, ``ctr``, ``r``, ``just``,
|
|
482
|
+
``dist``, ``thaiDist``. Translated from ``PP_ALIGN`` /
|
|
483
|
+
``PP_PARAGRAPH_ALIGNMENT`` by the SDK before emit. Closes
|
|
484
|
+
baseline-parity Gap A2 (~52 diffs across table fixtures).
|
|
479
485
|
"""
|
|
480
486
|
|
|
481
487
|
shape_id: ShapeId
|
|
@@ -486,6 +492,7 @@ class SetTableCell(Command):
|
|
|
486
492
|
font_size_centipoints: Optional[int] = None
|
|
487
493
|
bold: Optional[bool] = None
|
|
488
494
|
font_color_hex: Optional[str] = None
|
|
495
|
+
paragraph_alignment: Optional[str] = None
|
|
489
496
|
|
|
490
497
|
@property
|
|
491
498
|
def command_type(self) -> str:
|
|
@@ -56,6 +56,57 @@ _ELEMENT_TYPE_TO_MSO_SHAPE_TYPE: dict[str, MSO_SHAPE_TYPE] = {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
|
|
59
|
+
# Map PP_PARAGRAPH_ALIGNMENT enum members and python-pptx string aliases
|
|
60
|
+
# to OOXML <a:pPr algn="..."> short forms. Accepts the IntEnum int values
|
|
61
|
+
# directly so callers can pass ``PP_ALIGN.CENTER`` without importing the
|
|
62
|
+
# enum class. ``None`` clears the attribute.
|
|
63
|
+
_PP_ALIGN_INT_TO_OOXML: dict[int, str] = {
|
|
64
|
+
1: "l",
|
|
65
|
+
2: "ctr",
|
|
66
|
+
3: "r",
|
|
67
|
+
4: "just",
|
|
68
|
+
5: "dist",
|
|
69
|
+
6: "thaiDist",
|
|
70
|
+
7: "justLow",
|
|
71
|
+
}
|
|
72
|
+
_PP_ALIGN_NAME_TO_OOXML: dict[str, str] = {
|
|
73
|
+
"left": "l",
|
|
74
|
+
"center": "ctr",
|
|
75
|
+
"right": "r",
|
|
76
|
+
"justify": "just",
|
|
77
|
+
"distribute": "dist",
|
|
78
|
+
"thai_distribute": "thaiDist",
|
|
79
|
+
"justify_low": "justLow",
|
|
80
|
+
# Already-short forms pass through.
|
|
81
|
+
"l": "l", "ctr": "ctr", "r": "r",
|
|
82
|
+
"just": "just", "dist": "dist", "thaiDist": "thaiDist", "justLow": "justLow",
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def _normalize_pp_align(value: Any) -> Optional[str]:
|
|
87
|
+
"""Translate a PP_ALIGN value to the OOXML short form used by SetTableCell.
|
|
88
|
+
|
|
89
|
+
Accepts ``PP_PARAGRAPH_ALIGNMENT`` (or any ``int``) and the lowercased
|
|
90
|
+
python-pptx string aliases used by ``pptx.text.PP_ALIGN``. Returns
|
|
91
|
+
``None`` for ``None`` input so the setter can clear the attribute.
|
|
92
|
+
"""
|
|
93
|
+
if value is None:
|
|
94
|
+
return None
|
|
95
|
+
if isinstance(value, int) and not isinstance(value, bool):
|
|
96
|
+
try:
|
|
97
|
+
return _PP_ALIGN_INT_TO_OOXML[int(value)]
|
|
98
|
+
except KeyError:
|
|
99
|
+
raise ValueError(f"Unsupported paragraph alignment value: {value!r}")
|
|
100
|
+
if isinstance(value, str):
|
|
101
|
+
try:
|
|
102
|
+
return _PP_ALIGN_NAME_TO_OOXML[value]
|
|
103
|
+
except KeyError:
|
|
104
|
+
raise ValueError(f"Unsupported paragraph alignment value: {value!r}")
|
|
105
|
+
raise TypeError(
|
|
106
|
+
f"alignment must be a PP_ALIGN enum, int, or string; got {type(value).__name__}"
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
|
|
59
110
|
# Map XL_CHART_TYPE → (server chart_type, grouping). Only the chart types
|
|
60
111
|
# author.ts supports today are listed here; anything else raises
|
|
61
112
|
# UnsupportedFeatureError. Surface area mirrors python-pptx's accepted enum
|
|
@@ -5814,15 +5865,13 @@ class _TableCellParagraph:
|
|
|
5814
5865
|
For API parity with python-pptx, ``add_run()`` and ``clear()`` are
|
|
5815
5866
|
supported but operate on the single underlying run — multiple
|
|
5816
5867
|
``add_run()`` calls return the *same* ``_TableCellRun`` object, and
|
|
5817
|
-
only the last text/style assignment wins. ``alignment``
|
|
5818
|
-
|
|
5819
|
-
paragraph-alignment command on the applier).
|
|
5868
|
+
only the last text/style assignment wins. ``alignment`` round-trips
|
|
5869
|
+
to ``<a:pPr algn="...">`` on the cell's text body via SetTableCell.
|
|
5820
5870
|
"""
|
|
5821
5871
|
|
|
5822
5872
|
def __init__(self, cell: "TableCell"):
|
|
5823
5873
|
self._cell = cell
|
|
5824
5874
|
self._runs = [_TableCellRun(cell)]
|
|
5825
|
-
self._alignment: Optional[Any] = None
|
|
5826
5875
|
|
|
5827
5876
|
@property
|
|
5828
5877
|
def runs(self) -> list[_TableCellRun]:
|
|
@@ -5838,12 +5887,22 @@ class _TableCellParagraph:
|
|
|
5838
5887
|
|
|
5839
5888
|
@property
|
|
5840
5889
|
def alignment(self) -> Optional[Any]:
|
|
5841
|
-
|
|
5890
|
+
"""Return the cell's paragraph alignment as the original input value.
|
|
5891
|
+
|
|
5892
|
+
Stored on the parent cell so that text-body re-creation (which
|
|
5893
|
+
rebuilds the paragraph wrapper) doesn't lose the assignment.
|
|
5894
|
+
"""
|
|
5895
|
+
return self._cell._paragraph_alignment_input
|
|
5842
5896
|
|
|
5843
5897
|
@alignment.setter
|
|
5844
5898
|
def alignment(self, value: Any) -> None:
|
|
5845
|
-
#
|
|
5846
|
-
|
|
5899
|
+
# Translate PP_ALIGN enum / string to OOXML short form. Stored on
|
|
5900
|
+
# the cell so we can re-emit it inside SetTableCell. Keep the
|
|
5901
|
+
# original input around for the getter to return per python-pptx
|
|
5902
|
+
# semantics (callers expect the same value type back).
|
|
5903
|
+
self._cell._paragraph_alignment_input = value
|
|
5904
|
+
self._cell._paragraph_alignment = _normalize_pp_align(value)
|
|
5905
|
+
self._cell._emit_cell_change()
|
|
5847
5906
|
|
|
5848
5907
|
def add_run(self) -> _TableCellRun:
|
|
5849
5908
|
"""Return the single underlying run.
|
|
@@ -5943,6 +6002,10 @@ class TableCell:
|
|
|
5943
6002
|
self._margin_top = margin_top
|
|
5944
6003
|
self._margin_bottom = margin_bottom
|
|
5945
6004
|
self._vertical_anchor = vertical_anchor
|
|
6005
|
+
# OOXML short form (``l``/``ctr``/``r``/...) sent over the wire and
|
|
6006
|
+
# the caller's original input retained for the python-pptx getter.
|
|
6007
|
+
self._paragraph_alignment: Optional[str] = None
|
|
6008
|
+
self._paragraph_alignment_input: Any = None
|
|
5946
6009
|
|
|
5947
6010
|
@property
|
|
5948
6011
|
def text(self) -> str:
|
|
@@ -6318,6 +6381,7 @@ class TableCell:
|
|
|
6318
6381
|
font_size_centipoints=int(self._font_size_pt * 100) if self._font_size_pt is not None else None,
|
|
6319
6382
|
bold=self._bold,
|
|
6320
6383
|
font_color_hex=self._font_color_hex,
|
|
6384
|
+
paragraph_alignment=self._paragraph_alignment,
|
|
6321
6385
|
)
|
|
6322
6386
|
self._table._buffer.add(cmd)
|
|
6323
6387
|
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "athena-python-pptx"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.76"
|
|
8
8
|
description = "Drop-in replacement for python-pptx that connects to PPTX Studio for real-time collaboration"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|