pptx-viewer-mcp 2.3.0 → 2.4.1

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.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { PptxHandler, hasTextProperties, resolveThemeColorRef, cloneElement as cloneElement$1, isTemplateElementId, makeStoreAwareId, reassignDescendantIds, groupElements as groupElements$1, ungroupElements as ungroupElements$1, TABLE_STYLE_PART_SEQUENCE, normalizeTableStyleGuid, createTableStyleEntry, addTableStyleToMap, deleteTableStyleFromMap, PptxMarkdownConverter, ThemePresets, getThemePreset, setChartType, setChartTitle, setChartGrouping, setChartLegend, setChartDataLabels, setChartAxis, setChartCategories, addChartSeries, removeChartSeries, updateChartSeriesValues, ChartBuilder, setChartDataPointStyle, setChartDataPointExplosion, setChartDataPointMarker, setChartDataPointLabel, setChartSeriesMarker, setChartSeriesTrendline, setChartSeriesErrorBars, setChartHelperLine, setChartColorMapOverride, listChartUserShapes, addChartUserShape, updateChartUserShape, removeChartUserShape, decomposeSmartArt, demoteSmartArtNode, promoteSmartArtNode, reorderSmartArtNode, updateSmartArtNodeText, removeSmartArtNode, addSmartArtNode, mergePresentation, diffPresentations, findPlaceholders, applyTemplate, getSectionForSlide, moveSlidesToSection, reorderSections, removeSection, addSection, SvgExporter, buildPptxJsonDocument, deserializePptxFromJson, applyImportedPptxData, replaceWithCustomGeometry, replaceShapeGeometry, setElementLocked, validatePptx, repairPptx, findLayoutByName, findLayoutByType } from 'pptx-viewer-core';
1
+ import { PptxHandler, hasTextProperties, resolveDisplayedChartTypeName, resolveThemeColorRef, cloneElement as cloneElement$1, isTemplateElementId, makeStoreAwareId, reassignDescendantIds, groupElements as groupElements$1, ungroupElements as ungroupElements$1, TABLE_STYLE_PART_SEQUENCE, normalizeTableStyleGuid, createTableStyleEntry, addTableStyleToMap, deleteTableStyleFromMap, PptxMarkdownConverter, ThemePresets, getThemePreset, setChartType, setChartTitle, setChartGrouping, setChartLegend, setChartDataLabels, setChartAxis, setChartCategories, addChartSeries, removeChartSeries, updateChartSeriesValues, ChartBuilder, setChartDataPointStyle, setChartDataPointExplosion, setChartDataPointMarker, setChartDataPointLabel, setChartSeriesMarker, setChartSeriesTrendline, setChartSeriesErrorBars, setChartHelperLine, setChartColorMapOverride, listChartUserShapes, addChartUserShape, updateChartUserShape, removeChartUserShape, decomposeSmartArt, demoteSmartArtNode, promoteSmartArtNode, reorderSmartArtNode, updateSmartArtNodeText, removeSmartArtNode, addSmartArtNode, mergePresentation, diffPresentations, findPlaceholders, applyTemplate, getSectionForSlide, moveSlidesToSection, reorderSections, removeSection, addSection, SvgExporter, buildPptxJsonDocument, deserializePptxFromJson, applyImportedPptxData, replaceWithCustomGeometry, replaceShapeGeometry, setElementLocked, validatePptx, repairPptx, findLayoutByName, findLayoutByType } from 'pptx-viewer-core';
2
2
  export { PptxHandler } from 'pptx-viewer-core';
3
3
 
4
4
  // src/execution.ts
@@ -165,8 +165,8 @@ function describeElement(el) {
165
165
  base.cells = tbl.tableData.rows.map((row) => row.cells.map((cell) => cell.text ?? ""));
166
166
  }
167
167
  }
168
- if (el.type === "chart") {
169
- base.chartType = el.chartData?.type;
168
+ if (el.type === "chart" && el.chartData) {
169
+ base.chartType = resolveDisplayedChartTypeName(el.chartData);
170
170
  }
171
171
  if (el.type === "group") {
172
172
  const grp = el;
@@ -394,6 +394,240 @@ function setCanvasSize(ctx, params) {
394
394
  result: { canvasWidth: params.width, canvasHeight: params.height }
395
395
  };
396
396
  }
397
+ var ALT_TEXT_ELEMENT_TYPES = /* @__PURE__ */ new Set(["image", "picture", "table", "chart", "smartArt", "ole", "media", "text", "shape", "connector"]);
398
+ var TITLE_ELEMENT_TYPES = /* @__PURE__ */ new Set([
399
+ "table",
400
+ "chart",
401
+ "smartArt",
402
+ "ole",
403
+ "media",
404
+ "text",
405
+ "shape",
406
+ "connector"
407
+ ]);
408
+ function applyElementAltText(el, altText) {
409
+ if (!ALT_TEXT_ELEMENT_TYPES.has(el.type)) {
410
+ throw new Error(
411
+ `Element '${el.id}' (${el.type}) does not support altText; only ${[...ALT_TEXT_ELEMENT_TYPES].join(", ")} elements do.`
412
+ );
413
+ }
414
+ el.altText = altText;
415
+ }
416
+ function applyElementTitle(el, title) {
417
+ if (!TITLE_ELEMENT_TYPES.has(el.type)) {
418
+ throw new Error(
419
+ `Element '${el.id}' (${el.type}) does not support title; only ${[...TITLE_ELEMENT_TYPES].join(", ")} elements do.`
420
+ );
421
+ }
422
+ el.title = title;
423
+ }
424
+ function updateElementStyle(ctx, params) {
425
+ const err = validateSlideIndex(params.slideIndex, ctx.pptxData.slides.length);
426
+ if (err) {
427
+ throw new Error(err);
428
+ }
429
+ const slide = ctx.pptxData.slides[params.slideIndex];
430
+ const el = slide.elements.find((e) => e.id === params.elementId);
431
+ if (!el) {
432
+ throw new Error(`Element '${params.elementId}' not found on slide ${params.slideIndex}.`);
433
+ }
434
+ if ("shapeStyle" in el) {
435
+ if (!el.shapeStyle) {
436
+ el.shapeStyle = {};
437
+ }
438
+ const ss = el.shapeStyle;
439
+ if (params.fillThemeColor !== void 0) {
440
+ ss.fillColorRef = params.fillThemeColor;
441
+ const resolved = resolveThemeColorRef(params.fillThemeColor, ctx.pptxData.themeColorMap);
442
+ if (params.fillColor !== void 0) {
443
+ ss.fillColor = params.fillColor;
444
+ } else if (resolved) {
445
+ ss.fillColor = resolved;
446
+ }
447
+ } else if (params.fillColor !== void 0) {
448
+ ss.fillColor = params.fillColor;
449
+ ss.fillColorRef = void 0;
450
+ }
451
+ if (params.fillMode !== void 0) {
452
+ ss.fillMode = params.fillMode;
453
+ }
454
+ if (params.fillGradientStops !== void 0) {
455
+ ss.fillGradientStops = params.fillGradientStops;
456
+ }
457
+ if (params.fillGradientAngle !== void 0) {
458
+ ss.fillGradientAngle = params.fillGradientAngle;
459
+ }
460
+ if (params.fillGradientType !== void 0) {
461
+ ss.fillGradientType = params.fillGradientType;
462
+ }
463
+ if (params.fillOpacity !== void 0) {
464
+ ss.fillOpacity = params.fillOpacity;
465
+ }
466
+ if (params.strokeThemeColor !== void 0) {
467
+ ss.strokeColorRef = params.strokeThemeColor;
468
+ const resolved = resolveThemeColorRef(params.strokeThemeColor, ctx.pptxData.themeColorMap);
469
+ if (params.strokeColor !== void 0) {
470
+ ss.strokeColor = params.strokeColor;
471
+ } else if (resolved) {
472
+ ss.strokeColor = resolved;
473
+ }
474
+ } else if (params.strokeColor !== void 0) {
475
+ ss.strokeColor = params.strokeColor;
476
+ ss.strokeColorRef = void 0;
477
+ }
478
+ if (params.strokeWidth !== void 0) {
479
+ ss.strokeWidth = params.strokeWidth;
480
+ }
481
+ if (params.strokeDash !== void 0) {
482
+ ss.strokeDash = params.strokeDash;
483
+ }
484
+ if (params.strokeOpacity !== void 0) {
485
+ ss.strokeOpacity = params.strokeOpacity;
486
+ }
487
+ if (params.shadowColor !== void 0) {
488
+ ss.shadowColor = params.shadowColor;
489
+ }
490
+ if (params.shadowBlur !== void 0) {
491
+ ss.shadowBlur = params.shadowBlur;
492
+ }
493
+ if (params.shadowOffsetX !== void 0) {
494
+ ss.shadowOffsetX = params.shadowOffsetX;
495
+ }
496
+ if (params.shadowOffsetY !== void 0) {
497
+ ss.shadowOffsetY = params.shadowOffsetY;
498
+ }
499
+ if (params.shadowOpacity !== void 0) {
500
+ ss.shadowOpacity = params.shadowOpacity;
501
+ }
502
+ if (params.glowColor !== void 0) {
503
+ ss.glowColor = params.glowColor;
504
+ }
505
+ if (params.glowRadius !== void 0) {
506
+ ss.glowRadius = params.glowRadius;
507
+ }
508
+ if (params.glowOpacity !== void 0) {
509
+ ss.glowOpacity = params.glowOpacity;
510
+ }
511
+ if (params.softEdgeRadius !== void 0) {
512
+ ss.softEdgeRadius = params.softEdgeRadius;
513
+ }
514
+ }
515
+ if (params.altText !== void 0) {
516
+ applyElementAltText(el, params.altText);
517
+ }
518
+ if (params.title !== void 0) {
519
+ applyElementTitle(el, params.title);
520
+ }
521
+ if (el.type === "image" || el.type === "picture") {
522
+ const img = el;
523
+ if (params.cropLeft !== void 0) {
524
+ img.cropLeft = params.cropLeft;
525
+ }
526
+ if (params.cropTop !== void 0) {
527
+ img.cropTop = params.cropTop;
528
+ }
529
+ if (params.cropRight !== void 0) {
530
+ img.cropRight = params.cropRight;
531
+ }
532
+ if (params.cropBottom !== void 0) {
533
+ img.cropBottom = params.cropBottom;
534
+ }
535
+ if (params.brightness !== void 0 || params.contrast !== void 0 || params.grayscale !== void 0) {
536
+ if (!img.imageEffects) {
537
+ img.imageEffects = {};
538
+ }
539
+ if (params.brightness !== void 0) {
540
+ img.imageEffects.brightness = params.brightness;
541
+ }
542
+ if (params.contrast !== void 0) {
543
+ img.imageEffects.contrast = params.contrast;
544
+ }
545
+ if (params.grayscale !== void 0) {
546
+ img.imageEffects.grayscale = params.grayscale;
547
+ }
548
+ }
549
+ }
550
+ return {
551
+ pptxData: ctx.pptxData,
552
+ dirty: true,
553
+ result: { elementId: params.elementId }
554
+ };
555
+ }
556
+ function runAccessibilityCheck(ctx) {
557
+ const issues = [];
558
+ for (let si = 0; si < ctx.pptxData.slides.length; si++) {
559
+ const slide = ctx.pptxData.slides[si];
560
+ let slideHasText = false;
561
+ for (const el of slide.elements) {
562
+ if (el.type === "image" || el.type === "picture") {
563
+ const img = el;
564
+ if (!img.altText) {
565
+ issues.push({
566
+ slideIndex: si,
567
+ elementId: el.id,
568
+ severity: "error",
569
+ message: `Image element '${el.id}' has no alt text.`
570
+ });
571
+ }
572
+ }
573
+ if (hasTextProperties(el)) {
574
+ const textEl = el;
575
+ slideHasText = true;
576
+ if (!textEl.text || textEl.text.trim() === "") {
577
+ issues.push({
578
+ slideIndex: si,
579
+ elementId: el.id,
580
+ severity: "info",
581
+ message: `Text element '${el.id}' is empty.`
582
+ });
583
+ }
584
+ const fs = textEl.textStyle?.fontSize;
585
+ if (fs !== void 0 && fs < 10) {
586
+ issues.push({
587
+ slideIndex: si,
588
+ elementId: el.id,
589
+ severity: "warning",
590
+ message: `Text element '${el.id}' has very small font size (${fs}pt < 10pt).`
591
+ });
592
+ }
593
+ const textColor = textEl.textStyle?.color?.toLowerCase();
594
+ const bgColor = slide.backgroundColor?.toLowerCase();
595
+ if (textColor && bgColor && textColor === bgColor) {
596
+ issues.push({
597
+ slideIndex: si,
598
+ elementId: el.id,
599
+ severity: "error",
600
+ message: `Text element '${el.id}' has same color as slide background (${textColor}).`
601
+ });
602
+ }
603
+ }
604
+ }
605
+ if (!slideHasText) {
606
+ issues.push({
607
+ slideIndex: si,
608
+ severity: "warning",
609
+ message: `Slide ${si + 1} contains no text elements.`
610
+ });
611
+ }
612
+ }
613
+ const errorCount = issues.filter((i) => i.severity === "error").length;
614
+ const warningCount = issues.filter((i) => i.severity === "warning").length;
615
+ const infoCount = issues.filter((i) => i.severity === "info").length;
616
+ return {
617
+ pptxData: ctx.pptxData,
618
+ dirty: false,
619
+ result: {
620
+ slideCount: ctx.pptxData.slides.length,
621
+ totalIssues: issues.length,
622
+ errorCount,
623
+ warningCount,
624
+ infoCount,
625
+ issues
626
+ }
627
+ };
628
+ }
629
+
630
+ // src/tools/element-tools.ts
397
631
  function addElement(ctx, params) {
398
632
  const err = validateSlideIndex(params.slideIndex, ctx.pptxData.slides.length);
399
633
  if (err) {
@@ -573,6 +807,12 @@ function updateElement(ctx, params) {
573
807
  if (params.flipV !== void 0) {
574
808
  el.flipVertical = params.flipV;
575
809
  }
810
+ if (params.altText !== void 0) {
811
+ applyElementAltText(el, params.altText);
812
+ }
813
+ if (params.title !== void 0) {
814
+ applyElementTitle(el, params.title);
815
+ }
576
816
  if (hasTextProperties(el)) {
577
817
  const textEl = el;
578
818
  if (params.text !== void 0) {
@@ -1229,208 +1469,6 @@ function assignTableStyle(ctx, params) {
1229
1469
  result: { elementId: params.elementId, styleId: normalizedId }
1230
1470
  };
1231
1471
  }
1232
- function updateElementStyle(ctx, params) {
1233
- const err = validateSlideIndex(params.slideIndex, ctx.pptxData.slides.length);
1234
- if (err) {
1235
- throw new Error(err);
1236
- }
1237
- const slide = ctx.pptxData.slides[params.slideIndex];
1238
- const el = slide.elements.find((e) => e.id === params.elementId);
1239
- if (!el) {
1240
- throw new Error(`Element '${params.elementId}' not found on slide ${params.slideIndex}.`);
1241
- }
1242
- if ("shapeStyle" in el) {
1243
- if (!el.shapeStyle) {
1244
- el.shapeStyle = {};
1245
- }
1246
- const ss = el.shapeStyle;
1247
- if (params.fillThemeColor !== void 0) {
1248
- ss.fillColorRef = params.fillThemeColor;
1249
- const resolved = resolveThemeColorRef(params.fillThemeColor, ctx.pptxData.themeColorMap);
1250
- if (params.fillColor !== void 0) {
1251
- ss.fillColor = params.fillColor;
1252
- } else if (resolved) {
1253
- ss.fillColor = resolved;
1254
- }
1255
- } else if (params.fillColor !== void 0) {
1256
- ss.fillColor = params.fillColor;
1257
- ss.fillColorRef = void 0;
1258
- }
1259
- if (params.fillMode !== void 0) {
1260
- ss.fillMode = params.fillMode;
1261
- }
1262
- if (params.fillGradientStops !== void 0) {
1263
- ss.fillGradientStops = params.fillGradientStops;
1264
- }
1265
- if (params.fillGradientAngle !== void 0) {
1266
- ss.fillGradientAngle = params.fillGradientAngle;
1267
- }
1268
- if (params.fillGradientType !== void 0) {
1269
- ss.fillGradientType = params.fillGradientType;
1270
- }
1271
- if (params.fillOpacity !== void 0) {
1272
- ss.fillOpacity = params.fillOpacity;
1273
- }
1274
- if (params.strokeThemeColor !== void 0) {
1275
- ss.strokeColorRef = params.strokeThemeColor;
1276
- const resolved = resolveThemeColorRef(params.strokeThemeColor, ctx.pptxData.themeColorMap);
1277
- if (params.strokeColor !== void 0) {
1278
- ss.strokeColor = params.strokeColor;
1279
- } else if (resolved) {
1280
- ss.strokeColor = resolved;
1281
- }
1282
- } else if (params.strokeColor !== void 0) {
1283
- ss.strokeColor = params.strokeColor;
1284
- ss.strokeColorRef = void 0;
1285
- }
1286
- if (params.strokeWidth !== void 0) {
1287
- ss.strokeWidth = params.strokeWidth;
1288
- }
1289
- if (params.strokeDash !== void 0) {
1290
- ss.strokeDash = params.strokeDash;
1291
- }
1292
- if (params.strokeOpacity !== void 0) {
1293
- ss.strokeOpacity = params.strokeOpacity;
1294
- }
1295
- if (params.shadowColor !== void 0) {
1296
- ss.shadowColor = params.shadowColor;
1297
- }
1298
- if (params.shadowBlur !== void 0) {
1299
- ss.shadowBlur = params.shadowBlur;
1300
- }
1301
- if (params.shadowOffsetX !== void 0) {
1302
- ss.shadowOffsetX = params.shadowOffsetX;
1303
- }
1304
- if (params.shadowOffsetY !== void 0) {
1305
- ss.shadowOffsetY = params.shadowOffsetY;
1306
- }
1307
- if (params.shadowOpacity !== void 0) {
1308
- ss.shadowOpacity = params.shadowOpacity;
1309
- }
1310
- if (params.glowColor !== void 0) {
1311
- ss.glowColor = params.glowColor;
1312
- }
1313
- if (params.glowRadius !== void 0) {
1314
- ss.glowRadius = params.glowRadius;
1315
- }
1316
- if (params.glowOpacity !== void 0) {
1317
- ss.glowOpacity = params.glowOpacity;
1318
- }
1319
- if (params.softEdgeRadius !== void 0) {
1320
- ss.softEdgeRadius = params.softEdgeRadius;
1321
- }
1322
- }
1323
- if (el.type === "image" || el.type === "picture") {
1324
- const img = el;
1325
- if (params.altText !== void 0) {
1326
- img.altText = params.altText;
1327
- }
1328
- if (params.cropLeft !== void 0) {
1329
- img.cropLeft = params.cropLeft;
1330
- }
1331
- if (params.cropTop !== void 0) {
1332
- img.cropTop = params.cropTop;
1333
- }
1334
- if (params.cropRight !== void 0) {
1335
- img.cropRight = params.cropRight;
1336
- }
1337
- if (params.cropBottom !== void 0) {
1338
- img.cropBottom = params.cropBottom;
1339
- }
1340
- if (params.brightness !== void 0 || params.contrast !== void 0 || params.grayscale !== void 0) {
1341
- if (!img.imageEffects) {
1342
- img.imageEffects = {};
1343
- }
1344
- if (params.brightness !== void 0) {
1345
- img.imageEffects.brightness = params.brightness;
1346
- }
1347
- if (params.contrast !== void 0) {
1348
- img.imageEffects.contrast = params.contrast;
1349
- }
1350
- if (params.grayscale !== void 0) {
1351
- img.imageEffects.grayscale = params.grayscale;
1352
- }
1353
- }
1354
- }
1355
- return {
1356
- pptxData: ctx.pptxData,
1357
- dirty: true,
1358
- result: { elementId: params.elementId }
1359
- };
1360
- }
1361
- function runAccessibilityCheck(ctx) {
1362
- const issues = [];
1363
- for (let si = 0; si < ctx.pptxData.slides.length; si++) {
1364
- const slide = ctx.pptxData.slides[si];
1365
- let slideHasText = false;
1366
- for (const el of slide.elements) {
1367
- if (el.type === "image" || el.type === "picture") {
1368
- const img = el;
1369
- if (!img.altText) {
1370
- issues.push({
1371
- slideIndex: si,
1372
- elementId: el.id,
1373
- severity: "error",
1374
- message: `Image element '${el.id}' has no alt text.`
1375
- });
1376
- }
1377
- }
1378
- if (hasTextProperties(el)) {
1379
- const textEl = el;
1380
- slideHasText = true;
1381
- if (!textEl.text || textEl.text.trim() === "") {
1382
- issues.push({
1383
- slideIndex: si,
1384
- elementId: el.id,
1385
- severity: "info",
1386
- message: `Text element '${el.id}' is empty.`
1387
- });
1388
- }
1389
- const fs = textEl.textStyle?.fontSize;
1390
- if (fs !== void 0 && fs < 10) {
1391
- issues.push({
1392
- slideIndex: si,
1393
- elementId: el.id,
1394
- severity: "warning",
1395
- message: `Text element '${el.id}' has very small font size (${fs}pt < 10pt).`
1396
- });
1397
- }
1398
- const textColor = textEl.textStyle?.color?.toLowerCase();
1399
- const bgColor = slide.backgroundColor?.toLowerCase();
1400
- if (textColor && bgColor && textColor === bgColor) {
1401
- issues.push({
1402
- slideIndex: si,
1403
- elementId: el.id,
1404
- severity: "error",
1405
- message: `Text element '${el.id}' has same color as slide background (${textColor}).`
1406
- });
1407
- }
1408
- }
1409
- }
1410
- if (!slideHasText) {
1411
- issues.push({
1412
- slideIndex: si,
1413
- severity: "warning",
1414
- message: `Slide ${si + 1} contains no text elements.`
1415
- });
1416
- }
1417
- }
1418
- const errorCount = issues.filter((i) => i.severity === "error").length;
1419
- const warningCount = issues.filter((i) => i.severity === "warning").length;
1420
- const infoCount = issues.filter((i) => i.severity === "info").length;
1421
- return {
1422
- pptxData: ctx.pptxData,
1423
- dirty: false,
1424
- result: {
1425
- slideCount: ctx.pptxData.slides.length,
1426
- totalIssues: issues.length,
1427
- errorCount,
1428
- warningCount,
1429
- infoCount,
1430
- issues
1431
- }
1432
- };
1433
- }
1434
1472
  var MAX_REGEX_LEN = 200;
1435
1473
  function hasNestedUnboundedQuantifier(pattern) {
1436
1474
  return /\([^)]*[+*]\)[+*]/u.test(pattern);