UNPKG

line-commenter-tool

Version:

A tool to comment or uncomment lines in a file based on regex patterns and specific strings.

143 lines (123 loc) 6.13 kB
import fs from 'fs-extra'; // Helper function to escape special characters for use in regex export function escapeRegExp(string) { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } // Main function to process the file export async function processFile(action, filename, regexPattern, strings, options = {}) { const { silent = false, multiline = false } = options; // Helper function to determine the comment symbol based on file extension function getCommentSymbol(filename) { if (filename.match(/\.(js|jsx|ts|tsx|c|cpp|cs|java|php)$/)) return '//'; if (filename.match(/\.(py|rb|sh|yml|yaml)$/) || filename === 'Dockerfile') return '#'; if (filename.match(/\.(html|xml|md)$/)) return '<!-- -->'; if (filename.match(/\.(css|scss|less)$/)) return '/* */'; return '//'; // Default } // Helper function to detect line endings function detectLineEnding(content) { const crlf = /\r\n/; return crlf.test(content) ? '\r\n' : '\n'; } try { let content = await fs.readFile(filename, 'utf8'); // Detect original line endings const originalLineEnding = detectLineEnding(content); // Normalize line endings to LF for consistent processing content = content.replace(/\r\n/g, '\n'); const commentSymbol = getCommentSymbol(filename); const startComment = commentSymbol.split(' ')[0]; const endComment = commentSymbol.split(' ')[1] ? commentSymbol.split(' ')[1] : ''; const processSingleLineComment = (commentRegex, actionType) => { if (actionType === 'comment') { content = content.replace(commentRegex, (match, p1, p2) => { // Skip lines only if they already start with the comment symbol if (p2.trimStart().startsWith(commentSymbol)) { return match; } return `${p1}${startComment} ${p2}`; }); } else if (actionType === 'uncomment') { content = content.replace(commentRegex, (match, p1, p2) => { return `${p1}${p2}`; }); } }; const processMultilineBlockComment = (startPattern, endPattern, actionType) => { const blockCommentRegex = new RegExp( new RegExp(`^([\\s]*)${startPattern}\\s*[\\S]*?${endPattern}`, 'gm'), 'gm' ); if (actionType === 'comment') { content = content.replace(blockCommentRegex, match => { // Properly handle nested block comments if (match.trim().startsWith(startPattern)) { return match; } return `${startPattern} ${match.trim()} ${endPattern}`; }); } else if (actionType === 'uncomment') { content = content.replace(blockCommentRegex, match => match.replace(new RegExp(`^\\s*${startPattern}\\s*|\\s*${endPattern}\\s*$`, 'g'), '')); } }; const processPythonMultilineStrings = (actionType) => { const tripleQuoteRegex = /(["']{3})([\s\S]*?)\1/gm; if (actionType === 'comment') { content = content.replace(tripleQuoteRegex, (match, p1, p2) => { // Skip processing inside triple-quoted strings return match; }); } }; if (action === 'comment' || action === 'uncomment') { if (multiline && endComment) { // Handle multiline comments if (regexPattern) { const startPattern = startComment; const endPattern = endComment; processMultilineBlockComment(startPattern, endPattern, action); } } else { if (filename.endsWith('.py') && action === 'comment') { // Process Python multiline strings first to avoid modifying them processPythonMultilineStrings(action); const regex = new RegExp(`^\\s*${regexPattern}`, 'gm'); content = content.replace(regex, (match) => { if (match.trimStart().startsWith(commentSymbol)) { return match; } return `${startComment} ${match}`; }); } else if (filename.endsWith('.css') && action === 'comment') { const regex = new RegExp(regexPattern, 'g'); content = content.replace(regex, (match) => { // Wrap matched content in block comments return `/* ${match.trim()} */`; }); } else { if (strings && strings.length > 0) { strings.forEach((string) => { const escapedString = escapeRegExp(string); const commentRegex = new RegExp(`^([\\s]*)${action === 'uncomment' ? startComment + '\\s*' : ''}(.*${escapedString}.*)$`, 'gm'); processSingleLineComment(commentRegex, action); }); } if (regexPattern) { const regexCommentRegex = new RegExp(`^([\\s]*)${action === 'uncomment' ? startComment + '\\s*' : ''}(.*${regexPattern}.*)$`, 'gm'); processSingleLineComment(regexCommentRegex, action); } } } } // Restore original line endings content = content.replace(/\n/g, originalLineEnding); await fs.writeFile(filename, content, 'utf8'); if (!silent) { console.log(`Successfully processed file ${filename}`); } } catch (error) { console.error(`Error processing file: ${error.message}`); process.exit(1); } } export default processFile;