@kortix/sandbox 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/customize.sh +143 -0
- package/config/kortix-env-setup.sh +25 -0
- package/kortix-master/package.json +22 -0
- package/kortix-master/src/config.ts +22 -0
- package/kortix-master/src/index.ts +44 -0
- package/kortix-master/src/routes/env.ts +65 -0
- package/kortix-master/src/routes/proxy.ts +108 -0
- package/kortix-master/src/routes/update.ts +185 -0
- package/kortix-master/src/services/proxy.ts +43 -0
- package/kortix-master/src/services/secret-store.ts +156 -0
- package/kortix-master/tsconfig.json +14 -0
- package/opencode/agents/kortix-browser.md +142 -0
- package/opencode/agents/kortix-build.md +62 -0
- package/opencode/agents/kortix-explore.md +66 -0
- package/opencode/agents/kortix-image-gen.md +33 -0
- package/opencode/agents/kortix-main.md +450 -0
- package/opencode/agents/kortix-plan.md +100 -0
- package/opencode/agents/kortix-research.md +84 -0
- package/opencode/agents/kortix-sheets.md +61 -0
- package/opencode/agents/kortix-slides.md +64 -0
- package/opencode/agents/kortix-web-dev.md +572 -0
- package/opencode/commands/email.md +36 -0
- package/opencode/commands/init.md +43 -0
- package/opencode/commands/journal.md +44 -0
- package/opencode/commands/memory-init.md +81 -0
- package/opencode/commands/memory-search.md +50 -0
- package/opencode/commands/memory-status.md +56 -0
- package/opencode/commands/research.md +36 -0
- package/opencode/commands/search.md +38 -0
- package/opencode/commands/slides.md +32 -0
- package/opencode/commands/spreadsheet.md +30 -0
- package/opencode/memory.json +37 -0
- package/opencode/ocx.jsonc +10 -0
- package/opencode/opencode.jsonc +103 -0
- package/opencode/package.json +25 -0
- package/opencode/patches/apply.sh +19 -0
- package/opencode/patches/opencode-pty-spawn.txt +49 -0
- package/opencode/plugin/background-agents.ts.disabled +483 -0
- package/opencode/plugin/kdco-primitives/get-project-id.ts +172 -0
- package/opencode/plugin/kdco-primitives/index.ts +26 -0
- package/opencode/plugin/kdco-primitives/log-warn.ts +51 -0
- package/opencode/plugin/kdco-primitives/mutex.ts +122 -0
- package/opencode/plugin/kdco-primitives/shell.ts +138 -0
- package/opencode/plugin/kdco-primitives/temp.ts +36 -0
- package/opencode/plugin/kdco-primitives/terminal-detect.ts +34 -0
- package/opencode/plugin/kdco-primitives/types.ts +13 -0
- package/opencode/plugin/kdco-primitives/with-timeout.ts +84 -0
- package/opencode/plugin/memory.ts +306 -0
- package/opencode/plugin/worktree/state.ts +412 -0
- package/opencode/plugin/worktree/terminal.ts +1002 -0
- package/opencode/plugin/worktree.ts +861 -0
- package/opencode/skills/KORTIX-browser/SKILL.md +478 -0
- package/opencode/skills/KORTIX-cron-triggers/SKILL.md +173 -0
- package/opencode/skills/KORTIX-deep-research/SKILL.md +278 -0
- package/opencode/skills/KORTIX-docx/SKILL.md +398 -0
- package/opencode/skills/KORTIX-docx/scripts/__init__.py +1 -0
- package/opencode/skills/KORTIX-docx/scripts/accept_changes.py +104 -0
- package/opencode/skills/KORTIX-docx/scripts/comment.py +244 -0
- package/opencode/skills/KORTIX-docx/scripts/office/helpers/__init__.py +0 -0
- package/opencode/skills/KORTIX-docx/scripts/office/helpers/merge_runs.py +199 -0
- package/opencode/skills/KORTIX-docx/scripts/office/helpers/simplify_redlines.py +197 -0
- package/opencode/skills/KORTIX-docx/scripts/office/pack.py +159 -0
- package/opencode/skills/KORTIX-docx/scripts/office/soffice.py +183 -0
- package/opencode/skills/KORTIX-docx/scripts/office/unpack.py +132 -0
- package/opencode/skills/KORTIX-docx/scripts/office/validate.py +111 -0
- package/opencode/skills/KORTIX-docx/scripts/office/validators/__init__.py +15 -0
- package/opencode/skills/KORTIX-docx/scripts/office/validators/base.py +847 -0
- package/opencode/skills/KORTIX-docx/scripts/office/validators/docx.py +446 -0
- package/opencode/skills/KORTIX-docx/scripts/office/validators/pptx.py +275 -0
- package/opencode/skills/KORTIX-docx/scripts/office/validators/redlining.py +247 -0
- package/opencode/skills/KORTIX-docx/scripts/render_docx.py +179 -0
- package/opencode/skills/KORTIX-docx/scripts/templates/comments.xml +3 -0
- package/opencode/skills/KORTIX-docx/scripts/templates/commentsExtended.xml +3 -0
- package/opencode/skills/KORTIX-docx/scripts/templates/commentsExtensible.xml +3 -0
- package/opencode/skills/KORTIX-docx/scripts/templates/commentsIds.xml +3 -0
- package/opencode/skills/KORTIX-docx/scripts/templates/people.xml +3 -0
- package/opencode/skills/KORTIX-domain-research/SKILL.md +96 -0
- package/opencode/skills/KORTIX-domain-research/scripts/domain-lookup.py +810 -0
- package/opencode/skills/KORTIX-elevenlabs/SKILL.md +230 -0
- package/opencode/skills/KORTIX-elevenlabs/scripts/tts.py +389 -0
- package/opencode/skills/KORTIX-email/SKILL.md +145 -0
- package/opencode/skills/KORTIX-legal-writer/SKILL.md +409 -0
- package/opencode/skills/KORTIX-legal-writer/references/bluebook.md +152 -0
- package/opencode/skills/KORTIX-legal-writer/references/document-types.md +416 -0
- package/opencode/skills/KORTIX-legal-writer/scripts/courtlistener.py +291 -0
- package/opencode/skills/KORTIX-legal-writer/scripts/ecfr_lookup.py +299 -0
- package/opencode/skills/KORTIX-legal-writer/scripts/verify-legal.py +507 -0
- package/opencode/skills/KORTIX-logo-creator/SKILL.md +293 -0
- package/opencode/skills/KORTIX-logo-creator/references/prompt-patterns.md +134 -0
- package/opencode/skills/KORTIX-logo-creator/scripts/compose_logo.py +406 -0
- package/opencode/skills/KORTIX-logo-creator/scripts/create_logo_sheet.py +258 -0
- package/opencode/skills/KORTIX-logo-creator/scripts/remove_bg.py +96 -0
- package/opencode/skills/KORTIX-memory/SKILL.md +261 -0
- package/opencode/skills/KORTIX-memory/scripts/export-sessions.py +409 -0
- package/opencode/skills/KORTIX-paper-creator/SKILL.md +549 -0
- package/opencode/skills/KORTIX-paper-creator/assets/template.tex +101 -0
- package/opencode/skills/KORTIX-paper-creator/scripts/compile.sh +177 -0
- package/opencode/skills/KORTIX-paper-creator/scripts/openalex_to_bibtex.py +220 -0
- package/opencode/skills/KORTIX-paper-creator/scripts/verify.sh +354 -0
- package/opencode/skills/KORTIX-paper-search/SKILL.md +418 -0
- package/opencode/skills/KORTIX-pdf/SKILL.md +232 -0
- package/opencode/skills/KORTIX-pdf/forms.md +36 -0
- package/opencode/skills/KORTIX-pdf/reference.md +105 -0
- package/opencode/skills/KORTIX-pdf/scripts/check_bounding_boxes.py +65 -0
- package/opencode/skills/KORTIX-pdf/scripts/check_fillable_fields.py +11 -0
- package/opencode/skills/KORTIX-pdf/scripts/convert_pdf_to_images.py +33 -0
- package/opencode/skills/KORTIX-pdf/scripts/create_validation_image.py +37 -0
- package/opencode/skills/KORTIX-pdf/scripts/extract_form_field_info.py +122 -0
- package/opencode/skills/KORTIX-pdf/scripts/extract_form_structure.py +115 -0
- package/opencode/skills/KORTIX-pdf/scripts/fill_fillable_fields.py +98 -0
- package/opencode/skills/KORTIX-pdf/scripts/fill_pdf_form_with_annotations.py +107 -0
- package/opencode/skills/KORTIX-plan/SKILL.md +228 -0
- package/opencode/skills/KORTIX-presentation-viewer/SKILL.md +87 -0
- package/opencode/skills/KORTIX-presentation-viewer/serve.ts +136 -0
- package/opencode/skills/KORTIX-presentation-viewer/viewer.html +559 -0
- package/opencode/skills/KORTIX-presentations/SKILL.md +344 -0
- package/opencode/skills/KORTIX-remotion/SKILL.md +56 -0
- package/opencode/skills/KORTIX-remotion/rules/3d.md +86 -0
- package/opencode/skills/KORTIX-remotion/rules/animations.md +29 -0
- package/opencode/skills/KORTIX-remotion/rules/assets.md +78 -0
- package/opencode/skills/KORTIX-remotion/rules/audio-visualization.md +198 -0
- package/opencode/skills/KORTIX-remotion/rules/audio.md +169 -0
- package/opencode/skills/KORTIX-remotion/rules/calculate-metadata.md +104 -0
- package/opencode/skills/KORTIX-remotion/rules/can-decode.md +75 -0
- package/opencode/skills/KORTIX-remotion/rules/charts.md +120 -0
- package/opencode/skills/KORTIX-remotion/rules/compositions.md +141 -0
- package/opencode/skills/KORTIX-remotion/rules/display-captions.md +184 -0
- package/opencode/skills/KORTIX-remotion/rules/extract-frames.md +229 -0
- package/opencode/skills/KORTIX-remotion/rules/ffmpeg.md +38 -0
- package/opencode/skills/KORTIX-remotion/rules/fonts.md +152 -0
- package/opencode/skills/KORTIX-remotion/rules/get-audio-duration.md +58 -0
- package/opencode/skills/KORTIX-remotion/rules/get-video-dimensions.md +68 -0
- package/opencode/skills/KORTIX-remotion/rules/get-video-duration.md +58 -0
- package/opencode/skills/KORTIX-remotion/rules/gifs.md +141 -0
- package/opencode/skills/KORTIX-remotion/rules/images.md +130 -0
- package/opencode/skills/KORTIX-remotion/rules/import-srt-captions.md +69 -0
- package/opencode/skills/KORTIX-remotion/rules/light-leaks.md +73 -0
- package/opencode/skills/KORTIX-remotion/rules/lottie.md +68 -0
- package/opencode/skills/KORTIX-remotion/rules/maps.md +401 -0
- package/opencode/skills/KORTIX-remotion/rules/measuring-dom-nodes.md +35 -0
- package/opencode/skills/KORTIX-remotion/rules/measuring-text.md +143 -0
- package/opencode/skills/KORTIX-remotion/rules/parameters.md +98 -0
- package/opencode/skills/KORTIX-remotion/rules/sequencing.md +118 -0
- package/opencode/skills/KORTIX-remotion/rules/subtitles.md +36 -0
- package/opencode/skills/KORTIX-remotion/rules/tailwind.md +11 -0
- package/opencode/skills/KORTIX-remotion/rules/text-animations.md +20 -0
- package/opencode/skills/KORTIX-remotion/rules/timing.md +179 -0
- package/opencode/skills/KORTIX-remotion/rules/transcribe-captions.md +70 -0
- package/opencode/skills/KORTIX-remotion/rules/transitions.md +197 -0
- package/opencode/skills/KORTIX-remotion/rules/transparent-videos.md +106 -0
- package/opencode/skills/KORTIX-remotion/rules/trimming.md +53 -0
- package/opencode/skills/KORTIX-remotion/rules/videos.md +171 -0
- package/opencode/skills/KORTIX-secrets/SKILL.md +280 -0
- package/opencode/skills/KORTIX-semantic-search/SKILL.md +213 -0
- package/opencode/skills/KORTIX-session-search/SKILL.md +807 -0
- package/opencode/skills/KORTIX-session-search/Untitled +1 -0
- package/opencode/skills/KORTIX-skill-creator/SKILL.md +163 -0
- package/opencode/skills/KORTIX-web-research/SKILL.md +69 -0
- package/opencode/skills/KORTIX-xlsx/LICENSE.txt +30 -0
- package/opencode/skills/KORTIX-xlsx/SKILL.md +549 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/helpers/__init__.py +0 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/helpers/merge_runs.py +199 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/helpers/simplify_redlines.py +197 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/pack.py +159 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/mce/mc.xsd +75 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/soffice.py +183 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/unpack.py +132 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/validate.py +111 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/validators/__init__.py +15 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/validators/base.py +847 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/validators/docx.py +446 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/validators/pptx.py +275 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/validators/redlining.py +247 -0
- package/opencode/skills/KORTIX-xlsx/scripts/recalc.py +184 -0
- package/opencode/tools/image-gen.ts +342 -0
- package/opencode/tools/image-search.ts +190 -0
- package/opencode/tools/memory-get.ts +168 -0
- package/opencode/tools/memory-search.ts +247 -0
- package/opencode/tools/presentation-gen.ts +723 -0
- package/opencode/tools/scrape-webpage.ts +115 -0
- package/opencode/tools/scripts/.python-version +1 -0
- package/opencode/tools/scripts/convert_pdf.py +184 -0
- package/opencode/tools/scripts/convert_pptx.py +562 -0
- package/opencode/tools/scripts/pyproject.toml +11 -0
- package/opencode/tools/scripts/uv.lock +287 -0
- package/opencode/tools/scripts/validate_slide.py +74 -0
- package/opencode/tools/show-user.ts +217 -0
- package/opencode/tools/tests/e2e-presentation-fix.ts +277 -0
- package/opencode/tools/tests/image-gen.test.ts +215 -0
- package/opencode/tools/tests/image-search.test.ts +125 -0
- package/opencode/tools/tests/memory-system-benchmark.ts +1076 -0
- package/opencode/tools/tests/presentation-gen.test.ts +389 -0
- package/opencode/tools/tests/scrape-webpage.test.ts +74 -0
- package/opencode/tools/tests/show-user.test.ts +241 -0
- package/opencode/tools/tests/video-gen.test.ts +110 -0
- package/opencode/tools/tests/web-search.test.ts +106 -0
- package/opencode/tools/video-gen.ts +200 -0
- package/opencode/tools/web-search.ts +153 -0
- package/opencode/tsconfig.json +29 -0
- package/package.json +36 -0
- package/patch-agent-browser.js +100 -0
- package/postinstall.sh +88 -0
- package/services/KORTIX-presentation-viewer/run +37 -0
- package/services/agent-browser-viewer/run +48 -0
- package/services/kortix-master/run +16 -0
- package/services/lss-sync/run +22 -0
- package/services/opencode-serve/run +25 -0
- package/services/opencode-web/run +21 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:s="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns="http://schemas.microsoft.com/office/word/2018/wordml/cex" targetNamespace="http://schemas.microsoft.com/office/word/2018/wordml/cex">
|
|
2
|
+
<xsd:import id="w16" namespace="http://schemas.microsoft.com/office/word/2018/wordml" schemaLocation="wml-2018.xsd"/>
|
|
3
|
+
<xsd:import id="w" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
|
|
4
|
+
<xsd:import id="s" namespace="http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes" schemaLocation="../ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd"/>
|
|
5
|
+
<xsd:complexType name="CT_CommentsExtensible">
|
|
6
|
+
<xsd:sequence>
|
|
7
|
+
<xsd:element name="commentExtensible" type="CT_CommentExtensible" minOccurs="0" maxOccurs="unbounded"/>
|
|
8
|
+
<xsd:element name="extLst" type="w16:CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
|
|
9
|
+
</xsd:sequence>
|
|
10
|
+
</xsd:complexType>
|
|
11
|
+
<xsd:complexType name="CT_CommentExtensible">
|
|
12
|
+
<xsd:sequence>
|
|
13
|
+
<xsd:element name="extLst" type="w16:CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
|
|
14
|
+
</xsd:sequence>
|
|
15
|
+
<xsd:attribute name="durableId" type="w:ST_LongHexNumber" use="required"/>
|
|
16
|
+
<xsd:attribute name="dateUtc" type="w:ST_DateTime" use="optional"/>
|
|
17
|
+
<xsd:attribute name="intelligentPlaceholder" type="s:ST_OnOff" use="optional"/>
|
|
18
|
+
</xsd:complexType>
|
|
19
|
+
<xsd:element name="commentsExtensible" type="CT_CommentsExtensible"/>
|
|
20
|
+
</xsd:schema>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w12="http://schemas.openxmlformats.org/wordprocessingml/2006/main" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns="http://schemas.microsoft.com/office/word/2016/wordml/cid" targetNamespace="http://schemas.microsoft.com/office/word/2016/wordml/cid">
|
|
2
|
+
<xsd:import id="w12" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
|
|
3
|
+
<xsd:complexType name="CT_CommentsIds">
|
|
4
|
+
<xsd:sequence>
|
|
5
|
+
<xsd:element name="commentId" type="CT_CommentId" minOccurs="0" maxOccurs="unbounded"/>
|
|
6
|
+
</xsd:sequence>
|
|
7
|
+
</xsd:complexType>
|
|
8
|
+
<xsd:complexType name="CT_CommentId">
|
|
9
|
+
<xsd:attribute name="paraId" type="w12:ST_LongHexNumber" use="required"/>
|
|
10
|
+
<xsd:attribute name="durableId" type="w12:ST_LongHexNumber" use="required"/>
|
|
11
|
+
</xsd:complexType>
|
|
12
|
+
<xsd:element name="commentsIds" type="CT_CommentsIds"/>
|
|
13
|
+
</xsd:schema>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w12="http://schemas.openxmlformats.org/wordprocessingml/2006/main" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" targetNamespace="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash">
|
|
2
|
+
<xsd:import id="w12" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
|
|
3
|
+
<xsd:attribute name="storeItemChecksum" type="w12:ST_String"/>
|
|
4
|
+
</xsd:schema>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:w12="http://schemas.openxmlformats.org/wordprocessingml/2006/main" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" xmlns="http://schemas.microsoft.com/office/word/2015/wordml/symex" targetNamespace="http://schemas.microsoft.com/office/word/2015/wordml/symex">
|
|
2
|
+
<xsd:import id="w12" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="../ISO-IEC29500-4_2016/wml.xsd"/>
|
|
3
|
+
<xsd:complexType name="CT_SymEx">
|
|
4
|
+
<xsd:attribute name="font" type="w12:ST_String"/>
|
|
5
|
+
<xsd:attribute name="char" type="w12:ST_LongHexNumber"/>
|
|
6
|
+
</xsd:complexType>
|
|
7
|
+
<xsd:element name="symEx" type="CT_SymEx"/>
|
|
8
|
+
</xsd:schema>
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Helper for running LibreOffice (soffice) in environments where AF_UNIX
|
|
3
|
+
sockets may be blocked (e.g., sandboxed VMs). Detects the restriction
|
|
4
|
+
at runtime and applies an LD_PRELOAD shim if needed.
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
from office.soffice import run_soffice, get_soffice_env
|
|
8
|
+
|
|
9
|
+
# Option 1 – run soffice directly
|
|
10
|
+
result = run_soffice(["--headless", "--convert-to", "pdf", "input.docx"])
|
|
11
|
+
|
|
12
|
+
# Option 2 – get env dict for your own subprocess calls
|
|
13
|
+
env = get_soffice_env()
|
|
14
|
+
subprocess.run(["soffice", ...], env=env)
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
import os
|
|
18
|
+
import socket
|
|
19
|
+
import subprocess
|
|
20
|
+
import tempfile
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def get_soffice_env() -> dict:
|
|
25
|
+
env = os.environ.copy()
|
|
26
|
+
env["SAL_USE_VCLPLUGIN"] = "svp"
|
|
27
|
+
|
|
28
|
+
if _needs_shim():
|
|
29
|
+
shim = _ensure_shim()
|
|
30
|
+
env["LD_PRELOAD"] = str(shim)
|
|
31
|
+
|
|
32
|
+
return env
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def run_soffice(args: list[str], **kwargs) -> subprocess.CompletedProcess:
|
|
36
|
+
env = get_soffice_env()
|
|
37
|
+
return subprocess.run(["soffice"] + args, env=env, **kwargs)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
_SHIM_SO = Path(tempfile.gettempdir()) / "lo_socket_shim.so"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _needs_shim() -> bool:
|
|
45
|
+
try:
|
|
46
|
+
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
|
47
|
+
s.close()
|
|
48
|
+
return False
|
|
49
|
+
except OSError:
|
|
50
|
+
return True
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _ensure_shim() -> Path:
|
|
54
|
+
if _SHIM_SO.exists():
|
|
55
|
+
return _SHIM_SO
|
|
56
|
+
|
|
57
|
+
src = Path(tempfile.gettempdir()) / "lo_socket_shim.c"
|
|
58
|
+
src.write_text(_SHIM_SOURCE)
|
|
59
|
+
subprocess.run(
|
|
60
|
+
["gcc", "-shared", "-fPIC", "-o", str(_SHIM_SO), str(src), "-ldl"],
|
|
61
|
+
check=True,
|
|
62
|
+
capture_output=True,
|
|
63
|
+
)
|
|
64
|
+
src.unlink()
|
|
65
|
+
return _SHIM_SO
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
_SHIM_SOURCE = r"""
|
|
70
|
+
#define _GNU_SOURCE
|
|
71
|
+
#include <dlfcn.h>
|
|
72
|
+
#include <errno.h>
|
|
73
|
+
#include <signal.h>
|
|
74
|
+
#include <stdio.h>
|
|
75
|
+
#include <stdlib.h>
|
|
76
|
+
#include <sys/socket.h>
|
|
77
|
+
#include <unistd.h>
|
|
78
|
+
|
|
79
|
+
static int (*real_socket)(int, int, int);
|
|
80
|
+
static int (*real_socketpair)(int, int, int, int[2]);
|
|
81
|
+
static int (*real_listen)(int, int);
|
|
82
|
+
static int (*real_accept)(int, struct sockaddr *, socklen_t *);
|
|
83
|
+
static int (*real_close)(int);
|
|
84
|
+
static int (*real_read)(int, void *, size_t);
|
|
85
|
+
|
|
86
|
+
/* Per-FD bookkeeping (FDs >= 1024 are passed through unshimmed). */
|
|
87
|
+
static int is_shimmed[1024];
|
|
88
|
+
static int peer_of[1024];
|
|
89
|
+
static int wake_r[1024]; /* accept() blocks reading this */
|
|
90
|
+
static int wake_w[1024]; /* close() writes to this */
|
|
91
|
+
static int listener_fd = -1; /* FD that received listen() */
|
|
92
|
+
|
|
93
|
+
__attribute__((constructor))
|
|
94
|
+
static void init(void) {
|
|
95
|
+
real_socket = dlsym(RTLD_NEXT, "socket");
|
|
96
|
+
real_socketpair = dlsym(RTLD_NEXT, "socketpair");
|
|
97
|
+
real_listen = dlsym(RTLD_NEXT, "listen");
|
|
98
|
+
real_accept = dlsym(RTLD_NEXT, "accept");
|
|
99
|
+
real_close = dlsym(RTLD_NEXT, "close");
|
|
100
|
+
real_read = dlsym(RTLD_NEXT, "read");
|
|
101
|
+
for (int i = 0; i < 1024; i++) {
|
|
102
|
+
peer_of[i] = -1;
|
|
103
|
+
wake_r[i] = -1;
|
|
104
|
+
wake_w[i] = -1;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* ---- socket ---------------------------------------------------------- */
|
|
109
|
+
int socket(int domain, int type, int protocol) {
|
|
110
|
+
if (domain == AF_UNIX) {
|
|
111
|
+
int fd = real_socket(domain, type, protocol);
|
|
112
|
+
if (fd >= 0) return fd;
|
|
113
|
+
/* socket(AF_UNIX) blocked – fall back to socketpair(). */
|
|
114
|
+
int sv[2];
|
|
115
|
+
if (real_socketpair(domain, type, protocol, sv) == 0) {
|
|
116
|
+
if (sv[0] >= 0 && sv[0] < 1024) {
|
|
117
|
+
is_shimmed[sv[0]] = 1;
|
|
118
|
+
peer_of[sv[0]] = sv[1];
|
|
119
|
+
int wp[2];
|
|
120
|
+
if (pipe(wp) == 0) {
|
|
121
|
+
wake_r[sv[0]] = wp[0];
|
|
122
|
+
wake_w[sv[0]] = wp[1];
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return sv[0];
|
|
126
|
+
}
|
|
127
|
+
errno = EPERM;
|
|
128
|
+
return -1;
|
|
129
|
+
}
|
|
130
|
+
return real_socket(domain, type, protocol);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/* ---- listen ---------------------------------------------------------- */
|
|
134
|
+
int listen(int sockfd, int backlog) {
|
|
135
|
+
if (sockfd >= 0 && sockfd < 1024 && is_shimmed[sockfd]) {
|
|
136
|
+
listener_fd = sockfd;
|
|
137
|
+
return 0;
|
|
138
|
+
}
|
|
139
|
+
return real_listen(sockfd, backlog);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/* ---- accept ---------------------------------------------------------- */
|
|
143
|
+
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
|
|
144
|
+
if (sockfd >= 0 && sockfd < 1024 && is_shimmed[sockfd]) {
|
|
145
|
+
/* Block until close() writes to the wake pipe. */
|
|
146
|
+
if (wake_r[sockfd] >= 0) {
|
|
147
|
+
char buf;
|
|
148
|
+
real_read(wake_r[sockfd], &buf, 1);
|
|
149
|
+
}
|
|
150
|
+
errno = ECONNABORTED;
|
|
151
|
+
return -1;
|
|
152
|
+
}
|
|
153
|
+
return real_accept(sockfd, addr, addrlen);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/* ---- close ----------------------------------------------------------- */
|
|
157
|
+
int close(int fd) {
|
|
158
|
+
if (fd >= 0 && fd < 1024 && is_shimmed[fd]) {
|
|
159
|
+
int was_listener = (fd == listener_fd);
|
|
160
|
+
is_shimmed[fd] = 0;
|
|
161
|
+
|
|
162
|
+
if (wake_w[fd] >= 0) { /* unblock accept() */
|
|
163
|
+
char c = 0;
|
|
164
|
+
write(wake_w[fd], &c, 1);
|
|
165
|
+
real_close(wake_w[fd]);
|
|
166
|
+
wake_w[fd] = -1;
|
|
167
|
+
}
|
|
168
|
+
if (wake_r[fd] >= 0) { real_close(wake_r[fd]); wake_r[fd] = -1; }
|
|
169
|
+
if (peer_of[fd] >= 0) { real_close(peer_of[fd]); peer_of[fd] = -1; }
|
|
170
|
+
|
|
171
|
+
if (was_listener)
|
|
172
|
+
_exit(0); /* conversion done – exit */
|
|
173
|
+
}
|
|
174
|
+
return real_close(fd);
|
|
175
|
+
}
|
|
176
|
+
"""
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
if __name__ == "__main__":
|
|
181
|
+
import sys
|
|
182
|
+
result = run_soffice(sys.argv[1:])
|
|
183
|
+
sys.exit(result.returncode)
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"""Unpack Office files (DOCX, PPTX, XLSX) for editing.
|
|
2
|
+
|
|
3
|
+
Extracts the ZIP archive, pretty-prints XML files, and optionally:
|
|
4
|
+
- Merges adjacent runs with identical formatting (DOCX only)
|
|
5
|
+
- Simplifies adjacent tracked changes from same author (DOCX only)
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
python unpack.py <office_file> <output_dir> [options]
|
|
9
|
+
|
|
10
|
+
Examples:
|
|
11
|
+
python unpack.py document.docx unpacked/
|
|
12
|
+
python unpack.py presentation.pptx unpacked/
|
|
13
|
+
python unpack.py document.docx unpacked/ --merge-runs false
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import argparse
|
|
17
|
+
import sys
|
|
18
|
+
import zipfile
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
|
|
21
|
+
import defusedxml.minidom
|
|
22
|
+
|
|
23
|
+
from helpers.merge_runs import merge_runs as do_merge_runs
|
|
24
|
+
from helpers.simplify_redlines import simplify_redlines as do_simplify_redlines
|
|
25
|
+
|
|
26
|
+
SMART_QUOTE_REPLACEMENTS = {
|
|
27
|
+
"\u201c": "“",
|
|
28
|
+
"\u201d": "”",
|
|
29
|
+
"\u2018": "‘",
|
|
30
|
+
"\u2019": "’",
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def unpack(
|
|
35
|
+
input_file: str,
|
|
36
|
+
output_directory: str,
|
|
37
|
+
merge_runs: bool = True,
|
|
38
|
+
simplify_redlines: bool = True,
|
|
39
|
+
) -> tuple[None, str]:
|
|
40
|
+
input_path = Path(input_file)
|
|
41
|
+
output_path = Path(output_directory)
|
|
42
|
+
suffix = input_path.suffix.lower()
|
|
43
|
+
|
|
44
|
+
if not input_path.exists():
|
|
45
|
+
return None, f"Error: {input_file} does not exist"
|
|
46
|
+
|
|
47
|
+
if suffix not in {".docx", ".pptx", ".xlsx"}:
|
|
48
|
+
return None, f"Error: {input_file} must be a .docx, .pptx, or .xlsx file"
|
|
49
|
+
|
|
50
|
+
try:
|
|
51
|
+
output_path.mkdir(parents=True, exist_ok=True)
|
|
52
|
+
|
|
53
|
+
with zipfile.ZipFile(input_path, "r") as zf:
|
|
54
|
+
zf.extractall(output_path)
|
|
55
|
+
|
|
56
|
+
xml_files = list(output_path.rglob("*.xml")) + list(output_path.rglob("*.rels"))
|
|
57
|
+
for xml_file in xml_files:
|
|
58
|
+
_pretty_print_xml(xml_file)
|
|
59
|
+
|
|
60
|
+
message = f"Unpacked {input_file} ({len(xml_files)} XML files)"
|
|
61
|
+
|
|
62
|
+
if suffix == ".docx":
|
|
63
|
+
if simplify_redlines:
|
|
64
|
+
simplify_count, _ = do_simplify_redlines(str(output_path))
|
|
65
|
+
message += f", simplified {simplify_count} tracked changes"
|
|
66
|
+
|
|
67
|
+
if merge_runs:
|
|
68
|
+
merge_count, _ = do_merge_runs(str(output_path))
|
|
69
|
+
message += f", merged {merge_count} runs"
|
|
70
|
+
|
|
71
|
+
for xml_file in xml_files:
|
|
72
|
+
_escape_smart_quotes(xml_file)
|
|
73
|
+
|
|
74
|
+
return None, message
|
|
75
|
+
|
|
76
|
+
except zipfile.BadZipFile:
|
|
77
|
+
return None, f"Error: {input_file} is not a valid Office file"
|
|
78
|
+
except Exception as e:
|
|
79
|
+
return None, f"Error unpacking: {e}"
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _pretty_print_xml(xml_file: Path) -> None:
|
|
83
|
+
try:
|
|
84
|
+
content = xml_file.read_text(encoding="utf-8")
|
|
85
|
+
dom = defusedxml.minidom.parseString(content)
|
|
86
|
+
xml_file.write_bytes(dom.toprettyxml(indent=" ", encoding="utf-8"))
|
|
87
|
+
except Exception:
|
|
88
|
+
pass
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def _escape_smart_quotes(xml_file: Path) -> None:
|
|
92
|
+
try:
|
|
93
|
+
content = xml_file.read_text(encoding="utf-8")
|
|
94
|
+
for char, entity in SMART_QUOTE_REPLACEMENTS.items():
|
|
95
|
+
content = content.replace(char, entity)
|
|
96
|
+
xml_file.write_text(content, encoding="utf-8")
|
|
97
|
+
except Exception:
|
|
98
|
+
pass
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
if __name__ == "__main__":
|
|
102
|
+
parser = argparse.ArgumentParser(
|
|
103
|
+
description="Unpack an Office file (DOCX, PPTX, XLSX) for editing"
|
|
104
|
+
)
|
|
105
|
+
parser.add_argument("input_file", help="Office file to unpack")
|
|
106
|
+
parser.add_argument("output_directory", help="Output directory")
|
|
107
|
+
parser.add_argument(
|
|
108
|
+
"--merge-runs",
|
|
109
|
+
type=lambda x: x.lower() == "true",
|
|
110
|
+
default=True,
|
|
111
|
+
metavar="true|false",
|
|
112
|
+
help="Merge adjacent runs with identical formatting (DOCX only, default: true)",
|
|
113
|
+
)
|
|
114
|
+
parser.add_argument(
|
|
115
|
+
"--simplify-redlines",
|
|
116
|
+
type=lambda x: x.lower() == "true",
|
|
117
|
+
default=True,
|
|
118
|
+
metavar="true|false",
|
|
119
|
+
help="Merge adjacent tracked changes from same author (DOCX only, default: true)",
|
|
120
|
+
)
|
|
121
|
+
args = parser.parse_args()
|
|
122
|
+
|
|
123
|
+
_, message = unpack(
|
|
124
|
+
args.input_file,
|
|
125
|
+
args.output_directory,
|
|
126
|
+
merge_runs=args.merge_runs,
|
|
127
|
+
simplify_redlines=args.simplify_redlines,
|
|
128
|
+
)
|
|
129
|
+
print(message)
|
|
130
|
+
|
|
131
|
+
if "Error" in message:
|
|
132
|
+
sys.exit(1)
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Command line tool to validate Office document XML files against XSD schemas and tracked changes.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
python validate.py <path> [--original <original_file>] [--auto-repair] [--author NAME]
|
|
6
|
+
|
|
7
|
+
The first argument can be either:
|
|
8
|
+
- An unpacked directory containing the Office document XML files
|
|
9
|
+
- A packed Office file (.docx/.pptx/.xlsx) which will be unpacked to a temp directory
|
|
10
|
+
|
|
11
|
+
Auto-repair fixes:
|
|
12
|
+
- paraId/durableId values that exceed OOXML limits
|
|
13
|
+
- Missing xml:space="preserve" on w:t elements with whitespace
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import argparse
|
|
17
|
+
import sys
|
|
18
|
+
import tempfile
|
|
19
|
+
import zipfile
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
|
|
22
|
+
from validators import DOCXSchemaValidator, PPTXSchemaValidator, RedliningValidator
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def main():
|
|
26
|
+
parser = argparse.ArgumentParser(description="Validate Office document XML files")
|
|
27
|
+
parser.add_argument(
|
|
28
|
+
"path",
|
|
29
|
+
help="Path to unpacked directory or packed Office file (.docx/.pptx/.xlsx)",
|
|
30
|
+
)
|
|
31
|
+
parser.add_argument(
|
|
32
|
+
"--original",
|
|
33
|
+
required=False,
|
|
34
|
+
default=None,
|
|
35
|
+
help="Path to original file (.docx/.pptx/.xlsx). If omitted, all XSD errors are reported and redlining validation is skipped.",
|
|
36
|
+
)
|
|
37
|
+
parser.add_argument(
|
|
38
|
+
"-v",
|
|
39
|
+
"--verbose",
|
|
40
|
+
action="store_true",
|
|
41
|
+
help="Enable verbose output",
|
|
42
|
+
)
|
|
43
|
+
parser.add_argument(
|
|
44
|
+
"--auto-repair",
|
|
45
|
+
action="store_true",
|
|
46
|
+
help="Automatically repair common issues (hex IDs, whitespace preservation)",
|
|
47
|
+
)
|
|
48
|
+
parser.add_argument(
|
|
49
|
+
"--author",
|
|
50
|
+
default="Claude",
|
|
51
|
+
help="Author name for redlining validation (default: Claude)",
|
|
52
|
+
)
|
|
53
|
+
args = parser.parse_args()
|
|
54
|
+
|
|
55
|
+
path = Path(args.path)
|
|
56
|
+
assert path.exists(), f"Error: {path} does not exist"
|
|
57
|
+
|
|
58
|
+
original_file = None
|
|
59
|
+
if args.original:
|
|
60
|
+
original_file = Path(args.original)
|
|
61
|
+
assert original_file.is_file(), f"Error: {original_file} is not a file"
|
|
62
|
+
assert original_file.suffix.lower() in [".docx", ".pptx", ".xlsx"], (
|
|
63
|
+
f"Error: {original_file} must be a .docx, .pptx, or .xlsx file"
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
file_extension = (original_file or path).suffix.lower()
|
|
67
|
+
assert file_extension in [".docx", ".pptx", ".xlsx"], (
|
|
68
|
+
f"Error: Cannot determine file type from {path}. Use --original or provide a .docx/.pptx/.xlsx file."
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
if path.is_file() and path.suffix.lower() in [".docx", ".pptx", ".xlsx"]:
|
|
72
|
+
temp_dir = tempfile.mkdtemp()
|
|
73
|
+
with zipfile.ZipFile(path, "r") as zf:
|
|
74
|
+
zf.extractall(temp_dir)
|
|
75
|
+
unpacked_dir = Path(temp_dir)
|
|
76
|
+
else:
|
|
77
|
+
assert path.is_dir(), f"Error: {path} is not a directory or Office file"
|
|
78
|
+
unpacked_dir = path
|
|
79
|
+
|
|
80
|
+
match file_extension:
|
|
81
|
+
case ".docx":
|
|
82
|
+
validators = [
|
|
83
|
+
DOCXSchemaValidator(unpacked_dir, original_file, verbose=args.verbose),
|
|
84
|
+
]
|
|
85
|
+
if original_file:
|
|
86
|
+
validators.append(
|
|
87
|
+
RedliningValidator(unpacked_dir, original_file, verbose=args.verbose, author=args.author)
|
|
88
|
+
)
|
|
89
|
+
case ".pptx":
|
|
90
|
+
validators = [
|
|
91
|
+
PPTXSchemaValidator(unpacked_dir, original_file, verbose=args.verbose),
|
|
92
|
+
]
|
|
93
|
+
case _:
|
|
94
|
+
print(f"Error: Validation not supported for file type {file_extension}")
|
|
95
|
+
sys.exit(1)
|
|
96
|
+
|
|
97
|
+
if args.auto_repair:
|
|
98
|
+
total_repairs = sum(v.repair() for v in validators)
|
|
99
|
+
if total_repairs:
|
|
100
|
+
print(f"Auto-repaired {total_repairs} issue(s)")
|
|
101
|
+
|
|
102
|
+
success = all(v.validate() for v in validators)
|
|
103
|
+
|
|
104
|
+
if success:
|
|
105
|
+
print("All validations PASSED!")
|
|
106
|
+
|
|
107
|
+
sys.exit(0 if success else 1)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
if __name__ == "__main__":
|
|
111
|
+
main()
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Validation modules for Word document processing.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from .base import BaseSchemaValidator
|
|
6
|
+
from .docx import DOCXSchemaValidator
|
|
7
|
+
from .pptx import PPTXSchemaValidator
|
|
8
|
+
from .redlining import RedliningValidator
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"BaseSchemaValidator",
|
|
12
|
+
"DOCXSchemaValidator",
|
|
13
|
+
"PPTXSchemaValidator",
|
|
14
|
+
"RedliningValidator",
|
|
15
|
+
]
|