comment-strip-cli
Version:
A powerful CLI tool to strip comments from source code files while preserving strings and important metadata
357 lines (332 loc) • 8.3 kB
JavaScript
const fs = require('fs');
const path = require('path');
const builtinLanguageConfigs = {
// C/C++ family
c: {
name: 'C',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
},
h: {
name: 'C Header',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
},
cpp: {
name: 'C++',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
},
cxx: {
name: 'C++',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
},
cc: {
name: 'C++',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
},
hpp: {
name: 'C++ Header',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
},
hxx: {
name: 'C++ Header',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
},
// JavaScript/TypeScript family
js: {
name: 'JavaScript',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
},
mjs: {
name: 'JavaScript Module',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
},
jsx: {
name: 'React JSX',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
},
ts: {
name: 'TypeScript',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
},
tsx: {
name: 'TypeScript JSX',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
},
// Python
py: {
name: 'Python',
hash: { type: 'hash', pattern: '#' }
},
pyw: {
name: 'Python',
hash: { type: 'hash', pattern: '#' }
},
// Other programming languages
sol: {
name: 'Solidity',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
},
rs: {
name: 'Rust',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
},
go: {
name: 'Go',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
},
java: {
name: 'Java',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
},
kt: {
name: 'Kotlin',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
},
kts: {
name: 'Kotlin Script',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
},
swift: {
name: 'Swift',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
},
dart: {
name: 'Dart',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
},
scala: {
name: 'Scala',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
},
sc: {
name: 'Scala',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
},
// Web technologies
php: {
name: 'PHP',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' },
hash: { type: 'hash', pattern: '#' }
},
phtml: {
name: 'PHP',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' },
hash: { type: 'hash', pattern: '#' }
},
css: {
name: 'CSS',
block: { type: 'block', pattern: '/* */' }
},
scss: {
name: 'SCSS',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
},
// Scripting languages
rb: {
name: 'Ruby',
hash: { type: 'hash', pattern: '#' }
},
rbw: {
name: 'Ruby',
hash: { type: 'hash', pattern: '#' }
},
pl: {
name: 'Perl',
hash: { type: 'hash', pattern: '#' }
},
pm: {
name: 'Perl',
hash: { type: 'hash', pattern: '#' }
},
r: {
name: 'R',
hash: { type: 'hash', pattern: '#' }
},
R: {
name: 'R',
hash: { type: 'hash', pattern: '#' }
},
// Shell scripts
sh: {
name: 'Shell',
hash: { type: 'hash', pattern: '#' }
},
bash: {
name: 'Bash',
hash: { type: 'hash', pattern: '#' }
},
zsh: {
name: 'Zsh',
hash: { type: 'hash', pattern: '#' }
},
// Configuration files
dockerfile: {
name: 'Docker',
hash: { type: 'hash', pattern: '#' }
},
cmake: {
name: 'CMake',
hash: { type: 'hash', pattern: '#' }
},
toml: {
name: 'TOML',
hash: { type: 'hash', pattern: '#' }
},
yml: {
name: 'YAML',
hash: { type: 'hash', pattern: '#' }
},
yaml: {
name: 'YAML',
hash: { type: 'hash', pattern: '#' }
},
ini: {
name: 'INI Config',
hash: { type: 'hash', pattern: '#' },
semicolon: { type: 'semicolon', pattern: ';' }
},
cfg: {
name: 'Config',
hash: { type: 'hash', pattern: '#' },
semicolon: { type: 'semicolon', pattern: ';' }
},
conf: {
name: 'Config',
hash: { type: 'hash', pattern: '#' },
semicolon: { type: 'semicolon', pattern: ';' }
},
makefile: {
name: 'Makefile',
hash: { type: 'hash', pattern: '#' }
},
mk: {
name: 'Makefile',
hash: { type: 'hash', pattern: '#' }
},
// Assembly
asm: {
name: 'Assembly',
hash: { type: 'hash', pattern: '#' },
semicolon: { type: 'semicolon', pattern: ';' }
},
s: {
name: 'Assembly',
hash: { type: 'hash', pattern: '#' },
semicolon: { type: 'semicolon', pattern: ';' }
},
// Database
sql: {
name: 'SQL',
single: { type: 'single', pattern: '--' },
block: { type: 'block', pattern: '/* */' }
},
// Functional languages
lua: {
name: 'Lua',
single: { type: 'single', pattern: '--' },
block: { type: 'block', pattern: '--[[ ]]' }
},
hs: {
name: 'Haskell',
single: { type: 'single', pattern: '--' },
block: { type: 'block', pattern: '{- -}' }
},
lhs: {
name: 'Haskell',
single: { type: 'single', pattern: '--' },
block: { type: 'block', pattern: '{- -}' }
},
// JSON (with comments)
json: {
name: 'JSON',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
},
jsonc: {
name: 'JSON with Comments',
single: { type: 'single', pattern: '//' },
block: { type: 'block', pattern: '/* */' }
}
};
function loadCustomLanguages() {
try {
const configPath = path.join(__dirname, '../config/languages.json');
if (fs.existsSync(configPath)) {
const customConfig = JSON.parse(fs.readFileSync(configPath, 'utf8'));
return customConfig;
}
} catch (error) {
console.warn('Warning: Could not load custom language config:', error.message);
}
return {};
}
function detectSpecialFiles(filename) {
const lowerName = filename.toLowerCase();
if (lowerName === 'dockerfile' || lowerName.startsWith('dockerfile.')) {
return 'dockerfile';
}
if (lowerName === 'makefile' || lowerName.startsWith('makefile.')) {
return 'makefile';
}
if (lowerName === 'cmakelists.txt') {
return 'cmake';
}
return null;
}
// Merge built-in and custom configurations
const customLanguages = loadCustomLanguages();
const allLanguageConfigs = { ...builtinLanguageConfigs, ...customLanguages };
function getLanguageConfig(fileExtension) {
const ext = fileExtension.toLowerCase();
return allLanguageConfigs[ext] || null;
}
function getLanguageConfigByFilename(filename) {
// First try special file detection
const specialType = detectSpecialFiles(filename);
if (specialType) {
return allLanguageConfigs[specialType];
}
// Then try by extension
const ext = path.extname(filename).slice(1).toLowerCase();
return getLanguageConfig(ext);
}
function getSupportedExtensions() {
return Object.keys(allLanguageConfigs);
}
function isExtensionSupported(fileExtension) {
return allLanguageConfigs.hasOwnProperty(fileExtension.toLowerCase());
}
function getAllLanguages() {
return allLanguageConfigs;
}
module.exports = {
getLanguageConfig,
getLanguageConfigByFilename,
getSupportedExtensions,
isExtensionSupported,
getAllLanguages
};