You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 lines
2.6 KiB
Plaintext

#!/usr/bin/env node
//# vi: ft=javascript
var fs = require('fs');
var path = require('path');
var _ = require('lodash');
var express = require('express');
var handlebars = require('handlebars');
var app = express();
var staticHandler = express['static'].bind(express);
function toInt(num) {
return parseInt(num, 10);
}
app.use((function log() {
var text = '{{date}} {{req.method}} {{req.url}}';
var logTemplate = handlebars.compile(text);
return function (req, res, next) {
console.log(logTemplate({date: new Date().toISOString(), req: req}));
next();
};
}()));
function renderError(res, err) {
console.error(err.toString());
res.writeHead(500, {'Content-Type': 'text/plain'});
res.send(err.toString());
}
function pathToFile() {
return path.normalize(
path.join.apply(null, [__dirname, '..'].concat(_.toArray(arguments)))
);
}
function index(req, res) {
var indexFile = pathToFile('assets', 'index.html');
function compileServe(err, text) {
if (err) {
renderError(res, err);
return;
}
var tmpl = handlebars.compile(text);
res.send(tmpl());
}
fs.readFile(indexFile, {encoding: 'utf8'}, compileServe);
}
app.get('/', index);
function getMarkdownFiles(cb) {
fs.readdir(pathToFile('data', 'slide'), function (err, files) {
if (err) {
return cb(err);
}
files.sort();
var markdownFiles = _.filter(files, function (file) {
return /\.md$/.test(file);
});
cb(null, markdownFiles);
});
}
app.get('/slides', function showHandler(req, res) {
getMarkdownFiles(function (err, files) {
if (err) {
return renderError(res, err);
}
res.send(_.map(files, function (file, index) {
return {id: index + 1, slug: file.replace(/\.md$/, '')};
}));
});
});
app.get(/slide\/(\d+)/, function showHandler(req, res, next) {
if (!req.xhr) {
index(req, res);
return;
}
var slideIndex = toInt(req.params[0]);
getMarkdownFiles(function (err, files) {
if (err) {
return renderError(res, err);
}
if (slideIndex > files.length) {
return next();
}
var markdownFile = files[slideIndex - 1];
var markdownPath = pathToFile('data', 'slide', markdownFile);
fs.readFile(markdownPath, {encoding: 'utf8'}, function (err, content) {
if (err) {
return renderError(res, err);
}
res.send({
copy: content,
id: toInt(slideIndex),
slug: markdownFile.replace(/\.md$/, '')
});
});
});
});
app.use('/data', staticHandler('data'));
app.use('/vendor', staticHandler('vendor'));
app.use('/static', staticHandler('static'));
app.listen(8000);