documentation-hub 5.7.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 (271) hide show
  1. package/.eslintrc.json +43 -0
  2. package/.github/workflows/build.yml +64 -0
  3. package/.github/workflows/ci.yml +39 -0
  4. package/.vscode/extensions.json +3 -0
  5. package/Current.md +97 -0
  6. package/DocHub_Image.png +0 -0
  7. package/README.md +666 -0
  8. package/USER_GUIDE.md +1173 -0
  9. package/Updater.md +311 -0
  10. package/build/256x256.png +0 -0
  11. package/build/512x512.png +0 -0
  12. package/build/app-update.yml +4 -0
  13. package/build/create-icon.js +208 -0
  14. package/build/icon.ico +0 -0
  15. package/build/icon.png +0 -0
  16. package/build/icon_1024x1024.png +0 -0
  17. package/dist/assets/Analytics-BpsG9895.js +1 -0
  18. package/dist/assets/Card-IAZin8kp.js +1 -0
  19. package/dist/assets/CurrentSession-B-rFkHvf.js +12 -0
  20. package/dist/assets/Dashboard-C_5gMb0q.js +1 -0
  21. package/dist/assets/Documents-CqZ25axS.js +1 -0
  22. package/dist/assets/Input-l89xwXBi.js +1 -0
  23. package/dist/assets/Reporting-DqdHJY_a.js +1 -0
  24. package/dist/assets/Search-XNbu5z_3.js +1 -0
  25. package/dist/assets/SessionManager-lH9hZfzH.js +1 -0
  26. package/dist/assets/Sessions-ClZOPYNc.js +1 -0
  27. package/dist/assets/Settings-DUEHGURa.js +11 -0
  28. package/dist/assets/index-8xUe8ptc.js +24 -0
  29. package/dist/assets/index-RYyJqF7O.css +1 -0
  30. package/dist/assets/path-BkOl0AGO.js +1 -0
  31. package/dist/assets/promises-ID_B9S-h.js +1 -0
  32. package/dist/assets/urlHelpers-TvgahX0r.js +1 -0
  33. package/dist/assets/useToast-yRSO1dkm.js +1 -0
  34. package/dist/assets/vendor-charts-RkGK5ROP.js +36 -0
  35. package/dist/assets/vendor-db-l0sNRNKZ.js +1 -0
  36. package/dist/assets/vendor-react-BVZ_anCF.js +4 -0
  37. package/dist/assets/vendor-search-Dw8P0qyA.js +1 -0
  38. package/dist/assets/vendor-ui-BU7NfluV.js +53 -0
  39. package/dist/electron/PowerAutomateApiService-LfW09ZGr.js +147 -0
  40. package/dist/electron/main-CXkNtyv-.js +19789 -0
  41. package/dist/electron/main.js +5 -0
  42. package/dist/electron/preload.js +1 -0
  43. package/dist/icon.png +0 -0
  44. package/dist/index.html +27 -0
  45. package/docs/CODEBASE_ANALYSIS_REPORT.md +309 -0
  46. package/docs/DEBUG_LOGGING_GUIDE.md +244 -0
  47. package/docs/README.md +115 -0
  48. package/docs/TOC_WIRING_GUIDE.md +344 -0
  49. package/docs/analysis/Bullet_Symbol_Bug_Analysis.md +136 -0
  50. package/docs/analysis/DOCXMLATER_ANALYSIS_SUMMARY.txt +169 -0
  51. package/docs/analysis/Document_Processing_Issues_Analysis.md +704 -0
  52. package/docs/analysis/FIELD_PRESERVATION_ANALYSIS.md +1200 -0
  53. package/docs/analysis/INDENTATION_PRESERVE_ANALYSIS.md +181 -0
  54. package/docs/analysis/INDENTATION_PRESERVE_IMPLEMENTATION.md +207 -0
  55. package/docs/analysis/List_Implementation.md +206 -0
  56. package/docs/analysis/List_Implementation_Accuracy_Report.md +366 -0
  57. package/docs/analysis/PROCESSING_OPTIONS_UI_UPDATES.md +220 -0
  58. package/docs/analysis/RefactorStyles.md +852 -0
  59. package/docs/analysis/STYLE_PARAMETER_ENHANCEMENT.md +143 -0
  60. package/docs/analysis/docxmlater-comparison-todo-2025-11-13.md +636 -0
  61. package/docs/analysis/docxmlater-implementation-analysis-2025-11-13.md +340 -0
  62. package/docs/analysis/docxmlater-template_ui-integration-analysis.md +263 -0
  63. package/docs/analysis/github-issues-to-create.md +237 -0
  64. package/docs/api/API_README.md +538 -0
  65. package/docs/api/API_REFERENCE.md +751 -0
  66. package/docs/api/TYPE_DEFINITIONS.md +869 -0
  67. package/docs/architecture/FONT_EMBEDDING_GUIDE.md +318 -0
  68. package/docs/architecture/docxmlater-functions-and-structure.md +726 -0
  69. package/docs/docxmlater-readme.md +1341 -0
  70. package/docs/fixes/EXECUTION_LOG_TEST_BASE.md +573 -0
  71. package/docs/fixes/HYPERLINK_TEXT_SANITIZATION.md +253 -0
  72. package/docs/fixes/README.md +37 -0
  73. package/docs/github-issues/issue-1-body.md +125 -0
  74. package/docs/github-issues/issue-10-body.md +850 -0
  75. package/docs/github-issues/issue-2-body.md +200 -0
  76. package/docs/github-issues/issue-3-body.md +270 -0
  77. package/docs/github-issues/issue-4-body.md +169 -0
  78. package/docs/github-issues/issue-5-body.md +173 -0
  79. package/docs/github-issues/issue-6-body.md +158 -0
  80. package/docs/github-issues/issue-7-body.md +171 -0
  81. package/docs/github-issues/issue-8-body.md +407 -0
  82. package/docs/github-issues/issue-9-body.md +515 -0
  83. package/docs/github-issues/issue-tracker.md +274 -0
  84. package/docs/github-issues/predictive-analysis-2025-10-18.md +2131 -0
  85. package/docs/implementation/List_Framework_Refactor_Plan.md +336 -0
  86. package/docs/implementation/PRIMARY_TEXT_COLOR_FEATURE.md +217 -0
  87. package/docs/implementation/RELEASE_PLAN_v2.1.0.md +362 -0
  88. package/docs/implementation/RefactorStyles.md +588 -0
  89. package/docs/implementation/implement-plan.md +489 -0
  90. package/docs/implementation/missing-helpers-implementation.md +391 -0
  91. package/docs/implementation/refactor-plan.md +520 -0
  92. package/docs/implementation/session-implementation-complete.md +233 -0
  93. package/docs/implementation/session-management-plan.md +250 -0
  94. package/docs/setup-checklist.md +77 -0
  95. package/docs/versions/changelog.md +345 -0
  96. package/electron/customUpdater.ts +656 -0
  97. package/electron/main.ts +2441 -0
  98. package/electron/memoryConfig.ts +187 -0
  99. package/electron/preload.ts +394 -0
  100. package/electron/proxyConfig.ts +340 -0
  101. package/electron/services/BackupService.ts +452 -0
  102. package/electron/services/DictionaryService.ts +402 -0
  103. package/electron/services/LocalDictionaryLookupService.ts +147 -0
  104. package/electron/services/PowerAutomateApiService.ts +231 -0
  105. package/electron/services/SharePointSyncService.ts +474 -0
  106. package/electron/windowsCertStore.ts +427 -0
  107. package/electron/zscalerConfig.ts +381 -0
  108. package/eslint.config.js +92 -0
  109. package/jest.config.js +52 -0
  110. package/package.json +214 -0
  111. package/postcss.config.mjs +6 -0
  112. package/public/icon.png +0 -0
  113. package/publish-release.ps1 +5 -0
  114. package/renovate.json +30 -0
  115. package/src/App.tsx +216 -0
  116. package/src/__mocks__/p-limit.js +12 -0
  117. package/src/__mocks__/styleMock.js +1 -0
  118. package/src/components/common/BugReportButton.tsx +44 -0
  119. package/src/components/common/BugReportDialog.tsx +193 -0
  120. package/src/components/common/Button.tsx +153 -0
  121. package/src/components/common/Card.tsx +86 -0
  122. package/src/components/common/ColorPickerDialog.tsx +177 -0
  123. package/src/components/common/ConfirmDialog.tsx +96 -0
  124. package/src/components/common/DebugConsole.tsx +275 -0
  125. package/src/components/common/EmptyState.tsx +183 -0
  126. package/src/components/common/ErrorBoundary.tsx +98 -0
  127. package/src/components/common/ErrorDetailsDialog.tsx +153 -0
  128. package/src/components/common/ErrorFallback.tsx +218 -0
  129. package/src/components/common/Input.tsx +109 -0
  130. package/src/components/common/Skeleton.tsx +184 -0
  131. package/src/components/common/SplashScreen.tsx +81 -0
  132. package/src/components/common/Toast.tsx +155 -0
  133. package/src/components/common/Tooltip.tsx +79 -0
  134. package/src/components/common/UpdateNotification.tsx +320 -0
  135. package/src/components/comparison/ComparisonWindow.tsx +374 -0
  136. package/src/components/comparison/SideBySideDiff.tsx +486 -0
  137. package/src/components/comparison/index.ts +8 -0
  138. package/src/components/document/DocumentUploader.tsx +288 -0
  139. package/src/components/document/HyperlinkPreview.tsx +430 -0
  140. package/src/components/document/HyperlinkService.md +1484 -0
  141. package/src/components/document/Hyperlink_Technical_Documentation.md +496 -0
  142. package/src/components/document/InlineChangesView.tsx +707 -0
  143. package/src/components/document/ProcessingProgress.tsx +303 -0
  144. package/src/components/document/ProcessingResults.tsx +256 -0
  145. package/src/components/document/TrackedChangesDetail.tsx +530 -0
  146. package/src/components/document/TrackedChangesPanel.tsx +546 -0
  147. package/src/components/document/VirtualDocumentList.tsx +240 -0
  148. package/src/components/editor/DocumentEditor.tsx +723 -0
  149. package/src/components/editor/DocumentEditorModal.tsx +640 -0
  150. package/src/components/editor/EditorQuickActions.tsx +502 -0
  151. package/src/components/editor/EditorToolbar.tsx +312 -0
  152. package/src/components/editor/TableEditor.tsx +926 -0
  153. package/src/components/editor/index.ts +18 -0
  154. package/src/components/layout/Header.tsx +190 -0
  155. package/src/components/layout/Sidebar.tsx +313 -0
  156. package/src/components/layout/TitleBar.tsx +190 -0
  157. package/src/components/navigation/CommandPalette.tsx +233 -0
  158. package/src/components/navigation/KeyboardShortcutsModal.tsx +173 -0
  159. package/src/components/sessions/ChangeItem.tsx +408 -0
  160. package/src/components/sessions/ChangeViewer.tsx +1155 -0
  161. package/src/components/sessions/DocumentComparisonModal.tsx +314 -0
  162. package/src/components/sessions/ProcessingOptions.tsx +297 -0
  163. package/src/components/sessions/ReplacementsTab.tsx +438 -0
  164. package/src/components/sessions/RevisionHandlingOptions.tsx +87 -0
  165. package/src/components/sessions/SessionManager.tsx +188 -0
  166. package/src/components/sessions/StylesEditor.tsx +1335 -0
  167. package/src/components/sessions/TabContainer.tsx +151 -0
  168. package/src/components/sessions/VirtualSessionList.tsx +157 -0
  169. package/src/components/sessions/sessionToProcessorManager.tsx +420 -0
  170. package/src/components/settings/CertificateManager.tsx +410 -0
  171. package/src/components/settings/SegmentedControl.tsx +88 -0
  172. package/src/components/settings/SettingRow.tsx +52 -0
  173. package/src/contexts/GlobalStatsContext.tsx +396 -0
  174. package/src/contexts/SessionContext.tsx +2129 -0
  175. package/src/contexts/ThemeContext.tsx +428 -0
  176. package/src/contexts/UserSettingsContext.tsx +290 -0
  177. package/src/contexts/__tests__/GlobalStatsContext.test.tsx +390 -0
  178. package/src/global.d.ts +273 -0
  179. package/src/hooks/useDocumentQueue.tsx +210 -0
  180. package/src/hooks/useToast.tsx +55 -0
  181. package/src/main.tsx +10 -0
  182. package/src/pages/Analytics.tsx +386 -0
  183. package/src/pages/CurrentSession.tsx +1174 -0
  184. package/src/pages/Dashboard.tsx +319 -0
  185. package/src/pages/Documents.tsx +317 -0
  186. package/src/pages/Projects.tsx +250 -0
  187. package/src/pages/Reporting.tsx +386 -0
  188. package/src/pages/Search.tsx +349 -0
  189. package/src/pages/Sessions.tsx +285 -0
  190. package/src/pages/Settings.tsx +2662 -0
  191. package/src/services/HyperlinkService.ts +1085 -0
  192. package/src/services/document/DocXMLaterProcessor.ts +617 -0
  193. package/src/services/document/DocumentProcessingComparison.ts +856 -0
  194. package/src/services/document/DocumentSnapshotService.ts +575 -0
  195. package/src/services/document/WordDocumentProcessor.ts +10509 -0
  196. package/src/services/document/__tests__/DocXMLaterProcessor.hyperlinks.test.md +311 -0
  197. package/src/services/document/__tests__/WordDocumentProcessor.integration.test.ts +515 -0
  198. package/src/services/document/__tests__/WordDocumentProcessor.test.ts +812 -0
  199. package/src/services/document/blanklines/BlankLineManager.ts +658 -0
  200. package/src/services/document/blanklines/__tests__/paragraphChecks.test.ts +281 -0
  201. package/src/services/document/blanklines/helpers/blankLineInsertion.ts +87 -0
  202. package/src/services/document/blanklines/helpers/blankLineSnapshot.ts +251 -0
  203. package/src/services/document/blanklines/helpers/clearCustom.ts +121 -0
  204. package/src/services/document/blanklines/helpers/contextChecks.ts +117 -0
  205. package/src/services/document/blanklines/helpers/imageChecks.ts +51 -0
  206. package/src/services/document/blanklines/helpers/paragraphChecks.ts +236 -0
  207. package/src/services/document/blanklines/helpers/removeBlanksBetweenListItems.ts +91 -0
  208. package/src/services/document/blanklines/helpers/removeTrailingBlanks.ts +35 -0
  209. package/src/services/document/blanklines/helpers/tableGuards.ts +21 -0
  210. package/src/services/document/blanklines/index.ts +67 -0
  211. package/src/services/document/blanklines/rules/additionRules.ts +337 -0
  212. package/src/services/document/blanklines/rules/indentationRules.ts +317 -0
  213. package/src/services/document/blanklines/rules/removalRules.ts +362 -0
  214. package/src/services/document/blanklines/rules/ruleTypes.ts +92 -0
  215. package/src/services/document/blanklines/types.ts +29 -0
  216. package/src/services/document/helpers/ImageBorderCropper.ts +377 -0
  217. package/src/services/document/helpers/__tests__/whitespace.test.ts +272 -0
  218. package/src/services/document/helpers/whitespace.ts +117 -0
  219. package/src/services/document/list/ListNormalizer.ts +947 -0
  220. package/src/services/document/list/index.ts +45 -0
  221. package/src/services/document/list/list-detection.ts +275 -0
  222. package/src/services/document/list/list-types.ts +162 -0
  223. package/src/services/document/processors/HyperlinkProcessor.ts +370 -0
  224. package/src/services/document/processors/ListProcessor.ts +257 -0
  225. package/src/services/document/processors/StructureProcessor.ts +176 -0
  226. package/src/services/document/processors/StyleProcessor.ts +389 -0
  227. package/src/services/document/processors/TableProcessor.ts +2238 -0
  228. package/src/services/document/processors/__tests__/HyperlinkProcessor.test.ts +314 -0
  229. package/src/services/document/processors/__tests__/ListProcessor.test.ts +291 -0
  230. package/src/services/document/processors/__tests__/StructureProcessor.test.ts +257 -0
  231. package/src/services/document/processors/__tests__/TableProcessor.hlp-tips-bullets.test.ts +459 -0
  232. package/src/services/document/processors/__tests__/TableProcessor.test.ts +1604 -0
  233. package/src/services/document/processors/index.ts +28 -0
  234. package/src/services/document/types/docx-processing.ts +310 -0
  235. package/src/services/editor/EditorActionHandlers.ts +901 -0
  236. package/src/services/editor/index.ts +13 -0
  237. package/src/setupTests.ts +47 -0
  238. package/src/styles/global.css +782 -0
  239. package/src/types/backup.ts +132 -0
  240. package/src/types/dictionary.ts +125 -0
  241. package/src/types/document-processing.ts +331 -0
  242. package/src/types/docxmlater-augments.d.ts +142 -0
  243. package/src/types/editor.ts +280 -0
  244. package/src/types/electron.ts +340 -0
  245. package/src/types/globalStats.ts +155 -0
  246. package/src/types/hyperlink.ts +471 -0
  247. package/src/types/operations.ts +354 -0
  248. package/src/types/session.ts +427 -0
  249. package/src/types/settings.ts +112 -0
  250. package/src/utils/MemoryMonitor.ts +248 -0
  251. package/src/utils/cn.ts +6 -0
  252. package/src/utils/colorConvert.ts +306 -0
  253. package/src/utils/diffUtils.ts +347 -0
  254. package/src/utils/documentUtils.ts +202 -0
  255. package/src/utils/electronGuard.ts +62 -0
  256. package/src/utils/indexedDB.ts +915 -0
  257. package/src/utils/logger.ts +717 -0
  258. package/src/utils/pathSecurity.ts +232 -0
  259. package/src/utils/pathValidator.ts +236 -0
  260. package/src/utils/processingTimeEstimator.ts +153 -0
  261. package/src/utils/safeJsonParse.ts +62 -0
  262. package/src/utils/textSanitizer.ts +162 -0
  263. package/src/utils/urlHelpers.ts +304 -0
  264. package/src/utils/urlPatterns.ts +198 -0
  265. package/src/utils/urlSanitizer.ts +152 -0
  266. package/src/vite-env.d.ts +11 -0
  267. package/tsconfig.electron.json +19 -0
  268. package/tsconfig.json +36 -0
  269. package/tsconfig.node.json +12 -0
  270. package/typedoc.json +45 -0
  271. package/vite.config.ts +152 -0
@@ -0,0 +1,726 @@
1
+ # docXMLater - Professional DOCX Framework
2
+
3
+ [![npm version](https://img.shields.io/npm/v/docxmlater.svg)](https://www.npmjs.com/package/docxmlater)
4
+ [![Tests](https://img.shields.io/badge/tests-2073%20passing-brightgreen)](https://github.com/ItMeDiaTech/docXMLater)
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue)](https://www.typescriptlang.org/)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ A comprehensive, production-ready TypeScript/JavaScript library for creating, reading, and manipulating Microsoft Word (.docx) documents programmatically. Full OpenXML compliance with extensive API coverage and **100% test pass rate**.
9
+
10
+ **Version:** 1.16.0 | **Status:** Production Ready | **All 5 Implementation Phases Complete**
11
+
12
+ > For detailed version history and recent features, see [Version History](../versions/changelog.md)
13
+ >
14
+ > **Recent Highlights:**
15
+ > - v1.15.0: Hyperlink Defragmentation API
16
+ > - v1.14.0: List Formatting Helpers & Special Characters
17
+ > - v1.13.0: Fixed Hyperlink Duplication from Google Docs
18
+
19
+ ## Quick Start
20
+
21
+ ```bash
22
+ npm install docxmlater
23
+ ```
24
+
25
+ ```typescript
26
+ import { Document } from 'docxmlater';
27
+
28
+ // Create document
29
+ const doc = Document.create();
30
+ doc.createParagraph('Hello World').setStyle('Title');
31
+
32
+ // Save document
33
+ await doc.save('output.docx');
34
+ ```
35
+
36
+ ## Complete API Reference
37
+
38
+ ### Document Operations
39
+
40
+ | Method | Description | Example |
41
+ | --------------------------------- | ----------------------- | ------------------------------------------------ |
42
+ | `Document.create(options?)` | Create new document | `const doc = Document.create()` |
43
+ | `Document.createEmpty()` | Create minimal document | `const doc = Document.createEmpty()` |
44
+ | `Document.load(path)` | Load from file | `const doc = await Document.load('file.docx')` |
45
+ | `Document.loadFromBuffer(buffer)` | Load from buffer | `const doc = await Document.loadFromBuffer(buf)` |
46
+ | `save(path)` | Save to file | `await doc.save('output.docx')` |
47
+ | `toBuffer()` | Export as buffer | `const buffer = await doc.toBuffer()` |
48
+ | `dispose()` | Clean up resources | `doc.dispose()` |
49
+
50
+ ### Content Creation
51
+
52
+ | Method | Description | Example |
53
+ | -------------------------------- | ---------------------- | -------------------------------- |
54
+ | `createParagraph(text?)` | Add paragraph | `doc.createParagraph('Text')` |
55
+ | `createTable(rows, cols)` | Add table | `doc.createTable(3, 4)` |
56
+ | `addParagraph(para)` | Add existing paragraph | `doc.addParagraph(myPara)` |
57
+ | `addTable(table)` | Add existing table | `doc.addTable(myTable)` |
58
+ | `addImage(image)` | Add image | `doc.addImage(myImage)` |
59
+ | `addTableOfContents(toc?)` | Add TOC | `doc.addTableOfContents()` |
60
+ | `insertParagraphAt(index, para)` | Insert at position | `doc.insertParagraphAt(0, para)` |
61
+
62
+ ### Content Retrieval
63
+
64
+ | Method | Description | Returns |
65
+ | --------------------- | --------------------- | ------------------------------------------ |
66
+ | `getParagraphs()` | Get all paragraphs | `Paragraph[]` |
67
+ | `getTables()` | Get all tables | `Table[]` |
68
+ | `getBodyElements()` | Get all body elements | `BodyElement[]` |
69
+ | `getParagraphCount()` | Count paragraphs | `number` |
70
+ | `getTableCount()` | Count tables | `number` |
71
+ | `getHyperlinks()` | Get all links | `Array<{hyperlink, paragraph}>` |
72
+ | `getBookmarks()` | Get all bookmarks | `Array<{bookmark, paragraph}>` |
73
+ | `getImages()` | Get all images | `Array<{image, relationshipId, filename}>` |
74
+
75
+ ### Content Removal
76
+
77
+ | Method | Description | Returns |
78
+ | ------------------------------ | ------------------ | --------- |
79
+ | `removeParagraph(paraOrIndex)` | Remove paragraph | `boolean` |
80
+ | `removeTable(tableOrIndex)` | Remove table | `boolean` |
81
+ | `clearParagraphs()` | Remove all content | `this` |
82
+
83
+ ### Search & Replace
84
+
85
+ | Method | Description | Options |
86
+ | -------------------------------------- | --------------------- | ------------------------------ |
87
+ | `findText(text, options?)` | Find text occurrences | `{caseSensitive?, wholeWord?}` |
88
+ | `replaceText(find, replace, options?)` | Replace all text | `{caseSensitive?, wholeWord?}` |
89
+ | `updateHyperlinkUrls(urlMap)` | Update hyperlink URLs | `Map<oldUrl, newUrl>` |
90
+
91
+ ### Document Statistics
92
+
93
+ | Method | Description | Returns |
94
+ | ----------------------------------- | ------------------- | ------------------------------ |
95
+ | `getWordCount()` | Total word count | `number` |
96
+ | `getCharacterCount(includeSpaces?)` | Character count | `number` |
97
+ | `estimateSize()` | Size estimation | `{totalEstimatedMB, warning?}` |
98
+ | `getSizeStats()` | Detailed size stats | `{elements, size, warnings}` |
99
+
100
+ ### Text Formatting
101
+
102
+ | Property | Values | Example |
103
+ | ------------- | -------------------------------- | ----------------------- |
104
+ | `bold` | `true/false` | `{bold: true}` |
105
+ | `italic` | `true/false` | `{italic: true}` |
106
+ | `underline` | `'single'/'double'/'dotted'/etc` | `{underline: 'single'}` |
107
+ | `strike` | `true/false` | `{strike: true}` |
108
+ | `font` | Font name | `{font: 'Arial'}` |
109
+ | `size` | Points | `{size: 12}` |
110
+ | `color` | Hex color | `{color: 'FF0000'}` |
111
+ | `highlight` | Color name | `{highlight: 'yellow'}` |
112
+ | `subscript` | `true/false` | `{subscript: true}` |
113
+ | `superscript` | `true/false` | `{superscript: true}` |
114
+ | `smallCaps` | `true/false` | `{smallCaps: true}` |
115
+ | `allCaps` | `true/false` | `{allCaps: true}` |
116
+
117
+ ### Paragraph Formatting
118
+
119
+ | Method | Description | Values |
120
+ | ------------------------------ | ------------------- | ----------------------------------- |
121
+ | `setAlignment(align)` | Text alignment | `'left'/'center'/'right'/'justify'` |
122
+ | `setLeftIndent(twips)` | Left indentation | Twips value |
123
+ | `setRightIndent(twips)` | Right indentation | Twips value |
124
+ | `setFirstLineIndent(twips)` | First line indent | Twips value |
125
+ | `setSpaceBefore(twips)` | Space before | Twips value |
126
+ | `setSpaceAfter(twips)` | Space after | Twips value |
127
+ | `setLineSpacing(twips, rule?)` | Line spacing | Twips + rule |
128
+ | `setStyle(styleId)` | Apply style | Style ID |
129
+ | `setKeepNext()` | Keep with next | - |
130
+ | `setKeepLines()` | Keep lines together | - |
131
+ | `setPageBreakBefore()` | Page break before | - |
132
+
133
+ ### Table Operations
134
+
135
+ | Method | Description | Example |
136
+ | ----------------------- | -------------------- | ---------------------------------------- |
137
+ | `getRow(index)` | Get table row | `table.getRow(0)` |
138
+ | `getCell(row, col)` | Get table cell | `table.getCell(0, 1)` |
139
+ | `addRow()` | Add new row | `table.addRow()` |
140
+ | `removeRow(index)` | Remove row | `table.removeRow(2)` |
141
+ | `insertColumn(index)` | Insert column | `table.insertColumn(1)` |
142
+ | `removeColumn(index)` | Remove column | `table.removeColumn(3)` |
143
+ | `setWidth(twips)` | Set table width | `table.setWidth(8640)` |
144
+ | `setAlignment(align)` | Table alignment | `table.setAlignment('center')` |
145
+ | `setAllBorders(border)` | Set all borders | `table.setAllBorders({style: 'single'})` |
146
+ | `setBorders(borders)` | Set specific borders | `table.setBorders({top: {...}})` |
147
+
148
+ ### Table Cell Operations
149
+
150
+ | Method | Description | Example |
151
+ | ----------------------------- | --------------------- | ------------------------------------- |
152
+ | `createParagraph(text?)` | Add paragraph to cell | `cell.createParagraph('Text')` |
153
+ | `setShading(shading)` | Cell background | `cell.setShading({fill: 'E0E0E0'})` |
154
+ | `setVerticalAlignment(align)` | Vertical align | `cell.setVerticalAlignment('center')` |
155
+ | `setColumnSpan(cols)` | Merge columns | `cell.setColumnSpan(3)` |
156
+ | `setRowSpan(rows)` | Merge rows | `cell.setRowSpan(2)` |
157
+ | `setBorders(borders)` | Cell borders | `cell.setBorders({top: {...}})` |
158
+ | `setWidth(width, type?)` | Cell width | `cell.setWidth(2000, 'dxa')` |
159
+
160
+ ### Style Management
161
+
162
+ | Method | Description | Example |
163
+ | ----------------------------- | ------------------ | ---------------------------------- |
164
+ | `addStyle(style)` | Add custom style | `doc.addStyle(myStyle)` |
165
+ | `getStyle(styleId)` | Get style by ID | `doc.getStyle('Heading1')` |
166
+ | `hasStyle(styleId)` | Check style exists | `doc.hasStyle('CustomStyle')` |
167
+ | `getStyles()` | Get all styles | `doc.getStyles()` |
168
+ | `removeStyle(styleId)` | Remove style | `doc.removeStyle('OldStyle')` |
169
+ | `updateStyle(styleId, props)` | Update style | `doc.updateStyle('Normal', {...})` |
170
+
171
+ #### Built-in Styles
172
+
173
+ - `Normal` - Default paragraph
174
+ - `Title` - Document title
175
+ - `Subtitle` - Document subtitle
176
+ - `Heading1` through `Heading9` - Section headings
177
+ - `ListParagraph` - List items
178
+
179
+ ### List Management
180
+
181
+ | Method | Description | Returns |
182
+ | --------------------------------------- | ----------------------- | ------- |
183
+ | `createBulletList(levels?, bullets?)` | Create bullet list | `numId` |
184
+ | `createNumberedList(levels?, formats?)` | Create numbered list | `numId` |
185
+ | `createMultiLevelList()` | Create multi-level list | `numId` |
186
+
187
+ ### Image Handling
188
+
189
+ | Method | Description | Example |
190
+ | --------------------------------------- | ------------------ | -------------------------------- |
191
+ | `Image.fromFile(path, width?, height?)` | Load from file | `Image.fromFile('pic.jpg')` |
192
+ | `Image.fromBuffer(buffer, ext, w?, h?)` | Load from buffer | `Image.fromBuffer(buf, 'png')` |
193
+ | `setWidth(emus, maintainRatio?)` | Set width | `img.setWidth(inchesToEmus(3))` |
194
+ | `setHeight(emus, maintainRatio?)` | Set height | `img.setHeight(inchesToEmus(2))` |
195
+ | `setSize(width, height)` | Set dimensions | `img.setSize(w, h)` |
196
+ | `setRotation(degrees)` | Rotate image | `img.setRotation(90)` |
197
+ | `setAltText(text)` | Accessibility text | `img.setAltText('Description')` |
198
+
199
+ ### Hyperlinks
200
+
201
+ | Method | Description | Example |
202
+ | ------------------------------------------------- | ---------------- | ---------------------------------------------------------- |
203
+ | `Hyperlink.createExternal(url, text, format?)` | Web link | `Hyperlink.createExternal('https://example.com', 'Click')` |
204
+ | `Hyperlink.createEmail(email, text?, format?)` | Email link | `Hyperlink.createEmail('user@example.com')` |
205
+ | `Hyperlink.createInternal(anchor, text, format?)` | Internal link | `Hyperlink.createInternal('Section1', 'Go to')` |
206
+ | `para.addHyperlink(hyperlink)` | Add to paragraph | `para.addHyperlink(link)` |
207
+
208
+ ### Headers & Footers
209
+
210
+ | Method | Description | Example |
211
+ | ---------------------------- | ------------------ | -------------------------------- |
212
+ | `setHeader(header)` | Set default header | `doc.setHeader(myHeader)` |
213
+ | `setFooter(footer)` | Set default footer | `doc.setFooter(myFooter)` |
214
+ | `setFirstPageHeader(header)` | First page header | `doc.setFirstPageHeader(header)` |
215
+ | `setFirstPageFooter(footer)` | First page footer | `doc.setFirstPageFooter(footer)` |
216
+ | `setEvenPageHeader(header)` | Even page header | `doc.setEvenPageHeader(header)` |
217
+ | `setEvenPageFooter(footer)` | Even page footer | `doc.setEvenPageFooter(footer)` |
218
+
219
+ ### Page Setup
220
+
221
+ | Method | Description | Example |
222
+ | ------------------------------------- | ----------------- | ------------------------------------- |
223
+ | `setPageSize(width, height, orient?)` | Page dimensions | `doc.setPageSize(12240, 15840)` |
224
+ | `setPageOrientation(orientation)` | Page orientation | `doc.setPageOrientation('landscape')` |
225
+ | `setMargins(margins)` | Page margins | `doc.setMargins({top: 1440, ...})` |
226
+ | `setLanguage(language)` | Document language | `doc.setLanguage('en-US')` |
227
+
228
+ ### Document Properties
229
+
230
+ | Method | Description | Properties |
231
+ | ---------------------- | ------------ | ------------------------------------- |
232
+ | `setProperties(props)` | Set metadata | `{title, subject, creator, keywords}` |
233
+ | `getProperties()` | Get metadata | Returns all properties |
234
+
235
+ ### Advanced Features
236
+
237
+ #### Bookmarks
238
+
239
+ | Method | Description |
240
+ | ---------------------------------------- | ------------------- |
241
+ | `createBookmark(name)` | Create bookmark |
242
+ | `createHeadingBookmark(text)` | Auto-named bookmark |
243
+ | `getBookmark(name)` | Get by name |
244
+ | `hasBookmark(name)` | Check existence |
245
+ | `addBookmarkToParagraph(para, bookmark)` | Add to paragraph |
246
+
247
+ #### Comments
248
+
249
+ | Method | Description |
250
+ | ------------------------------------------- | ----------------- |
251
+ | `createComment(author, content, initials?)` | Add comment |
252
+ | `createReply(parentId, author, content)` | Reply to comment |
253
+ | `getComment(id)` | Get by ID |
254
+ | `getAllComments()` | Get all top-level |
255
+ | `addCommentToParagraph(para, comment)` | Add to paragraph |
256
+
257
+ #### Track Changes
258
+
259
+ | Method | Description |
260
+ | ------------------------------------ | ----------------- |
261
+ | `trackInsertion(para, author, text)` | Track insertion |
262
+ | `trackDeletion(para, author, text)` | Track deletion |
263
+ | `isTrackingChanges()` | Check if tracking |
264
+ | `getRevisionStats()` | Get statistics |
265
+
266
+ #### Footnotes & Endnotes
267
+
268
+ | Method | Description |
269
+ | -------------------------- | ---------------- |
270
+ | `FootnoteManager.create()` | Manage footnotes |
271
+ | `EndnoteManager.create()` | Manage endnotes |
272
+
273
+ ### Low-Level Document Parts
274
+
275
+ | Method | Description | Example |
276
+ | ---------------------------- | --------------------- | ------------------------------------------------- |
277
+ | `getPart(partName)` | Get document part | `doc.getPart('word/document.xml')` |
278
+ | `setPart(partName, content)` | Set document part | `doc.setPart('custom.xml', data)` |
279
+ | `removePart(partName)` | Remove part | `doc.removePart('custom.xml')` |
280
+ | `listParts()` | List all parts | `const parts = await doc.listParts()` |
281
+ | `partExists(partName)` | Check part exists | `if (await doc.partExists('...'))` |
282
+ | `getContentTypes()` | Get content types | `const types = await doc.getContentTypes()` |
283
+ | `addContentType(part, type)` | Register content type | `doc.addContentType('.json', 'application/json')` |
284
+
285
+ ### XML Parsing Utilities (Advanced)
286
+
287
+ | Method | Description | Example |
288
+ | -------------------------------------------- | ------------------------- | --------------------------------------------------------- |
289
+ | `XMLParser.parseToObject(xml, options?)` | Parse XML to JS object | `XMLParser.parseToObject(xml, {ignoreNamespace})` |
290
+ | `XMLParser.extractBody(docXml)` | Extract body from doc.xml | `XMLParser.extractBody(documentXml)` |
291
+ | `XMLParser.extractElements(xml, tagName)` | Extract elements by tag | `XMLParser.extractElements(xml, 'w:p')` |
292
+ | `XMLParser.extractAttribute(xml, name)` | Extract attribute value | `XMLParser.extractAttribute(xml, 'w:val')` |
293
+ | `XMLParser.extractText(xml)` | Extract all text content | `XMLParser.extractText(paraXml)` |
294
+ | `XMLParser.validateSize(xml, maxSize?)` | Validate XML size | `XMLParser.validateSize(xml, 10*1024*1024)` // 10MB |
295
+ | `DocumentParser.getRawXml(zip, part)` | Get raw XML from part | `DocumentParser.getRawXml(zipHandler, 'word/...')` |
296
+ | `DocumentParser.setRawXml(zip, part, xml)` | Set raw XML to part | `DocumentParser.setRawXml(zipHandler, 'word/...', xml)` |
297
+ | `DocumentParser.getRelationships(zip, part)` | Get part relationships | `DocumentParser.getRelationships(zipHandler, 'word/...')` |
298
+
299
+ #### parseToObject Options
300
+
301
+ | Option | Type | Default | Description |
302
+ | --------------------- | --------- | --------- | --------------------------------- |
303
+ | `ignoreAttributes` | `boolean` | `false` | Ignore all XML attributes |
304
+ | `attributeNamePrefix` | `string` | `'@_'` | Prefix for attribute names |
305
+ | `textNodeName` | `string` | `'#text'` | Property name for text content |
306
+ | `ignoreNamespace` | `boolean` | `false` | Remove namespace prefixes |
307
+ | `parseAttributeValue` | `boolean` | `true` | Parse numbers/booleans |
308
+ | `trimValues` | `boolean` | `true` | Trim whitespace from text |
309
+ | `alwaysArray` | `boolean` | `false` | Always return arrays for elements |
310
+
311
+ ### Unit Conversion Utilities
312
+
313
+ | Function | Description | Example |
314
+ | ---------------------------- | -------------------- | --------------------------- |
315
+ | `inchesToTwips(inches)` | Inches to twips | `inchesToTwips(1)` // 1440 |
316
+ | `inchesToEmus(inches)` | Inches to EMUs | `inchesToEmus(1)` // 914400 |
317
+ | `cmToTwips(cm)` | Centimeters to twips | `cmToTwips(2.54)` // 1440 |
318
+ | `pointsToTwips(points)` | Points to twips | `pointsToTwips(12)` // 240 |
319
+ | `pixelsToEmus(pixels, dpi?)` | Pixels to EMUs | `pixelsToEmus(96)` |
320
+
321
+ ## Common Recipes
322
+
323
+ ### Create a Simple Document
324
+
325
+ ```typescript
326
+ const doc = Document.create();
327
+ doc.createParagraph('Title').setStyle('Title');
328
+ doc.createParagraph('This is a simple document.');
329
+ await doc.save('simple.docx');
330
+ ```
331
+
332
+ ### Add Formatted Text
333
+
334
+ ```typescript
335
+ const para = doc.createParagraph();
336
+ para.addText('Bold', { bold: true });
337
+ para.addText(' and ');
338
+ para.addText('Colored', { color: 'FF0000' });
339
+ ```
340
+
341
+ ### Create a Table with Borders
342
+
343
+ ```typescript
344
+ const table = doc.createTable(3, 3);
345
+ table.setAllBorders({ style: 'single', size: 8, color: '000000' });
346
+ table.getCell(0, 0)?.createParagraph('Header 1');
347
+ table.getRow(0)?.getCell(0)?.setShading({ fill: '4472C4' });
348
+ ```
349
+
350
+ ### Insert an Image
351
+
352
+ ```typescript
353
+ import { Image, inchesToEmus } from 'docxmlater';
354
+
355
+ const image = Image.fromFile('./photo.jpg');
356
+ image.setWidth(inchesToEmus(4), true); // 4 inches, maintain ratio
357
+ doc.addImage(image);
358
+ ```
359
+
360
+ ### Add a Hyperlink
361
+
362
+ ```typescript
363
+ const para = doc.createParagraph();
364
+ para.addText('Visit ');
365
+ para.addHyperlink(Hyperlink.createExternal('https://example.com', 'our website'));
366
+ ```
367
+
368
+ ### Search and Replace Text
369
+
370
+ ```typescript
371
+ // Find all occurrences
372
+ const results = doc.findText('old text', { caseSensitive: true });
373
+ console.log(`Found ${results.length} occurrences`);
374
+
375
+ // Replace all
376
+ const count = doc.replaceText('old text', 'new text', { wholeWord: true });
377
+ console.log(`Replaced ${count} occurrences`);
378
+ ```
379
+
380
+ ### Load and Modify Existing Document
381
+
382
+ ```typescript
383
+ const doc = await Document.load('existing.docx');
384
+ doc.createParagraph('Added paragraph');
385
+
386
+ // Update all hyperlinks
387
+ const urlMap = new Map([['https://old-site.com', 'https://new-site.com']]);
388
+ doc.updateHyperlinkUrls(urlMap);
389
+
390
+ await doc.save('modified.docx');
391
+ ```
392
+
393
+ ### Create Lists
394
+
395
+ ```typescript
396
+ // Bullet list
397
+ const bulletId = doc.createBulletList(3);
398
+ doc.createParagraph('First item').setNumbering(bulletId, 0);
399
+ doc.createParagraph('Second item').setNumbering(bulletId, 0);
400
+
401
+ // Numbered list
402
+ const numberId = doc.createNumberedList(3);
403
+ doc.createParagraph('Step 1').setNumbering(numberId, 0);
404
+ doc.createParagraph('Step 2').setNumbering(numberId, 0);
405
+ ```
406
+
407
+ ### Apply Custom Styles
408
+
409
+ ```typescript
410
+ import { Style } from 'docxmlater';
411
+
412
+ const customStyle = Style.create({
413
+ styleId: 'CustomHeading',
414
+ name: 'Custom Heading',
415
+ basedOn: 'Normal',
416
+ runFormatting: { bold: true, size: 14, color: '2E74B5' },
417
+ paragraphFormatting: { alignment: 'center', spaceAfter: 240 },
418
+ });
419
+
420
+ doc.addStyle(customStyle);
421
+ doc.createParagraph('Custom Styled Text').setStyle('CustomHeading');
422
+ ```
423
+
424
+ ### Add Headers and Footers
425
+
426
+ ```typescript
427
+ import { Header, Footer, Field } from 'docxmlater';
428
+
429
+ // Header with page numbers
430
+ const header = Header.create();
431
+ header.addParagraph('Document Title').setAlignment('center');
432
+
433
+ // Footer with page numbers
434
+ const footer = Footer.create();
435
+ const footerPara = footer.addParagraph();
436
+ footerPara.addText('Page ');
437
+ footerPara.addField(Field.create({ type: 'PAGE' }));
438
+ footerPara.addText(' of ');
439
+ footerPara.addField(Field.create({ type: 'NUMPAGES' }));
440
+
441
+ doc.setHeader(header);
442
+ doc.setFooter(footer);
443
+ ```
444
+
445
+ ### Work with Document Statistics
446
+
447
+ ```typescript
448
+ // Get word and character counts
449
+ console.log('Words:', doc.getWordCount());
450
+ console.log('Characters:', doc.getCharacterCount());
451
+ console.log('Characters (no spaces):', doc.getCharacterCount(false));
452
+
453
+ // Check document size
454
+ const size = doc.estimateSize();
455
+ if (size.warning) {
456
+ console.warn(size.warning);
457
+ }
458
+ console.log(`Estimated size: ${size.totalEstimatedMB} MB`);
459
+ ```
460
+
461
+ ### Handle Large Documents Efficiently
462
+
463
+ ```typescript
464
+ const doc = Document.create({
465
+ maxMemoryUsagePercent: 80,
466
+ maxRssMB: 2048,
467
+ maxImageCount: 50,
468
+ maxTotalImageSizeMB: 100,
469
+ });
470
+
471
+ // Process document...
472
+
473
+ // Clean up resources after saving
474
+ await doc.save('large-document.docx');
475
+ doc.dispose(); // Free memory
476
+ ```
477
+
478
+ ### Parse XML to JavaScript Objects (Advanced)
479
+
480
+ ```typescript
481
+ import { XMLParser, DocumentParser } from 'docxmlater';
482
+
483
+ // Parse relationships
484
+ const relsXml = DocumentParser.getRawXml(doc.zipHandler, 'word/_rels/document.xml.rels');
485
+ if (relsXml) {
486
+ const parsed = XMLParser.parseToObject(relsXml);
487
+
488
+ // Access relationships
489
+ const relationships = Array.isArray(parsed.Relationships.Relationship)
490
+ ? parsed.Relationships.Relationship
491
+ : [parsed.Relationships.Relationship];
492
+
493
+ relationships.forEach((rel) => {
494
+ console.log(`${rel['@_Id']}: ${rel['@_Target']}`);
495
+ });
496
+ }
497
+
498
+ // Parse with options
499
+ const stylesXml = DocumentParser.getRawXml(doc.zipHandler, 'word/styles.xml');
500
+ if (stylesXml) {
501
+ const styles = XMLParser.parseToObject(stylesXml, {
502
+ ignoreNamespace: true, // Strip w: prefix
503
+ parseAttributeValue: true, // Convert "123" to 123
504
+ attributeNamePrefix: '$', // Use $ instead of @_
505
+ });
506
+ }
507
+
508
+ // Extract specific elements
509
+ const docXml = DocumentParser.getRawXml(doc.zipHandler, 'word/document.xml');
510
+ if (docXml) {
511
+ const paragraphs = XMLParser.extractElements(docXml, 'w:p');
512
+ console.log(`Found ${paragraphs.length} paragraphs`);
513
+
514
+ paragraphs.forEach((paraXml) => {
515
+ const text = XMLParser.extractText(paraXml);
516
+ if (text) console.log(`Paragraph text: ${text}`);
517
+ });
518
+ }
519
+ ```
520
+
521
+ ### Direct XML Access (Advanced)
522
+
523
+ ```typescript
524
+ // Get raw XML
525
+ const documentXml = await doc.getPart('word/document.xml');
526
+ console.log(documentXml?.content);
527
+
528
+ // Modify raw XML (use with caution)
529
+ await doc.setPart('word/custom.xml', '<custom>data</custom>');
530
+ await doc.addContentType('/word/custom.xml', 'application/xml');
531
+
532
+ // List all parts
533
+ const parts = await doc.listParts();
534
+ console.log('Document contains:', parts.length, 'parts');
535
+ ```
536
+
537
+ ## Features
538
+
539
+ - **Full OpenXML Compliance** - Follows ECMA-376 standard
540
+ - **TypeScript First** - Complete type definitions
541
+ - **Memory Efficient** - Handles large documents with streaming
542
+ - **Atomic Saves** - Prevents corruption with temp file pattern
543
+ - **Rich Formatting** - Complete text and paragraph formatting
544
+ - **Tables** - Full support with borders, shading, merging
545
+ - **Images** - PNG, JPEG, GIF with sizing and positioning
546
+ - **Hyperlinks** - External, internal, and email links
547
+ - **Styles** - 13 built-in styles + custom style creation
548
+ - **Lists** - Bullets, numbering, multi-level
549
+ - **Headers/Footers** - Different first/even/odd pages
550
+ - **Search & Replace** - With case and whole word options
551
+ - **Document Stats** - Word count, character count, size estimation
552
+ - **Track Changes** - Insertions and deletions with authors
553
+ - **Comments** - With replies and threading
554
+ - **Bookmarks** - For internal navigation
555
+ - **XML Parsing** - Native position-based parser (ReDoS-safe, fast-xml-parser compatible)
556
+ - **Low-level Access** - Direct ZIP and XML manipulation
557
+
558
+ ## Performance
559
+
560
+ - Process 100+ page documents efficiently
561
+ - Atomic save pattern prevents corruption
562
+ - Memory management for large files
563
+ - Lazy loading of document parts
564
+ - Resource cleanup with `dispose()`
565
+
566
+ ## Testing
567
+
568
+ ```bash
569
+ npm test # Run all tests
570
+ npm run test:watch # Watch mode
571
+ npm run test:coverage # Coverage report
572
+ ```
573
+
574
+ **Current:** 253 tests passing | 100% core functionality covered
575
+
576
+ ## Development
577
+
578
+ ```bash
579
+ # Install dependencies
580
+ npm install
581
+
582
+ # Build TypeScript
583
+ npm run build
584
+
585
+ # Run examples
586
+ npx ts-node examples/simple-document.ts
587
+ ```
588
+
589
+ ## Project Structure
590
+
591
+ ```text
592
+ src/
593
+ ├── core/ # Document, Parser, Generator, Validator
594
+ ├── elements/ # Paragraph, Run, Table, Image, Hyperlink
595
+ ├── formatting/ # Style, NumberingManager
596
+ ├── xml/ # XMLBuilder, XMLParser
597
+ ├── zip/ # ZipHandler for DOCX manipulation
598
+ └── utils/ # Validation, Units conversion
599
+
600
+ examples/
601
+ ├── 01-basic/ # Simple document creation
602
+ ├── 02-text/ # Text formatting examples
603
+ ├── 03-tables/ # Table examples
604
+ ├── 04-styles/ # Style examples
605
+ ├── 05-images/ # Image handling
606
+ ├── 06-complete/ # Full document examples
607
+ └── 07-hyperlinks/ # Link examples
608
+ ```
609
+
610
+ ## Hierarchy
611
+
612
+ ```text
613
+ w:document (root)
614
+ └── w:body (body container)
615
+ ├── w:p (paragraph) [1..n]
616
+ │ ├── w:pPr (paragraph properties) [0..1]
617
+ │ │ ├── w:pStyle (style reference)
618
+ │ │ ├── w:jc (justification/alignment)
619
+ │ │ ├── w:ind (indentation)
620
+ │ │ └── w:spacing (spacing before/after)
621
+ │ ├── w:r (run) [1..n]
622
+ │ │ ├── w:rPr (run properties) [0..1]
623
+ │ │ │ ├── w:b (bold)
624
+ │ │ │ ├── w:i (italic)
625
+ │ │ │ ├── w:u (underline)
626
+ │ │ │ ├── w:sz (font size)
627
+ │ │ │ └── w:color (text color)
628
+ │ │ └── w:t (text content) [1]
629
+ │ ├── w:hyperlink (hyperlink) [0..n]
630
+ │ │ └── w:r (run with hyperlink text)
631
+ │ └── w:drawing (embedded image/shape) [0..n]
632
+ ├── w:tbl (table) [1..n]
633
+ │ ├── w:tblPr (table properties)
634
+ │ └── w:tr (table row) [1..n]
635
+ │ └── w:tc (table cell) [1..n]
636
+ │ └── w:p (paragraph in cell)
637
+ └── w:sectPr (section properties) [1] (must be last child of w:body)
638
+ ```
639
+
640
+ ## Requirements
641
+
642
+ - Node.js 16+
643
+ - TypeScript 5.0+ (for development)
644
+
645
+ ## Installation Options
646
+
647
+ ```bash
648
+ # NPM
649
+ npm install docxmlater
650
+
651
+ # Yarn
652
+ yarn add docxmlater
653
+
654
+ # PNPM
655
+ pnpm add docxmlater
656
+ ```
657
+
658
+ ## Contributing
659
+
660
+ Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md).
661
+
662
+ 1. Fork the repository
663
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
664
+ 3. Commit changes (`git commit -m 'Add amazing feature'`)
665
+ 4. Push to branch (`git push origin feature/amazing-feature`)
666
+ 5. Open a Pull Request
667
+
668
+ ## License
669
+
670
+ MIT © DiaTech
671
+
672
+ ## Acknowledgments
673
+
674
+ - **Built with [JSZip](https://stuk.github.io/jszip/)** - Core ZIP archive handling (read/write/modify .docx containers)
675
+ - **Follows [ECMA-376](https://www.ecma-international.org/publications-and-standards/standards/ecma-376/)** - Office Open XML standard compliance
676
+ - **Inspired by [python-docx](https://python-docx.readthedocs.io/)** - API design patterns and document structure
677
+ - **Inspired by [docx](https://github.com/dolanmiu/docx)** - TypeScript implementation approach
678
+
679
+ ### What docXMLater Does Independently
680
+
681
+ Unlike other libraries, docXMLater implements these features **without external dependencies**:
682
+
683
+ - ✅ **XML Parsing** - Custom position-based parser (no `xml2js`, `fast-xml-parser`, or `sax`)
684
+ - ReDoS-safe parsing via position tracking instead of regex
685
+ - Compatible with `fast-xml-parser` output format
686
+ - Handles OOXML structures natively
687
+
688
+ - ✅ **XML Generation** - Native XMLBuilder (no external XML libraries)
689
+ - OpenXML-compliant namespace handling
690
+ - Attribute escaping and text node handling
691
+ - Self-closing tag validation
692
+
693
+ - ✅ **Document Validation** - Built-in OOXML validator
694
+ - Structure validation per ECMA-376
695
+ - Relationship integrity checking
696
+ - Content type verification
697
+
698
+ - ✅ **Relationship Management** - Custom implementation
699
+ - Automatic ID generation and tracking
700
+ - Orphan relationship cleanup
701
+ - Multi-part relationship handling
702
+
703
+ - ✅ **UTF-8 Encoding** - Native encoding handling
704
+ - Automatic Buffer conversion
705
+ - Cross-platform compatibility
706
+ - No encoding library dependencies
707
+
708
+ **Philosophy**: We only depend on what we can't reasonably implement ourselves (ZIP handling) and implement everything else for maximum control, security, and correctness.
709
+
710
+ ## Support
711
+
712
+ - **Documentation**: [Full Docs](https://github.com/ItMeDiaTech/docXMLater/tree/main/docs)
713
+ - **Examples**: [Example Code](https://github.com/ItMeDiaTech/docXMLater/tree/main/examples)
714
+ - **Issues**: [GitHub Issues](https://github.com/ItMeDiaTech/docXMLater/issues)
715
+ - **Discussions**: [GitHub Discussions](https://github.com/ItMeDiaTech/docXMLater/discussions)
716
+
717
+ ## Quick Links
718
+
719
+ - [NPM Package](https://www.npmjs.com/package/docxmlater)
720
+ - [GitHub Repository](https://github.com/ItMeDiaTech/docXMLater)
721
+ - [API Reference](https://github.com/ItMeDiaTech/docXMLater/tree/main/docs/api)
722
+ - [Change Log](https://github.com/ItMeDiaTech/docXMLater/blob/main/CHANGELOG.md)
723
+
724
+ ---
725
+
726
+ **Ready to create amazing Word documents?** Start with our [examples](https://github.com/ItMeDiaTech/docXMLater/tree/main/examples) or dive into the [API Reference](#complete-api-reference) above!