UNPKG

legal-markdown-js

Version:

Node.js implementation of LegalMarkdown for processing legal documents with markdown and YAML - Complete feature parity with Ruby version

182 lines 7.07 kB
/** * Remark plugin for Legal Markdown template field processing * * This plugin processes template fields like {{field_name}} in Legal Markdown documents * using AST-based processing. It handles: * - Simple variables: {{client.name}} * - Nested object access: {{client.contact.email}} * - Helper functions: {{formatDate date "YYYY-MM-DD"}} * - Parenthesized helper syntax: {{formatDate(@today, "YYYY-MM-DD")}} * - Subexpressions: {{formatDate (addYears today 2) "YYYY-MM-DD"}} * - Conditional expressions: {{active ? "Active" : "Inactive"}} * - Field tracking integration for highlighting * * Syntax Support (Issue #142): * - **Space-separated syntax** (standard): {{helper arg1 arg2}} * - **Parenthesized syntax**: {{helper(arg1, arg2)}} * * Architecture: * 1. Parse template field patterns in text nodes * 2. Resolve field values from metadata * 3. Replace patterns with resolved values * 4. Track fields for highlighting support * * @example * ```typescript * import { unified } from 'unified'; * import remarkParse from 'remark-parse'; * import remarkTemplateFields from './template-fields.js'; * * // Handlebars syntax (current) * const processor = unified() * .use(remarkParse) * .use(remarkTemplateFields, { * metadata: { * client_name: 'ACME Corp', * date: new Date('2025-01-15') * } * }); * * const result = await processor.process('Hello {{client_name}}! Date: {{formatDate date "MMMM Do, YYYY"}}'); * // Output: Hello ACME Corp! Date: January 15th, 2025 * ``` * * @module */ import type { Plugin } from 'unified'; import type { Root } from 'mdast'; import type { YamlValue } from '../../types/index.js'; /** * Template field definition extracted from text */ interface TemplateField { pattern: string; fieldName: string; expression: string; startIndex: number; endIndex: number; } /** * Plugin options for template field processing */ interface TemplateFieldOptions { /** Document metadata containing field values */ metadata: Record<string, YamlValue>; /** Enable debug logging */ debug?: boolean; /** Custom field patterns (defaults to {{field}} syntax) */ fieldPatterns?: string[]; /** Enable field tracking with highlighting during AST processing */ enableFieldTracking?: boolean; /** Use AST-first field tracking tokens */ astFieldTracking?: boolean; /** Highlight winner branches for conditionals */ logicBranchHighlighting?: boolean; } /** * Check if a position is inside a loop or conditional block */ declare function isInsideLoopOrConditional(text: string, position: number): boolean; /** * Extract template fields from text content */ declare function extractTemplateFields(text: string, patterns: string[]): TemplateField[]; /** * Resolve template field value from metadata */ declare function resolveFieldValue(fieldName: string, metadata: Record<string, YamlValue>): { value: YamlValue | undefined; hasLogic: boolean; mixinType?: string; isEmptyCondition?: boolean; }; /** * Resolve nested value from metadata using dot notation */ declare function resolveNestedValue(metadata: Record<string, YamlValue>, path: string): YamlValue | undefined; /** * Format value for display with optional field tracking */ declare function formatFieldValue(value: YamlValue | undefined, fieldName: string, enableFieldTracking?: boolean, hasLogic?: boolean, isEmptyField?: boolean): string; /** * Check if a text node is inside existing field tracking spans by examining sibling HTML nodes */ declare function isInsideFieldTrackingSpan(node: unknown, parent: unknown): boolean; /** * Smart split function that respects quoted strings and parentheses * * Splits a string on commas while preserving commas inside quoted strings * and nested parentheses (for helper function calls). * Handles both single and double quotes. * * @param str - String to split * @returns Array of split parts * * @example * ```typescript * smartSplitArguments('arg1, "arg with, comma", arg3') * // Returns: ['arg1', '"arg with, comma"', 'arg3'] * * smartSplitArguments('addYears(@today, 5), "YYYY-MM-DD"') * // Returns: ['addYears(@today, 5)', '"YYYY-MM-DD"'] * ``` */ declare function smartSplitArguments(str: string): string[]; /** * Parse comma-separated arguments from a helper function call with support for nested calls * * Parses helper function arguments, resolving metadata references, handling * string literals, numbers, booleans, and nested helper function calls. * * @param argsString - Raw arguments string from helper call * @param metadata - Metadata object for resolving references * @returns Array of parsed argument values * * @example * ```typescript * parseHelperArguments("@today, 'YYYY-MM-DD'", { today: new Date() }) * // Returns: [Date, 'YYYY-MM-DD'] * * parseHelperArguments("addYears(@today, 5), 'YYYY-MM-DD'", { '@today': new Date() }) * // Returns: [Date (5 years added), 'YYYY-MM-DD'] * * parseHelperArguments("amount, 'USD'", { amount: 1500 }) * // Returns: [1500, 'USD'] * ``` */ declare function parseHelperArguments(argsString: string, metadata: Record<string, YamlValue>): (YamlValue | undefined)[]; /** * Parse Handlebars-style space-separated arguments from a helper function call * * Parses Handlebars helper arguments (space-separated instead of comma-separated), * resolving metadata references, handling string literals, numbers, booleans, * subexpressions, and nested helper function calls. * * @param argsString - Raw arguments string from Handlebars helper call * @param metadata - Metadata object for resolving references * @returns Array of parsed argument values * * @example * ```typescript * parseHandlebarsArguments('date "MMMM Do, YYYY"', { date: new Date() }) * // Returns: [Date, 'MMMM Do, YYYY'] * * parseHandlebarsArguments('(addYears today 5) "YYYY-MM-DD"', { today: new Date() }) * // Returns: [Date (5 years added), 'YYYY-MM-DD'] * * parseHandlebarsArguments('amount "USD"', { amount: 1500 }) * // Returns: [1500, 'USD'] * * parseHandlebarsArguments('price quantity', { price: 10, quantity: 5 }) * // Returns: [10, 5] * ``` */ declare function parseHandlebarsArguments(argsString: string, metadata: Record<string, YamlValue>): (YamlValue | undefined)[]; /** * Remark plugin for processing template fields in Legal Markdown documents */ declare const remarkTemplateFields: Plugin<[TemplateFieldOptions], Root>; export default remarkTemplateFields; export type { TemplateFieldOptions, TemplateField }; export { isInsideLoopOrConditional as _isInsideLoopOrConditional, extractTemplateFields as _extractTemplateFields, resolveFieldValue as _resolveFieldValue, resolveNestedValue as _resolveNestedValue, formatFieldValue as _formatFieldValue, isInsideFieldTrackingSpan as _isInsideFieldTrackingSpan, smartSplitArguments as _smartSplitArguments, parseHelperArguments as _parseHelperArguments, parseHandlebarsArguments as _parseHandlebarsArguments, }; //# sourceMappingURL=template-fields.d.ts.map