summaryrefslogtreecommitdiffhomepage
path: root/services/blog/nuldoc-src/generators
diff options
context:
space:
mode:
Diffstat (limited to 'services/blog/nuldoc-src/generators')
-rw-r--r--services/blog/nuldoc-src/generators/about.ts23
-rw-r--r--services/blog/nuldoc-src/generators/atom.ts79
-rw-r--r--services/blog/nuldoc-src/generators/home.ts19
-rw-r--r--services/blog/nuldoc-src/generators/not_found.ts21
-rw-r--r--services/blog/nuldoc-src/generators/post.ts63
-rw-r--r--services/blog/nuldoc-src/generators/post_list.ts63
-rw-r--r--services/blog/nuldoc-src/generators/slide.ts53
-rw-r--r--services/blog/nuldoc-src/generators/slide_list.ts23
-rw-r--r--services/blog/nuldoc-src/generators/tag.ts33
-rw-r--r--services/blog/nuldoc-src/generators/tag_list.ts23
-rw-r--r--services/blog/nuldoc-src/generators/tagged_page.ts4
11 files changed, 404 insertions, 0 deletions
diff --git a/services/blog/nuldoc-src/generators/about.ts b/services/blog/nuldoc-src/generators/about.ts
new file mode 100644
index 00000000..6663a190
--- /dev/null
+++ b/services/blog/nuldoc-src/generators/about.ts
@@ -0,0 +1,23 @@
+import AboutPage from "../pages/AboutPage.tsx";
+import { Config } from "../config.ts";
+import { renderToDOM } from "../jsx/render.ts";
+import { Page } from "../page.ts";
+import { SlidePage } from "./slide.ts";
+
+export type AboutPage = Page;
+
+export async function generateAboutPage(
+ slides: SlidePage[],
+ config: Config,
+): Promise<AboutPage> {
+ const html = await renderToDOM(
+ AboutPage(slides, config),
+ );
+
+ return {
+ root: html,
+ renderer: "html",
+ destFilePath: "/about/index.html",
+ href: "/about/",
+ };
+}
diff --git a/services/blog/nuldoc-src/generators/atom.ts b/services/blog/nuldoc-src/generators/atom.ts
new file mode 100644
index 00000000..6ad07b46
--- /dev/null
+++ b/services/blog/nuldoc-src/generators/atom.ts
@@ -0,0 +1,79 @@
+import { Config } from "../config.ts";
+import { Page } from "../page.ts";
+import { PostPage } from "../generators/post.ts";
+import { SlidePage } from "../generators/slide.ts";
+import { dateToRfc3339String } from "../revision.ts";
+import AtomPage from "../pages/AtomPage.tsx";
+import { renderToDOM } from "../jsx/render.ts";
+
+export type Feed = {
+ author: string;
+ icon: string;
+ id: string;
+ linkToSelf: string;
+ linkToAlternate: string;
+ title: string;
+ updated: string;
+ entries: Entry[];
+};
+
+export type Entry = {
+ id: string;
+ linkToAlternate: string;
+ published: string;
+ summary: string;
+ title: string;
+ updated: string;
+};
+
+const BASE_NAME = "atom.xml";
+
+export async function generateFeedPageFromEntries(
+ alternateLink: string,
+ feedSlug: string,
+ feedTitle: string,
+ entries: Array<PostPage | SlidePage>,
+ config: Config,
+): Promise<Page> {
+ const entries_: Entry[] = [];
+ for (const entry of entries) {
+ entries_.push({
+ id: `urn:uuid:${entry.uuid}`,
+ linkToAlternate: `https://${config.blog.fqdn}${entry.href}`,
+ title: entry.title,
+ summary: entry.description,
+ published: dateToRfc3339String(entry.published),
+ updated: dateToRfc3339String(entry.updated),
+ });
+ }
+ // Sort by published date in ascending order.
+ entries_.sort((a, b) => {
+ if (a.published < b.published) {
+ return 1;
+ } else if (a.published > b.published) {
+ return -1;
+ }
+ return 0;
+ });
+ const feedPath = `${alternateLink}${BASE_NAME}`;
+ const feed: Feed = {
+ author: config.blog.author,
+ icon: `https://${config.blog.fqdn}/favicon.svg`,
+ id: `tag:${config.blog.fqdn},${config.blog.siteCopyrightYear}:${feedSlug}`,
+ linkToSelf: `https://${config.blog.fqdn}${feedPath}`,
+ linkToAlternate: `https://${config.blog.fqdn}${alternateLink}`,
+ title: feedTitle,
+ updated: entries_.reduce(
+ (latest, entry) => entry.updated > latest ? entry.updated : latest,
+ entries_[0].updated,
+ ),
+ entries: entries_,
+ };
+
+ return {
+ root: await renderToDOM(AtomPage({ feed: feed })),
+ renderer: "xml",
+ destFilePath: feedPath,
+ href: feedPath,
+ };
+}
diff --git a/services/blog/nuldoc-src/generators/home.ts b/services/blog/nuldoc-src/generators/home.ts
new file mode 100644
index 00000000..679dd39a
--- /dev/null
+++ b/services/blog/nuldoc-src/generators/home.ts
@@ -0,0 +1,19 @@
+import HomePage from "../pages/HomePage.tsx";
+import { renderToDOM } from "../jsx/render.ts";
+import { Config } from "../config.ts";
+import { Page } from "../page.ts";
+
+export type HomePage = Page;
+
+export async function generateHomePage(config: Config): Promise<HomePage> {
+ const html = await renderToDOM(
+ HomePage(config),
+ );
+
+ return {
+ root: html,
+ renderer: "html",
+ destFilePath: "/index.html",
+ href: "/",
+ };
+}
diff --git a/services/blog/nuldoc-src/generators/not_found.ts b/services/blog/nuldoc-src/generators/not_found.ts
new file mode 100644
index 00000000..f5a81c86
--- /dev/null
+++ b/services/blog/nuldoc-src/generators/not_found.ts
@@ -0,0 +1,21 @@
+import NotFoundPage from "../pages/NotFoundPage.tsx";
+import { renderToDOM } from "../jsx/render.ts";
+import { Config } from "../config.ts";
+import { Page } from "../page.ts";
+
+export type NotFoundPage = Page;
+
+export async function generateNotFoundPage(
+ config: Config,
+): Promise<NotFoundPage> {
+ const html = await renderToDOM(
+ NotFoundPage(config),
+ );
+
+ return {
+ root: html,
+ renderer: "html",
+ destFilePath: "/404.html",
+ href: "/404.html",
+ };
+}
diff --git a/services/blog/nuldoc-src/generators/post.ts b/services/blog/nuldoc-src/generators/post.ts
new file mode 100644
index 00000000..0e2a9553
--- /dev/null
+++ b/services/blog/nuldoc-src/generators/post.ts
@@ -0,0 +1,63 @@
+import { join } from "@std/path";
+import { renderToDOM } from "../jsx/render.ts";
+import PostPage from "../pages/PostPage.tsx";
+import { Config } from "../config.ts";
+import { Document } from "../djot/document.ts";
+import { Page } from "../page.ts";
+import { Date, Revision } from "../revision.ts";
+
+export interface PostPage extends Page {
+ title: string;
+ description: string;
+ tags: string[];
+ revisions: Revision[];
+ published: Date;
+ updated: Date;
+ uuid: string;
+}
+
+export function getPostPublishedDate(page: { revisions: Revision[] }): Date {
+ for (const rev of page.revisions) {
+ if (!rev.isInternal) {
+ return rev.date;
+ }
+ }
+ return page.revisions[0].date;
+}
+
+export function getPostUpdatedDate(page: { revisions: Revision[] }): Date {
+ return page.revisions[page.revisions.length - 1].date;
+}
+
+export function postHasAnyUpdates(page: { revisions: Revision[] }): boolean {
+ return 2 <= page.revisions.filter((rev) => !rev.isInternal).length;
+}
+
+export async function generatePostPage(
+ doc: Document,
+ config: Config,
+): Promise<PostPage> {
+ const html = await renderToDOM(
+ PostPage(doc, config),
+ );
+
+ const cwd = Deno.cwd();
+ const contentDir = join(cwd, config.locations.contentDir);
+ const destFilePath = join(
+ doc.sourceFilePath.replace(contentDir, "").replace(".dj", ""),
+ "index.html",
+ );
+ return {
+ root: html,
+ renderer: "html",
+ destFilePath: destFilePath,
+ href: destFilePath.replace("index.html", ""),
+ title: doc.title,
+ description: doc.description,
+ tags: doc.tags,
+ revisions: doc.revisions,
+ published: getPostPublishedDate(doc),
+ updated: getPostUpdatedDate(doc),
+ uuid: doc.uuid,
+ };
+}
diff --git a/services/blog/nuldoc-src/generators/post_list.ts b/services/blog/nuldoc-src/generators/post_list.ts
new file mode 100644
index 00000000..b05f7ee6
--- /dev/null
+++ b/services/blog/nuldoc-src/generators/post_list.ts
@@ -0,0 +1,63 @@
+import { renderToDOM } from "../jsx/render.ts";
+import PostListPage from "../pages/PostListPage.tsx";
+import { Config } from "../config.ts";
+import { Page } from "../page.ts";
+import { PostPage } from "./post.ts";
+
+export type PostListPage = Page;
+
+export async function generatePostListPages(
+ posts: PostPage[],
+ config: Config,
+): Promise<PostListPage[]> {
+ const postsPerPage = config.blog.postsPerPage;
+ const totalPages = Math.ceil(posts.length / postsPerPage);
+ const pages: PostListPage[] = [];
+
+ for (let pageIndex = 0; pageIndex < totalPages; pageIndex++) {
+ const pagePosts = posts.slice(
+ pageIndex * postsPerPage,
+ (pageIndex + 1) * postsPerPage,
+ );
+
+ const page = await generatePostListPage(
+ pagePosts,
+ config,
+ pageIndex + 1,
+ totalPages,
+ );
+
+ pages.push(page);
+ }
+
+ return pages;
+}
+
+async function generatePostListPage(
+ posts: PostPage[],
+ config: Config,
+ currentPage: number,
+ totalPages: number,
+): Promise<PostListPage> {
+ const html = await renderToDOM(
+ PostListPage(
+ posts,
+ config,
+ currentPage,
+ totalPages,
+ ),
+ );
+
+ const destFilePath = currentPage === 1
+ ? "/posts/index.html"
+ : `/posts/${currentPage}/index.html`;
+
+ const href = currentPage === 1 ? "/posts/" : `/posts/${currentPage}/`;
+
+ return {
+ root: html,
+ renderer: "html",
+ destFilePath,
+ href,
+ };
+}
diff --git a/services/blog/nuldoc-src/generators/slide.ts b/services/blog/nuldoc-src/generators/slide.ts
new file mode 100644
index 00000000..cd28879f
--- /dev/null
+++ b/services/blog/nuldoc-src/generators/slide.ts
@@ -0,0 +1,53 @@
+import { join } from "@std/path";
+import { renderToDOM } from "../jsx/render.ts";
+import SlidePage from "../pages/SlidePage.tsx";
+import { Config } from "../config.ts";
+import { Page } from "../page.ts";
+import { Date, Revision } from "../revision.ts";
+import { Slide } from "../slide/slide.ts";
+import { getPostPublishedDate, getPostUpdatedDate } from "./post.ts";
+
+export interface SlidePage extends Page {
+ title: string;
+ description: string;
+ event: string;
+ talkType: string;
+ slideLink: string;
+ tags: string[];
+ revisions: Revision[];
+ published: Date;
+ updated: Date;
+ uuid: string;
+}
+
+export async function generateSlidePage(
+ slide: Slide,
+ config: Config,
+): Promise<SlidePage> {
+ const html = await renderToDOM(
+ SlidePage(slide, config),
+ );
+
+ const cwd = Deno.cwd();
+ const contentDir = join(cwd, config.locations.contentDir);
+ const destFilePath = join(
+ slide.sourceFilePath.replace(contentDir, "").replace(".toml", ""),
+ "index.html",
+ );
+ return {
+ root: html,
+ renderer: "html",
+ destFilePath: destFilePath,
+ href: destFilePath.replace("index.html", ""),
+ title: slide.title,
+ description: `登壇: ${slide.event} (${slide.talkType})`,
+ event: slide.event,
+ talkType: slide.talkType,
+ slideLink: slide.slideLink,
+ tags: slide.tags,
+ revisions: slide.revisions,
+ published: getPostPublishedDate(slide),
+ updated: getPostUpdatedDate(slide),
+ uuid: slide.uuid,
+ };
+}
diff --git a/services/blog/nuldoc-src/generators/slide_list.ts b/services/blog/nuldoc-src/generators/slide_list.ts
new file mode 100644
index 00000000..abebe109
--- /dev/null
+++ b/services/blog/nuldoc-src/generators/slide_list.ts
@@ -0,0 +1,23 @@
+import { renderToDOM } from "../jsx/render.ts";
+import SlideListPage from "../pages/SlideListPage.tsx";
+import { Config } from "../config.ts";
+import { Page } from "../page.ts";
+import { SlidePage } from "./slide.ts";
+
+export type SlideListPage = Page;
+
+export async function generateSlideListPage(
+ slides: SlidePage[],
+ config: Config,
+): Promise<SlideListPage> {
+ const html = await renderToDOM(
+ SlideListPage(slides, config),
+ );
+
+ return {
+ root: html,
+ renderer: "html",
+ destFilePath: "/slides/index.html",
+ href: "/slides/",
+ };
+}
diff --git a/services/blog/nuldoc-src/generators/tag.ts b/services/blog/nuldoc-src/generators/tag.ts
new file mode 100644
index 00000000..dbd8ef93
--- /dev/null
+++ b/services/blog/nuldoc-src/generators/tag.ts
@@ -0,0 +1,33 @@
+import { renderToDOM } from "../jsx/render.ts";
+import TagPage from "../pages/TagPage.tsx";
+import { Config, getTagLabel } from "../config.ts";
+import { Page } from "../page.ts";
+import { TaggedPage } from "./tagged_page.ts";
+
+export interface TagPage extends Page {
+ tagSlug: string;
+ tagLabel: string;
+ numOfPosts: number;
+ numOfSlides: number;
+}
+
+export async function generateTagPage(
+ tagSlug: string,
+ pages: TaggedPage[],
+ config: Config,
+): Promise<TagPage> {
+ const html = await renderToDOM(
+ TagPage(tagSlug, pages, config),
+ );
+
+ return {
+ root: html,
+ renderer: "html",
+ destFilePath: `/tags/${tagSlug}/index.html`,
+ href: `/tags/${tagSlug}/`,
+ tagSlug: tagSlug,
+ tagLabel: getTagLabel(config, tagSlug),
+ numOfPosts: pages.filter((p) => !("event" in p)).length,
+ numOfSlides: pages.filter((p) => "event" in p).length,
+ };
+}
diff --git a/services/blog/nuldoc-src/generators/tag_list.ts b/services/blog/nuldoc-src/generators/tag_list.ts
new file mode 100644
index 00000000..7baad8cf
--- /dev/null
+++ b/services/blog/nuldoc-src/generators/tag_list.ts
@@ -0,0 +1,23 @@
+import { renderToDOM } from "../jsx/render.ts";
+import TagListPage from "../pages/TagListPage.tsx";
+import { Config } from "../config.ts";
+import { Page } from "../page.ts";
+import { TagPage } from "./tag.ts";
+
+export type TagListPage = Page;
+
+export async function generateTagListPage(
+ tags: TagPage[],
+ config: Config,
+): Promise<TagListPage> {
+ const html = await renderToDOM(
+ TagListPage(tags, config),
+ );
+
+ return {
+ root: html,
+ renderer: "html",
+ destFilePath: "/tags/index.html",
+ href: "/tags/",
+ };
+}
diff --git a/services/blog/nuldoc-src/generators/tagged_page.ts b/services/blog/nuldoc-src/generators/tagged_page.ts
new file mode 100644
index 00000000..23de8cb4
--- /dev/null
+++ b/services/blog/nuldoc-src/generators/tagged_page.ts
@@ -0,0 +1,4 @@
+import { PostPage } from "./post.ts";
+import { SlidePage } from "./slide.ts";
+
+export type TaggedPage = PostPage | SlidePage;