legal-markdown-js 2.3.0 → 2.5.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.
Files changed (58) hide show
  1. package/README.md +67 -9
  2. package/dist/core/index.d.ts +15 -2
  3. package/dist/core/index.d.ts.map +1 -1
  4. package/dist/core/index.js +19 -2
  5. package/dist/core/index.js.map +1 -1
  6. package/dist/core/processors/base-processor.d.ts +168 -0
  7. package/dist/core/processors/base-processor.d.ts.map +1 -0
  8. package/dist/core/processors/base-processor.js +108 -0
  9. package/dist/core/processors/base-processor.js.map +1 -0
  10. package/dist/core/processors/reference-processor.d.ts +40 -86
  11. package/dist/core/processors/reference-processor.d.ts.map +1 -1
  12. package/dist/core/processors/reference-processor.js +172 -215
  13. package/dist/core/processors/reference-processor.js.map +1 -1
  14. package/dist/core/tracking/field-state.d.ts +283 -0
  15. package/dist/core/tracking/field-state.d.ts.map +1 -0
  16. package/dist/core/tracking/field-state.js +166 -0
  17. package/dist/core/tracking/field-state.js.map +1 -0
  18. package/dist/extensions/ast-mixin-processor.d.ts +182 -0
  19. package/dist/extensions/ast-mixin-processor.d.ts.map +1 -0
  20. package/dist/extensions/ast-mixin-processor.js +637 -0
  21. package/dist/extensions/ast-mixin-processor.js.map +1 -0
  22. package/dist/extensions/index.d.ts +1 -0
  23. package/dist/extensions/index.d.ts.map +1 -1
  24. package/dist/extensions/index.js +1 -0
  25. package/dist/extensions/index.js.map +1 -1
  26. package/dist/extensions/pipeline/pipeline-config.d.ts +94 -0
  27. package/dist/extensions/pipeline/pipeline-config.d.ts.map +1 -0
  28. package/dist/extensions/pipeline/pipeline-config.js +494 -0
  29. package/dist/extensions/pipeline/pipeline-config.js.map +1 -0
  30. package/dist/extensions/pipeline/pipeline-logger.d.ts +217 -0
  31. package/dist/extensions/pipeline/pipeline-logger.d.ts.map +1 -0
  32. package/dist/extensions/pipeline/pipeline-logger.js +331 -0
  33. package/dist/extensions/pipeline/pipeline-logger.js.map +1 -0
  34. package/dist/extensions/pipeline/pipeline-manager.d.ts +221 -0
  35. package/dist/extensions/pipeline/pipeline-manager.d.ts.map +1 -0
  36. package/dist/extensions/pipeline/pipeline-manager.js +619 -0
  37. package/dist/extensions/pipeline/pipeline-manager.js.map +1 -0
  38. package/dist/extensions/pipeline/types.d.ts +354 -0
  39. package/dist/extensions/pipeline/types.d.ts.map +1 -0
  40. package/dist/extensions/pipeline/types.js +39 -0
  41. package/dist/extensions/pipeline/types.js.map +1 -0
  42. package/dist/extensions/template-loops.d.ts.map +1 -1
  43. package/dist/extensions/template-loops.js +32 -0
  44. package/dist/extensions/template-loops.js.map +1 -1
  45. package/dist/generators/html-generator.d.ts.map +1 -1
  46. package/dist/generators/html-generator.js +2 -0
  47. package/dist/generators/html-generator.js.map +1 -1
  48. package/dist/index.d.ts +3 -2
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +134 -10
  51. package/dist/index.js.map +1 -1
  52. package/dist/legal-markdown.umd.min.js +1 -1
  53. package/dist/legal-markdown.umd.min.js.map +1 -1
  54. package/dist/styles/default.css +407 -83
  55. package/dist/tracking/field-tracker.js +1 -1
  56. package/dist/tracking/field-tracker.js.map +1 -1
  57. package/dist/web/legal-markdown.umd.min.js +1 -1
  58. package/package.json +1 -1
package/README.md CHANGED
@@ -5,8 +5,8 @@
5
5
  > feature parity.
6
6
 
7
7
  Process markdown with YAML front matter, conditional clauses
8
- `[text]{condition}`, cross-references `|variable|`, imports `@import`, and
9
- generate professional PDFs ready to be shared.
8
+ `[text]{condition}`, cross-references `|reference|`, mixins `{{variable}}`,
9
+ imports `@import`, and generate professional PDFs ready to be shared.
10
10
 
11
11
  ![Legal Markdown JS Example](docs/legal-markdown-js-example.png)
12
12
 
@@ -60,16 +60,29 @@ legal-md document.md --html --css styles.css
60
60
  ### Programmatic Usage
61
61
 
62
62
  ```typescript
63
- import { processLegalMarkdown } from 'legal-markdown-js';
63
+ import {
64
+ processLegalMarkdown,
65
+ processLegalMarkdownAsync,
66
+ } from 'legal-markdown-js';
64
67
 
68
+ // Synchronous processing (legacy)
65
69
  const result = processLegalMarkdown(content, {
66
70
  basePath: './documents',
67
71
  exportMetadata: true,
68
72
  exportFormat: 'json',
69
73
  });
70
74
 
71
- console.log(result.content);
72
- console.log(result.metadata);
75
+ // Asynchronous processing with modern pipeline (recommended)
76
+ const asyncResult = await processLegalMarkdownAsync(content, {
77
+ basePath: './documents',
78
+ exportMetadata: true,
79
+ exportFormat: 'json',
80
+ enableFieldTracking: true,
81
+ });
82
+
83
+ console.log(asyncResult.content);
84
+ console.log(asyncResult.metadata);
85
+ console.log(asyncResult.fieldReport); // Enhanced field tracking
73
86
  ```
74
87
 
75
88
  ## Key Features
@@ -84,8 +97,7 @@ All original Legal Markdown features are fully implemented:
84
97
  `lll.`)
85
98
  - **Optional Clauses**: Boolean, equality, and logical operations
86
99
  (`[text]{condition}`)
87
- - **Cross-References**: All reference types including special date handling
88
- (`|reference|`)
100
+ - **Cross-References**: Internal section references using (`|reference|`) syntax
89
101
  - **Partial Imports**: File inclusion with path resolution (`@import`)
90
102
  - **Metadata Export**: YAML and JSON export with custom paths
91
103
 
@@ -93,14 +105,60 @@ All original Legal Markdown features are fully implemented:
93
105
 
94
106
  Additional features available only in the Node.js version:
95
107
 
96
- - **Mixins System**: Template substitution with `{{variable}}` syntax
108
+ - **Mixins System**: Template substitution and helpers with `{{variable}}`
109
+ syntax
110
+ - **AST-Based Processing**: Modern AST-based mixin processing to prevent text
111
+ contamination (v2.4.0+)
112
+ - **Pipeline Architecture**: Configurable step-based processing pipeline with
113
+ dependency management and performance monitoring (v2.4.0+)
97
114
  - **PDF Generation**: Professional PDF output with styling and field
98
115
  highlighting
99
116
  - **HTML Generation**: Custom HTML output with CSS support
100
- - **Template Loops**: Array iteration with `[#items]...[/items]` syntax
117
+ - **Template Loops**: Array iteration with `{{#items}}...{{/items}}` syntax
101
118
  - **Helper Functions**: Date, number, and string formatting helpers
102
119
  - **Force Commands**: Document-driven configuration with embedded CLI options
103
120
  - **Batch Processing**: Multi-file processing with concurrency control
121
+ - **Field Tracking**: Enhanced field tracking with proper categorization for
122
+ document review
123
+
124
+ ## Architecture & Performance
125
+
126
+ ### Modern Pipeline System (v2.4.0+)
127
+
128
+ Legal Markdown JS features a completely rewritten processing pipeline that
129
+ provides:
130
+
131
+ - **Step-Based Architecture**: Configurable processing steps with dependency
132
+ management
133
+ - **AST-Based Processing**: Modern AST parsing for mixin processing to prevent
134
+ text contamination
135
+ - **Performance Monitoring**: Built-in step profiling and performance metrics
136
+ - **Error Recovery**: Graceful fallback to legacy processing when needed
137
+ - **Field Tracking**: Enhanced field tracking with proper status categorization
138
+
139
+ #### Processing Order
140
+
141
+ The new pipeline ensures correct processing order to prevent conflicts:
142
+
143
+ 1. **YAML Front Matter** - Parse document metadata
144
+ 2. **Import Processing** - Handle file imports and inclusions
145
+ 3. **Optional Clauses** - Process conditional text blocks
146
+ 4. **Cross-References** - Resolve internal document references
147
+ 5. **Template Loops** - Expand array iterations first
148
+ 6. **AST Mixin Processing** - Process variables and helpers (avoids loop
149
+ conflicts)
150
+ 7. **Header Processing** - Apply numbering and formatting
151
+ 8. **Field Tracking** - Apply highlighting and generate reports
152
+
153
+ #### API Usage
154
+
155
+ ```typescript
156
+ // Use the modern async API for best performance
157
+ const result = await processLegalMarkdownAsync(content, options);
158
+
159
+ // Automatic fallback to legacy processing if needed
160
+ // No code changes required for existing applications
161
+ ```
104
162
 
105
163
  ## Documentation
106
164
 
@@ -14,6 +14,8 @@
14
14
  * - Mixin system for reusable content
15
15
  * - Date processing utilities
16
16
  * - Metadata export capabilities
17
+ * - Base processor interfaces for pipeline management
18
+ * - Core field tracking infrastructure
17
19
  *
18
20
  * @example
19
21
  * ```typescript
@@ -21,12 +23,21 @@
21
23
  * parseYamlFrontMatter,
22
24
  * processHeaders,
23
25
  * processOptionalClauses,
24
- * processCrossReferences
26
+ * processCrossReferences,
27
+ * BaseProcessor,
28
+ * FieldState
25
29
  * } from './core';
26
30
  *
27
31
  * // Use core processors in a custom pipeline
28
32
  * const { content, metadata } = parseYamlFrontMatter(rawContent);
29
33
  * const processed = processHeaders(content, metadata);
34
+ *
35
+ * // Implement a custom processor
36
+ * class MyProcessor implements BaseProcessor {
37
+ * name = 'my-processor';
38
+ * isEnabled(options) { return true; }
39
+ * process(content, metadata, options) { return content; }
40
+ * }
30
41
  * ```
31
42
  */
32
43
  export * from './parsers/yaml-parser';
@@ -34,7 +45,9 @@ export * from './processors/header-processor';
34
45
  export * from './processors/clause-processor';
35
46
  export * from './processors/reference-processor';
36
47
  export * from './processors/import-processor';
37
- export * from './processors/mixin-processor';
48
+ export * from '../extensions/ast-mixin-processor';
38
49
  export * from './processors/date-processor';
39
50
  export * from './exporters/metadata-exporter';
51
+ export * from './processors/base-processor';
52
+ export * from './tracking/field-state';
40
53
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,cAAc,uBAAuB,CAAC;AACtC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC;AACjD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAGH,cAAc,uBAAuB,CAAC;AAGtC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC;AACjD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mCAAmC,CAAC;AAClD,cAAc,6BAA6B,CAAC;AAG5C,cAAc,+BAA+B,CAAC;AAG9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC"}
@@ -15,6 +15,8 @@
15
15
  * - Mixin system for reusable content
16
16
  * - Date processing utilities
17
17
  * - Metadata export capabilities
18
+ * - Base processor interfaces for pipeline management
19
+ * - Core field tracking infrastructure
18
20
  *
19
21
  * @example
20
22
  * ```typescript
@@ -22,12 +24,21 @@
22
24
  * parseYamlFrontMatter,
23
25
  * processHeaders,
24
26
  * processOptionalClauses,
25
- * processCrossReferences
27
+ * processCrossReferences,
28
+ * BaseProcessor,
29
+ * FieldState
26
30
  * } from './core';
27
31
  *
28
32
  * // Use core processors in a custom pipeline
29
33
  * const { content, metadata } = parseYamlFrontMatter(rawContent);
30
34
  * const processed = processHeaders(content, metadata);
35
+ *
36
+ * // Implement a custom processor
37
+ * class MyProcessor implements BaseProcessor {
38
+ * name = 'my-processor';
39
+ * isEnabled(options) { return true; }
40
+ * process(content, metadata, options) { return content; }
41
+ * }
31
42
  * ```
32
43
  */
33
44
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
@@ -45,12 +56,18 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
45
56
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
46
57
  };
47
58
  Object.defineProperty(exports, "__esModule", { value: true });
59
+ // Core parsers
48
60
  __exportStar(require("./parsers/yaml-parser"), exports);
61
+ // Core processors
49
62
  __exportStar(require("./processors/header-processor"), exports);
50
63
  __exportStar(require("./processors/clause-processor"), exports);
51
64
  __exportStar(require("./processors/reference-processor"), exports);
52
65
  __exportStar(require("./processors/import-processor"), exports);
53
- __exportStar(require("./processors/mixin-processor"), exports);
66
+ __exportStar(require("../extensions/ast-mixin-processor"), exports);
54
67
  __exportStar(require("./processors/date-processor"), exports);
68
+ // Core exporters
55
69
  __exportStar(require("./exporters/metadata-exporter"), exports);
70
+ // Core infrastructure for pipeline management
71
+ __exportStar(require("./processors/base-processor"), exports);
72
+ __exportStar(require("./tracking/field-state"), exports);
56
73
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;;;;;;;;;;;;;;;;AAEH,wDAAsC;AACtC,gEAA8C;AAC9C,gEAA8C;AAC9C,mEAAiD;AACjD,gEAA8C;AAC9C,+DAA6C;AAC7C,8DAA4C;AAC5C,gEAA8C"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;;;;;;;;;;;;;;;;AAEH,eAAe;AACf,wDAAsC;AAEtC,kBAAkB;AAClB,gEAA8C;AAC9C,gEAA8C;AAC9C,mEAAiD;AACjD,gEAA8C;AAC9C,oEAAkD;AAClD,8DAA4C;AAE5C,iBAAiB;AACjB,gEAA8C;AAE9C,8CAA8C;AAC9C,8DAA4C;AAC5C,yDAAuC"}
@@ -0,0 +1,168 @@
1
+ /**
2
+ * @fileoverview Base Processor Interface for Legal Markdown Processing Pipeline
3
+ *
4
+ * This module defines the fundamental interface that all processors in the Legal Markdown
5
+ * pipeline must implement. It provides a standardized contract for processing steps,
6
+ * enabling the pipeline manager to orchestrate document processing in a consistent manner.
7
+ *
8
+ * Features:
9
+ * - Standardized processor interface
10
+ * - Enable/disable logic per processor
11
+ * - Consistent processing contract
12
+ * - Pipeline orchestration support
13
+ * - Backward compatibility with existing processors
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * import { BaseProcessor } from './base-processor';
18
+ *
19
+ * class MyCustomProcessor implements BaseProcessor {
20
+ * name = 'my-custom-processor';
21
+ *
22
+ * isEnabled(options: LegalMarkdownOptions): boolean {
23
+ * return !options.noCustomProcessing;
24
+ * }
25
+ *
26
+ * process(content: string, metadata: Record<string, any>, options: any): string {
27
+ * // Custom processing logic
28
+ * return processedContent;
29
+ * }
30
+ * }
31
+ * ```
32
+ */
33
+ import { LegalMarkdownOptions } from '@types';
34
+ /**
35
+ * Base interface that all processors in the Legal Markdown pipeline must implement
36
+ *
37
+ * This interface ensures consistency across all processing steps and enables
38
+ * the pipeline manager to coordinate document processing effectively.
39
+ *
40
+ * @interface BaseProcessor
41
+ * @example
42
+ * ```typescript
43
+ * class MixinProcessor implements BaseProcessor {
44
+ * name = 'mixins';
45
+ *
46
+ * isEnabled(options: LegalMarkdownOptions): boolean {
47
+ * return !options.noMixins;
48
+ * }
49
+ *
50
+ * process(content: string, metadata: Record<string, any>, options: LegalMarkdownOptions): string {
51
+ * return processMixins(content, metadata, options);
52
+ * }
53
+ * }
54
+ * ```
55
+ */
56
+ export interface BaseProcessor {
57
+ /** Unique name identifier for this processor */
58
+ readonly name: string;
59
+ /**
60
+ * Determines whether this processor should be executed based on the provided options
61
+ *
62
+ * @param options - The Legal Markdown processing options
63
+ * @returns True if the processor should be executed, false otherwise
64
+ * @example
65
+ * ```typescript
66
+ * // Processor that runs unless explicitly disabled
67
+ * isEnabled(options: LegalMarkdownOptions): boolean {
68
+ * return !options.noMixins;
69
+ * }
70
+ *
71
+ * // Processor that only runs when specific option is enabled
72
+ * isEnabled(options: LegalMarkdownOptions): boolean {
73
+ * return options.enableAdvancedFeatures;
74
+ * }
75
+ * ```
76
+ */
77
+ isEnabled(options: LegalMarkdownOptions): boolean;
78
+ /**
79
+ * Processes the document content according to this processor's specific logic
80
+ *
81
+ * @param content - The document content to process
82
+ * @param metadata - The document metadata (YAML front matter, etc.)
83
+ * @param options - The Legal Markdown processing options
84
+ * @returns The processed content
85
+ * @throws {Error} When processing fails critically
86
+ * @example
87
+ * ```typescript
88
+ * process(content: string, metadata: Record<string, any>, options: LegalMarkdownOptions): string {
89
+ * if (!this.isEnabled(options)) {
90
+ * return content; // Return unchanged if disabled
91
+ * }
92
+ *
93
+ * try {
94
+ * return this.performProcessing(content, metadata, options);
95
+ * } catch (error) {
96
+ * console.warn(`Processor ${this.name} failed, returning original content:`, error);
97
+ * return content; // Graceful fallback
98
+ * }
99
+ * }
100
+ * ```
101
+ */
102
+ process(content: string, metadata: Record<string, any>, options: LegalMarkdownOptions): string;
103
+ }
104
+ /**
105
+ * Abstract base class that provides common functionality for processors
106
+ *
107
+ * This class implements common patterns and provides utility methods that
108
+ * most processors will need, reducing boilerplate code.
109
+ *
110
+ * @abstract
111
+ * @class AbstractProcessor
112
+ * @implements {BaseProcessor}
113
+ * @example
114
+ * ```typescript
115
+ * class MyProcessor extends AbstractProcessor {
116
+ * name = 'my-processor';
117
+ *
118
+ * isEnabled(options: LegalMarkdownOptions): boolean {
119
+ * return !options.noMyProcessor;
120
+ * }
121
+ *
122
+ * protected performProcessing(content: string, metadata: Record<string, any>, options: LegalMarkdownOptions): string {
123
+ * // Actual processing logic here
124
+ * return processedContent;
125
+ * }
126
+ * }
127
+ * ```
128
+ */
129
+ export declare abstract class AbstractProcessor implements BaseProcessor {
130
+ abstract readonly name: string;
131
+ abstract isEnabled(options: LegalMarkdownOptions): boolean;
132
+ /**
133
+ * Template method that handles common processing patterns
134
+ *
135
+ * This method provides error handling, logging, and other common functionality,
136
+ * delegating the actual processing to the performProcessing method.
137
+ */
138
+ process(content: string, metadata: Record<string, any>, options: LegalMarkdownOptions): string;
139
+ /**
140
+ * Abstract method where subclasses implement their specific processing logic
141
+ *
142
+ * @param content - The document content to process
143
+ * @param metadata - The document metadata
144
+ * @param options - The processing options
145
+ * @returns The processed content
146
+ * @protected
147
+ */
148
+ protected abstract performProcessing(content: string, metadata: Record<string, any>, options: LegalMarkdownOptions): string;
149
+ /**
150
+ * Utility method to check if content has already been processed by another step
151
+ *
152
+ * This helps prevent double-processing and conflicts between processors.
153
+ *
154
+ * @param content - The content to check
155
+ * @returns True if content appears to have been processed (contains spans, etc.)
156
+ * @protected
157
+ */
158
+ protected hasBeenProcessed(content: string): boolean;
159
+ /**
160
+ * Utility method to log processing information in debug mode
161
+ *
162
+ * @param message - The message to log
163
+ * @param data - Optional data to include in the log
164
+ * @protected
165
+ */
166
+ protected debug(message: string, data?: any): void;
167
+ }
168
+ //# sourceMappingURL=base-processor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-processor.d.ts","sourceRoot":"","sources":["../../../src/core/processors/base-processor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;;;;;;;;;;;;;;;OAiBG;IACH,SAAS,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC;IAElD;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAAC;CAChG;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,8BAAsB,iBAAkB,YAAW,aAAa;IAC9D,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO;IAE1D;;;;;OAKG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,oBAAoB,GAAG,MAAM;IAa9F;;;;;;;;OAQG;IACH,SAAS,CAAC,QAAQ,CAAC,iBAAiB,CAClC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC7B,OAAO,EAAE,oBAAoB,GAC5B,MAAM;IAET;;;;;;;;OAQG;IACH,SAAS,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAQpD;;;;;;OAMG;IACH,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;CAKnD"}
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ /**
3
+ * @fileoverview Base Processor Interface for Legal Markdown Processing Pipeline
4
+ *
5
+ * This module defines the fundamental interface that all processors in the Legal Markdown
6
+ * pipeline must implement. It provides a standardized contract for processing steps,
7
+ * enabling the pipeline manager to orchestrate document processing in a consistent manner.
8
+ *
9
+ * Features:
10
+ * - Standardized processor interface
11
+ * - Enable/disable logic per processor
12
+ * - Consistent processing contract
13
+ * - Pipeline orchestration support
14
+ * - Backward compatibility with existing processors
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * import { BaseProcessor } from './base-processor';
19
+ *
20
+ * class MyCustomProcessor implements BaseProcessor {
21
+ * name = 'my-custom-processor';
22
+ *
23
+ * isEnabled(options: LegalMarkdownOptions): boolean {
24
+ * return !options.noCustomProcessing;
25
+ * }
26
+ *
27
+ * process(content: string, metadata: Record<string, any>, options: any): string {
28
+ * // Custom processing logic
29
+ * return processedContent;
30
+ * }
31
+ * }
32
+ * ```
33
+ */
34
+ Object.defineProperty(exports, "__esModule", { value: true });
35
+ exports.AbstractProcessor = void 0;
36
+ /**
37
+ * Abstract base class that provides common functionality for processors
38
+ *
39
+ * This class implements common patterns and provides utility methods that
40
+ * most processors will need, reducing boilerplate code.
41
+ *
42
+ * @abstract
43
+ * @class AbstractProcessor
44
+ * @implements {BaseProcessor}
45
+ * @example
46
+ * ```typescript
47
+ * class MyProcessor extends AbstractProcessor {
48
+ * name = 'my-processor';
49
+ *
50
+ * isEnabled(options: LegalMarkdownOptions): boolean {
51
+ * return !options.noMyProcessor;
52
+ * }
53
+ *
54
+ * protected performProcessing(content: string, metadata: Record<string, any>, options: LegalMarkdownOptions): string {
55
+ * // Actual processing logic here
56
+ * return processedContent;
57
+ * }
58
+ * }
59
+ * ```
60
+ */
61
+ class AbstractProcessor {
62
+ /**
63
+ * Template method that handles common processing patterns
64
+ *
65
+ * This method provides error handling, logging, and other common functionality,
66
+ * delegating the actual processing to the performProcessing method.
67
+ */
68
+ process(content, metadata, options) {
69
+ if (!this.isEnabled(options)) {
70
+ return content;
71
+ }
72
+ try {
73
+ return this.performProcessing(content, metadata, options);
74
+ }
75
+ catch (error) {
76
+ console.warn(`Processor '${this.name}' failed, returning original content:`, error);
77
+ return content;
78
+ }
79
+ }
80
+ /**
81
+ * Utility method to check if content has already been processed by another step
82
+ *
83
+ * This helps prevent double-processing and conflicts between processors.
84
+ *
85
+ * @param content - The content to check
86
+ * @returns True if content appears to have been processed (contains spans, etc.)
87
+ * @protected
88
+ */
89
+ hasBeenProcessed(content) {
90
+ return (content.includes('class="imported-value"') ||
91
+ content.includes('class="missing-value"') ||
92
+ content.includes('class="highlight"'));
93
+ }
94
+ /**
95
+ * Utility method to log processing information in debug mode
96
+ *
97
+ * @param message - The message to log
98
+ * @param data - Optional data to include in the log
99
+ * @protected
100
+ */
101
+ debug(message, data) {
102
+ if (process.env.NODE_ENV === 'development') {
103
+ console.log(`[${this.name.toUpperCase()}] ${message}`, data || '');
104
+ }
105
+ }
106
+ }
107
+ exports.AbstractProcessor = AbstractProcessor;
108
+ //# sourceMappingURL=base-processor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-processor.js","sourceRoot":"","sources":["../../../src/core/processors/base-processor.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;;;AA6EH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAsB,iBAAiB;IAIrC;;;;;OAKG;IACH,OAAO,CAAC,OAAe,EAAE,QAA6B,EAAE,OAA6B;QACnF,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7B,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC5D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,uCAAuC,EAAE,KAAK,CAAC,CAAC;YACpF,OAAO,OAAO,CAAC;QACjB,CAAC;IACH,CAAC;IAiBD;;;;;;;;OAQG;IACO,gBAAgB,CAAC,OAAe;QACxC,OAAO,CACL,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAC;YAC1C,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAC;YACzC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CACtC,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACO,KAAK,CAAC,OAAe,EAAE,IAAU;QACzC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,EAAE,CAAC;YAC3C,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,OAAO,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;QACrE,CAAC;IACH,CAAC;CACF;AAnED,8CAmEC"}
@@ -1,115 +1,69 @@
1
1
  /**
2
2
  * @fileoverview Cross-Reference Processing Module for Legal Markdown Documents
3
3
  *
4
- * This module provides functionality to process cross-references in Legal Markdown
5
- * documents, replacing reference placeholders with actual values from metadata.
6
- * It supports various formatting options including date formatting, currency
7
- * formatting, and nested metadata access through dot notation.
4
+ * This module provides functionality to process internal cross-references in Legal Markdown
5
+ * documents, allowing sections to reference other sections by their keys.
6
+ * Based on the original Ruby Legal Markdown specification.
8
7
  *
9
8
  * Features:
10
- * - Cross-reference syntax: |reference_key|
11
- * - Date reference processing with @today support
12
- * - Automatic currency formatting for amount fields
13
- * - Nested metadata value access with dot notation
14
- * - Type-aware value formatting (dates, numbers, strings)
15
- * - Fallback to original reference if value not found
16
- * - Integration with date-processor for date handling
9
+ * - Internal cross-reference syntax: |reference_key|
10
+ * - Automatic section numbering and reference resolution
11
+ * - Reference capture from headers with |key| syntax
12
+ * - Section reference replacement throughout the document
13
+ * - Compatible with legal document numbering (l., ll., lll.)
17
14
  *
18
15
  * @example
19
16
  * ```typescript
20
17
  * import { processCrossReferences } from './reference-processor';
21
18
  *
22
19
  * const content = `
23
- * This agreement is between |client.name| and |provider.name|.
24
- * The total amount is |contract.amount| due on |contract.due_date|.
25
- * Document generated on |@today|.
26
- * `;
20
+ * l. **Definitions** |definitions|
21
+ *
22
+ * Terms defined in |definitions| apply throughout this agreement.
27
23
  *
28
- * const metadata = {
29
- * client: { name: "Acme Corp" },
30
- * provider: { name: "Service Ltd" },
31
- * contract: {
32
- * amount: 25000,
33
- * due_date: new Date("2024-12-31")
34
- * },
35
- * payment_currency: "USD"
36
- * };
24
+ * l. **Payment Terms** |payment|
37
25
  *
38
- * const processed = processCrossReferences(content, metadata);
26
+ * As outlined in |payment|, payment is due within 30 days.
27
+ * Reference to |definitions| for term meanings.
28
+ * `;
29
+ *
30
+ * const processed = processCrossReferences(content, {});
39
31
  * console.log(processed);
40
32
  * // Output:
41
- * // This agreement is between Acme Corp and Service Ltd.
42
- * // The total amount is $25,000.00 due on 2024-12-31.
43
- * // Document generated on 2024-01-15.
33
+ * // Article 1. **Definitions**
34
+ * //
35
+ * // Terms defined in Article 1 apply throughout this agreement.
36
+ * //
37
+ * // Article 2. **Payment Terms**
38
+ * //
39
+ * // As outlined in Article 2, payment is due within 30 days.
40
+ * // Reference to Article 1 for term meanings.
44
41
  * ```
45
42
  */
46
43
  /**
47
- * Processes cross-references in a LegalMarkdown document
44
+ * Processes internal cross-references in a Legal Markdown document
48
45
  *
49
- * This is the main function that processes cross-references using the |reference_key|
50
- * syntax. It first processes date references, then handles regular cross-references
51
- * with automatic formatting based on value type and field names.
46
+ * This function implements a hybrid approach:
47
+ * 1. First tries to resolve |key| as internal section references (Ruby spec)
48
+ * 2. Falls back to metadata values for backward compatibility
52
49
  *
53
50
  * @param {string} content - The document content containing cross-references
54
- * @param {Record<string, any>} metadata - Document metadata with reference values
55
- * @returns {string} Processed content with references replaced by their values
51
+ * @param {Record<string, any>} metadata - Document metadata (used for level formatting and fallback)
52
+ * @returns {string} Processed content with internal references resolved
56
53
  * @example
57
54
  * ```typescript
58
- * // Basic reference processing
59
- * const content = "Payment due: |payment.amount| on |payment.date|";
60
- * const metadata = {
61
- * payment: {
62
- * amount: 1500,
63
- * date: new Date("2024-03-15")
64
- * },
65
- * payment_currency: "EUR"
66
- * };
67
- *
68
- * const result = processCrossReferences(content, metadata);
69
- * // Output: "Payment due: €1,500.00 on 2024-03-15"
55
+ * const content = `
56
+ * l. **Contract Terms** |terms|
70
57
  *
71
- * // Nested reference access
72
- * const content2 = "Contact: |client.contact.email| (|client.contact.phone|)";
73
- * const metadata2 = {
74
- * client: {
75
- * contact: {
76
- * email: "info@client.com",
77
- * phone: "+1-555-0123"
78
- * }
79
- * }
80
- * };
58
+ * As specified in |terms|, this agreement is binding.
59
+ * Reference to |client_name| from metadata.
60
+ * `;
81
61
  *
82
- * const result2 = processCrossReferences(content2, metadata2);
83
- * // Output: "Contact: info@client.com (+1-555-0123)"
62
+ * const metadata = { client_name: "ACME Corp" };
63
+ * const result = processCrossReferences(content, metadata);
64
+ * // |terms| -> "Article 1." (internal reference)
65
+ * // |client_name| -> "ACME Corp" (metadata fallback)
84
66
  * ```
85
67
  */
86
68
  export declare function processCrossReferences(content: string, metadata: Record<string, any>): string;
87
- /**
88
- * Processes special reference formats like dates and currency amounts
89
- *
90
- * Applies appropriate formatting to reference values based on their type and
91
- * optional format specifiers. Handles dates, currency amounts, and falls back
92
- * to string conversion for other types.
93
- *
94
- * @param {any} value - The reference value to format
95
- * @param {string} [format] - Optional format specifier (e.g., "currency:USD:en-US")
96
- * @returns {string} Formatted value as string
97
- * @example
98
- * ```typescript
99
- * // Date formatting
100
- * const date = new Date("2024-03-15");
101
- * console.log(formatReferenceValue(date)); // "2024-03-15"
102
- * console.log(formatReferenceValue(date, "long")); // "March 15, 2024"
103
- * console.log(formatReferenceValue(date, "short")); // "3/15/2024"
104
- *
105
- * // Currency formatting
106
- * console.log(formatReferenceValue(1500, "currency:USD")); // "$1,500.00"
107
- * console.log(formatReferenceValue(1500, "currency:EUR:de-DE")); // "1.500,00 €"
108
- *
109
- * // Default string conversion
110
- * console.log(formatReferenceValue("Hello World")); // "Hello World"
111
- * console.log(formatReferenceValue(12345)); // "12345"
112
- * ```
113
- */
114
- export declare function formatReferenceValue(value: any, format?: string): string;
115
69
  //# sourceMappingURL=reference-processor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reference-processor.d.ts","sourceRoot":"","sources":["../../../src/core/processors/reference-processor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAIH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CA4B7F;AA6CD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAgBxE"}
1
+ {"version":3,"file":"reference-processor.d.ts","sourceRoot":"","sources":["../../../src/core/processors/reference-processor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAWH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAM7F"}