Variable declarations

This commit is contained in:
Joseph Rautenbach 2019-07-18 11:42:39 +02:00
parent 73942d746b
commit 49784697ab

85
app.js
View File

@ -1,47 +1,46 @@
var fs = require('fs'); const fs = require('fs');
var shell = require('shelljs'); const shell = require('shelljs');
const express = require('express');
var express = require('express'); const port = 3001;
var port = 3001; const staticDir = 'static/';
const tempDirRoot = 'temp/';
var staticDir = 'static/'; const outputDir = 'output/';
var tempDirRoot = 'temp/'; const httpOutputURL = 'output/';
var outputDir = 'output/';
var httpOutputURL = 'output/';
// Command to compile .tex file to .dvi file. Timeout kills LaTeX after 5 seconds if held up
var latexCMD = 'timeout 5 latex -interaction nonstopmode -halt-on-error --no-shell-escape equation.tex';
// Command to convert .dvi to .svg file
var dvisvgmCMD = 'dvisvgm --no-fonts --scale=OUTPUT_SCALE --exact equation.dvi';
var dockerImageName = 'blang/latex:ubuntu'; // https://github.com/blang/latex-docker
// Command to run the above commands in a new Docker container (with LaTeX preinstalled)
var dockerCMD = `cd TEMP_DIR_NAME && exec docker run --rm -i --user="$(id -u):$(id -g)" --net=none -v "$PWD":/data "${dockerImageName}" /bin/sh -c "${latexCMD} && ${dvisvgmCMD}"`;
// Commands to convert .svg to .png/.jpg and compress
var svgToImageCMD = 'svgexport SVG_FILE_NAME OUT_FILE_NAME';
var imageMinCMD = 'imagemin IN_FILE_NAME > OUT_FILE_NAME';
// Checklist of valid formats and scales, to verify form values are correct // Checklist of valid formats and scales, to verify form values are correct
var validFormats = ['SVG', 'PNG', 'JPG']; const validFormats = ['SVG', 'PNG', 'JPG'];
var validScales = ['10%', '25%', '50%', '75%', '100%', '125%', '150%', '200%', '500%', '1000%']; const validScales = ['10%', '25%', '50%', '75%', '100%', '125%', '150%', '200%', '500%', '1000%'];
// Percentage scales mapped to floating point values used in arguments // Percentage scales mapped to floating point values used in arguments
var validScalesInternal = ['0.1', '0.25', '0.5', '0.75', '1.0', '1.25', '1.5', '2.0', '5.0', '10.0']; const validScalesInternal = ['0.1', '0.25', '0.5', '0.75', '1.0', '1.25', '1.5', '2.0', '5.0', '10.0'];
var fontSize = 12; // Command to compile .tex file to .dvi file. Timeout kills LaTeX after 5 seconds if held up
const latexCMD = 'timeout 5 latex -interaction nonstopmode -halt-on-error --no-shell-escape equation.tex';
// Command to convert .dvi to .svg file
const dvisvgmCMD = 'dvisvgm --no-fonts --scale=OUTPUT_SCALE --exact equation.dvi';
const dockerImageName = 'blang/latex:ubuntu'; // https://github.com/blang/latex-docker
// Command to run the above commands in a new Docker container (with LaTeX preinstalled)
const dockerCMD = `cd TEMP_DIR_NAME && exec docker run --rm -i --user="$(id -u):$(id -g)" --net=none -v "$PWD":/data "${dockerImageName}" /bin/sh -c "${latexCMD} && ${dvisvgmCMD}"`;
// Commands to convert .svg to .png/.jpg and compress
const svgToImageCMD = 'svgexport SVG_FILE_NAME OUT_FILE_NAME';
const imageMinCMD = 'imagemin IN_FILE_NAME > OUT_FILE_NAME';
const fontSize = 12;
// LaTeX document template // LaTeX document template
var preamble = ` const preamble = `
\\usepackage{amsmath} \\usepackage{amsmath}
\\usepackage{amssymb} \\usepackage{amssymb}
\\usepackage{amsfonts} \\usepackage{amsfonts}
\\usepackage[utf8]{inputenc} \\usepackage[utf8]{inputenc}
`; `;
var documentTemplate = ` const documentTemplate = `
\\documentclass[${fontSize}pt]{article} \\documentclass[${fontSize}pt]{article}
${preamble} ${preamble}
\\thispagestyle{empty} \\thispagestyle{empty}
@ -59,9 +58,9 @@ if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir); fs.mkdirSync(outputDir);
} }
var app = express(); const app = express();
var bodyParser = require('body-parser'); const bodyParser = require('body-parser');
app.use(bodyParser.json()); app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true})); app.use(bodyParser.urlencoded({extended: true}));
@ -75,26 +74,26 @@ app.post('/convert', function (req, res) {
if (req.body.latexInput) { if (req.body.latexInput) {
if (validScales.includes(req.body.outputScale)) { if (validScales.includes(req.body.outputScale)) {
if (validFormats.includes(req.body.outputFormat)) { if (validFormats.includes(req.body.outputFormat)) {
var id = generateID(); // Generate unique ID for filename const id = generateID(); // Generate unique ID for filename
var eqnInput = req.body.latexInput.trim(); let eqnInput = req.body.latexInput.trim();
if (/\\\\(?!$)/.test(eqnInput) && !eqnInput.includes("&")) { // if any "\\" not at EOF, unless intentionally aligned with & if (/\\\\(?!$)/.test(eqnInput) && !eqnInput.includes("&")) { // if any "\\" not at EOF, unless intentionally aligned with &
eqnInput = '&' + eqnInput.replace(/\\\\(?!$)/g, "\\\\&"); // replace any "\\" not at EOF with "\\&", to enforce left alignment eqnInput = '&' + eqnInput.replace(/\\\\(?!$)/g, "\\\\&"); // replace any "\\" not at EOF with "\\&", to enforce left alignment
} }
shell.mkdir(`${tempDirRoot}${id}`); shell.mkdir(`${tempDirRoot}${id}`);
var document = documentTemplate.replace('EQUATION', eqnInput); const document = documentTemplate.replace('EQUATION', eqnInput);
fs.writeFileSync(`${tempDirRoot}${id}/equation.tex`, document); // Write generated .tex file fs.writeFileSync(`${tempDirRoot}${id}/equation.tex`, document); // Write generated .tex file
var result = {}; let result = {};
var finalDockerCMD = dockerCMD.replace('TEMP_DIR_NAME', `${tempDirRoot}${id}`); let finalDockerCMD = dockerCMD.replace('TEMP_DIR_NAME', `${tempDirRoot}${id}`);
finalDockerCMD = finalDockerCMD.replace('OUTPUT_SCALE', validScalesInternal[validScales.indexOf(req.body.outputScale)]); finalDockerCMD = finalDockerCMD.replace('OUTPUT_SCALE', validScalesInternal[validScales.indexOf(req.body.outputScale)]);
var fileFormat = req.body.outputFormat.toLowerCase(); const fileFormat = req.body.outputFormat.toLowerCase();
// Asynchronously compile and render the LaTeX to svg // Asynchronously compile and render the LaTeX to an image
shell.exec(finalDockerCMD, {async: true}, function() { shell.exec(finalDockerCMD, {async: true}, function() {
if (fs.existsSync(`${tempDirRoot}${id}/equation.svg`)) { if (fs.existsSync(`${tempDirRoot}${id}/equation.svg`)) {
if (fileFormat === 'svg') { // Converting to SVG, no further processing required if (fileFormat === 'svg') { // Converting to SVG, no further processing required
@ -103,7 +102,7 @@ app.post('/convert', function (req, res) {
} else { } else {
// Convert svg to png/jpg // Convert svg to png/jpg
var finalSvgToImageCMD = svgToImageCMD.replace('SVG_FILE_NAME', `${tempDirRoot}${id}/equation.svg`); let finalSvgToImageCMD = svgToImageCMD.replace('SVG_FILE_NAME', `${tempDirRoot}${id}/equation.svg`);
finalSvgToImageCMD = finalSvgToImageCMD.replace('OUT_FILE_NAME', `${tempDirRoot}${id}/equation.${fileFormat}`); finalSvgToImageCMD = finalSvgToImageCMD.replace('OUT_FILE_NAME', `${tempDirRoot}${id}/equation.${fileFormat}`);
if (fileFormat === 'jpg') { // Add a white background for jpg images if (fileFormat === 'jpg') { // Add a white background for jpg images
finalSvgToImageCMD += ' "svg {background: white}"'; finalSvgToImageCMD += ' "svg {background: white}"';
@ -113,7 +112,7 @@ app.post('/convert', function (req, res) {
// Ensure conversion was successful; eg. fails if `svgexport` or `imagemin` is not installed // Ensure conversion was successful; eg. fails if `svgexport` or `imagemin` is not installed
if (fs.existsSync(`${tempDirRoot}${id}/equation.${fileFormat}`)) { if (fs.existsSync(`${tempDirRoot}${id}/equation.${fileFormat}`)) {
// Compress the resultant image // Compress the resultant image
var finalImageMinCMD = imageMinCMD.replace('IN_FILE_NAME', `${tempDirRoot}${id}/equation.${fileFormat}`); let finalImageMinCMD = imageMinCMD.replace('IN_FILE_NAME', `${tempDirRoot}${id}/equation.${fileFormat}`);
finalImageMinCMD = finalImageMinCMD.replace('OUT_FILE_NAME', `${tempDirRoot}${id}/equation_compressed.${fileFormat}`); finalImageMinCMD = finalImageMinCMD.replace('OUT_FILE_NAME', `${tempDirRoot}${id}/equation_compressed.${fileFormat}`);
shell.exec(finalImageMinCMD); shell.exec(finalImageMinCMD);
@ -152,8 +151,8 @@ app.listen(port, function() {
function generateID() { // Generate a random 16-char hexadecimal ID function generateID() { // Generate a random 16-char hexadecimal ID
var output = ''; let output = '';
for (var i = 0; i < 16; i++) { for (let i = 0; i < 16; i++) {
output += '0123456789abcdef'.charAt(Math.floor(Math.random() * 16)); output += '0123456789abcdef'.charAt(Math.floor(Math.random() * 16));
} }
return output; return output;