UNPKG

markmv

Version:

TypeScript CLI for markdown file operations with intelligent link refactoring

184 lines • 7.07 kB
import { ContentSplitter } from '../core/content-splitter.js'; /** * Execute the split command to divide a single markdown file into multiple files. * * This command provides intelligent splitting of markdown files using various strategies and * automatic link refactoring. It supports: * * - Header-based splitting (by heading levels) * - Size-based splitting (by file size limits) * - Line-based splitting (at specific line numbers) * - Manual splitting (with user guidance) * - Automatic link updates and integrity validation * - Custom output directory specification * * The split operation automatically updates all cross-references to reflect the new file structure * and maintains link integrity throughout the project. * * @category Commands * * @example * Header-based splitting * ```typescript * await splitCommand('large-document.md', { * strategy: 'headers', * headerLevel: 2, * output: './sections/' * }); * ``` * * @example * Size-based splitting with dry run * ```typescript * await splitCommand('big-file.md', { * strategy: 'size', * maxSize: 50, // 50KB per file * dryRun: true, * verbose: true * }); * ``` * * @example * Line-based splitting * ```typescript * await splitCommand('content.md', { * strategy: 'lines', * splitLines: '100,250,400', * output: './parts/' * }); * ``` * * @param source - Path to the markdown file to split * @param options - Configuration options for the split operation * * @throws Will exit the process with code 1 if the operation fails */ export async function splitCommand(source, options) { const splitter = new ContentSplitter(); // Parse split lines if provided let splitLines; if (options.splitLines) { try { splitLines = options.splitLines .split(',') .map((line) => Number.parseInt(line.trim(), 10)) .filter((line) => !Number.isNaN(line)); if (splitLines.length === 0) { console.error('āŒ Invalid split lines format. Use comma-separated numbers like: 10,25,50'); process.exit(1); } } catch (error) { console.error('āŒ Failed to parse split lines:', error); process.exit(1); } } const splitOptions = { strategy: options.strategy || 'headers', outputDir: options.output || '.', dryRun: options.dryRun || false, verbose: options.verbose || false, headerLevel: options.headerLevel || 2, maxSize: options.maxSize || 100, splitLines: splitLines || undefined, }; if (options.verbose) { console.log(`šŸ”Ŗ Splitting ${source} using ${splitOptions.strategy} strategy`); if (options.dryRun) { console.log('šŸ” Dry run mode - no changes will be made'); } if (splitOptions.strategy === 'headers') { console.log(`šŸ“‹ Split on header level: ${splitOptions.headerLevel}`); } if (splitOptions.strategy === 'size') { console.log(`šŸ“ Maximum size per section: ${splitOptions.maxSize}KB`); } if (splitOptions.strategy === 'lines' && splitOptions.splitLines) { console.log(`šŸ“ Split at lines: ${splitOptions.splitLines.join(', ')}`); } } try { const result = await splitter.splitFile(source, splitOptions); if (!result.success) { console.error('āŒ Split operation failed:'); for (const error of result.errors) { console.error(` ${error}`); } process.exit(1); } // Display results if (options.dryRun) { console.log('\nšŸ“‹ Changes that would be made:'); if (result.createdFiles.length > 0) { console.log('\nšŸ“„ Files that would be created:'); for (const file of result.createdFiles) { console.log(` + ${file}`); } } if (result.modifiedFiles.length > 0) { console.log('\nšŸ“ Files that would be modified:'); for (const file of result.modifiedFiles) { console.log(` ~ ${file}`); } } if (result.changes.length > 0 && options.verbose) { console.log('\nšŸ”— Changes:'); for (const change of result.changes) { if (change.type === 'file-created') { console.log(` + Created: ${change.filePath}`); } else if (change.type === 'link-updated') { console.log(` ~ Updated links in: ${change.filePath}`); } } } console.log(`\nšŸ“Š Summary: Would create ${result.createdFiles.length} file(s) and modify ${result.modifiedFiles.length} file(s)`); } else { console.log('āœ… Split operation completed successfully!'); console.log(`šŸ“„ Created ${result.createdFiles.length} new file(s):`); for (const file of result.createdFiles) { console.log(` + ${file}`); } if (result.modifiedFiles.length > 0) { console.log(`\nšŸ“ Modified ${result.modifiedFiles.length} file(s):`); for (const file of result.modifiedFiles) { console.log(` ~ ${file}`); } } if (options.verbose && result.changes.length > 0) { const linkUpdates = result.changes.filter((c) => c.type === 'link-updated').length; if (linkUpdates > 0) { console.log(`\nšŸ”— Updated links in ${linkUpdates} file(s)`); } } } // Display warnings if (result.warnings.length > 0) { console.log('\nāš ļø Warnings:'); for (const warning of result.warnings) { console.log(` ${warning}`); } } // Show helpful tips if (!options.dryRun && result.success) { console.log('\nšŸ’” Tips:'); console.log(' • Use --dry-run to preview changes before splitting'); console.log(' • Use --verbose for detailed operation logs'); if (splitOptions.strategy === 'headers') { console.log(' • Use --header-level to control which headers trigger splits'); } if (splitOptions.strategy === 'size') { console.log(' • Use --max-size to adjust the maximum file size (in KB)'); } if (splitOptions.strategy === 'lines') { console.log(' • Use --split-lines with comma-separated line numbers (e.g., --split-lines 10,25,50)'); } } } catch (error) { console.error(`āŒ Unexpected error: ${error}`); process.exit(1); } } //# sourceMappingURL=split.js.map