pptx-viewer-mcp 2.2.0 → 2.3.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/dist/index.js CHANGED
@@ -22,11 +22,17 @@ async function loadPresentation(filePath, execCtx) {
22
22
  const pptxData = await handler.load(rawBytes.buffer);
23
23
  return { pptxData, rawBytes };
24
24
  }
25
- async function savePresentation(filePath, pptxData, rawBytes, execCtx) {
25
+ async function savePresentation(filePath, pptxData, rawBytes, execCtx, tableStyleSaveOptions) {
26
26
  const handler = new pptxViewerCore.PptxHandler();
27
27
  await handler.load(rawBytes.buffer);
28
28
  const outputBytes = await handler.save(pptxData.slides, {
29
- headerFooter: pptxData.headerFooter
29
+ headerFooter: pptxData.headerFooter,
30
+ // `pptxData.tableStyleMap` carries any in-memory table-style edits a
31
+ // tool made (e.g. `set_table_style_section`, `create_table_style`);
32
+ // without forwarding it here those edits were silently dropped on
33
+ // save even though the core save pipeline already supports them.
34
+ tableStyles: pptxData.tableStyleMap,
35
+ ...tableStyleSaveOptions
30
36
  });
31
37
  if (execCtx.collaboration) {
32
38
  const room = execCtx.collaboration.getRoom(filePath);
@@ -58,7 +64,13 @@ async function executeToolWithContext(filePath, execCtx, toolFn) {
58
64
  const { pptxData, rawBytes } = await loadPresentation(filePath, execCtx);
59
65
  const toolResult = await toolFn({ pptxData });
60
66
  if (toolResult.dirty) {
61
- const saveResult = await savePresentation(filePath, toolResult.pptxData, rawBytes, execCtx);
67
+ const saveResult = await savePresentation(
68
+ filePath,
69
+ toolResult.pptxData,
70
+ rawBytes,
71
+ execCtx,
72
+ toolResult.saveOptions
73
+ );
62
74
  return { ...toolResult.result, ...saveResult };
63
75
  }
64
76
  return toolResult.result;
@@ -581,8 +593,17 @@ function updateElement(ctx, params) {
581
593
  if (params.fontFamily !== void 0) {
582
594
  textEl.textStyle.fontFamily = params.fontFamily;
583
595
  }
584
- if (params.fontColor !== void 0) {
596
+ if (params.fontThemeColor !== void 0) {
597
+ textEl.textStyle.colorRef = params.fontThemeColor;
598
+ const resolved = pptxViewerCore.resolveThemeColorRef(params.fontThemeColor, ctx.pptxData.themeColorMap);
599
+ if (params.fontColor !== void 0) {
600
+ textEl.textStyle.color = params.fontColor;
601
+ } else if (resolved) {
602
+ textEl.textStyle.color = resolved;
603
+ }
604
+ } else if (params.fontColor !== void 0) {
585
605
  textEl.textStyle.color = params.fontColor;
606
+ textEl.textStyle.colorRef = void 0;
586
607
  }
587
608
  if (params.bold !== void 0) {
588
609
  textEl.textStyle.bold = params.bold;
@@ -1073,6 +1094,142 @@ function manageTableStructure(ctx, params) {
1073
1094
  }
1074
1095
  };
1075
1096
  }
1097
+ function findTableElement(ctx, slideIndex, elementId) {
1098
+ const err = validateSlideIndex(slideIndex, ctx.pptxData.slides.length);
1099
+ if (err) {
1100
+ throw new Error(err);
1101
+ }
1102
+ const slide = ctx.pptxData.slides[slideIndex];
1103
+ const el = slide.elements.find((e) => e.id === elementId);
1104
+ if (!el) {
1105
+ throw new Error(`Element '${elementId}' not found on slide ${slideIndex}.`);
1106
+ }
1107
+ if (el.type !== "table") {
1108
+ throw new Error(`Element '${elementId}' is not a table.`);
1109
+ }
1110
+ return el;
1111
+ }
1112
+ function tableStyleIdsInUse(ctx) {
1113
+ const used = /* @__PURE__ */ new Set();
1114
+ for (const slide of ctx.pptxData.slides) {
1115
+ for (const el of slide.elements) {
1116
+ if (el.type === "table" && el.tableData?.tableStyleId) {
1117
+ used.add(pptxViewerCore.normalizeTableStyleGuid(el.tableData.tableStyleId));
1118
+ }
1119
+ }
1120
+ }
1121
+ return used;
1122
+ }
1123
+ function setTableStyleSection(ctx, params) {
1124
+ if (!pptxViewerCore.TABLE_STYLE_PART_SEQUENCE.includes(params.section)) {
1125
+ throw new Error(
1126
+ `Unknown table style section '${params.section}'. Valid sections: ${pptxViewerCore.TABLE_STYLE_PART_SEQUENCE.join(", ")}.`
1127
+ );
1128
+ }
1129
+ const map = ctx.pptxData.tableStyleMap ?? {};
1130
+ ctx.pptxData.tableStyleMap = map;
1131
+ const normalizedId = pptxViewerCore.normalizeTableStyleGuid(params.styleId);
1132
+ const entry = map[normalizedId];
1133
+ if (!entry) {
1134
+ throw new Error(
1135
+ `Table style '${params.styleId}' is not loaded in this presentation. Use create_table_style to add a new one.`
1136
+ );
1137
+ }
1138
+ if (params.styleName !== void 0) {
1139
+ entry.styleName = params.styleName;
1140
+ }
1141
+ const mutableEntry = entry;
1142
+ if (params.fill !== void 0) {
1143
+ mutableEntry[`${params.section}Fill`] = params.fill;
1144
+ }
1145
+ if (params.text !== void 0) {
1146
+ mutableEntry[`${params.section}Text`] = params.text;
1147
+ }
1148
+ if (params.borders !== void 0) {
1149
+ mutableEntry[`${params.section}Borders`] = params.borders;
1150
+ }
1151
+ if (params.cell3D !== void 0) {
1152
+ mutableEntry[`${params.section}Cell3D`] = params.cell3D;
1153
+ }
1154
+ return {
1155
+ pptxData: ctx.pptxData,
1156
+ dirty: true,
1157
+ result: { styleId: normalizedId, section: params.section }
1158
+ };
1159
+ }
1160
+ function createTableStyle(ctx, params) {
1161
+ const map = ctx.pptxData.tableStyleMap ?? {};
1162
+ ctx.pptxData.tableStyleMap = map;
1163
+ const basedOn = params.basedOnStyleId ? map[pptxViewerCore.normalizeTableStyleGuid(params.basedOnStyleId)] : void 0;
1164
+ if (params.basedOnStyleId && !basedOn) {
1165
+ throw new Error(`basedOnStyleId '${params.basedOnStyleId}' is not a loaded table style.`);
1166
+ }
1167
+ const entry = pptxViewerCore.createTableStyleEntry(map, { styleName: params.styleName, basedOn });
1168
+ pptxViewerCore.addTableStyleToMap(map, entry);
1169
+ return {
1170
+ pptxData: ctx.pptxData,
1171
+ dirty: true,
1172
+ result: { styleId: entry.styleId },
1173
+ ...params.setAsDefault ? { saveOptions: { tableStylesDefaultId: entry.styleId } } : {}
1174
+ };
1175
+ }
1176
+ function deleteTableStyle(ctx, params) {
1177
+ const normalizedId = pptxViewerCore.normalizeTableStyleGuid(params.styleId);
1178
+ if (!params.force) {
1179
+ const used = tableStyleIdsInUse(ctx);
1180
+ if (used.has(normalizedId)) {
1181
+ throw new Error(
1182
+ `Table style '${params.styleId}' is assigned to at least one table on this deck. Reassign those tables first, or pass force: true.`
1183
+ );
1184
+ }
1185
+ }
1186
+ const map = ctx.pptxData.tableStyleMap ?? {};
1187
+ ctx.pptxData.tableStyleMap = map;
1188
+ pptxViewerCore.deleteTableStyleFromMap(map, normalizedId);
1189
+ return {
1190
+ pptxData: ctx.pptxData,
1191
+ dirty: true,
1192
+ result: { deleted: true },
1193
+ saveOptions: { tableStylesToDelete: [normalizedId] }
1194
+ };
1195
+ }
1196
+ function assignTableStyle(ctx, params) {
1197
+ const el = findTableElement(ctx, params.slideIndex, params.elementId);
1198
+ if (!el.tableData) {
1199
+ throw new Error(`Table '${params.elementId}' has no tableData.`);
1200
+ }
1201
+ const styleId = params.styleId ?? ctx.pptxData.tableStylesDefaultId;
1202
+ if (!styleId) {
1203
+ throw new Error(
1204
+ "styleId was not provided and this presentation has no tableStylesDefaultId to fall back to."
1205
+ );
1206
+ }
1207
+ const normalizedId = pptxViewerCore.normalizeTableStyleGuid(styleId);
1208
+ el.tableData.tableStyleId = normalizedId;
1209
+ if (params.bandedRows !== void 0) {
1210
+ el.tableData.bandedRows = params.bandedRows;
1211
+ }
1212
+ if (params.bandedColumns !== void 0) {
1213
+ el.tableData.bandedColumns = params.bandedColumns;
1214
+ }
1215
+ if (params.firstRowHeader !== void 0) {
1216
+ el.tableData.firstRowHeader = params.firstRowHeader;
1217
+ }
1218
+ if (params.lastRow !== void 0) {
1219
+ el.tableData.lastRow = params.lastRow;
1220
+ }
1221
+ if (params.firstCol !== void 0) {
1222
+ el.tableData.firstCol = params.firstCol;
1223
+ }
1224
+ if (params.lastCol !== void 0) {
1225
+ el.tableData.lastCol = params.lastCol;
1226
+ }
1227
+ return {
1228
+ pptxData: ctx.pptxData,
1229
+ dirty: true,
1230
+ result: { elementId: params.elementId, styleId: normalizedId }
1231
+ };
1232
+ }
1076
1233
  function updateElementStyle(ctx, params) {
1077
1234
  const err = validateSlideIndex(params.slideIndex, ctx.pptxData.slides.length);
1078
1235
  if (err) {
@@ -1088,8 +1245,17 @@ function updateElementStyle(ctx, params) {
1088
1245
  el.shapeStyle = {};
1089
1246
  }
1090
1247
  const ss = el.shapeStyle;
1091
- if (params.fillColor !== void 0) {
1248
+ if (params.fillThemeColor !== void 0) {
1249
+ ss.fillColorRef = params.fillThemeColor;
1250
+ const resolved = pptxViewerCore.resolveThemeColorRef(params.fillThemeColor, ctx.pptxData.themeColorMap);
1251
+ if (params.fillColor !== void 0) {
1252
+ ss.fillColor = params.fillColor;
1253
+ } else if (resolved) {
1254
+ ss.fillColor = resolved;
1255
+ }
1256
+ } else if (params.fillColor !== void 0) {
1092
1257
  ss.fillColor = params.fillColor;
1258
+ ss.fillColorRef = void 0;
1093
1259
  }
1094
1260
  if (params.fillMode !== void 0) {
1095
1261
  ss.fillMode = params.fillMode;
@@ -1106,8 +1272,17 @@ function updateElementStyle(ctx, params) {
1106
1272
  if (params.fillOpacity !== void 0) {
1107
1273
  ss.fillOpacity = params.fillOpacity;
1108
1274
  }
1109
- if (params.strokeColor !== void 0) {
1275
+ if (params.strokeThemeColor !== void 0) {
1276
+ ss.strokeColorRef = params.strokeThemeColor;
1277
+ const resolved = pptxViewerCore.resolveThemeColorRef(params.strokeThemeColor, ctx.pptxData.themeColorMap);
1278
+ if (params.strokeColor !== void 0) {
1279
+ ss.strokeColor = params.strokeColor;
1280
+ } else if (resolved) {
1281
+ ss.strokeColor = resolved;
1282
+ }
1283
+ } else if (params.strokeColor !== void 0) {
1110
1284
  ss.strokeColor = params.strokeColor;
1285
+ ss.strokeColorRef = void 0;
1111
1286
  }
1112
1287
  if (params.strokeWidth !== void 0) {
1113
1288
  ss.strokeWidth = params.strokeWidth;
@@ -1863,6 +2038,98 @@ function findChartElement(ctx, slideIndex, elementId) {
1863
2038
  }
1864
2039
  return el;
1865
2040
  }
2041
+ function formatChartDataPoint(ctx, params) {
2042
+ const chart = findChartElement(ctx, params.slideIndex, params.elementId);
2043
+ if (params.clearStyle) {
2044
+ pptxViewerCore.setChartDataPointStyle(chart, params.seriesIndex, params.pointIndex, null);
2045
+ } else if (params.fillColor !== void 0 || params.strokeColor !== void 0 || params.strokeWidth !== void 0 || params.strokeDashStyle !== void 0) {
2046
+ pptxViewerCore.setChartDataPointStyle(chart, params.seriesIndex, params.pointIndex, {
2047
+ ...params.fillColor !== void 0 ? { fillColor: params.fillColor } : {},
2048
+ ...params.strokeColor !== void 0 ? { strokeColor: params.strokeColor } : {},
2049
+ ...params.strokeWidth !== void 0 ? { strokeWidth: params.strokeWidth } : {},
2050
+ ...params.strokeDashStyle !== void 0 ? { strokeDashStyle: params.strokeDashStyle } : {}
2051
+ });
2052
+ }
2053
+ if (params.explosion !== void 0) {
2054
+ pptxViewerCore.setChartDataPointExplosion(chart, params.seriesIndex, params.pointIndex, params.explosion);
2055
+ }
2056
+ if (params.marker !== void 0) {
2057
+ pptxViewerCore.setChartDataPointMarker(chart, params.seriesIndex, params.pointIndex, params.marker);
2058
+ }
2059
+ return { pptxData: ctx.pptxData, dirty: true, result: { elementId: params.elementId } };
2060
+ }
2061
+ function formatChartDataLabel(ctx, params) {
2062
+ const chart = findChartElement(ctx, params.slideIndex, params.elementId);
2063
+ if (params.remove) {
2064
+ pptxViewerCore.setChartDataPointLabel(chart, params.seriesIndex, params.pointIndex, null);
2065
+ return { pptxData: ctx.pptxData, dirty: true, result: { elementId: params.elementId } };
2066
+ }
2067
+ pptxViewerCore.setChartDataPointLabel(chart, params.seriesIndex, params.pointIndex, {
2068
+ ...params.showValue !== void 0 ? { showValue: params.showValue } : {},
2069
+ ...params.showCategory !== void 0 ? { showCategory: params.showCategory } : {},
2070
+ ...params.showSeriesName !== void 0 ? { showSeriesName: params.showSeriesName } : {},
2071
+ ...params.showPercent !== void 0 ? { showPercent: params.showPercent } : {},
2072
+ ...params.showLegendKey !== void 0 ? { showLegendKey: params.showLegendKey } : {},
2073
+ ...params.position !== void 0 ? { position: params.position } : {},
2074
+ ...params.text !== void 0 ? { text: params.text } : {},
2075
+ ...params.spPr !== void 0 ? { spPr: params.spPr } : {},
2076
+ ...params.txPr !== void 0 ? { txPr: params.txPr } : {}
2077
+ });
2078
+ return { pptxData: ctx.pptxData, dirty: true, result: { elementId: params.elementId } };
2079
+ }
2080
+ function formatChartSeries(ctx, params) {
2081
+ const chart = findChartElement(ctx, params.slideIndex, params.elementId);
2082
+ if (params.marker !== void 0) {
2083
+ if (params.marker === null) {
2084
+ pptxViewerCore.setChartSeriesMarker(chart, params.seriesIndex, null);
2085
+ } else if (params.marker.strokeColor !== void 0 || params.marker.strokeWidth !== void 0 || params.marker.strokeDashStyle !== void 0) {
2086
+ pptxViewerCore.setChartSeriesMarker(chart, params.seriesIndex, {
2087
+ symbol: params.marker.symbol ?? "circle",
2088
+ ...params.marker.size !== void 0 ? { size: params.marker.size } : {},
2089
+ spPr: {
2090
+ ...params.marker.fillColor !== void 0 ? { fillColor: params.marker.fillColor } : {},
2091
+ ...params.marker.strokeColor !== void 0 ? { strokeColor: params.marker.strokeColor } : {},
2092
+ ...params.marker.strokeWidth !== void 0 ? { strokeWidth: params.marker.strokeWidth } : {},
2093
+ ...params.marker.strokeDashStyle !== void 0 ? { strokeDashStyle: params.marker.strokeDashStyle } : {}
2094
+ }
2095
+ });
2096
+ } else {
2097
+ pptxViewerCore.setChartSeriesMarker(chart, params.seriesIndex, params.marker);
2098
+ }
2099
+ }
2100
+ if (params.trendline !== void 0) {
2101
+ pptxViewerCore.setChartSeriesTrendline(chart, params.seriesIndex, params.trendline);
2102
+ }
2103
+ if (params.errorBars !== void 0) {
2104
+ pptxViewerCore.setChartSeriesErrorBars(chart, params.seriesIndex, params.errorBars);
2105
+ }
2106
+ return { pptxData: ctx.pptxData, dirty: true, result: { elementId: params.elementId } };
2107
+ }
2108
+ function setChartHelperLineT(ctx, params) {
2109
+ const chart = findChartElement(ctx, params.slideIndex, params.elementId);
2110
+ pptxViewerCore.setChartHelperLine(chart, params.line, params.style);
2111
+ return { pptxData: ctx.pptxData, dirty: true, result: { elementId: params.elementId } };
2112
+ }
2113
+ function setChartColorMapOverrideT(ctx, params) {
2114
+ const chart = findChartElement(ctx, params.slideIndex, params.elementId);
2115
+ pptxViewerCore.setChartColorMapOverride(chart, params.overrides);
2116
+ return { pptxData: ctx.pptxData, dirty: true, result: { elementId: params.elementId } };
2117
+ }
2118
+ function findChartElement2(ctx, slideIndex, elementId) {
2119
+ const err = validateSlideIndex(slideIndex, ctx.pptxData.slides.length);
2120
+ if (err) {
2121
+ throw new Error(err);
2122
+ }
2123
+ const slide = ctx.pptxData.slides[slideIndex];
2124
+ const el = slide.elements.find((e) => e.id === elementId);
2125
+ if (!el) {
2126
+ throw new Error(`Element '${elementId}' not found on slide ${slideIndex}.`);
2127
+ }
2128
+ if (el.type !== "chart") {
2129
+ throw new Error(`Element '${elementId}' is not a chart.`);
2130
+ }
2131
+ return el;
2132
+ }
1866
2133
  function buildShape(input) {
1867
2134
  return {
1868
2135
  kind: input.kind ?? "sp",
@@ -1878,17 +2145,17 @@ function buildShape(input) {
1878
2145
  };
1879
2146
  }
1880
2147
  function listChartUserShapesT(ctx, params) {
1881
- const chart = findChartElement(ctx, params.slideIndex, params.elementId);
2148
+ const chart = findChartElement2(ctx, params.slideIndex, params.elementId);
1882
2149
  return { pptxData: ctx.pptxData, dirty: false, result: { shapes: pptxViewerCore.listChartUserShapes(chart) } };
1883
2150
  }
1884
2151
  function addChartUserShapeT(ctx, params) {
1885
- const chart = findChartElement(ctx, params.slideIndex, params.elementId);
2152
+ const chart = findChartElement2(ctx, params.slideIndex, params.elementId);
1886
2153
  pptxViewerCore.addChartUserShape(chart, buildShape(params.shape));
1887
2154
  const index = (chart.chartData?.userShapes?.length ?? 1) - 1;
1888
2155
  return { pptxData: ctx.pptxData, dirty: true, result: { elementId: params.elementId, index } };
1889
2156
  }
1890
2157
  function updateChartUserShapeT(ctx, params) {
1891
- const chart = findChartElement(ctx, params.slideIndex, params.elementId);
2158
+ const chart = findChartElement2(ctx, params.slideIndex, params.elementId);
1892
2159
  const patch = {
1893
2160
  ...params.patch.kind ? { kind: params.patch.kind } : {},
1894
2161
  ...params.patch.anchor ? { anchor: params.patch.anchor } : {},
@@ -1905,7 +2172,7 @@ function updateChartUserShapeT(ctx, params) {
1905
2172
  return { pptxData: ctx.pptxData, dirty: true, result: { elementId: params.elementId } };
1906
2173
  }
1907
2174
  function removeChartUserShapeT(ctx, params) {
1908
- const chart = findChartElement(ctx, params.slideIndex, params.elementId);
2175
+ const chart = findChartElement2(ctx, params.slideIndex, params.elementId);
1909
2176
  pptxViewerCore.removeChartUserShape(chart, params.index);
1910
2177
  return { pptxData: ctx.pptxData, dirty: true, result: { elementId: params.elementId } };
1911
2178
  }
@@ -2661,12 +2928,15 @@ exports.applyLayout = applyLayout;
2661
2928
  exports.applyTemplateT = applyTemplateT;
2662
2929
  exports.applyThemePreset = applyThemePreset;
2663
2930
  exports.arrangeElements = arrangeElements;
2931
+ exports.assignTableStyle = assignTableStyle;
2664
2932
  exports.batchUpdateElements = batchUpdateElements;
2665
2933
  exports.cloneElement = cloneElement;
2666
2934
  exports.convertToMarkdown = convertToMarkdown;
2667
2935
  exports.createChart = createChart;
2936
+ exports.createTableStyle = createTableStyle;
2668
2937
  exports.deleteElements = deleteElements;
2669
2938
  exports.deleteSlides = deleteSlides;
2939
+ exports.deleteTableStyle = deleteTableStyle;
2670
2940
  exports.describeElement = describeElement;
2671
2941
  exports.diffPresentationsT = diffPresentationsT;
2672
2942
  exports.duplicateSlide = duplicateSlide;
@@ -2677,6 +2947,9 @@ exports.exportToSvg = exportToSvg;
2677
2947
  exports.extractSlideText = extractSlideText;
2678
2948
  exports.findPlaceholdersT = findPlaceholdersT;
2679
2949
  exports.findText = findText;
2950
+ exports.formatChartDataLabel = formatChartDataLabel;
2951
+ exports.formatChartDataPoint = formatChartDataPoint;
2952
+ exports.formatChartSeries = formatChartSeries;
2680
2953
  exports.generateElementId = generateElementId;
2681
2954
  exports.generateSlideId = generateSlideId;
2682
2955
  exports.getLayouts = getLayouts;
@@ -2704,9 +2977,12 @@ exports.replaceText = replaceText;
2704
2977
  exports.runAccessibilityCheck = runAccessibilityCheck;
2705
2978
  exports.savePresentation = savePresentation;
2706
2979
  exports.setCanvasSize = setCanvasSize;
2980
+ exports.setChartColorMapOverrideT = setChartColorMapOverrideT;
2981
+ exports.setChartHelperLineT = setChartHelperLineT;
2707
2982
  exports.setElementAnimation = setElementAnimation;
2708
2983
  exports.setElementLockT = setElementLockT;
2709
2984
  exports.setSlideTransition = setSlideTransition;
2985
+ exports.setTableStyleSection = setTableStyleSection;
2710
2986
  exports.ungroupElements = ungroupElements;
2711
2987
  exports.updateChart = updateChart;
2712
2988
  exports.updateChartSeriesData = updateChartSeriesData;