pptx-viewer-mcp 1.1.26 → 1.2.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.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { PptxHandler, hasTextProperties, PptxMarkdownConverter } from 'pptx-viewer-core';
1
+ import { PptxHandler, hasTextProperties, PptxMarkdownConverter, ThemePresets, getThemePreset, setChartType, setChartTitle, setChartGrouping, setChartLegend, setChartDataLabels, setChartAxis, setChartCategories, addChartSeries, removeChartSeries, updateChartSeriesValues, ChartBuilder, decomposeSmartArt, demoteSmartArtNode, promoteSmartArtNode, reorderSmartArtNode, updateSmartArtNodeText, removeSmartArtNode, addSmartArtNode, mergePresentation, diffPresentations, findPlaceholders, applyTemplate, getSectionForSlide, moveSlidesToSection, reorderSections, removeSection, addSection, SvgExporter, replaceWithCustomGeometry, replaceShapeGeometry, setElementLocked, validatePptx, repairPptx, findLayoutByName, findLayoutByType } from 'pptx-viewer-core';
2
2
  export { PptxHandler } from 'pptx-viewer-core';
3
3
  import { resolve, isAbsolute, sep } from 'path';
4
4
 
@@ -1587,5 +1587,945 @@ async function convertToMarkdown(ctx, params) {
1587
1587
  }
1588
1588
  };
1589
1589
  }
1590
+ function getThemeInfo(ctx) {
1591
+ const theme = ctx.pptxData.theme;
1592
+ return {
1593
+ pptxData: ctx.pptxData,
1594
+ dirty: false,
1595
+ result: {
1596
+ themeName: theme?.name,
1597
+ colorScheme: theme?.colorScheme,
1598
+ fontScheme: theme?.fontScheme,
1599
+ availablePresets: Object.keys(ThemePresets)
1600
+ }
1601
+ };
1602
+ }
1603
+ function applyThemePreset(ctx, params) {
1604
+ const preset = getThemePreset(params.presetName);
1605
+ if (!preset) {
1606
+ throw new Error(
1607
+ `Unknown theme preset: "${params.presetName}". Available: ${Object.keys(ThemePresets).join(", ")}`
1608
+ );
1609
+ }
1610
+ if (!ctx.pptxData.theme) {
1611
+ ctx.pptxData.theme = {};
1612
+ }
1613
+ const theme = ctx.pptxData.theme;
1614
+ theme.name = preset.name;
1615
+ theme.colorScheme = preset.colors;
1616
+ if (preset.fonts) {
1617
+ theme.fontScheme = preset.fonts;
1618
+ }
1619
+ return {
1620
+ pptxData: ctx.pptxData,
1621
+ dirty: true,
1622
+ result: {
1623
+ appliedPreset: params.presetName,
1624
+ colorScheme: theme.colorScheme
1625
+ }
1626
+ };
1627
+ }
1628
+ function updateThemeColors(ctx, params) {
1629
+ if (!ctx.pptxData.theme) {
1630
+ ctx.pptxData.theme = {};
1631
+ }
1632
+ const theme = ctx.pptxData.theme;
1633
+ if (!theme.colorScheme) {
1634
+ theme.colorScheme = {
1635
+ dk1: "#000000",
1636
+ lt1: "#FFFFFF",
1637
+ dk2: "#44546A",
1638
+ lt2: "#E7E6E6",
1639
+ accent1: "#4472C4",
1640
+ accent2: "#ED7D31",
1641
+ accent3: "#A5A5A5",
1642
+ accent4: "#FFC000",
1643
+ accent5: "#5B9BD5",
1644
+ accent6: "#70AD47",
1645
+ hlink: "#0563C1",
1646
+ folHlink: "#954F72"
1647
+ };
1648
+ }
1649
+ const cs = theme.colorScheme;
1650
+ for (const key of Object.keys(params)) {
1651
+ if (params[key] !== void 0) {
1652
+ cs[key] = params[key];
1653
+ }
1654
+ }
1655
+ return {
1656
+ pptxData: ctx.pptxData,
1657
+ dirty: true,
1658
+ result: { colorScheme: cs }
1659
+ };
1660
+ }
1661
+ function updateThemeFonts(ctx, params) {
1662
+ if (!ctx.pptxData.theme) {
1663
+ ctx.pptxData.theme = {};
1664
+ }
1665
+ const theme = ctx.pptxData.theme;
1666
+ if (!theme.fontScheme) {
1667
+ theme.fontScheme = {};
1668
+ }
1669
+ if (params.majorFont !== void 0) {
1670
+ theme.fontScheme.majorFont = { latin: params.majorFont };
1671
+ }
1672
+ if (params.minorFont !== void 0) {
1673
+ theme.fontScheme.minorFont = { latin: params.minorFont };
1674
+ }
1675
+ return {
1676
+ pptxData: ctx.pptxData,
1677
+ dirty: true,
1678
+ result: { fontScheme: theme.fontScheme }
1679
+ };
1680
+ }
1681
+ function updateChart(ctx, params) {
1682
+ const err = validateSlideIndex(params.slideIndex, ctx.pptxData.slides.length);
1683
+ if (err) {
1684
+ throw new Error(err);
1685
+ }
1686
+ const slide = ctx.pptxData.slides[params.slideIndex];
1687
+ const el = slide.elements.find((e) => e.id === params.elementId);
1688
+ if (!el) {
1689
+ throw new Error(`Element '${params.elementId}' not found on slide ${params.slideIndex}.`);
1690
+ }
1691
+ if (el.type !== "chart") {
1692
+ throw new Error(`Element '${params.elementId}' is not a chart.`);
1693
+ }
1694
+ const chart = el;
1695
+ if (params.chartType) {
1696
+ setChartType(chart, params.chartType);
1697
+ }
1698
+ if (params.title !== void 0) {
1699
+ setChartTitle(chart, params.title);
1700
+ }
1701
+ if (params.grouping) {
1702
+ setChartGrouping(chart, params.grouping);
1703
+ }
1704
+ if (params.legend) {
1705
+ setChartLegend(chart, {
1706
+ show: params.legend.show,
1707
+ position: params.legend.position
1708
+ });
1709
+ }
1710
+ if (params.dataLabels) {
1711
+ setChartDataLabels(chart, params.dataLabels);
1712
+ }
1713
+ if (params.axis) {
1714
+ setChartAxis(chart, params.axis.type, params.axis.edit);
1715
+ }
1716
+ if (params.categories) {
1717
+ setChartCategories(chart, params.categories);
1718
+ }
1719
+ return { pptxData: ctx.pptxData, dirty: true, result: { elementId: params.elementId } };
1720
+ }
1721
+ function addChartSeriesT(ctx, params) {
1722
+ const err = validateSlideIndex(params.slideIndex, ctx.pptxData.slides.length);
1723
+ if (err) {
1724
+ throw new Error(err);
1725
+ }
1726
+ const slide = ctx.pptxData.slides[params.slideIndex];
1727
+ const el = slide.elements.find((e) => e.id === params.elementId);
1728
+ if (!el) {
1729
+ throw new Error(`Element '${params.elementId}' not found on slide ${params.slideIndex}.`);
1730
+ }
1731
+ if (el.type !== "chart") {
1732
+ throw new Error(`Element '${params.elementId}' is not a chart.`);
1733
+ }
1734
+ const chart = el;
1735
+ addChartSeries(chart, { name: params.name, values: params.values, color: params.color });
1736
+ const seriesCount = chart.chartData?.series?.length ?? 0;
1737
+ return {
1738
+ pptxData: ctx.pptxData,
1739
+ dirty: true,
1740
+ result: { elementId: params.elementId, seriesCount }
1741
+ };
1742
+ }
1743
+ function removeChartSeriesT(ctx, params) {
1744
+ const err = validateSlideIndex(params.slideIndex, ctx.pptxData.slides.length);
1745
+ if (err) {
1746
+ throw new Error(err);
1747
+ }
1748
+ const slide = ctx.pptxData.slides[params.slideIndex];
1749
+ const el = slide.elements.find((e) => e.id === params.elementId);
1750
+ if (!el) {
1751
+ throw new Error(`Element '${params.elementId}' not found on slide ${params.slideIndex}.`);
1752
+ }
1753
+ if (el.type !== "chart") {
1754
+ throw new Error(`Element '${params.elementId}' is not a chart.`);
1755
+ }
1756
+ const chart = el;
1757
+ removeChartSeries(chart, params.seriesIndex);
1758
+ const seriesCount = chart.chartData?.series?.length ?? 0;
1759
+ return {
1760
+ pptxData: ctx.pptxData,
1761
+ dirty: true,
1762
+ result: { elementId: params.elementId, seriesCount }
1763
+ };
1764
+ }
1765
+ function updateChartSeriesData(ctx, params) {
1766
+ const err = validateSlideIndex(params.slideIndex, ctx.pptxData.slides.length);
1767
+ if (err) {
1768
+ throw new Error(err);
1769
+ }
1770
+ const slide = ctx.pptxData.slides[params.slideIndex];
1771
+ const el = slide.elements.find((e) => e.id === params.elementId);
1772
+ if (!el) {
1773
+ throw new Error(`Element '${params.elementId}' not found on slide ${params.slideIndex}.`);
1774
+ }
1775
+ if (el.type !== "chart") {
1776
+ throw new Error(`Element '${params.elementId}' is not a chart.`);
1777
+ }
1778
+ const chart = el;
1779
+ updateChartSeriesValues(chart, params.seriesIndex, params.values);
1780
+ return { pptxData: ctx.pptxData, dirty: true, result: { elementId: params.elementId } };
1781
+ }
1782
+ function createChart(ctx, params) {
1783
+ const err = validateSlideIndex(params.slideIndex, ctx.pptxData.slides.length);
1784
+ if (err) {
1785
+ throw new Error(err);
1786
+ }
1787
+ const builder = ChartBuilder.create(
1788
+ params.chartType
1789
+ );
1790
+ builder.position(params.x ?? 100, params.y ?? 100);
1791
+ builder.size(params.width ?? 500, params.height ?? 350);
1792
+ if (params.title) {
1793
+ builder.title(params.title);
1794
+ }
1795
+ if (params.categories) {
1796
+ builder.categories(params.categories);
1797
+ }
1798
+ if (params.series) {
1799
+ for (const s of params.series) {
1800
+ builder.addSeries(s.name, s.values, s.color);
1801
+ }
1802
+ }
1803
+ if (params.legend) {
1804
+ builder.legend(
1805
+ params.legend.show,
1806
+ params.legend.position
1807
+ );
1808
+ }
1809
+ const chart = builder.build();
1810
+ const slide = ctx.pptxData.slides[params.slideIndex];
1811
+ slide.elements.push(chart);
1812
+ return {
1813
+ pptxData: ctx.pptxData,
1814
+ dirty: true,
1815
+ result: { elementId: chart.id, slideIndex: params.slideIndex }
1816
+ };
1817
+ }
1818
+ function extractNodes(data) {
1819
+ if (!data.nodes) {
1820
+ return [];
1821
+ }
1822
+ return data.nodes.map((n) => ({
1823
+ id: n.id,
1824
+ text: n.text ?? "",
1825
+ children: n.children?.map((c) => ({ id: c.id, text: c.text ?? "" }))
1826
+ }));
1827
+ }
1828
+ function manageSmartArt(ctx, params) {
1829
+ const err = validateSlideIndex(params.slideIndex, ctx.pptxData.slides.length);
1830
+ if (err) {
1831
+ throw new Error(err);
1832
+ }
1833
+ const slide = ctx.pptxData.slides[params.slideIndex];
1834
+ const el = slide.elements.find((e) => e.id === params.elementId);
1835
+ if (!el) {
1836
+ throw new Error(`Element '${params.elementId}' not found on slide ${params.slideIndex}.`);
1837
+ }
1838
+ if (el.type !== "smartArt") {
1839
+ throw new Error(`Element '${params.elementId}' is not a SmartArt.`);
1840
+ }
1841
+ const smartArt = el;
1842
+ if (!smartArt.smartArtData) {
1843
+ throw new Error(`SmartArt '${params.elementId}' has no data.`);
1844
+ }
1845
+ switch (params.action) {
1846
+ case "getNodes": {
1847
+ return {
1848
+ pptxData: ctx.pptxData,
1849
+ dirty: false,
1850
+ result: {
1851
+ action: "getNodes",
1852
+ elementId: params.elementId,
1853
+ nodes: extractNodes(smartArt.smartArtData)
1854
+ }
1855
+ };
1856
+ }
1857
+ case "addNode": {
1858
+ smartArt.smartArtData = addSmartArtNode(
1859
+ smartArt.smartArtData,
1860
+ params.text ?? "",
1861
+ params.afterNodeId
1862
+ );
1863
+ return {
1864
+ pptxData: ctx.pptxData,
1865
+ dirty: true,
1866
+ result: {
1867
+ action: "addNode",
1868
+ elementId: params.elementId,
1869
+ nodes: extractNodes(smartArt.smartArtData)
1870
+ }
1871
+ };
1872
+ }
1873
+ case "removeNode": {
1874
+ if (!params.nodeId) {
1875
+ throw new Error("nodeId is required for removeNode.");
1876
+ }
1877
+ smartArt.smartArtData = removeSmartArtNode(smartArt.smartArtData, params.nodeId);
1878
+ return {
1879
+ pptxData: ctx.pptxData,
1880
+ dirty: true,
1881
+ result: {
1882
+ action: "removeNode",
1883
+ elementId: params.elementId,
1884
+ nodes: extractNodes(smartArt.smartArtData)
1885
+ }
1886
+ };
1887
+ }
1888
+ case "updateNodeText": {
1889
+ if (!params.nodeId) {
1890
+ throw new Error("nodeId is required for updateNodeText.");
1891
+ }
1892
+ smartArt.smartArtData = updateSmartArtNodeText(
1893
+ smartArt.smartArtData,
1894
+ params.nodeId,
1895
+ params.text ?? ""
1896
+ );
1897
+ return {
1898
+ pptxData: ctx.pptxData,
1899
+ dirty: true,
1900
+ result: { action: "updateNodeText", elementId: params.elementId }
1901
+ };
1902
+ }
1903
+ case "reorderNode": {
1904
+ if (!params.nodeId) {
1905
+ throw new Error("nodeId is required for reorderNode.");
1906
+ }
1907
+ const dir = params.direction ?? 1;
1908
+ smartArt.smartArtData = reorderSmartArtNode(smartArt.smartArtData, params.nodeId, dir);
1909
+ return {
1910
+ pptxData: ctx.pptxData,
1911
+ dirty: true,
1912
+ result: {
1913
+ action: "reorderNode",
1914
+ elementId: params.elementId,
1915
+ nodes: extractNodes(smartArt.smartArtData)
1916
+ }
1917
+ };
1918
+ }
1919
+ case "promoteNode": {
1920
+ if (!params.nodeId) {
1921
+ throw new Error("nodeId is required for promoteNode.");
1922
+ }
1923
+ smartArt.smartArtData = promoteSmartArtNode(smartArt.smartArtData, params.nodeId);
1924
+ return {
1925
+ pptxData: ctx.pptxData,
1926
+ dirty: true,
1927
+ result: {
1928
+ action: "promoteNode",
1929
+ elementId: params.elementId,
1930
+ nodes: extractNodes(smartArt.smartArtData)
1931
+ }
1932
+ };
1933
+ }
1934
+ case "demoteNode": {
1935
+ if (!params.nodeId) {
1936
+ throw new Error("nodeId is required for demoteNode.");
1937
+ }
1938
+ smartArt.smartArtData = demoteSmartArtNode(smartArt.smartArtData, params.nodeId);
1939
+ return {
1940
+ pptxData: ctx.pptxData,
1941
+ dirty: true,
1942
+ result: {
1943
+ action: "demoteNode",
1944
+ elementId: params.elementId,
1945
+ nodes: extractNodes(smartArt.smartArtData)
1946
+ }
1947
+ };
1948
+ }
1949
+ case "decompose": {
1950
+ const bounds = {
1951
+ x: smartArt.x,
1952
+ y: smartArt.y,
1953
+ width: smartArt.width,
1954
+ height: smartArt.height
1955
+ };
1956
+ const decomposed = decomposeSmartArt(smartArt.smartArtData, bounds);
1957
+ if (!decomposed || decomposed.length === 0) {
1958
+ throw new Error("Failed to decompose SmartArt into shapes.");
1959
+ }
1960
+ const idx = slide.elements.indexOf(el);
1961
+ slide.elements.splice(idx, 1, ...decomposed);
1962
+ return {
1963
+ pptxData: ctx.pptxData,
1964
+ dirty: true,
1965
+ result: {
1966
+ action: "decompose",
1967
+ elementId: params.elementId,
1968
+ decomposedCount: decomposed.length
1969
+ }
1970
+ };
1971
+ }
1972
+ default:
1973
+ throw new Error(`Unknown SmartArt action: ${String(params.action)}`);
1974
+ }
1975
+ }
1976
+ function mergePresentationT(ctx, params) {
1977
+ const options = {};
1978
+ if (params.slideIndices) {
1979
+ options.slideIndices = params.slideIndices;
1980
+ }
1981
+ if (params.insertAt !== void 0) {
1982
+ options.insertAt = params.insertAt;
1983
+ }
1984
+ if (params.keepSourceTheme !== void 0) {
1985
+ options.keepSourceTheme = params.keepSourceTheme;
1986
+ }
1987
+ const added = mergePresentation(ctx.pptxData, params.sourceData, options);
1988
+ return {
1989
+ pptxData: ctx.pptxData,
1990
+ dirty: added > 0,
1991
+ result: { slidesAdded: added, totalSlides: ctx.pptxData.slides.length }
1992
+ };
1993
+ }
1994
+ function diffPresentationsT(ctx, params) {
1995
+ const diff = diffPresentations(ctx.pptxData, params.otherData);
1996
+ return {
1997
+ pptxData: ctx.pptxData,
1998
+ dirty: false,
1999
+ result: diff
2000
+ };
2001
+ }
2002
+ function findPlaceholdersT(ctx) {
2003
+ const placeholders = findPlaceholders(ctx.pptxData);
2004
+ return {
2005
+ pptxData: ctx.pptxData,
2006
+ dirty: false,
2007
+ result: { placeholders, count: placeholders.length }
2008
+ };
2009
+ }
2010
+ function applyTemplateT(ctx, params) {
2011
+ applyTemplate(ctx.pptxData, params.data);
2012
+ return {
2013
+ pptxData: ctx.pptxData,
2014
+ dirty: true,
2015
+ result: { applied: true, slideCount: ctx.pptxData.slides.length }
2016
+ };
2017
+ }
2018
+
2019
+ // src/tools/metadata-tools.ts
2020
+ function getMetadata(ctx) {
2021
+ return {
2022
+ pptxData: ctx.pptxData,
2023
+ dirty: false,
2024
+ result: {
2025
+ coreProperties: ctx.pptxData.coreProperties,
2026
+ appProperties: ctx.pptxData.appProperties,
2027
+ customProperties: ctx.pptxData.customProperties,
2028
+ slideCount: ctx.pptxData.slides.length
2029
+ }
2030
+ };
2031
+ }
2032
+ function updateMetadata(ctx, params) {
2033
+ const updated = [];
2034
+ if (params.title !== void 0 || params.subject !== void 0 || params.creator !== void 0 || params.keywords !== void 0 || params.description !== void 0 || params.lastModifiedBy !== void 0 || params.category !== void 0) {
2035
+ if (!ctx.pptxData.coreProperties) {
2036
+ ctx.pptxData.coreProperties = {};
2037
+ }
2038
+ const cp = ctx.pptxData.coreProperties;
2039
+ if (params.title !== void 0) {
2040
+ cp.title = params.title;
2041
+ updated.push("title");
2042
+ }
2043
+ if (params.subject !== void 0) {
2044
+ cp.subject = params.subject;
2045
+ updated.push("subject");
2046
+ }
2047
+ if (params.creator !== void 0) {
2048
+ cp.creator = params.creator;
2049
+ updated.push("creator");
2050
+ }
2051
+ if (params.keywords !== void 0) {
2052
+ cp.keywords = params.keywords;
2053
+ updated.push("keywords");
2054
+ }
2055
+ if (params.description !== void 0) {
2056
+ cp.description = params.description;
2057
+ updated.push("description");
2058
+ }
2059
+ if (params.lastModifiedBy !== void 0) {
2060
+ cp.lastModifiedBy = params.lastModifiedBy;
2061
+ updated.push("lastModifiedBy");
2062
+ }
2063
+ if (params.category !== void 0) {
2064
+ cp.category = params.category;
2065
+ updated.push("category");
2066
+ }
2067
+ }
2068
+ if (params.company !== void 0 || params.manager !== void 0) {
2069
+ if (!ctx.pptxData.appProperties) {
2070
+ ctx.pptxData.appProperties = {};
2071
+ }
2072
+ const ap = ctx.pptxData.appProperties;
2073
+ if (params.company !== void 0) {
2074
+ ap.company = params.company;
2075
+ updated.push("company");
2076
+ }
2077
+ if (params.manager !== void 0) {
2078
+ ap.manager = params.manager;
2079
+ updated.push("manager");
2080
+ }
2081
+ }
2082
+ if (params.customProperties) {
2083
+ if (!ctx.pptxData.customProperties) {
2084
+ ctx.pptxData.customProperties = [];
2085
+ }
2086
+ for (const cp of params.customProperties) {
2087
+ const valueStr = String(cp.value);
2088
+ const vtType = typeof cp.value === "number" ? "i4" : typeof cp.value === "boolean" ? "bool" : "lpwstr";
2089
+ const existing = ctx.pptxData.customProperties.find((p) => p.name === cp.name);
2090
+ if (existing) {
2091
+ existing.value = valueStr;
2092
+ existing.type = vtType;
2093
+ } else {
2094
+ ctx.pptxData.customProperties.push({ name: cp.name, value: valueStr, type: vtType });
2095
+ }
2096
+ updated.push(`custom:${cp.name}`);
2097
+ }
2098
+ }
2099
+ return {
2100
+ pptxData: ctx.pptxData,
2101
+ dirty: updated.length > 0,
2102
+ result: { updated }
2103
+ };
2104
+ }
2105
+ function manageSections(ctx, params) {
2106
+ switch (params.action) {
2107
+ case "list": {
2108
+ const sections = (ctx.pptxData.sections ?? []).map((s) => ({
2109
+ id: s.id,
2110
+ name: s.name,
2111
+ slideIds: s.slideIds,
2112
+ collapsed: s.collapsed,
2113
+ color: s.color
2114
+ }));
2115
+ return { pptxData: ctx.pptxData, dirty: false, result: { action: "list", sections } };
2116
+ }
2117
+ case "add": {
2118
+ if (!params.name) {
2119
+ throw new Error("name is required for add action.");
2120
+ }
2121
+ const section = addSection(ctx.pptxData, params.name, params.slideIndices ?? []);
2122
+ return {
2123
+ pptxData: ctx.pptxData,
2124
+ dirty: true,
2125
+ result: {
2126
+ action: "add",
2127
+ section: { id: section.id, name: section.name, slideIds: section.slideIds }
2128
+ }
2129
+ };
2130
+ }
2131
+ case "remove": {
2132
+ if (!params.sectionId) {
2133
+ throw new Error("sectionId is required for remove action.");
2134
+ }
2135
+ const success = removeSection(ctx.pptxData, params.sectionId);
2136
+ return { pptxData: ctx.pptxData, dirty: success, result: { action: "remove", success } };
2137
+ }
2138
+ case "reorder": {
2139
+ if (!params.sectionIds) {
2140
+ throw new Error("sectionIds is required for reorder action.");
2141
+ }
2142
+ reorderSections(ctx.pptxData, params.sectionIds);
2143
+ return { pptxData: ctx.pptxData, dirty: true, result: { action: "reorder", success: true } };
2144
+ }
2145
+ case "moveSlides": {
2146
+ if (!params.sectionId) {
2147
+ throw new Error("sectionId is required for moveSlides action.");
2148
+ }
2149
+ if (!params.slideIndices) {
2150
+ throw new Error("slideIndices is required for moveSlides action.");
2151
+ }
2152
+ const success = moveSlidesToSection(ctx.pptxData, params.slideIndices, params.sectionId);
2153
+ return { pptxData: ctx.pptxData, dirty: success, result: { action: "moveSlides", success } };
2154
+ }
2155
+ case "getForSlide": {
2156
+ if (params.slideIndex === void 0) {
2157
+ throw new Error("slideIndex is required for getForSlide action.");
2158
+ }
2159
+ const section = getSectionForSlide(ctx.pptxData, params.slideIndex);
2160
+ const info = section ? { id: section.id, name: section.name, slideIds: section.slideIds } : null;
2161
+ return {
2162
+ pptxData: ctx.pptxData,
2163
+ dirty: false,
2164
+ result: { action: "getForSlide", section: info }
2165
+ };
2166
+ }
2167
+ default:
2168
+ throw new Error(`Unknown section action: ${String(params.action)}`);
2169
+ }
2170
+ }
2171
+ function exportToSvg(ctx, params) {
2172
+ if (params.slideIndices) {
2173
+ for (const si of params.slideIndices) {
2174
+ const err = validateSlideIndex(si, ctx.pptxData.slides.length);
2175
+ if (err) {
2176
+ throw new Error(err);
2177
+ }
2178
+ }
2179
+ }
2180
+ const options = {};
2181
+ if (params.slideIndices) {
2182
+ options.slideIndices = params.slideIndices;
2183
+ }
2184
+ if (params.includeHidden !== void 0) {
2185
+ options.includeHidden = params.includeHidden;
2186
+ }
2187
+ if (params.defaultFontFamily) {
2188
+ options.defaultFontFamily = params.defaultFontFamily;
2189
+ }
2190
+ if (params.defaultFontSize) {
2191
+ options.defaultFontSize = params.defaultFontSize;
2192
+ }
2193
+ const svgStrings = SvgExporter.exportAll(ctx.pptxData, options);
2194
+ return {
2195
+ pptxData: ctx.pptxData,
2196
+ dirty: false,
2197
+ result: { svgStrings, slideCount: svgStrings.length }
2198
+ };
2199
+ }
2200
+ function exportSlideSvg(ctx, params) {
2201
+ const err = validateSlideIndex(params.slideIndex, ctx.pptxData.slides.length);
2202
+ if (err) {
2203
+ throw new Error(err);
2204
+ }
2205
+ const slide = ctx.pptxData.slides[params.slideIndex];
2206
+ const width = ctx.pptxData.width ?? 960;
2207
+ const height = ctx.pptxData.height ?? 540;
2208
+ const options = {};
2209
+ if (params.defaultFontFamily) {
2210
+ options.defaultFontFamily = params.defaultFontFamily;
2211
+ }
2212
+ if (params.defaultFontSize) {
2213
+ options.defaultFontSize = params.defaultFontSize;
2214
+ }
2215
+ const svg = SvgExporter.exportSlide(slide, width, height, options);
2216
+ return {
2217
+ pptxData: ctx.pptxData,
2218
+ dirty: false,
2219
+ result: { svg, slideIndex: params.slideIndex }
2220
+ };
2221
+ }
2222
+
2223
+ // src/tools/hyperlink-tools.ts
2224
+ function manageHyperlinks(ctx, params) {
2225
+ const err = validateSlideIndex(params.slideIndex, ctx.pptxData.slides.length);
2226
+ if (err) {
2227
+ throw new Error(err);
2228
+ }
2229
+ const slide = ctx.pptxData.slides[params.slideIndex];
2230
+ switch (params.action) {
2231
+ case "list": {
2232
+ const hyperlinks = [];
2233
+ for (const el of slide.elements) {
2234
+ if (el.actionClick) {
2235
+ hyperlinks.push({
2236
+ elementId: el.id,
2237
+ trigger: "click",
2238
+ url: el.actionClick.url,
2239
+ tooltip: el.actionClick.tooltip,
2240
+ targetSlideIndex: el.actionClick.targetSlideIndex,
2241
+ actionType: el.actionClick.action
2242
+ });
2243
+ }
2244
+ if (el.actionHover) {
2245
+ hyperlinks.push({
2246
+ elementId: el.id,
2247
+ trigger: "hover",
2248
+ url: el.actionHover.url,
2249
+ tooltip: el.actionHover.tooltip,
2250
+ targetSlideIndex: el.actionHover.targetSlideIndex,
2251
+ actionType: el.actionHover.action
2252
+ });
2253
+ }
2254
+ }
2255
+ return { pptxData: ctx.pptxData, dirty: false, result: { action: "list", hyperlinks } };
2256
+ }
2257
+ case "set": {
2258
+ if (!params.elementId) {
2259
+ throw new Error("elementId is required for set action.");
2260
+ }
2261
+ const el = slide.elements.find((e) => e.id === params.elementId);
2262
+ if (!el) {
2263
+ throw new Error(`Element '${params.elementId}' not found on slide ${params.slideIndex}.`);
2264
+ }
2265
+ const trigger = params.trigger ?? "click";
2266
+ const action = {};
2267
+ if (params.url) {
2268
+ action.url = params.url;
2269
+ }
2270
+ if (params.tooltip) {
2271
+ action.tooltip = params.tooltip;
2272
+ }
2273
+ if (params.targetSlideIndex !== void 0) {
2274
+ action.targetSlideIndex = params.targetSlideIndex;
2275
+ }
2276
+ if (params.actionType) {
2277
+ switch (params.actionType) {
2278
+ case "url":
2279
+ action.action = "ppaction://hlinkpres";
2280
+ break;
2281
+ case "slide":
2282
+ action.action = "ppaction://hlinksldjump";
2283
+ break;
2284
+ case "nextSlide":
2285
+ action.action = "ppaction://hlinkshowjump?jump=nextslide";
2286
+ break;
2287
+ case "prevSlide":
2288
+ action.action = "ppaction://hlinkshowjump?jump=previousslide";
2289
+ break;
2290
+ case "firstSlide":
2291
+ action.action = "ppaction://hlinkshowjump?jump=firstslide";
2292
+ break;
2293
+ case "lastSlide":
2294
+ action.action = "ppaction://hlinkshowjump?jump=lastslide";
2295
+ break;
2296
+ case "endShow":
2297
+ action.action = "ppaction://hlinkshowjump?jump=endshow";
2298
+ break;
2299
+ }
2300
+ }
2301
+ if (trigger === "click") {
2302
+ el.actionClick = action;
2303
+ } else {
2304
+ el.actionHover = action;
2305
+ }
2306
+ return {
2307
+ pptxData: ctx.pptxData,
2308
+ dirty: true,
2309
+ result: { action: "set", elementId: params.elementId }
2310
+ };
2311
+ }
2312
+ case "remove": {
2313
+ if (!params.elementId) {
2314
+ throw new Error("elementId is required for remove action.");
2315
+ }
2316
+ const el = slide.elements.find((e) => e.id === params.elementId);
2317
+ if (!el) {
2318
+ throw new Error(`Element '${params.elementId}' not found on slide ${params.slideIndex}.`);
2319
+ }
2320
+ const trigger = params.trigger ?? "click";
2321
+ if (trigger === "click") {
2322
+ el.actionClick = void 0;
2323
+ } else {
2324
+ el.actionHover = void 0;
2325
+ }
2326
+ return {
2327
+ pptxData: ctx.pptxData,
2328
+ dirty: true,
2329
+ result: { action: "remove", elementId: params.elementId }
2330
+ };
2331
+ }
2332
+ default:
2333
+ throw new Error(`Unknown hyperlink action: ${String(params.action)}`);
2334
+ }
2335
+ }
2336
+ function replaceGeometry(ctx, params) {
2337
+ const err = validateSlideIndex(params.slideIndex, ctx.pptxData.slides.length);
2338
+ if (err) {
2339
+ throw new Error(err);
2340
+ }
2341
+ const slide = ctx.pptxData.slides[params.slideIndex];
2342
+ const el = slide.elements.find((e) => e.id === params.elementId);
2343
+ if (!el) {
2344
+ throw new Error(`Element '${params.elementId}' not found on slide ${params.slideIndex}.`);
2345
+ }
2346
+ if (el.type !== "shape") {
2347
+ throw new Error(`Element '${params.elementId}' is not a shape.`);
2348
+ }
2349
+ const shape = el;
2350
+ if (params.svgPath) {
2351
+ replaceWithCustomGeometry(shape, params.svgPath, params.pathWidth, params.pathHeight);
2352
+ return {
2353
+ pptxData: ctx.pptxData,
2354
+ dirty: true,
2355
+ result: { elementId: params.elementId, geometryType: "custom" }
2356
+ };
2357
+ }
2358
+ if (params.shapeType) {
2359
+ replaceShapeGeometry(shape, params.shapeType, params.adjustments);
2360
+ return {
2361
+ pptxData: ctx.pptxData,
2362
+ dirty: true,
2363
+ result: { elementId: params.elementId, geometryType: params.shapeType }
2364
+ };
2365
+ }
2366
+ throw new Error("Either shapeType or svgPath must be provided.");
2367
+ }
2368
+ function setElementLockT(ctx, params) {
2369
+ const err = validateSlideIndex(params.slideIndex, ctx.pptxData.slides.length);
2370
+ if (err) {
2371
+ throw new Error(err);
2372
+ }
2373
+ const slide = ctx.pptxData.slides[params.slideIndex];
2374
+ const idx = slide.elements.findIndex((e) => e.id === params.elementId);
2375
+ if (idx < 0) {
2376
+ throw new Error(`Element '${params.elementId}' not found on slide ${params.slideIndex}.`);
2377
+ }
2378
+ const extraLocks = {};
2379
+ if (params.noMove !== void 0) {
2380
+ extraLocks["noMove"] = params.noMove;
2381
+ }
2382
+ if (params.noResize !== void 0) {
2383
+ extraLocks["noResize"] = params.noResize;
2384
+ }
2385
+ if (params.noRotation !== void 0) {
2386
+ extraLocks["noRotation"] = params.noRotation;
2387
+ }
2388
+ if (params.noSelect !== void 0) {
2389
+ extraLocks["noSelect"] = params.noSelect;
2390
+ }
2391
+ if (params.noTextEdit !== void 0) {
2392
+ extraLocks["noTextEdit"] = params.noTextEdit;
2393
+ }
2394
+ const updated = setElementLocked(slide.elements[idx], params.locked, extraLocks);
2395
+ slide.elements[idx] = updated;
2396
+ return {
2397
+ pptxData: ctx.pptxData,
2398
+ dirty: true,
2399
+ result: { elementId: params.elementId, locked: params.locked }
2400
+ };
2401
+ }
2402
+ async function validatePresentation(rawBytes) {
2403
+ const result = await validatePptx(rawBytes);
2404
+ return {
2405
+ valid: result.valid,
2406
+ issueCount: result.issues.length,
2407
+ errors: result.issues.filter((i) => i.severity === "error").length,
2408
+ warnings: result.issues.filter((i) => i.severity === "warning").length,
2409
+ issues: result.issues
2410
+ };
2411
+ }
2412
+ async function repairPresentation(rawBytes) {
2413
+ const result = await repairPptx(rawBytes);
2414
+ return {
2415
+ result: {
2416
+ repairCount: result.repairs.length,
2417
+ repairs: result.repairs
2418
+ },
2419
+ repairedBytes: result.repaired
2420
+ };
2421
+ }
2422
+
2423
+ // src/tools/presentation-tools.ts
2424
+ function getPresentationProperties(ctx) {
2425
+ return {
2426
+ pptxData: ctx.pptxData,
2427
+ dirty: false,
2428
+ result: {
2429
+ properties: ctx.pptxData.presentationProperties,
2430
+ slideCount: ctx.pptxData.slides.length,
2431
+ width: ctx.pptxData.width,
2432
+ height: ctx.pptxData.height
2433
+ }
2434
+ };
2435
+ }
2436
+ function updatePresentationProperties(ctx, params) {
2437
+ if (!ctx.pptxData.presentationProperties) {
2438
+ ctx.pptxData.presentationProperties = {};
2439
+ }
2440
+ const pp = ctx.pptxData.presentationProperties;
2441
+ if (params.showType !== void 0) {
2442
+ pp.showType = params.showType;
2443
+ }
2444
+ if (params.loopContinuously !== void 0) {
2445
+ pp.loopContinuously = params.loopContinuously;
2446
+ }
2447
+ if (params.showWithNarration !== void 0) {
2448
+ pp.showWithNarration = params.showWithNarration;
2449
+ }
2450
+ if (params.showWithAnimation !== void 0) {
2451
+ pp.showWithAnimation = params.showWithAnimation;
2452
+ }
2453
+ if (params.advanceMode !== void 0) {
2454
+ pp.advanceMode = params.advanceMode;
2455
+ }
2456
+ if (params.showSlidesMode !== void 0) {
2457
+ pp.showSlidesMode = params.showSlidesMode;
2458
+ }
2459
+ if (params.showSlidesFrom !== void 0) {
2460
+ pp.showSlidesFrom = params.showSlidesFrom;
2461
+ }
2462
+ if (params.showSlidesTo !== void 0) {
2463
+ pp.showSlidesTo = params.showSlidesTo;
2464
+ }
2465
+ if (params.penColor !== void 0) {
2466
+ pp.penColor = params.penColor;
2467
+ }
2468
+ return {
2469
+ pptxData: ctx.pptxData,
2470
+ dirty: true,
2471
+ result: { properties: pp }
2472
+ };
2473
+ }
2474
+ function getLayouts(ctx) {
2475
+ const layouts = [];
2476
+ if (ctx.pptxData.slideMasters) {
2477
+ for (const master of ctx.pptxData.slideMasters) {
2478
+ if (master.layouts) {
2479
+ for (const layout of master.layouts) {
2480
+ layouts.push({
2481
+ name: layout.name ?? "Unknown",
2482
+ path: layout.path
2483
+ });
2484
+ }
2485
+ }
2486
+ }
2487
+ }
2488
+ if (ctx.pptxData.layoutOptions) {
2489
+ for (const opt of ctx.pptxData.layoutOptions) {
2490
+ if (!layouts.some((l) => l.path === opt.path)) {
2491
+ layouts.push({ name: opt.name, path: opt.path, type: opt.type });
2492
+ }
2493
+ }
2494
+ }
2495
+ return {
2496
+ pptxData: ctx.pptxData,
2497
+ dirty: false,
2498
+ result: { layouts, count: layouts.length }
2499
+ };
2500
+ }
2501
+ function applyLayout(ctx, params) {
2502
+ const err = validateSlideIndex(params.slideIndex, ctx.pptxData.slides.length);
2503
+ if (err) {
2504
+ throw new Error(err);
2505
+ }
2506
+ let layout;
2507
+ if (params.layoutName) {
2508
+ layout = findLayoutByName(ctx.pptxData, params.layoutName);
2509
+ } else if (params.layoutType) {
2510
+ layout = findLayoutByType(ctx.pptxData, params.layoutType);
2511
+ } else {
2512
+ throw new Error("Either layoutName or layoutType must be provided.");
2513
+ }
2514
+ if (!layout) {
2515
+ throw new Error(
2516
+ `Layout not found: ${params.layoutName ?? params.layoutType}. Use get_layouts to see available layouts.`
2517
+ );
2518
+ }
2519
+ const slide = ctx.pptxData.slides[params.slideIndex];
2520
+ slide.layoutName = layout.name;
2521
+ if (layout.path) {
2522
+ slide.layoutPath = layout.path;
2523
+ }
2524
+ return {
2525
+ pptxData: ctx.pptxData,
2526
+ dirty: true,
2527
+ result: { slideIndex: params.slideIndex, layoutName: layout.name ?? "Unknown" }
2528
+ };
2529
+ }
1590
2530
 
1591
- export { addElement, addSlide, arrangeElements, batchUpdateElements, cloneElement, convertToMarkdown, deleteElements, deleteSlides, describeElement, duplicateSlide, executeToolWithContext, extractSlideText, findText, generateElementId, generateSlideId, getSlide, groupElements, loadPresentation, manageComments, manageTableStructure, reorderSlides, replaceText, runAccessibilityCheck, savePresentation, setCanvasSize, setElementAnimation, setSlideTransition, ungroupElements, updateElement, updateElementStyle, updateSlideProperties, updateTableCells, validateSlideIndex };
2531
+ export { addChartSeriesT, addElement, addSlide, applyLayout, applyTemplateT, applyThemePreset, arrangeElements, batchUpdateElements, cloneElement, convertToMarkdown, createChart, deleteElements, deleteSlides, describeElement, diffPresentationsT, duplicateSlide, executeToolWithContext, exportSlideSvg, exportToSvg, extractSlideText, findPlaceholdersT, findText, generateElementId, generateSlideId, getLayouts, getMetadata, getPresentationProperties, getSlide, getThemeInfo, groupElements, loadPresentation, manageComments, manageHyperlinks, manageSections, manageSmartArt, manageTableStructure, mergePresentationT, removeChartSeriesT, reorderSlides, repairPresentation, replaceGeometry, replaceText, runAccessibilityCheck, savePresentation, setCanvasSize, setElementAnimation, setElementLockT, setSlideTransition, ungroupElements, updateChart, updateChartSeriesData, updateElement, updateElementStyle, updateMetadata, updatePresentationProperties, updateSlideProperties, updateTableCells, updateThemeColors, updateThemeFonts, validatePresentation, validateSlideIndex };