aboutsummaryrefslogtreecommitdiffhomepage
path: root/services/nuldoc/nuldoc-src/components
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-02-01 00:49:15 +0900
committernsfisis <nsfisis@gmail.com>2026-02-01 00:49:19 +0900
commit6dedddc545e2f1930bdc2256784eb1551bd4231d (patch)
tree75fcb5a6043dc0f2c31b098bf3cfd17a2b938599 /services/nuldoc/nuldoc-src/components
parentd08e3edb65b215152aa26e3518fb2f2cd7071c4b (diff)
downloadnsfisis.dev-6dedddc545e2f1930bdc2256784eb1551bd4231d.tar.gz
nsfisis.dev-6dedddc545e2f1930bdc2256784eb1551bd4231d.tar.zst
nsfisis.dev-6dedddc545e2f1930bdc2256784eb1551bd4231d.zip
feat(nuldoc): rewrite nuldoc in Ruby
Diffstat (limited to 'services/nuldoc/nuldoc-src/components')
-rw-r--r--services/nuldoc/nuldoc-src/components/AboutGlobalHeader.ts15
-rw-r--r--services/nuldoc/nuldoc-src/components/BlogGlobalHeader.ts28
-rw-r--r--services/nuldoc/nuldoc-src/components/DefaultGlobalHeader.ts15
-rw-r--r--services/nuldoc/nuldoc-src/components/GlobalFooter.ts9
-rw-r--r--services/nuldoc/nuldoc-src/components/PageLayout.ts76
-rw-r--r--services/nuldoc/nuldoc-src/components/Pagination.ts93
-rw-r--r--services/nuldoc/nuldoc-src/components/PostPageEntry.ts55
-rw-r--r--services/nuldoc/nuldoc-src/components/SlidePageEntry.ts55
-rw-r--r--services/nuldoc/nuldoc-src/components/SlidesGlobalHeader.ts27
-rw-r--r--services/nuldoc/nuldoc-src/components/StaticScript.ts26
-rw-r--r--services/nuldoc/nuldoc-src/components/StaticStylesheet.ts21
-rw-r--r--services/nuldoc/nuldoc-src/components/TableOfContents.ts30
-rw-r--r--services/nuldoc/nuldoc-src/components/TagList.ts19
-rw-r--r--services/nuldoc/nuldoc-src/components/utils.ts8
14 files changed, 0 insertions, 477 deletions
diff --git a/services/nuldoc/nuldoc-src/components/AboutGlobalHeader.ts b/services/nuldoc/nuldoc-src/components/AboutGlobalHeader.ts
deleted file mode 100644
index df437931..00000000
--- a/services/nuldoc/nuldoc-src/components/AboutGlobalHeader.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Config } from "../config.ts";
-import { a, div, Element, header } from "../dom.ts";
-
-export default function GlobalHeader({ config }: { config: Config }): Element {
- return header(
- { class: "header" },
- div(
- { class: "site-logo" },
- a(
- { href: `https://${config.sites.default.fqdn}/` },
- "nsfisis.dev",
- ),
- ),
- );
-}
diff --git a/services/nuldoc/nuldoc-src/components/BlogGlobalHeader.ts b/services/nuldoc/nuldoc-src/components/BlogGlobalHeader.ts
deleted file mode 100644
index ae0fc13a..00000000
--- a/services/nuldoc/nuldoc-src/components/BlogGlobalHeader.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { Config } from "../config.ts";
-import { a, div, Element, header, li, nav, ul } from "../dom.ts";
-
-export default function GlobalHeader({ config }: { config: Config }): Element {
- return header(
- { class: "header" },
- div(
- { class: "site-logo" },
- a(
- { href: `https://${config.sites.default.fqdn}/` },
- "nsfisis.dev",
- ),
- ),
- div({ class: "site-name" }, config.sites.blog.siteName),
- nav(
- { class: "nav" },
- ul(
- {},
- li(
- {},
- a({ href: `https://${config.sites.about.fqdn}/` }, "About"),
- ),
- li({}, a({ href: "/posts/" }, "Posts")),
- li({}, a({ href: "/tags/" }, "Tags")),
- ),
- ),
- );
-}
diff --git a/services/nuldoc/nuldoc-src/components/DefaultGlobalHeader.ts b/services/nuldoc/nuldoc-src/components/DefaultGlobalHeader.ts
deleted file mode 100644
index df437931..00000000
--- a/services/nuldoc/nuldoc-src/components/DefaultGlobalHeader.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Config } from "../config.ts";
-import { a, div, Element, header } from "../dom.ts";
-
-export default function GlobalHeader({ config }: { config: Config }): Element {
- return header(
- { class: "header" },
- div(
- { class: "site-logo" },
- a(
- { href: `https://${config.sites.default.fqdn}/` },
- "nsfisis.dev",
- ),
- ),
- );
-}
diff --git a/services/nuldoc/nuldoc-src/components/GlobalFooter.ts b/services/nuldoc/nuldoc-src/components/GlobalFooter.ts
deleted file mode 100644
index 313a01c5..00000000
--- a/services/nuldoc/nuldoc-src/components/GlobalFooter.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { Config } from "../config.ts";
-import { Element, footer } from "../dom.ts";
-
-export default function GlobalFooter({ config }: { config: Config }): Element {
- return footer(
- { class: "footer" },
- `&copy; ${config.site.copyrightYear} ${config.site.author}`,
- );
-}
diff --git a/services/nuldoc/nuldoc-src/components/PageLayout.ts b/services/nuldoc/nuldoc-src/components/PageLayout.ts
deleted file mode 100644
index f970c0b6..00000000
--- a/services/nuldoc/nuldoc-src/components/PageLayout.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-import { Config } from "../config.ts";
-import { elem, Element, link, meta, Node } from "../dom.ts";
-import StaticStylesheet from "./StaticStylesheet.ts";
-
-type Props = {
- metaCopyrightYear: number;
- metaDescription: string;
- metaKeywords?: string[];
- metaTitle: string;
- metaAtomFeedHref?: string;
- requiresSyntaxHighlight?: boolean;
- site: "default" | "about" | "blog" | "slides";
- config: Config;
- children: Node;
-};
-
-export default async function PageLayout(
- {
- metaCopyrightYear,
- metaDescription,
- metaKeywords,
- metaTitle,
- metaAtomFeedHref,
- requiresSyntaxHighlight: _,
- site,
- config,
- children,
- }: Props,
-): Promise<Element> {
- return elem(
- "html",
- { lang: "ja-JP" },
- elem(
- "head",
- {},
- meta({ charset: "UTF-8" }),
- meta({
- name: "viewport",
- content: "width=device-width, initial-scale=1.0",
- }),
- meta({ name: "author", content: config.site.author }),
- meta({
- name: "copyright",
- content: `&copy; ${metaCopyrightYear} ${config.site.author}`,
- }),
- meta({ name: "description", content: metaDescription }),
- metaKeywords && metaKeywords.length !== 0
- ? meta({ name: "keywords", content: metaKeywords.join(",") })
- : null,
- meta({ property: "og:type", content: "article" }),
- meta({ property: "og:title", content: metaTitle }),
- meta({ property: "og:description", content: metaDescription }),
- meta({
- property: "og:site_name",
- content: config.sites[site].siteName,
- }),
- meta({ property: "og:locale", content: "ja_JP" }),
- meta({ name: "Hatena::Bookmark", content: "nocomment" }),
- metaAtomFeedHref
- ? link({
- rel: "alternate",
- href: metaAtomFeedHref,
- type: "application/atom+xml",
- })
- : null,
- link({
- rel: "icon",
- href: "/favicon.svg",
- type: "image/svg+xml",
- }),
- elem("title", {}, metaTitle),
- await StaticStylesheet({ fileName: "/style.css", config }),
- ),
- children,
- );
-}
diff --git a/services/nuldoc/nuldoc-src/components/Pagination.ts b/services/nuldoc/nuldoc-src/components/Pagination.ts
deleted file mode 100644
index d9203165..00000000
--- a/services/nuldoc/nuldoc-src/components/Pagination.ts
+++ /dev/null
@@ -1,93 +0,0 @@
-import { a, div, Element, nav, span } from "../dom.ts";
-
-type Props = {
- currentPage: number;
- totalPages: number;
- basePath: string;
-};
-
-export default function Pagination(
- { currentPage, totalPages, basePath }: Props,
-): Element {
- if (totalPages <= 1) {
- return div({});
- }
-
- const pages = generatePageNumbers(currentPage, totalPages);
-
- return nav(
- { class: "pagination" },
- div(
- { class: "pagination-prev" },
- currentPage > 1
- ? a({ href: pageUrlAt(basePath, currentPage - 1) }, "前へ")
- : null,
- ),
- ...pages.map((page) => {
- if (page === "...") {
- return div({ class: "pagination-elipsis" }, "…");
- } else if (page === currentPage) {
- return div(
- { class: "pagination-page pagination-page-current" },
- span({}, String(page)),
- );
- } else {
- return div(
- { class: "pagination-page" },
- a({ href: pageUrlAt(basePath, page) }, String(page)),
- );
- }
- }),
- div(
- { class: "pagination-next" },
- currentPage < totalPages
- ? a({ href: pageUrlAt(basePath, currentPage + 1) }, "次へ")
- : null,
- ),
- );
-}
-
-type PageItem = number | "...";
-
-/**
- * Generates page numbers for pagination display.
- *
- * - Always show the first page
- * - Always show the last page
- * - Always show the current page
- * - Always show the page before and after the current page
- * - If there's only one page gap between displayed pages, fill it
- * - If there are two or more pages gap between displayed pages, show ellipsis
- */
-function generatePageNumbers(
- currentPage: number,
- totalPages: number,
-): PageItem[] {
- const pages = new Set<number>();
- pages.add(1);
- pages.add(Math.max(1, currentPage - 1));
- pages.add(currentPage);
- pages.add(Math.min(totalPages, currentPage + 1));
- pages.add(totalPages);
-
- const sorted = Array.from(pages).sort((a, b) => a - b);
-
- const result: PageItem[] = [];
- for (let i = 0; i < sorted.length; i++) {
- if (i > 0) {
- const gap = sorted[i] - sorted[i - 1];
- if (gap === 2) {
- result.push(sorted[i - 1] + 1);
- } else if (gap > 2) {
- result.push("...");
- }
- }
- result.push(sorted[i]);
- }
-
- return result;
-}
-
-function pageUrlAt(basePath: string, page: number): string {
- return page === 1 ? basePath : `${basePath}${page}/`;
-}
diff --git a/services/nuldoc/nuldoc-src/components/PostPageEntry.ts b/services/nuldoc/nuldoc-src/components/PostPageEntry.ts
deleted file mode 100644
index 482a3a8e..00000000
--- a/services/nuldoc/nuldoc-src/components/PostPageEntry.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import {
- getPostPublishedDate,
- getPostUpdatedDate,
- postHasAnyUpdates,
- PostPage,
-} from "../generators/post.ts";
-import { dateToString } from "../revision.ts";
-import { Config } from "../config.ts";
-import {
- a,
- article,
- elem,
- Element,
- footer,
- h2,
- header,
- p,
- section,
-} from "../dom.ts";
-import TagList from "./TagList.ts";
-
-type Props = { post: PostPage; config: Config };
-
-export default function PostPageEntry({ post, config }: Props): Element {
- return article(
- { class: "post-entry" },
- a(
- { href: post.href },
- header({ class: "entry-header" }, h2({}, post.title)),
- section(
- { class: "entry-content" },
- p({}, post.description),
- ),
- footer(
- { class: "entry-footer" },
- elem(
- "time",
- { datetime: dateToString(getPostPublishedDate(post)) },
- dateToString(getPostPublishedDate(post)),
- ),
- " 投稿",
- postHasAnyUpdates(post) ? "、" : null,
- postHasAnyUpdates(post)
- ? elem(
- "time",
- { datetime: dateToString(getPostUpdatedDate(post)) },
- dateToString(getPostUpdatedDate(post)),
- )
- : null,
- postHasAnyUpdates(post) ? " 更新" : null,
- post.tags.length !== 0 ? TagList({ tags: post.tags, config }) : null,
- ),
- ),
- );
-}
diff --git a/services/nuldoc/nuldoc-src/components/SlidePageEntry.ts b/services/nuldoc/nuldoc-src/components/SlidePageEntry.ts
deleted file mode 100644
index b48ab4e5..00000000
--- a/services/nuldoc/nuldoc-src/components/SlidePageEntry.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import {
- getPostPublishedDate,
- getPostUpdatedDate,
- postHasAnyUpdates,
-} from "../generators/post.ts";
-import { SlidePage } from "../generators/slide.ts";
-import { dateToString } from "../revision.ts";
-import { Config } from "../config.ts";
-import {
- a,
- article,
- elem,
- Element,
- footer,
- h2,
- header,
- p,
- section,
-} from "../dom.ts";
-import TagList from "./TagList.ts";
-
-type Props = { slide: SlidePage; config: Config };
-
-export default function SlidePageEntry({ slide, config }: Props): Element {
- return article(
- { class: "post-entry" },
- a(
- { href: slide.href },
- header(
- { class: "entry-header" },
- h2({}, slide.title),
- ),
- section({ class: "entry-content" }, p({}, slide.description)),
- footer(
- { class: "entry-footer" },
- elem(
- "time",
- { datetime: dateToString(getPostPublishedDate(slide)) },
- dateToString(getPostPublishedDate(slide)),
- ),
- " 登壇",
- postHasAnyUpdates(slide) ? "、" : null,
- postHasAnyUpdates(slide)
- ? elem(
- "time",
- { datetime: dateToString(getPostUpdatedDate(slide)) },
- dateToString(getPostUpdatedDate(slide)),
- )
- : null,
- postHasAnyUpdates(slide) ? " 更新" : null,
- slide.tags.length !== 0 ? TagList({ tags: slide.tags, config }) : null,
- ),
- ),
- );
-}
diff --git a/services/nuldoc/nuldoc-src/components/SlidesGlobalHeader.ts b/services/nuldoc/nuldoc-src/components/SlidesGlobalHeader.ts
deleted file mode 100644
index 666ca0e3..00000000
--- a/services/nuldoc/nuldoc-src/components/SlidesGlobalHeader.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { Config } from "../config.ts";
-import { a, div, Element, header, li, nav, ul } from "../dom.ts";
-
-export default function GlobalHeader({ config }: { config: Config }): Element {
- return header(
- { class: "header" },
- div(
- { class: "site-logo" },
- a(
- { href: `https://${config.sites.default.fqdn}/` },
- "nsfisis.dev",
- ),
- ),
- nav(
- { class: "nav" },
- ul(
- {},
- li(
- {},
- a({ href: `https://${config.sites.about.fqdn}/` }, "About"),
- ),
- li({}, a({ href: "/slides/" }, "Slides")),
- li({}, a({ href: "/tags/" }, "Tags")),
- ),
- ),
- );
-}
diff --git a/services/nuldoc/nuldoc-src/components/StaticScript.ts b/services/nuldoc/nuldoc-src/components/StaticScript.ts
deleted file mode 100644
index 1a3431a3..00000000
--- a/services/nuldoc/nuldoc-src/components/StaticScript.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { join } from "@std/path";
-import { Config } from "../config.ts";
-import { Element, script } from "../dom.ts";
-import { calculateFileHash } from "./utils.ts";
-
-export default async function StaticScript(
- { site, fileName, type, defer, config }: {
- site?: string;
- fileName: string;
- type?: string;
- defer?: "true";
- config: Config;
- },
-): Promise<Element> {
- const filePath = join(
- Deno.cwd(),
- config.locations.staticDir,
- site || "_all",
- fileName,
- );
- const hash = await calculateFileHash(filePath);
- const attrs: Record<string, string> = { src: `${fileName}?h=${hash}` };
- if (type) attrs.type = type;
- if (defer) attrs.defer = defer;
- return script(attrs);
-}
diff --git a/services/nuldoc/nuldoc-src/components/StaticStylesheet.ts b/services/nuldoc/nuldoc-src/components/StaticStylesheet.ts
deleted file mode 100644
index f2adb473..00000000
--- a/services/nuldoc/nuldoc-src/components/StaticStylesheet.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { join } from "@std/path";
-import { Config } from "../config.ts";
-import { Element, link } from "../dom.ts";
-import { calculateFileHash } from "./utils.ts";
-
-export default async function StaticStylesheet(
- { site, fileName, config }: {
- site?: string;
- fileName: string;
- config: Config;
- },
-): Promise<Element> {
- const filePath = join(
- Deno.cwd(),
- config.locations.staticDir,
- site || "_all",
- fileName,
- );
- const hash = await calculateFileHash(filePath);
- return link({ rel: "stylesheet", href: `${fileName}?h=${hash}` });
-}
diff --git a/services/nuldoc/nuldoc-src/components/TableOfContents.ts b/services/nuldoc/nuldoc-src/components/TableOfContents.ts
deleted file mode 100644
index 1eb79e98..00000000
--- a/services/nuldoc/nuldoc-src/components/TableOfContents.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import { TocEntry, TocRoot } from "../markdown/document.ts";
-import { a, Element, h2, li, nav, ul } from "../dom.ts";
-
-type Props = {
- toc: TocRoot;
-};
-
-export default function TableOfContents({ toc }: Props): Element {
- return nav(
- { class: "toc" },
- h2({}, "目次"),
- ul(
- {},
- ...toc.entries.map((entry) => TocEntryComponent({ entry })),
- ),
- );
-}
-
-function TocEntryComponent({ entry }: { entry: TocEntry }): Element {
- return li(
- {},
- a({ href: `#${entry.id}` }, entry.text),
- entry.children.length > 0
- ? ul(
- {},
- ...entry.children.map((child) => TocEntryComponent({ entry: child })),
- )
- : null,
- );
-}
diff --git a/services/nuldoc/nuldoc-src/components/TagList.ts b/services/nuldoc/nuldoc-src/components/TagList.ts
deleted file mode 100644
index ed3fc1a1..00000000
--- a/services/nuldoc/nuldoc-src/components/TagList.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { Config, getTagLabel } from "../config.ts";
-import { Element, li, span, text, ul } from "../dom.ts";
-
-type Props = {
- tags: string[];
- config: Config;
-};
-
-export default function TagList({ tags, config }: Props): Element {
- return ul(
- { class: "entry-tags" },
- ...tags.map((slug) =>
- li(
- { class: "tag" },
- span({ class: "tag-inner" }, text(getTagLabel(config, slug))),
- )
- ),
- );
-}
diff --git a/services/nuldoc/nuldoc-src/components/utils.ts b/services/nuldoc/nuldoc-src/components/utils.ts
deleted file mode 100644
index 14059b5b..00000000
--- a/services/nuldoc/nuldoc-src/components/utils.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { Hash } from "checksum/mod.ts";
-
-export async function calculateFileHash(
- filePath: string,
-): Promise<string> {
- const content = await Deno.readFile(filePath);
- return new Hash("md5").digest(content).hex();
-}