Changes
11 changed files (+236/-60)
-
-
@@ -42,7 +42,7 @@ uses: denoland/setup-deno@v1with: deno-version: v1.41.x - name: Build documentation website run: "deno task build-docs" run: "deno task build-docs --json" - name: Upload artifact uses: actions/upload-pages-artifact@v3 with:
-
-
-
@@ -152,6 +152,36 @@ "https://deno.land/std@0.221.0/yaml/schema/failsafe.ts": "24b2b630cef6fcce7de6d29db651523b0f49e5691d690931c42ecf4823837fdb","https://deno.land/std@0.221.0/yaml/schema/json.ts": "0fb9268282d266c24d963e75ef77f51accbbb74f40713a99e83ad621a81bc9ae", "https://deno.land/std@0.221.0/yaml/schema/mod.ts": "9bf7ff80c2a246f781bdcab979211d0389760831a974cf5883bf2016567e3507", "https://deno.land/std@0.221.0/yaml/type.ts": "708dde5f20b01cc1096489b7155b6af79a217d585afb841128e78c3c2391eb5c", "https://deno.land/std@0.223.0/assert/assert.ts": "09d30564c09de846855b7b071e62b5974b001bb72a4b797958fe0660e7849834", "https://deno.land/std@0.223.0/assert/assertion_error.ts": "ba8752bd27ebc51f723702fac2f54d3e94447598f54264a6653d6413738a8917", "https://deno.land/std@0.223.0/cli/_data.json": "cf2cc9d039a192b3adbfe64627167c7e6212704c888c25c769fc8f1709e1e1b8", "https://deno.land/std@0.223.0/cli/_run_length.ts": "7da8642a0f4f41ac27c0adb1364e18886be856c1d08c5cce6c6b5c00543c8722", "https://deno.land/std@0.223.0/cli/mod.ts": "9548eaf4fefac2ab9b02e0f8e4de8a08cac5d24b721a6019452efec172b59de3", "https://deno.land/std@0.223.0/cli/parse_args.ts": "5250832fb7c544d9111e8a41ad272c016f5a53f975ef84d5a9fe5fcb70566ece", "https://deno.land/std@0.223.0/cli/prompt_secret.ts": "3b2f95214422226482fba4a00cb25441475b6f97069a6f70f442c1c9a16c744c", "https://deno.land/std@0.223.0/cli/spinner.ts": "cf873605771270b4324cc063b5031ab250d8efee8799e45e1a3bfdd333ff721d", "https://deno.land/std@0.223.0/cli/unicode_width.ts": "656dd4271ecc90684b6bf23a5fb8c1cf833da625ef2906b61273ad617038072f", "https://deno.land/std@0.223.0/fmt/colors.ts": "d239d84620b921ea520125d778947881f62c50e78deef2657073840b8af9559a", "https://deno.land/std@0.223.0/fs/exists.ts": "3d38cb7dcbca3cf313be343a7b8af18a87bddb4b5ca1bd2314be12d06533b50f", "https://deno.land/std@0.223.0/io/types.ts": "acecb3074c730b5ff487ba4fe9ce51e67bd982aa07c95e5f5679b7b2f24ad129", "https://deno.land/std@0.223.0/io/write_all.ts": "24aac2312bb21096ae3ae0b102b22c26164d3249dff96dbac130958aa736f038", "https://deno.land/std@0.223.0/log/_config.ts": "489e11b6d3c917bf5fc954c5e914c095d3480efd924d1e85f2fc576468581c54", "https://deno.land/std@0.223.0/log/_state.ts": "314c0c31ab9c8f4fb33326ad446757d35f75e5bb21746b7720ed4e3f3a939da1", "https://deno.land/std@0.223.0/log/base_handler.ts": "f03f013dac9c1a226aab60c6f5751b3131cc4f2808720715285e0dab5697a54e", "https://deno.land/std@0.223.0/log/console_handler.ts": "9b17b9025c7d94eab950a25eccca81fd9dd71d063b9f458f149e52db52ab0295", "https://deno.land/std@0.223.0/log/critical.ts": "a8b44a4c6768629d2a506ffe1a1a048da7ae76d3146000f8a492008eac4ecba0", "https://deno.land/std@0.223.0/log/debug.ts": "ddd63a549fedc3061deba47e41cd2170263831fc266e503a12b610b77439333b", "https://deno.land/std@0.223.0/log/error.ts": "3979ee3aadc962345ad50eff8a5470ad3fe07c70370808ddc178ee08c3d6c89c", "https://deno.land/std@0.223.0/log/file_handler.ts": "68d6d81ec53bdd6ba61eaceec19d12de59a8ad12ace0d7980a592a51f924a242", "https://deno.land/std@0.223.0/log/formatters.ts": "29e0325902c3b1cbb3b9ffc1f9d77ac2d2e5af35d27b9bdfe4fdbbd83588d4a8", "https://deno.land/std@0.223.0/log/get_logger.ts": "36a5febf5338f68aadafaf23bbe38a208e2a3150ec02ca2ec5d3c6bbaf840641", "https://deno.land/std@0.223.0/log/info.ts": "e6c4971e35092d85cd3241fe7eccdb42999083d14db6aadc5e741f6231e275ad", "https://deno.land/std@0.223.0/log/levels.ts": "632ba12baa2600750d004cc5cb4eabe10e410f3f2bdfcb9f7142b6d767f2fee6", "https://deno.land/std@0.223.0/log/logger.ts": "57109848fb587fb3843a7b893f22f1a86c1b78c289172627a6305906738f238a", "https://deno.land/std@0.223.0/log/mod.ts": "650c53c2c5d9eb05210c4ec54184ecb5bd24fb32ce28e65fad039853978f53f3", "https://deno.land/std@0.223.0/log/rotating_file_handler.ts": "a6e7c712e568b618303273ff95483f6ab86dec0a485c73c2e399765f752b5aa8", "https://deno.land/std@0.223.0/log/setup.ts": "42425c550da52c7def7f63a4fcc1ac01a4aec6c73336697a640978d6a324e7a6", "https://deno.land/std@0.223.0/log/warn.ts": "f1a6bc33a481f231a0257e6d66e26c2e695b931d5e917d8de4f2b825778dfd4e", "https://deno.land/x/brotli@0.1.7/mod.ts": "08b913e51488b6e7fa181f2814b9ad087fdb5520041db0368f8156bfa45fd73e", "https://deno.land/x/brotli@0.1.7/wasm.js": "77771b89e89ec7ff6e3e0939a7fb4f9b166abec3504cec0532ad5c127d6f35d2", "https://deno.land/x/lz4@v0.1.2/mod.ts": "4decfc1a3569d03fd1813bd39128b71c8f082850fe98ecfdde20025772916582",
-
-
-
@@ -0,0 +1,5 @@// SPDX-FileCopyrightText: 2024 Shota FUJI <pockawoooh@gmail.com> // // SPDX-License-Identifier: Apache-2.0 export * from "https://deno.land/std@0.223.0/cli/mod.ts";
-
-
-
@@ -0,0 +1,5 @@// SPDX-FileCopyrightText: 2024 Shota FUJI <pockawoooh@gmail.com> // // SPDX-License-Identifier: Apache-2.0 export * from "https://deno.land/std@0.223.0/log/mod.ts";
-
-
-
@@ -2,6 +2,9 @@ // SPDX-FileCopyrightText: 2024 Shota FUJI <pockawoooh@gmail.com>// // SPDX-License-Identifier: Apache-2.0 import * as log from "../deps/deno.land/std/log/mod.ts"; import * as cli from "../deps/deno.land/std/cli/mod.ts"; import { DenoFsReader } from "../filesystem_reader/deno_fs.ts"; import { DenoFsWriter } from "../filesystem_writer/deno_fs.ts"; import {
-
@@ -16,54 +19,95 @@ import { JSONCanvasParser } from "../content_parser/json_canvas.ts";import { oneof } from "../content_parser/oneof.ts"; import { DefaultThemeBuilder } from "../page_builder/default_theme/builder.tsx"; const outDir = new URL("./.dist", import.meta.url); export async function build() { const outDir = new URL("./.dist", import.meta.url); await Deno.permissions.request({ name: "write", path: outDir, }); await Deno.permissions.request({ name: "write", path: outDir, }); const srcDir = new URL(".", import.meta.url); const srcDir = new URL(".", import.meta.url); await Deno.permissions.request({ name: "read", path: srcDir, }); await Deno.permissions.request({ name: "read", path: srcDir, }); await Deno.mkdir(outDir, { recursive: true }); await Deno.mkdir(outDir, { recursive: true }); const fileSystemReader = new DenoFsReader(srcDir); const fileSystemWriter = new DenoFsWriter(outDir); const treeBuilder = new DefaultTreeBuilder({ defaultLanguage: "en", strategies: [ ignoreDotfiles(), fileExtensions([".md", ".canvas"]), removeExtFromMetadata(), langDir({ en: "English", ja: "日本語", }, true), ], resolveShortestPathWhenPossible: true, }); const contentParser = oneof( new JSONCanvasParser(), new ObsidianMarkdownParser(), ); const pageBuilder = new DefaultThemeBuilder({ copyright: "© 2024 Shota FUJI. This document is licensed under CC BY 4.0", faviconSvg: ["Assets", "logo.svg"], faviconPng: ["Assets", "logo-64x64.png"], siteLogo: ["Assets", "logo.svg"], }); const fileSystemReader = new DenoFsReader(srcDir); const fileSystemWriter = new DenoFsWriter(outDir); const treeBuilder = new DefaultTreeBuilder({ defaultLanguage: "en", strategies: [ ignoreDotfiles(), fileExtensions([".md", ".canvas"]), removeExtFromMetadata(), langDir({ en: "English", ja: "日本語", }, true), ], resolveShortestPathWhenPossible: true, }); const contentParser = oneof( new JSONCanvasParser(), new ObsidianMarkdownParser(), ); const pageBuilder = new DefaultThemeBuilder({ copyright: "© 2024 Shota FUJI. This document is licensed under CC BY 4.0", faviconSvg: ["Assets", "logo.svg"], faviconPng: ["Assets", "logo-64x64.png"], siteLogo: ["Assets", "logo.svg"], }); const documentTree = await treeBuilder.build({ fileSystemReader, contentParser, }); await pageBuilder.build({ documentTree, fileSystemReader, fileSystemWriter, }); const documentTree = await treeBuilder.build({ fileSystemReader, contentParser, }); await pageBuilder.build({ documentTree, fileSystemReader, fileSystemWriter, }); } if (import.meta.main) { const args = cli.parseArgs(Deno.args, { boolean: ["json"], }); log.setup({ handlers: { default: new log.ConsoleHandler("DEBUG", { formatter: args.json ? log.jsonFormatter : undefined, useColors: args.json ? false : undefined, }), }, loggers: { macana: { level: "DEBUG", handlers: ["default"], }, }, }); try { const start = performance.now(); await build(); const duration = performance.now() - start; log.info(`Complete docs build, elapsed ${duration}ms`, { duration, }); } catch (error) { log.critical(`Build aborted due to an error: ${error}`, { error, }); Deno.exit(1); } }
-
-
-
@@ -4,6 +4,8 @@ // SPDX-License-Identifier: Apache-2.0import { SEPARATOR } from "../deps/deno.land/std/path/mod.ts"; import { logger } from "../logger.ts"; import type { FileSystemReader } from "./interface.ts"; import type { DirectoryReader,
-
@@ -48,14 +50,16 @@#fromDirEntry = ( dirEntry: Deno.DirEntry, parent: DirectoryReader | RootDirectoryReader, ): FileReader | DirectoryReader => { ): FileReader | DirectoryReader | null => { const { name, isSymlink, isFile } = dirEntry; const path = parent.type === "root" ? [name] : [...parent.path, name]; if (isSymlink) { // TODO: Log warning and skip. throw new Error("DenoFsReader does not support reading symlinks."); logger().warn(`Found symlink, skipping`, { path, }); return null; } if (isFile) {
-
@@ -79,7 +83,10 @@ read: async () => {const converted: Array<FileReader | DirectoryReader> = []; for await (const entry of Deno.readDir(this.#resolve(path))) { converted.push(this.#fromDirEntry(entry, dir)); const c = this.#fromDirEntry(entry, dir); if (c) { converted.push(c); } } return converted;
-
@@ -98,7 +105,10 @@ read: async () => {const converted: Array<FileReader | DirectoryReader> = []; for await (const entry of Deno.readDir(this.#root)) { converted.push(this.#fromDirEntry(entry, root)); const c = this.#fromDirEntry(entry, root); if (c) { converted.push(c); } } return converted;
-
@@ -154,7 +164,10 @@ read: async () => {const converted: Array<FileReader | DirectoryReader> = []; for await (const entry of Deno.readDir(this.#resolve(path))) { converted.push(this.#fromDirEntry(entry, dir)); const c = this.#fromDirEntry(entry, dir); if (c) { converted.push(c); } } return converted;
-
@@ -183,7 +196,10 @@ read: async () => {const converted: Array<FileReader | DirectoryReader> = []; for await (const entry of Deno.readDir(this.#resolve(path))) { converted.push(this.#fromDirEntry(entry, dir)); const c = this.#fromDirEntry(entry, dir); if (c) { converted.push(c); } } return converted;
-
-
-
@@ -4,6 +4,8 @@ // SPDX-License-Identifier: Apache-2.0import { dirname, SEPARATOR } from "../deps/deno.land/std/path/mod.ts"; import { logger } from "../logger.ts"; import type { FileSystemWriter } from "./interface.ts"; export class DenoFsWriter implements FileSystemWriter {
-
@@ -47,6 +49,12 @@ path: readonly string[],content: Uint8Array, ) { const resolvedPath = this.#resolve(path); logger().debug(`Writing file at ${path.join(SEPARATOR)}`, { path, resolvedPath, bytes: content.byteLength, }); await Deno.mkdir(dirname(resolvedPath), { recursive: true }); await Deno.writeFile(resolvedPath, content);
-
-
logger.ts (new)
-
@@ -0,0 +1,9 @@// SPDX-FileCopyrightText: 2024 Shota FUJI <pockawoooh@gmail.com> // // SPDX-License-Identifier: Apache-2.0 import { getLogger } from "./deps/deno.land/std/log/mod.ts"; export function logger() { return getLogger("macana"); }
-
-
-
@@ -6,6 +6,8 @@ /** @jsx h */import { h, renderSSR } from "../../deps/deno.land/x/nano_jsx/mod.ts"; import { logger } from "../../logger.ts"; import type { BuildParameters, PageBuilder } from "../interface.ts"; import { macanaReplaceAssetTokens,
-
@@ -103,6 +105,8 @@async build( { documentTree, fileSystemReader, fileSystemWriter }: BuildParameters, ) { const start = performance.now(); const styles = css.serialize( Html.styles, );
-
@@ -168,6 +172,11 @@ buildParameters: { fileSystemWriter, fileSystemReader },assets, }) )); const duration = performance.now() - start; logger().info(`Built with default theme in ${duration}ms`, { duration, }); } async #build(
-
-
-
@@ -6,6 +6,8 @@ /** @jsx h */import { h } from "../../../deps/deno.land/x/nano_jsx/mod.ts"; import { logger } from "../../../logger.ts"; import { css } from "../css.ts"; import type {
-
@@ -346,18 +348,24 @@ : "var(--canvas-color-fallback)";const fromNode = nodes.get(edge.fromNode); if (!fromNode) { // TODO: Proper logging console.warn( `JSONCanvas Renderer: Edge(id=${edge.id}) points to non-existing fromNode(id=${edge.fromNode})`, logger().warn( "Malformed JSONCanvas: " + `Edge(id=${edge.id}) points to non-existing fromNode(id=${edge.fromNode})`, { edge, }, ); return; } const toNode = nodes.get(edge.toNode); if (!toNode) { // TODO: Proper logging console.warn( `JSONCanvas Renderer: Edge(id=${edge.id}) points to non-existing toNode(id=${edge.toNode})`, logger().warn( "Malformed JSONCanvas: " + `Edge(id=${edge.id}) points to non-existing toNode(id=${edge.toNode})`, { edge, }, ); return; }
-
-
-
@@ -4,6 +4,8 @@ // SPDX-License-Identifier: Apache-2.0import { extname } from "../deps/deno.land/std/path/mod.ts"; import { logger } from "../logger.ts"; import type { BuildParameters, TreeBuilder } from "./interface.ts"; import type { AssetToken,
-
@@ -65,6 +67,9 @@ f: (fileOrDirectory: FileReader | DirectoryReader) => boolean,): TreeBuildStrategy { return (node, metadata) => { if (f(node)) { logger().debug(`Ignored: ${node.path.join(INTERNAL_PATH_SEPARATOR)}`, { path: node.path, }); return { skip: true }; }
-
@@ -98,6 +103,14 @@ const title = map.get(node.name);if (!title) { return { metadata }; } logger().debug( `Found language directory at ${node.path.join(INTERNAL_PATH_SEPARATOR)}`, { path: node.path, language: node.name, }, ); return { metadata: {
-
@@ -393,6 +406,7 @@async build( { fileSystemReader, contentParser }: BuildParameters, ): Promise<DocumentTree> { const start = performance.now(); const root = await fileSystemReader.getRootDirectory(); const assetTokensToFiles = new Map<AssetToken, FileReader>();
-
@@ -424,6 +438,23 @@ "No document found. Document tree must have at least one document.",); } logger().debug( `Default document at ${ defaultDocument.file.path.join(INTERNAL_PATH_SEPARATOR) }`, { path: defaultDocument.file.path, documentPath: defaultDocument.path, title: defaultDocument.metadata.title, }, ); const duration = performance.now() - start; logger().info(`Built document tree in ${duration}ms`, { duration, documents: flattenTree(nodes).length, }); return { type: "tree", nodes,
-
@@ -483,7 +514,6 @@for (const strategy of this.#strategies) { const result = await strategy(node, metadata); if (result.skip) { // TODO: Debug log (or this should be in the each strategies?) return null; }
-
@@ -640,3 +670,15 @@return null; } } function flattenTree( tree: ReadonlyArray<Document | DocumentDirectory>, ): readonly Document[] { return tree.map((node) => { if (node.type === "document") { return [node]; } return flattenTree(node.entries); }).flat(); }
-