@office-kit/pptx 0.23.0 → 0.24.0
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.
- package/CHANGELOG.md +253 -151
- package/README.md +136 -78
- package/THIRD_PARTY_NOTICES.md +291 -0
- package/dist/{api-BgUbq_WA.js → api-BNwRBemN.js} +6784 -2084
- package/dist/api-BNwRBemN.js.map +1 -0
- package/dist/{index-C8dd42jQ.d.ts → index-WCK8v0WT.d.ts} +1278 -353
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/node.d.ts +2 -2
- package/dist/node.js +2 -2
- package/package.json +2 -2
- package/dist/api-BgUbq_WA.js.map +0 -1
package/README.md
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
[](https://github.com/office-kit/pptx/actions/workflows/ci.yml)
|
|
5
5
|
[](./LICENSE)
|
|
6
6
|
|
|
7
|
-
Read, edit, and write `.pptx` (
|
|
8
|
-
|
|
7
|
+
Read, edit, and write `.pptx` (Office Open XML Presentation) files from
|
|
8
|
+
TypeScript, in **Node.js and the browser**, from a single ESM bundle.
|
|
9
9
|
|
|
10
10
|
**[Create slides with AI](#create-slides-with-ai-and-live-preview)** ·
|
|
11
11
|
**[Documentation](https://office-kit.github.io/pptx/)** ·
|
|
@@ -15,7 +15,7 @@ from TypeScript, in **Node.js and the browser**, from a single ESM bundle.
|
|
|
15
15
|
```ts
|
|
16
16
|
import { loadPresentation, replaceTokensInPresentation, savePresentation } from '@office-kit/pptx';
|
|
17
17
|
|
|
18
|
-
// A designer makes template.pptx in
|
|
18
|
+
// A designer makes template.pptx in a presentation app. Your code fills it in.
|
|
19
19
|
const pres = await loadPresentation(templateBytes);
|
|
20
20
|
replaceTokensInPresentation(pres, { name: 'Alice', event: 'Re:Invent', date: '2026-12-01' });
|
|
21
21
|
const out: Uint8Array = await savePresentation(pres);
|
|
@@ -31,7 +31,7 @@ const out: Uint8Array = await savePresentation(pres);
|
|
|
31
31
|
|
|
32
32
|
Create presentations in TSX with a live browser preview and Claude Code or Codex
|
|
33
33
|
beside the slide. Select an area and ask the agent to change it, edit text
|
|
34
|
-
directly, and export an editable
|
|
34
|
+
directly, and export an editable `.pptx` file. Changes are saved in the TSX
|
|
35
35
|
source; saving a source file also updates the preview.
|
|
36
36
|
|
|
37
37
|
Requires Node.js 22.18 or later. Create a project and start the preview in one
|
|
@@ -70,16 +70,16 @@ project setup as well, follow the
|
|
|
70
70
|
|
|
71
71
|
## Why this library
|
|
72
72
|
|
|
73
|
-
- **It reads as well as it writes.** Open a deck made in
|
|
74
|
-
or
|
|
73
|
+
- **It reads as well as it writes.** Open a deck made in Keynote, Google Slides
|
|
74
|
+
or any other presentation app, change it, and save it. Every setter has a getter, and
|
|
75
75
|
there are deck-wide queries (find every hyperlink, every comment by an
|
|
76
76
|
author, every slide with an empty title).
|
|
77
77
|
- **Parts it does not model survive the round trip.** SmartArt, OLE objects,
|
|
78
78
|
video, modern threaded comments, and vendor extensions are carried through
|
|
79
79
|
untouched. The library never silently strips what it does not understand.
|
|
80
|
-
- **The output is valid, not "valid enough".**
|
|
81
|
-
`OpenXmlValidator` gates every CI run. A file that opens in
|
|
82
|
-
breaks Keynote is treated as a bug.
|
|
80
|
+
- **The output is valid, not "valid enough".** The Open XML SDK's
|
|
81
|
+
`OpenXmlValidator` gates every CI run. A file that opens in one presentation
|
|
82
|
+
app but breaks Keynote is treated as a bug.
|
|
83
83
|
- **One ESM bundle for Node and the browser.** No `fs`, `Buffer`, or `zlib` on
|
|
84
84
|
the hot path, and one runtime dependency ([fflate](https://github.com/101arrowz/fflate), for ZIP).
|
|
85
85
|
- **You ship only what you import.** The API uses side-effect-free functions.
|
|
@@ -101,19 +101,19 @@ Compared against PptxGenJS 4.0.1:
|
|
|
101
101
|
| | `@office-kit/pptx` | PptxGenJS |
|
|
102
102
|
| --------------------------------- | --------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
|
|
103
103
|
| Open and edit an existing `.pptx` | ✅ Load, change, save; unknown parts are preserved | ❌ Creates new files only |
|
|
104
|
-
| Templates | Any `.pptx` a designer made in
|
|
104
|
+
| Templates | Any `.pptx` a designer made in a presentation app | Slide masters defined in code (`defineSlideMaster`) |
|
|
105
105
|
| Read back what is in a deck | ✅ Every setter has a getter, plus deck-wide queries | ❌ The API is write-only |
|
|
106
106
|
| API shape | Tree-shakeable functions (`addSlideChart(slide, …)`) | One class with methods (`slide.addChart(…)`) |
|
|
107
107
|
| Module formats | ESM only | ESM, CommonJS, and a script-tag bundle |
|
|
108
108
|
| Runtime dependencies | 1 (`fflate`) | 4 (`jszip`, `image-size`, `https`, `@types/node`) |
|
|
109
109
|
| Slide transitions | ✅ | ❌ |
|
|
110
|
-
| Animations | ✅
|
|
110
|
+
| Animations | ✅ All 95 gallery presets | ❌ |
|
|
111
111
|
| Comments | ✅ | ❌ (speaker notes only) |
|
|
112
112
|
| Chart types you can author | ✅ All 16 ECMA-376 plot types, incl. 3-D, stock, surface, pie-of-pie; combos, error bars, data table, date axis | Bar, line, area, pie, doughnut, scatter, bubble, radar, 3-D bar / bubble; combos |
|
|
113
113
|
| Audio, video, YouTube embeds | ✅ Embedded from bytes (Node and browser), with read-back (`getShapeMedia`); clips de-duplicated per deck | ✅ From a path or base64; write-only |
|
|
114
114
|
| HTML `<table>` to slides | ❌ | ✅ With automatic paging |
|
|
115
115
|
| Render a slide to an image | ✅ SVG and PNG, via [`@office-kit/pptx-preview`](packages/preview) | ❌ |
|
|
116
|
-
| How output is checked | Open XML SDK validator and ECMA-376 XSDs, in CI | Manual runs in
|
|
116
|
+
| How output is checked | Open XML SDK validator and ECMA-376 XSDs, in CI | Manual runs in presentation apps before a release |
|
|
117
117
|
|
|
118
118
|
**Pick PptxGenJS** if you only ever generate new decks and need HTML-table
|
|
119
119
|
import, CommonJS, or a `<script>`-tag build.
|
|
@@ -210,12 +210,12 @@ run `npx --no-install office-pptx build deck.tsx --out out.pptx`.
|
|
|
210
210
|
|
|
211
211
|
The core API uses explicit units (`inches(1)`, `cm(2.5)`, `pt(12)`). The DSL uses
|
|
212
212
|
inches for numeric geometry and points for font sizes, and compiles to the same
|
|
213
|
-
core model. Both produce editable
|
|
213
|
+
core model. Both produce editable native text and charts.
|
|
214
214
|
|
|
215
215
|
## How output is checked
|
|
216
216
|
|
|
217
|
-
- **Open XML SDK.** A CI job generates the sample decks and runs
|
|
218
|
-
`OpenXmlValidator` over them (`tools/ooxml-validate`). Any validation error
|
|
217
|
+
- **Open XML SDK.** A CI job generates the sample decks and runs the Open XML
|
|
218
|
+
SDK's `OpenXmlValidator` over them (`tools/ooxml-validate`). Any validation error
|
|
219
219
|
fails the build.
|
|
220
220
|
- **ECMA-376 XSDs.** Emitted XML is validated against the official schemas
|
|
221
221
|
with `xmllint` in the test suite (these tests skip on a machine without
|
|
@@ -260,7 +260,7 @@ When NOT to use this:
|
|
|
260
260
|
SVG in the browser and to PNG on the server, and its closeness to LibreOffice
|
|
261
261
|
is measured per slide and gated in CI (`site/fidelity`). It is a
|
|
262
262
|
high-fidelity preview, not a spec-complete paint engine. For
|
|
263
|
-
pixel-authoritative output, use
|
|
263
|
+
pixel-authoritative output, use a desktop presentation app itself or LibreOffice headless.
|
|
264
264
|
- You only generate new decks and need a feature in the PptxGenJS column
|
|
265
265
|
above. Use PptxGenJS.
|
|
266
266
|
- You want to convert PPTX to another format (Keynote, ODP). Out of scope
|
|
@@ -276,6 +276,16 @@ pnpm add @office-kit/pptx
|
|
|
276
276
|
yarn add @office-kit/pptx
|
|
277
277
|
```
|
|
278
278
|
|
|
279
|
+
## Packages
|
|
280
|
+
|
|
281
|
+
| Package | What it does |
|
|
282
|
+
| ---------------------------------------------- | ------------------------------------------------------------------------------ |
|
|
283
|
+
| `@office-kit/pptx` (this directory) | Read, edit and write `.pptx` files. Node and browser. |
|
|
284
|
+
| [`@office-kit/pptx-preview`](packages/preview) | Render a slide to SVG (browser and Node) or PNG (Node). |
|
|
285
|
+
| [`@office-kit/pptx-dsl`](packages/dsl) | Write a presentation as typed TSX. |
|
|
286
|
+
| [`@office-kit/pptx-editor`](packages/editor) | Embed a desktop-style slide editor in your web application with `mountEditor`. |
|
|
287
|
+
| [`@office-kit/pptx-dev`](packages/dev) | Preview, edit and export a TSX presentation locally. |
|
|
288
|
+
|
|
279
289
|
## One API
|
|
280
290
|
|
|
281
291
|
@office-kit/pptx exposes a single tree-shakeable free-function API. Every
|
|
@@ -370,7 +380,7 @@ const out = await savePresentation(pres);
|
|
|
370
380
|
### Build a deck from scratch (no template file)
|
|
371
381
|
|
|
372
382
|
`createPresentation()` returns an immediately-authorable deck — a slide
|
|
373
|
-
master,
|
|
383
|
+
master, a default theme, and three layouts (`Blank`, `Title Slide`,
|
|
374
384
|
`Title and Content`) — with no slides yet. No `.pptx` template needed.
|
|
375
385
|
|
|
376
386
|
```ts
|
|
@@ -394,7 +404,7 @@ addContentSlide(pres, { title: 'Agenda', body: 'Highlights and risks' });
|
|
|
394
404
|
|
|
395
405
|
// Or bind a layout explicitly. Prefer findSlideLayoutByType — it matches
|
|
396
406
|
// the `type` token (`'title'`, `'obj'`, `'blank'`), which is stable
|
|
397
|
-
// across
|
|
407
|
+
// across the reference desktop app's UI languages. findSlideLayout(pres, 'Blank') matches
|
|
398
408
|
// the user-visible name, which is case-sensitive and localized.
|
|
399
409
|
const titleLayout = findSlideLayoutByType(pres, 'title')!;
|
|
400
410
|
const slide = addSlide(pres, { layout: titleLayout });
|
|
@@ -553,7 +563,7 @@ addSlideChart(slide!, {
|
|
|
553
563
|
await savePresentation(pres);
|
|
554
564
|
```
|
|
555
565
|
|
|
556
|
-
The embedded xlsx that
|
|
566
|
+
The embedded xlsx that the reference desktop app requires for "Edit data" is generated
|
|
557
567
|
automatically. Inline `<c:strCache>` / `<c:numCache>` caches mean the
|
|
558
568
|
chart renders without opening the workbook.
|
|
559
569
|
|
|
@@ -565,9 +575,53 @@ import { setShapeAnimation, getSlideShapes, getSlides } from '@office-kit/pptx';
|
|
|
565
575
|
const slide = getSlides(pres)[0]!;
|
|
566
576
|
const shape = getSlideShapes(slide)[0]!;
|
|
567
577
|
setShapeAnimation(shape, { effect: 'fadeIn', durationMs: 800 });
|
|
568
|
-
|
|
578
|
+
setShapeAnimation(shape, { effect: 'flyIn', direction: 'topLeft', start: 'afterPrevious' });
|
|
579
|
+
setShapeAnimation(shape, { effect: 'shapeOut', shape: 'diamond', inOut: 'out' });
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
All 95 presets of the reference desktop app's Entrance (35), Emphasis (24) and Exit (36)
|
|
583
|
+
galleries are written exactly as the reference desktop app writes them: the same preset
|
|
584
|
+
numbers, behaviours, default duration and build entry. Entrances end in `In`
|
|
585
|
+
and exits in `Out` (`flyIn` / `flyOut`, `basicZoomIn`, `growTurnIn` /
|
|
586
|
+
`shrinkTurnOut`, `creditsIn`, …), except `appear` / `disappear`; emphasis
|
|
587
|
+
effects have plain names (`spin`, `pulse`, `darken`, `fillColor`, `wave`, …).
|
|
588
|
+
`zoomIn` / `zoomOut` are the Subtle gallery's Zoom (preset 53), and
|
|
589
|
+
`basicZoomIn` / `basicZoomOut` are Basic Zoom (preset 23).
|
|
590
|
+
|
|
591
|
+
Options are the ones the reference desktop app's Effect Options offer: `direction` for `fly…`
|
|
592
|
+
(eight), `wipe…` / `peek…` (four edges) and `strips…` (four corners);
|
|
593
|
+
`orientation` for `blinds…`, `checkerboard…`, `randomBars…`; `orientation` and
|
|
594
|
+
`inOut` for `split…`; `shape` and `inOut` for `shape…`; `spokes` for `wheel…`;
|
|
595
|
+
`spinDirection` and `spinDegrees` for `spin`; `scaleDirection` and
|
|
596
|
+
`scalePercent` for `growShrink`; `transparencyPercent` for `transparency`; and
|
|
597
|
+
`color` (a theme slot or `#RRGGBB`, optionally with colour transforms) for the
|
|
598
|
+
colour emphasis effects. `getSlideAnimations` reads every option back.
|
|
599
|
+
`durationMs` rescales every behaviour of the effect together, the way
|
|
600
|
+
the reference desktop app's Duration box does; `updateSlideAnimation` with a new `effect`
|
|
601
|
+
gives it that preset's default duration unless the patch states one. `build` is the Sequence option for text:
|
|
602
|
+
`'asOneObject'` (the default), `'allAtOnce'` or `'byParagraph'`.
|
|
603
|
+
|
|
604
|
+
### Transitions
|
|
605
|
+
|
|
606
|
+
```ts
|
|
607
|
+
import { getSlides, setSlideTransition } from '@office-kit/pptx';
|
|
608
|
+
|
|
609
|
+
const slide = getSlides(pres)[0]!;
|
|
610
|
+
setSlideTransition(slide, { effect: 'push', direction: 'u', durationMs: 1000 });
|
|
611
|
+
setSlideTransition(slide, { effect: 'vortex', direction: 'r' }); // a 2010+ extension effect
|
|
612
|
+
setSlideTransition(slide, { effect: 'prstTrans', preset: 'curtains' });
|
|
613
|
+
setSlideTransition(slide, { effect: 'morph', morphOption: 'byWord' });
|
|
569
614
|
```
|
|
570
615
|
|
|
616
|
+
The ECMA-376 effects are written as `<p:…>` elements. The 2010+ extension
|
|
617
|
+
effects (`vortex`, `ripple`, `honeycomb`, `prism`, `doors`, `window`, `ferris`,
|
|
618
|
+
`gallery`, `conveyor`, `pan`, `glitter`, `warp`, `flythrough`, `flash`,
|
|
619
|
+
`shred`, `reveal`, `switch`, `flip`, `wheelReverse`), the `prstTrans` presets
|
|
620
|
+
and `morph` are written the way the reference desktop app writes them: inside
|
|
621
|
+
`mc:AlternateContent`, with a `<p:fade/>` fallback for readers that do not
|
|
622
|
+
know them. Their options are `pattern`, `isContent`, `isInverted`,
|
|
623
|
+
`hasBounce`, `preset`, `invertX`, `invertY` and `morphOption`.
|
|
624
|
+
|
|
571
625
|
### Comments
|
|
572
626
|
|
|
573
627
|
```ts
|
|
@@ -651,47 +705,50 @@ handles preserved. Every layout must belong to the presentation.
|
|
|
651
705
|
Each row lists the free-function entry points. Read/write pairs are
|
|
652
706
|
shown together.
|
|
653
707
|
|
|
654
|
-
| Capability | API
|
|
655
|
-
| --------------------------------------------------------------------- |
|
|
656
|
-
| Load / save | `loadPresentation(input)`, `savePresentation(pres)`, `loadPresentationFile(path)` (node), `savePresentationToFile(pres, path)` (node)
|
|
657
|
-
| Create | `createPresentation({ size?: '16:9' \| '4:3' })` — blank deck with master + theme + `Blank` / `Title Slide` / `Title and Content` layouts
|
|
658
|
-
| Slide CRUD | `getSlides`, `getSlideAt`, `getSlideIndex`, `addSlide`, `removeSlide`, `moveSlide`, `duplicateSlide`, `clearSlideShapes`
|
|
659
|
-
| Slide layout | `getSlideLayouts`, `findSlideLayout` (by name — case-sensitive, exact; pass a `RegExp` for case-insensitive), `findSlideLayoutByType` (by locale-stable `type` token — preferred), `getSlideLayout(slide)`, `setSlideLayout(slide, layout)`, `getSlideLayoutName`, `getSlideLayoutType`
|
|
660
|
-
| Slide
|
|
661
|
-
|
|
|
662
|
-
|
|
|
663
|
-
|
|
|
664
|
-
|
|
|
665
|
-
|
|
|
666
|
-
|
|
|
667
|
-
|
|
|
668
|
-
|
|
|
669
|
-
|
|
|
670
|
-
|
|
|
671
|
-
|
|
|
672
|
-
| Shape
|
|
673
|
-
|
|
|
674
|
-
|
|
|
675
|
-
|
|
|
676
|
-
|
|
|
677
|
-
|
|
|
678
|
-
|
|
|
679
|
-
|
|
|
680
|
-
|
|
|
681
|
-
|
|
|
682
|
-
|
|
|
683
|
-
|
|
|
684
|
-
|
|
|
685
|
-
|
|
|
686
|
-
|
|
|
687
|
-
|
|
|
688
|
-
|
|
|
689
|
-
|
|
|
690
|
-
|
|
|
691
|
-
|
|
|
692
|
-
|
|
|
693
|
-
|
|
|
694
|
-
|
|
|
708
|
+
| Capability | API |
|
|
709
|
+
| --------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
710
|
+
| Load / save | `loadPresentation(input)`, `savePresentation(pres)`, `loadPresentationFile(path)` (node), `savePresentationToFile(pres, path)` (node) |
|
|
711
|
+
| Create | `createPresentation({ size?: '16:9' \| '4:3' })` — blank deck with master + theme + `Blank` / `Title Slide` / `Title and Content` layouts |
|
|
712
|
+
| Slide CRUD | `getSlides`, `getSlideAt`, `getSlideIndex`, `addSlide`, `removeSlide`, `moveSlide`, `duplicateSlide`, `clearSlideShapes` |
|
|
713
|
+
| Slide layout | `getSlideLayouts`, `findSlideLayout` (by name — case-sensitive, exact; pass a `RegExp` for case-insensitive), `findSlideLayoutByType` (by locale-stable `type` token — preferred), `getSlideLayout(slide)`, `setSlideLayout(slide, layout)`, `getSlideLayoutName`, `getSlideLayoutType` |
|
|
714
|
+
| Slide masters | `getSlideMasterPartNames`, `getSlideMasterLayouts`, `getSlideMasterPlaceholders`, `getSlideMasterName` / `setSlideMasterName`, `isSlideMasterPreserved` / `setSlideMasterPreserved`, `addSlideMaster` / `removeSlideMaster`, `addSlideLayout` / `removeSlideLayout`, `setSlideMasterPlaceholderIncluded`, `getSlideLayoutPlaceholders`, `addSlideLayoutPlaceholder`, `setSlideLayoutTitleIncluded`, `setSlideLayoutFootersIncluded`, `setSlideLayoutBackgroundGraphicsHidden` — removal refuses masters and layouts that slides use |
|
|
715
|
+
| Notes and handout masters | `getNotesMasterPlaceholders` / `setNotesMasterPlaceholderIncluded`, `getHandoutMasterPlaceholders` / `setHandoutMasterPlaceholderIncluded` (the first edit writes the reference desktop app's default master), `getNotesPageSize` / `setNotesPageOrientation`, `getHandoutSlidesPerPage` / `setHandoutSlidesPerPage` |
|
|
716
|
+
| Slide metadata | `getSlideTitle` / `setSlideTitle`, `getSlideSize` / `setSlideSize`, `isSlideHidden` / `setSlideHidden`, `getSlideText` |
|
|
717
|
+
| Slide sections | `getSlideSections`, `setSlideSections` (p14 sectionLst) |
|
|
718
|
+
| Placeholders | `findSlidePlaceholder(slide, 'title' \| 'body' \| ...)` |
|
|
719
|
+
| `addSlidePlaceholder(slide, type, { source?: 'layout' \| 'master' })` | Restore one missing layout placeholder, or explicitly inherit from the master without changing layouts. |
|
|
720
|
+
| Token / text replace | `replaceTokensInPresentation`, `replaceTokensInSlide`, `replaceTextInPresentation`, `replaceTextInSlide` |
|
|
721
|
+
| Background | `getSlideBackground` / `setSlideBackground` / `clearSlideBackground` |
|
|
722
|
+
| Notes | `getSlideNotes` / `setSlideNotes` |
|
|
723
|
+
| Transitions | `getSlideTransition` / `setSlideTransition` / `clearSlideTransition` |
|
|
724
|
+
| Animations | `getShapeAnimation` / `setShapeAnimation` (entrance / exit / emphasis presets), `clearSlideAnimations` |
|
|
725
|
+
| Comments | `addSlideComment`, `getSlideComments`, `removeSlideComment`, `getCommentAuthors`, `getCommentText` / `getCommentAuthor` / `getCommentPosition` |
|
|
726
|
+
| Shape authoring | `addSlideTextBox`, `addSlideShape`, `addSlideLine`, `addSlideTable`, `addSlideImage`, `addSlideMedia`, `addSlideChart` |
|
|
727
|
+
| Shape lookup | `findShapeByName`, `findShapesByName`, `findShapesByKind`, `findShapeInPresentation`, `getAllShapes`, `getSlideShapes` |
|
|
728
|
+
| Shape text | `setShapeText`, `setShapeParagraphs`, `setShapeBulletStyle`, `setShapeAlignment`, `setShapeTextFormat`, `setShapeHyperlink` / `getShapeHyperlink` |
|
|
729
|
+
| Per-paragraph | `setParagraphAlignment` / `getParagraphAlignment`, `setParagraphLevel` / `getParagraphLevel`, `setParagraphBullet` / `getParagraphBullet`, `setParagraphSpacing` / `getParagraphSpacing`, `setParagraphLineSpacing` / `getParagraphLineSpacing`, `getParagraphEndFormat` |
|
|
730
|
+
| Per-run text | `setShapeRunText` / `getShapeRunText`, `setShapeRunFormat` / `getShapeRunFormat`, `getShapeParagraphCount`, `getShapeRunCount` |
|
|
731
|
+
| Text frame | `setShapeTextAnchor` / `getShapeTextAnchor`, `setShapeTextMargins` / `getShapeTextMargins` |
|
|
732
|
+
| Fill | `setShapeFill` / `getShapeFill`, `setShapeGradientFill`, `setShapePatternFill`, `setShapeImageFill`, `setShapeNoFill`, `clearShapeFill` |
|
|
733
|
+
| Stroke | `setShapeStroke` / `getShapeStroke` (solid color or gradient `fill`; `getShapeStrokeGradient`), `setShapeStrokeDash` / `getShapeStrokeDash`, `setShapeStrokeArrow` / `getShapeStrokeArrow`, `setShapeStrokeSketch` / `getShapeStrokeSketch` (sketched lines: `curved` / `freehand` / `scribble`), `…NoStroke` |
|
|
734
|
+
| Effects | `setShapeShadow` / `setShapeGlow` / `getShapeEffect`, `clearShapeEffects` |
|
|
735
|
+
| Geometry | `setShapePosition`, `setShapeSize`, `setShapeRotation`, `setShapeFlip`, `setShapeBounds` / `getShapeBounds` |
|
|
736
|
+
| Pictures | `setShapeImage`, `setShapeImageCrop` / `getShapeImageCrop`, `setShapeImageOpacity` / `getShapeImageOpacity`, `setShapeImageBrightness`, `…Contrast`, `getShapeImageArtisticEffect`, `setShapePictureStyle` / `getShapePictureStyle` (the reference desktop app's 28 built-in picture styles, `BUILTIN_PICTURE_STYLES`), `setShapeImageCompressionState` / `getShapeImageCompressionState` |
|
|
737
|
+
| Z-order | `bringShapeToFront`, `sendShapeToBack`, `bringShapeForward`, `sendShapeBackward`, `getShapeZIndex`, `setShapeZIndex` |
|
|
738
|
+
| Click actions | `setShapeClickAction` / `getShapeClickAction` (`url` / `slide` / `nextSlide` / `prevSlide` / `firstSlide` / `lastSlide`) |
|
|
739
|
+
| Shape removal | `removeShape` |
|
|
740
|
+
| Tables | `getTableCell` / `getTableCells`, `setTableCellText` / `getTableCellText`, `setTableCellParagraphs` / `getTableCellParagraphs`, `setTableCellFill` / `clearTableCellFill`, `setTableCellAlignment`, `setTableCellTextFormat`, `insertTableRow` / `removeTableRow`, `insertTableColumn` / `removeTableColumn`, `mergeTableCells` / `getTableCellSpan` |
|
|
741
|
+
| Table styles | `setTableStyleId` (a GUID or a built-in name from `BUILTIN_TABLE_STYLES`; writes the reference desktop app's definition to `tableStyles.xml`) / `getTableStyleId`, `setTableStyleFlags` / `getTableStyleFlags`, `getTableCellAppearanceEffective`, `getTableBackgroundEffective` |
|
|
742
|
+
| Charts | `addSlideChart`, `getSlideCharts`, `setChartSpec` — kinds: `bar`, `column`, `line`, `pie`, `doughnut`, `area`; axis tick labels via `categoryAxisTickLabelPos` / `valueAxisTickLabelPos` / `secondaryValueAxis.tickLabelPos`; axis line / gridline widths via `valueAxisLineWidthEmu`, `valueAxisMajorGridlineWidthEmu` and their category / secondary-axis mirrors; series `lineColor` / `markerColor` / `markerLineColor`; `dataLabels.showLeaderLines` |
|
|
743
|
+
| Theme | `getPresentationTheme` / `setPresentationTheme` — color scheme (`accent1`..`accent6`, `dark1`, `light1`, `hyperlink`, ...); `getPresentationFonts` / `setPresentationFonts` — major / minor Latin, East Asian, and complex-script faces |
|
|
744
|
+
| Groups | `groupShapes`, `ungroupShapes`, `getGroupChildren`, `getGroupTransform` |
|
|
745
|
+
| Text autofit | `setShapeTextAutoFit` / `getShapeTextAutoFit`, `getShapeTextAutoFitParams` |
|
|
746
|
+
| Text 3-D (text-art bevels) | `setShapeText3D` / `getShapeText3D` (`getTableCellText3D` for cells) — `<a:scene3d>` camera and light rig, `<a:sp3d>` top bevel, extrusion, material, contour color; `setShapeTextFlat` / `getShapeTextFlat` (Keep text flat) |
|
|
747
|
+
| Preset adjustments | `setShapeAdjustValues`; `getShapeCustomGeometry` (custom geometry is read-only) |
|
|
748
|
+
| Document properties | `getCoreProperties` / `setCoreProperties`, `touchModified`, `getThumbnail` / `setThumbnail` / `removeThumbnail` |
|
|
749
|
+
| Package inspection | `listPackageParts`, `readPackagePart`, `getMediaParts`, `getOrphanMediaPartNames`, `getPackageSize`, `compactPackage` |
|
|
750
|
+
| Validation | `validatePresentation(pres)` — invariant checks, returns `ValidationIssue[]` |
|
|
751
|
+
| Units | `inches(n)`, `cm(n)`, `mm(n)`, `pt(n)`, `emu(n)` — return branded `Emu` numbers |
|
|
695
752
|
|
|
696
753
|
`setParagraphLevel` also accepts a UTF-16 text range and a relative level change,
|
|
697
754
|
so a selection can be indented in one update without rebuilding its text or links:
|
|
@@ -708,7 +765,7 @@ continues to edit that single paragraph.
|
|
|
708
765
|
### Outline view state
|
|
709
766
|
|
|
710
767
|
`getCollapsedOutlineSlides(presentation)` returns collapsed slides in deck order.
|
|
711
|
-
Use `setSlideOutlineCollapsed(slide, true)` to hide a slide's body in
|
|
768
|
+
Use `setSlideOutlineCollapsed(slide, true)` to hide a slide's body in the reference desktop app's
|
|
712
769
|
outline view, or `false` to expand it. The setting survives a save/load round trip
|
|
713
770
|
without changing the slide's text. Pass an array of slides to update a selection
|
|
714
771
|
or the whole deck in one operation:
|
|
@@ -729,13 +786,13 @@ unselected siblings are preserved.
|
|
|
729
786
|
|
|
730
787
|
Text formats (`TextFormat`, including a paragraph's `endFormat`) cover the Latin, East Asian and complex-script typefaces (`font`, `fontEastAsian`, `fontComplexScript` — `<a:latin>`, `<a:ea>`, `<a:cs>`). Each is authored and read on its own; setting one leaves the others as they were. Chart labels carry the Latin / East Asian pair and the complex-script slot on `ChartTextStyle`: `font` fills `<a:latin>` and `<a:ea>`, `fontComplexScript` fills `<a:cs>`, and neither implies the other. Rebuilding a typeface writes the `typeface` attribute only, so any `pitchFamily` / `charset` the source file carried on that element is dropped.
|
|
731
788
|
|
|
732
|
-
A run's colors take
|
|
789
|
+
A run's colors take the reference desktop app's theme tints the way gradient stops do: `colorTransforms` beside `color`, and inside `outline`, `shadow`, `innerShadow` and `glow`, writes `<a:lumMod>`, `<a:lumOff>`, `<a:tint>`, ... as children of that color, so `{ color: 'accent2', colorTransforms: [{ kind: 'lumMod', value: 0.4 }, { kind: 'lumOff', value: 0.6 }] }` stays linked to the theme. `getShapeRunFormat` reports them beside the unresolved color; the effective readers resolve them into `#RRGGBB` instead.
|
|
733
790
|
|
|
734
|
-
Runs that name no face fall back to the theme's font scheme, which is also where a per-script list (`<a:font script="Thai" typeface="Cordia New"/>` and 46 siblings) lives. `createPresentation`'s blank deck carries
|
|
791
|
+
Runs that name no face fall back to the theme's font scheme, which is also where a per-script list (`<a:font script="Thai" typeface="Cordia New"/>` and 46 siblings) lives. `createPresentation`'s blank deck carries the reference desktop app's own default list in both `majorFont` and `minorFont`.
|
|
735
792
|
|
|
736
793
|
Authored XML text and attribute values must contain only XML 1.0 characters. Illegal C0 controls (except tab, LF, and CR), U+FFFE, U+FFFF, and unpaired UTF-16 surrogates throw an error identifying the code point. Remove these characters before authoring; valid supplementary characters such as emoji are preserved.
|
|
737
794
|
|
|
738
|
-
Object geometry can be locked like
|
|
795
|
+
Object geometry can be locked like the reference desktop app's Selection Pane:
|
|
739
796
|
|
|
740
797
|
```ts
|
|
741
798
|
import { isShapeLocked, setShapeLocked } from '@office-kit/pptx';
|
|
@@ -754,7 +811,7 @@ remain available.
|
|
|
754
811
|
|
|
755
812
|
[`@office-kit/pptx-preview`](packages/preview) is a companion package that
|
|
756
813
|
renders a slide to SVG (browser and Node) or to PNG (Node, via resvg, with no
|
|
757
|
-
headless
|
|
814
|
+
headless desktop app). `auditTextLayout` reports text that overflows its box or
|
|
758
815
|
wraps unexpectedly, which is how an automated pipeline catches a broken slide
|
|
759
816
|
before a person sees it.
|
|
760
817
|
|
|
@@ -771,11 +828,11 @@ const svg = renderSlideToSvg(pres, getSlides(pres)[0]!);
|
|
|
771
828
|
ECMA-376 spec is the source of truth, output has to validate, and one ESM
|
|
772
829
|
build has to run everywhere.
|
|
773
830
|
|
|
774
|
-
| Package | Files
|
|
775
|
-
| -------------------------------------------------------- |
|
|
776
|
-
| [`@office-kit/pptx`](https://github.com/office-kit/pptx) |
|
|
777
|
-
| [`@office-kit/xlsx`](https://github.com/office-kit/xlsx) |
|
|
778
|
-
| [`@office-kit/docx`](https://github.com/office-kit/docx) |
|
|
831
|
+
| Package | Files |
|
|
832
|
+
| -------------------------------------------------------- | --------------------- |
|
|
833
|
+
| [`@office-kit/pptx`](https://github.com/office-kit/pptx) | Presentations `.pptx` |
|
|
834
|
+
| [`@office-kit/xlsx`](https://github.com/office-kit/xlsx) | Spreadsheets `.xlsx` |
|
|
835
|
+
| [`@office-kit/docx`](https://github.com/office-kit/docx) | Documents `.docx` |
|
|
779
836
|
|
|
780
837
|
## Compatibility
|
|
781
838
|
|
|
@@ -784,8 +841,8 @@ build has to run everywhere.
|
|
|
784
841
|
- **TypeScript**: >= 5.4 (for strict `satisfies` and `const` type parameters).
|
|
785
842
|
- **Output**: validated with the Open XML SDK and the ECMA-376 schemas (see
|
|
786
843
|
[How output is checked](#how-output-is-checked)), and smoke-tested against
|
|
787
|
-
|
|
788
|
-
Impress.
|
|
844
|
+
the reference desktop app (current), Keynote (current), Google Slides, and
|
|
845
|
+
LibreOffice Impress.
|
|
789
846
|
|
|
790
847
|
## Development
|
|
791
848
|
|
|
@@ -824,8 +881,9 @@ PRs are expected to:
|
|
|
824
881
|
|
|
825
882
|
## Trademarks
|
|
826
883
|
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
a trademark of
|
|
830
|
-
|
|
831
|
-
|
|
884
|
+
Not affiliated with or endorsed by Microsoft. PowerPoint is a trademark of the Microsoft group of companies.
|
|
885
|
+
|
|
886
|
+
Keynote is a trademark of Apple Inc., and Google Slides is a trademark of
|
|
887
|
+
Google LLC. Office Kit is an independent open-source project and is not
|
|
888
|
+
affiliated with, sponsored by, or endorsed by either; these names are used only
|
|
889
|
+
to describe file-format compatibility.
|