first comit
This commit is contained in:
commit
053de6aebd
157
compile.js
Executable file
157
compile.js
Executable file
@ -0,0 +1,157 @@
|
||||
const showdown = require('showdown')
|
||||
const express = require('express')
|
||||
const fs = require('fs')
|
||||
|
||||
const siteMap = require('./siteMap')
|
||||
|
||||
// ========================================
|
||||
// == compiles ============================
|
||||
// ========================================
|
||||
|
||||
const MDCompile = new showdown.Converter({tables: true})
|
||||
|
||||
function compileMD(file, fn){
|
||||
fs.readFile(file, 'utf-8', function(err, markdown){
|
||||
if(err){
|
||||
console.error("ERROR: could not read file:", file)
|
||||
if(typeof fn == 'function')
|
||||
fn(-1)
|
||||
}
|
||||
html = MDCompile.makeHtml(markdown);
|
||||
if(typeof fn == 'function')
|
||||
fn(html)
|
||||
else
|
||||
fs.writeFile(fn, html, function(err){
|
||||
if(err)
|
||||
console.error(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function compilePDF(file, fn){
|
||||
fs.readFile(file, 'utf-8', function(err, pdf){
|
||||
if(err){
|
||||
console.error("ERROR: could not read file:", file)
|
||||
if(typeof fn == 'function')
|
||||
fn(-1)
|
||||
}
|
||||
return fn("<h1>PDF not supoted yet</h1>")
|
||||
// pdf = MDCompile.makeHtml(markdown);
|
||||
// if(typeof fn == 'function')
|
||||
// fn(html)
|
||||
// else
|
||||
// fs.writeFile(fn, html, function(err){
|
||||
// if(err)
|
||||
// console.error(err)
|
||||
// })
|
||||
})
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// == webserver ===========================
|
||||
// ========================================
|
||||
|
||||
const app = express()
|
||||
app.set('view engine', 'ejs');
|
||||
app.set('views', __dirname + '/views')
|
||||
|
||||
app.use('/img', function(req, res, next){
|
||||
res.sendFile(__dirname + '/img' + req.path)
|
||||
})
|
||||
|
||||
app.use('/:vak/static', renderStatic)
|
||||
app.use('/:vak/:page', renderPage)
|
||||
app.use('/:vak', renderVak)
|
||||
app.use('/', renderIndex)
|
||||
app.use(render404)
|
||||
|
||||
function onError404(req, res, next){
|
||||
return function(err){
|
||||
render404(req, res, next)
|
||||
}
|
||||
}
|
||||
|
||||
function renderStatic(req, res, next){
|
||||
if(typeof siteMap[req.params.vak] == 'undefined') return next();
|
||||
vak = siteMap[req.params.vak]
|
||||
|
||||
dir = __dirname.split('/'); dir.pop() // remove dir of this code
|
||||
dir = `${dir.join('/')}/${vak.title}/notes/static${req.path}`
|
||||
|
||||
res.sendFile(dir, onError404(req, res, next))
|
||||
}
|
||||
|
||||
function renderPage(req, res, next){
|
||||
if(typeof siteMap[req.params.vak] == 'undefined') return next();
|
||||
vak = siteMap[req.params.vak]
|
||||
|
||||
if(typeof vak.pages[req.params.page] == 'undefined') return next();
|
||||
page = vak.pages[req.params.page]
|
||||
|
||||
|
||||
compileMD(page.file, function(html){
|
||||
if(typeof html != 'string'){ return next() }
|
||||
|
||||
res.render('mainV2', {
|
||||
siteMap,
|
||||
title: "notes",
|
||||
topNav: vak.pages,
|
||||
vak: req.params.vak,
|
||||
page: req.params.page,
|
||||
main: html
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function renderVak(req, res, next){
|
||||
if(typeof siteMap[req.params.vak] == 'undefined') return next();
|
||||
vak = siteMap[req.params.vak]
|
||||
|
||||
if(vak.index == null){
|
||||
res.render('mainV2', {
|
||||
siteMap,
|
||||
title: "notes",
|
||||
topNav: vak.pages,
|
||||
vak: req.params.vak,
|
||||
main: `<h1>${vak.title}</h1>`
|
||||
})
|
||||
}else{
|
||||
compileMD(vak.index, function(html){
|
||||
if(typeof html != 'string'){ return next() }
|
||||
|
||||
res.render('mainV2', {
|
||||
siteMap,
|
||||
title: "notes",
|
||||
topNav: vak.pages,
|
||||
vak: req.params.vak,
|
||||
main: html
|
||||
}, onError404(req, res, next))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function renderIndex(req, res, next){
|
||||
res.render('mainV2', {
|
||||
siteMap,
|
||||
title: "notes",
|
||||
topNav: siteMap,
|
||||
main: "<h1>Hoi</h1>"
|
||||
}, onError404(req, res, next))
|
||||
}
|
||||
|
||||
function render404(req, res, next){
|
||||
res.status(404)
|
||||
res.render('mainV2', {
|
||||
siteMap,
|
||||
title: "notes",
|
||||
topNav: vak.pages,
|
||||
vak: req.params.vak,
|
||||
main: "<h1>404 - Page not found</h1>"
|
||||
}, (err) => {
|
||||
if(err){
|
||||
res.send("<h1>404 - Page not found</h1>")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
app.listen(8081, ()=>{console.log("server started")})
|
||||
2528
package-lock.json
generated
Executable file
2528
package-lock.json
generated
Executable file
File diff suppressed because it is too large
Load Diff
16
package.json
Executable file
16
package.json
Executable file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "eps10",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "compile.js",
|
||||
"scripts": {
|
||||
"test": "nodemon compile.js"
|
||||
},
|
||||
"author": "Mats van Reenen",
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"ejs": "^3.1.3",
|
||||
"express": "^4.17.1",
|
||||
"showdown": "^1.9.1"
|
||||
}
|
||||
}
|
||||
85
siteMap.js
Executable file
85
siteMap.js
Executable file
@ -0,0 +1,85 @@
|
||||
const fs = require('fs')
|
||||
|
||||
function collectVakken(dir, child=null){
|
||||
files = fs.readdirSync(dir)
|
||||
//TODO: catch errors
|
||||
//if(err) { console.error("getVakken: readdir:" + err) }
|
||||
|
||||
siteMap = {};
|
||||
|
||||
for(i=files.length-1; i >= 0; i--){
|
||||
if(files[i] == 'notes') continue;
|
||||
Dfile = files[i]
|
||||
|
||||
//TODO: handel archief
|
||||
|
||||
link = Dfile.toLowerCase().replace(/\ /g, '-')
|
||||
p = colectPages(`${dir}/${Dfile}`, link)
|
||||
|
||||
siteMap[link] = {
|
||||
title: Dfile,
|
||||
url: `/${link}`,
|
||||
index: p.index,
|
||||
pages: p.pages
|
||||
}
|
||||
}
|
||||
return siteMap
|
||||
}
|
||||
|
||||
function colectPages(dir, baseURL){
|
||||
var pages = {index: null, pages: {}}
|
||||
|
||||
try {
|
||||
files = fs.readdirSync(dir + '/notes')
|
||||
} catch (error) {
|
||||
return []
|
||||
}
|
||||
|
||||
for(i=files.length-1; i >= 0; i--){
|
||||
if(files[i] == 'static') continue;
|
||||
|
||||
if(files[i] == 'index.md'){
|
||||
pages[0] = `${dir}/${files[i]}`
|
||||
continue
|
||||
}
|
||||
|
||||
file = files[i].split('.')
|
||||
extention = file.pop()
|
||||
fileName = file.join('.')
|
||||
file = files[i]
|
||||
fileDir = `${dir}/notes/${file}`
|
||||
friendlyURL = fileName.toLowerCase().replace(/\ /g, '-')
|
||||
|
||||
type = 'unknown'
|
||||
switch(extention){
|
||||
case 'pdf':
|
||||
case 'md':
|
||||
type = extention
|
||||
break;
|
||||
}
|
||||
|
||||
if(type == 'unknown'){
|
||||
console.warn(`501 - file type not suported (${extention}):`, fileDir)
|
||||
continue
|
||||
}
|
||||
|
||||
pages.pages[friendlyURL] = {
|
||||
title: fileName,
|
||||
url: `/${baseURL}/${friendlyURL}`,
|
||||
file: fileDir,
|
||||
type: type
|
||||
}
|
||||
}
|
||||
return pages
|
||||
}
|
||||
|
||||
function main(){
|
||||
dir = __dirname.split('/')
|
||||
dir.pop()
|
||||
dir = dir.join('/')
|
||||
|
||||
siteMap = collectVakken(dir)
|
||||
return siteMap
|
||||
}
|
||||
|
||||
module.exports = main()
|
||||
2
start.sh
Executable file
2
start.sh
Executable file
@ -0,0 +1,2 @@
|
||||
cleancss --level 2 -o views/style.min.css views/style.css
|
||||
node compile.js
|
||||
51
views/mainV2.ejs
Executable file
51
views/mainV2.ejs
Executable file
@ -0,0 +1,51 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title><%= title %></title>
|
||||
<%- "<style>" %><%- include('style.min.css') %></style>
|
||||
|
||||
<!-- latex expresions -->
|
||||
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
|
||||
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<nav>
|
||||
<ul>
|
||||
<%_ for(i in siteMap){ _%>
|
||||
<% if(typeof vak !== 'undefined' && i == vak){ _%>
|
||||
<li class='current'><%= siteMap[i].title %></li>
|
||||
<% }else{ _%>
|
||||
<li><a href="<%= siteMap[i].url %>"><%= siteMap[i].title %></a></li>
|
||||
<% } _%>
|
||||
<% } _%>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
<aside class='sidenav'>
|
||||
<nav>
|
||||
<ul>
|
||||
<%_ for(i in topNav){ _%>
|
||||
<% if((typeof page !== 'undefined' && i == page) ||
|
||||
(typeof vak !== 'undefined' && i == vak) ){ _%>
|
||||
<li class='current'><%= topNav[i].title %></li>
|
||||
<%_ }else{ _%>
|
||||
<li><a href="<%= topNav[i].url %>"><%= topNav[i].title %></a></li>
|
||||
<%_ } _%>
|
||||
<% } _%>
|
||||
</ul>
|
||||
</nav>
|
||||
</aside>
|
||||
<main>
|
||||
<%_
|
||||
if(typeof main == 'string'){
|
||||
_%><%- main _%><%_
|
||||
}else{
|
||||
%><h1>501 - No suport for this page yet.</h1><%
|
||||
}
|
||||
_%>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
123
views/style.css
Executable file
123
views/style.css
Executable file
@ -0,0 +1,123 @@
|
||||
|
||||
/* body */
|
||||
body{
|
||||
background-color: #333;
|
||||
color: #ccc;
|
||||
margin: 0;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
overflow: overlay;
|
||||
}
|
||||
|
||||
/* header */
|
||||
header{
|
||||
background-color: #000;
|
||||
position: fixed;
|
||||
width: 100vw;
|
||||
top:0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
/* nav */
|
||||
nav ul{
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
/* padding: 15px 5px 5px; */
|
||||
padding: 10px 0 0;
|
||||
text-align: center;
|
||||
}
|
||||
nav li{
|
||||
display: inline-block;
|
||||
}
|
||||
nav a,
|
||||
nav .current{
|
||||
padding: 5px;
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
display: inline-block;
|
||||
}
|
||||
nav a:hover,
|
||||
nav .current{
|
||||
background-color: #333;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* sidenav */
|
||||
aside{
|
||||
width: 15vw;
|
||||
min-height: 100vw;
|
||||
background-color: #222;
|
||||
position: fixed;
|
||||
}
|
||||
aside nav{
|
||||
padding: 70px 0 0;
|
||||
}
|
||||
aside nav li{
|
||||
display: block;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
}
|
||||
aside nav a,
|
||||
aside nav .current{
|
||||
width: calc(100% - 20px);
|
||||
padding: 10px;
|
||||
border-radius: 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
main{
|
||||
padding: 70px 10px 10px;
|
||||
}
|
||||
|
||||
h1{ text-align: center; }
|
||||
h1,h2,h3,h4,h5,h6,
|
||||
th, thead{
|
||||
font-family: 'Ubuntu', sans-serif;
|
||||
}
|
||||
a{
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover{
|
||||
text-decoration: underline;
|
||||
}
|
||||
img{
|
||||
max-width: 100%;
|
||||
}
|
||||
table{
|
||||
border-collapse: collapse;
|
||||
}
|
||||
td, th{
|
||||
padding: 3px;
|
||||
border-right: 1px #555 solid;
|
||||
}
|
||||
td:last-child, th:last-child{
|
||||
border: none;
|
||||
}
|
||||
main{
|
||||
width: 700px;
|
||||
max-width: 100%;
|
||||
margin: auto;
|
||||
}
|
||||
@media print {
|
||||
header, aside{
|
||||
display: none;
|
||||
}
|
||||
body{
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
|
||||
/* scroll bar */
|
||||
::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: none;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #555;
|
||||
border-radius: 5px;
|
||||
}
|
||||
Reference in New Issue
Block a user