Basic refactoring.
This commit is contained in:
parent
e5e0599bf6
commit
53bd81a8af
|
@ -15,9 +15,10 @@ article > header {
|
||||||
display: grid;
|
display: grid;
|
||||||
place-items: center;
|
place-items: center;
|
||||||
|
|
||||||
width: min(100%, 45ch);
|
width: fit-content;
|
||||||
|
|
||||||
padding: 1rem 2rem;
|
margin: 0 auto;
|
||||||
|
padding: 1rem 4rem;
|
||||||
background-color: var(--grey3);
|
background-color: var(--grey3);
|
||||||
border-radius: .5rem;
|
border-radius: .5rem;
|
||||||
box-shadow: 0 1rem 2rem var(--grey1);
|
box-shadow: 0 1rem 2rem var(--grey1);
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
{% include "templates/defaultTags.njk" %}
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>{{ serverName }} - Error 404</title>
|
<title>{{ serverName }} - Error 404</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
20
index.js
20
index.js
|
@ -15,29 +15,33 @@ const Config = JSON.parse(ConfigFile)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Create a server object
|
||||||
const Server = express()
|
const Server = express()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Some config
|
// Configure the assets directory
|
||||||
Server.use('/assets', express.static(Config.assetsDir))
|
Server.use('/assets', express.static(Config.assetsDir))
|
||||||
|
|
||||||
|
// Configure the nunjucks environment (HTML templating)
|
||||||
const njkEnv = njk.configure(
|
const njkEnv = njk.configure(
|
||||||
Config.contentDir,
|
Config.contentDir,
|
||||||
{
|
{
|
||||||
autoescape: true,
|
autoescape: true, // Automatically escape HTML aka a '<' will become '<'
|
||||||
watch: true,
|
watch: true, // Automatically reload all templates if they change on disk.
|
||||||
trimBlocks: true,
|
trimBlocks: true, // Remove trailing newlines from tags
|
||||||
lstripBlocks: true,
|
lstripBlocks: true, // Automatically remove leading whitespace from tags
|
||||||
express: Server
|
express: Server // Use the express server. (Currently obsolete, I think.)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Configure marked (markdown parser)
|
||||||
marked.use({
|
marked.use({
|
||||||
gfm: true,
|
gfm: true, // Use GitHub formatting?
|
||||||
renderer: markedRenderer
|
renderer: markedRenderer // Use my own custom rendering for som tags
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Let nunjucks use markdown.
|
||||||
njkMarkdown.register(njkEnv, marked)
|
njkMarkdown.register(njkEnv, marked)
|
||||||
|
|
||||||
|
|
||||||
|
|
16
libs/codeHighlighter.js
Normal file
16
libs/codeHighlighter.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import hljs from 'highlight.js'
|
||||||
|
|
||||||
|
export function highlight(code, lang) {
|
||||||
|
// Check if hljs recognises the language, else assume 'plaintext'.
|
||||||
|
const language = hljs.getLanguage(lang) ? lang : 'plaintext'
|
||||||
|
|
||||||
|
// Highlight it with the corresponding language.
|
||||||
|
return hljs.highlight(
|
||||||
|
// Switch out bullet points (•) to spaces (for proper indentation).
|
||||||
|
code.replace(/•/g, " "), { language })
|
||||||
|
// Replace newlines with <br> tags.
|
||||||
|
.value.replace(/\n/g, "<br>")
|
||||||
|
// Replace spaces with ' ' to forcefully render them.
|
||||||
|
.replace(/ /g, " "
|
||||||
|
)
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ export function parseExternalContext(externalContext) {
|
||||||
// If the line is falsey; leave.
|
// If the line is falsey; leave.
|
||||||
if (!line) return
|
if (!line) return
|
||||||
|
|
||||||
// Assign properties to parsedContext and give them values.
|
// Assign properties to parsedContext and give them their corresponding values.
|
||||||
line = line.split(/:/)
|
line = line.split(/:/)
|
||||||
parsedContext[line[0]] = line[1].replace(/^\s/, "")
|
parsedContext[line[0]] = line[1].replace(/^\s/, "")
|
||||||
})
|
})
|
||||||
|
|
26
libs/generateContext.js
Normal file
26
libs/generateContext.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import { JSDOM } from 'jsdom'
|
||||||
|
import { parseExternalContext } from './externalContext.js'
|
||||||
|
|
||||||
|
function generateToc(dom) {
|
||||||
|
// Get all ToC anchors from the DOM
|
||||||
|
const tocAnchors = dom.window.document.querySelectorAll(".toc-anchor")
|
||||||
|
|
||||||
|
// Generate links to lead to those anvhors.
|
||||||
|
let tocLinks = []
|
||||||
|
tocAnchors.forEach(anchor => tocLinks.push(`<a href="#${anchor.name}" class="${anchor.classList[1].replace("-anchor", "")}">${anchor.getAttribute('data-orig-text')}</a>`))
|
||||||
|
|
||||||
|
return tocLinks
|
||||||
|
}
|
||||||
|
|
||||||
|
export function generateContext(prerenderedNjk, externalContext = undefined) {
|
||||||
|
// Create a 'virtual DOM' for analysis.
|
||||||
|
const dom = new JSDOM(prerenderedNjk)
|
||||||
|
|
||||||
|
// Generate respective parts of the context.
|
||||||
|
return {
|
||||||
|
serverName: Config.serverName,
|
||||||
|
tocLinks: generateToc(dom),
|
||||||
|
externalMeta: externalContext ? parseExternalContext(externalContext) : undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,15 +1,7 @@
|
||||||
import hljs from 'highlight.js'
|
import { highlight } from "./codeHighlighter.js"
|
||||||
|
|
||||||
function highlight(code, lang) {
|
|
||||||
const language = hljs.getLanguage(lang) ? lang : 'plaintext'
|
|
||||||
return hljs.highlight(
|
|
||||||
code.replace(/•/g, " "), { language })
|
|
||||||
.value.replace(/\n/g, "<br>")
|
|
||||||
.replace(/ /g, " "
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const markedRenderer = {
|
export const markedRenderer = {
|
||||||
|
// Rendering of headings (add an anchor above all headings).
|
||||||
heading(text, level) {
|
heading(text, level) {
|
||||||
return `
|
return `
|
||||||
<a name="${text.replace(/\s/g, "-")}" data-orig-text="${text}" class="toc-anchor toc-anchor-h${level}"></a>
|
<a name="${text.replace(/\s/g, "-")}" data-orig-text="${text}" class="toc-anchor toc-anchor-h${level}"></a>
|
||||||
|
@ -19,6 +11,7 @@ export const markedRenderer = {
|
||||||
`
|
`
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Render code properly, and syntax highlight it.
|
||||||
code(code, lang, escaped) {
|
code(code, lang, escaped) {
|
||||||
return `
|
return `
|
||||||
<pre>
|
<pre>
|
||||||
|
|
|
@ -1,19 +1,21 @@
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import { mdRenderer, njkRenderer } from './siteRenderer.js'
|
import { mdRenderer, njkRenderer } from './siteRenderer.js'
|
||||||
|
|
||||||
|
|
||||||
|
// Handle all request and try to find a corresponding file/template.
|
||||||
export function requestHandler(req, res, Config) {
|
export function requestHandler(req, res, Config) {
|
||||||
|
// Check for njk files first
|
||||||
if (fs.existsSync(`./${Config.contentDir}/pages/${req.path}.njk`))
|
if (fs.existsSync(`./${Config.contentDir}/pages/${req.path}.njk`))
|
||||||
return res.send(njkRenderer(`./${Config.contentDir}/pages/${req.path}.njk`))
|
return res.send(njkRenderer(`./${Config.contentDir}/pages/${req.path}.njk`))
|
||||||
|
|
||||||
if (fs.existsSync(`./${Config.contentDir}/pages/${req.path}/index.njk`))
|
if (fs.existsSync(`./${Config.contentDir}/pages/${req.path}/index.njk`))
|
||||||
return res.send(njkRenderer(`./${Config.contentDir}/pages/${req.path}/index.njk`))
|
return res.send(njkRenderer(`./${Config.contentDir}/pages/${req.path}/index.njk`))
|
||||||
|
|
||||||
|
// Secondly search for markdown
|
||||||
if (fs.existsSync(`./${Config.contentDir}/pages/${req.path}.md`))
|
if (fs.existsSync(`./${Config.contentDir}/pages/${req.path}.md`))
|
||||||
return res.send(mdRenderer(`./${Config.contentDir}/pages/${req.path}.md`))
|
return res.send(mdRenderer(`./${Config.contentDir}/pages/${req.path}.md`))
|
||||||
|
|
||||||
if (fs.existsSync(`./${Config.contentDir}/pages/${req.path}/index.md`))
|
if (fs.existsSync(`./${Config.contentDir}/pages/${req.path}/index.md`))
|
||||||
return res.send(mdRenderer(`./${Config.contentDir}/pages/${req.path}/index.md`))
|
return res.send(mdRenderer(`./${Config.contentDir}/pages/${req.path}/index.md`))
|
||||||
|
|
||||||
|
// If no matching file is found, return a 404 error.
|
||||||
return res.status(404).send(njkRenderer(`./${Config.contentDir}/errors/404.njk`))
|
return res.status(404).send(njkRenderer(`./${Config.contentDir}/errors/404.njk`))
|
||||||
}
|
}
|
|
@ -1,38 +1,19 @@
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import njk from 'nunjucks'
|
import njk from 'nunjucks'
|
||||||
import { JSDOM } from 'jsdom'
|
import { generateContext } from './generateContext.js'
|
||||||
import { parseExternalContext } from './externalContext.js'
|
|
||||||
|
|
||||||
// Load in config
|
// Load in config
|
||||||
const ConfigFile = fs.readFileSync('./config.json')
|
const ConfigFile = fs.readFileSync('./config.json')
|
||||||
const Config = JSON.parse(ConfigFile)
|
const Config = JSON.parse(ConfigFile)
|
||||||
|
|
||||||
function generateToc(dom) {
|
|
||||||
const tocAnchors = dom.window.document.querySelectorAll(".toc-anchor")
|
|
||||||
let tocLinks = []
|
|
||||||
|
|
||||||
// This basically creates a proper link for the ToC. :)))
|
|
||||||
tocAnchors.forEach(anchor => tocLinks.push(`<a href="#${anchor.name}" class="${anchor.classList[1].replace("-anchor", "")}">${anchor.getAttribute('data-orig-text')}</a>`))
|
|
||||||
|
|
||||||
return tocLinks
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateContext(renderedNjk, externalContext = undefined) {
|
|
||||||
const dom = new JSDOM(renderedNjk)
|
|
||||||
|
|
||||||
return {
|
|
||||||
serverName: Config.serverName,
|
|
||||||
tocLinks: generateToc(dom),
|
|
||||||
externalMeta: externalContext ? parseExternalContext(externalContext) : undefined
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function njkRenderer(path) {
|
export function njkRenderer(path) {
|
||||||
|
// Read in the template
|
||||||
const njkFile = fs.readFileSync(path).toString()
|
const njkFile = fs.readFileSync(path).toString()
|
||||||
const renderedNjk = njk.renderString(njkFile)
|
// Pre-render it for analysis while rendering context
|
||||||
|
const prerenderedNjk = njk.renderString(njkFile)
|
||||||
const context = generateContext(renderedNjk)
|
|
||||||
|
|
||||||
|
// Generate proper context and make a final render of the template.
|
||||||
|
const context = generateContext(prerenderedNjk)
|
||||||
return njk.renderString(njkFile, context)
|
return njk.renderString(njkFile, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,10 +26,11 @@ export function mdRenderer(path) {
|
||||||
const externalMarkdown = externalMarkdownFile.replace(/^%%-\n[\S\s]*-%%\n/, "").replace(/```\w*[\s\S]*?```/g, match => match.replace(/ /g, "•"))
|
const externalMarkdown = externalMarkdownFile.replace(/^%%-\n[\S\s]*-%%\n/, "").replace(/```\w*[\s\S]*?```/g, match => match.replace(/ /g, "•"))
|
||||||
const externalContext = externalMarkdownFile.match(/^%%-\n[\S\s]*-%%\n/)[0]
|
const externalContext = externalMarkdownFile.match(/^%%-\n[\S\s]*-%%\n/)[0]
|
||||||
|
|
||||||
const renderedNjk = njk.renderString(njkFile, { externalMarkdown })
|
// Pre-render the template for analysis during context generation.
|
||||||
|
const prerenderedNjk = njk.renderString(njkFile, { externalMarkdown })
|
||||||
|
|
||||||
let context = generateContext(renderedNjk, externalContext)
|
// Generate the context and add the externalMarkdown to the context, then render the template.
|
||||||
|
let context = generateContext(prerenderedNjk, externalContext)
|
||||||
context.externalMarkdown = externalMarkdown
|
context.externalMarkdown = externalMarkdown
|
||||||
|
|
||||||
return njk.renderString(njkFile, context)
|
return njk.renderString(njkFile, context)
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user