|
| 1 | +import fs from "fs"; |
| 2 | +import path from "path"; |
| 3 | +import matter from "gray-matter"; |
| 4 | +import { getAllMarkdownFiles } from "./lib/markdown-utils.js"; |
| 5 | +import config from "./config.js"; |
| 6 | + |
| 7 | +const { baseUrl: BASE_URL, title: SITE_TITLE, description: SITE_DESC } = config.site; |
| 8 | + |
| 9 | +if (!BASE_URL) console.warn("⚠️ No baseUrl detected. Check .vuepress/theme.ts or set BASE_URL env var."); |
| 10 | +if (!SITE_TITLE) console.warn("⚠️ No site title detected. Check .vuepress/config.ts"); |
| 11 | + |
| 12 | +/** |
| 13 | + * Generate URL based on file path |
| 14 | + */ |
| 15 | +function generateUrl(filePath) { |
| 16 | + const relativePath = path.relative(config.docsDir, filePath); |
| 17 | + |
| 18 | + // Handle Docsify reading notes |
| 19 | + if (relativePath.startsWith("reading" + path.sep)) { |
| 20 | + const docsifyPath = relativePath |
| 21 | + .replace(/^reading[\/\\]/, "") |
| 22 | + .replace(/\\/g, "/") |
| 23 | + .replace(/\.md$/, ""); |
| 24 | + return `${BASE_URL}/reading/#/${docsifyPath}`; |
| 25 | + } |
| 26 | + |
| 27 | + // Handle VuePress pages |
| 28 | + let urlPath = relativePath.replace(/\\/g, "/"); |
| 29 | + |
| 30 | + if (urlPath.endsWith("README.md") || urlPath.endsWith("index.md")) { |
| 31 | + urlPath = urlPath.replace(/(^|\/)(README|index)\.md$/, "$1"); |
| 32 | + } else { |
| 33 | + urlPath = urlPath.replace(/\.md$/, ".html"); |
| 34 | + } |
| 35 | + |
| 36 | + if (urlPath && !urlPath.endsWith(".html") && !urlPath.endsWith("/")) { |
| 37 | + urlPath += "/"; |
| 38 | + } |
| 39 | + |
| 40 | + return `${BASE_URL}/${urlPath}`; |
| 41 | +} |
| 42 | + |
| 43 | +/** |
| 44 | + * Clean description text |
| 45 | + */ |
| 46 | +function cleanDescription(text) { |
| 47 | + if (text == null) return ""; |
| 48 | + if (Array.isArray(text)) text = text.filter(Boolean).join(" "); |
| 49 | + if (typeof text !== "string") { |
| 50 | + if (typeof text === "number" || typeof text === "boolean") text = String(text); |
| 51 | + else return ""; |
| 52 | + } |
| 53 | + return text |
| 54 | + .replace(/\[([^\]]+)\]\([^\)]+\)/g, "$1") |
| 55 | + .replace(/[\r\n]+/g, " ") |
| 56 | + .trim(); |
| 57 | +} |
| 58 | + |
| 59 | +/** |
| 60 | + * Main function |
| 61 | + */ |
| 62 | +function main() { |
| 63 | + console.log("🔍 Scanning for Markdown files..."); |
| 64 | + console.log(`🌐 Base URL: ${BASE_URL}`); |
| 65 | + const files = getAllMarkdownFiles(config.docsDir, config.llms.excludedDirs); |
| 66 | + console.log(`📄 Found ${files.length} files.`); |
| 67 | + |
| 68 | + const pages = []; |
| 69 | + |
| 70 | + files.forEach((filePath) => { |
| 71 | + try { |
| 72 | + const raw = fs.readFileSync(filePath, "utf-8"); |
| 73 | + const { data, content: body } = matter(raw); |
| 74 | + const frontmatter = Object.keys(data).length > 0 ? data : null; |
| 75 | + |
| 76 | + let title = frontmatter?.title ? String(frontmatter.title) : null; |
| 77 | + let description = frontmatter?.description ? cleanDescription(frontmatter.description) : null; |
| 78 | + |
| 79 | + // Fallback if no title in frontmatter |
| 80 | + if (!title) { |
| 81 | + const h1Match = body.match(/^#\s+(.+)$/m); |
| 82 | + if (h1Match) { |
| 83 | + title = h1Match[1].trim(); |
| 84 | + } |
| 85 | + } |
| 86 | + |
| 87 | + // Fallback: extract first content paragraph from body |
| 88 | + if (!description && title) { |
| 89 | + for (const line of body.split("\n")) { |
| 90 | + const trimmed = line.trim(); |
| 91 | + if (!trimmed || trimmed.startsWith("#") || trimmed.startsWith(">") || trimmed.startsWith("`; |
| 121 | + if (page.description) { |
| 122 | + content += ` - ${page.description}`; |
| 123 | + } |
| 124 | + content += `\n`; |
| 125 | + }); |
| 126 | + |
| 127 | + const outputDir = path.dirname(config.llms.outputFile); |
| 128 | + if (!fs.existsSync(outputDir)) { |
| 129 | + fs.mkdirSync(outputDir, { recursive: true }); |
| 130 | + } |
| 131 | + |
| 132 | + fs.writeFileSync(config.llms.outputFile, content, "utf-8"); |
| 133 | + console.log(`✅ Generated ${config.llms.outputFile} with ${pages.length} pages.`); |
| 134 | +} |
| 135 | + |
| 136 | +main(); |
0 commit comments