athena-python-pptx 0.16.0__tar.gz → 0.17.0__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.16.0 → athena_python_pptx-0.17.0}/AGENTS.md +29 -2
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/API_PARITY_REPORT.md +1 -1
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/CHANGELOG.md +140 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/PKG-INFO +2 -1
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/docs/API_PARITY_EXCEPTIONS.md +355 -8
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/__init__.py +2 -2
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/_unsupported.py +85 -43
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/batching.py +179 -4
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/client.py +13 -11
- athena_python_pptx-0.17.0/pptx/oxml/__init__.py +114 -0
- athena_python_pptx-0.17.0/pptx/oxml/_mirror.py +471 -0
- athena_python_pptx-0.17.0/pptx/oxml/_tbl.py +1152 -0
- athena_python_pptx-0.17.0/pptx/oxml/_txbody.py +1782 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/oxml/ns.py +8 -0
- athena_python_pptx-0.17.0/pptx/oxml/presentation.py +378 -0
- athena_python_pptx-0.17.0/pptx/oxml/shapes/__init__.py +68 -0
- athena_python_pptx-0.17.0/pptx/oxml/shapes/autoshape.py +32 -0
- athena_python_pptx-0.17.0/pptx/oxml/shapes/connector.py +31 -0
- athena_python_pptx-0.17.0/pptx/oxml/shapes/graphfrm.py +32 -0
- athena_python_pptx-0.17.0/pptx/oxml/shapes/groupshape.py +402 -0
- athena_python_pptx-0.17.0/pptx/oxml/shapes/picture.py +31 -0
- athena_python_pptx-0.17.0/pptx/oxml/shapes/shared.py +871 -0
- athena_python_pptx-0.17.0/pptx/oxml/simpletypes.py +727 -0
- athena_python_pptx-0.17.0/pptx/oxml/table.py +583 -0
- athena_python_pptx-0.17.0/pptx/oxml/text.py +652 -0
- athena_python_pptx-0.17.0/pptx/oxml/xmlchemy.py +716 -0
- athena_python_pptx-0.17.0/pptx/parts/presentation.py +54 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/presentation.py +65 -15
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/shapes/__init__.py +837 -84
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/slides.py +69 -4
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/text/__init__.py +169 -2
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/units.py +6 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pyproject.toml +5 -1
- athena_python_pptx-0.16.0/pptx/oxml/__init__.py +0 -43
- athena_python_pptx-0.16.0/pptx/parts/presentation.py +0 -15
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/.gitignore +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/CLAUDE.md +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/DEV-GUIDE.md +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/PARITY_QUESTIONS.md +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/README.md +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/docs/athena-api.json +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/docs/athena-api.md +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/_athena_extension.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/_citations.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/_ptc.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/_references.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/action.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/chart/__init__.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/chart/axis.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/chart/category.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/chart/chart.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/chart/data.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/chart/datalabel.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/chart/legend.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/chart/marker.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/chart/plot.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/chart/point.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/chart/series.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/chart/xlsx.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/commands.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/decorators.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/dml/__init__.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/dml/chtfmt.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/dml/color.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/dml/effect.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/dml/fill.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/dml/line.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/docgen.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/enum/__init__.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/enum/action.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/enum/chart.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/enum/dml.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/enum/lang.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/enum/shapes.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/enum/text.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/errors.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/exc.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/generated/__init__.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/generated/autoshape_types.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/kit.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/media.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/package.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/parts/__init__.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/parts/_base.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/parts/chart.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/parts/coreprops.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/parts/embeddedpackage.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/parts/image.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/parts/media.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/parts/slide.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/shapes/autoshape.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/shapes/base.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/shapes/connector.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/shapes/freeform.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/shapes/graphfrm.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/shapes/group.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/shapes/picture.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/shapes/placeholder.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/shapes/shapetree.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/shared.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/slide.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/spec.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/table.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/text/fonts.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/text/layout.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/text/text.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/types.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/typing.py +0 -0
- {athena_python_pptx-0.16.0 → athena_python_pptx-0.17.0}/pptx/util.py +0 -0
|
@@ -69,7 +69,8 @@ A small number of REST-SDK-specific departures are documented in
|
|
|
69
69
|
|
|
70
70
|
These standard python-pptx members are omitted because a REST SDK has no
|
|
71
71
|
local XML / OPC parts:
|
|
72
|
-
- `Shape.
|
|
72
|
+
- `Shape.part` — package part access. (`Shape.element` is implemented: the
|
|
73
|
+
shape's element, for python-pptx's shape-tree recipes; see Architecture.)
|
|
73
74
|
- `TextFrame.part`, `Paragraph.part`, `Run.part` — package part access.
|
|
74
75
|
- `FillFormat.from_fill_parent()`, `ColorFormat.from_colorchoice_parent()` — internal XML constructors.
|
|
75
76
|
- `Font.fill` — Font fill format (uncommon; use `font.color` for text color).
|
|
@@ -119,7 +120,33 @@ install fails the parity tests rather than skipping them.
|
|
|
119
120
|
|
|
120
121
|
This is a **REST API client** that mimics the python-pptx API. Instead of manipulating XML directly, method calls are translated to commands sent to the PPTX Studio API server. Key differences from python-pptx internals:
|
|
121
122
|
|
|
122
|
-
- No
|
|
123
|
+
- No local OOXML package. python-pptx's private XML attributes (`_tbl`,
|
|
124
|
+
`_tc`, `series._element`, ...) raise `UnsupportedAttributeError` naming the
|
|
125
|
+
supported API (`pptx/_unsupported.py`), except where common recipes map onto
|
|
126
|
+
commands. Those edits are held until complete
|
|
127
|
+
(`CommandBuffer.hold_pending_edit`):
|
|
128
|
+
- `prs.slides._sldIdLst` and `prs.part.drop_rel()` for slide delete and move
|
|
129
|
+
(`pptx/oxml/presentation.py`, tests in `tests/test_sldidlst_compat.py`);
|
|
130
|
+
- `shape._element` / `shape.element` (with `_sp`, `_pic`, `_graphicFrame`,
|
|
131
|
+
`_grpSp`) and `slide.shapes._spTree` for shape delete, z-order and
|
|
132
|
+
duplicate, sent as `DeleteShape`, `SetShapeZOrder` and `CloneShape`
|
|
133
|
+
(`pptx/oxml/shapes/`, tests in `tests/test_shape_element_compat.py`);
|
|
134
|
+
- a shape's text: `text_frame._txBody` / `_bodyPr`, `paragraph._p`,
|
|
135
|
+
`run._r` and `font._rPr` are real lxml elements of python-pptx's classes
|
|
136
|
+
(`pptx/oxml/text.py` on the ported `xmlchemy` / `simpletypes`), a mirror of
|
|
137
|
+
the deck that is diffed into the public API's commands when the change
|
|
138
|
+
resolves. `pptx/oxml/_mirror.py` holds the reusable lifecycle (hold,
|
|
139
|
+
resolve, in-place re-sync, late edits, the access hooks that resolve before
|
|
140
|
+
a public call), `pptx/oxml/_txbody.py` the text translation; tests in
|
|
141
|
+
`tests/test_text_xml_compat.py`. A change no command carries raises
|
|
142
|
+
naming the XML path; never drop one silently.
|
|
143
|
+
- a table: `table._tbl`, `cell._tc`, `row._tr` and `column._gridCol`
|
|
144
|
+
(`pptx/oxml/table.py`), the same kind of mirror (`pptx/oxml/_tbl.py`):
|
|
145
|
+
cell borders, margins, anchor and fill, row heights, column widths, the
|
|
146
|
+
look flags, and row / column removal. It captures rows by their
|
|
147
|
+
serialization and re-syncs only the cells an API write touched, so a
|
|
148
|
+
recipe that walks a large table cell by cell stays linear; tests in
|
|
149
|
+
`tests/test_table_xml_compat.py`.
|
|
123
150
|
- Operations are batched via `with prs.batch():` context manager
|
|
124
151
|
- State is synchronized via the PPTX Studio collaboration layer (Yjs)
|
|
125
152
|
- **Programmatic Tool Calling (PTC):** every `CommandBuffer.add` and
|
|
@@ -91,7 +91,7 @@ via Tranches R–W:
|
|
|
91
91
|
| SlideLayout | PASS (+`index`) |
|
|
92
92
|
| SlideMaster | PASS |
|
|
93
93
|
| SlideShapes | PASS (+SDK REST helpers; `add_connector` accepts optional `begin_shape`/`end_shape`) |
|
|
94
|
-
| Table | PASS (+SDK REST helpers + inherited `Shape.element`
|
|
94
|
+
| Table | PASS (+SDK REST helpers + inherited `Shape.element`, its frame's `p:graphicFrame` element) |
|
|
95
95
|
| `_Cell` | PASS (+SDK REST helpers) |
|
|
96
96
|
| PlaceholderFormat | PASS (+convenience type-check booleans + custom-prompt/transform fields) |
|
|
97
97
|
| Chart | PASS (`category_axis` / `value_axis` / `legend` / `font` / `chart_style` added in v0.1.68; replaces `UnsupportedFeatureError` stubs) |
|
|
@@ -2,6 +2,146 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `athena-python-pptx` are documented in this file.
|
|
4
4
|
|
|
5
|
+
## 0.17.0
|
|
6
|
+
|
|
7
|
+
- python-pptx's slide delete and move recipes work. They edit
|
|
8
|
+
`prs.slides._sldIdLst`, which raised `UnsupportedAttributeError`; it is now
|
|
9
|
+
python-pptx's `p:sldIdLst` (`pptx.oxml.presentation.CT_SlideIdList`):
|
|
10
|
+
- `xml_slides.remove(entry)` (or `del xml_slides[i]`) deletes the slide;
|
|
11
|
+
- re-inserting it (`insert`, `append`, `addnext`, `addprevious`) moves it
|
|
12
|
+
instead, and inserting a slide that is still in the list moves it, as
|
|
13
|
+
lxml does;
|
|
14
|
+
- `prs.part.drop_rel(entry.rId)` then `del` deletes the slide once;
|
|
15
|
+
- an entry's `id` is its slide's `slide_id`, as in python-pptx, so the
|
|
16
|
+
recipe that finds a slide's entry by comparing the two works.
|
|
17
|
+
|
|
18
|
+
Edits are held until the change is complete, then sent as deletes and one
|
|
19
|
+
reorder, so a move never deletes its slide first and "remove every slide,
|
|
20
|
+
then append them in a new order" is a single reorder. Anything that reads
|
|
21
|
+
slide positions sends an open change first (the next command, `prs.slides`,
|
|
22
|
+
a slide's index, a flush, a refresh, a `batch()` or `with prs:` block), so
|
|
23
|
+
later commands address slides by their new positions; a block that raises
|
|
24
|
+
drops the edits made inside it. The bulk-delete guard applies. Other lxml
|
|
25
|
+
members, and other OPC members of `prs.part`, raise naming the supported
|
|
26
|
+
API.
|
|
27
|
+
- A slide proxy held from before its slide was deleted (`prs.slides.delete`
|
|
28
|
+
or the recipes above) raises `ConflictError` on an edit. It wrote to the
|
|
29
|
+
slide that had taken its position.
|
|
30
|
+
- python-pptx's shape delete, z-order and duplicate recipes work.
|
|
31
|
+
`shape._element` and python-pptx's public `shape.element` (both raised or
|
|
32
|
+
answered with a delete-only proxy) are the shape's element, with python-pptx's
|
|
33
|
+
`_sp`, `_pic`, `_graphicFrame` and `_grpSp` aliases, and
|
|
34
|
+
`slide.shapes._spTree` is the slide's shape tree (`pptx.oxml.shapes`:
|
|
35
|
+
`CT_Shape`, `CT_Picture`, `CT_GraphicalObjectFrame`, `CT_Connector`,
|
|
36
|
+
`CT_GroupShape`). As in python-pptx, `group.shapes._spTree` is the group's
|
|
37
|
+
element and the tree holds `p:nvGrpSpPr` and `p:grpSpPr` first.
|
|
38
|
+
- `sp.getparent().remove(sp)` (or `spTree.remove(el)`, `del spTree[i]`)
|
|
39
|
+
deletes the shape or placeholder;
|
|
40
|
+
- putting it back (`insert`, `append`, `addnext`, `addprevious`), or
|
|
41
|
+
inserting a shape that is still in the tree, moves it, as lxml does, sent
|
|
42
|
+
as the fewest `SetShapeZOrder` steps that give exactly the new order:
|
|
43
|
+
`spTree.insert(2, el)` sends it to the back;
|
|
44
|
+
- inserting `copy.deepcopy(shape._element)` into any slide's tree clones the
|
|
45
|
+
shape there in place (`CloneShape` with no offset), and a copy never
|
|
46
|
+
inserted sends nothing.
|
|
47
|
+
|
|
48
|
+
Edits are held until the change is complete, as for `_sldIdLst`, so a move
|
|
49
|
+
never deletes its shape; the next command, a flush or refresh, and reading
|
|
50
|
+
`slide.shapes` send them (clones, then deletes, then z-order). An element's
|
|
51
|
+
tag, parent and siblings, and its `p:cNvPr` id and name, read as in
|
|
52
|
+
python-pptx. Other lxml members, property-level XML (`spPr`, `txBody`),
|
|
53
|
+
moving a shape to another slide or group, and copies changed after
|
|
54
|
+
`deepcopy()` raise naming the supported API.
|
|
55
|
+
- A held XML-recipe change that completes sends its commands without forcing
|
|
56
|
+
the other held change, so a shape move made during a slide move no longer
|
|
57
|
+
turns the slide's removal into a delete, and a clone lands on the slide it
|
|
58
|
+
named.
|
|
59
|
+
- A group member's `bring_to_front()` / `send_to_back()` / `bring_forward()` /
|
|
60
|
+
`send_backward()` and `delete()` update `group.shapes`, which kept the old
|
|
61
|
+
order and the deleted member until a refresh.
|
|
62
|
+
- python-pptx's text XML recipes work: bullets on and off, numbered lists,
|
|
63
|
+
hanging indents, superscript, letter spacing, line spacing and autofit
|
|
64
|
+
through XML. `text_frame._txBody` / `_bodyPr`, `paragraph._p` / `_pPr` /
|
|
65
|
+
`_defRPr`, `run._r` / `_rPr` and `font._rPr` raised
|
|
66
|
+
`UnsupportedAttributeError`; they are now real lxml elements of
|
|
67
|
+
python-pptx's classes (`pptx.oxml.text`), one tree per text frame built from
|
|
68
|
+
the deck, with python-pptx's helpers (`get_or_add_pPr()`,
|
|
69
|
+
`insert_element_before()`, `pPr.lvl`, ...). What a recipe changes is sent
|
|
70
|
+
through the public API's setters:
|
|
71
|
+
- `a:pPr` as `SetParagraphStyle` (indents, level, alignment, spacing, bullet
|
|
72
|
+
color and the `•` / `◦` / `▪`, `a:buNone` and `arabicPeriod` bullets),
|
|
73
|
+
its `a:defRPr` as `paragraph.font`;
|
|
74
|
+
- `a:rPr` as `SetRunStyle` (bold, italic, underline, size, strike,
|
|
75
|
+
baseline, caps, spacing, language, color, highlight, typeface);
|
|
76
|
+
- `a:bodyPr` as `SetTextFrameProperties` (wrap, anchor, insets, autofit);
|
|
77
|
+
- run text, appended runs, breaks and paragraphs, and trailing removals
|
|
78
|
+
through the existing text commands.
|
|
79
|
+
|
|
80
|
+
The change is sent before the next command, explicit flush, refresh or API
|
|
81
|
+
call on that text (never by the idle timer), so a later API write wins and
|
|
82
|
+
reads see the edit; like `_sldIdLst`'s, a `prs.batch()` or `with prs:` block
|
|
83
|
+
that raises drops the changes made inside it. Requested again, the tree shows
|
|
84
|
+
the deck's state in place. Anything no command carries raises
|
|
85
|
+
`UnsupportedAttributeError` naming the XML path and the supported API, and
|
|
86
|
+
is dropped. `pptx.oxml.parse_xml` and `pptx.oxml.xmlchemy.OxmlElement` build
|
|
87
|
+
real elements instead of raising. `lxml` is now a dependency.
|
|
88
|
+
- `str()` of a length (`Emu`, `Pt`, ...) and f-strings give the EMU integer, as
|
|
89
|
+
in python-pptx, so `pPr.set("marL", str(Emu(Pt(18))))` writes `"228600"`
|
|
90
|
+
(it wrote `"Emu(228600)"`); `repr()` is unchanged.
|
|
91
|
+
- A run's color writes merged into one command drop an earlier brightness the
|
|
92
|
+
later write does not set, as the studio does when it applies them one by
|
|
93
|
+
one: `font.color.brightness = 0.4` then `font.color.brightness = 0` (or a
|
|
94
|
+
new `theme_color`) sent the 0.4.
|
|
95
|
+
- python-pptx's table XML recipes work: cell borders, row heights, column
|
|
96
|
+
widths, the look flags, a cell's margins, anchor and fill through XML, and
|
|
97
|
+
the row and column delete recipes. `table._tbl`, `cell._tc`, `row._tr` and
|
|
98
|
+
`column._gridCol` raised `UnsupportedAttributeError`; they are now real lxml
|
|
99
|
+
elements of python-pptx's classes (`pptx.oxml.table`), one tree per table
|
|
100
|
+
built from the deck. What a recipe changes is sent through the public API's
|
|
101
|
+
setters:
|
|
102
|
+
- a cell's `a:lnL` / `a:lnR` / `a:lnT` / `a:lnB` as one `SetCellBorders`
|
|
103
|
+
(`w`, an RGB or no line, the dash), which `cell.border_*` then reads (a
|
|
104
|
+
later `width` or `dash_style` write keeps the no line or theme color);
|
|
105
|
+
- `marL` / `marR` / `marT` / `marB` as `SetCellMargins`, `anchor` as
|
|
106
|
+
`SetCellAnchor`, an RGB `a:solidFill` or `a:noFill` as `SetTableCell`;
|
|
107
|
+
- `a:tr/@h` as `SetRowHeight`, `a:gridCol/@w` as `SetColWidth`, the
|
|
108
|
+
`a:tblPr` flags as one `SetTableLook`;
|
|
109
|
+
- a removed `a:tr` as `DeleteTableRow`, a removed column (its `a:gridCol`
|
|
110
|
+
and its `a:tc` in every row) as `DeleteTableColumn`.
|
|
111
|
+
|
|
112
|
+
The studio cannot change an existing table's style, so an edit to
|
|
113
|
+
`a:tableStyleId` raises `UnsupportedAttributeError` naming what can change;
|
|
114
|
+
so do merges, a cell's text, rows or columns added through XML and the
|
|
115
|
+
other properties no command carries. A border's `cap` is ignored with a
|
|
116
|
+
warning. Walking the table (`table.cell(r, c)`, `row.cells`) does not send a
|
|
117
|
+
pending change, so a recipe that edits every cell sends its edits together.
|
|
118
|
+
- `table.delete_row(i)` / `table.delete_column(i)` drop the row's height (the
|
|
119
|
+
column's width) locally, as the server does: the rows below kept reading
|
|
120
|
+
the height of the row after them.
|
|
121
|
+
- A row or column proxy (`table.rows[i]`, `table.columns[i]`) kept across
|
|
122
|
+
rows or columns inserted or removed before it keeps meaning its own row or
|
|
123
|
+
column, as python-pptx's does: it read and wrote the one that took its
|
|
124
|
+
index. One whose row or column was removed raises `IndexError`.
|
|
125
|
+
- A chart data label's `text_frame` has python-pptx's `paragraphs`: one
|
|
126
|
+
paragraph over the label's text whose runs and font are the label's, so
|
|
127
|
+
`point.data_label.text_frame.paragraphs[0].runs[0].font.bold = True` and
|
|
128
|
+
`paragraphs[0].text = ...` work. `paragraphs` raised `AttributeError`.
|
|
129
|
+
- Table cell text frames have python-pptx's `vertical_anchor` and margins
|
|
130
|
+
(they write the cell's own), and `word_wrap` / `auto_size`; cell paragraphs
|
|
131
|
+
have `line_spacing`, `space_before`, `space_after` and `level`. A
|
|
132
|
+
one-paragraph cell cannot apply those last members, so a write warns once
|
|
133
|
+
per presentation and keeps the value for read-after-write, instead of
|
|
134
|
+
raising `AttributeError`, which production scripts hit. An uploaded cell's
|
|
135
|
+
paragraph reads its own level and spacing (`a:pPr`), as python-pptx does.
|
|
136
|
+
|
|
137
|
+
## 0.16.1 — `Presentation.upload()` and `create(pptx=...)` report the deck they create
|
|
138
|
+
|
|
139
|
+
- `Presentation.upload()` emits the `CreatePresentation` tool-call event with
|
|
140
|
+
the new deck's id, as `Presentation.create()` and the docx and xlsx uploads
|
|
141
|
+
do. It emitted nothing, so a deck uploaded from sandbox code, including one
|
|
142
|
+
seeded from a brand template with `Presentation.create(pptx=...)`, showed no
|
|
143
|
+
creation card and never joined the Athena session's created assets.
|
|
144
|
+
|
|
5
145
|
## 0.16.0 — `Presentation.create()` makes 13.333" × 7.5" decks; `create(name=, title=)` titles the deck
|
|
6
146
|
|
|
7
147
|
- **Behaviour change:** `Presentation.create()` makes a deck at PowerPoint's
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: athena-python-pptx
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.17.0
|
|
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
|
|
@@ -22,6 +22,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
22
22
|
Classifier: Typing :: Typed
|
|
23
23
|
Requires-Python: >=3.10
|
|
24
24
|
Requires-Dist: athena-references>=0.1.0
|
|
25
|
+
Requires-Dist: lxml>=4.9.0
|
|
25
26
|
Requires-Dist: requests>=2.28.0
|
|
26
27
|
Provides-Extra: dev
|
|
27
28
|
Requires-Dist: mypy>=1.0; extra == 'dev'
|