Skip to content

Releases: shbernal/PptxGenJS

v6.0.0

14 Jun 21:14

Choose a tag to compare

This major release introduces the new pptxgenjs/read subsystem — a separate, lossless read/edit/round-trip layer for existing decks — alongside radial gradient fills and image-in-shape composition. The new public ./read subpath export and its substantial API surface motivate the major version bump.

Added

  • New pptxgenjs/read subsystem (@shbernal/pptxgenjs/read): open an existing .pptx, navigate and edit it, and save it back losslessly (untouched parts stay byte-for-byte identical).
    • OPC layer (OpcPackage): parts, content types, relationships, writable parts, lossless save().
    • Navigable read model: Presentation → slides → shapes → text frame → paragraphs → runs, incl. tables, charts (read-only), connectors, nested groups.
    • Typed edits over the live DOM: run text & character formatting, shape position/size, fill/line colour, Slide.hidden, Picture.setImage, Slide.addPicture.
    • Structural edits: add/remove shapes, add pictures, edit table cell text, slide cloning.
    • Cross-package composition: Presentation.importSlide (theme: 'preserve' | 'restyle', carryMasterGraphics, placeholder geometry/run-size baking) and importShape/importShapes.
    • Loader hardening: PowerPoint [trash] parts dropped on load.
  • Radial gradient fills: RadialGradientFillProps (kind: 'radial', optional center/rotateWithShape) serialized as <a:gradFill> with <a:path path="circle"> + <a:fillToRect>.
  • Image embedded in a shape: addImage({ points }) clips a picture to a custGeom path (or preset shape/rounding); with sizing: { type: 'cover' } it center-crops to fill the clip.

Changed

  • Image sizing now emits an explicit <a:fillRect/> inside <a:stretch> (canonical PowerPoint form) instead of an empty self-closing <a:stretch/>.

See CHANGELOG.md for full details.

v5.4.0

13 Jun 13:19

Choose a tag to compare

Added

  • slide.addConnector(...) — real PowerPoint connector shapes (<p:cxnSp>) with straight/elbow/curved geometries, flip derivation, and line styling/arrowheads (upstream gitbrent#1059).
  • ThemeProps.colorScheme to configure a presentation's theme color scheme (upstream gitbrent#1243).
  • Table autoPagePlaceholder to carry placeholders onto auto-paged overflow slides (upstream gitbrent#1136).
  • Image line border outline (<a:ln> on the picture), pairing with the existing shadow (upstream gitbrent#986).
  • Pie/doughnut data-label leader-line styling via leaderLineColor / leaderLineSize (upstream gitbrent#1376).
  • bullet.fontFace and bullet.size for custom symbol/numbered bullet glyphs (upstream gitbrent#800, gitbrent#743).
  • Actionable media-load errors with an opt-in placeholder fallback (upstream gitbrent#1310).

Changed

  • BREAKING: exported .pptx packages are now DEFLATE-compressed by default on every export path (previously STORE), producing much smaller files. Pass compression: false to restore the old uncompressed behavior (upstream gitbrent#1268).

Fixed

  • sizing: 'cover' | 'contain' is now aspect-correct for SVG images (intrinsic size read from <svg> width/height/viewBox instead of stretching).
  • defineSlideMaster passes rich-text arrays through master text objects unchanged (upstream gitbrent#962).
  • Table autoPage no longer crashes (addTable: Array expected) or emits empty overflow pages when h+y/margins leave no usable height.
  • Tables honor data-pptx-width and no longer compute NaN column widths for hidden tables (upstream gitbrent#1157).

v5.3.0

11 Jun 13:04

Choose a tag to compare

Added

  • addImage infers an image's natural size when w/h are omitted. For base64
    data images the intrinsic pixel size is read synchronously from the header
    (PNG/JPEG/GIF/BMP/WebP) and applied at 96 DPI; when only one of w/h is
    given, the other is derived from the natural aspect ratio. Previously a
    dimensionless image collapsed to a 1in square. path and SVG images (not
    synchronously measurable) keep the 1in fallback.
  • Explicit coordinate unit suffixes on any Coord (x/y/w/h): "<n>in"
    (inches), "<n>pt" (points), and "<n>emu" (raw EMU) — alongside the existing
    bare number (inches) and "<n>%". Example: { x: '72pt', w: '914400emu' }.
  • Exported branded Emu type and coordToEmu / percentToEmu converters from
    the units module (joining the existing inchesToEmu / pointsToEmu /
    emuToInches helpers).
  • Run-level text shadow: a shadow (or glow) set on a text run now emits an
    <a:effectLst> inside <a:rPr>, so text in table cells — which have no shape
    spPr — can finally carry a shadow (upstream gitbrent#1011).
  • OptsChartData.customLabels?: string[] for per-data-point data label text
    overrides on BAR/LINE/AREA/RADAR and PIE/DOUGHNUT charts; empty entries fall
    back to chart-level settings (upstream gitbrent#1337).
  • OptsChartData.pointStyles?: ChartDataPointStyle[] for typed per-data-point
    border/fill styling ({ border?: BorderProps; fill?: HexColor }), index-
    aligned with values[], on BAR/BAR3D/LINE/AREA/SCATTER/PIE/DOUGHNUT
    (upstream gitbrent#1343).
  • Text-box columns: columns (1–16) and columnSpacing (points) on
    TextPropsOptions, emitting numCol/spcCol on <a:bodyPr> (upstream gitbrent#1320).
  • Line cap ('flat'|'round'|'square') on ShapeLineProps and BorderProps,
    emitted on <a:ln> for shapes, table cell borders, and charts via a shared
    LineCap type (upstream gitbrent#782).
  • objectLock (ObjectLockProps) on shapes, text boxes, images, media, and
    tables, serializing DrawingML a:spLocks/a:picLocks/a:graphicFrameLocks
    (noGrp, noMove, noResize, noRot, noCrop, …) (upstream gitbrent#438).
  • shapeAdjust ({ name, value }, single or array) on ShapeProps and
    ImageBaseProps, emitting preset-shape adjustment guides in <a:avLst>
    (upstream gitbrent#1300).
  • Chart title titleItalic / titleUnderline props, mirroring titleBold
    (upstream gitbrent#1188).
  • Partial chart-title manual layout: titlePos now accepts a partial
    { x?, y? }, applying a manual offset on one axis while leaving the other on
    automatic layout (upstream gitbrent#1363).
  • Shrink-autofit tuning: fit accepts { type: 'shrink', fontScale?, lnSpcReduction? } (percent 0–100) emitted on <a:normAutofit>; bare
    fit: 'shrink' is unchanged (upstream gitbrent#1199).
  • barSeriesLine on bar charts (true or an OptsChartGridLine object) emits
    <c:serLines> for stacked bars (upstream gitbrent#1329).
  • showBubbleSize option for bubble-chart data labels (upstream gitbrent#744).

Changed

  • Behavior change: A bare-number coordinate is now always inches. The library no
    longer guesses units by magnitude — previously a number >= 100 was silently
    treated as raw EMU (and inch2Emu/coordinate parsing carried a matching
    > 100 passthrough), which mis-rendered any legitimately large value and made
    values near the threshold ambiguous.
    • Migration: if you were passing raw EMU as a large number (e.g. 914400),
      pass it explicitly as a string instead ('914400emu'), or convert with the
      emuToInches helper. Bare numbers, '%', and the new unit suffixes need no
      change.
    • Non-finite coordinates now throw with a descriptive message instead of
      collapsing the object to zero size; an implausibly large bare number (> 1000
      inches) is interpreted as inches but warns, pointing at the '<n>emu' form.
    • Internally, user coordinates are resolved to EMU exactly once at the
      emission boundary (no in-place pre-conversion / double-parse), and resolved
      values carry a branded Emu type so they cannot be silently re-converted.
  • Behavior change: Removed the invalid LINE_CALLOUT_4* shape presets
    (borderCallout4, accentCallout3=4, accentBorderCallout4, callout4) —
    no callout-4 exists in ECMA-376 ST_ShapeType, so they only ever produced
    corrupt packages. FOLDED_CORNER is also corrected from the invalid
    folderCorner to the spec spelling foldedCorner (upstream gitbrent#1449).
  • Chart values now carry their number format into each series'
    <c:numCache><c:formatCode> (resolved from valLabelFormatCode /
    dataTableFormatCode / dataLabelFormatCode, default #,##0) instead of a
    hard-coded General, so PowerPoint and Google Slides honor formatCode the
    way LibreOffice already did. This deliberately changes default cached output
    to match the data-label format (upstream gitbrent#1309).
  • Identical media is now deduplicated: inline base64 data: media is reused
    per slide, and a deck-wide export pass collapses repeated images (including
    background images and SVG) to a single package part instead of embedding one
    copy per use (upstream gitbrent#1339).
  • ChartLineCap is now a deprecated alias for the shared LineCap type.

Fixed

  • Table merged cells (colspan/rowspan covered cells) now render the span's outer
    borders and fill instead of emitting an empty <a:tcPr/>; the origin cell's
    border tuple and resolved fill are applied to the covered edges to match
    PowerPoint-authored output (upstream gitbrent#680).
  • RGBA effect colors no longer emit a duplicate <a:alpha>: when a shadow/glow
    caller supplies an explicit alpha (notably on table-cell paths that skip
    correctShadowOptions), it wins and the RGBA byte is dropped, fixing
    schema-invalid double-<a:alpha> output that triggered PowerPoint repair.
  • Text-box margin arrays are now mapped as [top, right, bottom, left],
    matching table cells and slide numbers; previously Top and Left were
    transposed, mis-rendering asymmetric margins (upstream gitbrent#1248).
  • Out-of-range fill/line/gradient transparency, glow opacity, and line widths
    are clamped to schema-valid <a:alpha> / <a:ln w> ranges (warning on
    coercion) instead of emitting values PowerPoint rejects.
  • Out-of-range fontSize, charSpacing, and lineSpacing are clamped to their
    schema ranges at run/paragraph emission (covering text boxes, table cells, and
    the slide-number placeholder).
  • Chart gapWidth/gapDepth, overlap, holeSize, and firstSliceAng are
    clamped to their schema ranges via a shared helper (upstream gitbrent#1233).
  • Chart lineDataSymbolSize is rounded and clamped into the valid
    ST_MarkerSize range 2–72 (upstream gitbrent#1233).
  • Non-finite (NaN/Infinity) chart data values are dropped (with a warning)
    rather than emitting an invalid <c:numCache> that PowerPoint flags for
    repair; null/undefined remain valid sparse gaps (upstream gitbrent#1357).
  • Chart text (title, legend, axis labels, data labels) now stamps the requested
    typeface onto the <a:latin>/<a:ea>/<a:cs> trio so East-Asian and
    complex-script glyphs honor the chosen font (most visibly on PowerPoint for
    Mac) (upstream gitbrent#1420).
  • Scatter/bubble X axes in combo charts now emit <c:valAx> instead of
    <c:catAx>, fixing packages PowerPoint flagged for repair; an unsatisfiable
    shared-axis configuration now warns (upstream gitbrent#1355).
  • addShape (and the shape option on addText/addImage) now rejects
    unknown presets with a clear error at the genXmlPresetGeom chokepoint rather
    than emitting an invalid <a:prstGeom> that corrupts the package
    (upstream gitbrent#1449).
  • HTML-table conversion preserves fractional border widths (e.g. 0.5px hairlines)
    instead of rounding them to 0pt; a zero/non-finite computed width now yields
    { type: 'none' } (upstream gitbrent#1235).

v5.2.0

10 Jun 12:36

Choose a tag to compare

Added

  • textRun / textRuns typed inline-run factory helpers
  • Native pattern fills for shapes (fill: { type: 'pattern', pattern })
  • defineTableStyle(), TABLE_STYLE enum + tblPr style flags, hasHeader option
  • Slide-master roundRect object + placeholder shapes
  • Chart seriesOptions (per-series color/label); combo-chart legend suppression
  • Image duotone recolor; firstSlideNum; setCustomProperty

Fixed

  • textRun / textRuns now exported from every runtime entry (node/browser/standalone/core), not just index — fixes a runtime "does not provide an export named 'textRun'" under the Node export condition
  • Image cover/contain crop computed from natural pixel ratio; out-of-bounds crop now throws
  • Multi-level category chart workbook/SST indices; round2SameRect/round2DiagRect adj values
  • Table autoPage line-wrap/section/rowspan fixes; breakLine: false on CRLF runs
  • SVG PNG preview placeholder; XML-encoded image hyperlink URLs

Full notes in CHANGELOG.md.

v5.1.0

08 Jun 22:20

Choose a tag to compare

Added

  • catAxisLabelFormatCode on scatter and bubble charts sets an independent number format for the X (horizontal) axis, decoupled from valAxisLabelFormatCode which controls the Y axis.
  • lineDashValues?: ChartLineDash[] on line, scatter, and bubble charts sets a per-series dash pattern; entries fall back to the chart-level lineDash default.
  • addImage({ shape }) clips a picture to any preset geometry (e.g. 'hexagon', 'roundRect'). rounding: true remains a shorthand for shape: 'ellipse'.
  • addImage({ points }) clips a picture to an arbitrary freeform path (custGeom) using the same path DSL as freeform shapes. Takes precedence over shape/rounding.
  • addImage({ svg }) accepts raw SVG markup directly, converting it to a base64 data URI internally.
  • altText prop extended to text boxes, shapes, tables, and media objects (previously only images and charts).
  • Object name validation: warns on names that cannot provide a stable Selection Pane identity — empty/whitespace, control characters, names over 255 chars, or duplicates on the same slide.
  • bullet.color (HexColor) colors a bullet glyph independently of the text run color.
  • TextBaseProps.caps ('none' | 'small' | 'all') applies all-caps or small-caps styling to a text run.
  • valAxisCrossBetween ('between' | 'midCat') exposes the OOXML crossBetween setting on the value axis.
  • STANDARD_LAYOUTS.* now expose .width / .height inch aliases. pptx.layout accepts a preset object directly. slide.width / slide.height getters return the active layout size in inches.
  • displayBlanksAs: 'zero' added as a valid chart option value.

Fixed

  • getSmartParseNumber now throws on NaN/Infinity instead of silently collapsing objects to zero size or position.
  • XML 1.0 illegal control characters stripped before serialization, preventing PowerPoint repair dialogs.
  • createColorElement guards against non-string input (prevents TypeError from chartColors).
  • Table write() / writeFile() is now idempotent on merged-cell tables.
  • Scatter/bubble chart data labels now apply dataLabelFontSize, dataLabelFontBold, dataLabelFontItalic, dataLabelColor, and dataLabelFontFace.
  • Slide master and layout media targets namespaced to prevent collisions in large decks.
  • Line charts now emit c:grouping (required) and respect barGrouping: 'stacked'.
  • Single-level category labels now emit c:strRef/c:strCache instead of c:multiLvlStrRef (better importer compatibility).
  • Chart zero values preserved in embedded workbook cells.
  • Pie/doughnut parent dLbls now use user-supplied font/color instead of hard-coded defaults.
  • Transparent chartColors entries on line/radar charts emit <a:noFill/> on markers.
  • Chart null values now omit <c:pt> entirely (correct OOXML gap encoding).
  • Stray apostrophe removed from embedded workbook table-ref attribute (fixes Keynote rendering).
  • Pie/doughnut dataLabelPosition applied to parent dLbls block instead of hard-coding 'ctr'.
  • Shadow blur, angle, and opacity zero values honored instead of replaced by defaults.
  • barOverlapPct respected on stacked bar charts.
  • Scatter/bubble cat-axis reads catAxisLabelPos instead of hard-coding 'nextTo'.
  • catAxisOrientation / valAxisOrientation type unions now include 'maxMin'.

Changed

  • displayBlanksAs default changed from 'span' to 'gap'.

v5.0.2

08 Jun 09:37

Choose a tag to compare

Added

  • Native linear gradient fills for shapes.
  • Public slide-layout unit helpers and package inspection primitives.
  • Generated documentation site and object identity reference documentation.

Fixed

  • Zero chart axis crossing values are preserved instead of being treated as absent.
  • Company metadata XML is escaped before serialization.
  • Inner shadow XML is closed correctly.

Changed

  • Regression tests were reorganized into the current suite layout.

v5.0.1

07 Jun 12:04

Choose a tag to compare

Added

  • GitHub Actions npm publishing workflow for @shbernal/pptxgenjs, using npm trusted publishing and provenance on published GitHub releases.

Changed

  • Release documentation now describes the automated publish.yml workflow, tag guard, manual retry path, and post-publish checks.

v5.0.0

07 Jun 11:48

Choose a tag to compare

v5.0.0

First GitHub release for the scoped fork package, @shbernal/pptxgenjs.

Highlights

  • Moves the maintained package target to @shbernal/pptxgenjs.
  • Keeps the runtime contract intentionally ESM-only for Node.js >=24 and modern bundlers.
  • Verifies scoped default and subpath imports for @shbernal/pptxgenjs, @shbernal/pptxgenjs/core, @shbernal/pptxgenjs/node, @shbernal/pptxgenjs/browser, and @shbernal/pptxgenjs/standalone.
  • Keeps package artifacts generated under dist/ and excludes legacy CJS/IIFE/browser-global artifacts.
  • Adds the release checklist under docs/RELEASING.md.
  • Updates CI to run Node 24 and Node 26 validation with package lint, pack checks, package smoke tests, and demo smoke tests.

Breaking Changes

  • Package import path changes from pptxgenjs to @shbernal/pptxgenjs.
  • CommonJS require(...), IIFE/global browser bundles, direct CDN script-tag workflows, and legacy artifact names are not maintained package targets.

npm Status

npm publishing is not automated for this first scoped release. Publishing @shbernal/pptxgenjs@5.0.0 remains a manual follow-up after npm ownership/package setup is confirmed.

Verification

GitHub CI passed on Node 24 and Node 26 for commit 688189aaa612fcd4e718bdb6131ac790dcf0e4d5.

CI run: https://github.com/shbernal/PptxGenJS/actions/runs/27091629379