wormclaude 1.0.119 → 1.0.121

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 (232) hide show
  1. package/dist/theme.js +1 -1
  2. package/dist/tui.js +6 -1
  3. package/package.json +1 -1
  4. package/skills/build-mcp-app/SKILL.md +0 -393
  5. package/skills/build-mcp-app/references/abuse-protection.md +0 -60
  6. package/skills/build-mcp-app/references/apps-sdk-messages.md +0 -227
  7. package/skills/build-mcp-app/references/directory-checklist.md +0 -18
  8. package/skills/build-mcp-app/references/iframe-sandbox.md +0 -164
  9. package/skills/build-mcp-app/references/payload-budgeting.md +0 -54
  10. package/skills/build-mcp-app/references/widget-templates.md +0 -249
  11. package/skills/build-mcp-server/SKILL.md +0 -222
  12. package/skills/build-mcp-server/references/auth.md +0 -108
  13. package/skills/build-mcp-server/references/deploy-cloudflare-workers.md +0 -106
  14. package/skills/build-mcp-server/references/elicitation.md +0 -129
  15. package/skills/build-mcp-server/references/remote-http-scaffold.md +0 -211
  16. package/skills/build-mcp-server/references/resources-and-prompts.md +0 -122
  17. package/skills/build-mcp-server/references/server-capabilities.md +0 -164
  18. package/skills/build-mcp-server/references/tool-design.md +0 -189
  19. package/skills/build-mcp-server/references/versions.md +0 -25
  20. package/skills/build-mcpb/SKILL.md +0 -200
  21. package/skills/build-mcpb/references/local-security.md +0 -149
  22. package/skills/build-mcpb/references/manifest-schema.md +0 -156
  23. package/skills/docx/script/__init__.py +0 -1
  24. package/skills/docx/script/accept_chages.py +0 -135
  25. package/skills/docx/script/comment.py +0 -318
  26. package/skills/docx/script/office/helpers/__init__.py +0 -0
  27. package/skills/docx/script/office/helpers/merge_runs.py +0 -199
  28. package/skills/docx/script/office/helpers/simplify_redlines.py +0 -197
  29. package/skills/docx/script/office/pack.py +0 -159
  30. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  31. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  32. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  33. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  34. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  35. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  36. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  37. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  38. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  39. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  40. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  41. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  42. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  43. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  44. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  45. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  46. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  47. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  48. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  49. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  50. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  51. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  52. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  53. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  54. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  55. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  56. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  57. package/skills/docx/script/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  58. package/skills/docx/script/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  59. package/skills/docx/script/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  60. package/skills/docx/script/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  61. package/skills/docx/script/office/schemas/mce/mc.xsd +0 -75
  62. package/skills/docx/script/office/schemas/microsoft/wml-2010.xsd +0 -560
  63. package/skills/docx/script/office/schemas/microsoft/wml-2012.xsd +0 -67
  64. package/skills/docx/script/office/schemas/microsoft/wml-2018.xsd +0 -14
  65. package/skills/docx/script/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
  66. package/skills/docx/script/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
  67. package/skills/docx/script/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  68. package/skills/docx/script/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
  69. package/skills/docx/script/office/soffice.py +0 -183
  70. package/skills/docx/script/office/unpack.py +0 -132
  71. package/skills/docx/script/office/validate.py +0 -117
  72. package/skills/docx/script/office/validators/__init__.py +0 -15
  73. package/skills/docx/script/office/validators/base.py +0 -851
  74. package/skills/docx/script/office/validators/docx.py +0 -446
  75. package/skills/docx/script/office/validators/pptx.py +0 -275
  76. package/skills/docx/script/office/validators/redlining.py +0 -247
  77. package/skills/docx/script/templates/comments.xml +0 -3
  78. package/skills/docx/script/templates/commentsExtended.xml +0 -3
  79. package/skills/docx/script/templates/commentsExtensible.xml +0 -3
  80. package/skills/docx/script/templates/commentsIds.xml +0 -3
  81. package/skills/docx/script/templates/people.xml +0 -3
  82. package/skills/docx/skill.md +0 -593
  83. package/skills/explain.md +0 -14
  84. package/skills/frontend-design/SKILL.md +0 -42
  85. package/skills/pdf/FORMS.md +0 -294
  86. package/skills/pdf/REFERENCE.md +0 -612
  87. package/skills/pdf/SKILL.md +0 -314
  88. package/skills/pdf/scripts/check_bounding_boxes.py +0 -65
  89. package/skills/pdf/scripts/check_fillable_fields.py +0 -11
  90. package/skills/pdf/scripts/convert_pdf_to_images.py +0 -33
  91. package/skills/pdf/scripts/create_validation_image.py +0 -37
  92. package/skills/pdf/scripts/extract_form_field_info.py +0 -122
  93. package/skills/pdf/scripts/extract_form_structure.py +0 -115
  94. package/skills/pdf/scripts/fill_fillable_fields.py +0 -98
  95. package/skills/pdf/scripts/fill_pdf_form_with_annotations.py +0 -107
  96. package/skills/playground/SKILL.md +0 -77
  97. package/skills/playground/templates/code-map.md +0 -158
  98. package/skills/playground/templates/concept-map.md +0 -73
  99. package/skills/playground/templates/data-explorer.md +0 -67
  100. package/skills/playground/templates/design-playground.md +0 -67
  101. package/skills/playground/templates/diff-review.md +0 -179
  102. package/skills/playground/templates/document-critique.md +0 -171
  103. package/skills/pptx/SKILL.md +0 -230
  104. package/skills/pptx/editing.md +0 -205
  105. package/skills/pptx/pptxgenjs.md +0 -437
  106. package/skills/pptx/scripts/__init__.py +0 -0
  107. package/skills/pptx/scripts/add_slide.py +0 -195
  108. package/skills/pptx/scripts/clean.py +0 -286
  109. package/skills/pptx/scripts/office/helpers/__init__.py +0 -0
  110. package/skills/pptx/scripts/office/helpers/merge_runs.py +0 -199
  111. package/skills/pptx/scripts/office/helpers/simplify_redlines.py +0 -197
  112. package/skills/pptx/scripts/office/pack.py +0 -159
  113. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  114. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  115. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  116. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  117. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  118. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  119. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  120. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  121. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  122. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  123. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  124. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  125. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  126. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  127. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  128. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  129. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  130. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  131. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  132. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  133. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  134. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  135. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  136. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  137. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  138. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  139. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  140. package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  141. package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  142. package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  143. package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  144. package/skills/pptx/scripts/office/schemas/mce/mc.xsd +0 -75
  145. package/skills/pptx/scripts/office/schemas/microsoft/wml-2010.xsd +0 -560
  146. package/skills/pptx/scripts/office/schemas/microsoft/wml-2012.xsd +0 -67
  147. package/skills/pptx/scripts/office/schemas/microsoft/wml-2018.xsd +0 -14
  148. package/skills/pptx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
  149. package/skills/pptx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
  150. package/skills/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  151. package/skills/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
  152. package/skills/pptx/scripts/office/soffice.py +0 -183
  153. package/skills/pptx/scripts/office/unpack.py +0 -132
  154. package/skills/pptx/scripts/office/validate.py +0 -117
  155. package/skills/pptx/scripts/office/validators/__init__.py +0 -15
  156. package/skills/pptx/scripts/office/validators/base.py +0 -851
  157. package/skills/pptx/scripts/office/validators/docx.py +0 -446
  158. package/skills/pptx/scripts/office/validators/pptx.py +0 -275
  159. package/skills/pptx/scripts/office/validators/redlining.py +0 -247
  160. package/skills/pptx/scripts/thumbnail.py +0 -289
  161. package/skills/recon.md +0 -16
  162. package/skills/security-audit/SKILL.md +0 -26
  163. package/skills/talent-creator/SKILL.md +0 -486
  164. package/skills/talent-creator/agents/analyzer.md +0 -274
  165. package/skills/talent-creator/agents/comparator.md +0 -202
  166. package/skills/talent-creator/agents/grader.md +0 -223
  167. package/skills/talent-creator/assets/eval_review.html +0 -146
  168. package/skills/talent-creator/eval-viewer/generate_review.py +0 -471
  169. package/skills/talent-creator/eval-viewer/viewer.html +0 -1325
  170. package/skills/talent-creator/references/schemas.md +0 -430
  171. package/skills/talent-creator/scripts/__init__.py +0 -0
  172. package/skills/talent-creator/scripts/aggregate_benchmark.py +0 -401
  173. package/skills/talent-creator/scripts/generate_report.py +0 -326
  174. package/skills/talent-creator/scripts/improve_description.py +0 -247
  175. package/skills/talent-creator/scripts/package_skill.py +0 -136
  176. package/skills/talent-creator/scripts/quick_validate.py +0 -146
  177. package/skills/talent-creator/scripts/run_eval.py +0 -310
  178. package/skills/talent-creator/scripts/run_loop.py +0 -328
  179. package/skills/talent-creator/scripts/utils.py +0 -47
  180. package/skills/xlsx/SKILL.md +0 -300
  181. package/skills/xlsx/scripts/office/helpers/__init__.py +0 -0
  182. package/skills/xlsx/scripts/office/helpers/merge_runs.py +0 -199
  183. package/skills/xlsx/scripts/office/helpers/simplify_redlines.py +0 -197
  184. package/skills/xlsx/scripts/office/pack.py +0 -159
  185. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  186. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  187. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  188. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  189. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  190. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  191. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  192. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  193. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  194. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  195. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  196. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  197. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  198. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  199. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  200. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  201. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  202. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  203. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  204. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  205. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  206. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  207. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  208. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  209. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  210. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  211. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  212. package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  213. package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  214. package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  215. package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  216. package/skills/xlsx/scripts/office/schemas/mce/mc.xsd +0 -75
  217. package/skills/xlsx/scripts/office/schemas/microsoft/wml-2010.xsd +0 -560
  218. package/skills/xlsx/scripts/office/schemas/microsoft/wml-2012.xsd +0 -67
  219. package/skills/xlsx/scripts/office/schemas/microsoft/wml-2018.xsd +0 -14
  220. package/skills/xlsx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
  221. package/skills/xlsx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
  222. package/skills/xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  223. package/skills/xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
  224. package/skills/xlsx/scripts/office/soffice.py +0 -183
  225. package/skills/xlsx/scripts/office/unpack.py +0 -132
  226. package/skills/xlsx/scripts/office/validate.py +0 -117
  227. package/skills/xlsx/scripts/office/validators/__init__.py +0 -15
  228. package/skills/xlsx/scripts/office/validators/base.py +0 -851
  229. package/skills/xlsx/scripts/office/validators/docx.py +0 -446
  230. package/skills/xlsx/scripts/office/validators/pptx.py +0 -275
  231. package/skills/xlsx/scripts/office/validators/redlining.py +0 -247
  232. package/skills/xlsx/scripts/recalc.py +0 -184
@@ -1,446 +0,0 @@
1
- """
2
- Validator for Word document XML files against XSD schemas.
3
- """
4
-
5
- import random
6
- import re
7
- import tempfile
8
- import zipfile
9
-
10
- import defusedxml.minidom
11
- import lxml.etree
12
-
13
- from .base import BaseSchemaValidator
14
-
15
-
16
- class DOCXSchemaValidator(BaseSchemaValidator):
17
-
18
- WORD_2006_NAMESPACE = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
19
- W14_NAMESPACE = "http://schemas.microsoft.com/office/word/2010/wordml"
20
- W16CID_NAMESPACE = "http://schemas.microsoft.com/office/word/2016/wordml/cid"
21
-
22
- ELEMENT_RELATIONSHIP_TYPES = {}
23
-
24
- def validate(self):
25
- if not self.validate_xml():
26
- return False
27
-
28
- all_valid = True
29
- if not self.validate_namespaces():
30
- all_valid = False
31
-
32
- if not self.validate_unique_ids():
33
- all_valid = False
34
-
35
- if not self.validate_file_references():
36
- all_valid = False
37
-
38
- if not self.validate_content_types():
39
- all_valid = False
40
-
41
- if not self.validate_against_xsd():
42
- all_valid = False
43
-
44
- if not self.validate_whitespace_preservation():
45
- all_valid = False
46
-
47
- if not self.validate_deletions():
48
- all_valid = False
49
-
50
- if not self.validate_insertions():
51
- all_valid = False
52
-
53
- if not self.validate_all_relationship_ids():
54
- all_valid = False
55
-
56
- if not self.validate_id_constraints():
57
- all_valid = False
58
-
59
- if not self.validate_comment_markers():
60
- all_valid = False
61
-
62
- self.compare_paragraph_counts()
63
-
64
- return all_valid
65
-
66
- def validate_whitespace_preservation(self):
67
- errors = []
68
-
69
- for xml_file in self.xml_files:
70
- if xml_file.name != "document.xml":
71
- continue
72
-
73
- try:
74
- root = lxml.etree.parse(str(xml_file)).getroot()
75
-
76
- for elem in root.iter(f"{{{self.WORD_2006_NAMESPACE}}}t"):
77
- if elem.text:
78
- text = elem.text
79
- if re.search(r"^[ \t\n\r]", text) or re.search(
80
- r"[ \t\n\r]$", text
81
- ):
82
- xml_space_attr = f"{{{self.XML_NAMESPACE}}}space"
83
- if (
84
- xml_space_attr not in elem.attrib
85
- or elem.attrib[xml_space_attr] != "preserve"
86
- ):
87
- text_preview = (
88
- repr(text)[:50] + "..."
89
- if len(repr(text)) > 50
90
- else repr(text)
91
- )
92
- errors.append(
93
- f" {xml_file.relative_to(self.unpacked_dir)}: "
94
- f"Line {elem.sourceline}: w:t element with whitespace missing xml:space='preserve': {text_preview}"
95
- )
96
-
97
- except (lxml.etree.XMLSyntaxError, Exception) as e:
98
- errors.append(
99
- f" {xml_file.relative_to(self.unpacked_dir)}: Error: {e}"
100
- )
101
-
102
- if errors:
103
- print(f"FAILED - Found {len(errors)} whitespace preservation violations:")
104
- for error in errors:
105
- print(error)
106
- return False
107
- else:
108
- if self.verbose:
109
- print("PASSED - All whitespace is properly preserved")
110
- return True
111
-
112
- def validate_deletions(self):
113
- errors = []
114
-
115
- for xml_file in self.xml_files:
116
- if xml_file.name != "document.xml":
117
- continue
118
-
119
- try:
120
- root = lxml.etree.parse(str(xml_file)).getroot()
121
- namespaces = {"w": self.WORD_2006_NAMESPACE}
122
-
123
- for t_elem in root.xpath(".//w:del//w:t", namespaces=namespaces):
124
- if t_elem.text:
125
- text_preview = (
126
- repr(t_elem.text)[:50] + "..."
127
- if len(repr(t_elem.text)) > 50
128
- else repr(t_elem.text)
129
- )
130
- errors.append(
131
- f" {xml_file.relative_to(self.unpacked_dir)}: "
132
- f"Line {t_elem.sourceline}: <w:t> found within <w:del>: {text_preview}"
133
- )
134
-
135
- for instr_elem in root.xpath(
136
- ".//w:del//w:instrText", namespaces=namespaces
137
- ):
138
- text_preview = (
139
- repr(instr_elem.text or "")[:50] + "..."
140
- if len(repr(instr_elem.text or "")) > 50
141
- else repr(instr_elem.text or "")
142
- )
143
- errors.append(
144
- f" {xml_file.relative_to(self.unpacked_dir)}: "
145
- f"Line {instr_elem.sourceline}: <w:instrText> found within <w:del> (use <w:delInstrText>): {text_preview}"
146
- )
147
-
148
- except (lxml.etree.XMLSyntaxError, Exception) as e:
149
- errors.append(
150
- f" {xml_file.relative_to(self.unpacked_dir)}: Error: {e}"
151
- )
152
-
153
- if errors:
154
- print(f"FAILED - Found {len(errors)} deletion validation violations:")
155
- for error in errors:
156
- print(error)
157
- return False
158
- else:
159
- if self.verbose:
160
- print("PASSED - No w:t elements found within w:del elements")
161
- return True
162
-
163
- def count_paragraphs_in_unpacked(self):
164
- count = 0
165
-
166
- for xml_file in self.xml_files:
167
- if xml_file.name != "document.xml":
168
- continue
169
-
170
- try:
171
- root = lxml.etree.parse(str(xml_file)).getroot()
172
- paragraphs = root.findall(f".//{{{self.WORD_2006_NAMESPACE}}}p")
173
- count = len(paragraphs)
174
- except Exception as e:
175
- print(f"Error counting paragraphs in unpacked document: {e}")
176
-
177
- return count
178
-
179
- def count_paragraphs_in_original(self):
180
- original = self.original_file
181
- if original is None:
182
- return 0
183
-
184
- count = 0
185
-
186
- try:
187
- with tempfile.TemporaryDirectory() as temp_dir:
188
- with zipfile.ZipFile(original, "r") as zip_ref:
189
- zip_ref.extractall(temp_dir)
190
-
191
- doc_xml_path = temp_dir + "/word/document.xml"
192
- root = lxml.etree.parse(doc_xml_path).getroot()
193
-
194
- paragraphs = root.findall(f".//{{{self.WORD_2006_NAMESPACE}}}p")
195
- count = len(paragraphs)
196
-
197
- except Exception as e:
198
- print(f"Error counting paragraphs in original document: {e}")
199
-
200
- return count
201
-
202
- def validate_insertions(self):
203
- errors = []
204
-
205
- for xml_file in self.xml_files:
206
- if xml_file.name != "document.xml":
207
- continue
208
-
209
- try:
210
- root = lxml.etree.parse(str(xml_file)).getroot()
211
- namespaces = {"w": self.WORD_2006_NAMESPACE}
212
-
213
- invalid_elements = root.xpath(
214
- ".//w:ins//w:delText[not(ancestor::w:del)]", namespaces=namespaces
215
- )
216
-
217
- for elem in invalid_elements:
218
- text_preview = (
219
- repr(elem.text or "")[:50] + "..."
220
- if len(repr(elem.text or "")) > 50
221
- else repr(elem.text or "")
222
- )
223
- errors.append(
224
- f" {xml_file.relative_to(self.unpacked_dir)}: "
225
- f"Line {elem.sourceline}: <w:delText> within <w:ins>: {text_preview}"
226
- )
227
-
228
- except (lxml.etree.XMLSyntaxError, Exception) as e:
229
- errors.append(
230
- f" {xml_file.relative_to(self.unpacked_dir)}: Error: {e}"
231
- )
232
-
233
- if errors:
234
- print(f"FAILED - Found {len(errors)} insertion validation violations:")
235
- for error in errors:
236
- print(error)
237
- return False
238
- else:
239
- if self.verbose:
240
- print("PASSED - No w:delText elements within w:ins elements")
241
- return True
242
-
243
- def compare_paragraph_counts(self):
244
- original_count = self.count_paragraphs_in_original()
245
- new_count = self.count_paragraphs_in_unpacked()
246
-
247
- diff = new_count - original_count
248
- diff_str = f"+{diff}" if diff > 0 else str(diff)
249
- print(f"\nParagraphs: {original_count} → {new_count} ({diff_str})")
250
-
251
- def _parse_id_value(self, val: str, base: int = 16) -> int:
252
- return int(val, base)
253
-
254
- def validate_id_constraints(self):
255
- errors = []
256
- para_id_attr = f"{{{self.W14_NAMESPACE}}}paraId"
257
- durable_id_attr = f"{{{self.W16CID_NAMESPACE}}}durableId"
258
-
259
- for xml_file in self.xml_files:
260
- try:
261
- for elem in lxml.etree.parse(str(xml_file)).iter():
262
- if val := elem.get(para_id_attr):
263
- if self._parse_id_value(val, base=16) >= 0x80000000:
264
- errors.append(
265
- f" {xml_file.name}:{elem.sourceline}: paraId={val} >= 0x80000000"
266
- )
267
-
268
- if val := elem.get(durable_id_attr):
269
- if xml_file.name == "numbering.xml":
270
- try:
271
- if self._parse_id_value(val, base=10) >= 0x7FFFFFFF:
272
- errors.append(
273
- f" {xml_file.name}:{elem.sourceline}: "
274
- f"durableId={val} >= 0x7FFFFFFF"
275
- )
276
- except ValueError:
277
- errors.append(
278
- f" {xml_file.name}:{elem.sourceline}: "
279
- f"durableId={val} must be decimal in numbering.xml"
280
- )
281
- else:
282
- if self._parse_id_value(val, base=16) >= 0x7FFFFFFF:
283
- errors.append(
284
- f" {xml_file.name}:{elem.sourceline}: "
285
- f"durableId={val} >= 0x7FFFFFFF"
286
- )
287
- except Exception:
288
- pass
289
-
290
- if errors:
291
- print(f"FAILED - {len(errors)} ID constraint violations:")
292
- for e in errors:
293
- print(e)
294
- elif self.verbose:
295
- print("PASSED - All paraId/durableId values within constraints")
296
- return not errors
297
-
298
- def validate_comment_markers(self):
299
- errors = []
300
-
301
- document_xml = None
302
- comments_xml = None
303
- for xml_file in self.xml_files:
304
- if xml_file.name == "document.xml" and "word" in str(xml_file):
305
- document_xml = xml_file
306
- elif xml_file.name == "comments.xml":
307
- comments_xml = xml_file
308
-
309
- if not document_xml:
310
- if self.verbose:
311
- print("PASSED - No document.xml found (skipping comment validation)")
312
- return True
313
-
314
- try:
315
- doc_root = lxml.etree.parse(str(document_xml)).getroot()
316
- namespaces = {"w": self.WORD_2006_NAMESPACE}
317
-
318
- range_starts = {
319
- elem.get(f"{{{self.WORD_2006_NAMESPACE}}}id")
320
- for elem in doc_root.xpath(
321
- ".//w:commentRangeStart", namespaces=namespaces
322
- )
323
- }
324
- range_ends = {
325
- elem.get(f"{{{self.WORD_2006_NAMESPACE}}}id")
326
- for elem in doc_root.xpath(
327
- ".//w:commentRangeEnd", namespaces=namespaces
328
- )
329
- }
330
- references = {
331
- elem.get(f"{{{self.WORD_2006_NAMESPACE}}}id")
332
- for elem in doc_root.xpath(
333
- ".//w:commentReference", namespaces=namespaces
334
- )
335
- }
336
-
337
- orphaned_ends = range_ends - range_starts
338
- for comment_id in sorted(
339
- orphaned_ends, key=lambda x: int(x) if x and x.isdigit() else 0
340
- ):
341
- errors.append(
342
- f' document.xml: commentRangeEnd id="{comment_id}" has no matching commentRangeStart'
343
- )
344
-
345
- orphaned_starts = range_starts - range_ends
346
- for comment_id in sorted(
347
- orphaned_starts, key=lambda x: int(x) if x and x.isdigit() else 0
348
- ):
349
- errors.append(
350
- f' document.xml: commentRangeStart id="{comment_id}" has no matching commentRangeEnd'
351
- )
352
-
353
- comment_ids = set()
354
- if comments_xml and comments_xml.exists():
355
- comments_root = lxml.etree.parse(str(comments_xml)).getroot()
356
- comment_ids = {
357
- elem.get(f"{{{self.WORD_2006_NAMESPACE}}}id")
358
- for elem in comments_root.xpath(
359
- ".//w:comment", namespaces=namespaces
360
- )
361
- }
362
-
363
- marker_ids = range_starts | range_ends | references
364
- invalid_refs = marker_ids - comment_ids
365
- for comment_id in sorted(
366
- invalid_refs, key=lambda x: int(x) if x and x.isdigit() else 0
367
- ):
368
- if comment_id:
369
- errors.append(
370
- f' document.xml: marker id="{comment_id}" references non-existent comment'
371
- )
372
-
373
- except (lxml.etree.XMLSyntaxError, Exception) as e:
374
- errors.append(f" Error parsing XML: {e}")
375
-
376
- if errors:
377
- print(f"FAILED - {len(errors)} comment marker violations:")
378
- for error in errors:
379
- print(error)
380
- return False
381
- else:
382
- if self.verbose:
383
- print("PASSED - All comment markers properly paired")
384
- return True
385
-
386
- def repair(self) -> int:
387
- repairs = super().repair()
388
- repairs += self.repair_durableId()
389
- return repairs
390
-
391
- def repair_durableId(self) -> int:
392
- repairs = 0
393
-
394
- for xml_file in self.xml_files:
395
- try:
396
- content = xml_file.read_text(encoding="utf-8")
397
- dom = defusedxml.minidom.parseString(content)
398
- modified = False
399
-
400
- for elem in dom.getElementsByTagName("*"):
401
- if not elem.hasAttribute("w16cid:durableId"):
402
- continue
403
-
404
- durable_id = elem.getAttribute("w16cid:durableId")
405
- needs_repair = False
406
-
407
- if xml_file.name == "numbering.xml":
408
- try:
409
- needs_repair = (
410
- self._parse_id_value(durable_id, base=10) >= 0x7FFFFFFF
411
- )
412
- except ValueError:
413
- needs_repair = True
414
- else:
415
- try:
416
- needs_repair = (
417
- self._parse_id_value(durable_id, base=16) >= 0x7FFFFFFF
418
- )
419
- except ValueError:
420
- needs_repair = True
421
-
422
- if needs_repair:
423
- value = random.randint(1, 0x7FFFFFFE)
424
- if xml_file.name == "numbering.xml":
425
- new_id = str(value)
426
- else:
427
- new_id = f"{value:08X}"
428
-
429
- elem.setAttribute("w16cid:durableId", new_id)
430
- print(
431
- f" Repaired: {xml_file.name}: durableId {durable_id} → {new_id}"
432
- )
433
- repairs += 1
434
- modified = True
435
-
436
- if modified:
437
- xml_file.write_bytes(dom.toxml(encoding="UTF-8"))
438
-
439
- except Exception:
440
- pass
441
-
442
- return repairs
443
-
444
-
445
- if __name__ == "__main__":
446
- raise RuntimeError("This module should not be run directly.")