Basic refactoring.
This commit is contained in:
parent
e5e0599bf6
commit
53bd81a8af
|
@ -15,9 +15,10 @@ article > header {
|
|||
display: grid;
|
||||
place-items: center;
|
||||
|
||||
width: min(100%, 45ch);
|
||||
width: fit-content;
|
||||
|
||||
padding: 1rem 2rem;
|
||||
margin: 0 auto;
|
||||
padding: 1rem 4rem;
|
||||
background-color: var(--grey3);
|
||||
border-radius: .5rem;
|
||||
box-shadow: 0 1rem 2rem var(--grey1);
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
{% include "templates/defaultTags.njk" %}
|
||||
<title>{{ serverName }} - Error 404</title>
|
||||
</head>
|
||||
<body>
|
||||
|
|
20
index.js
20
index.js
|
@ -15,29 +15,33 @@ const Config = JSON.parse(ConfigFile)
|
|||
|
||||
|
||||
|
||||
// Create a server object
|
||||
const Server = express()
|
||||
|
||||
|
||||
|
||||
// Some config
|
||||
// Configure the assets directory
|
||||
Server.use('/assets', express.static(Config.assetsDir))
|
||||
|
||||
// Configure the nunjucks environment (HTML templating)
|
||||
const njkEnv = njk.configure(
|
||||
Config.contentDir,
|
||||
{
|
||||
autoescape: true,
|
||||
watch: true,
|
||||
trimBlocks: true,
|
||||
lstripBlocks: true,
|
||||
express: Server
|
||||
autoescape: true, // Automatically escape HTML aka a '<' will become '<'
|
||||
watch: true, // Automatically reload all templates if they change on disk.
|
||||
trimBlocks: true, // Remove trailing newlines from tags
|
||||
lstripBlocks: true, // Automatically remove leading whitespace from tags
|
||||
express: Server // Use the express server. (Currently obsolete, I think.)
|
||||
}
|
||||
)
|
||||
|
||||
// Configure marked (markdown parser)
|
||||
marked.use({
|
||||
gfm: true,
|
||||
renderer: markedRenderer
|
||||
gfm: true, // Use GitHub formatting?
|
||||
renderer: markedRenderer // Use my own custom rendering for som tags
|
||||
})
|
||||
|
||||
// Let nunjucks use markdown.
|
||||
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, " "
|
||||
)
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
export function parseExternalContext(externalContext) {
|
||||
// Remove start and end tag
|
||||
externalContext = externalContext.replace(/%%-\n|-%%\n/g, "")
|
||||
|
||||
|
||||
let parsedContext = {}
|
||||
externalContext.split("\n").forEach(line => {
|
||||
// If the line is falsey; leave.
|
||||
if (!line) return
|
||||
|
||||
// Assign properties to parsedContext and give them values.
|
||||
// Assign properties to parsedContext and give them their corresponding values.
|
||||
line = line.split(/:/)
|
||||
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'
|
||||
|
||||
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, " "
|
||||
)
|
||||
}
|
||||
import { highlight } from "./codeHighlighter.js"
|
||||
|
||||
export const markedRenderer = {
|
||||
// Rendering of headings (add an anchor above all headings).
|
||||
heading(text, level) {
|
||||
return `
|
||||
<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) {
|
||||
return `
|
||||
<pre>
|
||||
|
|
|
@ -1,19 +1,21 @@
|
|||
import fs from 'fs'
|
||||
import { mdRenderer, njkRenderer } from './siteRenderer.js'
|
||||
|
||||
|
||||
// Handle all request and try to find a corresponding file/template.
|
||||
export function requestHandler(req, res, Config) {
|
||||
// Check for njk files first
|
||||
if (fs.existsSync(`./${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`))
|
||||
return res.send(njkRenderer(`./${Config.contentDir}/pages/${req.path}/index.njk`))
|
||||
|
||||
// Secondly search for markdown
|
||||
if (fs.existsSync(`./${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`))
|
||||
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`))
|
||||
}
|
|
@ -1,38 +1,19 @@
|
|||
import fs from 'fs'
|
||||
import njk from 'nunjucks'
|
||||
import { JSDOM } from 'jsdom'
|
||||
import { parseExternalContext } from './externalContext.js'
|
||||
import { generateContext } from './generateContext.js'
|
||||
|
||||
// Load in config
|
||||
const ConfigFile = fs.readFileSync('./config.json')
|
||||
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) {
|
||||
// Read in the template
|
||||
const njkFile = fs.readFileSync(path).toString()
|
||||
const renderedNjk = njk.renderString(njkFile)
|
||||
|
||||
const context = generateContext(renderedNjk)
|
||||
// Pre-render it for analysis while rendering context
|
||||
const prerenderedNjk = njk.renderString(njkFile)
|
||||
|
||||
// Generate proper context and make a final render of the template.
|
||||
const context = generateContext(prerenderedNjk)
|
||||
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 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
|
||||
|
||||
return njk.renderString(njkFile, context)
|
||||
}
|
Loading…
Reference in New Issue
Block a user