aboutsummaryrefslogtreecommitdiffhomepage
path: root/services/blog/nuldoc-src/components
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-11-02 17:49:34 +0900
committernsfisis <nsfisis@gmail.com>2025-11-02 17:49:34 +0900
commit57315c52be96d2a2c013f0cfb0de5429980e301a (patch)
tree5d691497772fddfe401cd970ead4e9a74b34ef38 /services/blog/nuldoc-src/components
parentcf4091a93ed831456e8b30e2a9e1fc2650dcae02 (diff)
downloadnsfisis.dev-57315c52be96d2a2c013f0cfb0de5429980e301a.tar.gz
nsfisis.dev-57315c52be96d2a2c013f0cfb0de5429980e301a.tar.zst
nsfisis.dev-57315c52be96d2a2c013f0cfb0de5429980e301a.zip
refactor(blog): rename directory, services/{blog => nuldoc}/
Diffstat (limited to 'services/blog/nuldoc-src/components')
-rw-r--r--services/blog/nuldoc-src/components/GlobalFooter.tsx9
-rw-r--r--services/blog/nuldoc-src/components/GlobalHeader.tsx27
-rw-r--r--services/blog/nuldoc-src/components/PageLayout.tsx63
-rw-r--r--services/blog/nuldoc-src/components/Pagination.tsx104
-rw-r--r--services/blog/nuldoc-src/components/PostPageEntry.tsx46
-rw-r--r--services/blog/nuldoc-src/components/SlidePageEntry.tsx46
-rw-r--r--services/blog/nuldoc-src/components/StaticScript.tsx18
-rw-r--r--services/blog/nuldoc-src/components/StaticStylesheet.tsx11
-rw-r--r--services/blog/nuldoc-src/components/TableOfContents.tsx33
-rw-r--r--services/blog/nuldoc-src/components/TagList.tsx18
-rw-r--r--services/blog/nuldoc-src/components/utils.ts8
11 files changed, 0 insertions, 383 deletions
diff --git a/services/blog/nuldoc-src/components/GlobalFooter.tsx b/services/blog/nuldoc-src/components/GlobalFooter.tsx
deleted file mode 100644
index 757bece..0000000
--- a/services/blog/nuldoc-src/components/GlobalFooter.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import { Config } from "../config.ts";
-
-export default function GlobalFooter({ config }: { config: Config }) {
- return (
- <footer className="footer">
- {`&copy; ${config.blog.siteCopyrightYear} ${config.blog.author}`}
- </footer>
- );
-}
diff --git a/services/blog/nuldoc-src/components/GlobalHeader.tsx b/services/blog/nuldoc-src/components/GlobalHeader.tsx
deleted file mode 100644
index c0fa7e8..0000000
--- a/services/blog/nuldoc-src/components/GlobalHeader.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import { Config } from "../config.ts";
-
-export default function GlobalHeader({ config }: { config: Config }) {
- return (
- <header className="header">
- <div className="site-logo">
- <a href="/">{config.blog.siteName}</a>
- </div>
- <nav className="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- );
-}
diff --git a/services/blog/nuldoc-src/components/PageLayout.tsx b/services/blog/nuldoc-src/components/PageLayout.tsx
deleted file mode 100644
index 78a5cde..0000000
--- a/services/blog/nuldoc-src/components/PageLayout.tsx
+++ /dev/null
@@ -1,63 +0,0 @@
-import { Config } from "../config.ts";
-import { JSXNode } from "myjsx/jsx-runtime";
-import StaticStylesheet from "./StaticStylesheet.tsx";
-
-type Props = {
- metaCopyrightYear: number;
- metaDescription: string;
- metaKeywords?: string[];
- metaTitle: string;
- metaAtomFeedHref?: string;
- requiresSyntaxHighlight?: boolean;
- config: Config;
- children: JSXNode;
-};
-
-export default function PageLayout(
- {
- metaCopyrightYear,
- metaDescription,
- metaKeywords,
- metaTitle,
- metaAtomFeedHref,
- requiresSyntaxHighlight: _,
- config,
- children,
- }: Props,
-) {
- return (
- <html lang="ja-JP">
- <head>
- <meta charset="UTF-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <meta name="author" content={config.blog.author} />
- <meta
- name="copyright"
- content={`&copy; ${metaCopyrightYear} ${config.blog.author}`}
- />
- <meta name="description" content={metaDescription} />
- {metaKeywords && metaKeywords.length !== 0 &&
- <meta name="keywords" content={metaKeywords.join(",")} />}
- <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.blog.siteName} />
- <meta property="og:locale" content="ja_JP" />
- {/* https://b.hatena.ne.jp/help/entry/nocomment */}
- <meta name="Hatena::Bookmark" content="nocomment" />
- {metaAtomFeedHref &&
- (
- <link
- rel="alternate"
- href={metaAtomFeedHref}
- type="application/atom+xml"
- />
- )}
- <link rel="icon" href="/favicon.svg" type="image/svg+xml" />
- <title>{metaTitle}</title>
- <StaticStylesheet fileName="/style.css" config={config} />
- </head>
- {children}
- </html>
- );
-}
diff --git a/services/blog/nuldoc-src/components/Pagination.tsx b/services/blog/nuldoc-src/components/Pagination.tsx
deleted file mode 100644
index 84752c5..0000000
--- a/services/blog/nuldoc-src/components/Pagination.tsx
+++ /dev/null
@@ -1,104 +0,0 @@
-type Props = {
- currentPage: number;
- totalPages: number;
- basePath: string;
-};
-
-export default function Pagination(
- { currentPage, totalPages, basePath }: Props,
-) {
- if (totalPages <= 1) {
- return <div></div>;
- }
-
- const pages = generatePageNumbers(currentPage, totalPages);
-
- return (
- <nav className="pagination">
- <div className="pagination-prev">
- {currentPage > 1
- ? (
- <a href={pageUrlAt(basePath, currentPage - 1)}>
- 前へ
- </a>
- )
- : null}
- </div>
- {pages.map((page) => {
- if (page === "...") {
- return (
- <div className="pagination-elipsis">
- …
- </div>
- );
- } else if (page === currentPage) {
- return (
- <div className="pagination-page pagination-page-current">
- <span>{String(page)}</span>
- </div>
- );
- } else {
- return (
- <div className="pagination-page">
- <a href={pageUrlAt(basePath, page)}>{String(page)}</a>
- </div>
- );
- }
- })}
- <div className="pagination-next">
- {currentPage < totalPages
- ? (
- <a href={pageUrlAt(basePath, currentPage + 1)}>
- 次へ
- </a>
- )
- : null}
- </div>
- </nav>
- );
-}
-
-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/blog/nuldoc-src/components/PostPageEntry.tsx b/services/blog/nuldoc-src/components/PostPageEntry.tsx
deleted file mode 100644
index 23ca88a..0000000
--- a/services/blog/nuldoc-src/components/PostPageEntry.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import {
- getPostPublishedDate,
- getPostUpdatedDate,
- postHasAnyUpdates,
- PostPage,
-} from "../generators/post.ts";
-import { dateToString } from "../revision.ts";
-import { Config } from "../config.ts";
-import TagList from "./TagList.tsx";
-
-type Props = { post: PostPage; config: Config };
-
-export default function PostPageEntry({ post, config }: Props) {
- return (
- <article className="post-entry">
- <a href={post.href}>
- <header className="entry-header">
- <h2>{post.title}</h2>
- </header>
- <section className="entry-content">
- <p>{post.description}</p>
- </section>
- <footer className="entry-footer">
- <time datetime={dateToString(getPostPublishedDate(post))}>
- {dateToString(getPostPublishedDate(post))}
- </time>
- {" 投稿"}
- {
- // TODO(jsx): support Fragment and merge them.
- postHasAnyUpdates(post) && "、"
- }
- {postHasAnyUpdates(post) &&
- (
- <time datetime={dateToString(getPostUpdatedDate(post))}>
- {dateToString(getPostUpdatedDate(post))}
- </time>
- )}
- {postHasAnyUpdates(post) && " 更新"}
- {post.tags.length !== 0 && (
- <TagList tags={post.tags} config={config} />
- )}
- </footer>
- </a>
- </article>
- );
-}
diff --git a/services/blog/nuldoc-src/components/SlidePageEntry.tsx b/services/blog/nuldoc-src/components/SlidePageEntry.tsx
deleted file mode 100644
index 2401765..0000000
--- a/services/blog/nuldoc-src/components/SlidePageEntry.tsx
+++ /dev/null
@@ -1,46 +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 TagList from "./TagList.tsx";
-
-type Props = { slide: SlidePage; config: Config };
-
-export default function SlidePageEntry({ slide, config }: Props) {
- return (
- <article className="post-entry">
- <a href={slide.href}>
- <header className="entry-header">
- <h2>{slide.description}</h2>
- </header>
- <section className="entry-content">
- <p>{slide.title}</p>
- </section>
- <footer className="entry-footer">
- <time datetime={dateToString(getPostPublishedDate(slide))}>
- {dateToString(getPostPublishedDate(slide))}
- </time>
- {" 登壇"}
- {
- // TODO(jsx): support Fragment and merge them.
- postHasAnyUpdates(slide) && "、"
- }
- {postHasAnyUpdates(slide) &&
- (
- <time datetime={dateToString(getPostUpdatedDate(slide))}>
- {dateToString(getPostUpdatedDate(slide))}
- </time>
- )}
- {postHasAnyUpdates(slide) && " 更新"}
- {slide.tags.length !== 0 && (
- <TagList tags={slide.tags} config={config} />
- )}
- </footer>
- </a>
- </article>
- );
-}
diff --git a/services/blog/nuldoc-src/components/StaticScript.tsx b/services/blog/nuldoc-src/components/StaticScript.tsx
deleted file mode 100644
index 0e3ab19..0000000
--- a/services/blog/nuldoc-src/components/StaticScript.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import { join } from "@std/path";
-import { Config } from "../config.ts";
-import { calculateFileHash } from "./utils.ts";
-
-export default async function StaticScript(
- { fileName, type, defer, config }: {
- fileName: string;
- type?: string;
- defer?: "true";
- config: Config;
- },
-) {
- const filePath = join(Deno.cwd(), config.locations.staticDir, fileName);
- const hash = await calculateFileHash(filePath);
- return (
- <script src={`${fileName}?h=${hash}`} type={type} defer={defer}></script>
- );
-}
diff --git a/services/blog/nuldoc-src/components/StaticStylesheet.tsx b/services/blog/nuldoc-src/components/StaticStylesheet.tsx
deleted file mode 100644
index 52b695e..0000000
--- a/services/blog/nuldoc-src/components/StaticStylesheet.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import { join } from "@std/path";
-import { Config } from "../config.ts";
-import { calculateFileHash } from "./utils.ts";
-
-export default async function StaticStylesheet(
- { fileName, config }: { fileName: string; config: Config },
-) {
- const filePath = join(Deno.cwd(), config.locations.staticDir, fileName);
- const hash = await calculateFileHash(filePath);
- return <link rel="stylesheet" href={`${fileName}?h=${hash}`} />;
-}
diff --git a/services/blog/nuldoc-src/components/TableOfContents.tsx b/services/blog/nuldoc-src/components/TableOfContents.tsx
deleted file mode 100644
index 29907d0..0000000
--- a/services/blog/nuldoc-src/components/TableOfContents.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import { TocEntry, TocRoot } from "../djot/document.ts";
-
-type Props = {
- toc: TocRoot;
-};
-
-export default function TableOfContents({ toc }: Props) {
- return (
- <nav className="toc">
- <h2>目次</h2>
- <ul>
- {toc.entries.map((entry, index) => (
- <TocEntryComponent key={String(index)} entry={entry} />
- ))}
- </ul>
- </nav>
- );
-}
-
-function TocEntryComponent({ entry }: { entry: TocEntry }) {
- return (
- <li>
- <a href={`#${entry.id}`}>{entry.text}</a>
- {entry.children.length > 0 && (
- <ul>
- {entry.children.map((child, index) => (
- <TocEntryComponent key={String(index)} entry={child} />
- ))}
- </ul>
- )}
- </li>
- );
-}
diff --git a/services/blog/nuldoc-src/components/TagList.tsx b/services/blog/nuldoc-src/components/TagList.tsx
deleted file mode 100644
index 86ee70b..0000000
--- a/services/blog/nuldoc-src/components/TagList.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import { Config, getTagLabel } from "../config.ts";
-
-type Props = {
- tags: string[];
- config: Config;
-};
-
-export default function TagList({ tags, config }: Props) {
- return (
- <ul className="entry-tags">
- {tags.map((slug) => (
- <li className="tag" key={slug}>
- {getTagLabel(config, slug)}
- </li>
- ))}
- </ul>
- );
-}
diff --git a/services/blog/nuldoc-src/components/utils.ts b/services/blog/nuldoc-src/components/utils.ts
deleted file mode 100644
index 14059b5..0000000
--- a/services/blog/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();
-}