let fs = require("fs"); let http = require("http"); let pathlib = require("path"); let spawn = require("child_process").spawn; let tmp = require("tmp"); function processPandoc(req, res) { let tmpf = tmp.fileSync({ postfix: ".pdf" }); let child = spawn("pandoc", [ "--standalone", "--output", tmpf.name ]); child.on("error", err => { res.writeHead(500); res.end(JSON.stringify({ output: err.toString() })); tmpf.removeCallback(); }); let output = ""; child.stdout.on("data", d => output += d.toString()); child.stderr.on("data", d => output += d.toString()); child.on("exit", (code, sig) => { if (code === 0) { res.end(JSON.stringify({ pdf: fs.readFileSync(tmpf.name).toString("base64"), output })); tmpf.removeCallback(); } else { res.end(JSON.stringify({ output })); tmpf.removeCallback(); } }); req.pipe(child.stdin); } function mime(path) { if (path.endsWith(".html")) return "text/html"; if (path.endsWith(".css")) return "text/css"; if (path.endsWith(".js")) return "application/javascript"; return "application/octet-stream"; } function serve(url, res) { let path = pathlib.join(__dirname, "web", url); let rs = fs.createReadStream(path); rs.once("error", err => { if (err.code == "ENOENT") { res.writeHead(404); res.end("404 Not Found"); } else { res.writeHead(500); res.end("500 Internal Server Error"); console.error(err); } }); rs.once("open", () => { res.writeHead(200, { "Content-Type": mime(path) }); rs.pipe(res); }); } let server = http.createServer((req, res) => { if (req.url == "/") { serve("/index.html", res); } else if (req.method == "POST" && req.url == "/pandoc") { processPandoc(req, res); } else { serve(req.url, res); } }); let port = process.env.PORT || 8080; server.listen(port, "127.0.0.1"); console.log("Listening to 127.0.0.1:" + port);