dimcode-darwin-x64 0.1.2-beta.1 → 0.1.2

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.
Files changed (148) hide show
  1. package/bin/dimcode +0 -0
  2. package/package.json +1 -1
  3. package/bin/runtime/sandbox/dim-sandbox-runner +0 -0
  4. package/bin/runtime/sandbox/manifest.json +0 -15
  5. package/bin/skills-assets/deep-investigate/SKILL.md +0 -101
  6. package/bin/skills-assets/deep-investigate/references/prompts.md +0 -75
  7. package/bin/skills-assets/deep-investigate/references/templates.md +0 -73
  8. package/bin/skills-assets/deep-investigate/references/thinking-tools.md +0 -36
  9. package/bin/skills-assets/docs-sprint/SKILL.md +0 -73
  10. package/bin/skills-assets/docs-sprint/agents/openai.yaml +0 -4
  11. package/bin/skills-assets/docs-sprint/references/contract-discipline.md +0 -30
  12. package/bin/skills-assets/docs-sprint/references/delivery-plan.md +0 -162
  13. package/bin/skills-assets/docs-sprint/references/documentation-system.md +0 -109
  14. package/bin/skills-assets/docs-sprint/references/ui-layout.md +0 -73
  15. package/bin/skills-assets/docs-sprint/references/worktree-guide.md +0 -45
  16. package/bin/skills-assets/docx/SKILL.md +0 -273
  17. package/bin/skills-assets/docx/assets/styles/academic_styles.xml +0 -250
  18. package/bin/skills-assets/docx/assets/styles/corporate_styles.xml +0 -284
  19. package/bin/skills-assets/docx/assets/styles/default_styles.xml +0 -449
  20. package/bin/skills-assets/docx/assets/xsd/aesthetic-rules.xsd +0 -470
  21. package/bin/skills-assets/docx/assets/xsd/business-rules.xsd +0 -130
  22. package/bin/skills-assets/docx/assets/xsd/common-types.xsd +0 -159
  23. package/bin/skills-assets/docx/assets/xsd/wml-subset.xsd +0 -589
  24. package/bin/skills-assets/docx/references/cjk_typography.md +0 -357
  25. package/bin/skills-assets/docx/references/cjk_university_template_guide.md +0 -184
  26. package/bin/skills-assets/docx/references/comments_guide.md +0 -191
  27. package/bin/skills-assets/docx/references/design_good_bad_examples.md +0 -829
  28. package/bin/skills-assets/docx/references/design_principles.md +0 -819
  29. package/bin/skills-assets/docx/references/openxml_element_order.md +0 -308
  30. package/bin/skills-assets/docx/references/openxml_encyclopedia_part1.md +0 -4061
  31. package/bin/skills-assets/docx/references/openxml_encyclopedia_part2.md +0 -2820
  32. package/bin/skills-assets/docx/references/openxml_encyclopedia_part3.md +0 -3381
  33. package/bin/skills-assets/docx/references/openxml_namespaces.md +0 -82
  34. package/bin/skills-assets/docx/references/openxml_units.md +0 -72
  35. package/bin/skills-assets/docx/references/scenario_a_create.md +0 -284
  36. package/bin/skills-assets/docx/references/scenario_b_edit_content.md +0 -295
  37. package/bin/skills-assets/docx/references/scenario_c_apply_template.md +0 -456
  38. package/bin/skills-assets/docx/references/track_changes_guide.md +0 -200
  39. package/bin/skills-assets/docx/references/troubleshooting.md +0 -506
  40. package/bin/skills-assets/docx/references/typography_guide.md +0 -294
  41. package/bin/skills-assets/docx/references/xsd_validation_guide.md +0 -158
  42. package/bin/skills-assets/docx/scripts/doc_to_docx.sh +0 -40
  43. package/bin/skills-assets/docx/scripts/docx_preview.sh +0 -37
  44. package/bin/skills-assets/docx/scripts/dotnet/Docx.Cli/Docx.Cli.csproj +0 -19
  45. package/bin/skills-assets/docx/scripts/dotnet/Docx.Cli/Program.cs +0 -18
  46. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Commands/AnalyzeCommand.cs +0 -147
  47. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Commands/ApplyTemplateCommand.cs +0 -322
  48. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Commands/CreateCommand.cs +0 -324
  49. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Commands/DiffCommand.cs +0 -155
  50. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Commands/EditContentCommand.cs +0 -487
  51. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Commands/FixOrderCommand.cs +0 -108
  52. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Commands/MergeRunsCommand.cs +0 -122
  53. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Commands/ValidateCommand.cs +0 -107
  54. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Docx.Core.csproj +0 -15
  55. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/OpenXml/CommentSynchronizer.cs +0 -169
  56. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/OpenXml/ElementOrder.cs +0 -80
  57. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/OpenXml/NamespaceConstants.cs +0 -42
  58. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/OpenXml/RunMerger.cs +0 -81
  59. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/OpenXml/StyleAnalyzer.cs +0 -81
  60. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/OpenXml/TrackChangesHelper.cs +0 -99
  61. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/OpenXml/UnitConverter.cs +0 -23
  62. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/AestheticRecipeSamples.cs +0 -1832
  63. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/AestheticRecipeSamples_Batch1.cs +0 -910
  64. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/AestheticRecipeSamples_Batch2.cs +0 -999
  65. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/AestheticRecipeSamples_Batch3.cs +0 -1048
  66. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/AestheticRecipeSamples_Batch4.cs +0 -1038
  67. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/CharacterFormattingSamples.cs +0 -1020
  68. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/DocumentCreationSamples.cs +0 -1121
  69. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/FieldAndTocSamples.cs +0 -624
  70. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/FootnoteAndCommentSamples.cs +0 -675
  71. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/HeaderFooterSamples.cs +0 -838
  72. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/ImageSamples.cs +0 -917
  73. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/ListAndNumberingSamples.cs +0 -826
  74. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/ParagraphFormattingSamples.cs +0 -1199
  75. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/StyleSystemSamples.cs +0 -1487
  76. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/TableSamples.cs +0 -1163
  77. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/TrackChangesSamples.cs +0 -595
  78. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Typography/CjkHelper.cs +0 -39
  79. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Typography/FontDefaults.cs +0 -24
  80. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Typography/PageSizes.cs +0 -20
  81. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Validation/BusinessRuleValidator.cs +0 -224
  82. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Validation/GateCheckValidator.cs +0 -148
  83. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Validation/ValidationResult.cs +0 -23
  84. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Validation/XsdValidator.cs +0 -69
  85. package/bin/skills-assets/docx/scripts/dotnet/Docx.slnx +0 -4
  86. package/bin/skills-assets/docx/scripts/env_check.sh +0 -196
  87. package/bin/skills-assets/docx/scripts/setup.ps1 +0 -274
  88. package/bin/skills-assets/docx/scripts/setup.sh +0 -504
  89. package/bin/skills-assets/pdf/README.md +0 -222
  90. package/bin/skills-assets/pdf/SKILL.md +0 -191
  91. package/bin/skills-assets/pdf/design/design.md +0 -381
  92. package/bin/skills-assets/pdf/scripts/cover.py +0 -1579
  93. package/bin/skills-assets/pdf/scripts/fill_inspect.py +0 -200
  94. package/bin/skills-assets/pdf/scripts/fill_write.py +0 -242
  95. package/bin/skills-assets/pdf/scripts/make.sh +0 -491
  96. package/bin/skills-assets/pdf/scripts/merge.py +0 -112
  97. package/bin/skills-assets/pdf/scripts/palette.py +0 -521
  98. package/bin/skills-assets/pdf/scripts/reformat_parse.py +0 -374
  99. package/bin/skills-assets/pdf/scripts/render_body.py +0 -1052
  100. package/bin/skills-assets/pdf/scripts/render_cover.js +0 -111
  101. package/bin/skills-assets/pptx-generator/SKILL.md +0 -248
  102. package/bin/skills-assets/pptx-generator/references/design-system.md +0 -392
  103. package/bin/skills-assets/pptx-generator/references/editing.md +0 -162
  104. package/bin/skills-assets/pptx-generator/references/pitfalls.md +0 -112
  105. package/bin/skills-assets/pptx-generator/references/pptxgenjs.md +0 -420
  106. package/bin/skills-assets/pptx-generator/references/slide-types.md +0 -413
  107. package/bin/skills-assets/skill-creator/SKILL.md +0 -368
  108. package/bin/skills-assets/skill-creator/agents/openai.yaml +0 -5
  109. package/bin/skills-assets/skill-creator/assets/skill-creator-small.svg +0 -3
  110. package/bin/skills-assets/skill-creator/assets/skill-creator.png +0 -0
  111. package/bin/skills-assets/skill-creator/license.txt +0 -202
  112. package/bin/skills-assets/skill-creator/references/openai_yaml.md +0 -49
  113. package/bin/skills-assets/skill-creator/scripts/generate_openai_yaml.py +0 -226
  114. package/bin/skills-assets/skill-creator/scripts/init_skill.py +0 -397
  115. package/bin/skills-assets/skill-creator/scripts/quick_validate.py +0 -101
  116. package/bin/skills-assets/skill-installer/LICENSE.txt +0 -202
  117. package/bin/skills-assets/skill-installer/SKILL.md +0 -58
  118. package/bin/skills-assets/skill-installer/agents/openai.yaml +0 -5
  119. package/bin/skills-assets/skill-installer/assets/skill-installer-small.svg +0 -3
  120. package/bin/skills-assets/skill-installer/assets/skill-installer.png +0 -0
  121. package/bin/skills-assets/skill-installer/scripts/github_utils.py +0 -21
  122. package/bin/skills-assets/skill-installer/scripts/install-skill-from-github.py +0 -308
  123. package/bin/skills-assets/skill-installer/scripts/list-skills.py +0 -107
  124. package/bin/skills-assets/xlsx/SKILL.md +0 -137
  125. package/bin/skills-assets/xlsx/references/create.md +0 -691
  126. package/bin/skills-assets/xlsx/references/edit.md +0 -684
  127. package/bin/skills-assets/xlsx/references/fix.md +0 -37
  128. package/bin/skills-assets/xlsx/references/format.md +0 -768
  129. package/bin/skills-assets/xlsx/references/ooxml-cheatsheet.md +0 -231
  130. package/bin/skills-assets/xlsx/references/read-analyze.md +0 -97
  131. package/bin/skills-assets/xlsx/references/validate.md +0 -772
  132. package/bin/skills-assets/xlsx/scripts/formula_check.py +0 -422
  133. package/bin/skills-assets/xlsx/scripts/libreoffice_recalc.py +0 -248
  134. package/bin/skills-assets/xlsx/scripts/shared_strings_builder.py +0 -163
  135. package/bin/skills-assets/xlsx/scripts/style_audit.py +0 -575
  136. package/bin/skills-assets/xlsx/scripts/xlsx_add_column.py +0 -395
  137. package/bin/skills-assets/xlsx/scripts/xlsx_insert_row.py +0 -274
  138. package/bin/skills-assets/xlsx/scripts/xlsx_pack.py +0 -87
  139. package/bin/skills-assets/xlsx/scripts/xlsx_reader.py +0 -362
  140. package/bin/skills-assets/xlsx/scripts/xlsx_shift_rows.py +0 -396
  141. package/bin/skills-assets/xlsx/scripts/xlsx_unpack.py +0 -130
  142. package/bin/skills-assets/xlsx/templates/minimal_xlsx/[Content_Types].xml +0 -9
  143. package/bin/skills-assets/xlsx/templates/minimal_xlsx/_rels/.rels +0 -6
  144. package/bin/skills-assets/xlsx/templates/minimal_xlsx/xl/_rels/workbook.xml.rels +0 -19
  145. package/bin/skills-assets/xlsx/templates/minimal_xlsx/xl/sharedStrings.xml +0 -33
  146. package/bin/skills-assets/xlsx/templates/minimal_xlsx/xl/styles.xml +0 -160
  147. package/bin/skills-assets/xlsx/templates/minimal_xlsx/xl/workbook.xml +0 -30
  148. package/bin/skills-assets/xlsx/templates/minimal_xlsx/xl/worksheets/sheet1.xml +0 -70
@@ -1,147 +0,0 @@
1
- using System.CommandLine;
2
- using System.IO.Compression;
3
- using System.Text.Json;
4
- using System.Xml.Linq;
5
-
6
- namespace Docx.Core.Commands;
7
-
8
- public static class AnalyzeCommand
9
- {
10
- private static readonly XNamespace W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
11
- private static readonly XNamespace WP = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
12
-
13
- public static Command Create()
14
- {
15
- var inputOption = new Option<string>("--input") { Description = "DOCX file to analyze", Required = true };
16
- var jsonOption = new Option<bool>("--json") { Description = "Output as JSON" };
17
-
18
- var cmd = new Command("analyze", "Analyze document structure and styles")
19
- {
20
- inputOption, jsonOption
21
- };
22
-
23
- cmd.SetAction((parseResult) =>
24
- {
25
- var input = parseResult.GetValue(inputOption)!;
26
- var asJson = parseResult.GetValue(jsonOption);
27
-
28
- if (!File.Exists(input))
29
- {
30
- Console.Error.WriteLine($"File not found: {input}");
31
- return;
32
- }
33
-
34
- using var zip = ZipFile.OpenRead(input);
35
- var docEntry = zip.GetEntry("word/document.xml");
36
- if (docEntry == null)
37
- {
38
- Console.Error.WriteLine("Not a valid DOCX");
39
- return;
40
- }
41
-
42
- XDocument doc;
43
- using (var stream = docEntry.Open())
44
- doc = XDocument.Load(stream);
45
-
46
- var body = doc.Root?.Element(W + "body");
47
- if (body == null) return;
48
-
49
- // Sections
50
- var sections = body.Descendants(W + "sectPr").ToList();
51
- var sectionBreaks = sections.Select(s => (string?)s.Element(W + "type")?.Attribute(W + "val") ?? "nextPage").ToList();
52
-
53
- // Headings
54
- var headings = new List<object>();
55
- foreach (var p in body.Descendants(W + "p"))
56
- {
57
- var style = (string?)p.Element(W + "pPr")?.Element(W + "pStyle")?.Attribute(W + "val");
58
- if (style?.StartsWith("Heading", StringComparison.OrdinalIgnoreCase) == true)
59
- {
60
- var text = string.Concat(p.Descendants(W + "t").Select(t => t.Value));
61
- headings.Add(new { style, text });
62
- }
63
- }
64
-
65
- // Tables
66
- var tables = body.Descendants(W + "tbl").Select(tbl => new
67
- {
68
- rows = tbl.Elements(W + "tr").Count(),
69
- cols = tbl.Elements(W + "tr").FirstOrDefault()?.Elements(W + "tc").Count() ?? 0
70
- }).ToList();
71
-
72
- // Images
73
- var images = body.Descendants(W + "drawing").Count();
74
-
75
- // Headers/footers
76
- var headerRefs = sections.SelectMany(s => s.Elements(W + "headerReference")).Count();
77
- var footerRefs = sections.SelectMany(s => s.Elements(W + "footerReference")).Count();
78
-
79
- // Paragraphs and word count
80
- var paragraphs = body.Descendants(W + "p").ToList();
81
- var allText = string.Concat(body.Descendants(W + "t").Select(t => t.Value));
82
- var wordCount = allText.Split(new[] { ' ', '\t', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries).Length;
83
-
84
- // XML file sizes
85
- var fileSizes = zip.Entries
86
- .Where(e => e.FullName.StartsWith("word/") && e.FullName.EndsWith(".xml"))
87
- .Select(e => new { file = e.FullName, size = e.Length })
88
- .OrderByDescending(e => e.size)
89
- .ToList();
90
-
91
- // Styles
92
- var styleNames = new List<string>();
93
- var stylesEntry = zip.GetEntry("word/styles.xml");
94
- if (stylesEntry != null)
95
- {
96
- using var stream = stylesEntry.Open();
97
- var stylesDoc = XDocument.Load(stream);
98
- styleNames = stylesDoc.Descendants(W + "style")
99
- .Where(s => (string?)s.Attribute(W + "customStyle") == "1")
100
- .Select(s => (string?)s.Attribute(W + "styleId") ?? "")
101
- .Where(s => s != "")
102
- .ToList();
103
- }
104
-
105
- var analysis = new
106
- {
107
- sections = new { count = sections.Count, breakTypes = sectionBreaks },
108
- headings,
109
- tables = new { count = tables.Count, details = tables },
110
- images,
111
- headerFooter = new { headers = headerRefs, footers = footerRefs },
112
- paragraphs = paragraphs.Count,
113
- estimatedWordCount = wordCount,
114
- xmlFileSizes = fileSizes,
115
- customStyles = new { count = styleNames.Count, names = styleNames }
116
- };
117
-
118
- if (asJson)
119
- {
120
- Console.WriteLine(JsonSerializer.Serialize(analysis, new JsonSerializerOptions { WriteIndented = true }));
121
- }
122
- else
123
- {
124
- Console.WriteLine($"Sections: {sections.Count} ({string.Join(", ", sectionBreaks)})");
125
- Console.WriteLine($"Headings: {headings.Count}");
126
- foreach (var h in headings)
127
- Console.WriteLine($" {h}");
128
- Console.WriteLine($"Tables: {tables.Count}");
129
- foreach (var t in tables)
130
- Console.WriteLine($" {t.rows} rows x {t.cols} cols");
131
- Console.WriteLine($"Images: {images}");
132
- Console.WriteLine($"Headers: {headerRefs}");
133
- Console.WriteLine($"Footers: {footerRefs}");
134
- Console.WriteLine($"Paragraphs: {paragraphs.Count}");
135
- Console.WriteLine($"Word count: ~{wordCount}");
136
- Console.WriteLine($"Custom styles: {styleNames.Count}");
137
- foreach (var s in styleNames)
138
- Console.WriteLine($" {s}");
139
- Console.WriteLine("XML file sizes:");
140
- foreach (var f in fileSizes)
141
- Console.WriteLine($" {f.file}: {f.size:N0} bytes");
142
- }
143
- });
144
-
145
- return cmd;
146
- }
147
- }
@@ -1,322 +0,0 @@
1
- using System.CommandLine;
2
- using DocumentFormat.OpenXml;
3
- using DocumentFormat.OpenXml.Packaging;
4
- using DocumentFormat.OpenXml.Wordprocessing;
5
-
6
- namespace Docx.Core.Commands;
7
-
8
- /// <summary>
9
- /// Scenario C: Apply formatting from a template DOCX to a source DOCX.
10
- /// Copies styles, theme, numbering, headers/footers, and section properties
11
- /// from the template while preserving all content from the source.
12
- /// </summary>
13
- public static class ApplyTemplateCommand
14
- {
15
- public static Command Create()
16
- {
17
- var inputOpt = new Option<string>("--input") { Description = "Source DOCX (content to keep)", Required = true };
18
- var templateOpt = new Option<string>("--template") { Description = "Template DOCX (formatting to apply)", Required = true };
19
- var outputOpt = new Option<string>("--output") { Description = "Output DOCX file path", Required = true };
20
- var applyStylesOpt = new Option<bool>("--apply-styles") { Description = "Copy styles.xml from template" };
21
- applyStylesOpt.DefaultValueFactory = _ => true;
22
- var applyThemeOpt = new Option<bool>("--apply-theme") { Description = "Copy theme from template" };
23
- applyThemeOpt.DefaultValueFactory = _ => true;
24
- var applyNumberingOpt = new Option<bool>("--apply-numbering") { Description = "Copy numbering.xml from template" };
25
- applyNumberingOpt.DefaultValueFactory = _ => true;
26
- var applyHeadersFootersOpt = new Option<bool>("--apply-headers-footers") { Description = "Copy headers/footers from template" };
27
- var applySectionsOpt = new Option<bool>("--apply-sections") { Description = "Apply section properties from template" };
28
- applySectionsOpt.DefaultValueFactory = _ => true;
29
-
30
- var cmd = new Command("apply-template", "Apply template formatting to a DOCX")
31
- {
32
- inputOpt, templateOpt, outputOpt, applyStylesOpt, applyThemeOpt,
33
- applyNumberingOpt, applyHeadersFootersOpt, applySectionsOpt
34
- };
35
-
36
- cmd.SetAction((parseResult) =>
37
- {
38
- var inputPath = parseResult.GetValue(inputOpt)!;
39
- var templatePath = parseResult.GetValue(templateOpt)!;
40
- var outputPath = parseResult.GetValue(outputOpt)!;
41
- var applyStyles = parseResult.GetValue(applyStylesOpt);
42
- var applyTheme = parseResult.GetValue(applyThemeOpt);
43
- var applyNumbering = parseResult.GetValue(applyNumberingOpt);
44
- var applyHeadersFooters = parseResult.GetValue(applyHeadersFootersOpt);
45
- var applySections = parseResult.GetValue(applySectionsOpt);
46
-
47
- if (!File.Exists(inputPath)) { Console.Error.WriteLine($"Input file not found: {inputPath}"); return; }
48
- if (!File.Exists(templatePath)) { Console.Error.WriteLine($"Template file not found: {templatePath}"); return; }
49
-
50
- // Create output as a copy of the source
51
- File.Copy(inputPath, outputPath, overwrite: true);
52
-
53
- using var output = WordprocessingDocument.Open(outputPath, true);
54
- using var template = WordprocessingDocument.Open(templatePath, false);
55
-
56
- var outputMain = output.MainDocumentPart;
57
- var templateMain = template.MainDocumentPart;
58
- if (outputMain == null || templateMain == null)
59
- {
60
- Console.Error.WriteLine("Invalid document: missing main document part.");
61
- return;
62
- }
63
-
64
- int appliedCount = 0;
65
-
66
- if (applyStyles)
67
- {
68
- CopyStyles(templateMain, outputMain);
69
- appliedCount++;
70
- Console.WriteLine(" Applied: styles");
71
- }
72
-
73
- if (applyTheme)
74
- {
75
- CopyTheme(templateMain, outputMain);
76
- appliedCount++;
77
- Console.WriteLine(" Applied: theme");
78
- }
79
-
80
- if (applyNumbering)
81
- {
82
- CopyNumbering(templateMain, outputMain);
83
- appliedCount++;
84
- Console.WriteLine(" Applied: numbering");
85
- }
86
-
87
- if (applyHeadersFooters)
88
- {
89
- CopyHeadersAndFooters(templateMain, outputMain);
90
- appliedCount++;
91
- Console.WriteLine(" Applied: headers/footers");
92
- }
93
-
94
- if (applySections)
95
- {
96
- CopySectionProperties(templateMain, outputMain);
97
- appliedCount++;
98
- Console.WriteLine(" Applied: section properties");
99
- }
100
-
101
- outputMain.Document.Save();
102
- Console.WriteLine($"Applied {appliedCount} formatting component(s) from template to {outputPath}");
103
- });
104
-
105
- return cmd;
106
- }
107
-
108
- /// <summary>
109
- /// Replaces the output's StyleDefinitionsPart with the template's version.
110
- /// </summary>
111
- private static void CopyStyles(MainDocumentPart template, MainDocumentPart output)
112
- {
113
- var templateStyles = template.StyleDefinitionsPart;
114
- if (templateStyles == null) return;
115
-
116
- if (output.StyleDefinitionsPart != null)
117
- output.DeletePart(output.StyleDefinitionsPart);
118
-
119
- var newStylesPart = output.AddNewPart<StyleDefinitionsPart>();
120
-
121
- using var stream = templateStyles.GetStream(FileMode.Open, FileAccess.Read);
122
- newStylesPart.FeedData(stream);
123
- }
124
-
125
- /// <summary>
126
- /// Replaces the output's ThemePart with the template's version.
127
- /// </summary>
128
- private static void CopyTheme(MainDocumentPart template, MainDocumentPart output)
129
- {
130
- var templateTheme = template.ThemePart;
131
- if (templateTheme == null) return;
132
-
133
- if (output.ThemePart != null)
134
- output.DeletePart(output.ThemePart);
135
-
136
- var newThemePart = output.AddNewPart<ThemePart>();
137
-
138
- using var stream = templateTheme.GetStream(FileMode.Open, FileAccess.Read);
139
- newThemePart.FeedData(stream);
140
- }
141
-
142
- /// <summary>
143
- /// Copies numbering definitions from template, remapping numbering IDs
144
- /// referenced in the output document's paragraphs.
145
- /// </summary>
146
- private static void CopyNumbering(MainDocumentPart template, MainDocumentPart output)
147
- {
148
- var templateNumbering = template.NumberingDefinitionsPart;
149
- if (templateNumbering == null) return;
150
-
151
- var referencedNumIds = new HashSet<string>();
152
- var body = output.Document.Body;
153
- if (body != null)
154
- {
155
- foreach (var numId in body.Descendants<NumberingId>())
156
- {
157
- if (numId.Val?.Value != null)
158
- referencedNumIds.Add(numId.Val.Value.ToString());
159
- }
160
- }
161
-
162
- if (output.NumberingDefinitionsPart != null)
163
- output.DeletePart(output.NumberingDefinitionsPart);
164
-
165
- var newNumberingPart = output.AddNewPart<NumberingDefinitionsPart>();
166
-
167
- using var stream = templateNumbering.GetStream(FileMode.Open, FileAccess.Read);
168
- newNumberingPart.FeedData(stream);
169
-
170
- if (referencedNumIds.Count > 0)
171
- {
172
- Console.WriteLine($" Note: {referencedNumIds.Count} numbering reference(s) in document content mapped to template definitions.");
173
- }
174
- }
175
-
176
- /// <summary>
177
- /// Copies headers and footers from the template, remapping relationship IDs.
178
- /// </summary>
179
- private static void CopyHeadersAndFooters(MainDocumentPart template, MainDocumentPart output)
180
- {
181
- var outputBody = output.Document.Body;
182
- if (outputBody == null) return;
183
-
184
- // Remove existing header/footer parts from output
185
- foreach (var hp in output.HeaderParts.ToList())
186
- output.DeletePart(hp);
187
- foreach (var fp in output.FooterParts.ToList())
188
- output.DeletePart(fp);
189
-
190
- // Remove existing header/footer references from all section properties
191
- foreach (var sectPr in outputBody.Descendants<SectionProperties>())
192
- {
193
- foreach (var hr in sectPr.Elements<HeaderReference>().ToList())
194
- hr.Remove();
195
- foreach (var fr in sectPr.Elements<FooterReference>().ToList())
196
- fr.Remove();
197
- }
198
-
199
- var templateBody = template.Document?.Body;
200
- if (templateBody == null) return;
201
-
202
- var templateFinalSectPr = templateBody.Descendants<SectionProperties>().LastOrDefault();
203
- if (templateFinalSectPr == null) return;
204
-
205
- var outputFinalSectPr = outputBody.Descendants<SectionProperties>().LastOrDefault();
206
- if (outputFinalSectPr == null)
207
- {
208
- outputFinalSectPr = new SectionProperties();
209
- outputBody.Append(outputFinalSectPr);
210
- }
211
-
212
- // Copy headers
213
- foreach (var headerRef in templateFinalSectPr.Elements<HeaderReference>())
214
- {
215
- var templateHeaderPart = template.GetPartById(headerRef.Id!) as HeaderPart;
216
- if (templateHeaderPart == null) continue;
217
-
218
- var newHeaderPart = output.AddNewPart<HeaderPart>();
219
- using (var stream = templateHeaderPart.GetStream(FileMode.Open, FileAccess.Read))
220
- {
221
- newHeaderPart.FeedData(stream);
222
- }
223
-
224
- CopyPartRelationships(templateHeaderPart, newHeaderPart);
225
-
226
- var newRefId = output.GetIdOfPart(newHeaderPart);
227
- outputFinalSectPr.InsertAt(new HeaderReference
228
- {
229
- Type = headerRef.Type,
230
- Id = newRefId
231
- }, 0);
232
- }
233
-
234
- // Copy footers
235
- foreach (var footerRef in templateFinalSectPr.Elements<FooterReference>())
236
- {
237
- var templateFooterPart = template.GetPartById(footerRef.Id!) as FooterPart;
238
- if (templateFooterPart == null) continue;
239
-
240
- var newFooterPart = output.AddNewPart<FooterPart>();
241
- using (var stream = templateFooterPart.GetStream(FileMode.Open, FileAccess.Read))
242
- {
243
- newFooterPart.FeedData(stream);
244
- }
245
-
246
- CopyPartRelationships(templateFooterPart, newFooterPart);
247
-
248
- var newRefId = output.GetIdOfPart(newFooterPart);
249
- var lastHeaderRef = outputFinalSectPr.Elements<HeaderReference>().LastOrDefault();
250
- if (lastHeaderRef != null)
251
- lastHeaderRef.InsertAfterSelf(new FooterReference { Type = footerRef.Type, Id = newRefId });
252
- else
253
- outputFinalSectPr.InsertAt(new FooterReference { Type = footerRef.Type, Id = newRefId }, 0);
254
- }
255
- }
256
-
257
- /// <summary>
258
- /// Copies sub-relationships (images, etc.) from a source part to a target part.
259
- /// </summary>
260
- private static void CopyPartRelationships(OpenXmlPart source, OpenXmlPart target)
261
- {
262
- foreach (var rel in source.ExternalRelationships)
263
- {
264
- target.AddExternalRelationship(rel.RelationshipType, rel.Uri, rel.Id);
265
- }
266
-
267
- foreach (var childPart in source.Parts)
268
- {
269
- try
270
- {
271
- var contentType = childPart.OpenXmlPart.ContentType;
272
- if (contentType.StartsWith("image/"))
273
- {
274
- var newChild = target.AddNewPart<ImagePart>(contentType, childPart.RelationshipId);
275
- using var stream = childPart.OpenXmlPart.GetStream(FileMode.Open, FileAccess.Read);
276
- newChild.FeedData(stream);
277
- }
278
- }
279
- catch (Exception ex)
280
- {
281
- Console.Error.WriteLine($"[WARN] Skipped non-image embedded part: {ex.Message}");
282
- }
283
- }
284
- }
285
-
286
- /// <summary>
287
- /// Copies page size, margins, columns, and document grid from template section properties.
288
- /// </summary>
289
- private static void CopySectionProperties(MainDocumentPart template, MainDocumentPart output)
290
- {
291
- var templateBody = template.Document?.Body;
292
- var outputBody = output.Document?.Body;
293
- if (templateBody == null || outputBody == null) return;
294
-
295
- var templateSectPr = templateBody.Descendants<SectionProperties>().LastOrDefault();
296
- if (templateSectPr == null) return;
297
-
298
- var outputSectPr = outputBody.Descendants<SectionProperties>().LastOrDefault();
299
- if (outputSectPr == null)
300
- {
301
- outputSectPr = new SectionProperties();
302
- outputBody.Append(outputSectPr);
303
- }
304
-
305
- CopyChildElement<PageSize>(templateSectPr, outputSectPr);
306
- CopyChildElement<PageMargin>(templateSectPr, outputSectPr);
307
- CopyChildElement<Columns>(templateSectPr, outputSectPr);
308
- CopyChildElement<DocGrid>(templateSectPr, outputSectPr);
309
- CopyChildElement<PageBorders>(templateSectPr, outputSectPr);
310
- }
311
-
312
- private static void CopyChildElement<T>(SectionProperties source, SectionProperties target) where T : OpenXmlElement
313
- {
314
- var sourceElement = source.GetFirstChild<T>();
315
- if (sourceElement == null) return;
316
-
317
- var existing = target.GetFirstChild<T>();
318
- existing?.Remove();
319
-
320
- target.Append((T)sourceElement.CloneNode(true));
321
- }
322
- }