141 lines
3.4 KiB
JavaScript
141 lines
3.4 KiB
JavaScript
import fs from "fs";
|
|
import path from "path";
|
|
import matter from "gray-matter";
|
|
import yaml from "js-yaml";
|
|
|
|
// Configuration
|
|
const inputDir = "./src/content/post/"; // Folder containing markdown files
|
|
const backupDir = "./backup"; // Backup before modifying
|
|
|
|
// Create backup directory if it doesn't exist
|
|
if (!fs.existsSync(backupDir)) {
|
|
fs.mkdirSync(backupDir);
|
|
}
|
|
|
|
// Preferred frontmatter key order
|
|
const preferredKeyOrder = [
|
|
"title",
|
|
"description",
|
|
"publishDate",
|
|
"updatedDate",
|
|
"tags",
|
|
"slug",
|
|
"draft",
|
|
];
|
|
|
|
function sortFrontmatterKeys(data) {
|
|
const sorted = {};
|
|
preferredKeyOrder.forEach((key) => {
|
|
if (data[key] !== undefined) {
|
|
sorted[key] = data[key];
|
|
}
|
|
});
|
|
Object.keys(data).forEach((key) => {
|
|
if (!sorted.hasOwnProperty(key)) {
|
|
sorted[key] = data[key];
|
|
}
|
|
});
|
|
return sorted;
|
|
}
|
|
|
|
// Format dates consistently
|
|
function formatDate(value) {
|
|
if (value instanceof Date) {
|
|
return value.toISOString().split("T")[0];
|
|
}
|
|
return value;
|
|
}
|
|
|
|
// Extract date from filename if present
|
|
function extractDateFromFilename(filename) {
|
|
const match = filename.match(/^(\d{4}-\d{2}-\d{2})-(.+)$/);
|
|
if (match) {
|
|
return {
|
|
date: match[1],
|
|
newFilename: match[2],
|
|
};
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Clean and fix a single file
|
|
function fixFile(filePath) {
|
|
const rawContent = fs.readFileSync(filePath, "utf8");
|
|
const { data: frontmatter, content } = matter(rawContent);
|
|
|
|
let cleanedFrontmatter = { ...frontmatter };
|
|
const fileName = path.basename(filePath);
|
|
const dateInfo = extractDateFromFilename(fileName);
|
|
|
|
// Move date from filename into publishDate if missing
|
|
if (dateInfo) {
|
|
if (!cleanedFrontmatter.publishDate) {
|
|
cleanedFrontmatter.publishDate = dateInfo.date;
|
|
}
|
|
}
|
|
|
|
// Rename "date" -> "publishDate" if necessary
|
|
if (cleanedFrontmatter.date && !cleanedFrontmatter.publishDate) {
|
|
cleanedFrontmatter.publishDate = cleanedFrontmatter.date;
|
|
delete cleanedFrontmatter.date;
|
|
}
|
|
|
|
// Fix date formats
|
|
Object.keys(cleanedFrontmatter).forEach((key) => {
|
|
if (key.toLowerCase().includes("date")) {
|
|
cleanedFrontmatter[key] = formatDate(cleanedFrontmatter[key]);
|
|
}
|
|
});
|
|
|
|
// If publishDate missing, set draft: true
|
|
if (
|
|
!cleanedFrontmatter.publishDate && cleanedFrontmatter.draft === undefined
|
|
) {
|
|
cleanedFrontmatter.draft = true;
|
|
}
|
|
|
|
// Sort frontmatter keys
|
|
cleanedFrontmatter = sortFrontmatterKeys(cleanedFrontmatter);
|
|
|
|
const yamlContent = yaml.dump(cleanedFrontmatter, {
|
|
lineWidth: 1000,
|
|
quotingType: '"',
|
|
});
|
|
|
|
const finalContent = `---\n${yamlContent}---\n\n${content.trim()}\n`;
|
|
|
|
// Backup original
|
|
const backupPath = path.join(backupDir, fileName);
|
|
fs.copyFileSync(filePath, backupPath);
|
|
|
|
// Determine new filename
|
|
let outputPath = filePath;
|
|
if (dateInfo) {
|
|
const newFilename = dateInfo.newFilename;
|
|
outputPath = path.join(path.dirname(filePath), newFilename);
|
|
}
|
|
|
|
// Write cleaned file (possibly with new filename)
|
|
fs.writeFileSync(outputPath, finalContent, "utf8");
|
|
|
|
// If filename changed, delete the old file
|
|
if (outputPath !== filePath) {
|
|
fs.unlinkSync(filePath);
|
|
console.log(`Fixed & Renamed: ${fileName} -> ${path.basename(outputPath)}`);
|
|
} else {
|
|
console.log(`Fixed: ${fileName}`);
|
|
}
|
|
}
|
|
|
|
// Process all markdown files
|
|
function fixAllFiles() {
|
|
const files = fs.readdirSync(inputDir);
|
|
files.forEach((file) => {
|
|
if (file.endsWith(".md")) {
|
|
fixFile(path.join(inputDir, file));
|
|
}
|
|
});
|
|
}
|
|
|
|
fixAllFiles();
|