Restructured toolchain to its own workspace
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -65,5 +65,6 @@ node_modules/
|
|||||||
# dotenv environment variables file
|
# dotenv environment variables file
|
||||||
.env
|
.env
|
||||||
|
|
||||||
.dist
|
dist
|
||||||
temp
|
temp
|
||||||
|
bin
|
||||||
97
build.js
97
build.js
@@ -1,97 +0,0 @@
|
|||||||
import * as fs from "fs";
|
|
||||||
import { toHtml } from "./markdown.js";
|
|
||||||
|
|
||||||
const paths = {
|
|
||||||
output: ".dist",
|
|
||||||
notes: {
|
|
||||||
root: "notes",
|
|
||||||
assets: "assets",
|
|
||||||
note: "note.md",
|
|
||||||
},
|
|
||||||
templates: {
|
|
||||||
root: "templates",
|
|
||||||
note: "note.html",
|
|
||||||
index: "index.html",
|
|
||||||
notFound: "404.html",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
if (fs.readdirSync(".").includes(paths.output)) {
|
|
||||||
fs.rmSync(paths.output, { recursive: true, force: true });
|
|
||||||
console.log("Starting rebuild");
|
|
||||||
} else {
|
|
||||||
console.log("Starting build");
|
|
||||||
}
|
|
||||||
fs.mkdirSync(paths.output);
|
|
||||||
|
|
||||||
console.log("Indexing content..");
|
|
||||||
const directoryNames = fs.readdirSync(paths.notes.root);
|
|
||||||
const manifest = directoryNames.map((noteDirectory) => ({
|
|
||||||
directoryName: noteDirectory,
|
|
||||||
name: noteDirectory,
|
|
||||||
markdown: fs.readFileSync(
|
|
||||||
`${paths.notes.root}/${noteDirectory}/${paths.notes.note}`,
|
|
||||||
{ encoding: "utf-8" }
|
|
||||||
),
|
|
||||||
assetDirectoryPath: `${paths.notes.root}/${noteDirectory}/${paths.notes.assets}`,
|
|
||||||
publicAssetDirectoryPath: `/${noteDirectory}_`,
|
|
||||||
}));
|
|
||||||
|
|
||||||
console.log("Parsing content..");
|
|
||||||
manifest.forEach((m) => {
|
|
||||||
const notePath = `${paths.templates.root}/${paths.templates.note}`;
|
|
||||||
let htmlTemplate = fs.readFileSync(notePath, {
|
|
||||||
encoding: "utf-8",
|
|
||||||
});
|
|
||||||
htmlTemplate = htmlTemplate.replace(
|
|
||||||
"{{markdown}}",
|
|
||||||
toHtml(m.markdown, m.publicAssetDirectoryPath)
|
|
||||||
);
|
|
||||||
fs.writeFileSync(`${paths.output}/${m.directoryName}.html`, htmlTemplate, {
|
|
||||||
encoding: "utf-8",
|
|
||||||
flag: "ax",
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!fs.existsSync(m.assetDirectoryPath)) return;
|
|
||||||
const assetsList = fs.readdirSync(m.assetDirectoryPath);
|
|
||||||
assetsList.forEach((assetName) =>
|
|
||||||
fs.cpSync(
|
|
||||||
`${m.assetDirectoryPath}/${assetName}`,
|
|
||||||
`${paths.output}/${m.name}_${assetName}`
|
|
||||||
)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log("Moving static templates..");
|
|
||||||
[paths.templates.notFound].forEach((filename) => {
|
|
||||||
fs.copyFileSync(
|
|
||||||
`${paths.templates.root}/${filename}`,
|
|
||||||
`${paths.output}/${filename}`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log("Building startpage..");
|
|
||||||
let htmlTemplate = fs.readFileSync(
|
|
||||||
`${paths.templates.root}/${paths.templates.index}`,
|
|
||||||
{
|
|
||||||
encoding: "utf-8",
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const links = manifest
|
|
||||||
.map((m) => `<a href='/${m.directoryName}.html'>${m.name}</a>`)
|
|
||||||
.reverse();
|
|
||||||
|
|
||||||
const unorderedListItems = links.map((l) => `<li>${l}</li>`).join("\r\n");
|
|
||||||
const html = `
|
|
||||||
<ul>
|
|
||||||
${unorderedListItems}
|
|
||||||
<ul>
|
|
||||||
`;
|
|
||||||
htmlTemplate = htmlTemplate.replace("{{content}}", html);
|
|
||||||
fs.writeFileSync(`${paths.output}/index.html`, htmlTemplate, {
|
|
||||||
encoding: "utf-8",
|
|
||||||
flag: "ax",
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log("Done");
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"hosting": {
|
"hosting": {
|
||||||
"public": ".dist",
|
"public": "dist",
|
||||||
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"]
|
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
package-lock.json
generated
14
package-lock.json
generated
@@ -8,6 +8,9 @@
|
|||||||
"name": "blog",
|
"name": "blog",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
|
"workspaces": [
|
||||||
|
"packages/@zblog/toolchain"
|
||||||
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.11.5",
|
"@types/node": "^20.11.5",
|
||||||
"concurrently": "^8.2.1",
|
"concurrently": "^8.2.1",
|
||||||
@@ -37,6 +40,10 @@
|
|||||||
"undici-types": "~5.26.4"
|
"undici-types": "~5.26.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@zblog/toolchain": {
|
||||||
|
"resolved": "packages/@zblog/toolchain",
|
||||||
|
"link": true
|
||||||
|
},
|
||||||
"node_modules/@zeit/schemas": {
|
"node_modules/@zeit/schemas": {
|
||||||
"version": "2.29.0",
|
"version": "2.29.0",
|
||||||
"resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.29.0.tgz",
|
"resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.29.0.tgz",
|
||||||
@@ -1721,6 +1728,13 @@
|
|||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"packages/@zblog/toolchain": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "ISC",
|
||||||
|
"bin": {
|
||||||
|
"zblog-toolchain": "bin/zblog-toolchain.js"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
16
package.json
16
package.json
@@ -1,17 +1,21 @@
|
|||||||
{
|
{
|
||||||
"name": "blog",
|
"name": "blog",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "",
|
"description": "A static blog generator",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "concurrently --kill-others -n Build,Serve -c auto \"npm run watch-build\" \"npm run serve\"",
|
"dev": "concurrently --kill-others -n Build,Serve -c auto \"npm run watch-build\" \"npm run serve\"",
|
||||||
"watch-build": "nodemon --watch notes --watch build.js --watch markdown.js --watch templates -e js,md,html,css build.js",
|
"watch-build": "nodemon --watch notes --watch src --watch markdown.ts --exec \"npm run build && npm run generate-blog\"",
|
||||||
"build": "node build.js",
|
"build": "tsc -p tsconfig.json",
|
||||||
"init": "npm install -g firebase-tools && firebase login",
|
"serve": "serve dist",
|
||||||
"serve": "serve .dist"
|
"generate-blog": "node bin/index.js",
|
||||||
|
"initialize-firebase": "npm install -g firebase-tools && firebase login"
|
||||||
},
|
},
|
||||||
"author": "",
|
"workspaces": [
|
||||||
|
"packages/@zblog/toolchain"
|
||||||
|
],
|
||||||
|
"author": "Wholteza (Zackarias Montell)",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.11.5",
|
"@types/node": "^20.11.5",
|
||||||
|
|||||||
3
packages/@zblog/toolchain/.gitignore
vendored
Normal file
3
packages/@zblog/toolchain/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
node_modules
|
||||||
|
bin
|
||||||
|
dist
|
||||||
17
packages/@zblog/toolchain/package.json
Normal file
17
packages/@zblog/toolchain/package.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"name": "@zblog/toolchain",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"type": "module",
|
||||||
|
"module": "bin/zblog-toolchain.js",
|
||||||
|
"main": "bin/zblog-toolchain.js",
|
||||||
|
"bin": {
|
||||||
|
"zblog-toolchain": "./bin/zblog-toolchain.js"
|
||||||
|
},
|
||||||
|
"types": "./bin/zblog-toolchain.d.ts",
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc -p tsconfig.json"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC"
|
||||||
|
}
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
class LineFeed {
|
class LineFeed {
|
||||||
originalText = undefined;
|
originalText: string | undefined = undefined;
|
||||||
/**
|
/**
|
||||||
* @type {string[]}
|
* @type {string[]}
|
||||||
*/
|
*/
|
||||||
feed = undefined;
|
feed: string[] | undefined = undefined;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string} markdown
|
* @param {string} markdown
|
||||||
*/
|
*/
|
||||||
constructor(markdown) {
|
constructor(markdown: string) {
|
||||||
this.originalText = markdown;
|
this.originalText = markdown;
|
||||||
// TODO: Need to identify line endings
|
// TODO: Need to identify line endings
|
||||||
this.feed = markdown.split("\n");
|
this.feed = markdown.split("\n");
|
||||||
@@ -17,16 +17,16 @@ class LineFeed {
|
|||||||
/**
|
/**
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
peek() {
|
peek(): string {
|
||||||
return this.feed[0] ?? undefined;
|
return this.feed?.[0] ?? "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
claim() {
|
claim(): string {
|
||||||
const line = this.feed.shift();
|
const line = this.feed?.shift();
|
||||||
if (line === undefined) throw new Error("Feed is empty");
|
if (line === undefined) throw new Error("Feed is empty");
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
@@ -35,25 +35,25 @@ class LineFeed {
|
|||||||
*
|
*
|
||||||
* @param {string} line
|
* @param {string} line
|
||||||
*/
|
*/
|
||||||
push(line) {
|
push(line: string | null | undefined) {
|
||||||
if (line === undefined || line === null) return;
|
if (line === undefined || line === null) return;
|
||||||
this.feed = [line, ...this.feed];
|
this.feed = [line, ...(this.feed ?? [])];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
isEmpty() {
|
isEmpty(): boolean {
|
||||||
return this.feed.length === 0;
|
return this.feed?.length === 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Symbol {
|
class Symbol {
|
||||||
static canParse(line) {
|
static canParse(line: string) {
|
||||||
throw new Error("Not implemented");
|
throw new Error("Not implemented");
|
||||||
}
|
}
|
||||||
static create(lineFeed, assetDirectory) {
|
static create(lineFeed: LineFeed, assetDirectory: string): Symbol {
|
||||||
throw new Error("Not implemented");
|
throw new Error("Not implemented");
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -61,7 +61,7 @@ class Symbol {
|
|||||||
* @param {string} assetDirectory
|
* @param {string} assetDirectory
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
process(assetDirectory) {
|
process(assetDirectory: string): void {
|
||||||
throw new Error("Not Implemented");
|
throw new Error("Not Implemented");
|
||||||
}
|
}
|
||||||
render() {
|
render() {
|
||||||
@@ -73,17 +73,17 @@ class Heading extends Symbol {
|
|||||||
/**
|
/**
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
text = "";
|
text: string = "";
|
||||||
/**
|
/**
|
||||||
* @type {number}
|
* @type {number}
|
||||||
*/
|
*/
|
||||||
level = 1;
|
level: number = 1;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string} line
|
* @param {string} line
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
static canParse(line) {
|
static canParse(line: string): boolean {
|
||||||
return line.trim().startsWith("#");
|
return line.trim().startsWith("#");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ class Heading extends Symbol {
|
|||||||
* @param {LineFeed} lineFeed
|
* @param {LineFeed} lineFeed
|
||||||
* @returns {Symbol}
|
* @returns {Symbol}
|
||||||
*/
|
*/
|
||||||
static create(lineFeed) {
|
static create(lineFeed: LineFeed): Symbol {
|
||||||
const instance = new Heading();
|
const instance = new Heading();
|
||||||
const line = lineFeed.claim();
|
const line = lineFeed.claim();
|
||||||
instance.text = line.replaceAll("#", "").trim();
|
instance.text = line.replaceAll("#", "").trim();
|
||||||
@@ -107,7 +107,7 @@ class Heading extends Symbol {
|
|||||||
* @param {string} assetDirectory
|
* @param {string} assetDirectory
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
process(assetDirectory) {
|
process(assetDirectory: string): void {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,7 +122,7 @@ class JustALineBreak extends Symbol {
|
|||||||
* @param {string} line
|
* @param {string} line
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
static canParse(line) {
|
static canParse(line: string): boolean {
|
||||||
return line === "";
|
return line === "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ class JustALineBreak extends Symbol {
|
|||||||
* @param {LineFeed} lineFeed
|
* @param {LineFeed} lineFeed
|
||||||
* @returns {Symbol}
|
* @returns {Symbol}
|
||||||
*/
|
*/
|
||||||
static create(lineFeed) {
|
static create(lineFeed: LineFeed): Symbol {
|
||||||
const instance = new JustALineBreak();
|
const instance = new JustALineBreak();
|
||||||
lineFeed.claim();
|
lineFeed.claim();
|
||||||
return instance;
|
return instance;
|
||||||
@@ -142,7 +142,7 @@ class JustALineBreak extends Symbol {
|
|||||||
* @param {string} assetDirectory
|
* @param {string} assetDirectory
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
process(assetDirectory) {
|
process(assetDirectory: string): void {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,17 +155,17 @@ class Paragraph extends Symbol {
|
|||||||
/**
|
/**
|
||||||
* @type {string[]}
|
* @type {string[]}
|
||||||
*/
|
*/
|
||||||
lines = [];
|
lines: string[] = [];
|
||||||
/**
|
/**
|
||||||
* @type {Symbol[]}
|
* @type {Symbol[]}
|
||||||
*/
|
*/
|
||||||
children = [];
|
children: Symbol[] = [];
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string} line
|
* @param {string} line
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
static canParse(line) {
|
static canParse(line: string): boolean {
|
||||||
return line === "";
|
return line === "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +174,7 @@ class Paragraph extends Symbol {
|
|||||||
* @param {LineFeed} lineFeed
|
* @param {LineFeed} lineFeed
|
||||||
* @returns {Symbol}
|
* @returns {Symbol}
|
||||||
*/
|
*/
|
||||||
static create(lineFeed) {
|
static create(lineFeed: LineFeed): Symbol {
|
||||||
const instance = new Paragraph();
|
const instance = new Paragraph();
|
||||||
lineFeed.claim();
|
lineFeed.claim();
|
||||||
|
|
||||||
@@ -198,7 +198,7 @@ class Paragraph extends Symbol {
|
|||||||
* @param {string} assetDirectory
|
* @param {string} assetDirectory
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
process(assetDirectory) {
|
process(assetDirectory: string): void {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,17 +211,17 @@ class UnorderedListItem extends Symbol {
|
|||||||
/**
|
/**
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
text = "";
|
text: string = "";
|
||||||
/**
|
/**
|
||||||
* @type {number}
|
* @type {number}
|
||||||
*/
|
*/
|
||||||
level = 0;
|
level: number = 0;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string} line
|
* @param {string} line
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
static canParse(line) {
|
static canParse(line: string): boolean {
|
||||||
return line.trim().startsWith("- ");
|
return line.trim().startsWith("- ");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,7 +230,7 @@ class UnorderedListItem extends Symbol {
|
|||||||
* @param {LineFeed} lineFeed
|
* @param {LineFeed} lineFeed
|
||||||
* @returns {Symbol}
|
* @returns {Symbol}
|
||||||
*/
|
*/
|
||||||
static create(lineFeed) {
|
static create(lineFeed: LineFeed): Symbol {
|
||||||
const instance = new UnorderedListItem();
|
const instance = new UnorderedListItem();
|
||||||
const line = lineFeed.claim();
|
const line = lineFeed.claim();
|
||||||
instance.text = line.replaceAll("-", "").trim();
|
instance.text = line.replaceAll("-", "").trim();
|
||||||
@@ -243,7 +243,7 @@ class UnorderedListItem extends Symbol {
|
|||||||
* @param {string} assetDirectory
|
* @param {string} assetDirectory
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
process(assetDirectory) {
|
process(assetDirectory: string): void {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,17 +256,17 @@ class OrderedListItem extends Symbol {
|
|||||||
/**
|
/**
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
text = "";
|
text: string = "";
|
||||||
/**
|
/**
|
||||||
* @type {number}
|
* @type {number}
|
||||||
*/
|
*/
|
||||||
level = 0;
|
level: number = 0;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string} line
|
* @param {string} line
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
static canParse(line) {
|
static canParse(line: string): boolean {
|
||||||
return new RegExp(/^\d\. /).test(line.trim());
|
return new RegExp(/^\d\. /).test(line.trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,7 +275,7 @@ class OrderedListItem extends Symbol {
|
|||||||
* @param {LineFeed} lineFeed
|
* @param {LineFeed} lineFeed
|
||||||
* @returns {Symbol}
|
* @returns {Symbol}
|
||||||
*/
|
*/
|
||||||
static create(lineFeed) {
|
static create(lineFeed: LineFeed): Symbol {
|
||||||
const instance = new UnorderedListItem();
|
const instance = new UnorderedListItem();
|
||||||
const line = lineFeed.claim();
|
const line = lineFeed.claim();
|
||||||
instance.text = line.trim().replace(/^\d\. /, "");
|
instance.text = line.trim().replace(/^\d\. /, "");
|
||||||
@@ -288,7 +288,7 @@ class OrderedListItem extends Symbol {
|
|||||||
* @param {string} assetDirectory
|
* @param {string} assetDirectory
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
process(assetDirectory) {
|
process(assetDirectory: string): void {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,25 +300,27 @@ class Link extends Symbol {
|
|||||||
/**
|
/**
|
||||||
* @type {RegExp}
|
* @type {RegExp}
|
||||||
*/
|
*/
|
||||||
static canParseRegExp = new RegExp(/^\[.*\]\(.*\)/);
|
static canParseRegExp: RegExp = new RegExp(/^\[.*\]\(.*\)/);
|
||||||
/**
|
/**
|
||||||
* @type {RegExp}
|
* @type {RegExp}
|
||||||
*/
|
*/
|
||||||
static textAndLinkRegExp = new RegExp(/\[(?<text>.*)\]\((?<link>.*)\)/);
|
static textAndLinkRegExp: RegExp = new RegExp(
|
||||||
|
/\[(?<text>.*)\]\((?<link>.*)\)/
|
||||||
|
);
|
||||||
/**
|
/**
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
text = "";
|
text: string = "";
|
||||||
/**
|
/**
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
link = "";
|
link: string = "";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string} line
|
* @param {string} line
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
static canParse(line) {
|
static canParse(line: string): boolean {
|
||||||
return Link.canParseRegExp.test(line.trim());
|
return Link.canParseRegExp.test(line.trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,7 +329,7 @@ class Link extends Symbol {
|
|||||||
* @param {LineFeed} lineFeed
|
* @param {LineFeed} lineFeed
|
||||||
* @returns {Symbol}
|
* @returns {Symbol}
|
||||||
*/
|
*/
|
||||||
static create(lineFeed) {
|
static create(lineFeed: LineFeed): Symbol {
|
||||||
const instance = new Link();
|
const instance = new Link();
|
||||||
const line = lineFeed.claim().trim();
|
const line = lineFeed.claim().trim();
|
||||||
const [linkLine, rest] = extractTokenAndRest(Link.textAndLinkRegExp, line);
|
const [linkLine, rest] = extractTokenAndRest(Link.textAndLinkRegExp, line);
|
||||||
@@ -343,7 +345,7 @@ class Link extends Symbol {
|
|||||||
* @param {string} assetDirectory
|
* @param {string} assetDirectory
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
process(assetDirectory) {
|
process(assetDirectory: string): void {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,29 +358,31 @@ class ImageLink extends Symbol {
|
|||||||
/**
|
/**
|
||||||
* @type {RegExp}
|
* @type {RegExp}
|
||||||
*/
|
*/
|
||||||
static canParseRegExp = new RegExp(/^!\[.*\]\(.*\)/);
|
static canParseRegExp: RegExp = new RegExp(/^!\[.*\]\(.*\)/);
|
||||||
/**
|
/**
|
||||||
* @type {RegExp}
|
* @type {RegExp}
|
||||||
*/
|
*/
|
||||||
static textAndLinkRegExp = new RegExp(/!\[(?<text>.*)\]\((?<link>.*)\)/);
|
static textAndLinkRegExp: RegExp = new RegExp(
|
||||||
|
/!\[(?<text>.*)\]\((?<link>.*)\)/
|
||||||
|
);
|
||||||
/**
|
/**
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
static assetDirectoryToken = "@asset/";
|
static assetDirectoryToken: string = "@asset/";
|
||||||
/**
|
/**
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
alt = "";
|
alt: string = "";
|
||||||
/**
|
/**
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
link = "";
|
link: string = "";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string} line
|
* @param {string} line
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
static canParse(line) {
|
static canParse(line: string): boolean {
|
||||||
return ImageLink.canParseRegExp.test(line.trim());
|
return ImageLink.canParseRegExp.test(line.trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,7 +391,7 @@ class ImageLink extends Symbol {
|
|||||||
* @param {LineFeed} lineFeed
|
* @param {LineFeed} lineFeed
|
||||||
* @returns {Symbol}
|
* @returns {Symbol}
|
||||||
*/
|
*/
|
||||||
static create(lineFeed, assetDirectory) {
|
static create(lineFeed: LineFeed, assetDirectory: string): Symbol {
|
||||||
const instance = new ImageLink();
|
const instance = new ImageLink();
|
||||||
const line = lineFeed.claim().trim();
|
const line = lineFeed.claim().trim();
|
||||||
const [linkLine, rest] = extractTokenAndRest(
|
const [linkLine, rest] = extractTokenAndRest(
|
||||||
@@ -408,7 +412,7 @@ class ImageLink extends Symbol {
|
|||||||
* @param {string} assetDirectory
|
* @param {string} assetDirectory
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
process(assetDirectory) {
|
process(assetDirectory: string): void {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,13 +425,13 @@ class Italic extends Symbol {
|
|||||||
/**
|
/**
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
text = "";
|
text: string = "";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string} line
|
* @param {string} line
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
static canParse(line) {
|
static canParse(line: string): boolean {
|
||||||
return line.startsWith("_");
|
return line.startsWith("_");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -436,7 +440,7 @@ class Italic extends Symbol {
|
|||||||
* @param {LineFeed} lineFeed
|
* @param {LineFeed} lineFeed
|
||||||
* @returns {Symbol}
|
* @returns {Symbol}
|
||||||
*/
|
*/
|
||||||
static create(lineFeed) {
|
static create(lineFeed: LineFeed): Symbol {
|
||||||
const instance = new Italic();
|
const instance = new Italic();
|
||||||
const line = lineFeed.claim().trim();
|
const line = lineFeed.claim().trim();
|
||||||
const lineWithoutStartingUnderscore = line.slice(1, line.length);
|
const lineWithoutStartingUnderscore = line.slice(1, line.length);
|
||||||
@@ -465,7 +469,7 @@ class Italic extends Symbol {
|
|||||||
* @param {string} assetDirectory
|
* @param {string} assetDirectory
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
process(assetDirectory) {
|
process(assetDirectory: string): void {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -478,13 +482,13 @@ class Bold extends Symbol {
|
|||||||
/**
|
/**
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
text = "";
|
text: string = "";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string} line
|
* @param {string} line
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
static canParse(line) {
|
static canParse(line: string): boolean {
|
||||||
return line.startsWith("**");
|
return line.startsWith("**");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -493,7 +497,7 @@ class Bold extends Symbol {
|
|||||||
* @param {LineFeed} lineFeed
|
* @param {LineFeed} lineFeed
|
||||||
* @returns {Symbol}
|
* @returns {Symbol}
|
||||||
*/
|
*/
|
||||||
static create(lineFeed) {
|
static create(lineFeed: LineFeed): Symbol {
|
||||||
const instance = new Bold();
|
const instance = new Bold();
|
||||||
const line = lineFeed.claim().trim();
|
const line = lineFeed.claim().trim();
|
||||||
const lineWithoutStartingUnderscore = line.slice(2, line.length);
|
const lineWithoutStartingUnderscore = line.slice(2, line.length);
|
||||||
@@ -522,7 +526,7 @@ class Bold extends Symbol {
|
|||||||
* @param {string} assetDirectory
|
* @param {string} assetDirectory
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
process(assetDirectory) {
|
process(assetDirectory: string): void {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -535,13 +539,13 @@ class SingleLineCode extends Symbol {
|
|||||||
/**
|
/**
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
text = "";
|
text: string = "";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string} line
|
* @param {string} line
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
static canParse(line) {
|
static canParse(line: string): boolean {
|
||||||
return line.startsWith("`");
|
return line.startsWith("`");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -550,7 +554,7 @@ class SingleLineCode extends Symbol {
|
|||||||
* @param {LineFeed} lineFeed
|
* @param {LineFeed} lineFeed
|
||||||
* @returns {Symbol}
|
* @returns {Symbol}
|
||||||
*/
|
*/
|
||||||
static create(lineFeed) {
|
static create(lineFeed: LineFeed): Symbol {
|
||||||
const instance = new SingleLineCode();
|
const instance = new SingleLineCode();
|
||||||
const line = lineFeed.claim().trim();
|
const line = lineFeed.claim().trim();
|
||||||
const lineWithoutStartingUnderscore = line.slice(1, line.length);
|
const lineWithoutStartingUnderscore = line.slice(1, line.length);
|
||||||
@@ -579,7 +583,7 @@ class SingleLineCode extends Symbol {
|
|||||||
* @param {string} assetDirectory
|
* @param {string} assetDirectory
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
process(assetDirectory) {
|
process(assetDirectory: string): void {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,13 +596,13 @@ class MultiLineCode extends Symbol {
|
|||||||
/**
|
/**
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
text = "";
|
text: string = "";
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string} line
|
* @param {string} line
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
static canParse(line) {
|
static canParse(line: string): boolean {
|
||||||
const trimmedLine = line.trim();
|
const trimmedLine = line.trim();
|
||||||
return trimmedLine.startsWith("```");
|
return trimmedLine.startsWith("```");
|
||||||
}
|
}
|
||||||
@@ -608,7 +612,7 @@ class MultiLineCode extends Symbol {
|
|||||||
* @param {LineFeed} lineFeed
|
* @param {LineFeed} lineFeed
|
||||||
* @returns {Symbol}
|
* @returns {Symbol}
|
||||||
*/
|
*/
|
||||||
static create(lineFeed) {
|
static create(lineFeed: LineFeed): Symbol {
|
||||||
const instance = new MultiLineCode();
|
const instance = new MultiLineCode();
|
||||||
const line = lineFeed.claim().trim();
|
const line = lineFeed.claim().trim();
|
||||||
const lineWithoutStartTag = line.slice(3, line.length);
|
const lineWithoutStartTag = line.slice(3, line.length);
|
||||||
@@ -656,7 +660,7 @@ class MultiLineCode extends Symbol {
|
|||||||
* @param {string} assetDirectory
|
* @param {string} assetDirectory
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
process(assetDirectory) {
|
process(assetDirectory: string): void {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -669,15 +673,15 @@ class TextRow extends Symbol {
|
|||||||
/**
|
/**
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
text = "";
|
text: string = "";
|
||||||
/**
|
/**
|
||||||
* @type {Symbol[]}
|
* @type {Symbol[]}
|
||||||
*/
|
*/
|
||||||
children = [];
|
children: Symbol[] = [];
|
||||||
/**
|
/**
|
||||||
* @type {Symbol[]}
|
* @type {Symbol[]}
|
||||||
*/
|
*/
|
||||||
allowedChildren = [
|
allowedChildren: (typeof Symbol)[] = [
|
||||||
Bold,
|
Bold,
|
||||||
Italic,
|
Italic,
|
||||||
ImageLink,
|
ImageLink,
|
||||||
@@ -691,7 +695,7 @@ class TextRow extends Symbol {
|
|||||||
* @param {string} line
|
* @param {string} line
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
static canParse(line) {
|
static canParse(line: string): boolean {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -700,7 +704,7 @@ class TextRow extends Symbol {
|
|||||||
* @param {LineFeed} lineFeed
|
* @param {LineFeed} lineFeed
|
||||||
* @returns {Symbol}
|
* @returns {Symbol}
|
||||||
*/
|
*/
|
||||||
static create(lineFeed) {
|
static create(lineFeed: LineFeed): Symbol {
|
||||||
const instance = new TextRow();
|
const instance = new TextRow();
|
||||||
instance.text = lineFeed.claim();
|
instance.text = lineFeed.claim();
|
||||||
return instance;
|
return instance;
|
||||||
@@ -711,7 +715,7 @@ class TextRow extends Symbol {
|
|||||||
* @param {string} assetDirectory
|
* @param {string} assetDirectory
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
process(assetDirectory) {
|
process(assetDirectory: string): void {
|
||||||
for (let i = 0; i < this.text.length; i++) {
|
for (let i = 0; i < this.text.length; i++) {
|
||||||
if (i === this.text.length - 1) {
|
if (i === this.text.length - 1) {
|
||||||
const plainText = new PlainText();
|
const plainText = new PlainText();
|
||||||
@@ -743,17 +747,17 @@ class PlainText extends Symbol {
|
|||||||
/**
|
/**
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
text = "";
|
text: string = "";
|
||||||
/**
|
/**
|
||||||
* @type {Symbol[]}
|
* @type {Symbol[]}
|
||||||
*/
|
*/
|
||||||
children = [];
|
children: Symbol[] = [];
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string} line
|
* @param {string} line
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
static canParse(line) {
|
static canParse(line: string): boolean {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -762,7 +766,7 @@ class PlainText extends Symbol {
|
|||||||
* @param {LineFeed} lineFeed
|
* @param {LineFeed} lineFeed
|
||||||
* @returns {Symbol}
|
* @returns {Symbol}
|
||||||
*/
|
*/
|
||||||
static create(lineFeed) {
|
static create(lineFeed: LineFeed): Symbol {
|
||||||
const instance = new PlainText();
|
const instance = new PlainText();
|
||||||
instance.text = lineFeed.claim();
|
instance.text = lineFeed.claim();
|
||||||
return instance;
|
return instance;
|
||||||
@@ -773,7 +777,7 @@ class PlainText extends Symbol {
|
|||||||
* @param {string} assetDirectory
|
* @param {string} assetDirectory
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
process(assetDirectory) {
|
process(assetDirectory: string): void {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -782,16 +786,21 @@ class PlainText extends Symbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isRegExp = (value: unknown): value is RegExp => value instanceof RegExp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string|RexExp} token
|
* @param {string|RexExp} token
|
||||||
* @param {string} string
|
* @param {string} string
|
||||||
* @returns {string[]}
|
* @returns {string[]}
|
||||||
*/
|
*/
|
||||||
const splitStringAtToken = (token, string) => {
|
const splitStringAtToken = (
|
||||||
|
token: string | RegExp,
|
||||||
|
string: string
|
||||||
|
): string[] => {
|
||||||
let index = 0;
|
let index = 0;
|
||||||
let length = 0;
|
let length = 0;
|
||||||
if (typeof token?.exec === "function") {
|
if (isRegExp(token)) {
|
||||||
const exp = new RegExp(token);
|
const exp = new RegExp(token);
|
||||||
const match = exp.exec(string);
|
const match = exp.exec(string);
|
||||||
index = match?.index ?? -1;
|
index = match?.index ?? -1;
|
||||||
@@ -808,14 +817,17 @@ const splitStringAtToken = (token, string) => {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string|RexExp} token
|
* @param {string|RegExp} token
|
||||||
* @param {string} string
|
* @param {string} string
|
||||||
* @returns {string[]}
|
* @returns {string[]}
|
||||||
*/
|
*/
|
||||||
const extractTokenAndRest = (token, string) => {
|
const extractTokenAndRest = (
|
||||||
|
token: string | RegExp,
|
||||||
|
string: string
|
||||||
|
): string[] => {
|
||||||
let index = 0;
|
let index = 0;
|
||||||
let length = 0;
|
let length = 0;
|
||||||
if (typeof token?.exec === "function") {
|
if (isRegExp(token)) {
|
||||||
const exp = new RegExp(token);
|
const exp = new RegExp(token);
|
||||||
const match = exp.exec(string);
|
const match = exp.exec(string);
|
||||||
index = match?.index ?? -1;
|
index = match?.index ?? -1;
|
||||||
@@ -835,7 +847,7 @@ const extractTokenAndRest = (token, string) => {
|
|||||||
* @param {string} token
|
* @param {string} token
|
||||||
* @param {string} string
|
* @param {string} string
|
||||||
*/
|
*/
|
||||||
const getAmountOfTokenInBeginningOfFile = (token, string) => {
|
const getAmountOfTokenInBeginningOfFile = (token: string, string: string) => {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
let searchIndex = 0;
|
let searchIndex = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -853,7 +865,7 @@ const getAmountOfTokenInBeginningOfFile = (token, string) => {
|
|||||||
/**
|
/**
|
||||||
* @type {Symbol[]}
|
* @type {Symbol[]}
|
||||||
*/
|
*/
|
||||||
const AllSymbols = [
|
const AllSymbols: (typeof Symbol)[] = [
|
||||||
JustALineBreak,
|
JustALineBreak,
|
||||||
Heading,
|
Heading,
|
||||||
UnorderedListItem,
|
UnorderedListItem,
|
||||||
@@ -873,7 +885,7 @@ const AllSymbols = [
|
|||||||
* @param {string} assetDirectory
|
* @param {string} assetDirectory
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
export const toHtml = (markdown, assetDirectory) => {
|
export const toHtml = (markdown: string, assetDirectory: string): string => {
|
||||||
// Stage one, markdown to symbols
|
// Stage one, markdown to symbols
|
||||||
const symbols = toSymbols(markdown, assetDirectory);
|
const symbols = toSymbols(markdown, assetDirectory);
|
||||||
|
|
||||||
@@ -895,7 +907,7 @@ export const toHtml = (markdown, assetDirectory) => {
|
|||||||
* @param {Symbol[]} symbols
|
* @param {Symbol[]} symbols
|
||||||
* @returns {Symbol[]}
|
* @returns {Symbol[]}
|
||||||
*/
|
*/
|
||||||
const stageThreeProcessing = (symbols) => {
|
const stageThreeProcessing = (symbols: Symbol[]): Symbol[] => {
|
||||||
const localSymbols = [...symbols];
|
const localSymbols = [...symbols];
|
||||||
// Turn line break pairs into paragraphs
|
// Turn line break pairs into paragraphs
|
||||||
while (localSymbols.filter((s) => s instanceof JustALineBreak).length !== 0) {
|
while (localSymbols.filter((s) => s instanceof JustALineBreak).length !== 0) {
|
||||||
@@ -929,13 +941,22 @@ const stageThreeProcessing = (symbols) => {
|
|||||||
* @param {Symbol[]} allowedSymbols
|
* @param {Symbol[]} allowedSymbols
|
||||||
* @returns {Symbol[]}
|
* @returns {Symbol[]}
|
||||||
*/
|
*/
|
||||||
const toSymbols = (markdown, assetDirectory, allowedSymbols = AllSymbols) => {
|
const toSymbols = (
|
||||||
|
markdown: string,
|
||||||
|
assetDirectory: string,
|
||||||
|
allowedSymbols: (typeof Symbol)[] = AllSymbols
|
||||||
|
): Symbol[] => {
|
||||||
const lineFeed = new LineFeed(markdown);
|
const lineFeed = new LineFeed(markdown);
|
||||||
const symbols = [];
|
const symbols: Symbol[] = [];
|
||||||
|
|
||||||
while (!lineFeed.isEmpty()) {
|
while (!lineFeed.isEmpty()) {
|
||||||
const line = lineFeed.peek();
|
const line = lineFeed.peek();
|
||||||
const factory = allowedSymbols.find((factory) => factory.canParse(line));
|
const factory = allowedSymbols.find((factory) => factory.canParse(line));
|
||||||
|
if (factory === undefined) {
|
||||||
|
const textRow = TextRow.create(lineFeed);
|
||||||
|
symbols.push(textRow);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const symbol = factory.create(lineFeed, assetDirectory);
|
const symbol = factory.create(lineFeed, assetDirectory);
|
||||||
symbols.push(symbol);
|
symbols.push(symbol);
|
||||||
}
|
}
|
||||||
102
packages/@zblog/toolchain/src/zblog-toolchain.ts
Normal file
102
packages/@zblog/toolchain/src/zblog-toolchain.ts
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
import * as fs from "fs";
|
||||||
|
import { toHtml } from "./markdown.js";
|
||||||
|
|
||||||
|
export type Paths = {
|
||||||
|
outputDirectory: string;
|
||||||
|
notes: {
|
||||||
|
rootPath: string;
|
||||||
|
assetsDirectoryName: string;
|
||||||
|
noteFileName: string;
|
||||||
|
};
|
||||||
|
templates: {
|
||||||
|
rootPath: string;
|
||||||
|
noteTemplateName: string;
|
||||||
|
indexTemplateName: string;
|
||||||
|
notFoundName: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export class ToolchainBuilder {
|
||||||
|
private paths: Paths;
|
||||||
|
constructor(paths: Paths) {
|
||||||
|
this.paths = paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
if (fs.readdirSync(".").includes(this.paths.outputDirectory)) {
|
||||||
|
fs.rmSync(this.paths.outputDirectory, { recursive: true, force: true });
|
||||||
|
console.log("Starting rebuild");
|
||||||
|
} else {
|
||||||
|
console.log("Starting build");
|
||||||
|
}
|
||||||
|
fs.mkdirSync(this.paths.outputDirectory);
|
||||||
|
console.log("Indexing content..");
|
||||||
|
const directoryNames = fs.readdirSync(this.paths.notes.rootPath);
|
||||||
|
const manifest = directoryNames.map((noteDirectory) => ({
|
||||||
|
directoryName: noteDirectory,
|
||||||
|
name: noteDirectory,
|
||||||
|
markdown: fs.readFileSync(
|
||||||
|
`${this.paths.notes.rootPath}/${noteDirectory}/${this.paths.notes.noteFileName}`,
|
||||||
|
{ encoding: "utf-8" }
|
||||||
|
),
|
||||||
|
assetDirectoryPath: `${this.paths.notes.rootPath}/${noteDirectory}/${this.paths.notes.assetsDirectoryName}`,
|
||||||
|
publicAssetDirectoryPath: `/${noteDirectory}_`,
|
||||||
|
}));
|
||||||
|
console.log("Parsing content..");
|
||||||
|
manifest.forEach((m) => {
|
||||||
|
const notePath = `${this.paths.templates.rootPath}/${this.paths.templates.noteTemplateName}`;
|
||||||
|
let htmlTemplate = fs.readFileSync(notePath, {
|
||||||
|
encoding: "utf-8",
|
||||||
|
});
|
||||||
|
htmlTemplate = htmlTemplate.replace(
|
||||||
|
"{{markdown}}",
|
||||||
|
toHtml(m.markdown, m.publicAssetDirectoryPath)
|
||||||
|
);
|
||||||
|
fs.writeFileSync(
|
||||||
|
`${this.paths.outputDirectory}/${m.directoryName}.html`,
|
||||||
|
htmlTemplate,
|
||||||
|
{
|
||||||
|
encoding: "utf-8",
|
||||||
|
flag: "ax",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (!fs.existsSync(m.assetDirectoryPath)) return;
|
||||||
|
const assetsList = fs.readdirSync(m.assetDirectoryPath);
|
||||||
|
assetsList.forEach((assetName) =>
|
||||||
|
fs.cpSync(
|
||||||
|
`${m.assetDirectoryPath}/${assetName}`,
|
||||||
|
`${this.paths.outputDirectory}/${m.name}_${assetName}`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
console.log("Moving static templates..");
|
||||||
|
[this.paths.templates.notFoundName].forEach((filename) => {
|
||||||
|
fs.copyFileSync(
|
||||||
|
`${this.paths.templates.rootPath}/${filename}`,
|
||||||
|
`${this.paths.outputDirectory}/${filename}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
console.log("Building startpage..");
|
||||||
|
let htmlTemplate = fs.readFileSync(
|
||||||
|
`${this.paths.templates.rootPath}/${this.paths.templates.indexTemplateName}`,
|
||||||
|
{
|
||||||
|
encoding: "utf-8",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const links = manifest
|
||||||
|
.map((m) => `<a href='/${m.directoryName}.html'>${m.name}</a>`)
|
||||||
|
.reverse();
|
||||||
|
const unorderedListItems = links.map((l) => `<li>${l}</li>`).join("\r\n");
|
||||||
|
const html = `
|
||||||
|
<ul>
|
||||||
|
${unorderedListItems}
|
||||||
|
<ul>
|
||||||
|
`;
|
||||||
|
htmlTemplate = htmlTemplate.replace("{{content}}", html);
|
||||||
|
fs.writeFileSync(`${this.paths.outputDirectory}/index.html`, htmlTemplate, {
|
||||||
|
encoding: "utf-8",
|
||||||
|
flag: "ax",
|
||||||
|
});
|
||||||
|
console.log("Done");
|
||||||
|
}
|
||||||
|
}
|
||||||
9
packages/@zblog/toolchain/tsconfig.json
Normal file
9
packages/@zblog/toolchain/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"include": ["src/zblog-toolchain.ts"],
|
||||||
|
"extends": "../../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "bin",
|
||||||
|
"declaration": true,
|
||||||
|
"declarationMap": true
|
||||||
|
}
|
||||||
|
}
|
||||||
10
readme.md
Normal file
10
readme.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# ZBlog
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
1. Clone the repository.
|
||||||
|
1. Install node 20.
|
||||||
|
1. Install all npmjs packages `npm run install --workspaces`
|
||||||
|
1. Build all workspaces `npm run build --workspaces`
|
||||||
|
1. Generate site `npm run generate-blog`
|
||||||
|
1. Start dev server `npm run dev`
|
||||||
18
src/index.ts
Normal file
18
src/index.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { Paths, ToolchainBuilder } from "@zblog/toolchain";
|
||||||
|
|
||||||
|
const paths: Paths = {
|
||||||
|
outputDirectory: "dist",
|
||||||
|
notes: {
|
||||||
|
rootPath: "src/notes",
|
||||||
|
assetsDirectoryName: "assets",
|
||||||
|
noteFileName: "note.md",
|
||||||
|
},
|
||||||
|
templates: {
|
||||||
|
rootPath: "src/templates",
|
||||||
|
noteTemplateName: "note.html",
|
||||||
|
indexTemplateName: "index.html",
|
||||||
|
notFoundName: "404.html",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
new ToolchainBuilder(paths).build();
|
||||||
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
14
tsconfig.json
Normal file
14
tsconfig.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"include": ["src/index.ts"],
|
||||||
|
"compilerOptions": {
|
||||||
|
"moduleResolution": "NodeNext",
|
||||||
|
"target": "ES2022" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
|
||||||
|
"module": "NodeNext" /* Specify what module code is generated. */,
|
||||||
|
"outDir": "bin" /* Specify an output folder for all emitted files. */,
|
||||||
|
"noEmit": false /* Disable emitting files from a compilation. */,
|
||||||
|
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
|
||||||
|
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
|
||||||
|
"strict": true /* Enable all strict type-checking options. */,
|
||||||
|
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user