Created
February 11, 2025 03:26
-
-
Save llbbl/70aa59c78f80652ec1ea2fe99459f966 to your computer and use it in GitHub Desktop.
fix markdown file names for astro
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import fs from 'fs/promises'; | |
import path from 'path'; | |
import { fileURLToPath } from 'url'; | |
const __filename = fileURLToPath(import.meta.url); | |
const __dirname = path.dirname(__filename); | |
interface ProcessResult { | |
success: boolean; | |
error?: Error; | |
changes: { | |
type: 'file' | 'directory'; | |
from: string; | |
to: string; | |
}[]; | |
} | |
// Function to convert string to kebab case | |
function toKebabCase(str: string): string { | |
return str | |
.toLowerCase() | |
// Replace special characters with spaces | |
.replace(/[?!()[\]<>:'"]/g, '') | |
// Replace multiple spaces with single space | |
.replace(/\s+/g, ' ') | |
// Trim spaces from ends | |
.trim() | |
// Replace spaces with hyphens | |
.replace(/\s/g, '-') | |
// Remove any non-alphanumeric characters (except hyphens) | |
.replace(/[^a-z0-9-]/g, ''); | |
} | |
// Function to process a single file | |
async function processFile(filePath: string): Promise<ProcessResult> { | |
const changes: ProcessResult['changes'] = []; | |
try { | |
const stats = await fs.stat(filePath); | |
if (stats.isDirectory()) { | |
// Handle directory | |
const items = await fs.readdir(filePath); | |
const newDirName = toKebabCase(path.basename(filePath)); | |
const parentDir = path.dirname(filePath); | |
const newDirPath = path.join(parentDir, newDirName); | |
// Rename directory if needed | |
if (newDirName !== path.basename(filePath)) { | |
await fs.rename(filePath, newDirPath); | |
console.log(`Renamed directory: ${path.basename(filePath)} → ${newDirName}`); | |
changes.push({ | |
type: 'directory', | |
from: path.basename(filePath), | |
to: newDirName | |
}); | |
} | |
// Process all items in directory | |
for (const item of items) { | |
const result = await processFile(path.join(newDirPath, item)); | |
changes.push(...result.changes); | |
} | |
} else if (path.extname(filePath) === '.md') { | |
// Handle markdown file | |
const originalName = path.basename(filePath, '.md'); | |
const newName = toKebabCase(originalName) + '.md'; | |
const dirPath = path.dirname(filePath); | |
const newPath = path.join(dirPath, newName); | |
if (newName !== path.basename(filePath)) { | |
// Read original content | |
const content = await fs.readFile(filePath, 'utf8'); | |
// Prepend the original file name as an H1 header. | |
// If front matter exists (starting with '---'), insert it after the front matter. | |
let newContent; | |
if (content.startsWith('---')) { | |
const frontMatterMatch = content.match(/^(---\s*\n[\s\S]*?\n---\s*\n)/); | |
if (frontMatterMatch) { | |
const frontMatter = frontMatterMatch[1]; | |
const restContent = content.slice(frontMatter.length); | |
newContent = `${frontMatter}# ${originalName}\n\n${restContent}`; | |
} else { | |
newContent = `# ${originalName}\n\n${content}`; | |
} | |
} else { | |
newContent = `# ${originalName}\n\n${content}`; | |
} | |
// Write new content to renamed file | |
await fs.writeFile(newPath, newContent, 'utf8'); | |
// Remove old file now that we've created the new one | |
await fs.unlink(filePath); | |
console.log(`Renamed file: ${path.basename(filePath)} → ${newName}`); | |
changes.push({ | |
type: 'file', | |
from: path.basename(filePath), | |
to: newName | |
}); | |
} | |
} | |
return { success: true, changes }; | |
} catch (error) { | |
console.error(`Error processing ${filePath}:`, error); | |
return { | |
success: false, | |
error: error instanceof Error ? error : new Error(String(error)), | |
changes | |
}; | |
} | |
} | |
// Main function | |
async function main(): Promise<void> { | |
const pagesDir = path.join(__dirname, '..', 'src', 'pages'); | |
try { | |
const result = await processFile(pagesDir); | |
console.log('File processing complete!'); | |
if (result.changes.length > 0) { | |
console.log('\nChanges made:'); | |
result.changes.forEach(change => { | |
console.log(`${change.type}: ${change.from} → ${change.to}`); | |
}); | |
} else { | |
console.log('No changes were necessary.'); | |
} | |
} catch (error) { | |
console.error('Error:', error); | |
process.exit(1); | |
} | |
} | |
main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment