@nguyenphp/antigravity-marketing 1.0.18 → 1.0.20
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/README.md +130 -78
- package/package.json +4 -3
- package/templates/.agent/skills/marketing-report-expert/SKILL.md +70 -0
- package/templates/.agent/skills/minimax-docx/LICENSE +21 -0
- package/templates/.agent/skills/minimax-docx/SKILL.md +274 -0
- package/templates/.agent/skills/minimax-docx/assets/styles/academic_styles.xml +250 -0
- package/templates/.agent/skills/minimax-docx/assets/styles/corporate_styles.xml +284 -0
- package/templates/.agent/skills/minimax-docx/assets/styles/default_styles.xml +449 -0
- package/templates/.agent/skills/minimax-docx/assets/xsd/aesthetic-rules.xsd +470 -0
- package/templates/.agent/skills/minimax-docx/assets/xsd/business-rules.xsd +130 -0
- package/templates/.agent/skills/minimax-docx/assets/xsd/common-types.xsd +159 -0
- package/templates/.agent/skills/minimax-docx/assets/xsd/wml-subset.xsd +589 -0
- package/templates/.agent/skills/minimax-docx/references/cjk_typography.md +357 -0
- package/templates/.agent/skills/minimax-docx/references/cjk_university_template_guide.md +184 -0
- package/templates/.agent/skills/minimax-docx/references/comments_guide.md +191 -0
- package/templates/.agent/skills/minimax-docx/references/design_good_bad_examples.md +829 -0
- package/templates/.agent/skills/minimax-docx/references/design_principles.md +819 -0
- package/templates/.agent/skills/minimax-docx/references/openxml_element_order.md +308 -0
- package/templates/.agent/skills/minimax-docx/references/openxml_encyclopedia_part1.md +4061 -0
- package/templates/.agent/skills/minimax-docx/references/openxml_encyclopedia_part2.md +2820 -0
- package/templates/.agent/skills/minimax-docx/references/openxml_encyclopedia_part3.md +3381 -0
- package/templates/.agent/skills/minimax-docx/references/openxml_namespaces.md +82 -0
- package/templates/.agent/skills/minimax-docx/references/openxml_units.md +72 -0
- package/templates/.agent/skills/minimax-docx/references/scenario_a_create.md +284 -0
- package/templates/.agent/skills/minimax-docx/references/scenario_b_edit_content.md +295 -0
- package/templates/.agent/skills/minimax-docx/references/scenario_c_apply_template.md +456 -0
- package/templates/.agent/skills/minimax-docx/references/track_changes_guide.md +200 -0
- package/templates/.agent/skills/minimax-docx/references/troubleshooting.md +506 -0
- package/templates/.agent/skills/minimax-docx/references/typography_guide.md +294 -0
- package/templates/.agent/skills/minimax-docx/references/xsd_validation_guide.md +158 -0
- package/templates/.agent/skills/minimax-docx/scripts/doc_to_docx.sh +40 -0
- package/templates/.agent/skills/minimax-docx/scripts/docx_preview.sh +37 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Cli/MiniMaxAIDocx.Cli.csproj +19 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Cli/Program.cs +18 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/AnalyzeCommand.cs +147 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/ApplyTemplateCommand.cs +322 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/CreateCommand.cs +324 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/DiffCommand.cs +155 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/EditContentCommand.cs +487 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/FixOrderCommand.cs +108 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/MergeRunsCommand.cs +122 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/ValidateCommand.cs +107 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/MiniMaxAIDocx.Core.csproj +15 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/CommentSynchronizer.cs +169 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/ElementOrder.cs +80 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/NamespaceConstants.cs +42 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/RunMerger.cs +81 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/StyleAnalyzer.cs +81 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/TrackChangesHelper.cs +99 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/UnitConverter.cs +23 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples.cs +1832 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch1.cs +910 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch2.cs +999 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch3.cs +1048 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch4.cs +1038 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/CharacterFormattingSamples.cs +1020 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/DocumentCreationSamples.cs +1121 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/FieldAndTocSamples.cs +624 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/FootnoteAndCommentSamples.cs +675 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/HeaderFooterSamples.cs +838 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/ImageSamples.cs +917 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/ListAndNumberingSamples.cs +826 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/ParagraphFormattingSamples.cs +1199 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/StyleSystemSamples.cs +1487 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/TableSamples.cs +1163 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/TrackChangesSamples.cs +595 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Typography/CjkHelper.cs +39 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Typography/FontDefaults.cs +24 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Typography/PageSizes.cs +20 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/BusinessRuleValidator.cs +224 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/GateCheckValidator.cs +148 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/ValidationResult.cs +23 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/XsdValidator.cs +69 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.slnx +4 -0
- package/templates/.agent/skills/minimax-docx/scripts/env_check.sh +196 -0
- package/templates/.agent/skills/minimax-docx/scripts/setup.ps1 +274 -0
- package/templates/.agent/skills/minimax-docx/scripts/setup.sh +504 -0
- package/templates/.agent/skills/minimax-multimodal-toolkit/SKILL.md +359 -0
- package/templates/.agent/skills/minimax-pdf/README.md +222 -0
- package/templates/.agent/skills/minimax-pdf/SKILL.md +201 -0
- package/templates/.agent/skills/minimax-pdf/design/design.md +381 -0
- package/templates/.agent/skills/minimax-pdf/scripts/cover.py +1579 -0
- package/templates/.agent/skills/minimax-pdf/scripts/fill_inspect.py +200 -0
- package/templates/.agent/skills/minimax-pdf/scripts/fill_write.py +242 -0
- package/templates/.agent/skills/minimax-pdf/scripts/make.sh +491 -0
- package/templates/.agent/skills/minimax-pdf/scripts/merge.py +112 -0
- package/templates/.agent/skills/minimax-pdf/scripts/palette.py +559 -0
- package/templates/.agent/skills/minimax-pdf/scripts/reformat_parse.py +374 -0
- package/templates/.agent/skills/minimax-pdf/scripts/render_body.py +1055 -0
- package/templates/.agent/skills/minimax-pdf/scripts/render_cover.cjs +111 -0
- package/templates/.agent/skills/minimax-xlsx/SKILL.md +138 -0
- package/templates/.agent/skills/minimax-xlsx/references/create.md +691 -0
- package/templates/.agent/skills/minimax-xlsx/references/edit.md +684 -0
- package/templates/.agent/skills/minimax-xlsx/references/fix.md +37 -0
- package/templates/.agent/skills/minimax-xlsx/references/format.md +768 -0
- package/templates/.agent/skills/minimax-xlsx/references/ooxml-cheatsheet.md +231 -0
- package/templates/.agent/skills/minimax-xlsx/references/read-analyze.md +97 -0
- package/templates/.agent/skills/minimax-xlsx/references/validate.md +772 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/formula_check.py +422 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/libreoffice_recalc.py +248 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/shared_strings_builder.py +163 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/style_audit.py +575 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_add_column.py +395 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_insert_row.py +274 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_pack.py +87 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_reader.py +362 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_shift_rows.py +396 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_unpack.py +130 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/[Content_Types].xml +9 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/_rels/.rels +6 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/_rels/workbook.xml.rels +19 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/sharedStrings.xml +33 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/styles.xml +160 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/workbook.xml +30 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/worksheets/sheet1.xml +70 -0
- package/templates/.agent/skills/pptx-generator/SKILL.md +249 -0
- package/templates/.agent/skills/pptx-generator/references/design-system.md +392 -0
- package/templates/.agent/skills/pptx-generator/references/editing.md +162 -0
- package/templates/.agent/skills/pptx-generator/references/pitfalls.md +112 -0
- package/templates/.agent/skills/pptx-generator/references/pptxgenjs.md +420 -0
- package/templates/.agent/skills/pptx-generator/references/slide-types.md +413 -0
- package/templates/.agent/skills/tutorial-video-expert/SKILL.md +88 -0
- package/templates/.agent/skills/ui-ux-pro-max/SKILL.md +170 -585
- package/templates/.agent/skills/vision-analysis/SKILL.md +174 -0
- package/templates/.agent/workflows/analyze.md +3 -0
- package/templates/.agent/workflows/brand-report.md +44 -0
- package/templates/.agent/workflows/report.md +49 -0
- package/templates/.agent/agents/backend-specialist.md +0 -263
- package/templates/.agent/agents/database-architect.md +0 -226
- package/templates/.agent/agents/debugger.md +0 -225
- package/templates/.agent/agents/devops-engineer.md +0 -242
- package/templates/.agent/agents/frontend-specialist.md +0 -527
- package/templates/.agent/agents/game-developer.md +0 -162
- package/templates/.agent/agents/mobile-developer.md +0 -377
- package/templates/.agent/agents/penetration-tester.md +0 -188
- package/templates/.agent/agents/security-auditor.md +0 -170
- package/templates/.agent/agents/test-engineer.md +0 -158
- package/templates/.agent/skills/api-patterns/SKILL.md +0 -81
- package/templates/.agent/skills/api-patterns/api-style.md +0 -42
- package/templates/.agent/skills/api-patterns/auth.md +0 -24
- package/templates/.agent/skills/api-patterns/documentation.md +0 -26
- package/templates/.agent/skills/api-patterns/graphql.md +0 -41
- package/templates/.agent/skills/api-patterns/rate-limiting.md +0 -31
- package/templates/.agent/skills/api-patterns/response.md +0 -37
- package/templates/.agent/skills/api-patterns/rest.md +0 -40
- package/templates/.agent/skills/api-patterns/scripts/api_validator.py +0 -211
- package/templates/.agent/skills/api-patterns/security-testing.md +0 -122
- package/templates/.agent/skills/api-patterns/trpc.md +0 -41
- package/templates/.agent/skills/api-patterns/versioning.md +0 -22
- package/templates/.agent/skills/app-builder/SKILL.md +0 -75
- package/templates/.agent/skills/app-builder/agent-coordination.md +0 -71
- package/templates/.agent/skills/app-builder/feature-building.md +0 -53
- package/templates/.agent/skills/app-builder/project-detection.md +0 -34
- package/templates/.agent/skills/app-builder/scaffolding.md +0 -118
- package/templates/.agent/skills/app-builder/tech-stack.md +0 -40
- package/templates/.agent/skills/app-builder/templates/SKILL.md +0 -39
- package/templates/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +0 -76
- package/templates/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +0 -92
- package/templates/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +0 -88
- package/templates/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +0 -88
- package/templates/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +0 -83
- package/templates/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +0 -90
- package/templates/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +0 -90
- package/templates/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +0 -82
- package/templates/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +0 -100
- package/templates/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +0 -106
- package/templates/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +0 -101
- package/templates/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +0 -83
- package/templates/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +0 -93
- package/templates/.agent/skills/architecture/SKILL.md +0 -55
- package/templates/.agent/skills/architecture/context-discovery.md +0 -43
- package/templates/.agent/skills/architecture/examples.md +0 -94
- package/templates/.agent/skills/architecture/pattern-selection.md +0 -68
- package/templates/.agent/skills/architecture/patterns-reference.md +0 -50
- package/templates/.agent/skills/architecture/trade-off-analysis.md +0 -77
- package/templates/.agent/skills/bash-linux/SKILL.md +0 -199
- package/templates/.agent/skills/behavioral-modes/SKILL.md +0 -242
- package/templates/.agent/skills/clean-code/SKILL.md +0 -201
- package/templates/.agent/skills/code-review-checklist/SKILL.md +0 -109
- package/templates/.agent/skills/database-design/SKILL.md +0 -52
- package/templates/.agent/skills/database-design/database-selection.md +0 -43
- package/templates/.agent/skills/database-design/indexing.md +0 -39
- package/templates/.agent/skills/database-design/migrations.md +0 -48
- package/templates/.agent/skills/database-design/optimization.md +0 -36
- package/templates/.agent/skills/database-design/orm-selection.md +0 -30
- package/templates/.agent/skills/database-design/schema-design.md +0 -56
- package/templates/.agent/skills/database-design/scripts/schema_validator.py +0 -172
- package/templates/.agent/skills/deployment-procedures/SKILL.md +0 -241
- package/templates/.agent/skills/docker-expert/SKILL.md +0 -409
- package/templates/.agent/skills/game-development/2d-games/SKILL.md +0 -119
- package/templates/.agent/skills/game-development/3d-games/SKILL.md +0 -135
- package/templates/.agent/skills/game-development/SKILL.md +0 -167
- package/templates/.agent/skills/game-development/game-art/SKILL.md +0 -185
- package/templates/.agent/skills/game-development/game-audio/SKILL.md +0 -190
- package/templates/.agent/skills/game-development/game-design/SKILL.md +0 -129
- package/templates/.agent/skills/game-development/mobile-games/SKILL.md +0 -108
- package/templates/.agent/skills/game-development/multiplayer/SKILL.md +0 -132
- package/templates/.agent/skills/game-development/pc-games/SKILL.md +0 -144
- package/templates/.agent/skills/game-development/vr-ar/SKILL.md +0 -123
- package/templates/.agent/skills/game-development/web-games/SKILL.md +0 -150
- package/templates/.agent/skills/lint-and-validate/SKILL.md +0 -45
- package/templates/.agent/skills/lint-and-validate/scripts/lint_runner.py +0 -172
- package/templates/.agent/skills/lint-and-validate/scripts/type_coverage.py +0 -173
- package/templates/.agent/skills/mcp-builder/SKILL.md +0 -176
- package/templates/.agent/skills/nestjs-expert/SKILL.md +0 -552
- package/templates/.agent/skills/nextjs-best-practices/SKILL.md +0 -203
- package/templates/.agent/skills/nodejs-best-practices/SKILL.md +0 -333
- package/templates/.agent/skills/parallel-agents/SKILL.md +0 -175
- package/templates/.agent/skills/performance-profiling/SKILL.md +0 -143
- package/templates/.agent/skills/performance-profiling/scripts/lighthouse_audit.py +0 -76
- package/templates/.agent/skills/powershell-windows/SKILL.md +0 -167
- package/templates/.agent/skills/prisma-expert/SKILL.md +0 -355
- package/templates/.agent/skills/python-patterns/SKILL.md +0 -441
- package/templates/.agent/skills/react-patterns/SKILL.md +0 -198
- package/templates/.agent/skills/red-team-tactics/SKILL.md +0 -199
- package/templates/.agent/skills/server-management/SKILL.md +0 -161
- package/templates/.agent/skills/systematic-debugging/SKILL.md +0 -109
- package/templates/.agent/skills/tdd-workflow/SKILL.md +0 -149
- package/templates/.agent/skills/testing-patterns/SKILL.md +0 -178
- package/templates/.agent/skills/testing-patterns/scripts/test_runner.py +0 -219
- package/templates/.agent/skills/typescript-expert/SKILL.md +0 -429
- package/templates/.agent/skills/vue-expert/SKILL.md +0 -374
- package/templates/.agent/skills/vulnerability-scanner/SKILL.md +0 -276
- package/templates/.agent/skills/vulnerability-scanner/checklists.md +0 -121
- package/templates/.agent/skills/vulnerability-scanner/scripts/security_scan.py +0 -458
- package/templates/.agent/skills/webapp-testing/SKILL.md +0 -187
- package/templates/.agent/skills/webapp-testing/scripts/playwright_runner.py +0 -173
- package/templates/.agent/workflows/debug.md +0 -103
- package/templates/.agent/workflows/deploy.md +0 -176
- package/templates/.agent/workflows/enhance.md +0 -63
- package/templates/.agent/workflows/test.md +0 -144
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
using System.CommandLine;
|
|
2
|
+
using DocumentFormat.OpenXml;
|
|
3
|
+
using DocumentFormat.OpenXml.Packaging;
|
|
4
|
+
using DocumentFormat.OpenXml.Wordprocessing;
|
|
5
|
+
using MiniMaxAIDocx.Core.OpenXml;
|
|
6
|
+
using MiniMaxAIDocx.Core.Typography;
|
|
7
|
+
|
|
8
|
+
namespace MiniMaxAIDocx.Core.Commands;
|
|
9
|
+
|
|
10
|
+
/// <summary>
|
|
11
|
+
/// Scenario A: Create a new DOCX document from scratch with proper styles, sections,
|
|
12
|
+
/// headers/footers, and typography defaults.
|
|
13
|
+
/// </summary>
|
|
14
|
+
public static class CreateCommand
|
|
15
|
+
{
|
|
16
|
+
public static Command Create()
|
|
17
|
+
{
|
|
18
|
+
var outputOption = new Option<string>("--output") { Description = "Output DOCX file path", Required = true };
|
|
19
|
+
var typeOption = new Option<string>("--type") { Description = "Document type: report, letter, memo, academic" };
|
|
20
|
+
typeOption.DefaultValueFactory = _ => "report";
|
|
21
|
+
var titleOption = new Option<string>("--title") { Description = "Document title" };
|
|
22
|
+
var authorOption = new Option<string>("--author") { Description = "Document author" };
|
|
23
|
+
var pageSizeOption = new Option<string>("--page-size") { Description = "Page size: letter, a4, legal, a3" };
|
|
24
|
+
pageSizeOption.DefaultValueFactory = _ => "letter";
|
|
25
|
+
var marginsOption = new Option<string>("--margins") { Description = "Margin preset: standard, narrow, wide" };
|
|
26
|
+
marginsOption.DefaultValueFactory = _ => "standard";
|
|
27
|
+
var headerTextOption = new Option<string>("--header") { Description = "Header text" };
|
|
28
|
+
var footerTextOption = new Option<string>("--footer") { Description = "Footer text" };
|
|
29
|
+
var pageNumbersOption = new Option<bool>("--page-numbers") { Description = "Add page numbers in footer" };
|
|
30
|
+
var tocOption = new Option<bool>("--toc") { Description = "Insert table of contents placeholder" };
|
|
31
|
+
var contentJsonOption = new Option<string>("--content-json") { Description = "Path to JSON file describing document content" };
|
|
32
|
+
|
|
33
|
+
var cmd = new Command("create", "Create a new DOCX document from scratch")
|
|
34
|
+
{
|
|
35
|
+
outputOption, typeOption, titleOption, authorOption, pageSizeOption,
|
|
36
|
+
marginsOption, headerTextOption, footerTextOption, pageNumbersOption,
|
|
37
|
+
tocOption, contentJsonOption
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
cmd.SetAction((parseResult) =>
|
|
41
|
+
{
|
|
42
|
+
var output = parseResult.GetValue(outputOption)!;
|
|
43
|
+
var docType = parseResult.GetValue(typeOption) ?? "report";
|
|
44
|
+
var title = parseResult.GetValue(titleOption);
|
|
45
|
+
var author = parseResult.GetValue(authorOption);
|
|
46
|
+
var pageSizeName = parseResult.GetValue(pageSizeOption) ?? "letter";
|
|
47
|
+
var marginsName = parseResult.GetValue(marginsOption) ?? "standard";
|
|
48
|
+
var headerText = parseResult.GetValue(headerTextOption);
|
|
49
|
+
var footerText = parseResult.GetValue(footerTextOption);
|
|
50
|
+
var pageNumbers = parseResult.GetValue(pageNumbersOption);
|
|
51
|
+
var tocPlaceholder = parseResult.GetValue(tocOption);
|
|
52
|
+
var contentJson = parseResult.GetValue(contentJsonOption);
|
|
53
|
+
|
|
54
|
+
var fontConfig = GetFontConfig(docType);
|
|
55
|
+
var pageSize = GetPageSizeConfig(pageSizeName);
|
|
56
|
+
var margins = GetMargins(marginsName);
|
|
57
|
+
|
|
58
|
+
using var doc = WordprocessingDocument.Create(output, WordprocessingDocumentType.Document);
|
|
59
|
+
var mainPart = doc.AddMainDocumentPart();
|
|
60
|
+
mainPart.Document = new Document(new Body());
|
|
61
|
+
var body = mainPart.Document.Body!;
|
|
62
|
+
|
|
63
|
+
// Add styles part with defaults
|
|
64
|
+
AddDefaultStyles(mainPart, fontConfig);
|
|
65
|
+
|
|
66
|
+
// Add section properties (page size, margins)
|
|
67
|
+
var sectPr = new SectionProperties();
|
|
68
|
+
sectPr.Append(new DocumentFormat.OpenXml.Wordprocessing.PageSize
|
|
69
|
+
{
|
|
70
|
+
Width = (UInt32Value)(uint)pageSize.WidthDxa,
|
|
71
|
+
Height = (UInt32Value)(uint)pageSize.HeightDxa
|
|
72
|
+
});
|
|
73
|
+
sectPr.Append(new PageMargin
|
|
74
|
+
{
|
|
75
|
+
Top = margins.TopDxa,
|
|
76
|
+
Bottom = margins.BottomDxa,
|
|
77
|
+
Left = (UInt32Value)(uint)margins.LeftDxa,
|
|
78
|
+
Right = (UInt32Value)(uint)margins.RightDxa
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Add header if requested
|
|
82
|
+
if (!string.IsNullOrEmpty(headerText))
|
|
83
|
+
{
|
|
84
|
+
var headerPart = mainPart.AddNewPart<HeaderPart>();
|
|
85
|
+
headerPart.Header = new Header(
|
|
86
|
+
new Paragraph(new Run(new Text(headerText))));
|
|
87
|
+
var headerRefId = mainPart.GetIdOfPart(headerPart);
|
|
88
|
+
sectPr.Append(new HeaderReference
|
|
89
|
+
{
|
|
90
|
+
Type = HeaderFooterValues.Default,
|
|
91
|
+
Id = headerRefId
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Add footer if requested
|
|
96
|
+
if (!string.IsNullOrEmpty(footerText) || pageNumbers)
|
|
97
|
+
{
|
|
98
|
+
var footerPart = mainPart.AddNewPart<FooterPart>();
|
|
99
|
+
var footerParagraph = new Paragraph();
|
|
100
|
+
|
|
101
|
+
if (!string.IsNullOrEmpty(footerText))
|
|
102
|
+
{
|
|
103
|
+
footerParagraph.Append(new Run(new Text(footerText)));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (pageNumbers)
|
|
107
|
+
{
|
|
108
|
+
if (!string.IsNullOrEmpty(footerText))
|
|
109
|
+
footerParagraph.Append(new Run(new Text(" — ") { Space = SpaceProcessingModeValues.Preserve }));
|
|
110
|
+
|
|
111
|
+
footerParagraph.Append(new Run(
|
|
112
|
+
new FieldChar { FieldCharType = FieldCharValues.Begin }));
|
|
113
|
+
footerParagraph.Append(new Run(
|
|
114
|
+
new FieldCode(" PAGE ") { Space = SpaceProcessingModeValues.Preserve }));
|
|
115
|
+
footerParagraph.Append(new Run(
|
|
116
|
+
new FieldChar { FieldCharType = FieldCharValues.End }));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
footerPart.Footer = new Footer(footerParagraph);
|
|
120
|
+
var footerRefId = mainPart.GetIdOfPart(footerPart);
|
|
121
|
+
sectPr.Append(new FooterReference
|
|
122
|
+
{
|
|
123
|
+
Type = HeaderFooterValues.Default,
|
|
124
|
+
Id = footerRefId
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Title
|
|
129
|
+
if (!string.IsNullOrEmpty(title))
|
|
130
|
+
{
|
|
131
|
+
var titlePara = new Paragraph(
|
|
132
|
+
new ParagraphProperties(new ParagraphStyleId { Val = "Title" }),
|
|
133
|
+
new Run(new Text(title)));
|
|
134
|
+
body.Append(titlePara);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Author subtitle
|
|
138
|
+
if (!string.IsNullOrEmpty(author))
|
|
139
|
+
{
|
|
140
|
+
var authorPara = new Paragraph(
|
|
141
|
+
new ParagraphProperties(new ParagraphStyleId { Val = "Subtitle" }),
|
|
142
|
+
new Run(new Text(author)));
|
|
143
|
+
body.Append(authorPara);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// TOC placeholder
|
|
147
|
+
if (tocPlaceholder)
|
|
148
|
+
{
|
|
149
|
+
body.Append(new Paragraph(
|
|
150
|
+
new ParagraphProperties(new ParagraphStyleId { Val = "TOCHeading" }),
|
|
151
|
+
new Run(new Text("Table of Contents"))));
|
|
152
|
+
|
|
153
|
+
// Insert TOC field
|
|
154
|
+
var tocPara = new Paragraph();
|
|
155
|
+
tocPara.Append(new Run(new FieldChar { FieldCharType = FieldCharValues.Begin }));
|
|
156
|
+
tocPara.Append(new Run(new FieldCode(" TOC \\o \"1-3\" \\h \\z \\u ") { Space = SpaceProcessingModeValues.Preserve }));
|
|
157
|
+
tocPara.Append(new Run(new FieldChar { FieldCharType = FieldCharValues.Separate }));
|
|
158
|
+
tocPara.Append(new Run(new Text("Update this field to generate table of contents.")));
|
|
159
|
+
tocPara.Append(new Run(new FieldChar { FieldCharType = FieldCharValues.End }));
|
|
160
|
+
body.Append(tocPara);
|
|
161
|
+
|
|
162
|
+
// Page break after TOC
|
|
163
|
+
body.Append(new Paragraph(new Run(new Break { Type = BreakValues.Page })));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Content from JSON (if provided)
|
|
167
|
+
if (!string.IsNullOrEmpty(contentJson) && File.Exists(contentJson))
|
|
168
|
+
{
|
|
169
|
+
var jsonContent = File.ReadAllText(contentJson);
|
|
170
|
+
AddContentFromJson(body, jsonContent, fontConfig);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Ensure body has at least one paragraph
|
|
174
|
+
if (!body.Elements<Paragraph>().Any())
|
|
175
|
+
{
|
|
176
|
+
body.Append(new Paragraph());
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// sectPr must be the last child of body
|
|
180
|
+
body.Append(sectPr);
|
|
181
|
+
|
|
182
|
+
mainPart.Document.Save();
|
|
183
|
+
Console.WriteLine($"Created {docType} document: {output}");
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
return cmd;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private static FontConfig GetFontConfig(string docType) => docType.ToLowerInvariant() switch
|
|
190
|
+
{
|
|
191
|
+
"letter" => FontDefaults.Letter,
|
|
192
|
+
"memo" => FontDefaults.Memo,
|
|
193
|
+
"academic" => FontDefaults.Academic,
|
|
194
|
+
_ => FontDefaults.Report,
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
private static Typography.PageSize GetPageSizeConfig(string name) => name.ToLowerInvariant() switch
|
|
198
|
+
{
|
|
199
|
+
"a4" => PageSizes.A4,
|
|
200
|
+
"legal" => PageSizes.Legal,
|
|
201
|
+
"a3" => PageSizes.A3,
|
|
202
|
+
_ => PageSizes.Letter,
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
private static MarginConfig GetMargins(string name) => name.ToLowerInvariant() switch
|
|
206
|
+
{
|
|
207
|
+
"narrow" => PageSizes.NarrowMargins,
|
|
208
|
+
"wide" => PageSizes.WideMargins,
|
|
209
|
+
_ => PageSizes.StandardMargins,
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
private static void AddDefaultStyles(MainDocumentPart mainPart, FontConfig fontConfig)
|
|
213
|
+
{
|
|
214
|
+
var stylesPart = mainPart.AddNewPart<StyleDefinitionsPart>();
|
|
215
|
+
var styles = new Styles();
|
|
216
|
+
|
|
217
|
+
// Default run properties
|
|
218
|
+
var defaultRPr = new StyleRunProperties(
|
|
219
|
+
new RunFonts { Ascii = fontConfig.BodyFont, HighAnsi = fontConfig.BodyFont },
|
|
220
|
+
new FontSize { Val = UnitConverter.FontSizeToSz(fontConfig.BodySize) },
|
|
221
|
+
new FontSizeComplexScript { Val = UnitConverter.FontSizeToSz(fontConfig.BodySize) });
|
|
222
|
+
|
|
223
|
+
// Normal style
|
|
224
|
+
styles.Append(new Style(
|
|
225
|
+
new StyleName { Val = "Normal" },
|
|
226
|
+
new PrimaryStyle(),
|
|
227
|
+
defaultRPr)
|
|
228
|
+
{ Type = StyleValues.Paragraph, StyleId = "Normal", Default = true });
|
|
229
|
+
|
|
230
|
+
// Heading styles 1-6
|
|
231
|
+
double[] headingSizes = [fontConfig.Heading1Size, fontConfig.Heading2Size, fontConfig.Heading3Size,
|
|
232
|
+
fontConfig.Heading4Size, fontConfig.Heading5Size, fontConfig.Heading6Size];
|
|
233
|
+
for (int i = 0; i < 6; i++)
|
|
234
|
+
{
|
|
235
|
+
var level = i + 1;
|
|
236
|
+
var headingStyle = new Style(
|
|
237
|
+
new StyleName { Val = $"heading {level}" },
|
|
238
|
+
new BasedOn { Val = "Normal" },
|
|
239
|
+
new NextParagraphStyle { Val = "Normal" },
|
|
240
|
+
new PrimaryStyle(),
|
|
241
|
+
new StyleParagraphProperties(
|
|
242
|
+
new KeepNext(),
|
|
243
|
+
new KeepLines(),
|
|
244
|
+
new SpacingBetweenLines { Before = "240", After = "120" },
|
|
245
|
+
new OutlineLevel { Val = i }),
|
|
246
|
+
new StyleRunProperties(
|
|
247
|
+
new RunFonts { Ascii = fontConfig.HeadingFont, HighAnsi = fontConfig.HeadingFont },
|
|
248
|
+
new FontSize { Val = UnitConverter.FontSizeToSz(headingSizes[i]) },
|
|
249
|
+
new FontSizeComplexScript { Val = UnitConverter.FontSizeToSz(headingSizes[i]) },
|
|
250
|
+
new Bold()))
|
|
251
|
+
{ Type = StyleValues.Paragraph, StyleId = $"Heading{level}" };
|
|
252
|
+
styles.Append(headingStyle);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Title style
|
|
256
|
+
styles.Append(new Style(
|
|
257
|
+
new StyleName { Val = "Title" },
|
|
258
|
+
new BasedOn { Val = "Normal" },
|
|
259
|
+
new NextParagraphStyle { Val = "Normal" },
|
|
260
|
+
new PrimaryStyle(),
|
|
261
|
+
new StyleParagraphProperties(
|
|
262
|
+
new Justification { Val = JustificationValues.Center },
|
|
263
|
+
new SpacingBetweenLines { After = "300" }),
|
|
264
|
+
new StyleRunProperties(
|
|
265
|
+
new RunFonts { Ascii = fontConfig.HeadingFont, HighAnsi = fontConfig.HeadingFont },
|
|
266
|
+
new FontSize { Val = UnitConverter.FontSizeToSz(fontConfig.Heading1Size + 6) },
|
|
267
|
+
new FontSizeComplexScript { Val = UnitConverter.FontSizeToSz(fontConfig.Heading1Size + 6) }))
|
|
268
|
+
{ Type = StyleValues.Paragraph, StyleId = "Title" });
|
|
269
|
+
|
|
270
|
+
// Subtitle style
|
|
271
|
+
styles.Append(new Style(
|
|
272
|
+
new StyleName { Val = "Subtitle" },
|
|
273
|
+
new BasedOn { Val = "Normal" },
|
|
274
|
+
new NextParagraphStyle { Val = "Normal" },
|
|
275
|
+
new StyleParagraphProperties(
|
|
276
|
+
new Justification { Val = JustificationValues.Center },
|
|
277
|
+
new SpacingBetweenLines { After = "200" }),
|
|
278
|
+
new StyleRunProperties(
|
|
279
|
+
new Color { Val = "5A5A5A" },
|
|
280
|
+
new FontSize { Val = UnitConverter.FontSizeToSz(fontConfig.BodySize + 2) }))
|
|
281
|
+
{ Type = StyleValues.Paragraph, StyleId = "Subtitle" });
|
|
282
|
+
|
|
283
|
+
stylesPart.Styles = styles;
|
|
284
|
+
stylesPart.Styles.Save();
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
private static void AddContentFromJson(Body body, string jsonContent, FontConfig fontConfig)
|
|
288
|
+
{
|
|
289
|
+
// Simple JSON content format: array of {type, text, level?}
|
|
290
|
+
// e.g. [{"type":"heading","text":"Introduction","level":1},{"type":"paragraph","text":"..."}]
|
|
291
|
+
try
|
|
292
|
+
{
|
|
293
|
+
using var jsonDoc = System.Text.Json.JsonDocument.Parse(jsonContent);
|
|
294
|
+
foreach (var element in jsonDoc.RootElement.EnumerateArray())
|
|
295
|
+
{
|
|
296
|
+
var type = element.GetProperty("type").GetString() ?? "paragraph";
|
|
297
|
+
var text = element.GetProperty("text").GetString() ?? "";
|
|
298
|
+
|
|
299
|
+
switch (type)
|
|
300
|
+
{
|
|
301
|
+
case "heading":
|
|
302
|
+
var level = element.TryGetProperty("level", out var lvl) ? lvl.GetInt32() : 1;
|
|
303
|
+
level = Math.Clamp(level, 1, 6);
|
|
304
|
+
body.Append(new Paragraph(
|
|
305
|
+
new ParagraphProperties(new ParagraphStyleId { Val = $"Heading{level}" }),
|
|
306
|
+
new Run(new Text(text))));
|
|
307
|
+
break;
|
|
308
|
+
|
|
309
|
+
case "paragraph":
|
|
310
|
+
body.Append(new Paragraph(new Run(new Text(text))));
|
|
311
|
+
break;
|
|
312
|
+
|
|
313
|
+
case "pagebreak":
|
|
314
|
+
body.Append(new Paragraph(new Run(new Break { Type = BreakValues.Page })));
|
|
315
|
+
break;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
catch (System.Text.Json.JsonException ex)
|
|
320
|
+
{
|
|
321
|
+
Console.Error.WriteLine($"Warning: could not parse content JSON: {ex.Message}");
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
using System.CommandLine;
|
|
2
|
+
using System.IO.Compression;
|
|
3
|
+
using System.Text.Json;
|
|
4
|
+
using System.Xml.Linq;
|
|
5
|
+
|
|
6
|
+
namespace MiniMaxAIDocx.Core.Commands;
|
|
7
|
+
|
|
8
|
+
public static class DiffCommand
|
|
9
|
+
{
|
|
10
|
+
private static readonly XNamespace W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
11
|
+
|
|
12
|
+
public static Command Create()
|
|
13
|
+
{
|
|
14
|
+
var beforeOption = new Option<string>("--before") { Description = "Original DOCX", Required = true };
|
|
15
|
+
var afterOption = new Option<string>("--after") { Description = "Modified DOCX", Required = true };
|
|
16
|
+
var jsonOption = new Option<bool>("--json") { Description = "Output as JSON" };
|
|
17
|
+
|
|
18
|
+
var cmd = new Command("diff", "Compare two DOCX files")
|
|
19
|
+
{
|
|
20
|
+
beforeOption, afterOption, jsonOption
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
cmd.SetAction((parseResult) =>
|
|
24
|
+
{
|
|
25
|
+
var before = parseResult.GetValue(beforeOption)!;
|
|
26
|
+
var after = parseResult.GetValue(afterOption)!;
|
|
27
|
+
var asJson = parseResult.GetValue(jsonOption);
|
|
28
|
+
|
|
29
|
+
if (!File.Exists(before)) { Console.Error.WriteLine($"File not found: {before}"); return; }
|
|
30
|
+
if (!File.Exists(after)) { Console.Error.WriteLine($"File not found: {after}"); return; }
|
|
31
|
+
|
|
32
|
+
var beforeParas = ExtractParagraphs(before);
|
|
33
|
+
var afterParas = ExtractParagraphs(after);
|
|
34
|
+
var beforeStyles = ExtractStyleIds(before);
|
|
35
|
+
var afterStyles = ExtractStyleIds(after);
|
|
36
|
+
var beforeStructure = ExtractStructure(before);
|
|
37
|
+
var afterStructure = ExtractStructure(after);
|
|
38
|
+
|
|
39
|
+
// Text diff
|
|
40
|
+
var textChanges = new List<object>();
|
|
41
|
+
int maxLen = Math.Max(beforeParas.Count, afterParas.Count);
|
|
42
|
+
int changedParas = 0;
|
|
43
|
+
for (int i = 0; i < maxLen; i++)
|
|
44
|
+
{
|
|
45
|
+
var bText = i < beforeParas.Count ? beforeParas[i] : null;
|
|
46
|
+
var aText = i < afterParas.Count ? afterParas[i] : null;
|
|
47
|
+
|
|
48
|
+
if (bText != aText)
|
|
49
|
+
{
|
|
50
|
+
changedParas++;
|
|
51
|
+
textChanges.Add(new
|
|
52
|
+
{
|
|
53
|
+
paragraph = i + 1,
|
|
54
|
+
before = bText ?? "(absent)",
|
|
55
|
+
after = aText ?? "(absent)"
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Style diff
|
|
61
|
+
var addedStyles = afterStyles.Except(beforeStyles).ToList();
|
|
62
|
+
var removedStyles = beforeStyles.Except(afterStyles).ToList();
|
|
63
|
+
|
|
64
|
+
// Structure diff
|
|
65
|
+
var structureChanges = new List<string>();
|
|
66
|
+
if (beforeStructure.Sections != afterStructure.Sections)
|
|
67
|
+
structureChanges.Add($"Sections: {beforeStructure.Sections} -> {afterStructure.Sections}");
|
|
68
|
+
if (beforeStructure.Tables != afterStructure.Tables)
|
|
69
|
+
structureChanges.Add($"Tables: {beforeStructure.Tables} -> {afterStructure.Tables}");
|
|
70
|
+
if (beforeStructure.Images != afterStructure.Images)
|
|
71
|
+
structureChanges.Add($"Images: {beforeStructure.Images} -> {afterStructure.Images}");
|
|
72
|
+
|
|
73
|
+
var result = new
|
|
74
|
+
{
|
|
75
|
+
textChanges,
|
|
76
|
+
styleChanges = new { added = addedStyles, removed = removedStyles },
|
|
77
|
+
structureChanges,
|
|
78
|
+
summary = $"{changedParas} paragraphs changed, {addedStyles.Count + removedStyles.Count} styles modified, {structureChanges.Count} structural changes"
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
if (asJson)
|
|
82
|
+
{
|
|
83
|
+
Console.WriteLine(JsonSerializer.Serialize(result, new JsonSerializerOptions { WriteIndented = true }));
|
|
84
|
+
}
|
|
85
|
+
else
|
|
86
|
+
{
|
|
87
|
+
Console.WriteLine(result.summary);
|
|
88
|
+
Console.WriteLine();
|
|
89
|
+
|
|
90
|
+
if (textChanges.Count > 0)
|
|
91
|
+
{
|
|
92
|
+
Console.WriteLine($"Text changes ({textChanges.Count}):");
|
|
93
|
+
foreach (var tc in textChanges.Take(20))
|
|
94
|
+
Console.WriteLine($" {tc}");
|
|
95
|
+
if (textChanges.Count > 20)
|
|
96
|
+
Console.WriteLine($" ... and {textChanges.Count - 20} more");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (addedStyles.Count > 0)
|
|
100
|
+
Console.WriteLine($"Added styles: {string.Join(", ", addedStyles)}");
|
|
101
|
+
if (removedStyles.Count > 0)
|
|
102
|
+
Console.WriteLine($"Removed styles: {string.Join(", ", removedStyles)}");
|
|
103
|
+
|
|
104
|
+
foreach (var sc in structureChanges)
|
|
105
|
+
Console.WriteLine($"Structure: {sc}");
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
return cmd;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
private static List<string> ExtractParagraphs(string docxPath)
|
|
113
|
+
{
|
|
114
|
+
using var zip = ZipFile.OpenRead(docxPath);
|
|
115
|
+
var entry = zip.GetEntry("word/document.xml");
|
|
116
|
+
if (entry == null) return new();
|
|
117
|
+
|
|
118
|
+
using var stream = entry.Open();
|
|
119
|
+
var doc = XDocument.Load(stream);
|
|
120
|
+
return doc.Descendants(W + "p")
|
|
121
|
+
.Select(p => string.Concat(p.Descendants(W + "t").Select(t => t.Value)))
|
|
122
|
+
.ToList();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
private static HashSet<string> ExtractStyleIds(string docxPath)
|
|
126
|
+
{
|
|
127
|
+
using var zip = ZipFile.OpenRead(docxPath);
|
|
128
|
+
var entry = zip.GetEntry("word/styles.xml");
|
|
129
|
+
if (entry == null) return new();
|
|
130
|
+
|
|
131
|
+
using var stream = entry.Open();
|
|
132
|
+
var doc = XDocument.Load(stream);
|
|
133
|
+
return doc.Descendants(W + "style")
|
|
134
|
+
.Select(s => (string?)s.Attribute(W + "styleId"))
|
|
135
|
+
.Where(id => id != null)
|
|
136
|
+
.ToHashSet()!;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
private record StructureInfo(int Sections, int Tables, int Images);
|
|
140
|
+
|
|
141
|
+
private static StructureInfo ExtractStructure(string docxPath)
|
|
142
|
+
{
|
|
143
|
+
using var zip = ZipFile.OpenRead(docxPath);
|
|
144
|
+
var entry = zip.GetEntry("word/document.xml");
|
|
145
|
+
if (entry == null) return new(0, 0, 0);
|
|
146
|
+
|
|
147
|
+
using var stream = entry.Open();
|
|
148
|
+
var doc = XDocument.Load(stream);
|
|
149
|
+
return new(
|
|
150
|
+
doc.Descendants(W + "sectPr").Count(),
|
|
151
|
+
doc.Descendants(W + "tbl").Count(),
|
|
152
|
+
doc.Descendants(W + "drawing").Count()
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
}
|