blog-engine-sac
Advanced tools
Comparing version 1.0.4 to 1.0.8
@@ -1,5 +0,9 @@ | ||
import styles from "./styles.html.js"; | ||
import header from "./header.html.js"; | ||
import footer from "./footer.html.js"; | ||
export default function (options) { | ||
export { createAboutHtml }; | ||
import { styleSheets } from "./styles.html.js"; | ||
import { createHeaderHtml } from "./header.html.js"; | ||
import { createFooterHtml } from "./footer.html.js"; | ||
const createAboutHtml = (options) => { | ||
const { body, title, author, description } = options; | ||
@@ -18,3 +22,3 @@ return `<!DOCTYPE html> | ||
${styles(options)} | ||
${styleSheets(options)} | ||
@@ -24,3 +28,3 @@ </head> | ||
<body> | ||
${header({ ...options, topLevel: true })} | ||
${createHeaderHtml({ ...options, topLevel: true })} | ||
@@ -52,7 +56,6 @@ <header class="masthead" style="background-image: url('images/about-bg.jpg')"> | ||
<hr> | ||
${footer(options)} | ||
${createFooterHtml(options)} | ||
</body> | ||
</html> | ||
`; | ||
} | ||
}; |
@@ -1,6 +0,10 @@ | ||
import styles from "./styles.html.js"; | ||
import header from "./header.html.js"; | ||
import footer from "./footer.html.js"; | ||
export { createCategoryHtml }; | ||
import { styleSheets } from "./styles.html.js"; | ||
import { createHeaderHtml } from "./header.html.js"; | ||
import { createFooterHtml } from "./footer.html.js"; | ||
import { normalizeDate } from "../source/dates.js"; | ||
export default function (options) { | ||
const createCategoryHtml = (options) => { | ||
const { posts, categoryName } = options; | ||
@@ -12,7 +16,2 @@ const MAX_ARTICLE_PREVIEW = Number.MAX_SAFE_INTEGER || 3; | ||
posts.sort(function (postA, postB) { | ||
const postADate = normalizeDate(postA.creationDate); | ||
const postBDate = normalizeDate(postB.creationDate); | ||
return -(postADate - postBDate); | ||
}); | ||
const listOfPosts = posts.map(function (post) { | ||
@@ -40,9 +39,8 @@ // inline 3 first preview | ||
${styles(options)} | ||
${styleSheets(options)} | ||
</head> | ||
<body> | ||
${header({ ...options, topLevel: false })} | ||
${createHeaderHtml({ ...options, topLevel: false })} | ||
<!-- Page Header --> | ||
<header class="masthead" style="background-image: url('../images/home-bg.jpg')"> | ||
@@ -77,3 +75,3 @@ <div class="overlay"></div> | ||
<hr> | ||
${footer(options)} | ||
${createFooterHtml(options)} | ||
</body> | ||
@@ -83,3 +81,3 @@ </html> | ||
} | ||
}; | ||
@@ -1,11 +0,13 @@ | ||
import styles from "./styles.html.js"; | ||
import header from "./header.html.js"; | ||
import footer from "./footer.html.js"; | ||
export default function (options) { | ||
export { createContactHtml }; | ||
import { styleSheets } from "./styles.html.js"; | ||
import { createHeaderHtml } from "./header.html.js"; | ||
import { createFooterHtml } from "./footer.html.js"; | ||
const createContactHtml = (options) => { | ||
const { body, title, author, description } = options; | ||
return `<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8"> | ||
@@ -15,11 +17,8 @@ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> | ||
<meta name="author" content="${author}"> | ||
<title>Contact</title> | ||
${styles(options)} | ||
${styleSheets(options)} | ||
</head> | ||
<body> | ||
${header({ ...options, topLevel: true })} | ||
${createHeaderHtml({ ...options, topLevel: true })} | ||
<!-- Page Header --> | ||
@@ -51,3 +50,3 @@ <header class="masthead" style="background-image: url('images/contact-bg.jpg')"> | ||
<hr> | ||
${footer(options)} | ||
${createFooterHtml(options)} | ||
</body> | ||
@@ -57,3 +56,3 @@ </html> | ||
} | ||
}; | ||
@@ -0,3 +1,5 @@ | ||
export {createFooterHtml}; | ||
export default function (options) { | ||
const createFooterHtml = (options) => { | ||
const { footerText } = options; | ||
@@ -9,3 +11,3 @@ return ` | ||
<div class="col-lg-8 col-md-10 mx-auto"> | ||
<p><a href="#nav">Go to the top</a></p> | ||
<!--<p><a href="#nav">Go to the top</a></p>--> | ||
<p class="copyright text-muted">${footerText}</p> | ||
@@ -45,2 +47,2 @@ </div> | ||
} | ||
}; |
@@ -0,3 +1,5 @@ | ||
export { createHeaderHtml }; | ||
export default function (options) { | ||
const createHeaderHtml = (options) => { | ||
const {searchCode, topLevel} = options; | ||
@@ -32,2 +34,2 @@ let prePath; | ||
} | ||
}; |
@@ -1,6 +0,10 @@ | ||
import styles from "./styles.html.js"; | ||
import header from "./header.html.js"; | ||
import footer from "./footer.html.js"; | ||
export { createIndexHtml }; | ||
import { styleSheets } from "./styles.html.js"; | ||
import { createHeaderHtml } from "./header.html.js"; | ||
import { createFooterHtml } from "./footer.html.js"; | ||
import { normalizeDate } from "../source/dates.js"; | ||
export default function (options) { | ||
const createIndexHtml = (options) => { | ||
const { body, title, author, description, posts } = options; | ||
@@ -12,7 +16,2 @@ const MAX_ARTICLE_PREVIEW = Number.MAX_SAFE_INTEGER || 3; | ||
posts.sort(function (postA, postB) { | ||
const postADate = normalizeDate(postA.creationDate); | ||
const postBDate = normalizeDate(postB.creationDate); | ||
return -(postADate - postBDate); | ||
}); | ||
const postsPreview = posts.filter(function (post, index) { | ||
@@ -28,3 +27,3 @@ return index < MAX_ARTICLE_PREVIEW; | ||
${post.author} | ||
on <time>${post.creationDate}</time></p> | ||
on <time>${post.creationDateString}</time></p> | ||
</a>`; | ||
@@ -51,7 +50,7 @@ // const postsPreview = `<hr> | ||
<title>Blog</title> | ||
${styles(options)} | ||
${styleSheets(options)} | ||
</head> | ||
<body> | ||
${header({ ...options, topLevel: true })} | ||
${createHeaderHtml({ ...options, topLevel: true })} | ||
<header class="masthead" style="background-image: url('images/home-bg.jpg')"> | ||
@@ -88,3 +87,3 @@ <div class="overlay"></div> | ||
<hr> | ||
${footer(options)} | ||
${createFooterHtml(options)} | ||
</body> | ||
@@ -94,3 +93,2 @@ </html> | ||
} | ||
}; |
@@ -1,14 +0,16 @@ | ||
import styles from "./styles.html.js"; | ||
import footer from "./footer.html.js"; | ||
import header from "./header.html.js"; | ||
export {createPostHtml}; | ||
import { styleSheets } from "./styles.html.js"; | ||
import { createFooterHtml } from "./footer.html.js"; | ||
import { createHeaderHtml } from "./header.html.js"; | ||
import { normalizeDate } from "../source/dates.js"; | ||
export default function (options) { | ||
const { body, title, author, description, creationDate } = options; | ||
const createPostHtml = (options) => { | ||
const { body, title, author, description, creationDateString, modifiedDateString } = options; | ||
let lastEdit; | ||
if (normalizeDate(options.modifiedDate) === normalizeDate(options.creationDate)) { | ||
if (modifiedDateString === creationDateString) { | ||
lastEdit = ``; | ||
} else { | ||
lastEdit = `<p>Last edit: <time>${options.modifiedDate}</time></p>`; | ||
lastEdit = `<p>Last edit: <time>${modifiedDateString}</time></p>`; | ||
} | ||
@@ -25,7 +27,7 @@ return `<!DOCTYPE html> | ||
<title>${title}</title> | ||
${styles(options)} | ||
${styleSheets(options)} | ||
</head> | ||
<body> | ||
${header({ ...options, topLevel: false })} | ||
${createHeaderHtml({ ...options, topLevel: false })} | ||
<header class="masthead" style="background-image: url('../images/post-bg.jpg')"> | ||
@@ -41,3 +43,3 @@ <div class="overlay"></div> | ||
${author} | ||
${creationDate} | ||
${creationDateString} | ||
</span> | ||
@@ -62,7 +64,7 @@ </div> | ||
<h3>Tags</h3> | ||
<ul> | ||
${options.finalTags.map(function (tag) { | ||
return `<li>${tag}</li>`; | ||
}).join(``)} | ||
</ul> | ||
<ul>${ | ||
options.finalTags.map(function (tag) { | ||
return `<li>${tag}</li>`; | ||
}).join(``) | ||
}</ul> | ||
</div> | ||
@@ -72,3 +74,5 @@ </div> | ||
<hr> | ||
${footer(options)} | ||
${nextInteractionHtml(options)} | ||
<hr> | ||
${createFooterHtml(options)} | ||
</body> | ||
@@ -78,2 +82,24 @@ </html> | ||
} | ||
}; | ||
// duplicate from search | ||
const makeUrl = (ref) => { | ||
return `/b/${ref}`; | ||
}; | ||
const nextInteractionHtml = (post) => { | ||
const {next, previous} = post; | ||
let nextHtml = ``; | ||
let previousHtml = ``; | ||
if (next) { | ||
nextHtml = `Next ${linkFromName(next)}`; | ||
} | ||
if (previous) { | ||
previousHtml = `Previous ${linkFromName(previous)}`; | ||
} | ||
return `<p class="col-lg-8 col-md-10 mx-auto">${nextHtml} ${previousHtml}</p>`; | ||
}; | ||
const linkFromName = (post) => { | ||
const {title} = post; | ||
return `<a href="${makeUrl(title)}">${title}</a>`; | ||
}; |
@@ -1,5 +0,8 @@ | ||
export default function (options) { | ||
export {styleSheets}; | ||
const styleSheets = (options) => { | ||
return ` | ||
<link href="/css/bootstrap.min.css" rel="stylesheet"> | ||
<link href="/css/clean-blog.min.css" rel="stylesheet">`; | ||
} | ||
}; |
@@ -34,2 +34,5 @@ export { searchCodeTemplate }; | ||
}; | ||
const makeUrl = (ref) => { | ||
return \`/b/\${ref}\`; | ||
}; | ||
@@ -45,6 +48,7 @@ searchInput.addEventListener("input", (event) => { | ||
const elements = results.map(url => { | ||
const elements = results.map(ref => { | ||
const url = makeUrl(ref); // root url | ||
const li = document.createElement("li"); | ||
const a = document.createElement("a"); | ||
a.textContent = url; | ||
a.textContent = ref; | ||
a.href = url; | ||
@@ -51,0 +55,0 @@ li.appendChild(a); |
{ | ||
"name": "blog-engine-sac", | ||
"version": "1.0.4", | ||
"version": "1.0.8", | ||
"type": "module", | ||
"bin": { | ||
"blog-engine-sac": "source/main.js" | ||
}, | ||
"scripts": { | ||
"lint-fix": "eslint --ignore-path .gitignore --fix source html", | ||
"lint": "eslint --ignore-path .gitignore source html" | ||
}, | ||
"dependencies": { | ||
@@ -18,10 +25,2 @@ "bootstrap": "^4.3.1", | ||
}, | ||
"scripts": { | ||
"lint-fix": "eslint --ignore-path .gitignore --fix source html", | ||
"lint": "eslint --ignore-path .gitignore source html", | ||
"build": "node --experimental-modules source/buildPosts.js" | ||
}, | ||
"bin": { | ||
"blog-engine-sac": "npm run build" | ||
}, | ||
"eslintConfig": { | ||
@@ -28,0 +27,0 @@ "extends": [ |
@@ -13,3 +13,3 @@ # Blog | ||
4. [npm i blog-engine-sac --ignore-scripts](https://www.npmjs.com/package/blog-engine-sac) | ||
5. add script "sac": "blog-engine-sac" or "node --experimental-modules node_modules/blog-engine-sac/source/buildPosts.js" if installed locally | ||
5. add script "sac": "blog-engine-sac" or "node --experimental-modules node_modules/blog-engine-sac/source/main.js" if installed locally | ||
5. follow instructions below to create required files | ||
@@ -16,0 +16,0 @@ 6. npm run build |
@@ -1,6 +0,191 @@ | ||
// main file | ||
import "./patchNode.js"; | ||
import { buildSite } from "./buildSite.js"; | ||
export { processPost, supportedFormats, getDetailsFromPost }; | ||
import { statSync, readdir, fstat } from "fs"; | ||
import { extname, basename, parse as parsePath } from "path"; | ||
import { textFileContent } from "filesac"; | ||
import { normalizeFileName } from "./strings.js"; | ||
import { isLocalUrl } from "./urls.js"; | ||
import markdownModule from "markdown"; | ||
const { markdown } = markdownModule; | ||
import nodeHtmlParser from "node-html-parser"; | ||
const { parse } = nodeHtmlParser; | ||
buildSite(); | ||
const supportedFormats = [`md`, `json`, `html`]; | ||
const processPost = async function ({ title, extension, postFilePath, fullPath }, detailedFiles) { | ||
if (!supportedFormats.includes(extension)) { | ||
return; | ||
} | ||
const [meta, content] = await Promise.all([ | ||
initialMeta({ fullPath, title }, detailedFiles), | ||
textFileContent(fullPath), | ||
]); | ||
if (extension === `html`) { | ||
return processPostAsHTML({ title, extension, postFilePath, fullPath, meta, content }); | ||
} | ||
if (extension === `md`) { | ||
return processPostAsMD({ title, extension, postFilePath, fullPath, meta, content }); | ||
} | ||
if (extension === `json`) { | ||
return processPostAsJSON({ title, extension, postFilePath, fullPath, meta, content }, detailedFiles); | ||
} | ||
}; | ||
const processPostAsHTML = function ({ title, extension, postFilePath, fullPath, meta, content }) { | ||
const htmlContainers = [`html`, `body`, `head`]; | ||
const rootOriginal = parse(content); | ||
const root = rootOriginal.firstChild; | ||
const rawText = root.text; | ||
let htmlBody; | ||
if (!htmlContainers.includes(root.tagName)) { | ||
htmlBody = rootOriginal.innerHTML; | ||
} else if (root.tagName === `html`) { | ||
const html = root; | ||
const head = html.querySelector(`head`); | ||
const body = html.querySelector(`body`); | ||
if (body) { | ||
htmlBody = body.innerHTML; | ||
} else { | ||
htmlBody = root.innerHTML; | ||
} | ||
} else if (root.tagName === `body`) { | ||
const body = root; | ||
htmlBody = body.innerHTML; | ||
} else { | ||
console.warn(`${root.tagName} as root is not supported`); | ||
htmlBody = ``; | ||
} | ||
const post = Object.assign({ | ||
body: htmlBody, | ||
raw: rawText, | ||
}, meta); | ||
return post; | ||
}; | ||
const processPostAsMD = function ({ title, extension, postFilePath, fullPath, meta, content }) { | ||
const postHTML = markdown.toHTML(content); | ||
const post = Object.assign({ | ||
body: postHTML, | ||
raw: content, | ||
}, meta); | ||
return post; | ||
}; | ||
const processExternalPost = function ({ src, meta }) { | ||
return fetch(src).then(response => { | ||
if (response.ok) { | ||
return response.text(); | ||
} | ||
throw `failed to fetch ${src}`; | ||
}).then(text => { | ||
return Object.assign({ | ||
body: text, | ||
raw: text, | ||
title: src, | ||
}, meta); | ||
}).catch(error => { | ||
console.warn(`could not fetch ${src}`); | ||
// todo idea, put sucessful stuff inside a intermediate folder inbetween source and built | ||
// if not fetch possible use that intermediate folder | ||
return Object.assign({ | ||
body: `request failed`, | ||
raw: `request failed`, | ||
title: src, | ||
}, meta); | ||
}); | ||
}; | ||
const processPostAsJSON = function ({ title, extension, postFilePath, fullPath, meta, content }, detailedFiles) { | ||
let postObject; | ||
try { | ||
postObject = JSON.parse(content); | ||
} catch (error) { | ||
console.error(`could not parse as JSON ${fullPath}`); | ||
console.error(error); | ||
return; | ||
} | ||
const { src } = postObject; | ||
if (!src) { | ||
return; | ||
} | ||
if (isLocalUrl(src)) { | ||
// open from file | ||
return processPost(getDetailsFromPost(src), detailedFiles); | ||
} | ||
return processExternalPost({ src, meta }); | ||
}; | ||
const defaultMetaFromPost = function ({ fullPath, title }) { | ||
let stats; | ||
if (isLocalUrl(fullPath)) { | ||
stats = statSync(fullPath); | ||
} else { | ||
stats = {}; | ||
} | ||
const meta = { | ||
hasExternalMeta: false, | ||
externalMeta: ``, | ||
creationDate: stats.birthtime, | ||
creationDateString: ``, | ||
modifiedDate: stats.mtime, | ||
modifiedDateString: ``, | ||
title: normalizeFileName(title), | ||
author: undefined, | ||
description: `post`, | ||
next: undefined, | ||
previous: undefined, | ||
categories: [], | ||
tags: [], | ||
generatedTags: [], | ||
finalTags: [], | ||
words: {}, | ||
}; | ||
return meta; | ||
}; | ||
const extendMetaWithPotentialMeta = function ({ fullPath, title, meta }, detailedFiles) { | ||
const metaFile = detailedFiles.find(function (detailedFile) { | ||
return ( | ||
(detailedFile.title === title) && | ||
(detailedFile.extension === `json`) | ||
); | ||
}); | ||
meta.hasExternalMeta = Boolean(metaFile); | ||
if (!meta.hasExternalMeta) { | ||
// do not extend meta | ||
return Promise.resolve(meta); | ||
} | ||
return textFileContent(`${metaFile.fullPath}`).then(function (metaText) { | ||
Object.assign(meta, JSON.parse(metaText)); | ||
}); | ||
}; | ||
const initialMeta = function ({ fullPath, title }, detailedFiles) { | ||
const meta = defaultMetaFromPost({ fullPath, title }); | ||
return extendMetaWithPotentialMeta({ fullPath, title, meta }, detailedFiles).then(function () { | ||
return meta; | ||
}); | ||
}; | ||
const getDetailsFromPost = function (fullPath) { | ||
const parsedPath = parsePath(fullPath); | ||
const title = parsedPath.name; | ||
const extension = extname(fullPath).substr(1); | ||
if (!supportedFormats.includes(extension) && extension !== ``) { | ||
console.warn(`File format from ${fullPath} is ${extension} and not recognized. | ||
Use one of ${supportedFormats.join(`, `)} instead.`); | ||
} | ||
console.log(`\t* ${fullPath}`); | ||
return { title, extension, base: parsedPath.base, fullPath }; | ||
}; |
@@ -6,14 +6,9 @@ /* stats.birthtime, can be later than modified date | ||
export { buildSite }; | ||
import { extname, basename, parse as parsePath } from "path"; | ||
import { statSync, readdir, fstat } from "fs"; | ||
import { textFileContent, writeTextInFile, namesInDirectory } from "filesac"; | ||
import { generateTags, wordCount } from "./tags.js"; | ||
import { normalizeFileName } from "./strings.js"; | ||
import { niceDateString } from "./dates.js"; | ||
import { isLocalUrl } from "./urls.js"; | ||
import { niceDateString, normalizeDate } from "./dates.js"; | ||
import { staticCopies } from "./staticCopies.js"; | ||
import { generateSearchCode } from "./search.js"; | ||
import { processPost, getDetailsFromPost } from "./buildPosts.js"; | ||
import nodeHtmlParser from "node-html-parser"; | ||
const { parse } = nodeHtmlParser; | ||
@@ -23,7 +18,7 @@ import markdownModule from "markdown"; | ||
import blogHTMLTemplate from "../html/post.html.js"; | ||
import indexHTMLTemplate from "../html/index.html.js"; | ||
import contactHTMLTemplate from "../html/contact.html.js"; | ||
import aboutHTMLTemplate from "../html/about.html.js"; | ||
import categoryHTMLTemplate from "../html/category.html.js"; | ||
import { createPostHtml } from "../html/post.html.js"; | ||
import {createIndexHtml } from "../html/index.html.js"; | ||
import { createContactHtml } from "../html/contact.html.js"; | ||
import { createAboutHtml } from "../html/about.html.js"; | ||
import { createCategoryHtml } from "../html/category.html.js"; | ||
@@ -43,183 +38,10 @@ // sources | ||
const author = `Cyril Walle`; | ||
const formats = [`md`, `json`, `html`]; | ||
const niceDatesOnPost = function (post) { | ||
post.modifiedDate = niceDateString(post.modifiedDate); | ||
post.creationDate = niceDateString(post.creationDate); | ||
post.modifiedDateString = niceDateString(post.modifiedDate); | ||
post.creationDateString = niceDateString(post.creationDate); | ||
}; | ||
const getDetailsFromPost = function (fullPath) { | ||
const parsedPath = parsePath(fullPath); | ||
const title = parsedPath.name; | ||
const extension = extname(fullPath).substr(1); | ||
if (!formats.includes(extension) && extension !== ``) { | ||
console.warn(`File format from ${fullPath} is ${extension} and not recognized. | ||
Use one of ${formats.join(`, `)} instead.`); | ||
} | ||
console.log(`\t* ${fullPath}`); | ||
return { title, extension, base: parsedPath.base, fullPath }; | ||
}; | ||
const defaultMetaFromPost = function ({ fullPath, title }) { | ||
let stats; | ||
if (isLocalUrl(fullPath)) { | ||
stats = statSync(fullPath); | ||
} else { | ||
stats = {}; | ||
} | ||
const meta = { | ||
hasExternalMeta: false, | ||
externalMeta: ``, | ||
creationDate: stats.birthtime, | ||
modifiedDate: stats.mtime, | ||
title: normalizeFileName(title), | ||
author, | ||
description: `post`, | ||
categories: [], | ||
tags: [], | ||
generatedTags: [], | ||
finalTags: [], | ||
words: {}, | ||
}; | ||
return meta; | ||
}; | ||
const extendMetaWithPotentialMeta = function ({ fullPath, title, meta }, detailedFiles) { | ||
const metaFile = detailedFiles.find(function (detailedFile) { | ||
return ( | ||
(detailedFile.title === title) && | ||
(detailedFile.extension === `json`) | ||
); | ||
}); | ||
meta.hasExternalMeta = Boolean(metaFile); | ||
if (!meta.hasExternalMeta) { | ||
// do not extend meta | ||
return Promise.resolve(meta); | ||
} | ||
return textFileContent(`${metaFile.fullPath}`).then(function (metaText) { | ||
Object.assign(meta, JSON.parse(metaText)); | ||
}); | ||
}; | ||
const baseMeta = function ({ fullPath, title }, detailedFiles) { | ||
const meta = defaultMetaFromPost({ fullPath, title }); | ||
return extendMetaWithPotentialMeta({ fullPath, title, meta }, detailedFiles).then(function () { | ||
return meta; | ||
}); | ||
}; | ||
const processPostAsHTML = function ({ title, extension, postFilePath, fullPath, meta, content }) { | ||
const htmlContainers = [`html`, `body`, `head`]; | ||
const rootOriginal = parse(content); | ||
const root = rootOriginal.firstChild; | ||
const rawText = root.text; | ||
let htmlBody; | ||
if (!htmlContainers.includes(root.tagName)) { | ||
htmlBody = rootOriginal.innerHTML; | ||
} else if (root.tagName === `html`) { | ||
const html = root; | ||
const head = html.querySelector(`head`); | ||
const body = html.querySelector(`body`); | ||
if (body) { | ||
htmlBody = body.innerHTML; | ||
} else { | ||
htmlBody = root.innerHTML; | ||
} | ||
} else if (root.tagName === `body`) { | ||
const body = root; | ||
htmlBody = body.innerHTML; | ||
} else { | ||
console.warn(`${root.tagName} as root is not supported`); | ||
htmlBody = ``; | ||
} | ||
const post = Object.assign({ | ||
body: htmlBody, | ||
raw: rawText, | ||
}, meta); | ||
return post; | ||
}; | ||
const processPostAsMD = function ({ title, extension, postFilePath, fullPath, meta, content }) { | ||
const postHTML = markdown.toHTML(content); | ||
const post = Object.assign({ | ||
body: postHTML, | ||
raw: content, | ||
}, meta); | ||
return post; | ||
}; | ||
const processExternalPost = function ({ src, meta }) { | ||
return fetch(src).then(response => { | ||
if (response.ok) { | ||
return response.text(); | ||
} | ||
throw `failed to fetch ${src}`; | ||
}).then(text => { | ||
return Object.assign({ | ||
body: text, | ||
raw: text, | ||
title: src, | ||
}, meta); | ||
}).catch(error => { | ||
console.warn(`could not fetch ${src}`); | ||
// todo idea, put sucessful stuff inside a intermediate folder inbetween source and built | ||
// if not fetch possible use that intermediate folder | ||
return Object.assign({ | ||
body: `request failed`, | ||
raw: `request failed`, | ||
title: src, | ||
}, meta); | ||
}); | ||
}; | ||
const processPostAsJSON = function ({ title, extension, postFilePath, fullPath, meta, content }, detailedFiles) { | ||
let postObject; | ||
try { | ||
postObject = JSON.parse(content); | ||
} catch (error) { | ||
console.error(`could not parse as JSON ${fullPath}`); | ||
console.error(error); | ||
return; | ||
} | ||
const { src } = postObject; | ||
if (!src) { | ||
return; | ||
} | ||
if (isLocalUrl(src)) { | ||
// open from file | ||
return processPost(getDetailsFromPost(src), detailedFiles); | ||
} | ||
return processExternalPost({ src, meta }); | ||
}; | ||
const processPost = async function ({ title, extension, postFilePath, fullPath }, detailedFiles) { | ||
if (!formats.includes(extension)) { | ||
return; | ||
} | ||
const [meta, content] = await Promise.all([ | ||
baseMeta({ fullPath, title }, detailedFiles), | ||
textFileContent(fullPath), | ||
]); | ||
if (extension === `html`) { | ||
return processPostAsHTML({ title, extension, postFilePath, fullPath, meta, content }); | ||
} | ||
if (extension === `md`) { | ||
return processPostAsMD({ title, extension, postFilePath, fullPath, meta, content }); | ||
} | ||
if (extension === `json`) { | ||
return processPostAsJSON({ title, extension, postFilePath, fullPath, meta, content }, detailedFiles); | ||
} | ||
}; | ||
const createCategories = function (posts) { | ||
@@ -243,3 +65,3 @@ const categories = {}; | ||
Object.entries(categories).map(function ([categoryName, posts]) { | ||
const categoryHTML = categoryHTMLTemplate(Object.assign({ | ||
const categoryHTML = createCategoryHtml(Object.assign({ | ||
categoryName, | ||
@@ -256,7 +78,5 @@ posts, | ||
const createIndex = async function (posts, categories, commonOptions) { | ||
const searchCode = await generateSearchCode(posts); | ||
const indexHTML = indexHTMLTemplate(Object.assign({ | ||
const indexHTML = createIndexHtml(Object.assign({ | ||
posts, | ||
categories, | ||
searchCode, | ||
}, commonOptions)); | ||
@@ -269,3 +89,3 @@ return writeTextInFile(indexPath, indexHTML); | ||
const contactHTMLBody = markdown.toHTML(contactMarkdown); | ||
return writeTextInFile(`${builtBlog}/contact.html`, contactHTMLTemplate(Object.assign({ | ||
return writeTextInFile(`${builtBlog}/contact.html`, createContactHtml(Object.assign({ | ||
body: contactHTMLBody, | ||
@@ -281,3 +101,3 @@ }, commonOptions))); | ||
const aboutHTMLBody = markdown.toHTML(aboutMarkdown); | ||
return writeTextInFile(`${builtBlog}/about.html`, aboutHTMLTemplate(Object.assign({ | ||
return writeTextInFile(`${builtBlog}/about.html`, createAboutHtml(Object.assign({ | ||
body: aboutHTMLBody, | ||
@@ -292,3 +112,3 @@ }, commonOptions))); | ||
return Promise.all(posts.map(function (post) { | ||
const postInsideHTML = blogHTMLTemplate(Object.assign(post, commonOptions)); | ||
const postInsideHTML = createPostHtml(Object.assign(post, commonOptions)); | ||
return writeTextInFile(`${blogPath}${post.title}.html`, postInsideHTML); | ||
@@ -299,2 +119,6 @@ })); | ||
const buildSite = async () => { | ||
// independent | ||
const staticPromise = staticCopies({ | ||
builtBlog, | ||
}); | ||
const commonOptions = { | ||
@@ -304,3 +128,3 @@ author, | ||
}; | ||
const [files, footerText] = await Promise.all([ | ||
const [sourceFileNames, footerText] = await Promise.all([ | ||
namesInDirectory(postsPath), | ||
@@ -312,22 +136,21 @@ textFileContent(footerSource), | ||
// independent | ||
const contactPromise = createContact(commonOptions); | ||
const aboutPromise = createAbout(commonOptions); | ||
const staticPromise = staticCopies({ | ||
builtBlog, | ||
}); | ||
const files2 = files.map((file) => { | ||
const sourceFileNames2 = sourceFileNames.map((file) => { | ||
return `${postsPath}${file}`; | ||
}); | ||
const detailedFiles = files2.map(getDetailsFromPost); | ||
const detailedSources = sourceFileNames2.map(getDetailsFromPost); | ||
const posts = (await Promise.all( | ||
detailedFiles.map(post => { | ||
return processPost(post, detailedFiles); | ||
}) | ||
)).filter(Boolean); | ||
const posts = (await Promise.all(detailedSources.map(post => { | ||
return processPost(post, detailedSources); | ||
}))).filter(Boolean); | ||
posts.sort(function (postA, postB) { | ||
const postADate = normalizeDate(postA.creationDate); | ||
const postBDate = normalizeDate(postB.creationDate); | ||
return -(postADate - postBDate); | ||
}); | ||
posts.forEach(function (post, i) { | ||
post.previous = posts[i - 1]; | ||
post.next = posts[i + 1]; | ||
}); | ||
const allWords = wordCount(posts); | ||
generateTags(posts, allWords); | ||
@@ -339,2 +162,6 @@ posts.forEach(function (post) { | ||
}); | ||
commonOptions.searchCode = await generateSearchCode(posts); | ||
const contactPromise = createContact(commonOptions); | ||
const aboutPromise = createAbout(commonOptions); | ||
const categories = createCategories(posts, commonOptions); | ||
@@ -341,0 +168,0 @@ createCategoryPages(categories); |
@@ -34,3 +34,2 @@ export { generateSearchCode }; | ||
resolveFileUrl({ relativePath, format }) { | ||
console.log(27) | ||
if (id === SEARCH) { | ||
@@ -44,7 +43,7 @@ return `new ${URL}('./search.js').href` | ||
// return a string to let load do the rest | ||
console.log(39, importee, importer) | ||
// console.log(importee, importer) | ||
return importee; | ||
}, | ||
load: function (id) { | ||
console.log(52, id) | ||
// console.log(id) | ||
@@ -51,0 +50,0 @@ if (id === SEARCH) { |
100169
24
2178