11ty-to-astro.mjs
· 3.4 KiB · JavaScript
Eredeti
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();
1 | import fs from "fs"; |
2 | import path from "path"; |
3 | import matter from "gray-matter"; |
4 | import yaml from "js-yaml"; |
5 | |
6 | // Configuration |
7 | const inputDir = "./src/content/post/"; // Folder containing markdown files |
8 | const backupDir = "./backup"; // Backup before modifying |
9 | |
10 | // Create backup directory if it doesn't exist |
11 | if (!fs.existsSync(backupDir)) { |
12 | fs.mkdirSync(backupDir); |
13 | } |
14 | |
15 | // Preferred frontmatter key order |
16 | const preferredKeyOrder = [ |
17 | "title", |
18 | "description", |
19 | "publishDate", |
20 | "updatedDate", |
21 | "tags", |
22 | "slug", |
23 | "draft", |
24 | ]; |
25 | |
26 | function sortFrontmatterKeys(data) { |
27 | const sorted = {}; |
28 | preferredKeyOrder.forEach((key) => { |
29 | if (data[key] !== undefined) { |
30 | sorted[key] = data[key]; |
31 | } |
32 | }); |
33 | Object.keys(data).forEach((key) => { |
34 | if (!sorted.hasOwnProperty(key)) { |
35 | sorted[key] = data[key]; |
36 | } |
37 | }); |
38 | return sorted; |
39 | } |
40 | |
41 | // Format dates consistently |
42 | function formatDate(value) { |
43 | if (value instanceof Date) { |
44 | return value.toISOString().split("T")[0]; |
45 | } |
46 | return value; |
47 | } |
48 | |
49 | // Extract date from filename if present |
50 | function extractDateFromFilename(filename) { |
51 | const match = filename.match(/^(\d{4}-\d{2}-\d{2})-(.+)$/); |
52 | if (match) { |
53 | return { |
54 | date: match[1], |
55 | newFilename: match[2], |
56 | }; |
57 | } |
58 | return null; |
59 | } |
60 | |
61 | // Clean and fix a single file |
62 | function fixFile(filePath) { |
63 | const rawContent = fs.readFileSync(filePath, "utf8"); |
64 | const { data: frontmatter, content } = matter(rawContent); |
65 | |
66 | let cleanedFrontmatter = { ...frontmatter }; |
67 | const fileName = path.basename(filePath); |
68 | const dateInfo = extractDateFromFilename(fileName); |
69 | |
70 | // Move date from filename into publishDate if missing |
71 | if (dateInfo) { |
72 | if (!cleanedFrontmatter.publishDate) { |
73 | cleanedFrontmatter.publishDate = dateInfo.date; |
74 | } |
75 | } |
76 | |
77 | // Rename "date" -> "publishDate" if necessary |
78 | if (cleanedFrontmatter.date && !cleanedFrontmatter.publishDate) { |
79 | cleanedFrontmatter.publishDate = cleanedFrontmatter.date; |
80 | delete cleanedFrontmatter.date; |
81 | } |
82 | |
83 | // Fix date formats |
84 | Object.keys(cleanedFrontmatter).forEach((key) => { |
85 | if (key.toLowerCase().includes("date")) { |
86 | cleanedFrontmatter[key] = formatDate(cleanedFrontmatter[key]); |
87 | } |
88 | }); |
89 | |
90 | // If publishDate missing, set draft: true |
91 | if ( |
92 | !cleanedFrontmatter.publishDate && cleanedFrontmatter.draft === undefined |
93 | ) { |
94 | cleanedFrontmatter.draft = true; |
95 | } |
96 | |
97 | // Sort frontmatter keys |
98 | cleanedFrontmatter = sortFrontmatterKeys(cleanedFrontmatter); |
99 | |
100 | const yamlContent = yaml.dump(cleanedFrontmatter, { |
101 | lineWidth: 1000, |
102 | quotingType: '"', |
103 | }); |
104 | |
105 | const finalContent = `---\n${yamlContent}---\n\n${content.trim()}\n`; |
106 | |
107 | // Backup original |
108 | const backupPath = path.join(backupDir, fileName); |
109 | fs.copyFileSync(filePath, backupPath); |
110 | |
111 | // Determine new filename |
112 | let outputPath = filePath; |
113 | if (dateInfo) { |
114 | const newFilename = dateInfo.newFilename; |
115 | outputPath = path.join(path.dirname(filePath), newFilename); |
116 | } |
117 | |
118 | // Write cleaned file (possibly with new filename) |
119 | fs.writeFileSync(outputPath, finalContent, "utf8"); |
120 | |
121 | // If filename changed, delete the old file |
122 | if (outputPath !== filePath) { |
123 | fs.unlinkSync(filePath); |
124 | console.log(`Fixed & Renamed: ${fileName} -> ${path.basename(outputPath)}`); |
125 | } else { |
126 | console.log(`Fixed: ${fileName}`); |
127 | } |
128 | } |
129 | |
130 | // Process all markdown files |
131 | function fixAllFiles() { |
132 | const files = fs.readdirSync(inputDir); |
133 | files.forEach((file) => { |
134 | if (file.endsWith(".md")) { |
135 | fixFile(path.join(inputDir, file)); |
136 | } |
137 | }); |
138 | } |
139 | |
140 | fixAllFiles(); |