Built from the kit specs (CLAUDE.md, docs/01-05): question index import, status seals, connections graph, Pagefind search, Scripture margin, and 157 evidence articles (drafts unless published) with sources and verified "Learn more" links. Includes link, owner-notes, a11y and publish scripts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
63 lines
2.3 KiB
JavaScript
63 lines
2.3 KiB
JavaScript
#!/usr/bin/env node
|
|
// Publishes reviewed articles by removing their `draft: true` line, or puts them back as drafts.
|
|
//
|
|
// npm run publish -- 7.9 1.1 3B.10 publish these questions' articles
|
|
// npm run publish -- --all publish every article
|
|
// npm run publish -- --draft 7.9 mark an article as a draft again (also works with --all)
|
|
// npm run publish -- --list show which articles are drafts and which are published
|
|
|
|
import { readFileSync, writeFileSync, readdirSync } from "node:fs";
|
|
|
|
const dir = "src/content/articles";
|
|
const args = process.argv.slice(2);
|
|
const toDraft = args.includes("--draft");
|
|
const all = args.includes("--all");
|
|
const ids = args.filter((a) => !a.startsWith("--"));
|
|
|
|
const files = readdirSync(dir).filter((f) => f.endsWith(".mdx"));
|
|
const questionOf = (text) => text.match(/^question:\s*"([^"]+)"/m)?.[1];
|
|
const isDraft = (text) => /^draft:\s*true\s*$/m.test(text);
|
|
|
|
if (args.includes("--list")) {
|
|
const rows = files.map((f) => {
|
|
const text = readFileSync(`${dir}/${f}`, "utf8");
|
|
return { id: questionOf(text) ?? f, draft: isDraft(text) };
|
|
});
|
|
const drafts = rows.filter((r) => r.draft).map((r) => r.id);
|
|
const published = rows.filter((r) => !r.draft).map((r) => r.id);
|
|
console.log(`Published (${published.length}): ${published.join(", ") || "none"}`);
|
|
console.log(`Drafts (${drafts.length}): ${drafts.join(", ") || "none"}`);
|
|
process.exit(0);
|
|
}
|
|
|
|
if (!all && ids.length === 0) {
|
|
console.error("Name question ids (e.g. 7.9 3B.10), or pass --all. Add --draft to unpublish.");
|
|
process.exit(1);
|
|
}
|
|
|
|
const wanted = new Set(ids.map((id) => id.toUpperCase()));
|
|
let changed = 0;
|
|
const missing = new Set(wanted);
|
|
|
|
for (const f of files) {
|
|
const path = `${dir}/${f}`;
|
|
const text = readFileSync(path, "utf8");
|
|
const id = questionOf(text);
|
|
if (!id || (!all && !wanted.has(id.toUpperCase()))) continue;
|
|
missing.delete(id.toUpperCase());
|
|
|
|
let next = text;
|
|
if (toDraft && !isDraft(text)) {
|
|
next = text.replace(/^(question:.*)$/m, "$1\ndraft: true");
|
|
} else if (!toDraft && isDraft(text)) {
|
|
next = text.replace(/^draft:\s*true\s*\r?\n/m, "");
|
|
}
|
|
if (next !== text) {
|
|
writeFileSync(path, next);
|
|
changed++;
|
|
}
|
|
}
|
|
|
|
if (missing.size) console.error(`No article found for: ${[...missing].join(", ")}`);
|
|
console.log(`${toDraft ? "Marked as draft" : "Published"}: ${changed} article(s).`);
|