diff --git a/services/clsi/app/coffee/CompileManager.coffee b/services/clsi/app/coffee/CompileManager.coffee index c4f3c7bfda..167a80e135 100644 --- a/services/clsi/app/coffee/CompileManager.coffee +++ b/services/clsi/app/coffee/CompileManager.coffee @@ -62,10 +62,12 @@ module.exports = CompileManager = callback() createTikzFileIfRequired = (callback) -> - if TikzManager.needsOutputFile(request.rootResourcePath, resourceList) - TikzManager.injectOutputFile compileDir, request.rootResourcePath, callback - else - callback() + TikzManager.checkMainFile compileDir, request.rootResourcePath, resourceList, (error, usesTikzExternalize) -> + return callback(error) if error? + if usesTikzExternalize + TikzManager.injectOutputFile compileDir, request.rootResourcePath, callback + else + callback() # set up environment variables for chktex env = {} diff --git a/services/clsi/app/coffee/ResourceWriter.coffee b/services/clsi/app/coffee/ResourceWriter.coffee index 55970ee850..0b6aef5b72 100644 --- a/services/clsi/app/coffee/ResourceWriter.coffee +++ b/services/clsi/app/coffee/ResourceWriter.coffee @@ -78,6 +78,8 @@ module.exports = ResourceWriter = should_delete = true if path.match(/^output\./) or path.match(/\.aux$/) or path.match(/^cache\//) # knitr cache should_delete = false + if path.match(/^output-.*/) # Tikz cached figures + should_delete = false if path == "output.pdf" or path == "output.dvi" or path == "output.log" or path == "output.xdv" should_delete = true if path == "output.tex" # created by TikzManager if present in output files diff --git a/services/clsi/app/coffee/TikzManager.coffee b/services/clsi/app/coffee/TikzManager.coffee index 5c08f205fd..07f87e3cff 100644 --- a/services/clsi/app/coffee/TikzManager.coffee +++ b/services/clsi/app/coffee/TikzManager.coffee @@ -1,6 +1,7 @@ fs = require "fs" Path = require "path" ResourceWriter = require "./ResourceWriter" +SafeReader = require "./SafeReader" logger = require "logger-sharelatex" # for \tikzexternalize to work the main file needs to match the @@ -8,25 +9,21 @@ logger = require "logger-sharelatex" # copy of the main file as 'output.tex'. module.exports = TikzManager = - needsOutputFile: (rootResourcePath, resources) -> + + checkMainFile: (compileDir, mainFile, resources, callback = (error, usesTikzExternalize) ->) -> # if there's already an output.tex file, we don't want to touch it for resource in resources if resource.path is "output.tex" - return false + logger.log compileDir: compileDir, mainFile: mainFile, "output.tex already in resources" + return callback(null, false) # if there's no output.tex, see if we are using tikz/pgf in the main file - for resource in resources - if resource.path is rootResourcePath - return TikzManager._includesTikz (resource) - # otherwise false - return false - - _includesTikz: (resource) -> - # check if we are using tikz externalize - content = resource.content?.slice(0,65536) - if content?.indexOf("\\tikzexternalize") >= 0 - return true - else - return false + ResourceWriter.checkPath compileDir, mainFile, (error, path) -> + return callback(error) if error? + SafeReader.readFile path, 65536, "utf8", (error, content) -> + return callback(error) if error? + usesTikzExternalize = content?.indexOf("\\tikzexternalize") >= 0 + logger.log compileDir: compileDir, mainFile: mainFile, usesTikzExternalize:usesTikzExternalize, "checked for tikzexternalize" + callback null, usesTikzExternalize injectOutputFile: (compileDir, mainFile, callback = (error) ->) -> ResourceWriter.checkPath compileDir, mainFile, (error, path) -> diff --git a/services/clsi/test/unit/coffee/CompileManagerTests.coffee b/services/clsi/test/unit/coffee/CompileManagerTests.coffee index 591939d68e..341ce2d0fe 100644 --- a/services/clsi/test/unit/coffee/CompileManagerTests.coffee +++ b/services/clsi/test/unit/coffee/CompileManagerTests.coffee @@ -108,7 +108,7 @@ describe "CompileManager", -> @OutputFileFinder.findOutputFiles = sinon.stub().callsArgWith(2, null, @output_files) @OutputCacheManager.saveOutputFiles = sinon.stub().callsArgWith(2, null, @build_files) @DraftModeManager.injectDraftMode = sinon.stub().callsArg(1) - @TikzManager.needsOutputFile = sinon.stub().returns(false) + @TikzManager.checkMainFile = sinon.stub().callsArg(3, false) describe "normally", -> beforeEach -> diff --git a/services/clsi/test/unit/coffee/TikzManager.coffee b/services/clsi/test/unit/coffee/TikzManager.coffee index 816b3b10cf..5a3ec5ce5a 100644 --- a/services/clsi/test/unit/coffee/TikzManager.coffee +++ b/services/clsi/test/unit/coffee/TikzManager.coffee @@ -7,34 +7,63 @@ describe 'TikzManager', -> beforeEach -> @TikzManager = SandboxedModule.require modulePath, requires: "./ResourceWriter": @ResourceWriter = {} + "./SafeReader": @SafeReader = {} "fs": @fs = {} "logger-sharelatex": @logger = {log: () ->} - describe "needsOutputFile", -> - it "should return true if there is a \\tikzexternalize", -> - @TikzManager.needsOutputFile("main.tex", [ - { path: 'foo.tex' }, - { path: 'main.tex', content:'foo \\usepackage{tikz} \\tikzexternalize' } - ]).should.equal true + describe "checkMainFile", -> + beforeEach -> + @compileDir = "compile-dir" + @mainFile = "main.tex" + @callback = sinon.stub() - it "should return false if there is no \\tikzexternalize", -> - @TikzManager.needsOutputFile("main.tex", [ - { path: 'foo.tex' }, - { path: 'main.tex', content:'foo \\usepackage{tikz}' } - ]).should.equal false + describe "if there is already an output.tex file in the resources", -> + beforeEach -> + @resources = [{path:"main.tex"},{path:"output.tex"}] + @TikzManager.checkMainFile @compileDir, @mainFile, @resources, @callback - it "should return false if there is already an output.tex file", -> - @TikzManager.needsOutputFile("main.tex", [ - { path: 'foo.tex' }, - { path: 'main.tex', content:'foo \\usepackage{tikz} \\tikzexternalize' }, - { path: 'output.tex' } - ]).should.equal false + it "should call the callback with false ", -> + @callback.calledWithExactly(null, false) + .should.equal true - it "should return false if the file has no content", -> - @TikzManager.needsOutputFile("main.tex", [ - { path: 'foo.tex' }, - { path: 'main.tex' } - ]).should.equal false + describe "if there is no output.tex file in the resources", -> + beforeEach -> + @resources = [{path:"main.tex"}] + @ResourceWriter.checkPath = sinon.stub() + .withArgs(@compileDir, @mainFile) + .callsArgWith(2, null, "#{@compileDir}/#{@mainFile}") + + describe "and the main file contains tikzexternalize", -> + beforeEach -> + @SafeReader.readFile = sinon.stub() + .withArgs("#{@compileDir}/#{@mainFile}") + .callsArgWith(3, null, "hello \\tikzexternalize") + @TikzManager.checkMainFile @compileDir, @mainFile, @resources, @callback + + it "should look at the file on disk", -> + @SafeReader.readFile + .calledWith("#{@compileDir}/#{@mainFile}") + .should.equal true + + it "should call the callback with true ", -> + @callback.calledWithExactly(null, true) + .should.equal true + + describe "and the main file does not contain tikzexternalize", -> + beforeEach -> + @SafeReader.readFile = sinon.stub() + .withArgs("#{@compileDir}/#{@mainFile}") + .callsArgWith(3, null, "hello") + @TikzManager.checkMainFile @compileDir, @mainFile, @resources, @callback + + it "should look at the file on disk", -> + @SafeReader.readFile + .calledWith("#{@compileDir}/#{@mainFile}") + .should.equal true + + it "should call the callback with false", -> + @callback.calledWithExactly(null, false) + .should.equal true describe "injectOutputFile", -> beforeEach ->