aboutsummaryrefslogtreecommitdiffhomepage
path: root/scripts/add-about-prop.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/add-about-prop.mjs')
-rw-r--r--scripts/add-about-prop.mjs107
1 files changed, 107 insertions, 0 deletions
diff --git a/scripts/add-about-prop.mjs b/scripts/add-about-prop.mjs
new file mode 100644
index 0000000..e519863
--- /dev/null
+++ b/scripts/add-about-prop.mjs
@@ -0,0 +1,107 @@
+import { readFileSync, writeFileSync } from "node:fs";
+import { readdir } from "node:fs/promises";
+import { join, extname, relative } from "node:path";
+
+const DOCS_DIR = join(import.meta.dirname, "..", "src", "content", "docs");
+
+/**
+ * Recursively collect all .mdx files.
+ */
+async function collectMdxFiles(dir) {
+ const entries = await readdir(dir, { withFileTypes: true });
+ const files = [];
+
+ for (const entry of entries) {
+ if (entry.name.startsWith("_")) continue;
+ const fullPath = join(dir, entry.name);
+ if (entry.isDirectory()) {
+ const subFiles = await collectMdxFiles(fullPath);
+ files.push(...subFiles);
+ } else if (extname(entry.name) === ".mdx") {
+ files.push(fullPath);
+ }
+ }
+
+ return files;
+}
+
+/**
+ * Extract tags from frontmatter.
+ */
+function extractTags(content) {
+ const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
+ if (!match) return [];
+ const fm = match[1];
+
+ // Match YAML-style tags array: tags:\n - tag1\n - tag2
+ const tagSection = fm.match(/^tags:\s*\n((?:\s+-\s+.+\n?)*)/m);
+ if (!tagSection) return [];
+
+ const tagLines = tagSection[1].match(/^\s+-\s+(.+)$/gm);
+ if (!tagLines) return [];
+
+ return tagLines.map((line) => line.replace(/^\s+-\s+/, "").trim());
+}
+
+/**
+ * Infer `about` from tags.
+ * Uses the first tag that is not "一般質問".
+ */
+function inferAbout(tags) {
+ for (const tag of tags) {
+ if (tag !== "一般質問") return tag;
+ }
+ return null;
+}
+
+async function main() {
+ const files = await collectMdxFiles(DOCS_DIR);
+
+ let updated = 0;
+ let skipped = 0;
+
+ for (const file of files) {
+ const content = readFileSync(file, "utf-8");
+
+ // Only process files that use QuestionSummary
+ if (!content.includes("<QuestionSummary")) continue;
+
+ // Skip files that already have about=
+ if (content.includes("about=")) {
+ skipped++;
+ continue;
+ }
+
+ const tags = extractTags(content);
+ const about = inferAbout(tags);
+
+ if (!about) {
+ console.log(` SKIP (no topic tag): ${relative(DOCS_DIR, file)}`);
+ skipped++;
+ continue;
+ }
+
+ // Insert about prop after headline prop
+ const newContent = content.replace(
+ /(headline=.*\n)(\s+datePublished=)/,
+ `$1 about="${about}"\n$2`,
+ );
+
+ if (newContent === content) {
+ console.log(` SKIP (pattern not matched): ${relative(DOCS_DIR, file)}`);
+ skipped++;
+ continue;
+ }
+
+ writeFileSync(file, newContent, "utf-8");
+ console.log(` about="${about}" → ${relative(DOCS_DIR, file)}`);
+ updated++;
+ }
+
+ console.log(`\nDone: ${updated} updated, ${skipped} skipped.`);
+}
+
+main().catch((err) => {
+ console.error("Error:", err);
+ process.exit(1);
+});