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.
- package/.eslintrc.json +43 -0
- package/.github/workflows/build.yml +64 -0
- package/.github/workflows/ci.yml +39 -0
- package/.vscode/extensions.json +3 -0
- package/Current.md +97 -0
- package/DocHub_Image.png +0 -0
- package/README.md +666 -0
- package/USER_GUIDE.md +1173 -0
- package/Updater.md +311 -0
- package/build/256x256.png +0 -0
- package/build/512x512.png +0 -0
- package/build/app-update.yml +4 -0
- package/build/create-icon.js +208 -0
- package/build/icon.ico +0 -0
- package/build/icon.png +0 -0
- package/build/icon_1024x1024.png +0 -0
- package/dist/assets/Analytics-BpsG9895.js +1 -0
- package/dist/assets/Card-IAZin8kp.js +1 -0
- package/dist/assets/CurrentSession-B-rFkHvf.js +12 -0
- package/dist/assets/Dashboard-C_5gMb0q.js +1 -0
- package/dist/assets/Documents-CqZ25axS.js +1 -0
- package/dist/assets/Input-l89xwXBi.js +1 -0
- package/dist/assets/Reporting-DqdHJY_a.js +1 -0
- package/dist/assets/Search-XNbu5z_3.js +1 -0
- package/dist/assets/SessionManager-lH9hZfzH.js +1 -0
- package/dist/assets/Sessions-ClZOPYNc.js +1 -0
- package/dist/assets/Settings-DUEHGURa.js +11 -0
- package/dist/assets/index-8xUe8ptc.js +24 -0
- package/dist/assets/index-RYyJqF7O.css +1 -0
- package/dist/assets/path-BkOl0AGO.js +1 -0
- package/dist/assets/promises-ID_B9S-h.js +1 -0
- package/dist/assets/urlHelpers-TvgahX0r.js +1 -0
- package/dist/assets/useToast-yRSO1dkm.js +1 -0
- package/dist/assets/vendor-charts-RkGK5ROP.js +36 -0
- package/dist/assets/vendor-db-l0sNRNKZ.js +1 -0
- package/dist/assets/vendor-react-BVZ_anCF.js +4 -0
- package/dist/assets/vendor-search-Dw8P0qyA.js +1 -0
- package/dist/assets/vendor-ui-BU7NfluV.js +53 -0
- package/dist/electron/PowerAutomateApiService-LfW09ZGr.js +147 -0
- package/dist/electron/main-CXkNtyv-.js +19789 -0
- package/dist/electron/main.js +5 -0
- package/dist/electron/preload.js +1 -0
- package/dist/icon.png +0 -0
- package/dist/index.html +27 -0
- package/docs/CODEBASE_ANALYSIS_REPORT.md +309 -0
- package/docs/DEBUG_LOGGING_GUIDE.md +244 -0
- package/docs/README.md +115 -0
- package/docs/TOC_WIRING_GUIDE.md +344 -0
- package/docs/analysis/Bullet_Symbol_Bug_Analysis.md +136 -0
- package/docs/analysis/DOCXMLATER_ANALYSIS_SUMMARY.txt +169 -0
- package/docs/analysis/Document_Processing_Issues_Analysis.md +704 -0
- package/docs/analysis/FIELD_PRESERVATION_ANALYSIS.md +1200 -0
- package/docs/analysis/INDENTATION_PRESERVE_ANALYSIS.md +181 -0
- package/docs/analysis/INDENTATION_PRESERVE_IMPLEMENTATION.md +207 -0
- package/docs/analysis/List_Implementation.md +206 -0
- package/docs/analysis/List_Implementation_Accuracy_Report.md +366 -0
- package/docs/analysis/PROCESSING_OPTIONS_UI_UPDATES.md +220 -0
- package/docs/analysis/RefactorStyles.md +852 -0
- package/docs/analysis/STYLE_PARAMETER_ENHANCEMENT.md +143 -0
- package/docs/analysis/docxmlater-comparison-todo-2025-11-13.md +636 -0
- package/docs/analysis/docxmlater-implementation-analysis-2025-11-13.md +340 -0
- package/docs/analysis/docxmlater-template_ui-integration-analysis.md +263 -0
- package/docs/analysis/github-issues-to-create.md +237 -0
- package/docs/api/API_README.md +538 -0
- package/docs/api/API_REFERENCE.md +751 -0
- package/docs/api/TYPE_DEFINITIONS.md +869 -0
- package/docs/architecture/FONT_EMBEDDING_GUIDE.md +318 -0
- package/docs/architecture/docxmlater-functions-and-structure.md +726 -0
- package/docs/docxmlater-readme.md +1341 -0
- package/docs/fixes/EXECUTION_LOG_TEST_BASE.md +573 -0
- package/docs/fixes/HYPERLINK_TEXT_SANITIZATION.md +253 -0
- package/docs/fixes/README.md +37 -0
- package/docs/github-issues/issue-1-body.md +125 -0
- package/docs/github-issues/issue-10-body.md +850 -0
- package/docs/github-issues/issue-2-body.md +200 -0
- package/docs/github-issues/issue-3-body.md +270 -0
- package/docs/github-issues/issue-4-body.md +169 -0
- package/docs/github-issues/issue-5-body.md +173 -0
- package/docs/github-issues/issue-6-body.md +158 -0
- package/docs/github-issues/issue-7-body.md +171 -0
- package/docs/github-issues/issue-8-body.md +407 -0
- package/docs/github-issues/issue-9-body.md +515 -0
- package/docs/github-issues/issue-tracker.md +274 -0
- package/docs/github-issues/predictive-analysis-2025-10-18.md +2131 -0
- package/docs/implementation/List_Framework_Refactor_Plan.md +336 -0
- package/docs/implementation/PRIMARY_TEXT_COLOR_FEATURE.md +217 -0
- package/docs/implementation/RELEASE_PLAN_v2.1.0.md +362 -0
- package/docs/implementation/RefactorStyles.md +588 -0
- package/docs/implementation/implement-plan.md +489 -0
- package/docs/implementation/missing-helpers-implementation.md +391 -0
- package/docs/implementation/refactor-plan.md +520 -0
- package/docs/implementation/session-implementation-complete.md +233 -0
- package/docs/implementation/session-management-plan.md +250 -0
- package/docs/setup-checklist.md +77 -0
- package/docs/versions/changelog.md +345 -0
- package/electron/customUpdater.ts +656 -0
- package/electron/main.ts +2441 -0
- package/electron/memoryConfig.ts +187 -0
- package/electron/preload.ts +394 -0
- package/electron/proxyConfig.ts +340 -0
- package/electron/services/BackupService.ts +452 -0
- package/electron/services/DictionaryService.ts +402 -0
- package/electron/services/LocalDictionaryLookupService.ts +147 -0
- package/electron/services/PowerAutomateApiService.ts +231 -0
- package/electron/services/SharePointSyncService.ts +474 -0
- package/electron/windowsCertStore.ts +427 -0
- package/electron/zscalerConfig.ts +381 -0
- package/eslint.config.js +92 -0
- package/jest.config.js +52 -0
- package/package.json +214 -0
- package/postcss.config.mjs +6 -0
- package/public/icon.png +0 -0
- package/publish-release.ps1 +5 -0
- package/renovate.json +30 -0
- package/src/App.tsx +216 -0
- package/src/__mocks__/p-limit.js +12 -0
- package/src/__mocks__/styleMock.js +1 -0
- package/src/components/common/BugReportButton.tsx +44 -0
- package/src/components/common/BugReportDialog.tsx +193 -0
- package/src/components/common/Button.tsx +153 -0
- package/src/components/common/Card.tsx +86 -0
- package/src/components/common/ColorPickerDialog.tsx +177 -0
- package/src/components/common/ConfirmDialog.tsx +96 -0
- package/src/components/common/DebugConsole.tsx +275 -0
- package/src/components/common/EmptyState.tsx +183 -0
- package/src/components/common/ErrorBoundary.tsx +98 -0
- package/src/components/common/ErrorDetailsDialog.tsx +153 -0
- package/src/components/common/ErrorFallback.tsx +218 -0
- package/src/components/common/Input.tsx +109 -0
- package/src/components/common/Skeleton.tsx +184 -0
- package/src/components/common/SplashScreen.tsx +81 -0
- package/src/components/common/Toast.tsx +155 -0
- package/src/components/common/Tooltip.tsx +79 -0
- package/src/components/common/UpdateNotification.tsx +320 -0
- package/src/components/comparison/ComparisonWindow.tsx +374 -0
- package/src/components/comparison/SideBySideDiff.tsx +486 -0
- package/src/components/comparison/index.ts +8 -0
- package/src/components/document/DocumentUploader.tsx +288 -0
- package/src/components/document/HyperlinkPreview.tsx +430 -0
- package/src/components/document/HyperlinkService.md +1484 -0
- package/src/components/document/Hyperlink_Technical_Documentation.md +496 -0
- package/src/components/document/InlineChangesView.tsx +707 -0
- package/src/components/document/ProcessingProgress.tsx +303 -0
- package/src/components/document/ProcessingResults.tsx +256 -0
- package/src/components/document/TrackedChangesDetail.tsx +530 -0
- package/src/components/document/TrackedChangesPanel.tsx +546 -0
- package/src/components/document/VirtualDocumentList.tsx +240 -0
- package/src/components/editor/DocumentEditor.tsx +723 -0
- package/src/components/editor/DocumentEditorModal.tsx +640 -0
- package/src/components/editor/EditorQuickActions.tsx +502 -0
- package/src/components/editor/EditorToolbar.tsx +312 -0
- package/src/components/editor/TableEditor.tsx +926 -0
- package/src/components/editor/index.ts +18 -0
- package/src/components/layout/Header.tsx +190 -0
- package/src/components/layout/Sidebar.tsx +313 -0
- package/src/components/layout/TitleBar.tsx +190 -0
- package/src/components/navigation/CommandPalette.tsx +233 -0
- package/src/components/navigation/KeyboardShortcutsModal.tsx +173 -0
- package/src/components/sessions/ChangeItem.tsx +408 -0
- package/src/components/sessions/ChangeViewer.tsx +1155 -0
- package/src/components/sessions/DocumentComparisonModal.tsx +314 -0
- package/src/components/sessions/ProcessingOptions.tsx +297 -0
- package/src/components/sessions/ReplacementsTab.tsx +438 -0
- package/src/components/sessions/RevisionHandlingOptions.tsx +87 -0
- package/src/components/sessions/SessionManager.tsx +188 -0
- package/src/components/sessions/StylesEditor.tsx +1335 -0
- package/src/components/sessions/TabContainer.tsx +151 -0
- package/src/components/sessions/VirtualSessionList.tsx +157 -0
- package/src/components/sessions/sessionToProcessorManager.tsx +420 -0
- package/src/components/settings/CertificateManager.tsx +410 -0
- package/src/components/settings/SegmentedControl.tsx +88 -0
- package/src/components/settings/SettingRow.tsx +52 -0
- package/src/contexts/GlobalStatsContext.tsx +396 -0
- package/src/contexts/SessionContext.tsx +2129 -0
- package/src/contexts/ThemeContext.tsx +428 -0
- package/src/contexts/UserSettingsContext.tsx +290 -0
- package/src/contexts/__tests__/GlobalStatsContext.test.tsx +390 -0
- package/src/global.d.ts +273 -0
- package/src/hooks/useDocumentQueue.tsx +210 -0
- package/src/hooks/useToast.tsx +55 -0
- package/src/main.tsx +10 -0
- package/src/pages/Analytics.tsx +386 -0
- package/src/pages/CurrentSession.tsx +1174 -0
- package/src/pages/Dashboard.tsx +319 -0
- package/src/pages/Documents.tsx +317 -0
- package/src/pages/Projects.tsx +250 -0
- package/src/pages/Reporting.tsx +386 -0
- package/src/pages/Search.tsx +349 -0
- package/src/pages/Sessions.tsx +285 -0
- package/src/pages/Settings.tsx +2662 -0
- package/src/services/HyperlinkService.ts +1085 -0
- package/src/services/document/DocXMLaterProcessor.ts +617 -0
- package/src/services/document/DocumentProcessingComparison.ts +856 -0
- package/src/services/document/DocumentSnapshotService.ts +575 -0
- package/src/services/document/WordDocumentProcessor.ts +10509 -0
- package/src/services/document/__tests__/DocXMLaterProcessor.hyperlinks.test.md +311 -0
- package/src/services/document/__tests__/WordDocumentProcessor.integration.test.ts +515 -0
- package/src/services/document/__tests__/WordDocumentProcessor.test.ts +812 -0
- package/src/services/document/blanklines/BlankLineManager.ts +658 -0
- package/src/services/document/blanklines/__tests__/paragraphChecks.test.ts +281 -0
- package/src/services/document/blanklines/helpers/blankLineInsertion.ts +87 -0
- package/src/services/document/blanklines/helpers/blankLineSnapshot.ts +251 -0
- package/src/services/document/blanklines/helpers/clearCustom.ts +121 -0
- package/src/services/document/blanklines/helpers/contextChecks.ts +117 -0
- package/src/services/document/blanklines/helpers/imageChecks.ts +51 -0
- package/src/services/document/blanklines/helpers/paragraphChecks.ts +236 -0
- package/src/services/document/blanklines/helpers/removeBlanksBetweenListItems.ts +91 -0
- package/src/services/document/blanklines/helpers/removeTrailingBlanks.ts +35 -0
- package/src/services/document/blanklines/helpers/tableGuards.ts +21 -0
- package/src/services/document/blanklines/index.ts +67 -0
- package/src/services/document/blanklines/rules/additionRules.ts +337 -0
- package/src/services/document/blanklines/rules/indentationRules.ts +317 -0
- package/src/services/document/blanklines/rules/removalRules.ts +362 -0
- package/src/services/document/blanklines/rules/ruleTypes.ts +92 -0
- package/src/services/document/blanklines/types.ts +29 -0
- package/src/services/document/helpers/ImageBorderCropper.ts +377 -0
- package/src/services/document/helpers/__tests__/whitespace.test.ts +272 -0
- package/src/services/document/helpers/whitespace.ts +117 -0
- package/src/services/document/list/ListNormalizer.ts +947 -0
- package/src/services/document/list/index.ts +45 -0
- package/src/services/document/list/list-detection.ts +275 -0
- package/src/services/document/list/list-types.ts +162 -0
- package/src/services/document/processors/HyperlinkProcessor.ts +370 -0
- package/src/services/document/processors/ListProcessor.ts +257 -0
- package/src/services/document/processors/StructureProcessor.ts +176 -0
- package/src/services/document/processors/StyleProcessor.ts +389 -0
- package/src/services/document/processors/TableProcessor.ts +2238 -0
- package/src/services/document/processors/__tests__/HyperlinkProcessor.test.ts +314 -0
- package/src/services/document/processors/__tests__/ListProcessor.test.ts +291 -0
- package/src/services/document/processors/__tests__/StructureProcessor.test.ts +257 -0
- package/src/services/document/processors/__tests__/TableProcessor.hlp-tips-bullets.test.ts +459 -0
- package/src/services/document/processors/__tests__/TableProcessor.test.ts +1604 -0
- package/src/services/document/processors/index.ts +28 -0
- package/src/services/document/types/docx-processing.ts +310 -0
- package/src/services/editor/EditorActionHandlers.ts +901 -0
- package/src/services/editor/index.ts +13 -0
- package/src/setupTests.ts +47 -0
- package/src/styles/global.css +782 -0
- package/src/types/backup.ts +132 -0
- package/src/types/dictionary.ts +125 -0
- package/src/types/document-processing.ts +331 -0
- package/src/types/docxmlater-augments.d.ts +142 -0
- package/src/types/editor.ts +280 -0
- package/src/types/electron.ts +340 -0
- package/src/types/globalStats.ts +155 -0
- package/src/types/hyperlink.ts +471 -0
- package/src/types/operations.ts +354 -0
- package/src/types/session.ts +427 -0
- package/src/types/settings.ts +112 -0
- package/src/utils/MemoryMonitor.ts +248 -0
- package/src/utils/cn.ts +6 -0
- package/src/utils/colorConvert.ts +306 -0
- package/src/utils/diffUtils.ts +347 -0
- package/src/utils/documentUtils.ts +202 -0
- package/src/utils/electronGuard.ts +62 -0
- package/src/utils/indexedDB.ts +915 -0
- package/src/utils/logger.ts +717 -0
- package/src/utils/pathSecurity.ts +232 -0
- package/src/utils/pathValidator.ts +236 -0
- package/src/utils/processingTimeEstimator.ts +153 -0
- package/src/utils/safeJsonParse.ts +62 -0
- package/src/utils/textSanitizer.ts +162 -0
- package/src/utils/urlHelpers.ts +304 -0
- package/src/utils/urlPatterns.ts +198 -0
- package/src/utils/urlSanitizer.ts +152 -0
- package/src/vite-env.d.ts +11 -0
- package/tsconfig.electron.json +19 -0
- package/tsconfig.json +36 -0
- package/tsconfig.node.json +12 -0
- package/typedoc.json +45 -0
- package/vite.config.ts +152 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BlankLineManager module - Rule-based blank line management for DOCX documents.
|
|
3
|
+
*
|
|
4
|
+
* This module manages blank line operations using a rule-based engine that
|
|
5
|
+
* applies explicit removal/addition rules first, then preserves original
|
|
6
|
+
* blank lines where no rule matched.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// Main orchestrator
|
|
10
|
+
export { BlankLineManager, blankLineManager } from "./BlankLineManager";
|
|
11
|
+
|
|
12
|
+
// Types
|
|
13
|
+
export type { BlankLineOptions } from "./types";
|
|
14
|
+
export { DEFAULT_BLANK_LINE_OPTIONS } from "./types";
|
|
15
|
+
|
|
16
|
+
// Rule engine types
|
|
17
|
+
export type {
|
|
18
|
+
RuleContext,
|
|
19
|
+
BlankLineRule,
|
|
20
|
+
BlankLineProcessingOptions,
|
|
21
|
+
RuleEngineResult,
|
|
22
|
+
} from "./rules/ruleTypes";
|
|
23
|
+
|
|
24
|
+
// Snapshot system
|
|
25
|
+
export type { BlankLineSnapshot } from "./helpers/blankLineSnapshot";
|
|
26
|
+
export {
|
|
27
|
+
captureBlankLineSnapshot,
|
|
28
|
+
wasOriginallyBlankAtBody,
|
|
29
|
+
wasOriginallyBlankInCell,
|
|
30
|
+
} from "./helpers/blankLineSnapshot";
|
|
31
|
+
|
|
32
|
+
// Rules
|
|
33
|
+
export { removalRules } from "./rules/removalRules";
|
|
34
|
+
export { additionRules } from "./rules/additionRules";
|
|
35
|
+
export { applyIndentationRules, removeSmallIndents } from "./rules/indentationRules";
|
|
36
|
+
|
|
37
|
+
// Helper functions
|
|
38
|
+
export {
|
|
39
|
+
isParagraphBlank,
|
|
40
|
+
startsWithBoldColon,
|
|
41
|
+
isCenteredBoldText,
|
|
42
|
+
isTextOnlyParagraph,
|
|
43
|
+
isTocParagraph,
|
|
44
|
+
} from "./helpers/paragraphChecks";
|
|
45
|
+
|
|
46
|
+
export {
|
|
47
|
+
isImageSmall,
|
|
48
|
+
isSmallImageParagraph,
|
|
49
|
+
getImageRunFromParagraph,
|
|
50
|
+
} from "./helpers/imageChecks";
|
|
51
|
+
|
|
52
|
+
export {
|
|
53
|
+
isWithinListContext,
|
|
54
|
+
isWithinListContextInCell,
|
|
55
|
+
} from "./helpers/contextChecks";
|
|
56
|
+
|
|
57
|
+
export {
|
|
58
|
+
createBlankParagraph,
|
|
59
|
+
insertOrMarkBlankAfter,
|
|
60
|
+
insertOrMarkBlankBefore,
|
|
61
|
+
} from "./helpers/blankLineInsertion";
|
|
62
|
+
|
|
63
|
+
export { clearCustom } from "./helpers/clearCustom";
|
|
64
|
+
|
|
65
|
+
export { removeTrailingBlanksInTableCells } from "./helpers/removeTrailingBlanks";
|
|
66
|
+
|
|
67
|
+
export { removeBlanksBetweenListItems } from "./helpers/removeBlanksBetweenListItems";
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Addition Rules - Define when blank lines must be ADDED or preserved.
|
|
3
|
+
*
|
|
4
|
+
* Addition rules are checked after removal rules. If an addition rule matches
|
|
5
|
+
* a position and no blank exists there, one is added.
|
|
6
|
+
*
|
|
7
|
+
* Each rule's matches() checks the context to determine if a blank line
|
|
8
|
+
* should exist at the position AFTER the current element.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { Paragraph, Table } from "docxmlater";
|
|
12
|
+
import type { BlankLineRule, RuleContext } from "./ruleTypes";
|
|
13
|
+
import { isParagraphBlank, isTocParagraph, startsWithBoldColon, getEffectiveLeftIndent, hasNavigationHyperlink } from "../helpers/paragraphChecks";
|
|
14
|
+
import { getImageRunFromParagraph, isImageSmall, isSmallImageParagraph } from "../helpers/imageChecks";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Add blank line after Heading 1 style text.
|
|
18
|
+
*/
|
|
19
|
+
export const afterHeading1Rule: BlankLineRule = {
|
|
20
|
+
id: "add-after-heading1",
|
|
21
|
+
action: "add",
|
|
22
|
+
scope: "body",
|
|
23
|
+
matches(ctx: RuleContext): boolean {
|
|
24
|
+
if (ctx.scope !== "body") return false;
|
|
25
|
+
if (!(ctx.currentElement instanceof Paragraph)) return false;
|
|
26
|
+
|
|
27
|
+
const style = ctx.currentElement.getStyle();
|
|
28
|
+
if (style !== "Heading1") return false;
|
|
29
|
+
if (ctx.currentElement.getText().trim() === "") return false;
|
|
30
|
+
|
|
31
|
+
// Want a blank AFTER this heading
|
|
32
|
+
return true;
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Add blank line after the Table of Contents.
|
|
38
|
+
* Detects both TOC elements and TOC-styled paragraphs.
|
|
39
|
+
*/
|
|
40
|
+
export const afterTocRule: BlankLineRule = {
|
|
41
|
+
id: "add-after-toc",
|
|
42
|
+
action: "add",
|
|
43
|
+
scope: "body",
|
|
44
|
+
matches(ctx: RuleContext): boolean {
|
|
45
|
+
if (ctx.scope !== "body") return false;
|
|
46
|
+
if (!(ctx.currentElement instanceof Paragraph)) return false;
|
|
47
|
+
|
|
48
|
+
// Current must be a TOC paragraph
|
|
49
|
+
if (!isTocParagraph(ctx.currentElement)) return false;
|
|
50
|
+
|
|
51
|
+
// Next must NOT be a TOC paragraph (this is the last TOC entry)
|
|
52
|
+
if (ctx.nextElement instanceof Paragraph && isTocParagraph(ctx.nextElement)) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return true;
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Add blank line before the first 1x1 table in the document.
|
|
62
|
+
*/
|
|
63
|
+
export const beforeFirst1x1TableRule: BlankLineRule = {
|
|
64
|
+
id: "add-before-first-1x1-table",
|
|
65
|
+
action: "add",
|
|
66
|
+
scope: "body",
|
|
67
|
+
matches(ctx: RuleContext): boolean {
|
|
68
|
+
if (ctx.scope !== "body") return false;
|
|
69
|
+
|
|
70
|
+
// Current element must be a paragraph (the blank would go before the table,
|
|
71
|
+
// but we check from the perspective of "should there be a blank between prev and next")
|
|
72
|
+
// This rule is handled specially in the engine - it checks if nextElement is the first 1x1 table
|
|
73
|
+
if (!(ctx.currentElement instanceof Paragraph)) return false;
|
|
74
|
+
|
|
75
|
+
if (ctx.nextElement instanceof Table) {
|
|
76
|
+
const rowCount = ctx.nextElement.getRowCount();
|
|
77
|
+
const colCount = ctx.nextElement.getColumnCount();
|
|
78
|
+
if (rowCount === 1 && colCount === 1) {
|
|
79
|
+
// Check if this is the first 1x1 table in the document
|
|
80
|
+
const doc = ctx.doc;
|
|
81
|
+
for (let i = 0; i < ctx.currentIndex; i++) {
|
|
82
|
+
const el = doc.getBodyElementAt(i);
|
|
83
|
+
if (el instanceof Table) {
|
|
84
|
+
const r = el.getRowCount();
|
|
85
|
+
const c = el.getColumnCount();
|
|
86
|
+
if (r === 1 && c === 1) {
|
|
87
|
+
return false; // Not the first 1x1 table
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return true; // This is before the first 1x1 table
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return false;
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Add blank line after 1x1 tables.
|
|
100
|
+
*/
|
|
101
|
+
export const after1x1TablesRule: BlankLineRule = {
|
|
102
|
+
id: "add-after-1x1-tables",
|
|
103
|
+
action: "add",
|
|
104
|
+
scope: "body",
|
|
105
|
+
matches(ctx: RuleContext): boolean {
|
|
106
|
+
if (ctx.scope !== "body") return false;
|
|
107
|
+
if (!(ctx.currentElement instanceof Table)) return false;
|
|
108
|
+
|
|
109
|
+
const rowCount = ctx.currentElement.getRowCount();
|
|
110
|
+
const colCount = ctx.currentElement.getColumnCount();
|
|
111
|
+
|
|
112
|
+
return rowCount === 1 && colCount === 1;
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Add blank line after tables larger than 1x1.
|
|
118
|
+
*/
|
|
119
|
+
export const afterLargeTablesRule: BlankLineRule = {
|
|
120
|
+
id: "add-after-large-tables",
|
|
121
|
+
action: "add",
|
|
122
|
+
scope: "body",
|
|
123
|
+
matches(ctx: RuleContext): boolean {
|
|
124
|
+
if (ctx.scope !== "body") return false;
|
|
125
|
+
if (!(ctx.currentElement instanceof Table)) return false;
|
|
126
|
+
|
|
127
|
+
const rowCount = ctx.currentElement.getRowCount();
|
|
128
|
+
const colCount = ctx.currentElement.getColumnCount();
|
|
129
|
+
|
|
130
|
+
return rowCount > 1 || colCount > 1;
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Add blank line ABOVE bold+colon non-indented paragraphs.
|
|
136
|
+
* Checks ctx.nextElement to see if the upcoming paragraph starts with bold text + colon.
|
|
137
|
+
*/
|
|
138
|
+
export const aboveBoldColonNoIndentRule: BlankLineRule = {
|
|
139
|
+
id: "add-above-bold-colon-no-indent",
|
|
140
|
+
action: "add",
|
|
141
|
+
scope: "both",
|
|
142
|
+
matches(ctx: RuleContext): boolean {
|
|
143
|
+
if (!(ctx.nextElement instanceof Paragraph)) return false;
|
|
144
|
+
if (isParagraphBlank(ctx.nextElement)) return false;
|
|
145
|
+
if (!startsWithBoldColon(ctx.nextElement)) return false;
|
|
146
|
+
if (ctx.nextElement.getNumbering()) return false;
|
|
147
|
+
|
|
148
|
+
const indent = ctx.nextElement.getFormatting()?.indentation?.left;
|
|
149
|
+
if (indent && indent > 0) return false;
|
|
150
|
+
|
|
151
|
+
return true;
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Bold+colon with no indentation where next line is NOT indented:
|
|
157
|
+
* add blank after, UNLESS there is a 1x1 table with "Related Document"
|
|
158
|
+
* text within 15 lines above.
|
|
159
|
+
*/
|
|
160
|
+
export const boldColonNoIndentAfterRule: BlankLineRule = {
|
|
161
|
+
id: "add-after-bold-colon-no-indent",
|
|
162
|
+
action: "add",
|
|
163
|
+
scope: "both",
|
|
164
|
+
matches(ctx: RuleContext): boolean {
|
|
165
|
+
if (!(ctx.currentElement instanceof Paragraph)) return false;
|
|
166
|
+
if (isParagraphBlank(ctx.currentElement)) return false;
|
|
167
|
+
if (!startsWithBoldColon(ctx.currentElement)) return false;
|
|
168
|
+
|
|
169
|
+
// Must not be a list item
|
|
170
|
+
if (ctx.currentElement.getNumbering()) return false;
|
|
171
|
+
|
|
172
|
+
// Must have no indentation
|
|
173
|
+
const indent = ctx.currentElement.getFormatting()?.indentation?.left;
|
|
174
|
+
if (indent && indent > 0) return false;
|
|
175
|
+
|
|
176
|
+
// Next line must NOT be indented and NOT be a list item
|
|
177
|
+
if (ctx.nextElement instanceof Paragraph) {
|
|
178
|
+
if (ctx.nextElement.getNumbering()) return false;
|
|
179
|
+
const nextIndent = ctx.nextElement.getFormatting()?.indentation?.left;
|
|
180
|
+
if (nextIndent && nextIndent > 0) return false;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Check for "Related Document" 1x1 table within 15 lines above
|
|
184
|
+
if (ctx.scope === "body") {
|
|
185
|
+
const lookbackLimit = Math.max(0, ctx.currentIndex - 15);
|
|
186
|
+
for (let i = ctx.currentIndex - 1; i >= lookbackLimit; i--) {
|
|
187
|
+
const el = ctx.doc.getBodyElementAt(i);
|
|
188
|
+
if (el instanceof Table) {
|
|
189
|
+
const r = el.getRowCount();
|
|
190
|
+
const c = el.getColumnCount();
|
|
191
|
+
if (r === 1 && c === 1) {
|
|
192
|
+
try {
|
|
193
|
+
const cell = el.getCell(0, 0);
|
|
194
|
+
if (cell) {
|
|
195
|
+
const cellText = cell
|
|
196
|
+
.getParagraphs()
|
|
197
|
+
.map((p) => p.getText())
|
|
198
|
+
.join(" ")
|
|
199
|
+
.toLowerCase();
|
|
200
|
+
if (cellText.includes("related document")) {
|
|
201
|
+
return false; // Skip - Related Document table nearby
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
} catch {
|
|
205
|
+
// Skip if cell access fails
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return true;
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Add blank line ABOVE navigation hyperlinks (text starts with "Top of" or "Return to").
|
|
218
|
+
*/
|
|
219
|
+
export const aboveTopOfDocHyperlinkRule: BlankLineRule = {
|
|
220
|
+
id: "add-above-top-of-doc-hyperlink",
|
|
221
|
+
action: "add",
|
|
222
|
+
scope: "body",
|
|
223
|
+
matches(ctx: RuleContext): boolean {
|
|
224
|
+
if (ctx.scope !== "body") return false;
|
|
225
|
+
if (!(ctx.nextElement instanceof Paragraph)) return false;
|
|
226
|
+
return hasNavigationHyperlink(ctx.nextElement);
|
|
227
|
+
},
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Add blank line after list items ONLY when the next line is NOT indented text.
|
|
232
|
+
*/
|
|
233
|
+
export const afterListItemsRule: BlankLineRule = {
|
|
234
|
+
id: "add-after-list-items",
|
|
235
|
+
action: "add",
|
|
236
|
+
scope: "both",
|
|
237
|
+
matches(ctx: RuleContext): boolean {
|
|
238
|
+
if (!(ctx.currentElement instanceof Paragraph)) return false;
|
|
239
|
+
if (!ctx.currentElement.getNumbering()) return false;
|
|
240
|
+
|
|
241
|
+
// This is a list item - check if it's the LAST in its sequence
|
|
242
|
+
if (ctx.nextElement instanceof Paragraph) {
|
|
243
|
+
// If next is also a list item, don't add blank
|
|
244
|
+
if (ctx.nextElement.getNumbering()) return false;
|
|
245
|
+
|
|
246
|
+
// If next is a centered image, always add blank
|
|
247
|
+
if (ctx.nextElement.getAlignment() === "center") {
|
|
248
|
+
const imageRun = getImageRunFromParagraph(ctx.nextElement);
|
|
249
|
+
if (imageRun) return true;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// If next is indented text, don't add blank
|
|
253
|
+
// Use getEffectiveLeftIndent to also check style-inherited indentation
|
|
254
|
+
// (e.g., ListParagraph style defines w:left="720" but paragraph may have no direct w:ind)
|
|
255
|
+
const nextIndent = getEffectiveLeftIndent(ctx.nextElement, ctx.doc);
|
|
256
|
+
if (nextIndent > 0) return false;
|
|
257
|
+
|
|
258
|
+
// If next is a small image paragraph with indentation, don't add blank
|
|
259
|
+
if (isSmallImageParagraph(ctx.nextElement)) {
|
|
260
|
+
const imgIndent = getEffectiveLeftIndent(ctx.nextElement, ctx.doc);
|
|
261
|
+
if (imgIndent > 0) return false;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Next is not indented text/list, so we need a blank after this list item
|
|
266
|
+
return true;
|
|
267
|
+
},
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Add blank line above and below images larger than 100x100 pixels.
|
|
272
|
+
* In table cells, do not add blank after if image is the last element.
|
|
273
|
+
*/
|
|
274
|
+
export const aboveAndBelowLargeImagesRule: BlankLineRule = {
|
|
275
|
+
id: "add-around-large-images",
|
|
276
|
+
action: "add",
|
|
277
|
+
scope: "both",
|
|
278
|
+
matches(ctx: RuleContext): boolean {
|
|
279
|
+
if (!(ctx.currentElement instanceof Paragraph)) return false;
|
|
280
|
+
if (isParagraphBlank(ctx.currentElement)) return false;
|
|
281
|
+
|
|
282
|
+
const imageRun = getImageRunFromParagraph(ctx.currentElement);
|
|
283
|
+
if (!imageRun) return false;
|
|
284
|
+
|
|
285
|
+
const image = imageRun.getImageElement();
|
|
286
|
+
if (isImageSmall(image)) return false;
|
|
287
|
+
|
|
288
|
+
// Large image - blank needed above and below
|
|
289
|
+
// (The engine will handle checking both directions)
|
|
290
|
+
return true;
|
|
291
|
+
},
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Add blank line above the end-of-document warning/disclaimer.
|
|
296
|
+
* Matches the specific two-line disclaimer:
|
|
297
|
+
* "Not to Be Reproduced or Disclosed to Others Without Prior Written Approval"
|
|
298
|
+
* "ELECTRONIC DATA = OFFICIAL VERSION - PAPER COPY = INFORMATIONAL ONLY"
|
|
299
|
+
*/
|
|
300
|
+
export const aboveWarningRule: BlankLineRule = {
|
|
301
|
+
id: "add-above-warning",
|
|
302
|
+
action: "add",
|
|
303
|
+
scope: "body",
|
|
304
|
+
matches(ctx: RuleContext): boolean {
|
|
305
|
+
if (ctx.scope !== "body") return false;
|
|
306
|
+
|
|
307
|
+
// Check if next element is the document disclaimer
|
|
308
|
+
if (!(ctx.nextElement instanceof Paragraph)) return false;
|
|
309
|
+
|
|
310
|
+
const nextText = ctx.nextElement.getText().trim().toLowerCase();
|
|
311
|
+
if (!nextText) return false;
|
|
312
|
+
|
|
313
|
+
const isDisclaimer =
|
|
314
|
+
nextText.includes("not to be reproduced") ||
|
|
315
|
+
nextText.includes("electronic data") ||
|
|
316
|
+
nextText.includes("paper copy = informational only");
|
|
317
|
+
|
|
318
|
+
return isDisclaimer;
|
|
319
|
+
},
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* All addition rules in evaluation order.
|
|
324
|
+
*/
|
|
325
|
+
export const additionRules: BlankLineRule[] = [
|
|
326
|
+
afterHeading1Rule,
|
|
327
|
+
afterTocRule,
|
|
328
|
+
beforeFirst1x1TableRule,
|
|
329
|
+
after1x1TablesRule,
|
|
330
|
+
afterLargeTablesRule,
|
|
331
|
+
aboveBoldColonNoIndentRule,
|
|
332
|
+
boldColonNoIndentAfterRule,
|
|
333
|
+
aboveTopOfDocHyperlinkRule,
|
|
334
|
+
afterListItemsRule,
|
|
335
|
+
aboveAndBelowLargeImagesRule,
|
|
336
|
+
aboveWarningRule,
|
|
337
|
+
];
|