Monday, 3 April 2017

Node JS - Render and Compile LaTeX File via a Child Process

I would like to compile LaTeX files in Node using a child process.

Say I have a template from which an intermediary LaTeX file should be created using some data provided from the data base.

1) To compile a LaTeX file I simply use a child process

    var spawn = require("child_process").spawn;
    var templateFolder = "some folder path";
    var pdfLatex = spawn("latexmk", ["-outdir=" + templateFolder, "-pdf", templateFolder + "template.tex"]);
    pdfLatex.stdout.on("end", function (data) {
        //Do something with "template.pdf"
    });

This all works fine. However, how would I detect a LaTeX error that would lead to the file "template.pdf" not being created? For instance, using stderr I could log all errors but some LaTeX errors are not really important (e.g. overflow boxes) and the PDF is still created.

2) To create an indermediate LaTeX file using provided data I was thinking of using mu

    var mu = require("mu2");
    var templateFolder = "some folder";

    mu.root = templateFolder;
    mu.compileAndRender("template.tex", { "name": "John"}) //replace 
    .on("data", function (data) {
        //data.toString() gives the indermediate file
    });

This also works fine.

To combine 1) and 2) I did the following

    var spawn = require("child_process").spawn;
    var path = require("path");
    var mu = require("mu2");
    var fs = require("fs-extra");

    var string = "";
    var templateFolder = "some folder path";

    mu.root = templateFolder;
    mu.compileAndRender("template.tex", { "name": "John"}) //replace  
    .on("data", function (data) {
        string = string + data.toString();
    })
    .on("end", function () {

        var file = path.join(templateFolder, "rendered.tex");

        //Create the rendered file and compile
        return fs.writeFile(file, string, function (err) {

            if (err) {

                //Do something

            } else {

                var pdfLatex = spawn("latexmk", ["-outdir=" + templateFolder, "-pdf", file]);
                pdfLatex.stdout.on("end", function (data) {
                    //Do something with "rendered.pdf"
                });

            }

        });

    });

Even though this works, it looks naive. How would I do this without creating the file "rendered.tex" but by directly pumping the rendered data (e.g. via stdin) into the child process and how would I handle errors in this case?

Any help would be greatly appreciated. Thanks.



via Fluffy

No comments:

Post a Comment