diff options
29 files changed, 404 insertions, 327 deletions
diff --git a/services/nuldoc/nuldoc-src/components/AboutGlobalHeader.ts b/services/nuldoc/nuldoc-src/components/AboutGlobalHeader.ts index b6ef84c..df43793 100644 --- a/services/nuldoc/nuldoc-src/components/AboutGlobalHeader.ts +++ b/services/nuldoc/nuldoc-src/components/AboutGlobalHeader.ts @@ -1,15 +1,12 @@ import { Config } from "../config.ts"; -import { elem, Element } from "../dom.ts"; +import { a, div, Element, header } from "../dom.ts"; export default function GlobalHeader({ config }: { config: Config }): Element { - return elem( - "header", + return header( { class: "header" }, - elem( - "div", + div( { class: "site-logo" }, - elem( - "a", + 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 index 034c2ab..ae0fc13 100644 --- a/services/nuldoc/nuldoc-src/components/BlogGlobalHeader.ts +++ b/services/nuldoc/nuldoc-src/components/BlogGlobalHeader.ts @@ -1,33 +1,27 @@ import { Config } from "../config.ts"; -import { elem, Element } from "../dom.ts"; +import { a, div, Element, header, li, nav, ul } from "../dom.ts"; export default function GlobalHeader({ config }: { config: Config }): Element { - return elem( - "header", + return header( { class: "header" }, - elem( - "div", + div( { class: "site-logo" }, - elem( - "a", + a( { href: `https://${config.sites.default.fqdn}/` }, "nsfisis.dev", ), ), - elem("div", { class: "site-name" }, config.sites.blog.siteName), - elem( - "nav", + div({ class: "site-name" }, config.sites.blog.siteName), + nav( { class: "nav" }, - elem( - "ul", + ul( {}, - elem( - "li", + li( {}, - elem("a", { href: `https://${config.sites.about.fqdn}/` }, "About"), + a({ href: `https://${config.sites.about.fqdn}/` }, "About"), ), - elem("li", {}, elem("a", { href: "/posts/" }, "Posts")), - elem("li", {}, elem("a", { href: "/tags/" }, "Tags")), + 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 index b6ef84c..df43793 100644 --- a/services/nuldoc/nuldoc-src/components/DefaultGlobalHeader.ts +++ b/services/nuldoc/nuldoc-src/components/DefaultGlobalHeader.ts @@ -1,15 +1,12 @@ import { Config } from "../config.ts"; -import { elem, Element } from "../dom.ts"; +import { a, div, Element, header } from "../dom.ts"; export default function GlobalHeader({ config }: { config: Config }): Element { - return elem( - "header", + return header( { class: "header" }, - elem( - "div", + div( { class: "site-logo" }, - elem( - "a", + 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 index 835d73f..313a01c 100644 --- a/services/nuldoc/nuldoc-src/components/GlobalFooter.ts +++ b/services/nuldoc/nuldoc-src/components/GlobalFooter.ts @@ -1,9 +1,8 @@ import { Config } from "../config.ts"; -import { elem, Element } from "../dom.ts"; +import { Element, footer } from "../dom.ts"; export default function GlobalFooter({ config }: { config: Config }): Element { - return elem( - "footer", + return footer( { class: "footer" }, `© ${config.site.copyrightYear} ${config.site.author}`, ); diff --git a/services/nuldoc/nuldoc-src/components/PageLayout.ts b/services/nuldoc/nuldoc-src/components/PageLayout.ts index 19a8e86..f970c0b 100644 --- a/services/nuldoc/nuldoc-src/components/PageLayout.ts +++ b/services/nuldoc/nuldoc-src/components/PageLayout.ts @@ -1,5 +1,5 @@ import { Config } from "../config.ts"; -import { elem, Element, Node } from "../dom.ts"; +import { elem, Element, link, meta, Node } from "../dom.ts"; import StaticStylesheet from "./StaticStylesheet.ts"; type Props = { @@ -33,37 +33,37 @@ export default async function PageLayout( elem( "head", {}, - elem("meta", { charset: "UTF-8" }), - elem("meta", { + meta({ charset: "UTF-8" }), + meta({ name: "viewport", content: "width=device-width, initial-scale=1.0", }), - elem("meta", { name: "author", content: config.site.author }), - elem("meta", { + meta({ name: "author", content: config.site.author }), + meta({ name: "copyright", content: `© ${metaCopyrightYear} ${config.site.author}`, }), - elem("meta", { name: "description", content: metaDescription }), + meta({ name: "description", content: metaDescription }), metaKeywords && metaKeywords.length !== 0 - ? elem("meta", { name: "keywords", content: metaKeywords.join(",") }) + ? meta({ name: "keywords", content: metaKeywords.join(",") }) : null, - elem("meta", { property: "og:type", content: "article" }), - elem("meta", { property: "og:title", content: metaTitle }), - elem("meta", { property: "og:description", content: metaDescription }), - elem("meta", { + 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, }), - elem("meta", { property: "og:locale", content: "ja_JP" }), - elem("meta", { name: "Hatena::Bookmark", content: "nocomment" }), + meta({ property: "og:locale", content: "ja_JP" }), + meta({ name: "Hatena::Bookmark", content: "nocomment" }), metaAtomFeedHref - ? elem("link", { + ? link({ rel: "alternate", href: metaAtomFeedHref, type: "application/atom+xml", }) : null, - elem("link", { + link({ rel: "icon", href: "/favicon.svg", type: "image/svg+xml", diff --git a/services/nuldoc/nuldoc-src/components/Pagination.ts b/services/nuldoc/nuldoc-src/components/Pagination.ts index 62e796b..d920316 100644 --- a/services/nuldoc/nuldoc-src/components/Pagination.ts +++ b/services/nuldoc/nuldoc-src/components/Pagination.ts @@ -1,4 +1,4 @@ -import { elem, Element } from "../dom.ts"; +import { a, div, Element, nav, span } from "../dom.ts"; type Props = { currentPage: number; @@ -10,43 +10,38 @@ export default function Pagination( { currentPage, totalPages, basePath }: Props, ): Element { if (totalPages <= 1) { - return elem("div", {}); + return div({}); } const pages = generatePageNumbers(currentPage, totalPages); - return elem( - "nav", + return nav( { class: "pagination" }, - elem( - "div", + div( { class: "pagination-prev" }, currentPage > 1 - ? elem("a", { href: pageUrlAt(basePath, currentPage - 1) }, "前へ") + ? a({ href: pageUrlAt(basePath, currentPage - 1) }, "前へ") : null, ), ...pages.map((page) => { if (page === "...") { - return elem("div", { class: "pagination-elipsis" }, "…"); + return div({ class: "pagination-elipsis" }, "…"); } else if (page === currentPage) { - return elem( - "div", + return div( { class: "pagination-page pagination-page-current" }, - elem("span", {}, String(page)), + span({}, String(page)), ); } else { - return elem( - "div", + return div( { class: "pagination-page" }, - elem("a", { href: pageUrlAt(basePath, page) }, String(page)), + a({ href: pageUrlAt(basePath, page) }, String(page)), ); } }), - elem( - "div", + div( { class: "pagination-next" }, currentPage < totalPages - ? elem("a", { href: pageUrlAt(basePath, currentPage + 1) }, "次へ") + ? a({ href: pageUrlAt(basePath, currentPage + 1) }, "次へ") : null, ), ); diff --git a/services/nuldoc/nuldoc-src/components/PostPageEntry.ts b/services/nuldoc/nuldoc-src/components/PostPageEntry.ts index 75ad11c..482a3a8 100644 --- a/services/nuldoc/nuldoc-src/components/PostPageEntry.ts +++ b/services/nuldoc/nuldoc-src/components/PostPageEntry.ts @@ -6,26 +6,32 @@ import { } from "../generators/post.ts"; import { dateToString } from "../revision.ts"; import { Config } from "../config.ts"; -import { elem, Element } from "../dom.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 elem( - "article", + return article( { class: "post-entry" }, - elem( - "a", + a( { href: post.href }, - elem("header", { class: "entry-header" }, elem("h2", {}, post.title)), - elem( - "section", + header({ class: "entry-header" }, h2({}, post.title)), + section( { class: "entry-content" }, - elem("p", {}, post.description), + p({}, post.description), ), - elem( - "footer", + footer( { class: "entry-footer" }, elem( "time", diff --git a/services/nuldoc/nuldoc-src/components/SlidePageEntry.ts b/services/nuldoc/nuldoc-src/components/SlidePageEntry.ts index 1dc5f1a..f14a537 100644 --- a/services/nuldoc/nuldoc-src/components/SlidePageEntry.ts +++ b/services/nuldoc/nuldoc-src/components/SlidePageEntry.ts @@ -6,26 +6,32 @@ import { import { SlidePage } from "../generators/slide.ts"; import { dateToString } from "../revision.ts"; import { Config } from "../config.ts"; -import { elem, Element } from "../dom.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 elem( - "article", + return article( { class: "post-entry" }, - elem( - "a", + a( { href: slide.href }, - elem( - "header", + header( { class: "entry-header" }, - elem("h2", {}, slide.description), + h2({}, slide.description), ), - elem("section", { class: "entry-content" }, elem("p", {}, slide.title)), - elem( - "footer", + section({ class: "entry-content" }, p({}, slide.title)), + footer( { class: "entry-footer" }, elem( "time", diff --git a/services/nuldoc/nuldoc-src/components/SlidesGlobalHeader.ts b/services/nuldoc/nuldoc-src/components/SlidesGlobalHeader.ts index 902e12f..666ca0e 100644 --- a/services/nuldoc/nuldoc-src/components/SlidesGlobalHeader.ts +++ b/services/nuldoc/nuldoc-src/components/SlidesGlobalHeader.ts @@ -1,32 +1,26 @@ import { Config } from "../config.ts"; -import { elem, Element } from "../dom.ts"; +import { a, div, Element, header, li, nav, ul } from "../dom.ts"; export default function GlobalHeader({ config }: { config: Config }): Element { - return elem( - "header", + return header( { class: "header" }, - elem( - "div", + div( { class: "site-logo" }, - elem( - "a", + a( { href: `https://${config.sites.default.fqdn}/` }, "nsfisis.dev", ), ), - elem( - "nav", + nav( { class: "nav" }, - elem( - "ul", + ul( {}, - elem( - "li", + li( {}, - elem("a", { href: `https://${config.sites.about.fqdn}/` }, "About"), + a({ href: `https://${config.sites.about.fqdn}/` }, "About"), ), - elem("li", {}, elem("a", { href: "/slides/" }, "Slides")), - elem("li", {}, elem("a", { href: "/tags/" }, "Tags")), + 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 index 7df40fd..b8dc95d 100644 --- a/services/nuldoc/nuldoc-src/components/StaticScript.ts +++ b/services/nuldoc/nuldoc-src/components/StaticScript.ts @@ -1,6 +1,6 @@ import { join } from "@std/path"; import { Config } from "../config.ts"; -import { elem, Element } from "../dom.ts"; +import { Element, script } from "../dom.ts"; import { calculateFileHash } from "./utils.ts"; export default async function StaticScript( @@ -16,5 +16,5 @@ export default async function StaticScript( const attrs: Record<string, string> = { src: `${fileName}?h=${hash}` }; if (type) attrs.type = type; if (defer) attrs.defer = defer; - return elem("script", attrs); + return script(attrs); } diff --git a/services/nuldoc/nuldoc-src/components/StaticStylesheet.ts b/services/nuldoc/nuldoc-src/components/StaticStylesheet.ts index 43802d2..065ee20 100644 --- a/services/nuldoc/nuldoc-src/components/StaticStylesheet.ts +++ b/services/nuldoc/nuldoc-src/components/StaticStylesheet.ts @@ -1,6 +1,6 @@ import { join } from "@std/path"; import { Config } from "../config.ts"; -import { elem, Element } from "../dom.ts"; +import { Element, link } from "../dom.ts"; import { calculateFileHash } from "./utils.ts"; export default async function StaticStylesheet( @@ -8,5 +8,5 @@ export default async function StaticStylesheet( ): Promise<Element> { const filePath = join(Deno.cwd(), config.locations.staticDir, fileName); const hash = await calculateFileHash(filePath); - return elem("link", { rel: "stylesheet", href: `${fileName}?h=${hash}` }); + 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 index 37796ff..1eb79e9 100644 --- a/services/nuldoc/nuldoc-src/components/TableOfContents.ts +++ b/services/nuldoc/nuldoc-src/components/TableOfContents.ts @@ -1,17 +1,15 @@ import { TocEntry, TocRoot } from "../markdown/document.ts"; -import { elem, Element } from "../dom.ts"; +import { a, Element, h2, li, nav, ul } from "../dom.ts"; type Props = { toc: TocRoot; }; export default function TableOfContents({ toc }: Props): Element { - return elem( - "nav", + return nav( { class: "toc" }, - elem("h2", {}, "目次"), - elem( - "ul", + h2({}, "目次"), + ul( {}, ...toc.entries.map((entry) => TocEntryComponent({ entry })), ), @@ -19,13 +17,11 @@ export default function TableOfContents({ toc }: Props): Element { } function TocEntryComponent({ entry }: { entry: TocEntry }): Element { - return elem( - "li", + return li( {}, - elem("a", { href: `#${entry.id}` }, entry.text), + a({ href: `#${entry.id}` }, entry.text), entry.children.length > 0 - ? elem( - "ul", + ? ul( {}, ...entry.children.map((child) => TocEntryComponent({ entry: child })), ) diff --git a/services/nuldoc/nuldoc-src/components/TagList.ts b/services/nuldoc/nuldoc-src/components/TagList.ts index 540abe6..7260c53 100644 --- a/services/nuldoc/nuldoc-src/components/TagList.ts +++ b/services/nuldoc/nuldoc-src/components/TagList.ts @@ -1,5 +1,5 @@ import { Config, getTagLabel } from "../config.ts"; -import { elem, Element, text } from "../dom.ts"; +import { Element, li, text, ul } from "../dom.ts"; type Props = { tags: string[]; @@ -7,11 +7,10 @@ type Props = { }; export default function TagList({ tags, config }: Props): Element { - return elem( - "ul", + return ul( { class: "entry-tags" }, ...tags.map((slug) => - elem("li", { class: "tag" }, text(getTagLabel(config, slug))) + li({ class: "tag" }, text(getTagLabel(config, slug))) ), ); } diff --git a/services/nuldoc/nuldoc-src/config.ts b/services/nuldoc/nuldoc-src/config.ts index 95d7941..267a8f9 100644 --- a/services/nuldoc/nuldoc-src/config.ts +++ b/services/nuldoc/nuldoc-src/config.ts @@ -8,11 +8,6 @@ const ConfigSchema = z.object({ destDir: z.string(), staticDir: z.string(), }), - rendering: z.object({ - html: z.object({ - indentWidth: z.number(), - }), - }), site: z.object({ author: z.string(), copyrightYear: z.number(), @@ -29,25 +24,23 @@ const ConfigSchema = z.object({ blog: z.object({ fqdn: z.string(), siteName: z.string(), + postsPerPage: z.number(), }), slides: z.object({ fqdn: z.string(), siteName: z.string(), }), }), - blog: z.object({ - postsPerPage: z.number().default(10), - tagLabels: z.record(z.string(), z.string()), - }), + tagLabels: z.record(z.string(), z.string()), }); export type Config = z.infer<typeof ConfigSchema>; export function getTagLabel(c: Config, slug: string): string { - if (!(slug in c.blog.tagLabels)) { + if (!(slug in c.tagLabels)) { throw new Error(`Unknown tag: ${slug}`); } - return c.blog.tagLabels[slug]; + return c.tagLabels[slug]; } export function getDefaultConfigPath(): string { diff --git a/services/nuldoc/nuldoc-src/dom.ts b/services/nuldoc/nuldoc-src/dom.ts index be503a3..5faf184 100644 --- a/services/nuldoc/nuldoc-src/dom.ts +++ b/services/nuldoc/nuldoc-src/dom.ts @@ -63,6 +63,116 @@ export function elem( }; } +// Helper functions for commonly used elements +export const a = ( + attributes?: Record<string, string>, + ...children: NodeLike[] +) => elem("a", attributes, ...children); + +export const article = ( + attributes?: Record<string, string>, + ...children: NodeLike[] +) => elem("article", attributes, ...children); + +export const button = ( + attributes?: Record<string, string>, + ...children: NodeLike[] +) => elem("button", attributes, ...children); + +export const div = ( + attributes?: Record<string, string>, + ...children: NodeLike[] +) => elem("div", attributes, ...children); + +export const footer = ( + attributes?: Record<string, string>, + ...children: NodeLike[] +) => elem("footer", attributes, ...children); + +export const h1 = ( + attributes?: Record<string, string>, + ...children: NodeLike[] +) => elem("h1", attributes, ...children); + +export const h2 = ( + attributes?: Record<string, string>, + ...children: NodeLike[] +) => elem("h2", attributes, ...children); + +export const h3 = ( + attributes?: Record<string, string>, + ...children: NodeLike[] +) => elem("h3", attributes, ...children); + +export const h4 = ( + attributes?: Record<string, string>, + ...children: NodeLike[] +) => elem("h4", attributes, ...children); + +export const h5 = ( + attributes?: Record<string, string>, + ...children: NodeLike[] +) => elem("h5", attributes, ...children); + +export const h6 = ( + attributes?: Record<string, string>, + ...children: NodeLike[] +) => elem("h6", attributes, ...children); + +export const header = ( + attributes?: Record<string, string>, + ...children: NodeLike[] +) => elem("header", attributes, ...children); + +export const img = (attributes?: Record<string, string>) => + elem("img", attributes); + +export const li = ( + attributes?: Record<string, string>, + ...children: NodeLike[] +) => elem("li", attributes, ...children); + +export const link = (attributes?: Record<string, string>) => + elem("link", attributes); + +export const meta = (attributes?: Record<string, string>) => + elem("meta", attributes); + +export const nav = ( + attributes?: Record<string, string>, + ...children: NodeLike[] +) => elem("nav", attributes, ...children); + +export const ol = ( + attributes?: Record<string, string>, + ...children: NodeLike[] +) => elem("ol", attributes, ...children); + +export const p = ( + attributes?: Record<string, string>, + ...children: NodeLike[] +) => elem("p", attributes, ...children); + +export const script = ( + attributes?: Record<string, string>, + ...children: NodeLike[] +) => elem("script", attributes, ...children); + +export const section = ( + attributes?: Record<string, string>, + ...children: NodeLike[] +) => elem("section", attributes, ...children); + +export const span = ( + attributes?: Record<string, string>, + ...children: NodeLike[] +) => elem("span", attributes, ...children); + +export const ul = ( + attributes?: Record<string, string>, + ...children: NodeLike[] +) => elem("ul", attributes, ...children); + export function addClass(e: Element, klass: string) { const classes = e.attributes.class; if (classes === undefined) { diff --git a/services/nuldoc/nuldoc-src/generators/post_list.ts b/services/nuldoc/nuldoc-src/generators/post_list.ts index cb3d5c8..3be4ec0 100644 --- a/services/nuldoc/nuldoc-src/generators/post_list.ts +++ b/services/nuldoc/nuldoc-src/generators/post_list.ts @@ -9,7 +9,7 @@ export async function generatePostListPages( posts: PostPage[], config: Config, ): Promise<PostListPage[]> { - const postsPerPage = config.blog.postsPerPage; + const postsPerPage = config.sites.blog.postsPerPage; const totalPages = Math.ceil(posts.length / postsPerPage); const pages: PostListPage[] = []; diff --git a/services/nuldoc/nuldoc-src/markdown/mdast2ndoc.ts b/services/nuldoc/nuldoc-src/markdown/mdast2ndoc.ts index 367627c..626f119 100644 --- a/services/nuldoc/nuldoc-src/markdown/mdast2ndoc.ts +++ b/services/nuldoc/nuldoc-src/markdown/mdast2ndoc.ts @@ -29,7 +29,23 @@ import type { LeafDirective, TextDirective, } from "mdast-util-directive"; -import { elem, Element, Node, rawHTML, text } from "../dom.ts"; +import { + a, + article, + div, + elem, + Element, + img, + li, + Node, + ol, + p, + rawHTML, + section, + span, + text, + ul, +} from "../dom.ts"; type DirectiveNode = ContainerDirective | LeafDirective | TextDirective; @@ -118,7 +134,7 @@ function processBlock(node: RootContent): Element | Element[] | null { } function processParagraph(node: Paragraph): Element { - return elem("p", {}, ...node.children.map(processInline)); + return p({}, ...node.children.map(processInline)); } function processThematicBreak(_node: ThematicBreak): Element { @@ -182,7 +198,9 @@ function processList(node: List): Element { processListItem(item, isTaskList) ); - return elem(node.ordered ? "ol" : "ul", attributes, ...children); + return node.ordered + ? ol(attributes, ...children) + : ul(attributes, ...children); } function processListItem(node: ListItem, isTaskList: boolean): Element { @@ -204,7 +222,7 @@ function processListItem(node: ListItem, isTaskList: boolean): Element { } } - return elem("li", attributes, ...children); + return li(attributes, ...children); } function processTable(node: Table): Element { @@ -261,7 +279,7 @@ function processTableCell( } function processHtmlBlock(node: Html): Element { - return elem("div", { class: "raw-html" }, rawHTML(node.value)); + return div({ class: "raw-html" }, rawHTML(node.value)); } function processDefinition(_node: Definition): null { @@ -331,8 +349,7 @@ function processDirective(node: DirectiveNode): Element | null { } } - return elem( - "div", + return div( node.attributes as Record<string, string> || {}, ...children, ); @@ -366,8 +383,7 @@ function processInline(node: PhrasingContent): Node { return text(String(node.value)); } if ("children" in node && Array.isArray(node.children)) { - return elem( - "span", + return span( {}, ...node.children.map((c: PhrasingContent) => processInline(c)), ); @@ -407,7 +423,7 @@ function processLink(node: Link): Element { if (isAutolink) { attributes.class = "url"; } - return elem("a", attributes, ...node.children.map(processInline)); + return a(attributes, ...node.children.map(processInline)); } function processImage(node: Image): Element { @@ -421,7 +437,7 @@ function processImage(node: Image): Element { if (node.title) { attributes.title = node.title; } - return elem("img", attributes); + return img(attributes); } function processDelete(node: Delete): Element { @@ -453,8 +469,7 @@ export function mdast2ndoc(root: Root): Element { // Add footnotes section if any exist if (footnotes.length > 0) { - const footnoteSection = elem( - "section", + const footnoteSection = section( { class: "footnotes" }, ...footnotes, ); @@ -464,7 +479,7 @@ export function mdast2ndoc(root: Root): Element { return elem( "__root__", undefined, - elem("article", undefined, ...articleContent), + article(undefined, ...articleContent), ); } @@ -566,8 +581,7 @@ function createSectionElement(sectionInfo: SectionInfo): Element { attributes.id = sectionInfo.id; } - return elem( - "section", + return section( attributes, sectionInfo.heading, ...sectionInfo.children, diff --git a/services/nuldoc/nuldoc-src/markdown/to_html.ts b/services/nuldoc/nuldoc-src/markdown/to_html.ts index 8219b74..8758b0d 100644 --- a/services/nuldoc/nuldoc-src/markdown/to_html.ts +++ b/services/nuldoc/nuldoc-src/markdown/to_html.ts @@ -2,8 +2,9 @@ import { BundledLanguage, bundledLanguages, codeToHtml } from "shiki"; import { Document, TocEntry } from "./document.ts"; import { NuldocError } from "../errors.ts"; import { + a, addClass, - elem, + div, Element, forEachChild, forEachChildRecursively, @@ -115,7 +116,7 @@ function transformLinkLikeToAnchorElement(doc: Document) { } const [_, prefix, url, suffix] = match; nodes.push(text(prefix)); - nodes.push(elem("a", { href: url, class: "url" }, text(url))); + nodes.push(a({ href: url, class: "url" }, text(url))); restContent = suffix; } return nodes; @@ -188,7 +189,7 @@ function setSectionTitleAnchor(doc: Document) { ); } const sectionId = currentSection.attributes.id; - const aElement = elem("a", undefined, ...c.children); + const aElement = a(undefined, ...c.children); aElement.attributes.href = `#${sectionId}`; c.children = [aElement]; } @@ -224,13 +225,11 @@ function transformNoteElement(doc: Document) { const operationAttr = n.attributes?.operation; const isEditBlock = editatAttr && operationAttr; - const labelElement = elem( - "div", + const labelElement = div( { class: "admonition-label" }, text(isEditBlock ? `${editatAttr} ${operationAttr}` : "NOTE"), ); - const contentElement = elem( - "div", + const contentElement = div( { class: "admonition-content" }, ...n.children, ); @@ -273,8 +272,7 @@ function traverseFootnotes(doc: Document) { delete n.attributes.reference; n.attributes.class = "footnote"; n.children = [ - elem( - "a", + a( { id: `footnoteref--${reference}`, class: "footnote", @@ -301,8 +299,7 @@ function traverseFootnotes(doc: Document) { n.attributes.id = `footnote--${id}`; n.children = [ - elem( - "a", + a( { href: `#footnoteref--${id}` }, text(`${footnoteNumber}. `), ), @@ -373,7 +370,7 @@ async function transformAndHighlightCodeBlockElement(doc: Document) { delete n.attributes.filename; n.children = [ - elem("div", { class: "filename" }, text(filename)), + div({ class: "filename" }, text(filename)), rawHTML(highlighted), ]; } else { diff --git a/services/nuldoc/nuldoc-src/pages/AboutPage.ts b/services/nuldoc/nuldoc-src/pages/AboutPage.ts index 43e239e..65a503d 100644 --- a/services/nuldoc/nuldoc-src/pages/AboutPage.ts +++ b/services/nuldoc/nuldoc-src/pages/AboutPage.ts @@ -6,7 +6,21 @@ import { Config } from "../config.ts"; import { dateToString } from "../revision.ts"; import { getPostPublishedDate } from "../generators/post.ts"; import { SlidePage } from "../generators/slide.ts"; -import { elem, Element } from "../dom.ts"; +import { + a, + article, + div, + elem, + Element, + h1, + h2, + header, + img, + li, + p, + section, + ul, +} from "../dom.ts"; export default async function AboutPage( slides: SlidePage[], @@ -25,20 +39,16 @@ export default async function AboutPage( elem( "main", { class: "main" }, - elem( - "article", + article( { class: "post-single" }, - elem( - "header", + header( { class: "post-header" }, - elem("h1", { class: "post-title" }, "nsfisis"), - elem( - "div", + h1({ class: "post-title" }, "nsfisis"), + div( { class: "my-icon" }, - elem( - "div", + div( { id: "myIcon" }, - elem("img", { src: "/favicon.svg" }), + img({ src: "/favicon.svg" }), ), await StaticScript({ fileName: "/my-icon.js", @@ -47,31 +57,24 @@ export default async function AboutPage( }), ), ), - elem( - "div", + div( { class: "post-content" }, - elem( - "section", + section( {}, - elem("h2", {}, "読み方"), - elem( - "p", + h2({}, "読み方"), + p( {}, "読み方は決めていません。音にする必要があるときは本名である「いまむら」をお使いください。", ), ), - elem( - "section", + section( {}, - elem("h2", {}, "アカウント"), - elem( - "ul", + h2({}, "アカウント"), + ul( {}, - elem( - "li", + li( {}, - elem( - "a", + a( { href: "https://twitter.com/nsfisis", target: "_blank", @@ -80,11 +83,9 @@ export default async function AboutPage( "Twitter (現 𝕏): @nsfisis", ), ), - elem( - "li", + li( {}, - elem( - "a", + a( { href: "https://github.com/nsfisis", target: "_blank", @@ -95,19 +96,15 @@ export default async function AboutPage( ), ), ), - elem( - "section", + section( {}, - elem("h2", {}, "仕事"), - elem( - "ul", + h2({}, "仕事"), + ul( {}, - elem( - "li", + li( {}, "2021-01~現在: ", - elem( - "a", + a( { href: "https://www.dgcircus.com/", target: "_blank", @@ -118,27 +115,23 @@ export default async function AboutPage( ), ), ), - elem( - "section", + section( {}, - elem("h2", {}, "登壇"), - elem( - "ul", + h2({}, "登壇"), + ul( {}, ...Array.from(slides) - .sort((a, b) => { - const ta = dateToString(getPostPublishedDate(a)); - const tb = dateToString(getPostPublishedDate(b)); + .sort((s1, s2) => { + const ta = dateToString(getPostPublishedDate(s1)); + const tb = dateToString(getPostPublishedDate(s2)); if (ta > tb) return -1; if (ta < tb) return 1; return 0; }) .map((slide) => - elem( - "li", + li( {}, - elem( - "a", + a( { href: `https://${config.sites.slides.fqdn}${slide.href}`, diff --git a/services/nuldoc/nuldoc-src/pages/AtomPage.ts b/services/nuldoc/nuldoc-src/pages/AtomPage.ts index f270972..b39902e 100644 --- a/services/nuldoc/nuldoc-src/pages/AtomPage.ts +++ b/services/nuldoc/nuldoc-src/pages/AtomPage.ts @@ -1,5 +1,5 @@ import { Feed } from "../generators/atom.ts"; -import { elem, Element } from "../dom.ts"; +import { elem, Element, link } from "../dom.ts"; export default function AtomPage({ feed }: { feed: Feed }): Element { return elem( @@ -7,8 +7,8 @@ export default function AtomPage({ feed }: { feed: Feed }): Element { { xmlns: "http://www.w3.org/2005/Atom" }, elem("id", {}, feed.id), elem("title", {}, feed.title), - elem("link", { rel: "alternate", href: feed.linkToAlternate }), - elem("link", { rel: "self", href: feed.linkToSelf }), + link({ rel: "alternate", href: feed.linkToAlternate }), + link({ rel: "self", href: feed.linkToSelf }), elem("author", {}, elem("name", {}, feed.author)), elem("updated", {}, feed.updated), ...feed.entries.map((entry) => @@ -16,7 +16,7 @@ export default function AtomPage({ feed }: { feed: Feed }): Element { "entry", {}, elem("id", {}, entry.id), - elem("link", { rel: "alternate", href: entry.linkToAlternate }), + link({ rel: "alternate", href: entry.linkToAlternate }), elem("title", {}, entry.title), elem("summary", {}, entry.summary), elem("published", {}, entry.published), diff --git a/services/nuldoc/nuldoc-src/pages/HomePage.ts b/services/nuldoc/nuldoc-src/pages/HomePage.ts index 503a382..6e98458 100644 --- a/services/nuldoc/nuldoc-src/pages/HomePage.ts +++ b/services/nuldoc/nuldoc-src/pages/HomePage.ts @@ -2,7 +2,7 @@ import GlobalFooter from "../components/GlobalFooter.ts"; import GlobalHeader from "../components/DefaultGlobalHeader.ts"; import PageLayout from "../components/PageLayout.ts"; import { Config } from "../config.ts"; -import { elem, Element } from "../dom.ts"; +import { a, article, elem, Element, h2, header } from "../dom.ts"; export default async function HomePage(config: Config): Promise<Element> { return await PageLayout({ @@ -19,54 +19,42 @@ export default async function HomePage(config: Config): Promise<Element> { elem( "main", { class: "main" }, - elem( - "article", + article( { class: "post-single" }, - elem( - "article", + article( { class: "post-entry" }, - elem( - "a", + a( { href: `https://${config.sites.about.fqdn}/` }, - elem( - "header", + header( { class: "entry-header" }, - elem("h2", {}, "About"), + h2({}, "About"), ), ), ), - elem( - "article", + article( { class: "post-entry" }, - elem( - "a", + a( { href: `https://${config.sites.blog.fqdn}/posts/` }, - elem("header", { class: "entry-header" }, elem("h2", {}, "Blog")), + header({ class: "entry-header" }, h2({}, "Blog")), ), ), - elem( - "article", + article( { class: "post-entry" }, - elem( - "a", + a( { href: `https://${config.sites.slides.fqdn}/slides/` }, - elem( - "header", + header( { class: "entry-header" }, - elem("h2", {}, "Slides"), + h2({}, "Slides"), ), ), ), - elem( - "article", + article( { class: "post-entry" }, - elem( - "a", + a( { href: `https://repos.${config.sites.default.fqdn}/` }, - elem( - "header", + header( { class: "entry-header" }, - elem("h2", {}, "Repositories"), + h2({}, "Repositories"), ), ), ), diff --git a/services/nuldoc/nuldoc-src/pages/NotFoundPage.ts b/services/nuldoc/nuldoc-src/pages/NotFoundPage.ts index 34854c4..6208066 100644 --- a/services/nuldoc/nuldoc-src/pages/NotFoundPage.ts +++ b/services/nuldoc/nuldoc-src/pages/NotFoundPage.ts @@ -5,7 +5,7 @@ import SlidesGlobalHeader from "../components/SlidesGlobalHeader.ts"; import DefaultGlobalHeader from "../components/DefaultGlobalHeader.ts"; import PageLayout from "../components/PageLayout.ts"; import { Config } from "../config.ts"; -import { elem, Element } from "../dom.ts"; +import { article, div, elem, Element } from "../dom.ts"; export default async function NotFoundPage( site: "default" | "about" | "blog" | "slides", @@ -32,7 +32,7 @@ export default async function NotFoundPage( elem( "main", { class: "main" }, - elem("article", {}, elem("div", { class: "not-found" }, "404")), + article({}, div({ class: "not-found" }, "404")), ), GlobalFooter({ config }), ), diff --git a/services/nuldoc/nuldoc-src/pages/PostListPage.ts b/services/nuldoc/nuldoc-src/pages/PostListPage.ts index 53b8fa4..ef7bfc5 100644 --- a/services/nuldoc/nuldoc-src/pages/PostListPage.ts +++ b/services/nuldoc/nuldoc-src/pages/PostListPage.ts @@ -5,7 +5,7 @@ import Pagination from "../components/Pagination.ts"; import PostPageEntry from "../components/PostPageEntry.ts"; import { Config } from "../config.ts"; import { PostPage } from "../generators/post.ts"; -import { elem, Element } from "../dom.ts"; +import { elem, Element, h1, header } from "../dom.ts"; export default async function PostListPage( posts: PostPage[], @@ -34,10 +34,9 @@ export default async function PostListPage( elem( "main", { class: "main" }, - elem( - "header", + header( { class: "page-header" }, - elem("h1", {}, pageTitle + pageInfoSuffix), + h1({}, pageTitle + pageInfoSuffix), ), Pagination({ currentPage, totalPages, basePath: "/posts/" }), ...posts.map((post) => PostPageEntry({ post, config })), diff --git a/services/nuldoc/nuldoc-src/pages/PostPage.ts b/services/nuldoc/nuldoc-src/pages/PostPage.ts index fe67089..3b163d1 100644 --- a/services/nuldoc/nuldoc-src/pages/PostPage.ts +++ b/services/nuldoc/nuldoc-src/pages/PostPage.ts @@ -3,7 +3,20 @@ import GlobalHeader from "../components/BlogGlobalHeader.ts"; import PageLayout from "../components/PageLayout.ts"; import TableOfContents from "../components/TableOfContents.ts"; import { Config, getTagLabel } from "../config.ts"; -import { elem, Element } from "../dom.ts"; +import { + a, + article, + div, + elem, + Element, + h1, + h2, + header, + li, + ol, + section, + ul, +} from "../dom.ts"; import { Document } from "../markdown/document.ts"; import { dateToString } from "../revision.ts"; import { getPostPublishedDate } from "../generators/post.ts"; @@ -27,23 +40,18 @@ export default async function PostPage( elem( "main", { class: "main" }, - elem( - "article", + article( { class: "post-single" }, - elem( - "header", + header( { class: "post-header" }, - elem("h1", { class: "post-title" }, doc.title), + h1({ class: "post-title" }, doc.title), doc.tags.length !== 0 - ? elem( - "ul", + ? ul( { class: "post-tags" }, ...doc.tags.map((slug) => - elem( - "li", + li( { class: "tag" }, - elem( - "a", + a( { href: `/tags/${slug}/` }, getTagLabel(config, slug), ), @@ -55,19 +63,15 @@ export default async function PostPage( doc.toc && doc.toc.entries.length > 0 ? TableOfContents({ toc: doc.toc }) : null, - elem( - "div", + div( { class: "post-content" }, - elem( - "section", + section( { id: "changelog" }, - elem("h2", {}, elem("a", { href: "#changelog" }, "更新履歴")), - elem( - "ol", + h2({}, a({ href: "#changelog" }, "更新履歴")), + ol( {}, ...doc.revisions.map((rev) => - elem( - "li", + li( { class: "revision" }, elem( "time", diff --git a/services/nuldoc/nuldoc-src/pages/SlideListPage.ts b/services/nuldoc/nuldoc-src/pages/SlideListPage.ts index 9a1c2b2..f1b1a2a 100644 --- a/services/nuldoc/nuldoc-src/pages/SlideListPage.ts +++ b/services/nuldoc/nuldoc-src/pages/SlideListPage.ts @@ -6,7 +6,7 @@ import { Config } from "../config.ts"; import { dateToString } from "../revision.ts"; import { getPostPublishedDate } from "../generators/post.ts"; import { SlidePage } from "../generators/slide.ts"; -import { elem, Element } from "../dom.ts"; +import { elem, Element, h1, header } from "../dom.ts"; export default async function SlideListPage( slides: SlidePage[], @@ -28,11 +28,11 @@ export default async function SlideListPage( elem( "main", { class: "main" }, - elem("header", { class: "page-header" }, elem("h1", {}, pageTitle)), + header({ class: "page-header" }, h1({}, pageTitle)), ...Array.from(slides) - .sort((a, b) => { - const ta = dateToString(getPostPublishedDate(a)); - const tb = dateToString(getPostPublishedDate(b)); + .sort((s1, s2) => { + const ta = dateToString(getPostPublishedDate(s1)); + const tb = dateToString(getPostPublishedDate(s2)); if (ta > tb) return -1; if (ta < tb) return 1; return 0; diff --git a/services/nuldoc/nuldoc-src/pages/SlidePage.ts b/services/nuldoc/nuldoc-src/pages/SlidePage.ts index 8699134..1c6709c 100644 --- a/services/nuldoc/nuldoc-src/pages/SlidePage.ts +++ b/services/nuldoc/nuldoc-src/pages/SlidePage.ts @@ -6,7 +6,21 @@ import { Config, getTagLabel } from "../config.ts"; import { dateToString } from "../revision.ts"; import { Slide } from "../slide/slide.ts"; import { getPostPublishedDate } from "../generators/post.ts"; -import { elem, Element } from "../dom.ts"; +import { + a, + article, + button, + div, + elem, + Element, + h1, + h2, + header, + li, + ol, + section, + ul, +} from "../dom.ts"; export default async function SlidePage( slide: Slide, @@ -28,23 +42,18 @@ export default async function SlidePage( elem( "main", { class: "main" }, - elem( - "article", + article( { class: "post-single" }, - elem( - "header", + header( { class: "post-header" }, - elem("h1", { class: "post-title" }, slide.title), + h1({ class: "post-title" }, slide.title), slide.tags.length !== 0 - ? elem( - "ul", + ? ul( { class: "post-tags" }, ...slide.tags.map((slug) => - elem( - "li", + li( { class: "tag" }, - elem( - "a", + a( { href: `/tags/${slug}/` }, getTagLabel(config, slug), ), @@ -53,19 +62,15 @@ export default async function SlidePage( ) : null, ), - elem( - "div", + div( { class: "post-content" }, - elem( - "section", + section( { id: "changelog" }, - elem("h2", {}, elem("a", { href: "#changelog" }, "更新履歴")), - elem( - "ol", + h2({}, a({ href: "#changelog" }, "更新履歴")), + ol( {}, ...slide.revisions.map((rev) => - elem( - "li", + li( { class: "revision" }, elem( "time", @@ -78,11 +83,10 @@ export default async function SlidePage( ), ), elem("canvas", { id: "slide", "data-slide-link": slide.slideLink }), - elem( - "div", + div( {}, - elem("button", { id: "prev", type: "button" }, "Prev"), - elem("button", { id: "next", type: "button" }, "Next"), + button({ id: "prev", type: "button" }, "Prev"), + button({ id: "next", type: "button" }, "Next"), ), await StaticScript({ fileName: "/slide.js", diff --git a/services/nuldoc/nuldoc-src/pages/TagListPage.ts b/services/nuldoc/nuldoc-src/pages/TagListPage.ts index 6872a2f..cf1ec51 100644 --- a/services/nuldoc/nuldoc-src/pages/TagListPage.ts +++ b/services/nuldoc/nuldoc-src/pages/TagListPage.ts @@ -4,7 +4,7 @@ import SlidesGlobalHeader from "../components/SlidesGlobalHeader.ts"; import PageLayout from "../components/PageLayout.ts"; import { Config } from "../config.ts"; import { TagPage } from "../generators/tag.ts"; -import { elem, Element } from "../dom.ts"; +import { a, article, elem, Element, footer, h1, h2, header } from "../dom.ts"; export default async function TagListPage( tags: TagPage[], @@ -28,11 +28,11 @@ export default async function TagListPage( elem( "main", { class: "main" }, - elem("header", { class: "page-header" }, elem("h1", {}, pageTitle)), + header({ class: "page-header" }, h1({}, pageTitle)), ...Array.from(tags) - .sort((a, b) => { - const ta = a.tagSlug; - const tb = b.tagSlug; + .sort((t1, t2) => { + const ta = t1.tagSlug; + const tb = t2.tagSlug; if (ta < tb) return -1; if (ta > tb) return 1; return 0; @@ -48,18 +48,15 @@ export default async function TagListPage( posts && slides ? "、" : "" }${slides}`; - return elem( - "article", + return article( { class: "post-entry" }, - elem( - "a", + a( { href: tag.href }, - elem( - "header", + header( { class: "entry-header" }, - elem("h2", {}, tag.tagLabel), + h2({}, tag.tagLabel), ), - elem("footer", { class: "entry-footer" }, footerText), + footer({ class: "entry-footer" }, footerText), ), ); }), diff --git a/services/nuldoc/nuldoc-src/pages/TagPage.ts b/services/nuldoc/nuldoc-src/pages/TagPage.ts index 408f0b4..1826219 100644 --- a/services/nuldoc/nuldoc-src/pages/TagPage.ts +++ b/services/nuldoc/nuldoc-src/pages/TagPage.ts @@ -7,7 +7,7 @@ import SlidePageEntry from "../components/SlidePageEntry.ts"; import { Config, getTagLabel } from "../config.ts"; import { getPostPublishedDate } from "../generators/post.ts"; import { TaggedPage } from "../generators/tagged_page.ts"; -import { elem, Element } from "../dom.ts"; +import { elem, Element, h1, header } from "../dom.ts"; export default async function TagPage( tagSlug: string, @@ -37,7 +37,7 @@ export default async function TagPage( elem( "main", { class: "main" }, - elem("header", { class: "page-header" }, elem("h1", {}, pageTitle)), + header({ class: "page-header" }, h1({}, pageTitle)), ...pages.map((page) => "event" in page ? SlidePageEntry({ slide: page, config }) diff --git a/services/nuldoc/nuldoc.toml b/services/nuldoc/nuldoc.toml index 8640a74..568e0cf 100644 --- a/services/nuldoc/nuldoc.toml +++ b/services/nuldoc/nuldoc.toml @@ -3,9 +3,6 @@ contentDir = "/content" destDir = "/public" staticDir = "/static" -[rendering.html] -indentWidth = 2 - [site] author = "nsfisis" copyrightYear = 2021 @@ -21,15 +18,13 @@ siteName = "nsfisis.dev" [sites.blog] fqdn = "blog.nsfisis.dev" siteName = "REPL: Rest-Eat-Program Loop" +postsPerPage = 10 [sites.slides] fqdn = "slides.nsfisis.dev" siteName = "nsfisis.dev" -[blog] -postsPerPage = 10 - -[blog.tagLabels] +[tagLabels] c = "C" ci-cd = "CI/CD" code-golf = "コードゴルフ" |
