diff options
| author | nsfisis <nsfisis@gmail.com> | 2023-03-17 02:10:54 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2023-03-17 02:12:11 +0900 |
| commit | 29bcdc6c1bad2240d404de9dca2463e46fdc1e93 (patch) | |
| tree | 505e3004281013531a99327c83044852f20775fb /nuldoc-src/commands/build.ts | |
| parent | cbfb56927c34a8d45c789fe463ab1b66b8d9d9ff (diff) | |
| download | blog.nsfisis.dev-29bcdc6c1bad2240d404de9dca2463e46fdc1e93.tar.gz blog.nsfisis.dev-29bcdc6c1bad2240d404de9dca2463e46fdc1e93.tar.zst blog.nsfisis.dev-29bcdc6c1bad2240d404de9dca2463e46fdc1e93.zip | |
refactor: split command.ts
Diffstat (limited to 'nuldoc-src/commands/build.ts')
| -rw-r--r-- | nuldoc-src/commands/build.ts | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/nuldoc-src/commands/build.ts b/nuldoc-src/commands/build.ts new file mode 100644 index 0000000..734f520 --- /dev/null +++ b/nuldoc-src/commands/build.ts @@ -0,0 +1,170 @@ +import { dirname, join, joinGlobs } from "std/path/mod.ts"; +import { ensureDir } from "std/fs/mod.ts"; +import { expandGlob } from "std/fs/expand_glob.ts"; +import { Config } from "../config.ts"; +import { parseDocBookFile } from "../docbook/parse.ts"; +import { writeHtmlFile } from "../html.ts"; +import { Document } from "../docbook/document.ts"; +import convertPost from "../templates/post.ts"; +import convertPostList from "../templates/post_list.ts"; +import convertTag from "../templates/tag.ts"; +import generateAbout from "../templates/about.ts"; + +export async function runBuildCommand(config: Config) { + const posts = await generatePosts(config); + await generateTags(posts, config); + await generatePostList(posts, config); + await generateAboutPage(config); + await copyStaticFiles(config); +} + +async function generatePosts(config: Config) { + const sourceDir = join(Deno.cwd(), config.locations.contentDir, "posts"); + const postFiles = await collectPostFiles(sourceDir); + const posts = await parsePosts(postFiles, config); + await outputPosts(posts, config); + return posts; +} + +async function collectPostFiles(sourceDir: string): Promise<string[]> { + const filePaths = []; + const globPattern = joinGlobs([sourceDir, "**", "*.xml"]); + for await (const entry of expandGlob(globPattern)) { + filePaths.push(entry.path); + } + return filePaths; +} + +async function parsePosts( + postFiles: string[], + config: Config, +): Promise<Document[]> { + const posts = []; + for (const postFile of postFiles) { + posts.push( + await convertPost(await parseDocBookFile(postFile, config), config), + ); + } + return posts; +} + +async function outputPosts(posts: Document[], config: Config) { + const cwd = Deno.cwd(); + const contentDir = join(cwd, config.locations.contentDir); + const destDir = join(cwd, config.locations.destDir); + for (const post of posts) { + const destFilePath = join( + post.sourceFilePath.replace(contentDir, destDir).replace(".xml", ""), + "index.html", + ); + await ensureDir(dirname(destFilePath)); + await writeHtmlFile(post, destFilePath); + } +} + +async function generatePostList(posts: Document[], config: Config) { + const postList = await buildPostListDoc(posts, config); + await outputPostList(postList, config); +} + +async function buildPostListDoc( + posts: Document[], + config: Config, +): Promise<Document> { + return await convertPostList(posts, config); +} + +async function outputPostList(postList: Document, config: Config) { + const cwd = Deno.cwd(); + const destDir = join(cwd, config.locations.destDir); + const destFilePath = join(destDir, "posts", "index.html"); + await ensureDir(dirname(destFilePath)); + await writeHtmlFile(postList, destFilePath); +} + +async function generateAboutPage(config: Config) { + const aboutDoc = await generateAbout(config); + await outputAboutPage(aboutDoc, config); +} + +async function outputAboutPage(about: Document, config: Config) { + const cwd = Deno.cwd(); + const destDir = join(cwd, config.locations.destDir); + const destFilePath = join(destDir, "about", "index.html"); + await ensureDir(dirname(destFilePath)); + await writeHtmlFile(about, destFilePath); +} + +async function generateTags(posts: Document[], config: Config) { + const tagsAndPosts = collectTags(posts); + const tagDocs = await buildTagDocs(tagsAndPosts, config); + await outputTags(tagDocs, config); +} + +function collectTags(posts: Document[]): [string, Document[]][] { + const tagsAndPosts = new Map(); + for (const post of posts) { + for (const tag of post.tags) { + if (!tagsAndPosts.has(tag)) { + tagsAndPosts.set(tag, []); + } + tagsAndPosts.get(tag).push(post); + } + } + + const result: [string, Document[]][] = []; + for (const tag of Array.from(tagsAndPosts.keys()).sort()) { + result.push([ + tag, + tagsAndPosts.get(tag).sort((a: Document, b: Document) => { + const ta = a.revisions[0].date; + const tb = b.revisions[0].date; + if (ta > tb) return -1; + if (ta < tb) return 1; + return 0; + }), + ]); + } + return result; +} + +async function buildTagDocs( + tagsAndPosts: [string, Document[]][], + config: Config, +): Promise<[string, Document][]> { + const docs: [string, Document][] = []; + for (const [tag, posts] of tagsAndPosts) { + docs.push([tag, await buildTagDoc(tag, posts, config)]); + } + return docs; +} + +async function buildTagDoc( + tag: string, + posts: Document[], + config: Config, +): Promise<Document> { + return await convertTag(tag, posts, config); +} + +async function outputTags(tagDocs: [string, Document][], config: Config) { + const cwd = Deno.cwd(); + const destDir = join(cwd, config.locations.destDir); + for (const [tag, tagDoc] of tagDocs) { + const destFilePath = join(destDir, "tags", tag, "index.html"); + await ensureDir(dirname(destFilePath)); + await writeHtmlFile(tagDoc, destFilePath); + } +} + +async function copyStaticFiles(config: Config) { + const globPattern = joinGlobs([Deno.cwd(), config.locations.staticDir, "*"]); + for await (const entry of expandGlob(globPattern)) { + const src = entry.path; + const dst = src.replace( + config.locations.staticDir, + config.locations.destDir, + ); + await Deno.copyFile(src, dst); + } +} |
