8

Here are my files:

.
├── app.js
├── res.cls
└── res.tex

And here is the relevant contents of my app.js file:

const { spawn } = require('child_process')
const latex = spawn('pdflatex', ['res.tex'])

Running this code successfully creates a res.pdf file in the same directory. However, rather than creating a file, I would like to get the PDF as a stream and send it as a response to the browser instead. I'm trying to avoid creating any PDF files in the server, I just want to send the generated PDF as a response immediately. Is it possible to alter this code to do this?

Alsphere
  • 513
  • 1
  • 7
  • 22
Saad
  • 49,729
  • 21
  • 73
  • 112
  • This is going to be tricky. I tried creating a named pipe called `res.pdf` in the output directory. This works to the extent that `pdflatex` tries to write to it (without removing it), but apparently it also tries to seek in its output file, which is of course not possible in a pipe. Why not simply read the output file back in? If you do all this on an in-memory filesystem, it should be plenty fast. – Thomas Jan 12 '17 at 21:10
  • Sorry, just to clarify, I'm actually trying to prevent a file being created at all. I don't want to actually save the file, I just want it to be created and sent directly as a response without having a file created in the directory. – Saad Jan 13 '17 at 02:06
  • A typical LaTeX run creates more than one file. It will typically also drop `.aux` and `.log` files, for instance. You still haven't clarified _why_ you want to prevent a file being created... don't fall for the [XY problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) :) – Thomas Jan 13 '17 at 11:34
  • You're right, sorry for not providing much information. I'm basically creating a webapp that takes user form input, creates a custom PDF from it, and then sends the PDF back to the user. Because of this, I'd rather not clog up the server with the generated PDFs. I forgot about the `.aux`, `.log`, and the other generated stuff, I'd like to avoid those as well. The only current thing I can think of is just deleting all the generated files immediately after sending the response, but this doesn't seem like great practice. – Saad Jan 13 '17 at 19:48
  • Have you tried [this node.js latex-wrapper](https://www.npmjs.com/package/latex-file)? – Asmus Jan 19 '17 at 18:00
  • Hey Asumus, that's what I originally was trying to use. Unfortunately, I don't think I could use it if my `.tex` file needs to use things like `.cls` files with it or font files. I could be wrong though, any help about that would be greatly appreciated. – Saad Jan 19 '17 at 23:00

3 Answers3

1

This is a bit late, but I ended up just writing my own wrapper around latex. It lets you use fonts and .cls, and other inputs. It creates a temp directory, puts the generated PDF in there and then streams the PDF back to you. The temp directory is cleaned up afterwards.

You can check out the module here: node-latex.

Saad
  • 49,729
  • 21
  • 73
  • 112
0

The node-pdflatex has the following methods.

var util = require('util');
var path = require('path');
var fs = require('fs');
var exec = require('child_process').exec;

/*
 PDFLatex class
*/
// constructor
function PDFLatex(inputPath) {
    // default settings
    this.outputDirectory = process.cwd() + "/";
    this.inputPath = inputPath;
};

PDFLatex.prototype.outputDir = function(path) {
    this.outputDirectory = path;
    return this;
};

PDFLatex.prototype.process = function() {
    if (this.inputPath && this.inputPath.length > 0) {
        var command = "pdflatex -output-directory " + this.outputDirectory + " '" + this.inputPath + "'";
        util.puts(command);
        exec(command, function(err) {
            if (err) throw err;
        });
    }
};

Solution

Once the file is generated, we can read the file, unlink the file from the directory and send the response to the browser.

 var outputDir = '/dir/pdf/a.pdf'.
 if(fs.existsSync(outputDir)) {

    var check = fs.readFileSync(outputDir);
    fs.unlinkSync(outputDir);
    res.attachment(name+'.pdf');
    res.end(check);
 }

Hope this helps.

SUNDARRAJAN K
  • 2,237
  • 2
  • 22
  • 38
  • Does this still create the PDF in my server? I'm trying to change my code to stop the PDF from actually being created in the server and just sending it as a response to the browser without it remaining in my server. – Saad Jan 13 '17 at 19:50
0

Based on the pdflatex documentation it's not able to handle streams, only files.

Gergo
  • 2,190
  • 22
  • 24