Last active 1746391523

I needed to convert 11ty formatted frontmatter to use Astro syntax for 20+ files. I needed it quickly and ChatGPT gave me the basics. Included is the chat with the bot so you can tweak it to suit your needs.

tiffmin revised this gist 1746391523. Go to revision

1 file changed, 3 insertions

11ty-to-astro.mjs

@@ -1,3 +1,6 @@
1 + // ChatGPT conversation to help with this script:
2 + // https://chatgpt.com/share/6817d17d-5a24-8002-9471-b5aa174f689d
3 +
1 4 import fs from "fs";
2 5 import path from "path";
3 6 import matter from "gray-matter";

tiffmin revised this gist 1746391294. Go to revision

1 file changed, 140 insertions

11ty-to-astro.mjs(file created)

@@ -0,0 +1,140 @@
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();
Newer Older