diff --git a/package-lock.json b/package-lock.json index d5e1fd9..25e003a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1733,7 +1733,7 @@ "version": "1.0.0", "license": "ISC", "bin": { - "zblog-toolchain": "bin/zblog-toolchain.js" + "zblog-toolchain": "bin/index.js" } } } diff --git a/packages/@zblog/toolchain/package.json b/packages/@zblog/toolchain/package.json index 02541bc..e173676 100644 --- a/packages/@zblog/toolchain/package.json +++ b/packages/@zblog/toolchain/package.json @@ -3,12 +3,12 @@ "version": "1.0.0", "description": "", "type": "module", - "module": "bin/zblog-toolchain.js", - "main": "bin/zblog-toolchain.js", + "module": "bin/index.js", + "main": "bin/index.js", "bin": { - "zblog-toolchain": "./bin/zblog-toolchain.js" + "zblog-toolchain": "./bin/index.js" }, - "types": "./bin/zblog-toolchain.d.ts", + "types": "./bin/index.d.ts", "scripts": { "build": "tsc -p tsconfig.json" }, diff --git a/packages/@zblog/toolchain/src/file-loader.ts b/packages/@zblog/toolchain/src/file-loader.ts new file mode 100644 index 0000000..77b2990 --- /dev/null +++ b/packages/@zblog/toolchain/src/file-loader.ts @@ -0,0 +1,30 @@ +import { IPluginBuilder, Plugin } from "./typings.js"; +import { copyFile } from "./toolchain-helpers.js"; + +type Options = { + files: { path: string; menuEntry?: boolean; nameOverride?: string }[]; +}; + +export class FileLoader implements IPluginBuilder { + options: Options; + constructor(options: Options) { + this.options = options; + } + build(): Plugin { + return async (builderContext) => { + const { menuManifest } = builderContext; + const { files } = this.options; + files.forEach((file) => { + const fileName = + file.nameOverride ?? file.path.split("/").pop() ?? file.path; + copyFile(file.path, `${builderContext.outputDirectory}/${fileName}`); + if (file.menuEntry) { + menuManifest.push({ + name: fileName, + link: file.path, + }); + } + }); + }; + } +} diff --git a/packages/@zblog/toolchain/src/index.ts b/packages/@zblog/toolchain/src/index.ts new file mode 100644 index 0000000..8de463f --- /dev/null +++ b/packages/@zblog/toolchain/src/index.ts @@ -0,0 +1,9 @@ +import { ToolchainBuilder as TSB, Paths as P } from "./zblog-toolchain.js"; +export const ToolchainBuilder = TSB; +export type Paths = P; +import { FileLoader as FL } from "./file-loader.js"; +export const FileLoader = FL; +import { MarkdownLoader as ML } from "./markdown-loader.js"; +export const MarkdownLoader = ML; +import { StartPagePlugin as SPP } from "./start-page-plugin.js"; +export const StartPagePlugin = SPP; diff --git a/packages/@zblog/toolchain/src/markdown-loader.ts b/packages/@zblog/toolchain/src/markdown-loader.ts index a974b0f..83f09d6 100644 --- a/packages/@zblog/toolchain/src/markdown-loader.ts +++ b/packages/@zblog/toolchain/src/markdown-loader.ts @@ -5,9 +5,9 @@ import { writeTextAsFile, } from "./toolchain-helpers.js"; import { toHtml } from "./markdown-parser.js"; -import { MenuManifest } from "./zblog-toolchain.js"; +import { IPluginBuilder, MenuManifest, Plugin } from "./typings.js"; -type MarkdownLoaderOptions = { +type MarkdownLoaderManifestOptions = { notesRootPath: string; noteFileName: string; assetsDirectoryName: string; @@ -26,7 +26,7 @@ const createMarkdownLoaderManifest = ({ notesRootPath, assetsDirectoryName, noteFileName, -}: MarkdownLoaderOptions): MarkdownLoaderManifest => { +}: MarkdownLoaderManifestOptions): MarkdownLoaderManifest => { const directoryNames = fs.readdirSync(notesRootPath); return directoryNames.map((noteDirectory) => { const assetDirectoryPath = `${notesRootPath}/${noteDirectory}/${assetsDirectoryName}`; @@ -79,34 +79,44 @@ const writeMarkdownAsHtmlToOutputDirectory = ( }); }; -export const loadMarkdown = ( - options: { - rootPath: string; - assetsDirectoryName: string; - noteFileName: string; - noteHtmlTemplatePath: string; - outputDirectory: string; - markdownHtmlReplacementTag: string; - }, - menuManifest: MenuManifest -) => { - const markdownManifest = createMarkdownLoaderManifest({ - notesRootPath: options.rootPath, - assetsDirectoryName: options.assetsDirectoryName, - noteFileName: options.noteFileName, - }); - menuManifest.push( - ...markdownManifest.map((m) => ({ - name: m.name, - link: `/${m.directoryName}.html`, - })) - ); - const noteHtmlTemplate = readFileAsText(options.noteHtmlTemplatePath); - writeMarkdownAsHtmlToOutputDirectory( - markdownManifest, - noteHtmlTemplate, - options.markdownHtmlReplacementTag, - options.outputDirectory - ); - copyAssetsToOutputDirectory(markdownManifest, options.outputDirectory); +type MarkdownLoaderOptions = { + rootPath: string; + assetsDirectoryName: string; + noteFileName: string; + noteHtmlTemplatePath: string; + markdownHtmlReplacementTag: string; }; +export class MarkdownLoader implements IPluginBuilder { + options: MarkdownLoaderOptions; + constructor(options: MarkdownLoaderOptions) { + this.options = options; + } + build(): Plugin { + return (builderContext) => { + const markdownManifest = createMarkdownLoaderManifest({ + notesRootPath: this.options.rootPath, + assetsDirectoryName: this.options.assetsDirectoryName, + noteFileName: this.options.noteFileName, + }); + builderContext.menuManifest.push( + ...markdownManifest.map((m) => ({ + name: m.name, + link: `/${m.directoryName}.html`, + })) + ); + const noteHtmlTemplate = readFileAsText( + this.options.noteHtmlTemplatePath + ); + writeMarkdownAsHtmlToOutputDirectory( + markdownManifest, + noteHtmlTemplate, + this.options.markdownHtmlReplacementTag, + builderContext.outputDirectory + ); + copyAssetsToOutputDirectory( + markdownManifest, + builderContext.outputDirectory + ); + }; + } +} diff --git a/packages/@zblog/toolchain/src/start-page-plugin.ts b/packages/@zblog/toolchain/src/start-page-plugin.ts new file mode 100644 index 0000000..5ebf43d --- /dev/null +++ b/packages/@zblog/toolchain/src/start-page-plugin.ts @@ -0,0 +1,32 @@ +import { IPluginBuilder, Plugin } from "./typings.js"; +import { readFileAsText, writeTextAsFile } from "./toolchain-helpers.js"; + +type StartPagePluginOptions = { + indexTemplatePath: string; + contentTemplateTag: string; +}; +export class StartPagePlugin implements IPluginBuilder { + options: StartPagePluginOptions; + constructor(options: StartPagePluginOptions) { + this.options = options; + } + build(): Plugin { + return (builderContext) => { + let htmlTemplate = readFileAsText(this.options.indexTemplatePath); + const links = builderContext.menuManifest + .map((m) => `${m.name}`) + .reverse(); + const unorderedListItems = links.map((l) => `