claude-code-templates 1.21.13 → 1.21.14
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/.claude/settings.local.json +8 -2
- package/.claude-plugin/marketplace.json +251 -0
- package/.github/workflows/component-security-validation.yml +129 -0
- package/README.md +13 -6
- package/cli-tool/README.md +56 -0
- package/cli-tool/bin/create-claude-config.js +2 -0
- package/cli-tool/components/.claude-plugin/marketplace.json +92 -0
- package/cli-tool/components/agents/development-tools/flutter-go-reviewer.md +163 -0
- package/cli-tool/components/agents/development-tools/unused-code-cleaner.md +194 -0
- package/cli-tool/components/commands/git-workflow/gemini-review.md +293 -0
- package/cli-tool/components/commands/testing/add-mutation-testing.md +2 -2
- package/cli-tool/components/commands/testing/add-property-based-testing.md +2 -2
- package/cli-tool/components/commands/testing/e2e-setup.md +2 -2
- package/cli-tool/components/commands/testing/generate-test-cases.md +2 -2
- package/cli-tool/components/commands/testing/generate-tests.md +8 -3
- package/cli-tool/components/commands/testing/setup-comprehensive-testing.md +2 -2
- package/cli-tool/components/commands/testing/setup-load-testing.md +2 -2
- package/cli-tool/components/commands/testing/setup-visual-testing.md +2 -2
- package/cli-tool/components/commands/testing/test-automation-orchestrator.md +2 -2
- package/cli-tool/components/commands/testing/test-changelog-automation.md +2 -2
- package/cli-tool/components/commands/testing/test-coverage.md +2 -2
- package/cli-tool/components/commands/testing/test-quality-analyzer.md +2 -2
- package/cli-tool/components/commands/testing/testing_plan_integration.md +2 -2
- package/cli-tool/components/commands/testing/write-tests.md +2 -2
- package/cli-tool/components/commands/utilities/ultra-think.md +10 -5
- package/cli-tool/components/hooks/git/validate-branch-name.json +1 -1
- package/cli-tool/components/mcps/devtools/chrome-devtools.json +9 -0
- package/cli-tool/components/mcps/devtools/grafana.json +15 -0
- package/cli-tool/components/mcps/devtools/pulumi.json +9 -0
- package/cli-tool/components/mcps/devtools/terraform.json +1 -1
- package/cli-tool/components/settings/statusline/context-monitor.py +1 -1
- package/cli-tool/components/skills/ANTHROPIC_ATTRIBUTION.md +81 -0
- package/cli-tool/components/skills/creative-design/algorithmic-art/LICENSE.txt +202 -0
- package/cli-tool/components/skills/creative-design/algorithmic-art/SKILL.md +405 -0
- package/cli-tool/components/skills/creative-design/algorithmic-art/templates/generator_template.js +223 -0
- package/cli-tool/components/skills/creative-design/algorithmic-art/templates/viewer.html +599 -0
- package/cli-tool/components/skills/creative-design/canvas-design/LICENSE.txt +202 -0
- package/cli-tool/components/skills/creative-design/canvas-design/SKILL.md +130 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/Italiana-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/Jura-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/PoiretOne-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
- package/cli-tool/components/skills/creative-design/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
- package/cli-tool/components/skills/creative-design/slack-gif-creator/LICENSE.txt +202 -0
- package/cli-tool/components/skills/creative-design/slack-gif-creator/SKILL.md +646 -0
- package/cli-tool/components/skills/creative-design/slack-gif-creator/core/color_palettes.py +302 -0
- package/cli-tool/components/skills/creative-design/slack-gif-creator/core/easing.py +230 -0
- package/cli-tool/components/skills/creative-design/slack-gif-creator/core/frame_composer.py +469 -0
- package/cli-tool/components/skills/creative-design/slack-gif-creator/core/gif_builder.py +246 -0
- package/cli-tool/components/skills/creative-design/slack-gif-creator/core/typography.py +357 -0
- package/cli-tool/components/skills/creative-design/slack-gif-creator/core/validators.py +264 -0
- package/cli-tool/components/skills/creative-design/slack-gif-creator/core/visual_effects.py +494 -0
- package/cli-tool/components/skills/creative-design/slack-gif-creator/requirements.txt +4 -0
- package/cli-tool/components/skills/creative-design/slack-gif-creator/templates/bounce.py +106 -0
- package/cli-tool/components/skills/creative-design/slack-gif-creator/templates/explode.py +331 -0
- package/cli-tool/components/skills/creative-design/slack-gif-creator/templates/fade.py +329 -0
- package/cli-tool/components/skills/creative-design/slack-gif-creator/templates/flip.py +291 -0
- package/cli-tool/components/skills/creative-design/slack-gif-creator/templates/kaleidoscope.py +211 -0
- package/cli-tool/components/skills/creative-design/slack-gif-creator/templates/morph.py +329 -0
- package/cli-tool/components/skills/creative-design/slack-gif-creator/templates/move.py +293 -0
- package/cli-tool/components/skills/creative-design/slack-gif-creator/templates/pulse.py +268 -0
- package/cli-tool/components/skills/creative-design/slack-gif-creator/templates/shake.py +127 -0
- package/cli-tool/components/skills/creative-design/slack-gif-creator/templates/slide.py +291 -0
- package/cli-tool/components/skills/creative-design/slack-gif-creator/templates/spin.py +269 -0
- package/cli-tool/components/skills/creative-design/slack-gif-creator/templates/wiggle.py +300 -0
- package/cli-tool/components/skills/creative-design/slack-gif-creator/templates/zoom.py +312 -0
- package/cli-tool/components/skills/creative-design/theme-factory/LICENSE.txt +202 -0
- package/cli-tool/components/skills/creative-design/theme-factory/SKILL.md +59 -0
- package/cli-tool/components/skills/creative-design/theme-factory/theme-showcase.pdf +0 -0
- package/cli-tool/components/skills/creative-design/theme-factory/themes/arctic-frost.md +19 -0
- package/cli-tool/components/skills/creative-design/theme-factory/themes/botanical-garden.md +19 -0
- package/cli-tool/components/skills/creative-design/theme-factory/themes/desert-rose.md +19 -0
- package/cli-tool/components/skills/creative-design/theme-factory/themes/forest-canopy.md +19 -0
- package/cli-tool/components/skills/creative-design/theme-factory/themes/golden-hour.md +19 -0
- package/cli-tool/components/skills/creative-design/theme-factory/themes/midnight-galaxy.md +19 -0
- package/cli-tool/components/skills/creative-design/theme-factory/themes/modern-minimalist.md +19 -0
- package/cli-tool/components/skills/creative-design/theme-factory/themes/ocean-depths.md +19 -0
- package/cli-tool/components/skills/creative-design/theme-factory/themes/sunset-boulevard.md +19 -0
- package/cli-tool/components/skills/creative-design/theme-factory/themes/tech-innovation.md +19 -0
- package/cli-tool/components/skills/development/artifacts-builder/LICENSE.txt +202 -0
- package/cli-tool/components/skills/development/artifacts-builder/SKILL.md +74 -0
- package/cli-tool/components/skills/development/artifacts-builder/scripts/bundle-artifact.sh +54 -0
- package/cli-tool/components/skills/development/artifacts-builder/scripts/init-artifact.sh +322 -0
- package/cli-tool/components/skills/development/artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/cli-tool/components/skills/development/git-commit-helper/SKILL.md +203 -0
- package/cli-tool/components/skills/development/mcp-builder/LICENSE.txt +202 -0
- package/cli-tool/components/skills/development/mcp-builder/SKILL.md +328 -0
- package/cli-tool/components/skills/development/mcp-builder/reference/evaluation.md +602 -0
- package/cli-tool/components/skills/development/mcp-builder/reference/mcp_best_practices.md +915 -0
- package/cli-tool/components/skills/development/mcp-builder/reference/node_mcp_server.md +916 -0
- package/cli-tool/components/skills/development/mcp-builder/reference/python_mcp_server.md +752 -0
- package/cli-tool/components/skills/development/mcp-builder/scripts/connections.py +151 -0
- package/cli-tool/components/skills/development/mcp-builder/scripts/evaluation.py +373 -0
- package/cli-tool/components/skills/development/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/cli-tool/components/skills/development/mcp-builder/scripts/requirements.txt +2 -0
- package/cli-tool/components/skills/development/skill-creator/LICENSE.txt +202 -0
- package/cli-tool/components/skills/development/skill-creator/SKILL.md +209 -0
- package/cli-tool/components/skills/development/skill-creator/scripts/init_skill.py +303 -0
- package/cli-tool/components/skills/development/skill-creator/scripts/package_skill.py +110 -0
- package/cli-tool/components/skills/development/skill-creator/scripts/quick_validate.py +65 -0
- package/cli-tool/components/skills/development/webapp-testing/LICENSE.txt +202 -0
- package/cli-tool/components/skills/development/webapp-testing/SKILL.md +96 -0
- package/cli-tool/components/skills/development/webapp-testing/examples/console_logging.py +35 -0
- package/cli-tool/components/skills/development/webapp-testing/examples/element_discovery.py +40 -0
- package/cli-tool/components/skills/development/webapp-testing/examples/static_html_automation.py +33 -0
- package/cli-tool/components/skills/development/webapp-testing/scripts/with_server.py +106 -0
- package/cli-tool/components/skills/document-processing/docx/LICENSE.txt +30 -0
- package/cli-tool/components/skills/document-processing/docx/SKILL.md +197 -0
- package/cli-tool/components/skills/document-processing/docx/docx-js.md +350 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/mce/mc.xsd +75 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/scripts/pack.py +159 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/scripts/unpack.py +29 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/scripts/validate.py +69 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/scripts/validation/__init__.py +15 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/scripts/validation/base.py +951 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/scripts/validation/docx.py +274 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/scripts/validation/pptx.py +315 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml/scripts/validation/redlining.py +279 -0
- package/cli-tool/components/skills/document-processing/docx/ooxml.md +610 -0
- package/cli-tool/components/skills/document-processing/docx/scripts/__init__.py +1 -0
- package/cli-tool/components/skills/document-processing/docx/scripts/document.py +1276 -0
- package/cli-tool/components/skills/document-processing/docx/scripts/templates/comments.xml +3 -0
- package/cli-tool/components/skills/document-processing/docx/scripts/templates/commentsExtended.xml +3 -0
- package/cli-tool/components/skills/document-processing/docx/scripts/templates/commentsExtensible.xml +3 -0
- package/cli-tool/components/skills/document-processing/docx/scripts/templates/commentsIds.xml +3 -0
- package/cli-tool/components/skills/document-processing/docx/scripts/templates/people.xml +3 -0
- package/cli-tool/components/skills/document-processing/docx/scripts/utilities.py +374 -0
- package/cli-tool/components/skills/document-processing/pdf-anthropic/LICENSE.txt +30 -0
- package/cli-tool/components/skills/document-processing/pdf-anthropic/SKILL.md +294 -0
- package/cli-tool/components/skills/document-processing/pdf-anthropic/forms.md +205 -0
- package/cli-tool/components/skills/document-processing/pdf-anthropic/reference.md +612 -0
- package/cli-tool/components/skills/document-processing/pdf-anthropic/scripts/check_bounding_boxes.py +70 -0
- package/cli-tool/components/skills/document-processing/pdf-anthropic/scripts/check_bounding_boxes_test.py +226 -0
- package/cli-tool/components/skills/document-processing/pdf-anthropic/scripts/check_fillable_fields.py +12 -0
- package/cli-tool/components/skills/document-processing/pdf-anthropic/scripts/convert_pdf_to_images.py +35 -0
- package/cli-tool/components/skills/document-processing/pdf-anthropic/scripts/create_validation_image.py +41 -0
- package/cli-tool/components/skills/document-processing/pdf-anthropic/scripts/extract_form_field_info.py +152 -0
- package/cli-tool/components/skills/document-processing/pdf-anthropic/scripts/fill_fillable_fields.py +114 -0
- package/cli-tool/components/skills/document-processing/pdf-anthropic/scripts/fill_pdf_form_with_annotations.py +108 -0
- package/cli-tool/components/skills/document-processing/pdf-processing/FORMS.md +143 -0
- package/cli-tool/components/skills/document-processing/pdf-processing/SKILL.md +149 -0
- package/cli-tool/components/skills/document-processing/pdf-processing-pro/FORMS.md +610 -0
- package/cli-tool/components/skills/document-processing/pdf-processing-pro/OCR.md +137 -0
- package/cli-tool/components/skills/document-processing/pdf-processing-pro/SKILL.md +296 -0
- package/cli-tool/components/skills/document-processing/pdf-processing-pro/TABLES.md +626 -0
- package/cli-tool/components/skills/document-processing/pdf-processing-pro/scripts/analyze_form.py +307 -0
- package/cli-tool/components/skills/document-processing/pptx/LICENSE.txt +30 -0
- package/cli-tool/components/skills/document-processing/pptx/SKILL.md +484 -0
- package/cli-tool/components/skills/document-processing/pptx/html2pptx.md +625 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/mce/mc.xsd +75 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/scripts/pack.py +159 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/scripts/unpack.py +29 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/scripts/validate.py +69 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/scripts/validation/__init__.py +15 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/scripts/validation/base.py +951 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/scripts/validation/docx.py +274 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/scripts/validation/pptx.py +315 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml/scripts/validation/redlining.py +279 -0
- package/cli-tool/components/skills/document-processing/pptx/ooxml.md +427 -0
- package/cli-tool/components/skills/document-processing/pptx/scripts/html2pptx.js +979 -0
- package/cli-tool/components/skills/document-processing/pptx/scripts/inventory.py +1020 -0
- package/cli-tool/components/skills/document-processing/pptx/scripts/rearrange.py +231 -0
- package/cli-tool/components/skills/document-processing/pptx/scripts/replace.py +385 -0
- package/cli-tool/components/skills/document-processing/pptx/scripts/thumbnail.py +450 -0
- package/cli-tool/components/skills/document-processing/xlsx/LICENSE.txt +30 -0
- package/cli-tool/components/skills/document-processing/xlsx/SKILL.md +289 -0
- package/cli-tool/components/skills/document-processing/xlsx/recalc.py +178 -0
- package/cli-tool/components/skills/enterprise-communication/brand-guidelines/LICENSE.txt +202 -0
- package/cli-tool/components/skills/enterprise-communication/brand-guidelines/SKILL.md +73 -0
- package/cli-tool/components/skills/enterprise-communication/email-composer/SKILL.md +317 -0
- package/cli-tool/components/skills/enterprise-communication/excel-analysis/SKILL.md +247 -0
- package/cli-tool/components/skills/enterprise-communication/internal-comms/LICENSE.txt +202 -0
- package/cli-tool/components/skills/enterprise-communication/internal-comms/SKILL.md +32 -0
- package/cli-tool/components/skills/enterprise-communication/internal-comms/examples/3p-updates.md +47 -0
- package/cli-tool/components/skills/enterprise-communication/internal-comms/examples/company-newsletter.md +65 -0
- package/cli-tool/components/skills/enterprise-communication/internal-comms/examples/faq-answers.md +30 -0
- package/cli-tool/components/skills/enterprise-communication/internal-comms/examples/general-comms.md +16 -0
- package/cli-tool/package-lock.json +39 -16
- package/cli-tool/package.json +7 -2
- package/cli-tool/security-report.json +62361 -0
- package/cli-tool/src/analytics-web/chats_mobile.html +17 -16
- package/cli-tool/src/console-bridge.js +3 -3
- package/cli-tool/src/index.js +157 -10
- package/cli-tool/src/plugin-dashboard-web/app.js +806 -0
- package/cli-tool/src/plugin-dashboard-web/index.html +292 -0
- package/cli-tool/src/plugin-dashboard-web/styles.css +1781 -0
- package/cli-tool/src/plugin-dashboard.js +689 -0
- package/cli-tool/src/security-audit.js +164 -0
- package/cli-tool/src/validation/ARCHITECTURE.md +309 -0
- package/cli-tool/src/validation/BaseValidator.js +152 -0
- package/cli-tool/src/validation/README.md +543 -0
- package/cli-tool/src/validation/ValidationOrchestrator.js +305 -0
- package/cli-tool/src/validation/validators/IntegrityValidator.js +338 -0
- package/cli-tool/src/validation/validators/ProvenanceValidator.js +399 -0
- package/cli-tool/src/validation/validators/ReferenceValidator.js +373 -0
- package/cli-tool/src/validation/validators/SemanticValidator.js +449 -0
- package/cli-tool/src/validation/validators/StructuralValidator.js +376 -0
- package/docs/CLAUDE.md +363 -0
- package/docs/api/README.md +297 -0
- package/docs/api/package.json +7 -0
- package/docs/api/track-download-supabase.js +150 -0
- package/docs/blog/README.md +199 -0
- package/docs/blog/blog-articles.json +133 -0
- package/docs/blog/css/blog-controls.css +254 -0
- package/docs/blog/e2b-claude-code-sandbox/index.html +8 -0
- package/docs/blog/index.html +81 -124
- package/docs/blog/js/blog-loader.js +602 -0
- package/docs/blog/nextjs-vercel-claude-code-integration/index.html +8 -0
- package/docs/blog/supabase-claude-code-integration/index.html +8 -0
- package/docs/component.html +226 -48
- package/docs/components.json +61610 -604
- package/docs/css/blog.css +292 -0
- package/docs/css/component-page.css +840 -3
- package/docs/css/plugin-page.css +648 -0
- package/docs/css/styles.css +504 -1
- package/docs/css/trending.css +110 -6
- package/docs/download-stats.html +8 -0
- package/docs/index.html +48 -22
- package/docs/jobs.html +8 -0
- package/docs/js/cart-manager.js +21 -8
- package/docs/js/component-page.js +1013 -12
- package/docs/js/data-loader.js +11 -8
- package/docs/js/index-events.js +305 -53
- package/docs/js/plugin-page.js +390 -0
- package/docs/js/script.js +50 -3
- package/docs/js/search-functionality.js +19 -16
- package/docs/js/trending.js +55 -20
- package/docs/plugin.html +262 -0
- package/docs/sandbox-interface.html +8 -0
- package/docs/static/favicon/about.txt +6 -0
- package/docs/static/favicon/android-chrome-192x192.png +0 -0
- package/docs/static/favicon/android-chrome-512x512.png +0 -0
- package/docs/static/favicon/apple-touch-icon.png +0 -0
- package/docs/static/favicon/favicon-16x16.png +0 -0
- package/docs/static/favicon/favicon-32x32.png +0 -0
- package/docs/static/favicon/favicon.ico +0 -0
- package/docs/static/favicon/site.webmanifest +1 -0
- package/docs/trending-data.json +616 -579
- package/docs/trending.html +24 -3
- package/docs/vercel.json +12 -0
- package/docs/workflows.html +8 -0
- package/generate_components_json.py +386 -11
- package/package.json +1 -1
- package/sync-api.sh +50 -0
- package/vercel.json +10 -75
- package/ROADMAP.md +0 -278
- package/test_serpapi.py +0 -36
- /package/cli-tool/components/commands/svelte/{svelte:a11y.md → svelte-a11y.md} +0 -0
- /package/cli-tool/components/commands/svelte/{svelte:component.md → svelte-component.md} +0 -0
- /package/cli-tool/components/commands/svelte/{svelte:debug.md → svelte-debug.md} +0 -0
- /package/cli-tool/components/commands/svelte/{svelte:migrate.md → svelte-migrate.md} +0 -0
- /package/cli-tool/components/commands/svelte/{svelte:optimize.md → svelte-optimize.md} +0 -0
- /package/cli-tool/components/commands/svelte/{svelte:scaffold.md → svelte-scaffold.md} +0 -0
- /package/cli-tool/components/commands/svelte/{svelte:storybook-migrate.md → svelte-storybook-migrate.md} +0 -0
- /package/cli-tool/components/commands/svelte/{svelte:storybook-mock.md → svelte-storybook-mock.md} +0 -0
- /package/cli-tool/components/commands/svelte/{svelte:storybook-setup.md → svelte-storybook-setup.md} +0 -0
- /package/cli-tool/components/commands/svelte/{svelte:storybook-story.md → svelte-storybook-story.md} +0 -0
- /package/cli-tool/components/commands/svelte/{svelte:storybook-troubleshoot.md → svelte-storybook-troubleshoot.md} +0 -0
- /package/cli-tool/components/commands/svelte/{svelte:storybook.md → svelte-storybook.md} +0 -0
- /package/cli-tool/components/commands/svelte/{svelte:test-coverage.md → svelte-test-coverage.md} +0 -0
- /package/cli-tool/components/commands/svelte/{svelte:test-fix.md → svelte-test-fix.md} +0 -0
- /package/cli-tool/components/commands/svelte/{svelte:test-setup.md → svelte-test-setup.md} +0 -0
- /package/cli-tool/components/commands/svelte/{svelte:test.md → svelte-test.md} +0 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Rearrange PowerPoint slides based on a sequence of indices.
|
|
4
|
+
|
|
5
|
+
Usage:
|
|
6
|
+
python rearrange.py template.pptx output.pptx 0,34,34,50,52
|
|
7
|
+
|
|
8
|
+
This will create output.pptx using slides from template.pptx in the specified order.
|
|
9
|
+
Slides can be repeated (e.g., 34 appears twice).
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import argparse
|
|
13
|
+
import shutil
|
|
14
|
+
import sys
|
|
15
|
+
from copy import deepcopy
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
18
|
+
import six
|
|
19
|
+
from pptx import Presentation
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def main():
|
|
23
|
+
parser = argparse.ArgumentParser(
|
|
24
|
+
description="Rearrange PowerPoint slides based on a sequence of indices.",
|
|
25
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
26
|
+
epilog="""
|
|
27
|
+
Examples:
|
|
28
|
+
python rearrange.py template.pptx output.pptx 0,34,34,50,52
|
|
29
|
+
Creates output.pptx using slides 0, 34 (twice), 50, and 52 from template.pptx
|
|
30
|
+
|
|
31
|
+
python rearrange.py template.pptx output.pptx 5,3,1,2,4
|
|
32
|
+
Creates output.pptx with slides reordered as specified
|
|
33
|
+
|
|
34
|
+
Note: Slide indices are 0-based (first slide is 0, second is 1, etc.)
|
|
35
|
+
""",
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
parser.add_argument("template", help="Path to template PPTX file")
|
|
39
|
+
parser.add_argument("output", help="Path for output PPTX file")
|
|
40
|
+
parser.add_argument(
|
|
41
|
+
"sequence", help="Comma-separated sequence of slide indices (0-based)"
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
args = parser.parse_args()
|
|
45
|
+
|
|
46
|
+
# Parse the slide sequence
|
|
47
|
+
try:
|
|
48
|
+
slide_sequence = [int(x.strip()) for x in args.sequence.split(",")]
|
|
49
|
+
except ValueError:
|
|
50
|
+
print(
|
|
51
|
+
"Error: Invalid sequence format. Use comma-separated integers (e.g., 0,34,34,50,52)"
|
|
52
|
+
)
|
|
53
|
+
sys.exit(1)
|
|
54
|
+
|
|
55
|
+
# Check template exists
|
|
56
|
+
template_path = Path(args.template)
|
|
57
|
+
if not template_path.exists():
|
|
58
|
+
print(f"Error: Template file not found: {args.template}")
|
|
59
|
+
sys.exit(1)
|
|
60
|
+
|
|
61
|
+
# Create output directory if needed
|
|
62
|
+
output_path = Path(args.output)
|
|
63
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
64
|
+
|
|
65
|
+
try:
|
|
66
|
+
rearrange_presentation(template_path, output_path, slide_sequence)
|
|
67
|
+
except ValueError as e:
|
|
68
|
+
print(f"Error: {e}")
|
|
69
|
+
sys.exit(1)
|
|
70
|
+
except Exception as e:
|
|
71
|
+
print(f"Error processing presentation: {e}")
|
|
72
|
+
sys.exit(1)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def duplicate_slide(pres, index):
|
|
76
|
+
"""Duplicate a slide in the presentation."""
|
|
77
|
+
source = pres.slides[index]
|
|
78
|
+
|
|
79
|
+
# Use source's layout to preserve formatting
|
|
80
|
+
new_slide = pres.slides.add_slide(source.slide_layout)
|
|
81
|
+
|
|
82
|
+
# Collect all image and media relationships from the source slide
|
|
83
|
+
image_rels = {}
|
|
84
|
+
for rel_id, rel in six.iteritems(source.part.rels):
|
|
85
|
+
if "image" in rel.reltype or "media" in rel.reltype:
|
|
86
|
+
image_rels[rel_id] = rel
|
|
87
|
+
|
|
88
|
+
# CRITICAL: Clear placeholder shapes to avoid duplicates
|
|
89
|
+
for shape in new_slide.shapes:
|
|
90
|
+
sp = shape.element
|
|
91
|
+
sp.getparent().remove(sp)
|
|
92
|
+
|
|
93
|
+
# Copy all shapes from source
|
|
94
|
+
for shape in source.shapes:
|
|
95
|
+
el = shape.element
|
|
96
|
+
new_el = deepcopy(el)
|
|
97
|
+
new_slide.shapes._spTree.insert_element_before(new_el, "p:extLst")
|
|
98
|
+
|
|
99
|
+
# Handle picture shapes - need to update the blip reference
|
|
100
|
+
# Look for all blip elements (they can be in pic or other contexts)
|
|
101
|
+
# Using the element's own xpath method without namespaces argument
|
|
102
|
+
blips = new_el.xpath(".//a:blip[@r:embed]")
|
|
103
|
+
for blip in blips:
|
|
104
|
+
old_rId = blip.get(
|
|
105
|
+
"{http://schemas.openxmlformats.org/officeDocument/2006/relationships}embed"
|
|
106
|
+
)
|
|
107
|
+
if old_rId in image_rels:
|
|
108
|
+
# Create a new relationship in the destination slide for this image
|
|
109
|
+
old_rel = image_rels[old_rId]
|
|
110
|
+
# get_or_add returns the rId directly, or adds and returns new rId
|
|
111
|
+
new_rId = new_slide.part.rels.get_or_add(
|
|
112
|
+
old_rel.reltype, old_rel._target
|
|
113
|
+
)
|
|
114
|
+
# Update the blip's embed reference to use the new relationship ID
|
|
115
|
+
blip.set(
|
|
116
|
+
"{http://schemas.openxmlformats.org/officeDocument/2006/relationships}embed",
|
|
117
|
+
new_rId,
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
# Copy any additional image/media relationships that might be referenced elsewhere
|
|
121
|
+
for rel_id, rel in image_rels.items():
|
|
122
|
+
try:
|
|
123
|
+
new_slide.part.rels.get_or_add(rel.reltype, rel._target)
|
|
124
|
+
except Exception:
|
|
125
|
+
pass # Relationship might already exist
|
|
126
|
+
|
|
127
|
+
return new_slide
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def delete_slide(pres, index):
|
|
131
|
+
"""Delete a slide from the presentation."""
|
|
132
|
+
rId = pres.slides._sldIdLst[index].rId
|
|
133
|
+
pres.part.drop_rel(rId)
|
|
134
|
+
del pres.slides._sldIdLst[index]
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def reorder_slides(pres, slide_index, target_index):
|
|
138
|
+
"""Move a slide from one position to another."""
|
|
139
|
+
slides = pres.slides._sldIdLst
|
|
140
|
+
|
|
141
|
+
# Remove slide element from current position
|
|
142
|
+
slide_element = slides[slide_index]
|
|
143
|
+
slides.remove(slide_element)
|
|
144
|
+
|
|
145
|
+
# Insert at target position
|
|
146
|
+
slides.insert(target_index, slide_element)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def rearrange_presentation(template_path, output_path, slide_sequence):
|
|
150
|
+
"""
|
|
151
|
+
Create a new presentation with slides from template in specified order.
|
|
152
|
+
|
|
153
|
+
Args:
|
|
154
|
+
template_path: Path to template PPTX file
|
|
155
|
+
output_path: Path for output PPTX file
|
|
156
|
+
slide_sequence: List of slide indices (0-based) to include
|
|
157
|
+
"""
|
|
158
|
+
# Copy template to preserve dimensions and theme
|
|
159
|
+
if template_path != output_path:
|
|
160
|
+
shutil.copy2(template_path, output_path)
|
|
161
|
+
prs = Presentation(output_path)
|
|
162
|
+
else:
|
|
163
|
+
prs = Presentation(template_path)
|
|
164
|
+
|
|
165
|
+
total_slides = len(prs.slides)
|
|
166
|
+
|
|
167
|
+
# Validate indices
|
|
168
|
+
for idx in slide_sequence:
|
|
169
|
+
if idx < 0 or idx >= total_slides:
|
|
170
|
+
raise ValueError(f"Slide index {idx} out of range (0-{total_slides - 1})")
|
|
171
|
+
|
|
172
|
+
# Track original slides and their duplicates
|
|
173
|
+
slide_map = [] # List of actual slide indices for final presentation
|
|
174
|
+
duplicated = {} # Track duplicates: original_idx -> [duplicate_indices]
|
|
175
|
+
|
|
176
|
+
# Step 1: DUPLICATE repeated slides
|
|
177
|
+
print(f"Processing {len(slide_sequence)} slides from template...")
|
|
178
|
+
for i, template_idx in enumerate(slide_sequence):
|
|
179
|
+
if template_idx in duplicated and duplicated[template_idx]:
|
|
180
|
+
# Already duplicated this slide, use the duplicate
|
|
181
|
+
slide_map.append(duplicated[template_idx].pop(0))
|
|
182
|
+
print(f" [{i}] Using duplicate of slide {template_idx}")
|
|
183
|
+
elif slide_sequence.count(template_idx) > 1 and template_idx not in duplicated:
|
|
184
|
+
# First occurrence of a repeated slide - create duplicates
|
|
185
|
+
slide_map.append(template_idx)
|
|
186
|
+
duplicates = []
|
|
187
|
+
count = slide_sequence.count(template_idx) - 1
|
|
188
|
+
print(
|
|
189
|
+
f" [{i}] Using original slide {template_idx}, creating {count} duplicate(s)"
|
|
190
|
+
)
|
|
191
|
+
for _ in range(count):
|
|
192
|
+
duplicate_slide(prs, template_idx)
|
|
193
|
+
duplicates.append(len(prs.slides) - 1)
|
|
194
|
+
duplicated[template_idx] = duplicates
|
|
195
|
+
else:
|
|
196
|
+
# Unique slide or first occurrence already handled, use original
|
|
197
|
+
slide_map.append(template_idx)
|
|
198
|
+
print(f" [{i}] Using original slide {template_idx}")
|
|
199
|
+
|
|
200
|
+
# Step 2: DELETE unwanted slides (work backwards)
|
|
201
|
+
slides_to_keep = set(slide_map)
|
|
202
|
+
print(f"\nDeleting {len(prs.slides) - len(slides_to_keep)} unused slides...")
|
|
203
|
+
for i in range(len(prs.slides) - 1, -1, -1):
|
|
204
|
+
if i not in slides_to_keep:
|
|
205
|
+
delete_slide(prs, i)
|
|
206
|
+
# Update slide_map indices after deletion
|
|
207
|
+
slide_map = [idx - 1 if idx > i else idx for idx in slide_map]
|
|
208
|
+
|
|
209
|
+
# Step 3: REORDER to final sequence
|
|
210
|
+
print(f"Reordering {len(slide_map)} slides to final sequence...")
|
|
211
|
+
for target_pos in range(len(slide_map)):
|
|
212
|
+
# Find which slide should be at target_pos
|
|
213
|
+
current_pos = slide_map[target_pos]
|
|
214
|
+
if current_pos != target_pos:
|
|
215
|
+
reorder_slides(prs, current_pos, target_pos)
|
|
216
|
+
# Update slide_map: the move shifts other slides
|
|
217
|
+
for i in range(len(slide_map)):
|
|
218
|
+
if slide_map[i] > current_pos and slide_map[i] <= target_pos:
|
|
219
|
+
slide_map[i] -= 1
|
|
220
|
+
elif slide_map[i] < current_pos and slide_map[i] >= target_pos:
|
|
221
|
+
slide_map[i] += 1
|
|
222
|
+
slide_map[target_pos] = target_pos
|
|
223
|
+
|
|
224
|
+
# Save the presentation
|
|
225
|
+
prs.save(output_path)
|
|
226
|
+
print(f"\nSaved rearranged presentation to: {output_path}")
|
|
227
|
+
print(f"Final presentation has {len(prs.slides)} slides")
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
if __name__ == "__main__":
|
|
231
|
+
main()
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Apply text replacements to PowerPoint presentation.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
python replace.py <input.pptx> <replacements.json> <output.pptx>
|
|
6
|
+
|
|
7
|
+
The replacements JSON should have the structure output by inventory.py.
|
|
8
|
+
ALL text shapes identified by inventory.py will have their text cleared
|
|
9
|
+
unless "paragraphs" is specified in the replacements for that shape.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import json
|
|
13
|
+
import sys
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import Any, Dict, List
|
|
16
|
+
|
|
17
|
+
from inventory import InventoryData, extract_text_inventory
|
|
18
|
+
from pptx import Presentation
|
|
19
|
+
from pptx.dml.color import RGBColor
|
|
20
|
+
from pptx.enum.dml import MSO_THEME_COLOR
|
|
21
|
+
from pptx.enum.text import PP_ALIGN
|
|
22
|
+
from pptx.oxml.xmlchemy import OxmlElement
|
|
23
|
+
from pptx.util import Pt
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def clear_paragraph_bullets(paragraph):
|
|
27
|
+
"""Clear bullet formatting from a paragraph."""
|
|
28
|
+
pPr = paragraph._element.get_or_add_pPr()
|
|
29
|
+
|
|
30
|
+
# Remove existing bullet elements
|
|
31
|
+
for child in list(pPr):
|
|
32
|
+
if (
|
|
33
|
+
child.tag.endswith("buChar")
|
|
34
|
+
or child.tag.endswith("buNone")
|
|
35
|
+
or child.tag.endswith("buAutoNum")
|
|
36
|
+
or child.tag.endswith("buFont")
|
|
37
|
+
):
|
|
38
|
+
pPr.remove(child)
|
|
39
|
+
|
|
40
|
+
return pPr
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def apply_paragraph_properties(paragraph, para_data: Dict[str, Any]):
|
|
44
|
+
"""Apply formatting properties to a paragraph."""
|
|
45
|
+
# Get the text but don't set it on paragraph directly yet
|
|
46
|
+
text = para_data.get("text", "")
|
|
47
|
+
|
|
48
|
+
# Get or create paragraph properties
|
|
49
|
+
pPr = clear_paragraph_bullets(paragraph)
|
|
50
|
+
|
|
51
|
+
# Handle bullet formatting
|
|
52
|
+
if para_data.get("bullet", False):
|
|
53
|
+
level = para_data.get("level", 0)
|
|
54
|
+
paragraph.level = level
|
|
55
|
+
|
|
56
|
+
# Calculate font-proportional indentation
|
|
57
|
+
font_size = para_data.get("font_size", 18.0)
|
|
58
|
+
level_indent_emu = int((font_size * (1.6 + level * 1.6)) * 12700)
|
|
59
|
+
hanging_indent_emu = int(-font_size * 0.8 * 12700)
|
|
60
|
+
|
|
61
|
+
# Set indentation
|
|
62
|
+
pPr.attrib["marL"] = str(level_indent_emu)
|
|
63
|
+
pPr.attrib["indent"] = str(hanging_indent_emu)
|
|
64
|
+
|
|
65
|
+
# Add bullet character
|
|
66
|
+
buChar = OxmlElement("a:buChar")
|
|
67
|
+
buChar.set("char", "•")
|
|
68
|
+
pPr.append(buChar)
|
|
69
|
+
|
|
70
|
+
# Default to left alignment for bullets if not specified
|
|
71
|
+
if "alignment" not in para_data:
|
|
72
|
+
paragraph.alignment = PP_ALIGN.LEFT
|
|
73
|
+
else:
|
|
74
|
+
# Remove indentation for non-bullet text
|
|
75
|
+
pPr.attrib["marL"] = "0"
|
|
76
|
+
pPr.attrib["indent"] = "0"
|
|
77
|
+
|
|
78
|
+
# Add buNone element
|
|
79
|
+
buNone = OxmlElement("a:buNone")
|
|
80
|
+
pPr.insert(0, buNone)
|
|
81
|
+
|
|
82
|
+
# Apply alignment
|
|
83
|
+
if "alignment" in para_data:
|
|
84
|
+
alignment_map = {
|
|
85
|
+
"LEFT": PP_ALIGN.LEFT,
|
|
86
|
+
"CENTER": PP_ALIGN.CENTER,
|
|
87
|
+
"RIGHT": PP_ALIGN.RIGHT,
|
|
88
|
+
"JUSTIFY": PP_ALIGN.JUSTIFY,
|
|
89
|
+
}
|
|
90
|
+
if para_data["alignment"] in alignment_map:
|
|
91
|
+
paragraph.alignment = alignment_map[para_data["alignment"]]
|
|
92
|
+
|
|
93
|
+
# Apply spacing
|
|
94
|
+
if "space_before" in para_data:
|
|
95
|
+
paragraph.space_before = Pt(para_data["space_before"])
|
|
96
|
+
if "space_after" in para_data:
|
|
97
|
+
paragraph.space_after = Pt(para_data["space_after"])
|
|
98
|
+
if "line_spacing" in para_data:
|
|
99
|
+
paragraph.line_spacing = Pt(para_data["line_spacing"])
|
|
100
|
+
|
|
101
|
+
# Apply run-level formatting
|
|
102
|
+
if not paragraph.runs:
|
|
103
|
+
run = paragraph.add_run()
|
|
104
|
+
run.text = text
|
|
105
|
+
else:
|
|
106
|
+
run = paragraph.runs[0]
|
|
107
|
+
run.text = text
|
|
108
|
+
|
|
109
|
+
# Apply font properties
|
|
110
|
+
apply_font_properties(run, para_data)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def apply_font_properties(run, para_data: Dict[str, Any]):
|
|
114
|
+
"""Apply font properties to a text run."""
|
|
115
|
+
if "bold" in para_data:
|
|
116
|
+
run.font.bold = para_data["bold"]
|
|
117
|
+
if "italic" in para_data:
|
|
118
|
+
run.font.italic = para_data["italic"]
|
|
119
|
+
if "underline" in para_data:
|
|
120
|
+
run.font.underline = para_data["underline"]
|
|
121
|
+
if "font_size" in para_data:
|
|
122
|
+
run.font.size = Pt(para_data["font_size"])
|
|
123
|
+
if "font_name" in para_data:
|
|
124
|
+
run.font.name = para_data["font_name"]
|
|
125
|
+
|
|
126
|
+
# Apply color - prefer RGB, fall back to theme_color
|
|
127
|
+
if "color" in para_data:
|
|
128
|
+
color_hex = para_data["color"].lstrip("#")
|
|
129
|
+
if len(color_hex) == 6:
|
|
130
|
+
r = int(color_hex[0:2], 16)
|
|
131
|
+
g = int(color_hex[2:4], 16)
|
|
132
|
+
b = int(color_hex[4:6], 16)
|
|
133
|
+
run.font.color.rgb = RGBColor(r, g, b)
|
|
134
|
+
elif "theme_color" in para_data:
|
|
135
|
+
# Get theme color by name (e.g., "DARK_1", "ACCENT_1")
|
|
136
|
+
theme_name = para_data["theme_color"]
|
|
137
|
+
try:
|
|
138
|
+
run.font.color.theme_color = getattr(MSO_THEME_COLOR, theme_name)
|
|
139
|
+
except AttributeError:
|
|
140
|
+
print(f" WARNING: Unknown theme color name '{theme_name}'")
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def detect_frame_overflow(inventory: InventoryData) -> Dict[str, Dict[str, float]]:
|
|
144
|
+
"""Detect text overflow in shapes (text exceeding shape bounds).
|
|
145
|
+
|
|
146
|
+
Returns dict of slide_key -> shape_key -> overflow_inches.
|
|
147
|
+
Only includes shapes that have text overflow.
|
|
148
|
+
"""
|
|
149
|
+
overflow_map = {}
|
|
150
|
+
|
|
151
|
+
for slide_key, shapes_dict in inventory.items():
|
|
152
|
+
for shape_key, shape_data in shapes_dict.items():
|
|
153
|
+
# Check for frame overflow (text exceeding shape bounds)
|
|
154
|
+
if shape_data.frame_overflow_bottom is not None:
|
|
155
|
+
if slide_key not in overflow_map:
|
|
156
|
+
overflow_map[slide_key] = {}
|
|
157
|
+
overflow_map[slide_key][shape_key] = shape_data.frame_overflow_bottom
|
|
158
|
+
|
|
159
|
+
return overflow_map
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def validate_replacements(inventory: InventoryData, replacements: Dict) -> List[str]:
|
|
163
|
+
"""Validate that all shapes in replacements exist in inventory.
|
|
164
|
+
|
|
165
|
+
Returns list of error messages.
|
|
166
|
+
"""
|
|
167
|
+
errors = []
|
|
168
|
+
|
|
169
|
+
for slide_key, shapes_data in replacements.items():
|
|
170
|
+
if not slide_key.startswith("slide-"):
|
|
171
|
+
continue
|
|
172
|
+
|
|
173
|
+
# Check if slide exists
|
|
174
|
+
if slide_key not in inventory:
|
|
175
|
+
errors.append(f"Slide '{slide_key}' not found in inventory")
|
|
176
|
+
continue
|
|
177
|
+
|
|
178
|
+
# Check each shape
|
|
179
|
+
for shape_key in shapes_data.keys():
|
|
180
|
+
if shape_key not in inventory[slide_key]:
|
|
181
|
+
# Find shapes without replacements defined and show their content
|
|
182
|
+
unused_with_content = []
|
|
183
|
+
for k in inventory[slide_key].keys():
|
|
184
|
+
if k not in shapes_data:
|
|
185
|
+
shape_data = inventory[slide_key][k]
|
|
186
|
+
# Get text from paragraphs as preview
|
|
187
|
+
paragraphs = shape_data.paragraphs
|
|
188
|
+
if paragraphs and paragraphs[0].text:
|
|
189
|
+
first_text = paragraphs[0].text[:50]
|
|
190
|
+
if len(paragraphs[0].text) > 50:
|
|
191
|
+
first_text += "..."
|
|
192
|
+
unused_with_content.append(f"{k} ('{first_text}')")
|
|
193
|
+
else:
|
|
194
|
+
unused_with_content.append(k)
|
|
195
|
+
|
|
196
|
+
errors.append(
|
|
197
|
+
f"Shape '{shape_key}' not found on '{slide_key}'. "
|
|
198
|
+
f"Shapes without replacements: {', '.join(sorted(unused_with_content)) if unused_with_content else 'none'}"
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
return errors
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def check_duplicate_keys(pairs):
|
|
205
|
+
"""Check for duplicate keys when loading JSON."""
|
|
206
|
+
result = {}
|
|
207
|
+
for key, value in pairs:
|
|
208
|
+
if key in result:
|
|
209
|
+
raise ValueError(f"Duplicate key found in JSON: '{key}'")
|
|
210
|
+
result[key] = value
|
|
211
|
+
return result
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def apply_replacements(pptx_file: str, json_file: str, output_file: str):
|
|
215
|
+
"""Apply text replacements from JSON to PowerPoint presentation."""
|
|
216
|
+
|
|
217
|
+
# Load presentation
|
|
218
|
+
prs = Presentation(pptx_file)
|
|
219
|
+
|
|
220
|
+
# Get inventory of all text shapes (returns ShapeData objects)
|
|
221
|
+
# Pass prs to use same Presentation instance
|
|
222
|
+
inventory = extract_text_inventory(Path(pptx_file), prs)
|
|
223
|
+
|
|
224
|
+
# Detect text overflow in original presentation
|
|
225
|
+
original_overflow = detect_frame_overflow(inventory)
|
|
226
|
+
|
|
227
|
+
# Load replacement data with duplicate key detection
|
|
228
|
+
with open(json_file, "r") as f:
|
|
229
|
+
replacements = json.load(f, object_pairs_hook=check_duplicate_keys)
|
|
230
|
+
|
|
231
|
+
# Validate replacements
|
|
232
|
+
errors = validate_replacements(inventory, replacements)
|
|
233
|
+
if errors:
|
|
234
|
+
print("ERROR: Invalid shapes in replacement JSON:")
|
|
235
|
+
for error in errors:
|
|
236
|
+
print(f" - {error}")
|
|
237
|
+
print("\nPlease check the inventory and update your replacement JSON.")
|
|
238
|
+
print(
|
|
239
|
+
"You can regenerate the inventory with: python inventory.py <input.pptx> <output.json>"
|
|
240
|
+
)
|
|
241
|
+
raise ValueError(f"Found {len(errors)} validation error(s)")
|
|
242
|
+
|
|
243
|
+
# Track statistics
|
|
244
|
+
shapes_processed = 0
|
|
245
|
+
shapes_cleared = 0
|
|
246
|
+
shapes_replaced = 0
|
|
247
|
+
|
|
248
|
+
# Process each slide from inventory
|
|
249
|
+
for slide_key, shapes_dict in inventory.items():
|
|
250
|
+
if not slide_key.startswith("slide-"):
|
|
251
|
+
continue
|
|
252
|
+
|
|
253
|
+
slide_index = int(slide_key.split("-")[1])
|
|
254
|
+
|
|
255
|
+
if slide_index >= len(prs.slides):
|
|
256
|
+
print(f"Warning: Slide {slide_index} not found")
|
|
257
|
+
continue
|
|
258
|
+
|
|
259
|
+
# Process each shape from inventory
|
|
260
|
+
for shape_key, shape_data in shapes_dict.items():
|
|
261
|
+
shapes_processed += 1
|
|
262
|
+
|
|
263
|
+
# Get the shape directly from ShapeData
|
|
264
|
+
shape = shape_data.shape
|
|
265
|
+
if not shape:
|
|
266
|
+
print(f"Warning: {shape_key} has no shape reference")
|
|
267
|
+
continue
|
|
268
|
+
|
|
269
|
+
# ShapeData already validates text_frame in __init__
|
|
270
|
+
text_frame = shape.text_frame # type: ignore
|
|
271
|
+
|
|
272
|
+
text_frame.clear() # type: ignore
|
|
273
|
+
shapes_cleared += 1
|
|
274
|
+
|
|
275
|
+
# Check for replacement paragraphs
|
|
276
|
+
replacement_shape_data = replacements.get(slide_key, {}).get(shape_key, {})
|
|
277
|
+
if "paragraphs" not in replacement_shape_data:
|
|
278
|
+
continue
|
|
279
|
+
|
|
280
|
+
shapes_replaced += 1
|
|
281
|
+
|
|
282
|
+
# Add replacement paragraphs
|
|
283
|
+
for i, para_data in enumerate(replacement_shape_data["paragraphs"]):
|
|
284
|
+
if i == 0:
|
|
285
|
+
p = text_frame.paragraphs[0] # type: ignore
|
|
286
|
+
else:
|
|
287
|
+
p = text_frame.add_paragraph() # type: ignore
|
|
288
|
+
|
|
289
|
+
apply_paragraph_properties(p, para_data)
|
|
290
|
+
|
|
291
|
+
# Check for issues after replacements
|
|
292
|
+
# Save to a temporary file and reload to avoid modifying the presentation during inventory
|
|
293
|
+
# (extract_text_inventory accesses font.color which adds empty <a:solidFill/> elements)
|
|
294
|
+
import tempfile
|
|
295
|
+
|
|
296
|
+
with tempfile.NamedTemporaryFile(suffix=".pptx", delete=False) as tmp:
|
|
297
|
+
tmp_path = Path(tmp.name)
|
|
298
|
+
prs.save(str(tmp_path))
|
|
299
|
+
|
|
300
|
+
try:
|
|
301
|
+
updated_inventory = extract_text_inventory(tmp_path)
|
|
302
|
+
updated_overflow = detect_frame_overflow(updated_inventory)
|
|
303
|
+
finally:
|
|
304
|
+
tmp_path.unlink() # Clean up temp file
|
|
305
|
+
|
|
306
|
+
# Check if any text overflow got worse
|
|
307
|
+
overflow_errors = []
|
|
308
|
+
for slide_key, shape_overflows in updated_overflow.items():
|
|
309
|
+
for shape_key, new_overflow in shape_overflows.items():
|
|
310
|
+
# Get original overflow (0 if there was no overflow before)
|
|
311
|
+
original = original_overflow.get(slide_key, {}).get(shape_key, 0.0)
|
|
312
|
+
|
|
313
|
+
# Error if overflow increased
|
|
314
|
+
if new_overflow > original + 0.01: # Small tolerance for rounding
|
|
315
|
+
increase = new_overflow - original
|
|
316
|
+
overflow_errors.append(
|
|
317
|
+
f'{slide_key}/{shape_key}: overflow worsened by {increase:.2f}" '
|
|
318
|
+
f'(was {original:.2f}", now {new_overflow:.2f}")'
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
# Collect warnings from updated shapes
|
|
322
|
+
warnings = []
|
|
323
|
+
for slide_key, shapes_dict in updated_inventory.items():
|
|
324
|
+
for shape_key, shape_data in shapes_dict.items():
|
|
325
|
+
if shape_data.warnings:
|
|
326
|
+
for warning in shape_data.warnings:
|
|
327
|
+
warnings.append(f"{slide_key}/{shape_key}: {warning}")
|
|
328
|
+
|
|
329
|
+
# Fail if there are any issues
|
|
330
|
+
if overflow_errors or warnings:
|
|
331
|
+
print("\nERROR: Issues detected in replacement output:")
|
|
332
|
+
if overflow_errors:
|
|
333
|
+
print("\nText overflow worsened:")
|
|
334
|
+
for error in overflow_errors:
|
|
335
|
+
print(f" - {error}")
|
|
336
|
+
if warnings:
|
|
337
|
+
print("\nFormatting warnings:")
|
|
338
|
+
for warning in warnings:
|
|
339
|
+
print(f" - {warning}")
|
|
340
|
+
print("\nPlease fix these issues before saving.")
|
|
341
|
+
raise ValueError(
|
|
342
|
+
f"Found {len(overflow_errors)} overflow error(s) and {len(warnings)} warning(s)"
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
# Save the presentation
|
|
346
|
+
prs.save(output_file)
|
|
347
|
+
|
|
348
|
+
# Report results
|
|
349
|
+
print(f"Saved updated presentation to: {output_file}")
|
|
350
|
+
print(f"Processed {len(prs.slides)} slides")
|
|
351
|
+
print(f" - Shapes processed: {shapes_processed}")
|
|
352
|
+
print(f" - Shapes cleared: {shapes_cleared}")
|
|
353
|
+
print(f" - Shapes replaced: {shapes_replaced}")
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
def main():
|
|
357
|
+
"""Main entry point for command-line usage."""
|
|
358
|
+
if len(sys.argv) != 4:
|
|
359
|
+
print(__doc__)
|
|
360
|
+
sys.exit(1)
|
|
361
|
+
|
|
362
|
+
input_pptx = Path(sys.argv[1])
|
|
363
|
+
replacements_json = Path(sys.argv[2])
|
|
364
|
+
output_pptx = Path(sys.argv[3])
|
|
365
|
+
|
|
366
|
+
if not input_pptx.exists():
|
|
367
|
+
print(f"Error: Input file '{input_pptx}' not found")
|
|
368
|
+
sys.exit(1)
|
|
369
|
+
|
|
370
|
+
if not replacements_json.exists():
|
|
371
|
+
print(f"Error: Replacements JSON file '{replacements_json}' not found")
|
|
372
|
+
sys.exit(1)
|
|
373
|
+
|
|
374
|
+
try:
|
|
375
|
+
apply_replacements(str(input_pptx), str(replacements_json), str(output_pptx))
|
|
376
|
+
except Exception as e:
|
|
377
|
+
print(f"Error applying replacements: {e}")
|
|
378
|
+
import traceback
|
|
379
|
+
|
|
380
|
+
traceback.print_exc()
|
|
381
|
+
sys.exit(1)
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
if __name__ == "__main__":
|
|
385
|
+
main()
|