UNPKG

periodic-table-cli

Version:

An interactive Periodic Table of Elements app for the console!

208 lines (191 loc) 8.53 kB
#!/usr/bin/env node const { App } = require('./app.js'); const { DataProcessor } = require('./dataprocessor.js'); const { ChartProcessor } = require('./chartprocessor.js'); const { version } = require('../package.json'); const MODES = { APP: 'APP', DATA: 'DATA', CHART: 'CHART', }; const printUsage = function() { console.log('\n' + ' ╔═╗ ╔═╗ \n' + ' ╠═╬═╗ ╔═╦═╦═╦═╦═╬═╣ \n' + ' ╠═╬═╣ ╠═╬═╬═╬═╬═╬═╣ \n' + ' ╠═╬═╬═╦═╦═╦═╦═╦═╦═╦═╦═╦═╬═╬═╬═╬═╬═╬═╣ \n' + ' ╠═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╣ \n' + ' ╠═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╣ \n' + ' ╠═╬═╣:╠═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╣ \n' + ' ╚═╩═╝ ╚═╩═╩═╩═╩═╩═╩═╩═╩═╩═╩═╩═╩═╩═╩═╝ \n' + ' ╔═╦═╦═╦═╦═╦═╦═╦═╦═╦═╦═╦═╦═╦═╦═╗ \n' + ' :╠═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╬═╣ \n' + ' ╚═╩═╩═╩═╩═╩═╩═╩═╩═╩═╩═╩═╩═╩═╩═╝ \n' + '\n' + ' An interactive Periodic Table of Elements app for the console!\n' + '\n' + ' Interactive Controls:\n' + ' - Navigation: Use <UP>|<DOWN>|<LEFT>|<RIGHT> arrows\n' + '\n' + ' - Display Mode: Use SLASH </> to toggle the display mode forwards\n' + ' Use BACKSLASH <\\> to toggle the display mode in reverse\n' + '\n' + ' - Search: Query with letters or numbers\n' + ' Use <UP>|<DOWN> arrows to navigate results\n' + ' Press <ENTER> to select\n' + ' Press <LEFT> to exit search\n' + '\n' + ' - Quit: Press <ESC> or <CTRL+C>\n' + '\n' + ' Usage:\n' + ' $ periodic-table-cli\n' + ' $ periodic-table-cli [options]\n' + '\n' + ' Options:\n' + ' --mode=<mode> Set the mode for the application. Supports three values:\n' + ' - app: Run in interactive mode (default)\n' + ' - data: Display data for a specified element\n' + ' - chart: Prints a non-interactive table only\n' + ' --atomic-number=<int> Initialize the Periodic Table at the specified atomic number (1-118)\n' + ' --symbol=<symbol> Initialize the Periodic Table at the specified element symbol\n' + ' --name=<name> Initialize the Periodic Table at the specified element name\n' + ' --small, -s Print a smaller Periodic Table of Elements (include --mode=chart)\n' + ' --verbose, -v Print a complete data chart with all elements (include --mode=data)\n' + '\n' + ' Full Docs: https://spirometaxas.com/projects/periodic-table-cli\n\n' + ' Last updated August 2025\n' + ' ' + getVersion() + '\n'); } const getFlags = function(params) { let flags = []; if (params) { for (let i = 0; i < params.length; i++) { if (params[i].startsWith('-')) { flags.push(params[i]); } } } return flags; } const isSmall = function(flags) { for (let i = 0; i < flags.length; i++) { if (flags[i] && (flags[i].toLowerCase() === '-s' || flags[i].toLowerCase() === '--small')) { return true; } } return false; } const isHelp = function(flags) { for (let i = 0; i < flags.length; i++) { if (flags[i] && (flags[i].toLowerCase() === '--help' || flags[i].toLowerCase() === '-h')) { return true; } } return false; } const isVerbose = function(flags, mode) { if (mode !== MODES.DATA) { return false; } for (let i = 0; i < flags.length; i++) { if (flags[i] && (flags[i].toLowerCase() === '--verbose' || flags[i].toLowerCase() === '-v')) { return true; } } return false; } const isVersion = function(flags, mode) { if (mode !== MODES.APP) { return false; } for (let i = 0; i < flags.length; i++) { if (flags[i] && (flags[i].toLowerCase() === '--version' || flags[i].toLowerCase() === '-v')) { return true; } } return false; } const getMode = function(flags) { const prefix = '--mode='; for (let i = 0; i < flags.length; i++) { if (flags[i] && flags[i].toLowerCase().startsWith(prefix)) { const modeString = flags[i].substring(prefix.length); if (modeString !== undefined && MODES[modeString.toUpperCase()] !== undefined) { return MODES[modeString.toUpperCase()]; } } } return MODES.APP; // Default to APP } const getAtomicNumber = function(flags) { const prefix = '--atomic-number='; for (let i = 0; i < flags.length; i++) { if (flags[i] && flags[i].toLowerCase().startsWith(prefix)) { const atomicNumberString = flags[i].substring(prefix.length); if (atomicNumberString !== undefined && !isNaN(atomicNumberString)) { return parseInt(atomicNumberString); } } } return undefined; } const getName = function(flags) { const prefix = '--name='; for (let i = 0; i < flags.length; i++) { if (flags[i] && flags[i].toLowerCase().startsWith(prefix)) { const nameString = flags[i].substring(prefix.length); if (nameString !== undefined) { return nameString; } } } return undefined; } const getSymbol = function(flags) { const prefix = '--symbol='; for (let i = 0; i < flags.length; i++) { if (flags[i] && flags[i].toLowerCase().startsWith(prefix)) { const symbolString = flags[i].substring(prefix.length); if (symbolString !== undefined) { return symbolString; } } } return undefined; } const getVersion = function() { return 'v' + version + ' (NodeJS)'; } var mode = MODES.APP; var atomicNumber = undefined; var name = undefined; var symbol = undefined; var small = false; var verbose = false; if (process.argv.length > 2) { const params = process.argv.slice(2); mode = getMode(params); atomicNumber = getAtomicNumber(params); name = getName(params); symbol = getSymbol(params); small = isSmall(params); verbose = isVerbose(params, mode); if (isHelp(params)) { printUsage(); process.exit(); } else if (isVersion(params, mode)) { console.log('\n ' + getVersion() + '\n'); process.exit(); } else if (mode === MODES.DATA) { console.log(DataProcessor.formatData({ atomicNumber: atomicNumber, symbol: symbol, name: name, verbose: verbose })); process.exit(); } else if (mode === MODES.CHART) { console.log(ChartProcessor.formatChart({ atomicNumber: atomicNumber, symbol: symbol, name: name, small: small })); process.exit(); } } if (!process.stdout.isTTY) { console.log(' Error: Interactive mode is only supported within a terminal screen.'); process.exit(); } new App().start({ atomicNumber: atomicNumber, name: name, symbol: symbol });