Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:50:16 +08:00
commit 60cd68dbbc
8 changed files with 876 additions and 0 deletions

View File

@@ -0,0 +1,216 @@
---
name: figlet-text-converter
description: This skill processes files containing figlet tags and replaces them with ASCII art representations. It detects and preserves comment styles (forward slash forward slash, hash, double-dash, forward slash asterisk), automatically manages Node.js dependencies, and supports 400+ fonts (defaulting to the standard font). The skill should be used when a user requests converting marked text in a file to ASCII art using figlet tag syntax, or when they want to list available fonts.
---
# Figlet Text Converter
## Overview
This skill converts marked text in files to ASCII art using the figlet library. It uses a simple, universal tag syntax that works across all file types and intelligently preserves comment formatting when tags are placed in commented sections. The skill handles dependency management automatically and supports 400+ fonts with sensible defaults.
## When to Use This Skill
Use this skill when:
- User asks to convert text in a file to ASCII art
- User provides a file containing `<figlet>` tags
- User requests to list available figlet fonts
- User wants to add visual ASCII art headers or banners to code, documentation, or configuration files
## Tag Syntax
### Universal Markup
Insert `<figlet>` tags anywhere in a file to mark text for ASCII art conversion:
**With font specification:**
```
<figlet font="3-D">Text to Convert</figlet>
```
**Using default font (standard):**
```
<figlet>Text to Convert</figlet>
```
### Usage in Different Contexts
#### Markdown Documents
```markdown
# Section Title
<figlet font="Standard">Important Notice</figlet>
Content goes here...
```
#### Shell Scripts
```bash
#!/bin/bash
echo '<figlet>Deployment Started</figlet>'
# Script logic...
```
#### Python Code
```python
# <figlet>Configuration</figlet>
config = {
'setting': 'value'
}
```
#### PHP/JavaScript
```php
// <figlet font="Block">Database Connection</figlet>
function connectDB() {
// ...
}
```
#### Plain Text/Config Files
```
<figlet>System Status Report</figlet>
This report contains...
```
## Workflow
### Processing a File
When a user requests ASCII art conversion:
1. Read the file containing `<figlet>` tags
2. Validate all font names (error immediately if invalid)
3. For each tag:
- Extract the font name (or use 'standard' if omitted)
- Generate ASCII art for the text
- Detect comment style from the surrounding line (// # -- /*)
- Format output with appropriate comment prefixes
4. Replace tags with formatted ASCII art
5. Write changes back to the file
### Handling Comments
The skill automatically detects comment context:
**Single-line comments:**
```bash
// <figlet>Section Break</figlet>
```
Outputs each line with `// ` prefix:
```bash
// ___ _ _ ____ _
// / __| ___ | | | | ___ _ _ | __ ) _ _ __| | |
// \__ \/ -_) | |_| |/ _ \| ' \ | _ \| '_|/ _` | |
// |___/\___| \___/ \___/|_|_|_| |_| \_\_| \__,_|_|
```
**Hash comments (Python, Shell):**
```python
# <figlet>Configuration</figlet>
```
Outputs with `# ` prefix.
**SQL/SQL comments:**
```sql
-- <figlet>Query Section</figlet>
```
Outputs with `-- ` prefix.
**Block comments:**
```java
/* <figlet>Module Start</figlet>
```
Outputs with ` * ` prefix:
```java
* ___ _ _ _ ___ _ _
* | \/ | ___ __| | _ | | ___ / __| | |_ __ _ _ | |_
* | |\/| |/ _ \ / _` ||_|| |/ -_) \__ \ | _|/ _` || || _|
* |_| |_|\___/ \__,_| \__/ \___| |___/ |_| \__,_|\__|\__|
```
**Plain text (no comment prefix):**
```
<figlet>Plain ASCII Art</figlet>
```
Outputs raw ASCII art without formatting.
## Font Selection
### Default Font
If no font is specified, 'standard' is used:
```
<figlet>Default Font Example</figlet>
```
### Custom Fonts
Specify any of 400+ available fonts:
```
<figlet font="Block">Bold Text</figlet>
<figlet font="3-D">3D Effect</figlet>
<figlet font="Shadow">Shadowed</figlet>
```
### Finding Fonts
When user requests to list available fonts, run the font discovery script to show:
- Previews of the first 10 fonts with examples
- Complete alphabetical listing of all 400+ fonts
- Font names for use in tags
Popular fonts:
- standard (default)
- 3-D
- Block
- Big
- Shadow
- Slant
- Graffiti
- Doom
## Error Handling
The skill validates fonts before processing:
- **Invalid font specified**: Error immediately with font name and suggestion to list available fonts
- **File not found**: Error with file path
- **Node.js/npm issues**: Error with installation instructions
## Bundled Resources
### scripts/
**process-file.js**
- Main processing script that reads files, finds all `<figlet>` tags, validates fonts, generates ASCII art, detects comment styles, and writes results
- Handles automatic Node.js verification and npm dependency installation on first run
- Usage: `node process-file.js <file-path>`
**list-fonts.js**
- Displays all available figlet fonts with previews and complete listing
- Helps users find the exact font names to use in tags
- Usage: `node list-fonts.js`
**package.json**
- Node.js project file with figlet v1.7.0+ dependency
**.gitignore**
- Excludes node_modules from version control
### references/
**usage-guide.md** - Comprehensive reference documentation for all features and edge cases
## Technical Details
- **Node.js Requirement**: v14 or higher
- **Figlet Package**: v1.7.0 or higher (auto-installed on first use)
- **Tag Format**: `<figlet font="font-name">text</figlet>` or `<figlet>text</figlet>`
- **Comment Styles Supported**: //, #, --, /*, or none
- **Default Font**: standard
- **File Processing**: In-place modification

View File

@@ -0,0 +1,15 @@
{
"name": "figlet-text-converter",
"description": "Converts marked text in files to ASCII art using figlet tag syntax.",
"version": "1.0.1",
"author": {
"name": "Tim Green",
"email": "rawveg@gmail.com"
},
"homepage": "https://github.com/rawveg/claude-skills-marketplace",
"repository": "https://github.com/rawveg/claude-skills-marketplace",
"license": "MIT",
"keywords": ["figlet", "text", "converter", "Claude Code"],
"category": "productivity",
"strict": false
}

View File

@@ -0,0 +1,324 @@
# Figlet Text Converter - Usage Guide
## Overview
The Figlet Text Converter skill converts marked text in files to ASCII art. It uses a universal `<figlet>` tag syntax that works across all file types and intelligently preserves comment formatting.
## Getting Started
### Installation
The skill automatically manages Node.js dependencies on first use. When invoked:
1. Verifies Node.js v14+ is installed
2. Installs the figlet package via npm if needed
3. Processes your file
### Basic Usage
Insert `<figlet>` tags in any file to mark text for conversion:
```
<figlet>Text to Convert</figlet>
```
Then ask Claude to process the file:
```
"Convert all figlet tags in this markdown file to ASCII art"
```
## Tag Syntax
### Simple Tag (Uses Default Font)
```
<figlet>Welcome</figlet>
```
Uses 'standard' font (default).
### Tag with Custom Font
```
<figlet font="3-D">Welcome</figlet>
```
Uses the specified font. Font names are case-sensitive and must exactly match figlet's font list.
## Usage Examples
### Markdown Document
**Input:**
```markdown
# My Documentation
<figlet font="Standard">Getting Started</figlet>
Follow these steps...
<figlet>Important Note</figlet>
This is critical...
```
**Output:**
```markdown
# My Documentation
____ _ _ _ _____ _ _ _ _
/ ___| ___| |_| |_(_)_ __ __ _ / ____| | |_ __ _ _ _| |_| |___ __| |
| | _/ -_| _| _| | '_ \ / _` | / __| _ | __| / _` | | | | _| / _ \/ _` |
| |_| \__ \ _| _| | | | | (_| |/ /____| | |_| (_| | | | | | |_| __/ (_| |
\____|___/\__|\__|_|_| |_|\__, |\_______| \__|\_\__,_\_/_|_|\__|\___|\_\__,
|___/
Follow these steps...
___ _
|_ _|_ __ ___ _ __ ___| |_ __ _ _ _ | |_
| | '_ ` _ \| '_ \ / _ \| _| / _` || | | | _|
| | | | | | | |_) | __/ | |_| (_| || | | | | |
|___|_| |_| |_| .__/ \___|_|\__|\_\__|\__,_|_| |
|_|
This is critical...
```
### Python Script
**Input:**
```python
# <figlet>Configuration</figlet>
DEBUG = True
LOG_LEVEL = "INFO"
```
**Output:**
```python
# ____ ___ _
# / ___|__ _ _ / __| ___ _ _ ___ ___ _ _ __ _ __ __| | __
# | |__/ _ \ | | | / /__ / _ \ | | | / _ \ / _ \| | | / _` | \ \/ /| |/ /
# | __| | | || | | ___| | | || |_|| (_) || __/ (_| |( _ | > < | __\
# |_| |_| |_| \_\ \___|_| |_| \__,_|\___/ \___|\__,_| \_/ |_/_/\_\ |_|
DEBUG = True
LOG_LEVEL = "INFO"
```
### Shell Script
**Input:**
```bash
#!/bin/bash
echo '<figlet font="Block">Starting Deployment</figlet>'
# Deploy code...
```
**Output:**
```bash
#!/bin/bash
echo ' ___ _ _ _ _ ___ _ _
/ __|_| |_ __ _ | |_| | ___ _ | | __ _ / ___| |___ _ __ | |
\__ \_ _/ _` || __| |/ _ \| | |/ _` | / / | | _ \| '_ \ | |_
|___/ |_| \__,_| \__|_| \___/|_|_|\__, | \_\__| | |_) | |_) ||___|
|___/ |_.__/ | .__/|___|
|_|'
# Deploy code...
```
### PHP Code
**Input:**
```php
<?php
// <figlet>Database Connection</figlet>
$conn = new PDO($dsn);
```
**Output:**
```php
<?php
// ___ __ _ _ _ ___
// | \ / \| |_ __ _ | |__ __ _ ___ ___ / __|
// | | || ()| / _` || _ \ / _` | -_) -_) \__ \
// |__/ \_/\_|\__,_||_|_|_|\__,_|\___|___| |___/
//
// ____ ___ _ _ _ _ _ ___ __ _
// / ___| / _ \ | | | | | | | / _ \ / \| |_
// | ___| | | || | | | | | _ | | | || ()| / _|
// | \__| |_| | \_/ | |_|_||_| \__/ \_/|\__\
// \____|___/
$conn = new PDO($dsn);
```
### Configuration File
**Input:**
```ini
[database]
<figlet>Database Settings</figlet>
host=localhost
port=5432
```
**Output:**
```ini
[database]
___ __ _ _ ___ __ _ _ _
| \ / \| |_ __ _ | |__ __ _ ___ / __| |_ _| | | | | |_ __ __ _ ___
| | || ()| / _` || _ \ / _` | -_) \__ \| _| |_| |_| _| / _` | / _ \
|__/ \_/\_|\__,_||_|_|_|\__,_|\___| |___/ |_| \___/ |_| \__, | \___/
|___/
host=localhost
port=5432
```
## Comment Style Detection
The skill automatically detects and preserves comment styles:
| Language | Comment Style | Example |
|----------|---------------|---------|
| C/C++/Java/PHP/JavaScript | `//` | `// <figlet>Section</figlet>` |
| Python/Bash | `#` | `# <figlet>Section</figlet>` |
| SQL | `--` | `-- <figlet>Section</figlet>` |
| C/Java (Block) | `/*` | `/* <figlet>Section</figlet>` |
| Plain text | None | `<figlet>Section</figlet>` |
When a tag is on a line with a comment marker, output is formatted with that comment style:
```
// <figlet>Header</figlet>
```
Becomes:
```
// ___ _ _
// | | | |___ ___ __| |__ _ ___ __
// | |_| // -_)/ _ \/ _` / _` / -_) / _ \
// \___/ \___|\___/\__,_\__,_|\___| __/
// |_|
```
## Finding Fonts
To see all available fonts, ask Claude to list them:
```
"List all available figlet fonts"
```
This will show:
- Previews of popular fonts
- Complete alphabetical listing of 400+ available fonts
- Font names to use in tags
### Popular Fonts
- **standard** - Default, traditional figlet style
- **3-D** - 3D effect with shading
- **Block** - Large, blocky characters
- **Big** - Large and simple
- **Shadow** - Shadowed appearance
- **Slant** - Slanted characters
- **Graffiti** - Artistic style
- **Doom** - Heavy, bold style
- **Isometric1/2** - Isometric projection
## Troubleshooting
### Invalid Font Error
```
❌ Error: Invalid font "MyFont" in tag: <figlet font="MyFont">Text</figlet>
Run 'node list-fonts.js' to see available fonts.
```
**Solution:** Use a valid font name from the list. Font names are case-sensitive.
### File Not Found
```
❌ Error: File not found: /path/to/file.txt
```
**Solution:** Verify the file path is correct.
### Node.js Not Installed
```
❌ Dependencies not installed. Please run: npm install
```
**Solution:** Install Node.js v14+ from https://nodejs.org/
## Advanced Usage
### Multiple Tags in One File
You can use multiple figlet tags in a single file:
```markdown
<figlet font="Block">Section One</figlet>
Content here...
<figlet font="3-D">Section Two</figlet>
More content...
```
Each tag is processed independently with its own font and style.
### Mixing Comment Styles
Different parts of a file can have different comment styles:
```
// <figlet>JavaScript Section</figlet>
const x = 10;
# <figlet>Python Section</figlet>
x = 10
```
Each is formatted appropriately for its comment context.
### Large Text Conversion
ASCII art can be quite large. For long text strings:
```
<figlet font="Standard">A</figlet> <!-- Smaller -->
<figlet font="Big">A</figlet> <!-- Larger -->
```
Use shorter fonts for longer text to keep output manageable.
## Tips & Tricks
1. **Preview Before Converting**: Ask Claude to show you the ASCII art for your text before inserting it
2. **Consistent Styling**: Use the same font throughout a file for visual consistency
3. **Comment the Conversion**: Leave a comment explaining what the ASCII art represents
4. **Test Display**: Verify the output displays correctly in your target environment (editor, terminal, web)
5. **Reserve for Impact**: Use ASCII art sparingly for section headers, not inline text
## Limitations
- Font names must match figlet's font list exactly (case-sensitive)
- Each tag is processed independently; multi-line ASCII art expands proportionally
- Comment detection is line-based (tag must be on same line as comment marker)
- Very long text may produce large ASCII art output

View 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();

View 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();