rreusser / gulp-latex

A gulp plugin for rendering LaTeX files
6 stars 3 forks source link

Error when loading external ressources with relatives paths #2

Open gurdilou opened 8 years ago

gurdilou commented 8 years ago

Hi, thanks for the plugin !

The plugin seems not able to load external resources. E.g. :

\input{src/1/main.tex}  % doesn't work

whereas

\input{/home/gurdi/tmp/testLatex/src/1/main.tex} %works

I double checked paths. Do you change the working directory, or things like that ?

Thank you.

rreusser commented 8 years ago

Ooh, sorry about that. Let's see. I'll have to think about this. I'm at work so can't fully debug at the moment. I don't think the command option is quite sufficient.

Ah, okay. So the actual code that calls latex is here:

https://github.com/mikolalysenko/node-latex/blob/master/texwrapper.js#L110-L118

I believe it makes a temporary directory and runs latex there, so relative includes will be relative to /tmp/???, which is probably why only the absolute include works. The original intention was to render single equations instead of documents with interrelated file dependencies, so I'll have to think about whether there's a more obvious solution or if this case just needs to be handled completely separately.

gurdilou commented 8 years ago

Thanks I will take a look !

rreusser commented 8 years ago

Actually, upon further thought, I think maybe what you're really up against here is shoehorning tex into a streaming gulp approach. Tex deals in multiple input and ouput files, so the best that can be done—and precisely what this plugin does—is to move latex into a tmp folder and grab the result so that it feels like file streaming and makes gulp happy.

My advice:

I think gulp-spawn might actually be what you're interested in, and perhaps I should note this in the docs. If you do have multiple inputs, then—correct me if I'm wrong—it sounds like you're perhaps more interested in running latex programmatically, which sounds like maybe a better fit for gulp-spawn. The majority of this code exists and jumps through hoops to get latex to work alongside file streaming, but you may not need that.

rreusser commented 8 years ago

So long story short, I think this behavior, unfortunately, makes sense due to the nature of latex, but if you can elaborate on your use case, I'm glad to brainstorm :smile:

gurdilou commented 8 years ago

Hi again !

You were right, the latex package wasn't made to compile files. So I created a new ;)

https://www.npmjs.com/package/latex-file

After changing index.js, everything goes fine.

'use strict';

var latex = require('latex-file').latex;
var through = require('through2');
var rawBody = require('raw-body');
var gutil = require('gulp-util');
var path = require('path');

module.exports = gulpLatex;

function gulpLatex(options) {
  options = options || {};

  // Sanitize against 'pdf' or 'dvi':
  options.format = {pdf: 'pdf', dvi: 'dvi'}[options.format] || 'pdf';

  return through.obj( function( file, enc, cb ) {
    var self = this;

    // Pass null files
    if( file.isNull() ) {
      cb(null,file);
      return;
    }
    // Compilation
    options.pipe_in_stream = true;
    var outDir = path.dirname(file.path);
    options.out_directory = outDir;
    latex(file.path, options, function(err){
      if(err) {
        console.error(err);
      }
      cb(null,file);
    });
  });
}

Could be cool right ?

kopax commented 8 years ago

I am experiencing the same problem.

Using gulp-latex,

I wan't to build my LaTeX files from [./docs/**/*.tex, '!/**/structure.tex']

One file is trying to import structure.tex.

I have the following error :

Error: LaTeX Syntax Error
! LaTeX Error: File `structure.tex' not found.
! Emergency stop.
!  ==> Fatal error occurred, no output PDF file produced!
    at ReadStream.<anonymous> (/workspace/kopaxgroup/latex/node_modules/latex/texwrapper.js:76:30)
    at ReadStream.emit (events.js:117:20)
    at _stream_readable.js:929:16
    at process._tickCallback (node.js:419:13)

Is there another way to automatically save to pdf my tex files on debian ?

rreusser commented 8 years ago

@kopax - Sorry for the delay! Was away from the computer for the weekend. What about gulp-spawn? Something like:

gulp.src("./docs/**/*.tex", { buffer: false })
    .pipe(spawn({cmd: "pdflatex"}));

Would need to think about getting the cwd correct, but I think this is perhaps closer to what you're looking for—a way to run a shell command programatically.

See https://github.com/mikolalysenko/node-latex/issues/11 for upstream issue.

rreusser commented 8 years ago

And @gurdilou — I've been distracted and have been meaning to sit down and process these subtleties, but thanks for the interest and solution!

kopax commented 8 years ago

@rreusser Finally made my own solution :

gulpfile.js

var gulp = require("gulp");
var shell = require("gulp-shell");

gulp.task("latex", shell.task([
    'bash pdf_all.sh',
    'find . -name "*.toc" -type f -delete',
    'find . -name "*.aux" -type f -delete',
    'find . -name "*.log" -type f -delete'
]));

pdf_all.sh

#!/bin/bash

PATTERN="*.tex"
IGNORED_TEX_FILE="structure.tex"
IGNORED_FOLDER="*node_modules/*"

BASE_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
TEX_FILE_LIST=$(find . -type f -not -path "$IGNORED_FOLDER" \( -iname "*.tex" ! -iname "$IGNORED_TEX_FILE" \))

for texFile in $TEX_FILE_LIST; do 
    cd $BASE_DIR
    directory=$(dirname "${texFile}")
    filename=$(basename "${texFile}")
    cd ${directory:2}
    pdflatex $filename

done

cd $BASE_DIR

exit 0

Using gulp-watch, I am able to automatically rebuild my tex files recursively on change.

lqdchrm commented 8 years ago

@rreusser I noticed, that you referred to node-latex for a possible problem upstream (https://github.com/mikolalysenko/node-latex/blob/master/texwrapper.js#L110-L118)

If i read it correctly, the spawn command runs pdflatex inside the temp folder (this is in the options with cwd: dirpath). So the caller's original working directory is not respected. A possible fix might be to run pdflatex in the original working path and referencing files from there. This snippet should fix this in node-latex:

 tex_file.on("close", function() {
      //Invoke LaTeX
      var tex = spawn(tex_command, [
        "-interaction=nonstopmode",
        // reference files from current working path
        "-output-directory=" + dirpath,
        input_path
      ], {
        // don't change process's working path
        // cwd: dirpath,
        env: process.env
      });

Sorry, I can't make a pull request for node-latex right now, as I can't properly test this fix and also I'm not very experienced with GitHub yet. My fork can be found here: https://github.com/lqdchrm/node-latex

So now using relative paths in tex-files with gulp-latex (after applying the fix above to node-latex) should work, even if you change the process's working directory. Might work for you guys :-)

gulp.task('latex2pdf', function () {
    process.chdir('./docs/latex/');
    return gulp.src(['./document.tex'])
        .pipe(plumber())
        .pipe(latex())
        .pipe(gulp.dest('./out'));
});
kopax commented 8 years ago

+1 for merging

coaxial commented 8 years ago

Thanks @kopax, your bash script + shell task made it work for me as well 👍

rreusser commented 8 years ago

Glad the solution works for people! If anyone wants to make a PR to solve this, I'd be glad to accept. Just short on time at the moment.