dimcode-darwin-arm64 0.2.19 → 0.2.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.
Files changed (109) hide show
  1. package/bin/dimcode +0 -0
  2. package/bin/skills-assets/chrome-control/SKILL.md +96 -0
  3. package/bin/skills-assets/dim-workflow/SKILL.md +78 -30
  4. package/bin/skills-assets/officecli/SKILL.md +423 -0
  5. package/package.json +1 -1
  6. package/bin/skills-assets/docx/SKILL.md +0 -273
  7. package/bin/skills-assets/docx/assets/styles/academic_styles.xml +0 -250
  8. package/bin/skills-assets/docx/assets/styles/corporate_styles.xml +0 -284
  9. package/bin/skills-assets/docx/assets/styles/default_styles.xml +0 -449
  10. package/bin/skills-assets/docx/assets/xsd/aesthetic-rules.xsd +0 -470
  11. package/bin/skills-assets/docx/assets/xsd/business-rules.xsd +0 -130
  12. package/bin/skills-assets/docx/assets/xsd/common-types.xsd +0 -159
  13. package/bin/skills-assets/docx/assets/xsd/wml-subset.xsd +0 -589
  14. package/bin/skills-assets/docx/references/cjk_typography.md +0 -357
  15. package/bin/skills-assets/docx/references/cjk_university_template_guide.md +0 -184
  16. package/bin/skills-assets/docx/references/comments_guide.md +0 -191
  17. package/bin/skills-assets/docx/references/design_good_bad_examples.md +0 -829
  18. package/bin/skills-assets/docx/references/design_principles.md +0 -819
  19. package/bin/skills-assets/docx/references/openxml_element_order.md +0 -308
  20. package/bin/skills-assets/docx/references/openxml_encyclopedia_part1.md +0 -4061
  21. package/bin/skills-assets/docx/references/openxml_encyclopedia_part2.md +0 -2820
  22. package/bin/skills-assets/docx/references/openxml_encyclopedia_part3.md +0 -3381
  23. package/bin/skills-assets/docx/references/openxml_namespaces.md +0 -82
  24. package/bin/skills-assets/docx/references/openxml_units.md +0 -72
  25. package/bin/skills-assets/docx/references/scenario_a_create.md +0 -284
  26. package/bin/skills-assets/docx/references/scenario_b_edit_content.md +0 -295
  27. package/bin/skills-assets/docx/references/scenario_c_apply_template.md +0 -456
  28. package/bin/skills-assets/docx/references/track_changes_guide.md +0 -200
  29. package/bin/skills-assets/docx/references/troubleshooting.md +0 -506
  30. package/bin/skills-assets/docx/references/typography_guide.md +0 -294
  31. package/bin/skills-assets/docx/references/xsd_validation_guide.md +0 -158
  32. package/bin/skills-assets/docx/scripts/doc_to_docx.sh +0 -40
  33. package/bin/skills-assets/docx/scripts/docx_preview.sh +0 -37
  34. package/bin/skills-assets/docx/scripts/dotnet/Docx.Cli/Docx.Cli.csproj +0 -19
  35. package/bin/skills-assets/docx/scripts/dotnet/Docx.Cli/Program.cs +0 -18
  36. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Commands/AnalyzeCommand.cs +0 -147
  37. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Commands/ApplyTemplateCommand.cs +0 -322
  38. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Commands/CreateCommand.cs +0 -324
  39. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Commands/DiffCommand.cs +0 -155
  40. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Commands/EditContentCommand.cs +0 -487
  41. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Commands/FixOrderCommand.cs +0 -108
  42. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Commands/MergeRunsCommand.cs +0 -122
  43. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Commands/ValidateCommand.cs +0 -107
  44. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Docx.Core.csproj +0 -15
  45. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/OpenXml/CommentSynchronizer.cs +0 -169
  46. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/OpenXml/ElementOrder.cs +0 -80
  47. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/OpenXml/NamespaceConstants.cs +0 -42
  48. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/OpenXml/RunMerger.cs +0 -81
  49. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/OpenXml/StyleAnalyzer.cs +0 -81
  50. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/OpenXml/TrackChangesHelper.cs +0 -99
  51. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/OpenXml/UnitConverter.cs +0 -23
  52. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/AestheticRecipeSamples.cs +0 -1832
  53. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/AestheticRecipeSamples_Batch1.cs +0 -910
  54. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/AestheticRecipeSamples_Batch2.cs +0 -999
  55. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/AestheticRecipeSamples_Batch3.cs +0 -1048
  56. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/AestheticRecipeSamples_Batch4.cs +0 -1038
  57. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/CharacterFormattingSamples.cs +0 -1020
  58. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/DocumentCreationSamples.cs +0 -1121
  59. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/FieldAndTocSamples.cs +0 -624
  60. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/FootnoteAndCommentSamples.cs +0 -675
  61. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/HeaderFooterSamples.cs +0 -838
  62. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/ImageSamples.cs +0 -917
  63. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/ListAndNumberingSamples.cs +0 -826
  64. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/ParagraphFormattingSamples.cs +0 -1199
  65. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/StyleSystemSamples.cs +0 -1487
  66. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/TableSamples.cs +0 -1163
  67. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/TrackChangesSamples.cs +0 -595
  68. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Typography/CjkHelper.cs +0 -39
  69. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Typography/FontDefaults.cs +0 -24
  70. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Typography/PageSizes.cs +0 -20
  71. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Validation/BusinessRuleValidator.cs +0 -224
  72. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Validation/GateCheckValidator.cs +0 -148
  73. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Validation/ValidationResult.cs +0 -23
  74. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Validation/XsdValidator.cs +0 -69
  75. package/bin/skills-assets/docx/scripts/dotnet/Docx.slnx +0 -4
  76. package/bin/skills-assets/docx/scripts/env_check.sh +0 -196
  77. package/bin/skills-assets/docx/scripts/setup.ps1 +0 -274
  78. package/bin/skills-assets/docx/scripts/setup.sh +0 -504
  79. package/bin/skills-assets/pptx-generator/SKILL.md +0 -248
  80. package/bin/skills-assets/pptx-generator/references/design-system.md +0 -392
  81. package/bin/skills-assets/pptx-generator/references/editing.md +0 -162
  82. package/bin/skills-assets/pptx-generator/references/pitfalls.md +0 -112
  83. package/bin/skills-assets/pptx-generator/references/pptxgenjs.md +0 -420
  84. package/bin/skills-assets/pptx-generator/references/slide-types.md +0 -413
  85. package/bin/skills-assets/xlsx/SKILL.md +0 -137
  86. package/bin/skills-assets/xlsx/references/create.md +0 -691
  87. package/bin/skills-assets/xlsx/references/edit.md +0 -684
  88. package/bin/skills-assets/xlsx/references/fix.md +0 -37
  89. package/bin/skills-assets/xlsx/references/format.md +0 -768
  90. package/bin/skills-assets/xlsx/references/ooxml-cheatsheet.md +0 -231
  91. package/bin/skills-assets/xlsx/references/read-analyze.md +0 -97
  92. package/bin/skills-assets/xlsx/references/validate.md +0 -772
  93. package/bin/skills-assets/xlsx/scripts/formula_check.py +0 -422
  94. package/bin/skills-assets/xlsx/scripts/libreoffice_recalc.py +0 -248
  95. package/bin/skills-assets/xlsx/scripts/shared_strings_builder.py +0 -163
  96. package/bin/skills-assets/xlsx/scripts/style_audit.py +0 -575
  97. package/bin/skills-assets/xlsx/scripts/xlsx_add_column.py +0 -395
  98. package/bin/skills-assets/xlsx/scripts/xlsx_insert_row.py +0 -274
  99. package/bin/skills-assets/xlsx/scripts/xlsx_pack.py +0 -87
  100. package/bin/skills-assets/xlsx/scripts/xlsx_reader.py +0 -362
  101. package/bin/skills-assets/xlsx/scripts/xlsx_shift_rows.py +0 -396
  102. package/bin/skills-assets/xlsx/scripts/xlsx_unpack.py +0 -130
  103. package/bin/skills-assets/xlsx/templates/minimal_xlsx/[Content_Types].xml +0 -9
  104. package/bin/skills-assets/xlsx/templates/minimal_xlsx/_rels/.rels +0 -6
  105. package/bin/skills-assets/xlsx/templates/minimal_xlsx/xl/_rels/workbook.xml.rels +0 -19
  106. package/bin/skills-assets/xlsx/templates/minimal_xlsx/xl/sharedStrings.xml +0 -33
  107. package/bin/skills-assets/xlsx/templates/minimal_xlsx/xl/styles.xml +0 -160
  108. package/bin/skills-assets/xlsx/templates/minimal_xlsx/xl/workbook.xml +0 -30
  109. package/bin/skills-assets/xlsx/templates/minimal_xlsx/xl/worksheets/sheet1.xml +0 -70
@@ -1,122 +0,0 @@
1
- using System.CommandLine;
2
- using System.IO.Compression;
3
- using System.Xml.Linq;
4
-
5
- namespace Docx.Core.Commands;
6
-
7
- public static class MergeRunsCommand
8
- {
9
- private static readonly XNamespace W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
10
-
11
- public static Command Create()
12
- {
13
- var inputOption = new Option<string>("--input") { Description = "DOCX file to optimize", Required = true };
14
- var outputOption = new Option<string>("--output") { Description = "Output path (default: overwrite input)" };
15
- var dryRunOption = new Option<bool>("--dry-run") { Description = "Report without modifying" };
16
-
17
- var cmd = new Command("merge-runs", "Merge adjacent runs with identical formatting")
18
- {
19
- inputOption, outputOption, dryRunOption
20
- };
21
-
22
- cmd.SetAction((parseResult) =>
23
- {
24
- var input = parseResult.GetValue(inputOption)!;
25
- var output = parseResult.GetValue(outputOption) ?? input;
26
- var dryRun = parseResult.GetValue(dryRunOption);
27
-
28
- if (!File.Exists(input))
29
- {
30
- Console.Error.WriteLine($"File not found: {input}");
31
- return;
32
- }
33
-
34
- var tempPath = Path.GetTempFileName();
35
- File.Copy(input, tempPath, true);
36
-
37
- using var zip = ZipFile.Open(tempPath, ZipArchiveMode.Update);
38
- var entry = zip.GetEntry("word/document.xml");
39
- if (entry == null)
40
- {
41
- Console.Error.WriteLine("Not a valid DOCX: missing word/document.xml");
42
- return;
43
- }
44
-
45
- XDocument doc;
46
- using (var stream = entry.Open())
47
- doc = XDocument.Load(stream);
48
-
49
- int originalCount = 0;
50
- int mergedCount = 0;
51
-
52
- foreach (var p in doc.Descendants(W + "p"))
53
- {
54
- var runs = p.Elements(W + "r").ToList();
55
- originalCount += runs.Count;
56
-
57
- for (int i = runs.Count - 1; i > 0; i--)
58
- {
59
- var current = runs[i];
60
- var previous = runs[i - 1];
61
-
62
- var curProps = current.Element(W + "rPr")?.ToString() ?? "";
63
- var prevProps = previous.Element(W + "rPr")?.ToString() ?? "";
64
-
65
- if (curProps == prevProps)
66
- {
67
- // Only merge if both contain only text elements
68
- var curChildren = current.Elements().Where(e => e.Name != W + "rPr").ToList();
69
- var prevChildren = previous.Elements().Where(e => e.Name != W + "rPr").ToList();
70
-
71
- if (curChildren.All(e => e.Name == W + "t") && prevChildren.All(e => e.Name == W + "t"))
72
- {
73
- var prevText = previous.Elements(W + "t").LastOrDefault();
74
- var curText = current.Elements(W + "t").FirstOrDefault();
75
-
76
- if (prevText != null && curText != null)
77
- {
78
- prevText.Value += curText.Value;
79
- prevText.SetAttributeValue(XNamespace.Xml + "space", "preserve");
80
-
81
- foreach (var extra in current.Elements(W + "t").Skip(1))
82
- {
83
- previous.Add(new XElement(extra));
84
- }
85
-
86
- current.Remove();
87
- runs.RemoveAt(i);
88
- }
89
- }
90
- }
91
- }
92
-
93
- mergedCount += runs.Count;
94
- }
95
-
96
- if (dryRun)
97
- {
98
- Console.WriteLine($"Original runs: {originalCount}");
99
- Console.WriteLine($"After merge: {mergedCount}");
100
- Console.WriteLine($"Reduction: {(originalCount > 0 ? (originalCount - mergedCount) * 100.0 / originalCount : 0):F1}%");
101
- File.Delete(tempPath);
102
- return;
103
- }
104
-
105
- entry.Delete();
106
- var newEntry = zip.CreateEntry("word/document.xml", CompressionLevel.Optimal);
107
- using (var stream = newEntry.Open())
108
- doc.Save(stream);
109
-
110
- zip.Dispose();
111
- File.Copy(tempPath, output, true);
112
- File.Delete(tempPath);
113
-
114
- Console.WriteLine($"Original runs: {originalCount}");
115
- Console.WriteLine($"After merge: {mergedCount}");
116
- Console.WriteLine($"Reduction: {(originalCount > 0 ? (originalCount - mergedCount) * 100.0 / originalCount : 0):F1}%");
117
- Console.WriteLine($"Written to: {output}");
118
- });
119
-
120
- return cmd;
121
- }
122
- }
@@ -1,107 +0,0 @@
1
- using System.CommandLine;
2
- using System.Text.Json;
3
- using Docx.Core.Validation;
4
-
5
- namespace Docx.Core.Commands;
6
-
7
- public static class ValidateCommand
8
- {
9
- public static Command Create()
10
- {
11
- var inputOption = new Option<string>("--input") { Description = "DOCX file to validate", Required = true };
12
- var xsdOption = new Option<string>("--xsd") { Description = "XSD schema path for XML validation" };
13
- var businessOption = new Option<bool>("--business") { Description = "Run business rule validation" };
14
- var gateCheckOption = new Option<string>("--gate-check") { Description = "Template DOCX for gate-check validation" };
15
- var jsonOption = new Option<bool>("--json") { Description = "Output results as JSON" };
16
-
17
- var cmd = new Command("validate", "Validate DOCX structure and content")
18
- {
19
- inputOption, xsdOption, businessOption, gateCheckOption, jsonOption
20
- };
21
-
22
- cmd.SetAction((parseResult) =>
23
- {
24
- var input = parseResult.GetValue(inputOption)!;
25
- var xsd = parseResult.GetValue(xsdOption);
26
- var business = parseResult.GetValue(businessOption);
27
- var gateCheck = parseResult.GetValue(gateCheckOption);
28
- var asJson = parseResult.GetValue(jsonOption);
29
-
30
- if (!File.Exists(input))
31
- {
32
- Console.Error.WriteLine($"File not found: {input}");
33
- return;
34
- }
35
-
36
- var combinedResult = new ValidationResult();
37
- GateCheckResult? gateResult = null;
38
-
39
- if (xsd != null)
40
- {
41
- var xsdValidator = new XsdValidator();
42
- combinedResult.Merge(xsdValidator.Validate(input, xsd));
43
- }
44
-
45
- if (business)
46
- {
47
- var bizValidator = new BusinessRuleValidator();
48
- combinedResult.Merge(bizValidator.Validate(input));
49
- }
50
-
51
- if (gateCheck != null)
52
- {
53
- var gateValidator = new GateCheckValidator();
54
- gateResult = gateValidator.Validate(input, gateCheck);
55
- }
56
-
57
- if (asJson)
58
- {
59
- var output = new
60
- {
61
- isValid = combinedResult.IsValid && (gateResult?.Passed ?? true),
62
- errors = combinedResult.Errors,
63
- warnings = combinedResult.Warnings,
64
- gateCheck = gateResult == null ? null : new
65
- {
66
- passed = gateResult.Passed,
67
- violations = gateResult.Violations
68
- }
69
- };
70
- Console.WriteLine(JsonSerializer.Serialize(output, new JsonSerializerOptions { WriteIndented = true }));
71
- }
72
- else
73
- {
74
- if (combinedResult.Errors.Count > 0)
75
- {
76
- Console.WriteLine($"ERRORS ({combinedResult.Errors.Count}):");
77
- foreach (var e in combinedResult.Errors)
78
- Console.WriteLine($" [{e.Severity}] {e.Message}" + (e.LineNumber > 0 ? $" (line {e.LineNumber}:{e.LinePosition})" : ""));
79
- }
80
-
81
- if (combinedResult.Warnings.Count > 0)
82
- {
83
- Console.WriteLine($"WARNINGS ({combinedResult.Warnings.Count}):");
84
- foreach (var w in combinedResult.Warnings)
85
- Console.WriteLine($" [{w.Severity}] {w.Message}");
86
- }
87
-
88
- if (gateResult != null)
89
- {
90
- Console.WriteLine(gateResult.Passed ? "GATE CHECK: PASSED" : "GATE CHECK: FAILED");
91
- foreach (var v in gateResult.Violations)
92
- Console.WriteLine($" - {v}");
93
- }
94
-
95
- if (combinedResult.IsValid && (gateResult?.Passed ?? true))
96
- Console.WriteLine("Validation: PASSED");
97
- else
98
- Console.WriteLine("Validation: FAILED");
99
- }
100
-
101
- if (!combinedResult.IsValid || gateResult is { Passed: false })
102
- Environment.ExitCode = 1;
103
- });
104
-
105
- return cmd;
106
- }
107
- }
@@ -1,15 +0,0 @@
1
- <Project Sdk="Microsoft.NET.Sdk">
2
-
3
- <PropertyGroup>
4
- <TargetFramework>net8.0</TargetFramework>
5
- <ImplicitUsings>enable</ImplicitUsings>
6
- <Nullable>enable</Nullable>
7
- <NeutralLanguage>en</NeutralLanguage>
8
- </PropertyGroup>
9
-
10
- <ItemGroup>
11
- <PackageReference Include="DocumentFormat.OpenXml" Version="3.5.1" />
12
- <PackageReference Include="System.CommandLine" Version="2.0.5" />
13
- </ItemGroup>
14
-
15
- </Project>
@@ -1,169 +0,0 @@
1
- using DocumentFormat.OpenXml;
2
- using DocumentFormat.OpenXml.Packaging;
3
- using DocumentFormat.OpenXml.Wordprocessing;
4
-
5
- namespace Docx.Core.OpenXml;
6
-
7
- /// <summary>
8
- /// Manages the 4-file comment system (comments.xml, commentsExtended.xml,
9
- /// commentsIds.xml, commentsExtensible.xml) plus document.xml markers.
10
- /// </summary>
11
- public static class CommentSynchronizer
12
- {
13
- /// <summary>
14
- /// Adds a comment to the document, updating all required parts.
15
- /// </summary>
16
- public static int AddComment(WordprocessingDocument doc, string text, string author, string rangeBookmark)
17
- {
18
- var mainPart = doc.MainDocumentPart
19
- ?? throw new InvalidOperationException("Document has no main part.");
20
-
21
- int commentId = GetNextCommentId(doc);
22
-
23
- // Ensure comments part exists
24
- var commentsPart = mainPart.WordprocessingCommentsPart
25
- ?? mainPart.AddNewPart<WordprocessingCommentsPart>();
26
-
27
- if (commentsPart.Comments == null)
28
- commentsPart.Comments = new Comments();
29
-
30
- // Create the comment
31
- var comment = new Comment
32
- {
33
- Id = commentId.ToString(),
34
- Author = author,
35
- Date = DateTime.UtcNow,
36
- Initials = author.Length > 0 ? author[..1].ToUpperInvariant() : "A"
37
- };
38
- comment.Append(new Paragraph(new Run(new Text(text))));
39
- commentsPart.Comments.Append(comment);
40
-
41
- // Add range markers in document body
42
- var body = mainPart.Document.Body;
43
- if (body != null)
44
- {
45
- // Find bookmark or append at end
46
- var rangeStart = new CommentRangeStart { Id = commentId.ToString() };
47
- var rangeEnd = new CommentRangeEnd { Id = commentId.ToString() };
48
- var reference = new Run(new CommentReference { Id = commentId.ToString() });
49
-
50
- body.Append(rangeStart);
51
- body.Append(rangeEnd);
52
- body.Append(new Paragraph(reference));
53
- }
54
-
55
- return commentId;
56
- }
57
-
58
- /// <summary>
59
- /// Adds a reply to an existing comment.
60
- /// </summary>
61
- public static int AddReply(WordprocessingDocument doc, int parentCommentId, string text, string author)
62
- {
63
- var mainPart = doc.MainDocumentPart
64
- ?? throw new InvalidOperationException("Document has no main part.");
65
-
66
- var commentsPart = mainPart.WordprocessingCommentsPart
67
- ?? throw new InvalidOperationException("Document has no comments part.");
68
-
69
- int replyId = GetNextCommentId(doc);
70
-
71
- var reply = new Comment
72
- {
73
- Id = replyId.ToString(),
74
- Author = author,
75
- Date = DateTime.UtcNow,
76
- Initials = author.Length > 0 ? author[..1].ToUpperInvariant() : "A"
77
- };
78
- reply.Append(new Paragraph(new Run(new Text(text))));
79
- commentsPart.Comments?.Append(reply);
80
-
81
- // Link reply to parent via commentsExtended.xml
82
- LinkReplyToParent(doc, replyId, parentCommentId);
83
-
84
- return replyId;
85
- }
86
-
87
- /// <summary>
88
- /// Marks a comment as resolved/done by setting done="1" in commentsExtended.xml.
89
- /// Uses raw XML manipulation since these extended parts lack typed SDK support.
90
- /// </summary>
91
- public static void ResolveComment(WordprocessingDocument doc, int commentId)
92
- {
93
- var mainPart = doc.MainDocumentPart;
94
- if (mainPart == null) return;
95
-
96
- // commentsExtended.xml is an untyped part — manipulate via raw XML
97
- const string ceUri = "http://schemas.microsoft.com/office/word/2018/wordml/cex";
98
- foreach (var part in mainPart.Parts)
99
- {
100
- if (part.OpenXmlPart.ContentType.Contains("commentsExtensible"))
101
- {
102
- using var stream = part.OpenXmlPart.GetStream(FileMode.Open, FileAccess.ReadWrite);
103
- var xdoc = System.Xml.Linq.XDocument.Load(stream);
104
- var ns = System.Xml.Linq.XNamespace.Get(ceUri);
105
- var commentEl = xdoc.Descendants(ns + "comment")
106
- .FirstOrDefault(e => e.Attribute(ns + "paraId")?.Value != null);
107
- // Set done flag if element found for this comment
108
- if (commentEl != null)
109
- {
110
- commentEl.SetAttributeValue("done", "1");
111
- stream.SetLength(0);
112
- xdoc.Save(stream);
113
- }
114
- return;
115
- }
116
- }
117
- }
118
-
119
- /// <summary>
120
- /// Links a reply comment to its parent via commentsExtended.xml (w15:commentEx).
121
- /// Uses raw XML since the extended comment parts lack typed SDK support.
122
- /// </summary>
123
- private static void LinkReplyToParent(WordprocessingDocument doc, int replyId, int parentCommentId)
124
- {
125
- var mainPart = doc.MainDocumentPart;
126
- if (mainPart == null) return;
127
-
128
- const string w15Uri = "http://schemas.microsoft.com/office/word/2012/wordml";
129
- var w15 = System.Xml.Linq.XNamespace.Get(w15Uri);
130
-
131
- // Find or create commentsExtended part
132
- foreach (var part in mainPart.Parts)
133
- {
134
- if (part.OpenXmlPart.ContentType.Contains("commentsExtended"))
135
- {
136
- using var stream = part.OpenXmlPart.GetStream(FileMode.Open, FileAccess.ReadWrite);
137
- var xdoc = System.Xml.Linq.XDocument.Load(stream);
138
- var root = xdoc.Root;
139
- if (root == null) return;
140
-
141
- root.Add(new System.Xml.Linq.XElement(w15 + "commentEx",
142
- new System.Xml.Linq.XAttribute(w15 + "paraId", replyId.ToString("X8")),
143
- new System.Xml.Linq.XAttribute(w15 + "paraIdParent", parentCommentId.ToString("X8")),
144
- new System.Xml.Linq.XAttribute(w15 + "done", "0")));
145
-
146
- stream.SetLength(0);
147
- xdoc.Save(stream);
148
- return;
149
- }
150
- }
151
- }
152
-
153
- /// <summary>
154
- /// Finds the maximum existing comment ID and returns the next one.
155
- /// </summary>
156
- public static int GetNextCommentId(WordprocessingDocument doc)
157
- {
158
- var commentsPart = doc.MainDocumentPart?.WordprocessingCommentsPart;
159
- if (commentsPart?.Comments == null) return 1;
160
-
161
- int maxId = 0;
162
- foreach (var comment in commentsPart.Comments.Elements<Comment>())
163
- {
164
- if (comment.Id?.Value != null && int.TryParse(comment.Id.Value, out int id) && id > maxId)
165
- maxId = id;
166
- }
167
- return maxId + 1;
168
- }
169
- }
@@ -1,80 +0,0 @@
1
- using System.Xml.Linq;
2
-
3
- namespace Docx.Core.OpenXml;
4
-
5
- /// <summary>
6
- /// Defines canonical child element ordering for key OpenXML parent elements
7
- /// and provides reordering utilities.
8
- /// </summary>
9
- public static class ElementOrder
10
- {
11
- private static readonly Dictionary<string, string[]> OrderMap = new()
12
- {
13
- ["w:body"] = ["w:p", "w:tbl", "w:sdt", "w:sectPr"],
14
- ["w:p"] = ["w:pPr", "w:hyperlink", "w:r", "w:ins", "w:del", "w:bookmarkStart", "w:bookmarkEnd", "w:commentRangeStart", "w:commentRangeEnd", "w:fldSimple"],
15
- ["w:pPr"] = ["w:pStyle", "w:keepNext", "w:keepLines", "w:pageBreakBefore", "w:widowControl", "w:numPr", "w:pBdr", "w:shd", "w:tabs", "w:suppressAutoHyphens", "w:spacing", "w:ind", "w:jc", "w:rPr", "w:sectPr", "w:pPrChange"],
16
- ["w:r"] = ["w:rPr", "w:t", "w:br", "w:tab", "w:cr", "w:sym", "w:drawing", "w:delText", "w:fldChar", "w:instrText", "w:lastRenderedPageBreak", "w:noBreakHyphen", "w:softHyphen"],
17
- ["w:rPr"] = ["w:rStyle", "w:rFonts", "w:b", "w:bCs", "w:i", "w:iCs", "w:caps", "w:smallCaps", "w:strike", "w:dstrike", "w:vanish", "w:color", "w:sz", "w:szCs", "w:u", "w:shd", "w:highlight", "w:lang", "w:rPrChange"],
18
- ["w:tbl"] = ["w:tblPr", "w:tblGrid", "w:tr"],
19
- ["w:tblPr"] = ["w:tblStyle", "w:tblpPr", "w:tblOverlap", "w:tblW", "w:jc", "w:tblCellSpacing", "w:tblInd", "w:tblBorders", "w:shd", "w:tblLayout", "w:tblCellMar", "w:tblLook", "w:tblPrChange"],
20
- ["w:tr"] = ["w:trPr", "w:tc"],
21
- ["w:trPr"] = ["w:cnfStyle", "w:divId", "w:gridBefore", "w:gridAfter", "w:wBefore", "w:wAfter", "w:cantSplit", "w:trHeight", "w:tblHeader", "w:tblCellSpacing", "w:jc", "w:hidden", "w:ins", "w:del", "w:trPrChange"],
22
- ["w:tc"] = ["w:tcPr", "w:p", "w:tbl"],
23
- ["w:tcPr"] = ["w:cnfStyle", "w:tcW", "w:gridSpan", "w:hMerge", "w:vMerge", "w:tcBorders", "w:shd", "w:noWrap", "w:tcMar", "w:textDirection", "w:tcFitText", "w:vAlign", "w:hideMark", "w:headers", "w:cellIns", "w:cellDel", "w:cellMerge", "w:tcPrChange"],
24
- ["w:sectPr"] = ["w:headerReference", "w:footerReference", "w:type", "w:pgSz", "w:pgMar", "w:paperSrc", "w:pgBorders", "w:lnNumType", "w:pgNumType", "w:cols", "w:formProt", "w:vAlign", "w:noEndnote", "w:titlePg", "w:textDirection", "w:bidi", "w:rtlGutter", "w:docGrid"],
25
- ["w:hdr"] = ["w:p", "w:tbl", "w:sdt"],
26
- ["w:ftr"] = ["w:p", "w:tbl", "w:sdt"],
27
- };
28
-
29
- /// <summary>
30
- /// Returns the canonical child ordering for a given parent element name (e.g. "w:p").
31
- /// Returns null if no ordering is defined.
32
- /// </summary>
33
- public static string[]? GetChildOrder(string parentElement)
34
- {
35
- return OrderMap.TryGetValue(parentElement, out var order) ? order : null;
36
- }
37
-
38
- /// <summary>
39
- /// Reorders children of the given XElement according to the canonical ordering rules.
40
- /// Children not listed in the ordering are placed at the end in their original order.
41
- /// </summary>
42
- public static void ReorderChildren(XElement parent)
43
- {
44
- var qualifiedName = GetQualifiedName(parent);
45
- var order = GetChildOrder(qualifiedName);
46
- if (order == null) return;
47
-
48
- var children = parent.Elements().ToList();
49
- if (children.Count <= 1) return;
50
-
51
- var orderIndex = new Dictionary<string, int>();
52
- for (int i = 0; i < order.Length; i++)
53
- orderIndex[order[i]] = i;
54
-
55
- int unknownBase = order.Length;
56
- int unknownCounter = 0;
57
-
58
- var sorted = children
59
- .Select(c => (Element: c, QName: GetQualifiedName(c)))
60
- .OrderBy(x => orderIndex.TryGetValue(x.QName, out var idx) ? idx : unknownBase + unknownCounter++)
61
- .Select(x => x.Element)
62
- .ToList();
63
-
64
- parent.RemoveNodes();
65
- foreach (var child in sorted)
66
- parent.Add(child);
67
- }
68
-
69
- private static string GetQualifiedName(XElement element)
70
- {
71
- var ns = element.Name.Namespace;
72
- var local = element.Name.LocalName;
73
-
74
- if (ns == Ns.W) return $"w:{local}";
75
- if (ns == Ns.R) return $"r:{local}";
76
- if (ns == Ns.MC) return $"mc:{local}";
77
-
78
- return local;
79
- }
80
- }
@@ -1,42 +0,0 @@
1
- using System.Xml.Linq;
2
-
3
- namespace Docx.Core.OpenXml;
4
-
5
- /// <summary>
6
- /// All OpenXML namespace URIs and common content/relationship type constants.
7
- /// </summary>
8
- public static class Ns
9
- {
10
- public static readonly XNamespace W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
11
- public static readonly XNamespace R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
12
- public static readonly XNamespace WP = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
13
- public static readonly XNamespace A = "http://schemas.openxmlformats.org/drawingml/2006/main";
14
- public static readonly XNamespace MC = "http://schemas.openxmlformats.org/markup-compatibility/2006";
15
- public static readonly XNamespace PIC = "http://schemas.openxmlformats.org/drawingml/2006/picture";
16
- public static readonly XNamespace W14 = "http://schemas.microsoft.com/office/word/2010/wordml";
17
- public static readonly XNamespace W15 = "http://schemas.microsoft.com/office/word/2012/wordml";
18
- public static readonly XNamespace W16CID = "http://schemas.microsoft.com/office/word/2016/wordml/cid";
19
- public static readonly XNamespace W16CEX = "http://schemas.microsoft.com/office/word/2018/wordml/cex";
20
- public static readonly XNamespace WPC = "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas";
21
- public static readonly XNamespace WPS = "http://schemas.microsoft.com/office/word/2010/wordprocessingShape";
22
-
23
- // Content types
24
- public const string MainDocumentContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml";
25
- public const string StylesContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml";
26
- public const string HeaderContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml";
27
- public const string FooterContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml";
28
- public const string CommentsContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml";
29
-
30
- // Relationship types
31
- public const string DocumentRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
32
- public const string StylesRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
33
- public const string HeaderRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header";
34
- public const string FooterRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer";
35
- public const string CommentsRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments";
36
- public const string ImageRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
37
- public const string HyperlinkRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink";
38
- public const string NumberingRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering";
39
- public const string FontTableRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable";
40
- public const string ThemeRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme";
41
- public const string SettingsRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings";
42
- }
@@ -1,81 +0,0 @@
1
- using System.Xml.Linq;
2
-
3
- namespace Docx.Core.OpenXml;
4
-
5
- /// <summary>
6
- /// Result of a run merge operation.
7
- /// </summary>
8
- public record RunMergeResult(int OriginalRunCount, int MergedRunCount, int SizeReductionBytes);
9
-
10
- /// <summary>
11
- /// Merges adjacent w:r elements with identical w:rPr formatting to reduce document size.
12
- /// </summary>
13
- public static class RunMerger
14
- {
15
- /// <summary>
16
- /// Merges adjacent runs with identical formatting in all paragraphs of the document body.
17
- /// </summary>
18
- public static RunMergeResult MergeRuns(XDocument document)
19
- {
20
- var body = document.Root?.Element(Ns.W + "body");
21
- if (body == null) return new(0, 0, 0);
22
-
23
- int originalCount = 0;
24
- int removedCount = 0;
25
-
26
- foreach (var paragraph in body.Descendants(Ns.W + "p"))
27
- {
28
- var runs = paragraph.Elements(Ns.W + "r").ToList();
29
- originalCount += runs.Count;
30
-
31
- for (int i = runs.Count - 1; i > 0; i--)
32
- {
33
- var current = runs[i];
34
- var previous = runs[i - 1];
35
-
36
- if (!AreRunPropertiesEqual(previous, current)) continue;
37
-
38
- // Merge text content from current into previous
39
- var prevText = GetOrCreateTextElement(previous);
40
- var currText = current.Element(Ns.W + "t");
41
- if (currText != null && prevText != null)
42
- {
43
- prevText.Value += currText.Value;
44
- // Preserve xml:space="preserve" if either has it
45
- if (currText.Attribute(XNamespace.Xml + "space")?.Value == "preserve" ||
46
- prevText.Value.StartsWith(' ') || prevText.Value.EndsWith(' '))
47
- {
48
- prevText.SetAttributeValue(XNamespace.Xml + "space", "preserve");
49
- }
50
- }
51
-
52
- current.Remove();
53
- removedCount++;
54
- }
55
- }
56
-
57
- return new(originalCount, originalCount - removedCount, 0);
58
- }
59
-
60
- private static bool AreRunPropertiesEqual(XElement run1, XElement run2)
61
- {
62
- var rPr1 = run1.Element(Ns.W + "rPr");
63
- var rPr2 = run2.Element(Ns.W + "rPr");
64
-
65
- if (rPr1 == null && rPr2 == null) return true;
66
- if (rPr1 == null || rPr2 == null) return false;
67
-
68
- return XNode.DeepEquals(rPr1, rPr2);
69
- }
70
-
71
- private static XElement? GetOrCreateTextElement(XElement run)
72
- {
73
- var t = run.Element(Ns.W + "t");
74
- if (t == null)
75
- {
76
- t = new XElement(Ns.W + "t");
77
- run.Add(t);
78
- }
79
- return t;
80
- }
81
- }