docxmlater 10.3.5 → 10.4.0
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.
- package/README.md +158 -7
- package/dist/core/Document.d.ts +102 -3
- package/dist/core/Document.d.ts.map +1 -1
- package/dist/core/Document.js +775 -50
- package/dist/core/Document.js.map +1 -1
- package/dist/core/DocumentContent.d.ts.map +1 -1
- package/dist/core/DocumentContent.js +0 -8
- package/dist/core/DocumentContent.js.map +1 -1
- package/dist/core/DocumentGenerator.d.ts.map +1 -1
- package/dist/core/DocumentGenerator.js +9 -5
- package/dist/core/DocumentGenerator.js.map +1 -1
- package/dist/core/DocumentParser.d.ts.map +1 -1
- package/dist/core/DocumentParser.js +588 -102
- package/dist/core/DocumentParser.js.map +1 -1
- package/dist/core/RelationshipManager.d.ts.map +1 -1
- package/dist/core/RelationshipManager.js +4 -3
- package/dist/core/RelationshipManager.js.map +1 -1
- package/dist/elements/Bookmark.d.ts +7 -0
- package/dist/elements/Bookmark.d.ts.map +1 -1
- package/dist/elements/Bookmark.js +24 -4
- package/dist/elements/Bookmark.js.map +1 -1
- package/dist/elements/BookmarkManager.d.ts.map +1 -1
- package/dist/elements/BookmarkManager.js +4 -3
- package/dist/elements/BookmarkManager.js.map +1 -1
- package/dist/elements/CommonTypes.d.ts +2 -2
- package/dist/elements/CommonTypes.d.ts.map +1 -1
- package/dist/elements/CommonTypes.js +14 -1
- package/dist/elements/CommonTypes.js.map +1 -1
- package/dist/elements/Field.d.ts +1 -1
- package/dist/elements/Field.d.ts.map +1 -1
- package/dist/elements/Field.js +1 -1
- package/dist/elements/Field.js.map +1 -1
- package/dist/elements/Footer.d.ts +2 -0
- package/dist/elements/Footer.d.ts.map +1 -1
- package/dist/elements/Footer.js +6 -0
- package/dist/elements/Footer.js.map +1 -1
- package/dist/elements/Header.d.ts +2 -0
- package/dist/elements/Header.d.ts.map +1 -1
- package/dist/elements/Header.js +6 -0
- package/dist/elements/Header.js.map +1 -1
- package/dist/elements/Image.d.ts +1 -0
- package/dist/elements/Image.d.ts.map +1 -1
- package/dist/elements/Image.js +17 -2
- package/dist/elements/Image.js.map +1 -1
- package/dist/elements/Paragraph.d.ts +81 -1
- package/dist/elements/Paragraph.d.ts.map +1 -1
- package/dist/elements/Paragraph.js +515 -21
- package/dist/elements/Paragraph.js.map +1 -1
- package/dist/elements/Revision.d.ts +0 -1
- package/dist/elements/Revision.d.ts.map +1 -1
- package/dist/elements/Revision.js +0 -12
- package/dist/elements/Revision.js.map +1 -1
- package/dist/elements/RevisionManager.d.ts +0 -1
- package/dist/elements/RevisionManager.d.ts.map +1 -1
- package/dist/elements/RevisionManager.js +0 -2
- package/dist/elements/RevisionManager.js.map +1 -1
- package/dist/elements/Run.d.ts +16 -4
- package/dist/elements/Run.d.ts.map +1 -1
- package/dist/elements/Run.js +114 -22
- package/dist/elements/Run.js.map +1 -1
- package/dist/elements/Section.d.ts +7 -1
- package/dist/elements/Section.d.ts.map +1 -1
- package/dist/elements/Section.js +185 -4
- package/dist/elements/Section.js.map +1 -1
- package/dist/elements/Shape.js.map +1 -1
- package/dist/elements/Table.d.ts +30 -1
- package/dist/elements/Table.d.ts.map +1 -1
- package/dist/elements/Table.js +357 -40
- package/dist/elements/Table.js.map +1 -1
- package/dist/elements/TableCell.d.ts +3 -0
- package/dist/elements/TableCell.d.ts.map +1 -1
- package/dist/elements/TableCell.js +30 -3
- package/dist/elements/TableCell.js.map +1 -1
- package/dist/elements/TableGridChange.d.ts +0 -1
- package/dist/elements/TableGridChange.d.ts.map +1 -1
- package/dist/elements/TableGridChange.js +0 -10
- package/dist/elements/TableGridChange.js.map +1 -1
- package/dist/elements/TableRow.d.ts +4 -0
- package/dist/elements/TableRow.d.ts.map +1 -1
- package/dist/elements/TableRow.js +31 -3
- package/dist/elements/TableRow.js.map +1 -1
- package/dist/formatting/AbstractNumbering.d.ts +5 -0
- package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
- package/dist/formatting/AbstractNumbering.js +22 -0
- package/dist/formatting/AbstractNumbering.js.map +1 -1
- package/dist/formatting/NumberingLevel.d.ts.map +1 -1
- package/dist/formatting/NumberingLevel.js +3 -3
- package/dist/formatting/NumberingLevel.js.map +1 -1
- package/dist/formatting/Style.d.ts +1 -0
- package/dist/formatting/Style.d.ts.map +1 -1
- package/dist/formatting/Style.js +25 -59
- package/dist/formatting/Style.js.map +1 -1
- package/dist/formatting/StylesManager.d.ts +1 -0
- package/dist/formatting/StylesManager.d.ts.map +1 -1
- package/dist/formatting/StylesManager.js +12 -0
- package/dist/formatting/StylesManager.js.map +1 -1
- package/dist/helpers/CleanupHelper.js.map +1 -1
- package/dist/images/ImageOptimizer.d.ts.map +1 -1
- package/dist/images/ImageOptimizer.js +0 -1
- package/dist/images/ImageOptimizer.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/managers/DrawingManager.d.ts.map +1 -1
- package/dist/managers/DrawingManager.js +4 -2
- package/dist/managers/DrawingManager.js.map +1 -1
- package/dist/types/formatting.d.ts +2 -2
- package/dist/types/formatting.d.ts.map +1 -1
- package/dist/types/formatting.js.map +1 -1
- package/dist/utils/ChangelogGenerator.d.ts +2 -2
- package/dist/utils/ChangelogGenerator.d.ts.map +1 -1
- package/dist/utils/ChangelogGenerator.js +4 -5
- package/dist/utils/ChangelogGenerator.js.map +1 -1
- package/dist/utils/InMemoryRevisionAcceptor.d.ts.map +1 -1
- package/dist/utils/InMemoryRevisionAcceptor.js +0 -1
- package/dist/utils/InMemoryRevisionAcceptor.js.map +1 -1
- package/dist/utils/RevisionAwareProcessor.d.ts +2 -2
- package/dist/utils/RevisionAwareProcessor.d.ts.map +1 -1
- package/dist/utils/RevisionAwareProcessor.js +2 -2
- package/dist/utils/RevisionAwareProcessor.js.map +1 -1
- package/dist/utils/SelectiveRevisionAcceptor.d.ts +0 -2
- package/dist/utils/SelectiveRevisionAcceptor.d.ts.map +1 -1
- package/dist/utils/SelectiveRevisionAcceptor.js +0 -26
- package/dist/utils/SelectiveRevisionAcceptor.js.map +1 -1
- package/dist/utils/ShadingResolver.d.ts.map +1 -1
- package/dist/utils/ShadingResolver.js.map +1 -1
- package/dist/utils/acceptRevisions.js +1 -1
- package/dist/utils/acceptRevisions.js.map +1 -1
- package/dist/utils/stripTrackedChanges.js +1 -1
- package/dist/utils/stripTrackedChanges.js.map +1 -1
- package/dist/utils/units.d.ts.map +1 -1
- package/dist/utils/units.js +1 -1
- package/dist/utils/units.js.map +1 -1
- package/dist/validation/RevisionAutoFixer.d.ts +2 -1
- package/dist/validation/RevisionAutoFixer.d.ts.map +1 -1
- package/dist/validation/RevisionAutoFixer.js.map +1 -1
- package/package.json +10 -1
- package/src/constants/CLAUDE.md +28 -0
- package/src/core/CLAUDE.md +4 -0
- package/src/core/Document.ts +1888 -137
- package/src/core/DocumentContent.ts +0 -11
- package/src/core/DocumentGenerator.ts +11 -12
- package/src/core/DocumentParser.ts +620 -139
- package/src/core/RelationshipManager.ts +6 -3
- package/src/elements/Bookmark.ts +39 -4
- package/src/elements/BookmarkManager.ts +4 -3
- package/src/elements/CLAUDE.md +18 -2
- package/src/elements/CommonTypes.ts +35 -8
- package/src/elements/Field.ts +1 -1
- package/src/elements/Footer.ts +23 -0
- package/src/elements/Header.ts +25 -0
- package/src/elements/Image.ts +28 -5
- package/src/elements/Paragraph.ts +1069 -41
- package/src/elements/Revision.ts +0 -19
- package/src/elements/RevisionManager.ts +1 -3
- package/src/elements/Run.ts +265 -35
- package/src/elements/Section.ts +214 -8
- package/src/elements/Shape.ts +1 -1
- package/src/elements/Table.ts +850 -61
- package/src/elements/TableCell.ts +84 -10
- package/src/elements/TableGridChange.ts +2 -16
- package/src/elements/TableRow.ts +94 -9
- package/src/formatting/AbstractNumbering.ts +42 -1
- package/src/formatting/CLAUDE.md +4 -0
- package/src/formatting/NumberingLevel.ts +11 -7
- package/src/formatting/Style.ts +39 -71
- package/src/formatting/StylesManager.ts +36 -0
- package/src/helpers/CleanupHelper.ts +1 -1
- package/src/images/ImageOptimizer.ts +0 -3
- package/src/index.ts +1 -1
- package/src/managers/DrawingManager.ts +5 -3
- package/src/tracking/CLAUDE.md +30 -0
- package/src/types/CLAUDE.md +39 -0
- package/src/types/formatting.ts +2 -2
- package/src/utils/CLAUDE.md +15 -0
- package/src/utils/ChangelogGenerator.ts +4 -5
- package/src/utils/InMemoryRevisionAcceptor.ts +0 -9
- package/src/utils/RevisionAwareProcessor.ts +2 -3
- package/src/utils/SelectiveRevisionAcceptor.ts +0 -39
- package/src/utils/ShadingResolver.ts +0 -1
- package/src/utils/acceptRevisions.ts +1 -1
- package/src/utils/stripTrackedChanges.ts +1 -1
- package/src/utils/units.ts +2 -1
- package/src/validation/CLAUDE.md +40 -0
- package/src/validation/RevisionAutoFixer.ts +2 -1
|
@@ -192,6 +192,42 @@ export class StylesManager {
|
|
|
192
192
|
return this.styles.get(styleId);
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
+
/**
|
|
196
|
+
* Clones an existing style with a new ID and optional name
|
|
197
|
+
*
|
|
198
|
+
* Deep-copies the source style (including all run, paragraph, and table
|
|
199
|
+
* formatting) and registers the clone with the new ID. If `newName` is
|
|
200
|
+
* not provided, the clone's name is set to the new ID.
|
|
201
|
+
*
|
|
202
|
+
* @param sourceId - ID of the style to clone
|
|
203
|
+
* @param newId - ID for the cloned style (must be unique)
|
|
204
|
+
* @param newName - Display name for the clone (defaults to newId)
|
|
205
|
+
* @returns The cloned Style, or undefined if source not found
|
|
206
|
+
*
|
|
207
|
+
* @example
|
|
208
|
+
* ```typescript
|
|
209
|
+
* // Create a variant of Heading1
|
|
210
|
+
* const variant = stylesManager.cloneStyle('Heading1', 'Heading1Blue', 'Blue Heading 1');
|
|
211
|
+
* variant?.setRunFormatting({ ...variant.getRunFormatting(), color: '0000FF' });
|
|
212
|
+
*
|
|
213
|
+
* // Clone a custom style for a different section
|
|
214
|
+
* stylesManager.cloneStyle('CustomNote', 'CustomNoteAlt');
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
217
|
+
cloneStyle(sourceId: string, newId: string, newName?: string): Style | undefined {
|
|
218
|
+
const source = this.getStyle(sourceId);
|
|
219
|
+
if (!source) return undefined;
|
|
220
|
+
|
|
221
|
+
const props = source.getProperties();
|
|
222
|
+
props.styleId = newId;
|
|
223
|
+
props.name = newName ?? newId;
|
|
224
|
+
props.isDefault = false; // Clones should never be default
|
|
225
|
+
|
|
226
|
+
const cloned = new Style(props);
|
|
227
|
+
this.addStyle(cloned);
|
|
228
|
+
return cloned;
|
|
229
|
+
}
|
|
230
|
+
|
|
195
231
|
/**
|
|
196
232
|
* Checks if a style exists or can be loaded
|
|
197
233
|
* @param styleId - Style ID to check
|
|
@@ -437,7 +437,7 @@ export class CleanupHelper {
|
|
|
437
437
|
};
|
|
438
438
|
|
|
439
439
|
// Helper to process paragraph content
|
|
440
|
-
const processParagraph = (paragraph:
|
|
440
|
+
const processParagraph = (paragraph: Paragraph): void => {
|
|
441
441
|
for (const item of paragraph.getContent()) {
|
|
442
442
|
// Process all Hyperlink instances (both internal AND external)
|
|
443
443
|
if (item instanceof Hyperlink) {
|
|
@@ -69,9 +69,6 @@ function buildPngChunk(type: string, data: Buffer): Buffer {
|
|
|
69
69
|
// PNG Re-compression
|
|
70
70
|
// =============================================================================
|
|
71
71
|
|
|
72
|
-
/** Chunks that must be preserved for correct PNG rendering */
|
|
73
|
-
const ESSENTIAL_CHUNK_TYPES = new Set(['IHDR', 'PLTE', 'tRNS', 'IDAT', 'IEND']);
|
|
74
|
-
|
|
75
72
|
/**
|
|
76
73
|
* Re-compresses a PNG buffer at zlib level 9 and strips non-essential metadata chunks.
|
|
77
74
|
* Returns the optimized buffer, or null if the PNG is invalid/cannot be optimized.
|
package/src/index.ts
CHANGED
|
@@ -35,7 +35,7 @@ export {
|
|
|
35
35
|
isShape,
|
|
36
36
|
isTextBox,
|
|
37
37
|
} from './elements/Paragraph';
|
|
38
|
-
export { Run, RunFormatting, ThemeColorValue } from './elements/Run';
|
|
38
|
+
export { Run, RunFormatting, ThemeColorValue, LanguageConfig } from './elements/Run';
|
|
39
39
|
export {
|
|
40
40
|
Section,
|
|
41
41
|
PageOrientation,
|
|
@@ -256,14 +256,16 @@ export class DrawingManager {
|
|
|
256
256
|
* @param drawing Drawing to check
|
|
257
257
|
* @returns True if PreservedDrawing
|
|
258
258
|
*/
|
|
259
|
-
private isPreservedDrawing(drawing:
|
|
259
|
+
private isPreservedDrawing(drawing: unknown): drawing is PreservedDrawing {
|
|
260
260
|
return (
|
|
261
|
-
drawing &&
|
|
261
|
+
!!drawing &&
|
|
262
262
|
typeof drawing === 'object' &&
|
|
263
263
|
'type' in drawing &&
|
|
264
264
|
'xml' in drawing &&
|
|
265
265
|
'relationshipIds' in drawing &&
|
|
266
|
-
(drawing
|
|
266
|
+
((drawing as PreservedDrawing).type === 'smartart' ||
|
|
267
|
+
(drawing as PreservedDrawing).type === 'chart' ||
|
|
268
|
+
(drawing as PreservedDrawing).type === 'wordart')
|
|
267
269
|
);
|
|
268
270
|
}
|
|
269
271
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Tracking Module
|
|
2
|
+
|
|
3
|
+
`src/tracking/` — Change tracking context for revision-aware document editing.
|
|
4
|
+
|
|
5
|
+
## Interfaces & Classes
|
|
6
|
+
|
|
7
|
+
### TrackingContext (interface)
|
|
8
|
+
|
|
9
|
+
Contract for tracking changes on document elements. Methods:
|
|
10
|
+
|
|
11
|
+
- `trackRunPropertyChange(run, previousProps)` — creates `w:rPrChange`
|
|
12
|
+
- `trackParagraphPropertyChange(para, previousProps)` — creates `w:pPrChange`
|
|
13
|
+
- `trackTableChange(table, previousProps)` — creates `w:tblPrChange`
|
|
14
|
+
- `trackInsertion(element)` / `trackDeletion(element)` — wraps in `w:ins`/`w:del`
|
|
15
|
+
- `flushPendingChanges()` — converts queued changes to Revision objects
|
|
16
|
+
- `isEnabled()` — check if tracking is active
|
|
17
|
+
|
|
18
|
+
### DocumentTrackingContext (`DocumentTrackingContext.ts`)
|
|
19
|
+
|
|
20
|
+
Implementation of `TrackingContext`. Key behaviors:
|
|
21
|
+
|
|
22
|
+
- **State:** enabled flag, author name, `trackFormatting` toggle, pending changes map
|
|
23
|
+
- **Consolidation:** Groups changes by element with time-window keys to batch similar edits (prevents one revision per keystroke)
|
|
24
|
+
- **PrChange application:** Creates/merges `*PrChange` markers (`rPrChange`, `pPrChange`, `tblPrChange`, `tcPrChange`, `sectPrChange`) per ECMA-376
|
|
25
|
+
- **Full snapshot tracking:** Stores complete previous properties (not deltas) for table/cell/section changes
|
|
26
|
+
- **WeakMap for element IDs:** Prevents GC issues with stable element references
|
|
27
|
+
|
|
28
|
+
## Key Pattern
|
|
29
|
+
|
|
30
|
+
Call `doc.flushPendingChanges()` before inspecting `pPrChange` or `rPrChange` in tests — pending changes are batched and only materialized on flush or save.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Types Module
|
|
2
|
+
|
|
3
|
+
`src/types/` — TypeScript type definitions shared across modules.
|
|
4
|
+
|
|
5
|
+
## Files
|
|
6
|
+
|
|
7
|
+
### `formatting.ts`
|
|
8
|
+
Formatting-related types used by Document search/replace and paragraph formatting:
|
|
9
|
+
- `BorderStyleType`, `BorderStyle`, `ParagraphBorder` — border definitions
|
|
10
|
+
- `ShadingPattern`, `ParagraphShading` — re-exported from CommonTypes
|
|
11
|
+
- `TabAlignment`, `TabLeader`, `TabStop` — tab stop configuration
|
|
12
|
+
- `FindOptions`, `ReplaceOptions`, `SearchResult` — text search/replace options
|
|
13
|
+
- `EmphasisType`, `ListPrefix`, `FormatOptions`, `StyleApplyOptions` — style application
|
|
14
|
+
|
|
15
|
+
### `styleConfig.ts`
|
|
16
|
+
Style configuration interfaces for Document's style application methods:
|
|
17
|
+
- `StyleRunFormatting` — character-level formatting (font, size, bold, etc.)
|
|
18
|
+
- `StyleParagraphFormatting` — paragraph-level formatting (alignment, spacing, indentation)
|
|
19
|
+
- `StyleConfig`, `Heading2Config`, `NormalConfig` — predefined style configurations
|
|
20
|
+
- `ApplyStylesOptions` — options for `doc.applyStyles()` / `doc.applyStylesFromObjects()`
|
|
21
|
+
- `ApplyCustomFormattingOptions` — deprecated alias for `ApplyStylesOptions`
|
|
22
|
+
|
|
23
|
+
### `settings-types.ts`
|
|
24
|
+
Document settings interfaces:
|
|
25
|
+
- `DocumentProtection` — password protection settings
|
|
26
|
+
- `RevisionViewSettings` — revision display mode
|
|
27
|
+
- `TrackChangesSettings` — track changes configuration
|
|
28
|
+
- `WebSettingsInfo` — web settings (div cleanup, encoding)
|
|
29
|
+
|
|
30
|
+
### `list-types.ts`
|
|
31
|
+
List detection and normalization:
|
|
32
|
+
- `ListCategory`, `NumberFormat`, `BulletFormat` — list type classification
|
|
33
|
+
- `ListDetectionResult`, `ListAnalysis` — detection output
|
|
34
|
+
- `ListNormalizationOptions`, `ListNormalizationReport` — normalization config/results
|
|
35
|
+
|
|
36
|
+
### `compatibility-types.ts`
|
|
37
|
+
Word compatibility mode types:
|
|
38
|
+
- `CompatSetting` — individual compatibility setting (name, uri, val)
|
|
39
|
+
- `CompatibilityInfo` — full compatibility state (mode value, legacy flags, modern settings)
|
package/src/types/formatting.ts
CHANGED
|
@@ -56,12 +56,12 @@ export type { ShadingConfig as ParagraphShading } from '../elements/CommonTypes'
|
|
|
56
56
|
/**
|
|
57
57
|
* Tab stop alignment
|
|
58
58
|
*/
|
|
59
|
-
export type TabAlignment = 'left' | 'center' | 'right' | 'decimal' | 'bar' | 'clear';
|
|
59
|
+
export type TabAlignment = 'left' | 'center' | 'right' | 'decimal' | 'bar' | 'clear' | 'num';
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
62
|
* Tab leader character
|
|
63
63
|
*/
|
|
64
|
-
export type TabLeader = 'none' | 'dot' | '
|
|
64
|
+
export type TabLeader = 'none' | 'dot' | 'hyphen' | 'underscore' | 'heavy' | 'middleDot';
|
|
65
65
|
|
|
66
66
|
/**
|
|
67
67
|
* Tab stop configuration
|
package/src/utils/CLAUDE.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
`src/utils/` — Standalone utilities (22 TypeScript files) for unit conversions, revision processing, validation, logging, and helpers.
|
|
4
4
|
|
|
5
|
+
## Architecture Classification
|
|
6
|
+
|
|
7
|
+
**Pure utilities** (no element/core imports — safe to use anywhere):
|
|
8
|
+
- `units.ts`, `validation.ts`, `deepClone.ts`, `dateFormatting.ts`, `errorHandling.ts`
|
|
9
|
+
- `xmlSanitization.ts`, `formatting.ts`, `parsingHelpers.ts`, `logger.ts`, `diagnostics.ts`
|
|
10
|
+
- `textDiff.ts`, `list-detection.ts`, `corruptionDetection.ts`
|
|
11
|
+
|
|
12
|
+
**Domain-specific processors** (import from elements/core — should arguably be in `src/processors/`):
|
|
13
|
+
- `acceptRevisions.ts`, `RevisionWalker.ts`, `InMemoryRevisionAcceptor.ts`
|
|
14
|
+
- `SelectiveRevisionAcceptor.ts`, `RevisionAwareProcessor.ts`, `MoveOperationHelper.ts`
|
|
15
|
+
- `ChangelogGenerator.ts`, `ShadingResolver.ts`, `stripTrackedChanges.ts`
|
|
16
|
+
- `CompatibilityUpgrader.ts`, `cnfStyleDecoder.ts`
|
|
17
|
+
|
|
18
|
+
This split explains the 36+ dependency-cruiser warnings about utils importing elements — the domain-specific files are processors, not pure utilities.
|
|
19
|
+
|
|
5
20
|
## Unit Conversions (`units.ts`)
|
|
6
21
|
|
|
7
22
|
40+ conversion functions between twips, EMUs, points, half-points, pixels, inches, centimeters.
|
|
@@ -198,7 +198,7 @@ export class ChangelogGenerator {
|
|
|
198
198
|
static fromRevisions(
|
|
199
199
|
revisions: Revision[],
|
|
200
200
|
options?: ChangelogOptions,
|
|
201
|
-
|
|
201
|
+
_doc?: Document
|
|
202
202
|
): ChangeEntry[] {
|
|
203
203
|
const logger = getLogger();
|
|
204
204
|
const opts = {
|
|
@@ -619,7 +619,6 @@ export class ChangelogGenerator {
|
|
|
619
619
|
*/
|
|
620
620
|
static describeRevision(revision: Revision, maxLength = 50): string {
|
|
621
621
|
const type = revision.getType();
|
|
622
|
-
const author = revision.getAuthor();
|
|
623
622
|
const runs = revision.getRuns();
|
|
624
623
|
const text = runs.map((r) => r.getText()).join('');
|
|
625
624
|
const excerpt =
|
|
@@ -676,7 +675,7 @@ export class ChangelogGenerator {
|
|
|
676
675
|
/**
|
|
677
676
|
* Generate description for a hyperlink change revision.
|
|
678
677
|
*/
|
|
679
|
-
private static describeHyperlinkChange(revision: Revision,
|
|
678
|
+
private static describeHyperlinkChange(revision: Revision, _maxLength: number): string {
|
|
680
679
|
const prevProps = revision.getPreviousProperties() || {};
|
|
681
680
|
const newProps = revision.getNewProperties() || {};
|
|
682
681
|
const changes: string[] = [];
|
|
@@ -883,7 +882,7 @@ export class ChangelogGenerator {
|
|
|
883
882
|
// Truncate if too long
|
|
884
883
|
return json.length > 100 ? json.substring(0, 97) + '...' : json;
|
|
885
884
|
} catch (e) {
|
|
886
|
-
getLogger().
|
|
885
|
+
getLogger().warn('Failed to stringify value for changelog', { error: String(e) });
|
|
887
886
|
return '[complex value]';
|
|
888
887
|
}
|
|
889
888
|
}
|
|
@@ -1203,7 +1202,7 @@ export class ChangelogGenerator {
|
|
|
1203
1202
|
* fs.writeFileSync('changelog.html', html);
|
|
1204
1203
|
* ```
|
|
1205
1204
|
*/
|
|
1206
|
-
static toHTML(entries: ChangeEntry[],
|
|
1205
|
+
static toHTML(entries: ChangeEntry[], _options?: ChangelogOptions): string {
|
|
1207
1206
|
const summary = this.getSummary(entries);
|
|
1208
1207
|
|
|
1209
1208
|
// Group entries by category
|
|
@@ -18,13 +18,9 @@ import type { Document } from '../core/Document';
|
|
|
18
18
|
import { Paragraph } from '../elements/Paragraph';
|
|
19
19
|
import type { ParagraphContent } from '../elements/Paragraph';
|
|
20
20
|
import { Revision, RevisionType } from '../elements/Revision';
|
|
21
|
-
import type { Run } from '../elements/Run';
|
|
22
|
-
import type { Hyperlink } from '../elements/Hyperlink';
|
|
23
21
|
import { isRunContent, isHyperlinkContent, isImageRunContent } from '../elements/RevisionContent';
|
|
24
|
-
import type { ImageRun } from '../elements/ImageRun';
|
|
25
22
|
import { ComplexField } from '../elements/Field';
|
|
26
23
|
import { Table } from '../elements/Table';
|
|
27
|
-
import { Section } from '../elements/Section';
|
|
28
24
|
import { getGlobalLogger, createScopedLogger, ILogger } from './logger';
|
|
29
25
|
|
|
30
26
|
/**
|
|
@@ -68,11 +64,6 @@ export interface AcceptRevisionsResult {
|
|
|
68
64
|
emptyTablesRemoved: number;
|
|
69
65
|
}
|
|
70
66
|
|
|
71
|
-
/**
|
|
72
|
-
* Revision types that represent content changes (contain actual text/runs)
|
|
73
|
-
*/
|
|
74
|
-
const CONTENT_REVISION_TYPES: RevisionType[] = ['insert', 'delete', 'moveFrom', 'moveTo'];
|
|
75
|
-
|
|
76
67
|
/**
|
|
77
68
|
* Revision types that represent property/formatting changes
|
|
78
69
|
*/
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
|
|
14
14
|
import type { Document } from '../core/Document';
|
|
15
15
|
import { Revision, RevisionType } from '../elements/Revision';
|
|
16
|
-
import { RevisionManager } from '../elements/RevisionManager';
|
|
17
16
|
import { ChangeCategory, ChangeLocation } from './ChangelogGenerator';
|
|
18
17
|
|
|
19
18
|
/**
|
|
@@ -382,7 +381,7 @@ export class RevisionAwareProcessor {
|
|
|
382
381
|
* @param runIndex - Optional run index
|
|
383
382
|
* @returns Conflicting revision or null
|
|
384
383
|
*/
|
|
385
|
-
static checkConflict(doc: Document, paragraphIndex: number,
|
|
384
|
+
static checkConflict(doc: Document, paragraphIndex: number, _runIndex?: number): Revision | null {
|
|
386
385
|
const revisionManager = doc.getRevisionManager();
|
|
387
386
|
if (!revisionManager) {
|
|
388
387
|
return null;
|
|
@@ -407,7 +406,7 @@ export class RevisionAwareProcessor {
|
|
|
407
406
|
static getAffectedRevisions(
|
|
408
407
|
doc: Document,
|
|
409
408
|
paragraphIndex: number,
|
|
410
|
-
|
|
409
|
+
_runIndex?: number
|
|
411
410
|
): Revision[] {
|
|
412
411
|
const revisionManager = doc.getRevisionManager();
|
|
413
412
|
if (!revisionManager) {
|
|
@@ -16,7 +16,6 @@ import type { Document } from '../core/Document';
|
|
|
16
16
|
import type { Paragraph, ParagraphContent } from '../elements/Paragraph';
|
|
17
17
|
import { Revision, RevisionType } from '../elements/Revision';
|
|
18
18
|
import type { Run } from '../elements/Run';
|
|
19
|
-
import type { Hyperlink } from '../elements/Hyperlink';
|
|
20
19
|
import { isRunContent, isHyperlinkContent } from '../elements/RevisionContent';
|
|
21
20
|
import { ChangeCategory } from './ChangelogGenerator';
|
|
22
21
|
import { SelectionCriteria } from './RevisionAwareProcessor';
|
|
@@ -533,27 +532,6 @@ export class SelectiveRevisionAcceptor {
|
|
|
533
532
|
return this.accept(doc, { categories: ['content'] });
|
|
534
533
|
}
|
|
535
534
|
|
|
536
|
-
/**
|
|
537
|
-
* Partition revisions into matching and non-matching based on criteria.
|
|
538
|
-
*/
|
|
539
|
-
private static partitionRevisions(
|
|
540
|
-
revisions: Revision[],
|
|
541
|
-
criteria: SelectionCriteria
|
|
542
|
-
): { matching: Revision[]; nonMatching: Revision[] } {
|
|
543
|
-
const matching: Revision[] = [];
|
|
544
|
-
const nonMatching: Revision[] = [];
|
|
545
|
-
|
|
546
|
-
for (const rev of revisions) {
|
|
547
|
-
if (this.matchesCriteria(rev, criteria)) {
|
|
548
|
-
matching.push(rev);
|
|
549
|
-
} else {
|
|
550
|
-
nonMatching.push(rev);
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
return { matching, nonMatching };
|
|
555
|
-
}
|
|
556
|
-
|
|
557
535
|
/**
|
|
558
536
|
* Check if a revision matches the given criteria.
|
|
559
537
|
*/
|
|
@@ -642,21 +620,4 @@ export class SelectiveRevisionAcceptor {
|
|
|
642
620
|
|
|
643
621
|
return 'content';
|
|
644
622
|
}
|
|
645
|
-
|
|
646
|
-
/**
|
|
647
|
-
* Create an empty result.
|
|
648
|
-
*/
|
|
649
|
-
private static emptyResult(): SelectiveAcceptResult {
|
|
650
|
-
return {
|
|
651
|
-
accepted: [],
|
|
652
|
-
rejected: [],
|
|
653
|
-
remaining: [],
|
|
654
|
-
summary: {
|
|
655
|
-
totalProcessed: 0,
|
|
656
|
-
acceptedCount: 0,
|
|
657
|
-
rejectedCount: 0,
|
|
658
|
-
remainingCount: 0,
|
|
659
|
-
},
|
|
660
|
-
};
|
|
661
|
-
}
|
|
662
623
|
}
|
|
@@ -18,7 +18,6 @@ import type { Table } from '../elements/Table';
|
|
|
18
18
|
import type { TableCell } from '../elements/TableCell';
|
|
19
19
|
import type { StylesManager } from '../formatting/StylesManager';
|
|
20
20
|
import { getActiveConditionalsInPriorityOrder } from './cnfStyleDecoder';
|
|
21
|
-
import type { ConditionalFormattingType } from '../formatting/Style';
|
|
22
21
|
|
|
23
22
|
/**
|
|
24
23
|
* Resolves the effective shading for a table cell through the style hierarchy.
|
|
@@ -281,7 +281,7 @@ class RevisionAcceptor {
|
|
|
281
281
|
|
|
282
282
|
result = result.replace(insRegex, (insMatch) => {
|
|
283
283
|
// For each image reference inside this insertion, generate a unique new ID
|
|
284
|
-
return insMatch.replace(/r:embed="(rId\d+)"/g, (
|
|
284
|
+
return insMatch.replace(/r:embed="(rId\d+)"/g, (_embedMatch, oldId) => {
|
|
285
285
|
// Generate new unique ID for THIS occurrence
|
|
286
286
|
const newId = this.getNextRelationshipId(existingIds);
|
|
287
287
|
existingIds.add(newId);
|
|
@@ -107,7 +107,7 @@ class TrackedChangesStripper {
|
|
|
107
107
|
|
|
108
108
|
result = result.replace(insRegex, (insMatch) => {
|
|
109
109
|
// For each image reference inside this insertion, generate a unique new ID
|
|
110
|
-
return insMatch.replace(/r:embed="(rId\d+)"/g, (
|
|
110
|
+
return insMatch.replace(/r:embed="(rId\d+)"/g, (_embedMatch, oldId) => {
|
|
111
111
|
// Generate new unique ID for THIS occurrence
|
|
112
112
|
const newId = this.getNextRelationshipId(existingIds);
|
|
113
113
|
existingIds.add(newId);
|
package/src/utils/units.ts
CHANGED
|
@@ -185,7 +185,8 @@ export function pointsToCm(points: number): number {
|
|
|
185
185
|
* @returns Value in half-points
|
|
186
186
|
*/
|
|
187
187
|
export function pointsToHalfPoints(points: number): number {
|
|
188
|
-
|
|
188
|
+
// Round to nearest integer — w:sz/w:szCs require ST_HpsMeasure (unsigned integer)
|
|
189
|
+
return Math.round(points * UNITS.HALF_POINTS_PER_POINT);
|
|
189
190
|
}
|
|
190
191
|
|
|
191
192
|
/**
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Validation Module
|
|
2
|
+
|
|
3
|
+
`src/validation/` — Revision validation, rule definitions, and auto-fix.
|
|
4
|
+
|
|
5
|
+
## Classes
|
|
6
|
+
|
|
7
|
+
### RevisionValidator (`RevisionValidator.ts`)
|
|
8
|
+
|
|
9
|
+
Static validation class. Entry point: `validate(doc, options?)`.
|
|
10
|
+
|
|
11
|
+
Runs all rules with configurable strictness (`strict` / `normal` / `lenient`). Returns `ValidationResult` with categorized issues (errors, warnings, infos) and summary stats.
|
|
12
|
+
|
|
13
|
+
Individual validators: `validateRevisionIds()`, `validateMovePairs()`, `validateAuthors()`, `validateDates()`, `validateContent()`, `validateSequentialIds()`.
|
|
14
|
+
|
|
15
|
+
### ValidationRules (`ValidationRules.ts`)
|
|
16
|
+
|
|
17
|
+
10 rules organized by severity:
|
|
18
|
+
|
|
19
|
+
| Rule | Severity | Description | Auto-fixable |
|
|
20
|
+
|--------|----------|----------------------------|-------------|
|
|
21
|
+
| REV001 | Error | Duplicate revision IDs | Yes |
|
|
22
|
+
| REV002 | Error | Missing authors | Yes |
|
|
23
|
+
| REV003 | Error | Orphaned moveFrom | Yes |
|
|
24
|
+
| REV004 | Error | Orphaned moveTo | Yes |
|
|
25
|
+
| REV101 | Warning | Missing dates | Yes |
|
|
26
|
+
| REV102 | Warning | Invalid date format | Yes |
|
|
27
|
+
| REV103 | Warning | Empty revisions | Yes |
|
|
28
|
+
| REV104 | Warning | Non-sequential IDs | Yes |
|
|
29
|
+
| REV201 | Info | Large revision count | No |
|
|
30
|
+
| REV202 | Info | Old revision dates | No |
|
|
31
|
+
|
|
32
|
+
**Auto-fix dependency order:** REV001 -> REV002 -> REV003/004 -> REV103 -> REV104
|
|
33
|
+
|
|
34
|
+
### RevisionAutoFixer (`RevisionAutoFixer.ts`)
|
|
35
|
+
|
|
36
|
+
Applies fixes in correct dependency order. Supports dry-run mode via `preview()`.
|
|
37
|
+
|
|
38
|
+
Entry point: `fix(doc, options?)`. Returns `AutoFixResult` with detailed actions taken.
|
|
39
|
+
|
|
40
|
+
Individual fixers: `fixDuplicateIds()`, `fixMissingAuthors()`, `fixOrphanedMoveMarkers()`, `fixEmptyRevisions()`, `fixNonSequentialIds()`.
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import type { Document } from '../core/Document';
|
|
11
11
|
import type { Revision } from '../elements/Revision';
|
|
12
|
+
import type { RevisionManager } from '../elements/RevisionManager';
|
|
12
13
|
import {
|
|
13
14
|
REVISION_RULES,
|
|
14
15
|
AutoFixOptions,
|
|
@@ -387,7 +388,7 @@ export class RevisionAutoFixer {
|
|
|
387
388
|
* @returns Array of fix actions
|
|
388
389
|
*/
|
|
389
390
|
static fixEmptyRevisions(
|
|
390
|
-
revisionManager:
|
|
391
|
+
revisionManager: RevisionManager,
|
|
391
392
|
revisions: Revision[],
|
|
392
393
|
dryRun?: boolean
|
|
393
394
|
): FixAction[] {
|