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,224 +0,0 @@
1
- using System.IO.Compression;
2
- using System.Xml.Linq;
3
-
4
- namespace Docx.Core.Validation;
5
-
6
- public class BusinessRuleValidator
7
- {
8
- private static readonly XNamespace W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
9
- private static readonly XNamespace R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
10
- private static readonly XNamespace WP = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
11
- private static readonly XNamespace A = "http://schemas.openxmlformats.org/drawingml/2006/main";
12
-
13
- private const int MinMarginDxa = 360; // 0.25 inch
14
- private const int MaxMarginDxa = 4320; // 3 inches
15
- private const int MinBodyFontHps = 16; // 8pt
16
- private const int MaxBodyFontHps = 144; // 72pt
17
- private const int MinHeadingFontHps = 20; // 10pt
18
- private const int MaxHeadingFontHps = 192; // 96pt
19
-
20
- public ValidationResult Validate(string docxPath)
21
- {
22
- var result = new ValidationResult();
23
-
24
- using var zip = ZipFile.OpenRead(docxPath);
25
- var docEntry = zip.GetEntry("word/document.xml")
26
- ?? throw new InvalidOperationException("Missing word/document.xml");
27
-
28
- var doc = LoadXml(docEntry);
29
- var body = doc.Root?.Element(W + "body");
30
- if (body == null)
31
- {
32
- result.Errors.Add(Error("Document has no body element"));
33
- return result;
34
- }
35
-
36
- ValidateMargins(body, result);
37
- ValidateFontSizes(body, result);
38
- ValidateHeadingHierarchy(body, result);
39
- ValidateTableColumnWidths(body, result);
40
- ValidateRelationships(zip, doc, result);
41
- ValidateComments(zip, result);
42
-
43
- return result;
44
- }
45
-
46
- private void ValidateMargins(XElement body, ValidationResult result)
47
- {
48
- foreach (var sectPr in body.Descendants(W + "sectPr"))
49
- {
50
- var pgMar = sectPr.Element(W + "pgMar");
51
- if (pgMar == null) continue;
52
-
53
- foreach (var attr in new[] { "top", "bottom", "left", "right" })
54
- {
55
- var val = (string?)pgMar.Attribute(W + attr);
56
- if (val != null && int.TryParse(val, out var dxa))
57
- {
58
- var absDxa = Math.Abs(dxa);
59
- if (absDxa < MinMarginDxa)
60
- result.Errors.Add(Error($"Margin '{attr}' is {absDxa} DXA ({absDxa / 1440.0:F2}\"), below minimum {MinMarginDxa} DXA"));
61
- if (absDxa > MaxMarginDxa)
62
- result.Warnings.Add(Warning($"Margin '{attr}' is {absDxa} DXA ({absDxa / 1440.0:F2}\"), above maximum {MaxMarginDxa} DXA"));
63
- }
64
- }
65
- }
66
- }
67
-
68
- private void ValidateFontSizes(XElement body, ValidationResult result)
69
- {
70
- foreach (var p in body.Descendants(W + "p"))
71
- {
72
- var pStyle = p.Element(W + "pPr")?.Element(W + "pStyle")?.Attribute(W + "val")?.Value;
73
- bool isHeading = pStyle?.StartsWith("Heading", StringComparison.OrdinalIgnoreCase) == true;
74
-
75
- foreach (var rPr in p.Descendants(W + "rPr"))
76
- {
77
- var szEl = rPr.Element(W + "sz");
78
- var val = (string?)szEl?.Attribute(W + "val");
79
- if (val != null && int.TryParse(val, out var hps))
80
- {
81
- int min = isHeading ? MinHeadingFontHps : MinBodyFontHps;
82
- int max = isHeading ? MaxHeadingFontHps : MaxBodyFontHps;
83
- if (hps < min || hps > max)
84
- result.Warnings.Add(Warning($"Font size {hps / 2.0}pt is outside {(isHeading ? "heading" : "body")} range ({min / 2}-{max / 2}pt)"));
85
- }
86
- }
87
- }
88
- }
89
-
90
- private void ValidateHeadingHierarchy(XElement body, ValidationResult result)
91
- {
92
- int lastLevel = 0;
93
- foreach (var p in body.Descendants(W + "p"))
94
- {
95
- var pStyle = p.Element(W + "pPr")?.Element(W + "pStyle")?.Attribute(W + "val")?.Value;
96
- if (pStyle == null) continue;
97
-
98
- int level = 0;
99
- if (pStyle.StartsWith("Heading", StringComparison.OrdinalIgnoreCase))
100
- {
101
- var numPart = pStyle.AsSpan(7);
102
- if (int.TryParse(numPart, out var parsed)) level = parsed;
103
- }
104
-
105
- if (level > 0)
106
- {
107
- if (lastLevel > 0 && level > lastLevel + 1)
108
- result.Warnings.Add(Warning($"Heading level skips from {lastLevel} to {level} (missing Heading{lastLevel + 1})"));
109
- lastLevel = level;
110
- }
111
- }
112
- }
113
-
114
- private void ValidateTableColumnWidths(XElement body, ValidationResult result)
115
- {
116
- var sectPr = body.Element(W + "sectPr");
117
- if (sectPr == null) return;
118
-
119
- var pgSz = sectPr.Element(W + "pgSz");
120
- var pgMar = sectPr.Element(W + "pgMar");
121
- if (pgSz == null || pgMar == null) return;
122
-
123
- if (!int.TryParse((string?)pgSz.Attribute(W + "w"), out var pageWidth)) return;
124
- int.TryParse((string?)pgMar.Attribute(W + "left"), out var marginLeft);
125
- int.TryParse((string?)pgMar.Attribute(W + "right"), out var marginRight);
126
- var contentWidth = pageWidth - marginLeft - marginRight;
127
-
128
- int tableIndex = 0;
129
- foreach (var tbl in body.Descendants(W + "tbl"))
130
- {
131
- tableIndex++;
132
- var firstRow = tbl.Element(W + "tr");
133
- if (firstRow == null) continue;
134
-
135
- int totalWidth = 0;
136
- foreach (var tc in firstRow.Elements(W + "tc"))
137
- {
138
- var tcW = tc.Element(W + "tcPr")?.Element(W + "tcW");
139
- var w = (string?)tcW?.Attribute(W + "w");
140
- if (w != null && int.TryParse(w, out var cellWidth))
141
- totalWidth += cellWidth;
142
- }
143
-
144
- if (totalWidth > 0)
145
- {
146
- var tolerance = contentWidth * 0.02;
147
- if (Math.Abs(totalWidth - contentWidth) > tolerance)
148
- result.Warnings.Add(Warning($"Table {tableIndex}: column widths sum to {totalWidth} DXA but content width is {contentWidth} DXA"));
149
- }
150
- }
151
- }
152
-
153
- private void ValidateRelationships(ZipArchive zip, XDocument doc, ValidationResult result)
154
- {
155
- var relsEntry = zip.GetEntry("word/_rels/document.xml.rels");
156
- if (relsEntry == null) return;
157
-
158
- var relDoc = LoadXml(relsEntry);
159
- var ns = relDoc.Root?.Name.Namespace ?? XNamespace.None;
160
- var definedIds = new HashSet<string>();
161
-
162
- foreach (var rel in relDoc.Descendants(ns + "Relationship"))
163
- {
164
- var id = (string?)rel.Attribute("Id");
165
- if (id != null) definedIds.Add(id);
166
- }
167
-
168
- var referencedIds = new HashSet<string>();
169
- foreach (var el in doc.Descendants())
170
- {
171
- var rid = (string?)el.Attribute(R + "id") ?? (string?)el.Attribute(R + "embed");
172
- if (rid != null) referencedIds.Add(rid);
173
- }
174
-
175
- foreach (var id in referencedIds.Except(definedIds))
176
- result.Errors.Add(Error($"Reference r:id='{id}' has no matching relationship"));
177
-
178
- foreach (var id in definedIds.Except(referencedIds))
179
- result.Warnings.Add(Warning($"Orphaned relationship: Id='{id}' is defined but never referenced"));
180
- }
181
-
182
- private void ValidateComments(ZipArchive zip, ValidationResult result)
183
- {
184
- var commentFiles = new[] { "word/comments.xml", "word/commentsExtended.xml", "word/commentsIds.xml", "word/commentsExtensible.xml" };
185
- var existing = commentFiles.Where(f => zip.GetEntry(f) != null).ToList();
186
-
187
- if (existing.Count > 0 && existing.Count < 4)
188
- {
189
- var missing = commentFiles.Except(existing);
190
- result.Warnings.Add(Warning($"Comments partially present. Missing: {string.Join(", ", missing)}"));
191
- }
192
-
193
- if (zip.GetEntry("word/comments.xml") is { } commentsEntry)
194
- {
195
- var commentsDoc = LoadXml(commentsEntry);
196
- var commentIds = commentsDoc.Descendants(W + "comment")
197
- .Select(c => (string?)c.Attribute(W + "id"))
198
- .Where(id => id != null)
199
- .ToHashSet();
200
-
201
- if (zip.GetEntry("word/commentsExtended.xml") is { } extEntry)
202
- {
203
- var W15 = XNamespace.Get("http://schemas.microsoft.com/office/word/2012/wordml");
204
- var extDoc = LoadXml(extEntry);
205
- var extIds = extDoc.Descendants(W15 + "commentEx")
206
- .Select(c => (string?)c.Attribute(W15 + "paraId"))
207
- .Where(id => id != null)
208
- .ToHashSet();
209
-
210
- if (commentIds.Count > 0 && extIds.Count == 0)
211
- result.Warnings.Add(Warning("comments.xml has entries but commentsExtended.xml has none"));
212
- }
213
- }
214
- }
215
-
216
- private static XDocument LoadXml(ZipArchiveEntry entry)
217
- {
218
- using var stream = entry.Open();
219
- return XDocument.Load(stream);
220
- }
221
-
222
- private static ValidationError Error(string msg) => new() { Message = msg, Severity = "Error" };
223
- private static ValidationError Warning(string msg) => new() { Message = msg, Severity = "Warning" };
224
- }
@@ -1,148 +0,0 @@
1
- using System.IO.Compression;
2
- using System.Xml.Linq;
3
-
4
- namespace Docx.Core.Validation;
5
-
6
- public class GateCheckResult
7
- {
8
- public bool Passed => Violations.Count == 0;
9
- public List<string> Violations { get; set; } = new();
10
- }
11
-
12
- public class GateCheckValidator
13
- {
14
- private static readonly XNamespace W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
15
-
16
- public GateCheckResult Validate(string outputDocxPath, string templateDocxPath)
17
- {
18
- var result = new GateCheckResult();
19
-
20
- var templateStyles = ExtractStyles(templateDocxPath);
21
- var outputStyles = ExtractStyles(outputDocxPath);
22
- var templateSectPr = ExtractSectionProperties(templateDocxPath);
23
- var outputSectPr = ExtractSectionProperties(outputDocxPath);
24
-
25
- // All template styles must exist in output
26
- foreach (var style in templateStyles)
27
- {
28
- if (!outputStyles.Contains(style))
29
- result.Violations.Add($"Missing style: '{style}' defined in template but absent from output");
30
- }
31
-
32
- // Page margins must match
33
- if (templateSectPr.Margins != null && outputSectPr.Margins != null)
34
- {
35
- var tm = templateSectPr.Margins;
36
- var om = outputSectPr.Margins;
37
- if (tm.Top != om.Top || tm.Bottom != om.Bottom || tm.Left != om.Left || tm.Right != om.Right)
38
- result.Violations.Add($"Page margins mismatch: template=({tm.Top},{tm.Bottom},{tm.Left},{tm.Right}) output=({om.Top},{om.Bottom},{om.Left},{om.Right})");
39
- }
40
-
41
- // Page size must match
42
- if (templateSectPr.PageWidth != outputSectPr.PageWidth || templateSectPr.PageHeight != outputSectPr.PageHeight)
43
- result.Violations.Add($"Page size mismatch: template=({templateSectPr.PageWidth}x{templateSectPr.PageHeight}) output=({outputSectPr.PageWidth}x{outputSectPr.PageHeight})");
44
-
45
- // Default font must match
46
- var templateFont = ExtractDefaultFont(templateDocxPath);
47
- var outputFont = ExtractDefaultFont(outputDocxPath);
48
- if (templateFont != null && outputFont != null && templateFont != outputFont)
49
- result.Violations.Add($"Default font mismatch: template='{templateFont}' output='{outputFont}'");
50
-
51
- // Heading font hierarchy consistency
52
- ValidateHeadingFontHierarchy(outputDocxPath, result);
53
-
54
- return result;
55
- }
56
-
57
- private HashSet<string> ExtractStyles(string docxPath)
58
- {
59
- using var zip = ZipFile.OpenRead(docxPath);
60
- var entry = zip.GetEntry("word/styles.xml");
61
- if (entry == null) return new();
62
-
63
- using var stream = entry.Open();
64
- var doc = XDocument.Load(stream);
65
- return doc.Descendants(W + "style")
66
- .Select(s => (string?)s.Attribute(W + "styleId"))
67
- .Where(id => id != null)
68
- .ToHashSet()!;
69
- }
70
-
71
- private record SectionProps(int PageWidth, int PageHeight, MarginInfo? Margins);
72
- private record MarginInfo(int Top, int Bottom, int Left, int Right);
73
-
74
- private SectionProps ExtractSectionProperties(string docxPath)
75
- {
76
- using var zip = ZipFile.OpenRead(docxPath);
77
- var entry = zip.GetEntry("word/document.xml")!;
78
- using var stream = entry.Open();
79
- var doc = XDocument.Load(stream);
80
-
81
- var sectPr = doc.Descendants(W + "sectPr").LastOrDefault();
82
- if (sectPr == null) return new(0, 0, null);
83
-
84
- int.TryParse((string?)sectPr.Element(W + "pgSz")?.Attribute(W + "w"), out var pw);
85
- int.TryParse((string?)sectPr.Element(W + "pgSz")?.Attribute(W + "h"), out var ph);
86
-
87
- var pgMar = sectPr.Element(W + "pgMar");
88
- MarginInfo? margins = null;
89
- if (pgMar != null)
90
- {
91
- int.TryParse((string?)pgMar.Attribute(W + "top"), out var t);
92
- int.TryParse((string?)pgMar.Attribute(W + "bottom"), out var b);
93
- int.TryParse((string?)pgMar.Attribute(W + "left"), out var l);
94
- int.TryParse((string?)pgMar.Attribute(W + "right"), out var r);
95
- margins = new(t, b, l, r);
96
- }
97
-
98
- return new(pw, ph, margins);
99
- }
100
-
101
- private string? ExtractDefaultFont(string docxPath)
102
- {
103
- using var zip = ZipFile.OpenRead(docxPath);
104
- var entry = zip.GetEntry("word/styles.xml");
105
- if (entry == null) return null;
106
-
107
- using var stream = entry.Open();
108
- var doc = XDocument.Load(stream);
109
-
110
- var defaultStyle = doc.Descendants(W + "style")
111
- .FirstOrDefault(s => (string?)s.Attribute(W + "type") == "paragraph"
112
- && (string?)s.Attribute(W + "default") == "1");
113
-
114
- return (string?)defaultStyle?.Descendants(W + "rFonts").FirstOrDefault()?.Attribute(W + "ascii");
115
- }
116
-
117
- private void ValidateHeadingFontHierarchy(string docxPath, GateCheckResult result)
118
- {
119
- using var zip = ZipFile.OpenRead(docxPath);
120
- var entry = zip.GetEntry("word/styles.xml");
121
- if (entry == null) return;
122
-
123
- using var stream = entry.Open();
124
- var doc = XDocument.Load(stream);
125
-
126
- var headingSizes = new SortedDictionary<int, int>();
127
- foreach (var style in doc.Descendants(W + "style"))
128
- {
129
- var id = (string?)style.Attribute(W + "styleId");
130
- if (id == null || !id.StartsWith("Heading", StringComparison.OrdinalIgnoreCase)) continue;
131
-
132
- var numPart = id.AsSpan(7);
133
- if (!int.TryParse(numPart, out var level)) continue;
134
-
135
- var sz = (string?)style.Descendants(W + "sz").FirstOrDefault()?.Attribute(W + "val");
136
- if (sz != null && int.TryParse(sz, out var hps))
137
- headingSizes[level] = hps;
138
- }
139
-
140
- int prevSize = int.MaxValue;
141
- foreach (var (level, size) in headingSizes)
142
- {
143
- if (size > prevSize)
144
- result.Violations.Add($"Heading{level} ({size / 2}pt) is larger than a higher-level heading ({prevSize / 2}pt)");
145
- prevSize = size;
146
- }
147
- }
148
- }
@@ -1,23 +0,0 @@
1
- namespace Docx.Core.Validation;
2
-
3
- public class ValidationResult
4
- {
5
- public bool IsValid => Errors.Count == 0;
6
- public List<ValidationError> Errors { get; set; } = new();
7
- public List<ValidationError> Warnings { get; set; } = new();
8
-
9
- public void Merge(ValidationResult other)
10
- {
11
- Errors.AddRange(other.Errors);
12
- Warnings.AddRange(other.Warnings);
13
- }
14
- }
15
-
16
- public class ValidationError
17
- {
18
- public int LineNumber { get; set; }
19
- public int LinePosition { get; set; }
20
- public string Element { get; set; } = "";
21
- public string Message { get; set; } = "";
22
- public string Severity { get; set; } = "Error";
23
- }
@@ -1,69 +0,0 @@
1
- using System.IO.Compression;
2
- using System.Xml;
3
- using System.Xml.Schema;
4
-
5
- namespace Docx.Core.Validation;
6
-
7
- public class XsdValidator
8
- {
9
- public ValidationResult Validate(string docxPath, string xsdPath)
10
- {
11
- using var zip = ZipFile.OpenRead(docxPath);
12
- var entry = zip.GetEntry("word/document.xml")
13
- ?? throw new InvalidOperationException("DOCX does not contain word/document.xml");
14
-
15
- using var stream = entry.Open();
16
- using var reader = new StreamReader(stream);
17
- var xmlContent = reader.ReadToEnd();
18
-
19
- return ValidateXml(xmlContent, xsdPath);
20
- }
21
-
22
- public ValidationResult ValidateXml(string xmlContent, string xsdPath)
23
- {
24
- var result = new ValidationResult();
25
- var settings = new XmlReaderSettings();
26
-
27
- var schemaSet = new XmlSchemaSet();
28
- schemaSet.Add(null, xsdPath);
29
- settings.Schemas = schemaSet;
30
- settings.ValidationType = ValidationType.Schema;
31
- settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
32
-
33
- settings.ValidationEventHandler += (sender, e) =>
34
- {
35
- var error = new ValidationError
36
- {
37
- LineNumber = e.Exception?.LineNumber ?? 0,
38
- LinePosition = e.Exception?.LinePosition ?? 0,
39
- Message = e.Message,
40
- Severity = e.Severity == XmlSeverityType.Warning ? "Warning" : "Error"
41
- };
42
-
43
- if (e.Severity == XmlSeverityType.Warning)
44
- result.Warnings.Add(error);
45
- else
46
- result.Errors.Add(error);
47
- };
48
-
49
- using var stringReader = new StringReader(xmlContent);
50
- using var xmlReader = XmlReader.Create(stringReader, settings);
51
-
52
- try
53
- {
54
- while (xmlReader.Read()) { }
55
- }
56
- catch (XmlException ex)
57
- {
58
- result.Errors.Add(new ValidationError
59
- {
60
- LineNumber = ex.LineNumber,
61
- LinePosition = ex.LinePosition,
62
- Message = $"XML parse error: {ex.Message}",
63
- Severity = "Error"
64
- });
65
- }
66
-
67
- return result;
68
- }
69
- }
@@ -1,4 +0,0 @@
1
- <Solution>
2
- <Project Path="Docx.Cli/Docx.Cli.csproj" />
3
- <Project Path="Docx.Core/Docx.Core.csproj" />
4
- </Solution>
@@ -1,196 +0,0 @@
1
- #!/usr/bin/env bash
2
- # docx Quick Environment Check
3
- # Cross-platform: macOS, Linux, WSL, Git Bash
4
- # Run this BEFORE any docx operation. Use setup.sh for initial installation.
5
- set -euo pipefail
6
-
7
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
- PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
9
- DOTNET_DIR="$SCRIPT_DIR/dotnet"
10
-
11
- # Force English output for dotnet CLI
12
- export DOTNET_CLI_UI_LANGUAGE=en
13
-
14
- echo "=== docx Environment Check ==="
15
- echo ""
16
-
17
- STATUS="READY"
18
- WARNINGS=0
19
-
20
- # --- Detect platform ---
21
- OS="unknown"
22
- case "$(uname -s)" in
23
- Darwin) OS="macos" ;;
24
- Linux)
25
- OS="linux"
26
- grep -qi microsoft /proc/version 2>/dev/null && OS="wsl"
27
- ;;
28
- MINGW*|MSYS*|CYGWIN*) OS="windows-shell" ;;
29
- esac
30
-
31
- # --- Critical: .NET SDK ---
32
- if ! command -v dotnet &>/dev/null; then
33
- printf "[FAIL] %-14s not found\n" "dotnet"
34
- echo ""
35
- echo " .NET SDK is REQUIRED. Install it:"
36
- case "$OS" in
37
- macos) echo " brew install --cask dotnet-sdk" ;;
38
- linux|wsl)
39
- echo " # Option 1: Microsoft install script"
40
- echo " wget https://dot.net/v1/dotnet-install.sh -O /tmp/dotnet-install.sh"
41
- echo " chmod +x /tmp/dotnet-install.sh && /tmp/dotnet-install.sh --channel 8.0"
42
- echo " # Option 2 (Ubuntu/Debian): sudo apt-get install -y dotnet-sdk-8.0"
43
- ;;
44
- windows-shell) echo " winget install Microsoft.DotNet.SDK.8" ;;
45
- *) echo " https://dotnet.microsoft.com/download" ;;
46
- esac
47
- echo ""
48
- echo " Or run the full setup: bash scripts/setup.sh"
49
- echo ""
50
- STATUS="NOT READY"
51
- else
52
- local_ver=$(dotnet --version 2>/dev/null || echo "0.0.0")
53
- local_major="${local_ver%%.*}"
54
- if [ "$local_major" -ge 8 ] 2>/dev/null; then
55
- printf "[OK] %-14s %s (>= 8.0)\n" "dotnet" "$local_ver"
56
- else
57
- printf "[FAIL] %-14s %s (requires >= 8.0)\n" "dotnet" "$local_ver"
58
- STATUS="NOT READY"
59
- fi
60
- fi
61
-
62
- # --- Critical: NuGet packages ---
63
- if [ -d "$DOTNET_DIR" ]; then
64
- if [ -f "$DOTNET_DIR/Docx.Cli/bin/Debug/net10.0/Docx.Cli.dll" ] || \
65
- [ -f "$DOTNET_DIR/Docx.Cli/bin/Debug/net8.0/Docx.Cli.dll" ]; then
66
- printf "[OK] %-14s built\n" "project"
67
- else
68
- # Try restore + build
69
- if dotnet restore "$DOTNET_DIR" --verbosity quiet &>/dev/null; then
70
- printf "[OK] %-14s packages restored\n" "nuget"
71
- if dotnet build "$DOTNET_DIR" --verbosity quiet --no-restore &>/dev/null; then
72
- printf "[OK] %-14s build succeeded\n" "project"
73
- else
74
- printf "[FAIL] %-14s build failed (run: dotnet build %s)\n" "project" "$DOTNET_DIR"
75
- STATUS="NOT READY"
76
- fi
77
- else
78
- printf "[FAIL] %-14s restore failed\n" "nuget"
79
- echo ""
80
- echo " Common causes:"
81
- echo " - No internet access (NuGet needs to download packages)"
82
- echo " - Corporate proxy blocking nuget.org"
83
- echo " - SSL certificate issues (try: dotnet nuget list source)"
84
- echo ""
85
- STATUS="NOT READY"
86
- fi
87
- fi
88
- else
89
- printf "[FAIL] %-14s directory not found: %s\n" "project" "$DOTNET_DIR"
90
- STATUS="NOT READY"
91
- fi
92
-
93
- # --- Optional: pandoc ---
94
- if command -v pandoc &>/dev/null; then
95
- pandoc_ver=$(pandoc --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+(\.[0-9]+)?' | head -1 || echo "?")
96
- printf "[OK] %-14s %s (content preview)\n" "pandoc" "$pandoc_ver"
97
- else
98
- printf "[WARN] %-14s not found — docx_preview.sh will use fallback\n" "pandoc"
99
- WARNINGS=$((WARNINGS + 1))
100
- case "$OS" in
101
- macos) echo " Install: brew install pandoc" ;;
102
- linux|wsl) echo " Install: sudo apt-get install pandoc # or dnf/pacman" ;;
103
- windows-shell) echo " Install: winget install JohnMacFarlane.Pandoc" ;;
104
- esac
105
- fi
106
-
107
- # --- Optional: LibreOffice ---
108
- if command -v soffice &>/dev/null; then
109
- soffice_ver=$(soffice --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+(\.[0-9]+)?' | head -1 || echo "?")
110
- printf "[OK] %-14s %s (.doc conversion)\n" "soffice" "$soffice_ver"
111
- else
112
- # Check common paths
113
- soffice_found=false
114
- for p in \
115
- "/Applications/LibreOffice.app/Contents/MacOS/soffice" \
116
- "/usr/lib/libreoffice/program/soffice" \
117
- "/snap/bin/libreoffice" \
118
- "/opt/libreoffice/program/soffice"; do
119
- if [ -x "$p" ]; then
120
- printf "[OK] %-14s found at %s (.doc conversion)\n" "soffice" "$p"
121
- soffice_found=true
122
- break
123
- fi
124
- done
125
- if ! $soffice_found; then
126
- printf "[WARN] %-14s not found — .doc files cannot be converted\n" "soffice"
127
- WARNINGS=$((WARNINGS + 1))
128
- case "$OS" in
129
- macos) echo " Install: brew install --cask libreoffice" ;;
130
- linux|wsl) echo " Install: sudo apt-get install libreoffice-core" ;;
131
- windows-shell) echo " Install: winget install TheDocumentFoundation.LibreOffice" ;;
132
- esac
133
- fi
134
- fi
135
-
136
- # --- Optional: zip/unzip ---
137
- zip_ok=true
138
- if ! command -v zip &>/dev/null; then
139
- printf "[WARN] %-14s not found (optional, .NET handles DOCX natively)\n" "zip"
140
- zip_ok=false
141
- WARNINGS=$((WARNINGS + 1))
142
- fi
143
- if ! command -v unzip &>/dev/null; then
144
- printf "[WARN] %-14s not found (optional, .NET handles DOCX natively)\n" "unzip"
145
- zip_ok=false
146
- WARNINGS=$((WARNINGS + 1))
147
- fi
148
- if $zip_ok; then
149
- printf "[OK] %-14s available\n" "zip/unzip"
150
- fi
151
-
152
- # --- Encoding check ---
153
- current_lang="${LANG:-}"
154
- if [ -n "$current_lang" ] && echo "$current_lang" | grep -qi "utf-8\|utf8"; then
155
- printf "[OK] %-14s %s\n" "locale" "$current_lang"
156
- else
157
- if [ -z "$current_lang" ]; then
158
- printf "[WARN] %-14s LANG not set (CJK text may have issues)\n" "locale"
159
- else
160
- printf "[WARN] %-14s %s (not UTF-8, CJK text may have issues)\n" "locale" "$current_lang"
161
- fi
162
- WARNINGS=$((WARNINGS + 1))
163
- echo " Fix: export LANG=en_US.UTF-8"
164
- fi
165
-
166
- # --- Shell script permissions ---
167
- perm_issues=0
168
- for s in "$SCRIPT_DIR"/*.sh; do
169
- if [ -f "$s" ] && [ ! -x "$s" ]; then
170
- perm_issues=$((perm_issues + 1))
171
- fi
172
- done
173
- if [ "$perm_issues" -gt 0 ]; then
174
- printf "[WARN] %-14s %d script(s) not executable\n" "permissions" "$perm_issues"
175
- echo " Fix: chmod +x scripts/*.sh"
176
- WARNINGS=$((WARNINGS + 1))
177
- else
178
- printf "[OK] %-14s all scripts executable\n" "permissions"
179
- fi
180
-
181
- # --- Result ---
182
- echo ""
183
- if [ "$STATUS" = "READY" ]; then
184
- if [ "$WARNINGS" -gt 0 ]; then
185
- echo "Status: READY (with $WARNINGS warning(s) — optional features may be limited)"
186
- else
187
- echo "Status: READY"
188
- fi
189
- else
190
- echo "Status: NOT READY"
191
- echo ""
192
- echo "Critical dependencies missing. Run the full setup:"
193
- echo " bash scripts/setup.sh # macOS / Linux / WSL"
194
- echo " powershell scripts/setup.ps1 # Windows PowerShell"
195
- exit 1
196
- fi