@nguyenphp/antigravity-marketing 1.0.18 → 1.0.19

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 (127) hide show
  1. package/README.md +186 -78
  2. package/package.json +4 -3
  3. package/templates/.agent/skills/marketing-report-expert/SKILL.md +70 -0
  4. package/templates/.agent/skills/minimax-docx/LICENSE +21 -0
  5. package/templates/.agent/skills/minimax-docx/SKILL.md +274 -0
  6. package/templates/.agent/skills/minimax-docx/assets/styles/academic_styles.xml +250 -0
  7. package/templates/.agent/skills/minimax-docx/assets/styles/corporate_styles.xml +284 -0
  8. package/templates/.agent/skills/minimax-docx/assets/styles/default_styles.xml +449 -0
  9. package/templates/.agent/skills/minimax-docx/assets/xsd/aesthetic-rules.xsd +470 -0
  10. package/templates/.agent/skills/minimax-docx/assets/xsd/business-rules.xsd +130 -0
  11. package/templates/.agent/skills/minimax-docx/assets/xsd/common-types.xsd +159 -0
  12. package/templates/.agent/skills/minimax-docx/assets/xsd/wml-subset.xsd +589 -0
  13. package/templates/.agent/skills/minimax-docx/references/cjk_typography.md +357 -0
  14. package/templates/.agent/skills/minimax-docx/references/cjk_university_template_guide.md +184 -0
  15. package/templates/.agent/skills/minimax-docx/references/comments_guide.md +191 -0
  16. package/templates/.agent/skills/minimax-docx/references/design_good_bad_examples.md +829 -0
  17. package/templates/.agent/skills/minimax-docx/references/design_principles.md +819 -0
  18. package/templates/.agent/skills/minimax-docx/references/openxml_element_order.md +308 -0
  19. package/templates/.agent/skills/minimax-docx/references/openxml_encyclopedia_part1.md +4061 -0
  20. package/templates/.agent/skills/minimax-docx/references/openxml_encyclopedia_part2.md +2820 -0
  21. package/templates/.agent/skills/minimax-docx/references/openxml_encyclopedia_part3.md +3381 -0
  22. package/templates/.agent/skills/minimax-docx/references/openxml_namespaces.md +82 -0
  23. package/templates/.agent/skills/minimax-docx/references/openxml_units.md +72 -0
  24. package/templates/.agent/skills/minimax-docx/references/scenario_a_create.md +284 -0
  25. package/templates/.agent/skills/minimax-docx/references/scenario_b_edit_content.md +295 -0
  26. package/templates/.agent/skills/minimax-docx/references/scenario_c_apply_template.md +456 -0
  27. package/templates/.agent/skills/minimax-docx/references/track_changes_guide.md +200 -0
  28. package/templates/.agent/skills/minimax-docx/references/troubleshooting.md +506 -0
  29. package/templates/.agent/skills/minimax-docx/references/typography_guide.md +294 -0
  30. package/templates/.agent/skills/minimax-docx/references/xsd_validation_guide.md +158 -0
  31. package/templates/.agent/skills/minimax-docx/scripts/doc_to_docx.sh +40 -0
  32. package/templates/.agent/skills/minimax-docx/scripts/docx_preview.sh +37 -0
  33. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Cli/MiniMaxAIDocx.Cli.csproj +19 -0
  34. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Cli/Program.cs +18 -0
  35. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/AnalyzeCommand.cs +147 -0
  36. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/ApplyTemplateCommand.cs +322 -0
  37. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/CreateCommand.cs +324 -0
  38. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/DiffCommand.cs +155 -0
  39. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/EditContentCommand.cs +487 -0
  40. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/FixOrderCommand.cs +108 -0
  41. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/MergeRunsCommand.cs +122 -0
  42. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/ValidateCommand.cs +107 -0
  43. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/MiniMaxAIDocx.Core.csproj +15 -0
  44. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/CommentSynchronizer.cs +169 -0
  45. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/ElementOrder.cs +80 -0
  46. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/NamespaceConstants.cs +42 -0
  47. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/RunMerger.cs +81 -0
  48. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/StyleAnalyzer.cs +81 -0
  49. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/TrackChangesHelper.cs +99 -0
  50. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/UnitConverter.cs +23 -0
  51. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples.cs +1832 -0
  52. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch1.cs +910 -0
  53. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch2.cs +999 -0
  54. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch3.cs +1048 -0
  55. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch4.cs +1038 -0
  56. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/CharacterFormattingSamples.cs +1020 -0
  57. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/DocumentCreationSamples.cs +1121 -0
  58. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/FieldAndTocSamples.cs +624 -0
  59. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/FootnoteAndCommentSamples.cs +675 -0
  60. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/HeaderFooterSamples.cs +838 -0
  61. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/ImageSamples.cs +917 -0
  62. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/ListAndNumberingSamples.cs +826 -0
  63. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/ParagraphFormattingSamples.cs +1199 -0
  64. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/StyleSystemSamples.cs +1487 -0
  65. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/TableSamples.cs +1163 -0
  66. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/TrackChangesSamples.cs +595 -0
  67. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Typography/CjkHelper.cs +39 -0
  68. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Typography/FontDefaults.cs +24 -0
  69. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Typography/PageSizes.cs +20 -0
  70. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/BusinessRuleValidator.cs +224 -0
  71. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/GateCheckValidator.cs +148 -0
  72. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/ValidationResult.cs +23 -0
  73. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/XsdValidator.cs +69 -0
  74. package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.slnx +4 -0
  75. package/templates/.agent/skills/minimax-docx/scripts/env_check.sh +196 -0
  76. package/templates/.agent/skills/minimax-docx/scripts/setup.ps1 +274 -0
  77. package/templates/.agent/skills/minimax-docx/scripts/setup.sh +504 -0
  78. package/templates/.agent/skills/minimax-multimodal-toolkit/SKILL.md +359 -0
  79. package/templates/.agent/skills/minimax-pdf/README.md +222 -0
  80. package/templates/.agent/skills/minimax-pdf/SKILL.md +201 -0
  81. package/templates/.agent/skills/minimax-pdf/design/design.md +381 -0
  82. package/templates/.agent/skills/minimax-pdf/scripts/cover.py +1579 -0
  83. package/templates/.agent/skills/minimax-pdf/scripts/fill_inspect.py +200 -0
  84. package/templates/.agent/skills/minimax-pdf/scripts/fill_write.py +242 -0
  85. package/templates/.agent/skills/minimax-pdf/scripts/make.sh +491 -0
  86. package/templates/.agent/skills/minimax-pdf/scripts/merge.py +112 -0
  87. package/templates/.agent/skills/minimax-pdf/scripts/palette.py +559 -0
  88. package/templates/.agent/skills/minimax-pdf/scripts/reformat_parse.py +374 -0
  89. package/templates/.agent/skills/minimax-pdf/scripts/render_body.py +1055 -0
  90. package/templates/.agent/skills/minimax-pdf/scripts/render_cover.cjs +111 -0
  91. package/templates/.agent/skills/minimax-xlsx/SKILL.md +138 -0
  92. package/templates/.agent/skills/minimax-xlsx/references/create.md +691 -0
  93. package/templates/.agent/skills/minimax-xlsx/references/edit.md +684 -0
  94. package/templates/.agent/skills/minimax-xlsx/references/fix.md +37 -0
  95. package/templates/.agent/skills/minimax-xlsx/references/format.md +768 -0
  96. package/templates/.agent/skills/minimax-xlsx/references/ooxml-cheatsheet.md +231 -0
  97. package/templates/.agent/skills/minimax-xlsx/references/read-analyze.md +97 -0
  98. package/templates/.agent/skills/minimax-xlsx/references/validate.md +772 -0
  99. package/templates/.agent/skills/minimax-xlsx/scripts/formula_check.py +422 -0
  100. package/templates/.agent/skills/minimax-xlsx/scripts/libreoffice_recalc.py +248 -0
  101. package/templates/.agent/skills/minimax-xlsx/scripts/shared_strings_builder.py +163 -0
  102. package/templates/.agent/skills/minimax-xlsx/scripts/style_audit.py +575 -0
  103. package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_add_column.py +395 -0
  104. package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_insert_row.py +274 -0
  105. package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_pack.py +87 -0
  106. package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_reader.py +362 -0
  107. package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_shift_rows.py +396 -0
  108. package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_unpack.py +130 -0
  109. package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/[Content_Types].xml +9 -0
  110. package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/_rels/.rels +6 -0
  111. package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/_rels/workbook.xml.rels +19 -0
  112. package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/sharedStrings.xml +33 -0
  113. package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/styles.xml +160 -0
  114. package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/workbook.xml +30 -0
  115. package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/worksheets/sheet1.xml +70 -0
  116. package/templates/.agent/skills/pptx-generator/SKILL.md +249 -0
  117. package/templates/.agent/skills/pptx-generator/references/design-system.md +392 -0
  118. package/templates/.agent/skills/pptx-generator/references/editing.md +162 -0
  119. package/templates/.agent/skills/pptx-generator/references/pitfalls.md +112 -0
  120. package/templates/.agent/skills/pptx-generator/references/pptxgenjs.md +420 -0
  121. package/templates/.agent/skills/pptx-generator/references/slide-types.md +413 -0
  122. package/templates/.agent/skills/tutorial-video-expert/SKILL.md +88 -0
  123. package/templates/.agent/skills/ui-ux-pro-max/SKILL.md +170 -585
  124. package/templates/.agent/skills/vision-analysis/SKILL.md +174 -0
  125. package/templates/.agent/workflows/analyze.md +3 -0
  126. package/templates/.agent/workflows/brand-report.md +44 -0
  127. package/templates/.agent/workflows/report.md +49 -0
@@ -0,0 +1,456 @@
1
+ # Scenario C: Applying Formatting / Templates
2
+
3
+ ## When to Use
4
+
5
+ Use Scenario C when:
6
+ - The user has an existing document and wants to apply a different visual style
7
+ - The user wants to rebrand a document (new fonts, colors, heading styles)
8
+ - The user provides a template DOCX and wants its look applied to a content document
9
+ - The user wants consistent formatting across multiple documents
10
+
11
+ Do NOT use when: the user wants to edit content (→ Scenario B) or create from scratch (→ Scenario A).
12
+
13
+ ---
14
+
15
+ ## Workflow
16
+
17
+ ```
18
+ 1. Analyze source → CLI: analyze source.docx (list styles, fonts, structure)
19
+ 2. Analyze template → CLI: analyze template.docx (list styles, fonts, structure)
20
+ 3. Map styles → Create mapping plan (source style → template style)
21
+ 4. Apply template → CLI: apply-template source.docx --template template.docx --output result.docx
22
+ 5. Validate (XSD) → CLI: validate result.docx --xsd wml-subset.xsd
23
+ 6. GATE-CHECK → CLI: validate result.docx --xsd business-rules.xsd ← MUST PASS
24
+ 7. Diff verify → CLI: diff source.docx result.docx --text-only (content must be identical)
25
+ ```
26
+
27
+ ---
28
+
29
+ ## What Gets Copied from Template
30
+
31
+ | Part | File | Description |
32
+ |------|------|-------------|
33
+ | Styles | `word/styles.xml` | All style definitions (paragraph, character, table, numbering) |
34
+ | Theme | `word/theme/theme1.xml` | Color scheme, font scheme, format scheme |
35
+ | Numbering | `word/numbering.xml` | List and numbering definitions |
36
+ | Headers | `word/header*.xml` | Header content and formatting |
37
+ | Footers | `word/footer*.xml` | Footer content and formatting |
38
+ | Section props | `w:sectPr` | Margins, page size, orientation, columns |
39
+
40
+ ## What Does NOT Get Copied
41
+
42
+ | Part | Reason |
43
+ |------|--------|
44
+ | Document content | Paragraphs, tables, images stay from source |
45
+ | Comments | Belong to source document's review history |
46
+ | Tracked changes | Belong to source document's revision history |
47
+ | Custom XML parts | Application-specific data, not visual |
48
+ | Document properties | Title, author, dates belong to source |
49
+ | Glossary document | Template's building blocks are not transferred |
50
+
51
+ ---
52
+
53
+ ## Template Structure Analysis (REQUIRED)
54
+
55
+ Before choosing Overlay or Base-Replace, you MUST analyze the template's internal structure. This is the #1 cause of failure when skipped.
56
+
57
+ ### Step 1: Count template paragraphs and identify structural zones
58
+
59
+ Run `$CLI analyze --input template.docx` or manually inspect:
60
+
61
+ ```bash
62
+ # Quick structure scan
63
+ scripts/docx_preview.sh template.docx
64
+ ```
65
+
66
+ Identify these zones in the template:
67
+ ```
68
+ Zone A: Front matter (cover page, declaration, abstract, TOC)
69
+ → These are KEPT from template, never replaced
70
+ Zone B: Example/placeholder body content ("第1章 XXX", sample paragraphs)
71
+ → This is REPLACED with user's actual content
72
+ Zone C: Back matter (appendices, acknowledgments, blank pages)
73
+ → These are KEPT from template or removed
74
+ Zone D: Final sectPr
75
+ → ALWAYS kept from template
76
+ ```
77
+
78
+ ### Step 2: Find Zone B boundaries (replacement range)
79
+
80
+ Search the template's document.xml for anchor text that marks the start and end of example content:
81
+
82
+ **Start anchor patterns** (first paragraph of example body):
83
+ - "第1章", "第一章", "Chapter 1", "1 Introduction", "绪论"
84
+ - The first paragraph with a Heading1-equivalent style after TOC
85
+
86
+ **End anchor patterns** (last paragraph before back matter):
87
+ - "参考文献", "References", "致谢", "Acknowledgments"
88
+ - The last paragraph before appendices or final sectPr
89
+
90
+ ```python
91
+ # Pseudocode for finding replacement range
92
+ for i, element in enumerate(template_body_elements):
93
+ text = get_text(element)
94
+ style = get_style(element)
95
+ if style in heading1_styles and ("第1章" in text or "Chapter 1" in text):
96
+ replace_start = i
97
+ if "参考文献" in text or "References" in text:
98
+ replace_end = i
99
+ break
100
+ ```
101
+
102
+ **CRITICAL**: Verify the range by printing what's inside:
103
+ ```
104
+ Template elements [0..replace_start-1]: front matter (KEEP)
105
+ Template elements [replace_start..replace_end]: example content (REPLACE)
106
+ Template elements [replace_end+1..end]: back matter (KEEP)
107
+ ```
108
+
109
+ If replace_start or replace_end cannot be found, DO NOT proceed. Ask the user to identify the replacement boundaries.
110
+
111
+ ### Step 3: Decide Overlay vs Base-Replace
112
+
113
+ Now that you know the structure:
114
+
115
+ | Observation | Decision |
116
+ |-------------|----------|
117
+ | Template has ≤30 paragraphs, no cover/TOC | **C-1: Overlay** (pure style template) |
118
+ | Template has >100 paragraphs with cover/TOC/example sections | **C-2: Base-Replace** |
119
+ | Template paragraph count ≈ user document | **C-1: Overlay** (similar structure) |
120
+ | Template paragraph count >> user document (e.g., 263 vs 134) | **C-2: Base-Replace** |
121
+
122
+ ### Step 4: For Base-Replace, execute the replacement
123
+
124
+ 1. Load template as base (all files)
125
+ 2. Extract user content elements using `list(body)` — NOT `findall('w:p')` (which misses tables)
126
+ 3. Build new body: `template[0:replace_start] + cleaned_user_content + template[replace_end+1:]`
127
+ 4. Apply style mapping to every paragraph
128
+ 5. Clean direct formatting (see rules below)
129
+ 6. Rebuild document.xml, keeping template's namespace declarations
130
+ 7. Merge relationships (images + hyperlinks)
131
+ 8. Write output using template as ZIP base
132
+
133
+ ---
134
+
135
+ ## Style Mapping Strategy
136
+
137
+ When template style names differ from source style names, a mapping is required. **This step is mandatory** — skipping it is the #1 cause of formatting failures in template application.
138
+
139
+ ### Step 0: Extract StyleIds from Both Documents (REQUIRED)
140
+
141
+ Before any template application, extract and compare styleIds from both documents:
142
+
143
+ ```bash
144
+ # Extract all styleIds from source
145
+ $CLI analyze --input source.docx --styles-only
146
+ # Output example:
147
+ # Heading1 (paragraph, basedOn: Normal)
148
+ # Heading2 (paragraph, basedOn: Normal)
149
+ # Normal (paragraph)
150
+ # ListBullet (paragraph, basedOn: Normal)
151
+
152
+ # Extract all styleIds from template
153
+ $CLI analyze --input template.docx --styles-only
154
+ # Output example:
155
+ # 1 (paragraph, basedOn: a, name: "heading 1")
156
+ # 2 (paragraph, basedOn: a, name: "heading 2")
157
+ # 3 (paragraph, basedOn: a, name: "heading 3")
158
+ # a (paragraph, name: "Normal")
159
+ # a0 (character, name: "Default Paragraph Font")
160
+ ```
161
+
162
+ **Critical distinction**: `w:styleId` vs `w:name`:
163
+ ```xml
164
+ <!-- styleId="1" but name="heading 1" -->
165
+ <w:style w:type="paragraph" w:styleId="1">
166
+ <w:name w:val="heading 1"/>
167
+ <w:basedOn w:val="a"/>
168
+ </w:style>
169
+ ```
170
+
171
+ The `w:styleId` attribute is what `<w:pStyle w:val="..."/>` references. The `w:name` attribute is the human-readable display name. **They can be completely different.** Many CJK templates use numeric styleIds (`1`, `2`, `3`, `a`, `a0`) instead of English names.
172
+
173
+ ### Tier 1: Exact StyleId Match
174
+ If source uses `Heading1` and template defines `Heading1` as a styleId, map directly. No action needed.
175
+
176
+ ### Tier 2: Name-Based Match
177
+ If no exact styleId match, try matching by `w:name` attribute:
178
+ - Source `Heading1` (name="heading 1") → Template styleId `1` (name="heading 1")
179
+ - Match is case-insensitive on the name value
180
+
181
+ Within the same type, also try matching by:
182
+ - Built-in style ID (Word's internal ID, e.g., heading 1 = built-in ID 1)
183
+ - Style type (paragraph → paragraph, character → character, table → table)
184
+
185
+ ### Tier 3: Manual Mapping
186
+ For renamed or custom styles, provide an explicit mapping:
187
+
188
+ ```json
189
+ {
190
+ "styleMap": {
191
+ "Heading1": "1",
192
+ "Heading2": "2",
193
+ "Heading3": "3",
194
+ "Heading4": "3",
195
+ "Normal": "a",
196
+ "BodyText": "a",
197
+ "ListBullet": "a",
198
+ "CompanyName": "Title",
199
+ "OldTableStyle": "TableGrid"
200
+ }
201
+ }
202
+ ```
203
+
204
+ ### Common Non-Standard StyleId Patterns
205
+
206
+ | Template Origin | StyleId Pattern | Example |
207
+ |----------------|-----------------|---------|
208
+ | Chinese Word (default) | Numeric/alphabetic | `1`, `2`, `3`, `a`, `a0` |
209
+ | English Word (default) | English names | `Heading1`, `Normal`, `Title` |
210
+ | Google Docs export | Prefixed | `Subtitle`, `NormalWeb` |
211
+ | WPS Office | Mixed | `1`, `Heading1`, custom names |
212
+ | Academic templates | Custom | `ThesisHeading1`, `ThesisBody` |
213
+
214
+ ### Building the Mapping Table
215
+
216
+ Follow this algorithm:
217
+
218
+ 1. **List source styleIds** actually used in `document.xml` (not all defined in `styles.xml`):
219
+ ```python
220
+ # Pseudocode: find all unique pStyle values in source document.xml
221
+ used_styles = set()
222
+ for p in body.iter('w:p'):
223
+ pStyle = p.find('w:pPr/w:pStyle')
224
+ if pStyle is not None:
225
+ used_styles.add(pStyle.get('val'))
226
+ ```
227
+
228
+ 2. **For each used style**, find the best match in template:
229
+ - First try: exact styleId match
230
+ - Second try: match by `w:name` value (case-insensitive)
231
+ - Third try: match by style purpose (any heading → template's heading style)
232
+ - Fallback: map to template's default paragraph style (usually `Normal` or `a`)
233
+
234
+ 3. **Validate the mapping** — every source styleId must map to an existing template styleId:
235
+ ```
236
+ ✓ Heading1 → 1 (name match: "heading 1")
237
+ ✓ Heading2 → 2 (name match: "heading 2")
238
+ ✓ Normal → a (name match: "Normal")
239
+ ✗ CustomCallout → ??? (no match found, will fallback to 'a')
240
+ ```
241
+
242
+ 4. **Apply the mapping** when copying content — update every `<w:pStyle w:val="..."/>`:
243
+ ```xml
244
+ <!-- Source -->
245
+ <w:pPr><w:pStyle w:val="Heading1"/></w:pPr>
246
+ <!-- After mapping -->
247
+ <w:pPr><w:pStyle w:val="1"/></w:pPr>
248
+ ```
249
+
250
+ ### Unmapped Styles
251
+ Styles in the source document that have no match in the template are logged as warnings:
252
+ ```
253
+ WARNING: Style 'CustomCallout' has no mapping in template. Content will fall back to 'a' (Normal).
254
+ ```
255
+
256
+ The content is preserved; only the style reference is updated to the template's default paragraph style.
257
+
258
+ ### C-2 BASE-REPLACE: Additional StyleId Considerations
259
+
260
+ When using the template as a base document (C-2 strategy), the template's `styles.xml` is already in place. You must:
261
+
262
+ 1. **Never copy source `styles.xml`** — the template's styles are the authority
263
+ 2. **Map every content paragraph's pStyle** to the template's styleId before insertion
264
+ 3. **Strip direct formatting selectively** (see detailed rules below) — let the template style control appearance
265
+ 4. **Verify table styles** — if source tables use `TableGrid` but template defines it as `a3` or similar, remap `<w:tblStyle>` too
266
+ 5. **Check character styles** — `rPr` inside runs may reference character styles like `Hyperlink` or `Strong` that have different IDs in the template
267
+
268
+ ### Direct Formatting Cleanup Rules (Detailed)
269
+
270
+ When copying content from source to template, apply these rules to EACH paragraph and run:
271
+
272
+ **REMOVE from `<w:rPr>`:**
273
+ - `<w:rFonts w:ascii="..." w:hAnsi="..."/>` — Latin font overrides (EXCEPT: keep `w:eastAsia`)
274
+ - `<w:sz>`, `<w:szCs>` — font size (let style control)
275
+ - `<w:color>` — text color
276
+ - `<w:highlight>` — highlight color
277
+ - `<w:shd>` — shading
278
+ - `<w:b>`, `<w:i>` — bold/italic UNLESS the source style requires it (e.g., emphasis)
279
+ - `<w:u>` — underline
280
+ - `<w:spacing>` — character spacing
281
+
282
+ **KEEP in `<w:rPr>`:**
283
+ - `<w:rFonts w:eastAsia="宋体"/>` — CJK font declaration (MUST keep, or Chinese text renders wrong)
284
+ - `<w:rFonts w:eastAsia="华文中宋"/>` — same reason
285
+ - Anything inside `<w:drawing>` — image references (handle separately via rId remapping)
286
+
287
+ **REMOVE from `<w:pPr>`:**
288
+ - `<w:pBdr>` — paragraph borders
289
+ - `<w:shd>` — paragraph shading
290
+ - `<w:spacing>` — line/paragraph spacing (let style control)
291
+ - `<w:jc>` — justification (let style control)
292
+ - `<w:tabs>` — custom tab stops
293
+ - `<w:rPr>` inside pPr — default run formatting for the paragraph
294
+
295
+ **KEEP in `<w:pPr>`:**
296
+ - `<w:pStyle>` — style reference (after mapping to template's styleId)
297
+ - `<w:sectPr>` — section properties (if intentionally inserting section breaks)
298
+ - `<w:numPr>` — numbering reference (after mapping numId to template's numbering)
299
+
300
+ **Table cells (`<w:tc>`):**
301
+ Apply the same rPr/pPr cleanup to every paragraph inside every cell. Also:
302
+ - Keep `<w:tcPr>` structural properties (column span, row span, width)
303
+ - Remove `<w:tcPr><w:shd>` (cell shading — let table style control)
304
+
305
+ ---
306
+
307
+ ## Relationship ID Remapping
308
+
309
+ When copying parts (headers, footers, images) from the template into the source package, relationship IDs (`r:id`) may collide.
310
+
311
+ **Problem**:
312
+ - Source has `rId7` → `image1.png`
313
+ - Template has `rId7` → `header1.xml`
314
+ - Copying template's `rId7` overwrites source's image reference
315
+
316
+ **Solution**:
317
+ 1. Scan source's `document.xml.rels` for all existing `rId` values
318
+ 2. Find the maximum numeric ID (e.g., `rId12`)
319
+ 3. Remap all template relationship IDs starting from `rId13`
320
+ 4. Update all references in copied parts to use new IDs
321
+
322
+ ```xml
323
+ <!-- Template original -->
324
+ <Relationship Id="rId1" Type="...header" Target="header1.xml" />
325
+
326
+ <!-- After remapping into source package -->
327
+ <Relationship Id="rId13" Type="...header" Target="header1.xml" />
328
+
329
+ <!-- Update sectPr reference -->
330
+ <w:headerReference w:type="default" r:id="rId13" />
331
+ ```
332
+
333
+ ### Hyperlink Relationship Merging
334
+
335
+ When the source document contains external hyperlinks (e.g., URLs in references or footnotes), these are stored as relationships in `word/_rels/document.xml.rels`:
336
+
337
+ ```xml
338
+ <Relationship Id="rId15" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
339
+ Target="https://example.com/paper" TargetMode="External"/>
340
+ ```
341
+
342
+ The corresponding text in document.xml references this rId:
343
+ ```xml
344
+ <w:hyperlink r:id="rId15">
345
+ <w:r><w:t>https://example.com/paper</w:t></w:r>
346
+ </w:hyperlink>
347
+ ```
348
+
349
+ **Merging steps:**
350
+ 1. Scan source document.xml for all `<w:hyperlink r:id="...">` elements
351
+ 2. For each, find the corresponding relationship in source's rels file
352
+ 3. Check if template already has a relationship with the same Target URL
353
+ - If yes: reuse the existing rId, update the hyperlink reference
354
+ - If no: assign a new rId (starting from template's max rId + 1), add the relationship to template's rels, update the hyperlink reference
355
+ 4. Also check for hyperlink relationships used in footnotes (`word/_rels/footnotes.xml.rels`) and endnotes
356
+
357
+ **Common mistake:** Copying hyperlink paragraphs without merging rels → hyperlinks silently break (clicking does nothing in Word).
358
+
359
+ ---
360
+
361
+ ## XSD Gate-Check
362
+
363
+ ### What It Is
364
+
365
+ After template application, the output document **MUST** pass `business-rules.xsd` validation. This is a **hard gate** — if it fails, the document is **NOT deliverable**.
366
+
367
+ ### What business-rules.xsd Checks
368
+
369
+ | Rule | What It Validates |
370
+ |------|-------------------|
371
+ | Template styles exist | All styles referenced by content paragraphs are defined in `styles.xml` |
372
+ | Margins match | Page margins match template specification |
373
+ | Fonts correct | `w:docDefaults` fonts match template's font scheme |
374
+ | Heading hierarchy | Heading levels are sequential (no H1 → H3 without H2) |
375
+ | Required styles present | `Normal`, `Heading1`-`Heading3`, `TableGrid` exist |
376
+ | Page size | Matches template's declared page size |
377
+
378
+ ### Handling Failures
379
+
380
+ ```
381
+ GATE-CHECK FAILED:
382
+ - Style 'CustomStyle1' referenced in paragraph 14 but not defined in styles.xml
383
+ - Margin w:left=1080 does not match template requirement 1440
384
+ ```
385
+
386
+ Fix each failure:
387
+ 1. **Missing style**: Add the style definition to `styles.xml`, or remap the paragraph to an existing style
388
+ 2. **Margin mismatch**: Update `w:sectPr` margins to match template
389
+ 3. **Font mismatch**: Update `w:docDefaults` to match template font scheme
390
+ 4. **Heading hierarchy gap**: Insert intermediate heading levels or adjust existing levels
391
+
392
+ Re-validate after every fix until gate-check passes.
393
+
394
+ ---
395
+
396
+ ## Common Pitfalls
397
+
398
+ ### 1. Orphaned Numbering References
399
+
400
+ **Problem**: Source document uses `w:numId="5"` in list paragraphs, but after replacing `numbering.xml` with the template's version, numbering ID 5 doesn't exist.
401
+
402
+ **Symptom**: Lists appear as plain paragraphs (no bullets/numbers).
403
+
404
+ **Fix**:
405
+ - Map source numbering IDs to template numbering IDs
406
+ - Update all `w:numId` references in document content
407
+ - Or merge source numbering definitions into template's `numbering.xml`
408
+
409
+ ### 2. Missing Theme Colors
410
+
411
+ **Problem**: Source document's styles reference theme colors (`w:themeColor="accent1"`) that have different values in the template's theme.
412
+
413
+ **Symptom**: Colors change unexpectedly (usually acceptable — this IS the point of re-theming). But if a style uses `w:color` with both `w:val` and `w:themeColor`, the theme color wins in Word.
414
+
415
+ **Fix**: Review color changes. If specific colors must be preserved, use explicit `w:val` without `w:themeColor`.
416
+
417
+ ### 3. Section Property Conflicts
418
+
419
+ **Problem**: Source document has multiple sections (e.g., portrait + landscape pages), but the template assumes a single section.
420
+
421
+ **Symptom**: All sections get the same margins/orientation, breaking landscape pages.
422
+
423
+ **Fix**:
424
+ - Only apply template section properties to the final `w:sectPr` in `w:body`
425
+ - Preserve intermediate `w:sectPr` elements (inside `w:pPr`) from the source
426
+ - Or apply template properties to all sections but preserve orientation overrides
427
+
428
+ ### 4. Embedded Font Conflicts
429
+
430
+ **Problem**: Template specifies fonts not available on the target system.
431
+
432
+ **Fix**: Either embed fonts in the DOCX (`word/fonts/`) or use web-safe alternatives:
433
+ - Calibri → available on Windows/Mac/Office online
434
+ - Arial → universal fallback
435
+ - Times New Roman → universal serif fallback
436
+
437
+ ### 5. Broken Style Inheritance
438
+
439
+ **Problem**: Template has `Heading1` based on `Normal`, but after applying template, `Normal` has different properties, cascading unwanted changes to headings.
440
+
441
+ **Fix**: Verify the `w:basedOn` chain for all critical styles. Ensure base styles are also correctly transferred from template.
442
+
443
+ ---
444
+
445
+ ## Verification Checklist
446
+
447
+ After template application, verify:
448
+
449
+ 1. **Content preserved** — text diff shows zero content changes
450
+ 2. **Gate-check passed** — `business-rules.xsd` validation succeeds
451
+ 3. **Styles applied** — headings, body text, tables use template formatting
452
+ 4. **Images intact** — all images render correctly (relationship IDs valid)
453
+ 5. **Lists working** — numbered and bulleted lists display correctly
454
+ 6. **Headers/footers** — template headers/footers appear on all pages
455
+ 7. **Page layout** — margins, page size, orientation match template
456
+ 8. **No corruption** — file opens without errors in Word
@@ -0,0 +1,200 @@
1
+ # Track Changes Guide
2
+
3
+ ## Overview
4
+
5
+ Track Changes in OpenXML uses revision markup elements to record insertions, deletions, and formatting changes. Each revision has a unique ID, author, and timestamp.
6
+
7
+ ---
8
+
9
+ ## Insertion: `<w:ins>`
10
+
11
+ Wraps runs that were inserted during tracking:
12
+
13
+ ```xml
14
+ <w:ins w:id="1" w:author="John Smith" w:date="2026-03-21T10:30:00Z">
15
+ <w:r>
16
+ <w:rPr>
17
+ <w:rFonts w:ascii="Calibri" w:hAnsi="Calibri" />
18
+ <w:sz w:val="22" />
19
+ </w:rPr>
20
+ <w:t>This text was inserted.</w:t>
21
+ </w:r>
22
+ </w:ins>
23
+ ```
24
+
25
+ - `w:id` — unique revision ID (integer, must be unique across document)
26
+ - `w:author` — free text string identifying the author
27
+ - `w:date` — ISO 8601 format with timezone: `YYYY-MM-DDTHH:MM:SSZ`
28
+ - Content inside is normal runs (`w:r`) with optional formatting
29
+
30
+ ---
31
+
32
+ ## Deletion: `<w:del>`
33
+
34
+ Wraps runs that were deleted during tracking:
35
+
36
+ ```xml
37
+ <w:del w:id="2" w:author="John Smith" w:date="2026-03-21T10:31:00Z">
38
+ <w:r>
39
+ <w:rPr>
40
+ <w:rFonts w:ascii="Calibri" w:hAnsi="Calibri" />
41
+ <w:sz w:val="22" />
42
+ </w:rPr>
43
+ <w:delText xml:space="preserve">This text was deleted.</w:delText>
44
+ </w:r>
45
+ </w:del>
46
+ ```
47
+
48
+ **CRITICAL**: Inside `<w:del>`, text MUST use `<w:delText>`, NOT `<w:t>`. Using `<w:t>` inside a deletion is invalid and will cause corruption or unexpected behavior. Word may silently repair it, but other consumers will fail.
49
+
50
+ ---
51
+
52
+ ## Formatting Change: `<w:rPrChange>`
53
+
54
+ Records that a run's formatting was changed. Placed inside `w:rPr`, it stores the **previous** formatting:
55
+
56
+ ```xml
57
+ <w:r>
58
+ <w:rPr>
59
+ <w:b /> <!-- Current: bold -->
60
+ <w:rPrChange w:id="3" w:author="Jane Doe" w:date="2026-03-21T11:00:00Z">
61
+ <w:rPr>
62
+ <!-- Previous: not bold (empty rPr means no formatting) -->
63
+ </w:rPr>
64
+ </w:rPrChange>
65
+ </w:rPr>
66
+ <w:t>This text was made bold.</w:t>
67
+ </w:r>
68
+ ```
69
+
70
+ The outer `w:rPr` holds the **new** (current) formatting. The `w:rPrChange` child holds the **old** (previous) formatting.
71
+
72
+ ---
73
+
74
+ ## Paragraph Property Change: `<w:pPrChange>`
75
+
76
+ Records paragraph-level formatting changes (alignment, spacing, style):
77
+
78
+ ```xml
79
+ <w:pPr>
80
+ <w:jc w:val="center" /> <!-- Current: centered -->
81
+ <w:pPrChange w:id="4" w:author="Jane Doe" w:date="2026-03-21T11:05:00Z">
82
+ <w:pPr>
83
+ <w:jc w:val="left" /> <!-- Previous: left-aligned -->
84
+ </w:pPr>
85
+ </w:pPrChange>
86
+ </w:pPr>
87
+ ```
88
+
89
+ ---
90
+
91
+ ## Revision ID Management
92
+
93
+ - Every revision element (`w:ins`, `w:del`, `w:rPrChange`, `w:pPrChange`, `w:tblPrChange`, etc.) requires a `w:id` attribute
94
+ - IDs must be **unique integers** across the entire document
95
+ - IDs should be **monotonically increasing** (not strictly required, but expected by Word)
96
+ - When adding revisions, scan for the current maximum `w:id` and increment from there
97
+
98
+ ```
99
+ Existing max ID: 47
100
+ New insertion: w:id="48"
101
+ New deletion: w:id="49"
102
+ ```
103
+
104
+ ---
105
+
106
+ ## Author and Date
107
+
108
+ - **Author**: Free text. Use consistent strings (e.g., `"MiniMaxAI"` for all automated edits)
109
+ - **Date**: ISO 8601 with UTC timezone marker: `2026-03-21T10:30:00Z`
110
+ - Must include the `T` separator and `Z` suffix (or `+HH:MM` offset)
111
+ - Omitting the date is allowed but not recommended
112
+
113
+ ---
114
+
115
+ ## Operations
116
+
117
+ ### Propose Insertion
118
+
119
+ Add `<w:ins>` wrapper around new content at the target location:
120
+
121
+ ```xml
122
+ <w:p>
123
+ <w:r><w:t>Existing text. </w:t></w:r>
124
+ <w:ins w:id="5" w:author="MiniMaxAI" w:date="2026-03-21T12:00:00Z">
125
+ <w:r><w:t>Proposed new text. </w:t></w:r>
126
+ </w:ins>
127
+ <w:r><w:t>More existing text.</w:t></w:r>
128
+ </w:p>
129
+ ```
130
+
131
+ ### Propose Deletion
132
+
133
+ Wrap existing content in `<w:del>` and change `<w:t>` to `<w:delText>`:
134
+
135
+ ```xml
136
+ <w:p>
137
+ <w:r><w:t>Keep this. </w:t></w:r>
138
+ <w:del w:id="6" w:author="MiniMaxAI" w:date="2026-03-21T12:01:00Z">
139
+ <w:r>
140
+ <w:rPr><w:b /></w:rPr>
141
+ <w:delText>Remove this.</w:delText>
142
+ </w:r>
143
+ </w:del>
144
+ <w:r><w:t> Keep this too.</w:t></w:r>
145
+ </w:p>
146
+ ```
147
+
148
+ ### Accept a Tracked Change
149
+
150
+ - **Accept insertion**: Remove the `<w:ins>` wrapper, keep the inner runs as normal content
151
+ - **Accept deletion**: Remove the entire `<w:del>` element and its content
152
+
153
+ ### Reject a Tracked Change
154
+
155
+ - **Reject insertion**: Remove the entire `<w:ins>` element and its content
156
+ - **Reject deletion**: Remove the `<w:del>` wrapper, change `<w:delText>` back to `<w:t>`
157
+
158
+ ---
159
+
160
+ ## Cross-Paragraph Operations
161
+
162
+ ### Deleting a Paragraph Break (Merging Paragraphs)
163
+
164
+ When tracked deletion spans a paragraph boundary, use `<w:pPrChange>` on the merged paragraph:
165
+
166
+ ```xml
167
+ <w:p>
168
+ <w:pPr>
169
+ <w:pPrChange w:id="7" w:author="MiniMaxAI" w:date="2026-03-21T12:05:00Z">
170
+ <w:pPr>
171
+ <w:pStyle w:val="Normal" />
172
+ </w:pPr>
173
+ </w:pPrChange>
174
+ </w:pPr>
175
+ <w:r><w:t>First paragraph text. </w:t></w:r>
176
+ <w:del w:id="8" w:author="MiniMaxAI" w:date="2026-03-21T12:05:00Z">
177
+ <w:r><w:delText> </w:delText></w:r>
178
+ </w:del>
179
+ <w:r><w:t>Second paragraph text (now merged).</w:t></w:r>
180
+ </w:p>
181
+ ```
182
+
183
+ ### Inserting a New Paragraph
184
+
185
+ The entire new paragraph is wrapped in `<w:ins>`:
186
+
187
+ ```xml
188
+ <w:p>
189
+ <w:pPr>
190
+ <w:rPr>
191
+ <w:ins w:id="9" w:author="MiniMaxAI" w:date="2026-03-21T12:10:00Z" />
192
+ </w:rPr>
193
+ </w:pPr>
194
+ <w:ins w:id="10" w:author="MiniMaxAI" w:date="2026-03-21T12:10:00Z">
195
+ <w:r><w:t>Entirely new paragraph.</w:t></w:r>
196
+ </w:ins>
197
+ </w:p>
198
+ ```
199
+
200
+ The paragraph mark itself is marked as inserted via `w:ins` inside `w:pPr > w:rPr`.