Initial commit
This commit is contained in:
54
skills/figlet-text-converter/scripts/list-fonts.js
Normal file
54
skills/figlet-text-converter/scripts/list-fonts.js
Normal file
@@ -0,0 +1,54 @@
|
||||
import { execSync } from 'child_process';
|
||||
|
||||
// Get available fonts via npx figlet
|
||||
function getAvailableFonts() {
|
||||
try {
|
||||
const output = execSync('npx figlet --list', { encoding: 'utf-8' });
|
||||
// Skip the "Available fonts:" header and filter out empty lines
|
||||
return output.trim().split('\n').slice(1).map(line => line.trim()).filter(line => line);
|
||||
} catch (error) {
|
||||
console.error('Error retrieving fonts:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate ASCII art via npx figlet
|
||||
function generateAsciiArt(text, font) {
|
||||
try {
|
||||
const output = execSync(`npx figlet -f "${font}" "${text}"`, { encoding: 'utf-8' });
|
||||
return output;
|
||||
} catch (error) {
|
||||
return '(Preview not available)';
|
||||
}
|
||||
}
|
||||
|
||||
// Main function
|
||||
function main() {
|
||||
const fonts = getAvailableFonts();
|
||||
|
||||
console.log(`\n📋 Available Figlet Fonts (${fonts.length} total):\n`);
|
||||
console.log('='.repeat(60));
|
||||
|
||||
// Show first 10 fonts with examples
|
||||
const previewCount = Math.min(10, fonts.length);
|
||||
|
||||
for (let i = 0; i < previewCount; i++) {
|
||||
const font = fonts[i];
|
||||
console.log(`\n🔤 ${font}`);
|
||||
console.log('-'.repeat(40));
|
||||
const preview = generateAsciiArt('Sample', font);
|
||||
console.log(preview);
|
||||
}
|
||||
|
||||
console.log('\n' + '='.repeat(60));
|
||||
console.log(`\n📝 All Available Fonts (${fonts.length} total):\n`);
|
||||
|
||||
fonts.forEach((font, index) => {
|
||||
console.log(` ${(index + 1).toString().padStart(3)}. ${font}`);
|
||||
});
|
||||
|
||||
console.log('\n💡 Tip: Use font="font-name" in figlet tags');
|
||||
console.log(' Default font: "standard"\n');
|
||||
}
|
||||
|
||||
main();
|
||||
192
skills/figlet-text-converter/scripts/process-file.js
Normal file
192
skills/figlet-text-converter/scripts/process-file.js
Normal file
@@ -0,0 +1,192 @@
|
||||
import { execSync } from 'child_process';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
// Get available fonts via npx figlet
|
||||
function getAvailableFonts() {
|
||||
try {
|
||||
const output = execSync('npx figlet --list', { encoding: 'utf-8' });
|
||||
// Skip the "Available fonts:" header and filter out empty lines
|
||||
return output.trim().split('\n').slice(1).map(line => line.trim()).filter(line => line);
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to fetch available fonts: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate ASCII art via npx figlet
|
||||
function generateAsciiArt(text, font) {
|
||||
try {
|
||||
// If no font specified, let figlet use its default (standard)
|
||||
const fontFlag = font ? `-f "${font}"` : '';
|
||||
const output = execSync(`npx figlet ${fontFlag} "${text}"`, { encoding: 'utf-8' });
|
||||
return output;
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to generate ASCII art: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Parse command line arguments
|
||||
function parseArguments() {
|
||||
const args = process.argv.slice(2);
|
||||
if (args.length === 0) {
|
||||
console.error('Usage: node process-file.js <file-path>');
|
||||
console.error('');
|
||||
console.error('This script processes <figlet> tags in files and replaces them with ASCII art.');
|
||||
console.error('');
|
||||
console.error('Syntax: <figlet font="font-name">Text to convert</figlet>');
|
||||
console.error(' <figlet>Text to convert</figlet> (uses standard font by default)');
|
||||
process.exit(1);
|
||||
}
|
||||
return args[0];
|
||||
}
|
||||
|
||||
// Detect comment style from the line
|
||||
function detectCommentStyle(line) {
|
||||
const trimmed = line.trimStart();
|
||||
|
||||
if (trimmed.startsWith('//')) {
|
||||
return '//';
|
||||
} else if (trimmed.startsWith('#')) {
|
||||
return '#';
|
||||
} else if (trimmed.startsWith('--')) {
|
||||
return '--';
|
||||
} else if (trimmed.startsWith('/*')) {
|
||||
return '/*';
|
||||
}
|
||||
|
||||
return null; // plain text, no comment style
|
||||
}
|
||||
|
||||
// Format ASCII art with comment prefixes
|
||||
function formatWithComments(asciiArt, commentStyle) {
|
||||
// Remove trailing empty lines
|
||||
const lines = asciiArt.split('\n').filter((line, index, arr) => {
|
||||
// Keep the line if it's not empty, or if it's not the last line
|
||||
return line.trim().length > 0 || index < arr.length - 1;
|
||||
});
|
||||
|
||||
if (!commentStyle) {
|
||||
return asciiArt.trimEnd();
|
||||
}
|
||||
|
||||
switch (commentStyle) {
|
||||
case '//':
|
||||
return lines.map(line => `// ${line}`).join('\n');
|
||||
|
||||
case '#':
|
||||
return lines.map(line => `# ${line}`).join('\n');
|
||||
|
||||
case '--':
|
||||
return lines.map(line => `-- ${line}`).join('\n');
|
||||
|
||||
case '/*':
|
||||
// For block comments, each line gets " * " prefix
|
||||
return lines.map(line => ` * ${line}`).join('\n');
|
||||
|
||||
default:
|
||||
return asciiArt.trimEnd();
|
||||
}
|
||||
}
|
||||
|
||||
// Main function
|
||||
function main() {
|
||||
const filePath = parseArguments();
|
||||
|
||||
// Verify file exists
|
||||
if (!fs.existsSync(filePath)) {
|
||||
console.error(`❌ Error: File not found: ${filePath}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Read file content
|
||||
let content = fs.readFileSync(filePath, 'utf-8');
|
||||
|
||||
// Get available fonts for validation
|
||||
let availableFonts;
|
||||
try {
|
||||
availableFonts = getAvailableFonts();
|
||||
} catch (err) {
|
||||
console.error(`❌ Error fetching available fonts: ${err.message}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Find all figlet tags: <figlet font="...">text</figlet> or <figlet>text</figlet>
|
||||
const tagRegex = /<figlet(?:\s+font="([^"]+)")?>(.+?)<\/figlet>/g;
|
||||
let match;
|
||||
const replacements = [];
|
||||
|
||||
// Add 'standard' to available fonts since figlet always accepts it as the default
|
||||
const validFonts = new Set([...availableFonts, 'standard']);
|
||||
|
||||
while ((match = tagRegex.exec(content)) !== null) {
|
||||
const fullTag = match[0];
|
||||
const fontName = match[1] || null; // null means use figlet's default
|
||||
const textToConvert = match[2];
|
||||
const tagIndex = match.index;
|
||||
|
||||
// Validate font if specified
|
||||
if (fontName && !validFonts.has(fontName)) {
|
||||
console.error(`❌ Error: Invalid font "${fontName}" in tag: ${fullTag}`);
|
||||
console.error(` Run 'node list-fonts.js' to see available fonts.`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Detect comment style from the line containing the tag
|
||||
const lineStart = content.lastIndexOf('\n', tagIndex) + 1;
|
||||
const lineEnd = content.indexOf('\n', tagIndex);
|
||||
const endPos = lineEnd === -1 ? content.length : lineEnd;
|
||||
const line = content.substring(lineStart, endPos);
|
||||
const commentStyle = detectCommentStyle(line);
|
||||
|
||||
replacements.push({
|
||||
tag: fullTag,
|
||||
font: fontName,
|
||||
text: textToConvert,
|
||||
commentStyle
|
||||
});
|
||||
}
|
||||
|
||||
// If no tags found, inform user
|
||||
if (replacements.length === 0) {
|
||||
console.log(`ℹ️ No figlet tags found in: ${filePath}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Process each replacement
|
||||
for (const replacement of replacements) {
|
||||
try {
|
||||
const asciiArt = generateAsciiArt(replacement.text, replacement.font);
|
||||
const formatted = formatWithComments(asciiArt, replacement.commentStyle);
|
||||
|
||||
// If there's a comment style and the tag is preceded by that comment on the same line,
|
||||
// we need to replace the comment prefix + tag together (not just the tag).
|
||||
// This prevents double comment prefixes (e.g., "# #" instead of "#")
|
||||
if (replacement.commentStyle) {
|
||||
const escapedComment = replacement.commentStyle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
const escapedTag = replacement.tag.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
// Match optional leading whitespace, the comment prefix, optional space, then the tag
|
||||
const commentPrefixPattern = new RegExp(`(^|\\n)\\s*${escapedComment}\\s*${escapedTag}`);
|
||||
if (commentPrefixPattern.test(content)) {
|
||||
// Replace both the comment prefix and tag with the formatted ASCII art
|
||||
content = content.replace(commentPrefixPattern, `$1${formatted}`);
|
||||
} else {
|
||||
// No leading comment prefix, just replace the tag
|
||||
content = content.replace(replacement.tag, formatted);
|
||||
}
|
||||
} else {
|
||||
// No comment style, just replace the tag
|
||||
content = content.replace(replacement.tag, formatted);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`❌ Error generating ASCII art for "${replacement.text}": ${err.message}`);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Write modified content back to file
|
||||
fs.writeFileSync(filePath, content, 'utf-8');
|
||||
|
||||
console.log(`✅ Successfully processed ${replacements.length} figlet tag(s) in: ${filePath}`);
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in New Issue
Block a user