mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
support for tikz externalize
make copy of main file as output.tex for tikz externalize
This commit is contained in:
parent
a602629406
commit
3bd919b3eb
4 changed files with 113 additions and 1 deletions
|
@ -8,6 +8,7 @@ logger = require "logger-sharelatex"
|
||||||
Metrics = require "./Metrics"
|
Metrics = require "./Metrics"
|
||||||
child_process = require "child_process"
|
child_process = require "child_process"
|
||||||
DraftModeManager = require "./DraftModeManager"
|
DraftModeManager = require "./DraftModeManager"
|
||||||
|
TikzManager = require "./TikzManager"
|
||||||
fs = require("fs")
|
fs = require("fs")
|
||||||
fse = require "fs-extra"
|
fse = require "fs-extra"
|
||||||
os = require("os")
|
os = require("os")
|
||||||
|
@ -42,6 +43,12 @@ module.exports = CompileManager =
|
||||||
else
|
else
|
||||||
callback()
|
callback()
|
||||||
|
|
||||||
|
createTikzFileIfRequired = (callback) ->
|
||||||
|
if TikzManager.needsOutputFile(request.rootResourcePath, request.resources)
|
||||||
|
TikzManager.injectOutputFile compileDir, request.rootResourcePath, callback
|
||||||
|
else
|
||||||
|
callback()
|
||||||
|
|
||||||
# set up environment variables for chktex
|
# set up environment variables for chktex
|
||||||
env = {}
|
env = {}
|
||||||
# only run chktex on LaTeX files (not knitr .Rtex files or any others)
|
# only run chktex on LaTeX files (not knitr .Rtex files or any others)
|
||||||
|
@ -54,7 +61,8 @@ module.exports = CompileManager =
|
||||||
if request.check is 'validate'
|
if request.check is 'validate'
|
||||||
env['CHKTEX_VALIDATE'] = 1
|
env['CHKTEX_VALIDATE'] = 1
|
||||||
|
|
||||||
injectDraftModeIfRequired (error) ->
|
# apply a series of file modifications/creations for draft mode and tikz
|
||||||
|
async.series [injectDraftModeIfRequired, createTikzFileIfRequired], (error) ->
|
||||||
return callback(error) if error?
|
return callback(error) if error?
|
||||||
timer = new Metrics.Timer("run-compile")
|
timer = new Metrics.Timer("run-compile")
|
||||||
# find the image tag to log it as a metric, e.g. 2015.1 (convert . to - for graphite)
|
# find the image tag to log it as a metric, e.g. 2015.1 (convert . to - for graphite)
|
||||||
|
|
|
@ -50,6 +50,8 @@ module.exports = ResourceWriter =
|
||||||
should_delete = false
|
should_delete = false
|
||||||
if path == "output.pdf" or path == "output.dvi" or path == "output.log"
|
if path == "output.pdf" or path == "output.dvi" or path == "output.log"
|
||||||
should_delete = true
|
should_delete = true
|
||||||
|
if path == "output.tex" # created by TikzManager if present in output files
|
||||||
|
should_delete = true
|
||||||
if should_delete
|
if should_delete
|
||||||
jobs.push (callback) -> ResourceWriter._deleteFileIfNotDirectory Path.join(basePath, path), callback
|
jobs.push (callback) -> ResourceWriter._deleteFileIfNotDirectory Path.join(basePath, path), callback
|
||||||
|
|
||||||
|
|
37
services/clsi/app/coffee/TikzManager.coffee
Normal file
37
services/clsi/app/coffee/TikzManager.coffee
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
fs = require "fs"
|
||||||
|
Path = require "path"
|
||||||
|
logger = require "logger-sharelatex"
|
||||||
|
|
||||||
|
# for \tikzexternalize to work the main file needs to match the
|
||||||
|
# jobname. Since we set the -jobname to output, we have to create a
|
||||||
|
# copy of the main file as 'output.tex'.
|
||||||
|
|
||||||
|
module.exports = TikzManager =
|
||||||
|
needsOutputFile: (rootResourcePath, resources) ->
|
||||||
|
# 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
|
||||||
|
# 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 loading tikz or pgf
|
||||||
|
content = resource.content.slice(0,4096)
|
||||||
|
if content.indexOf("\\usepackage{tikz") >= 0
|
||||||
|
return true
|
||||||
|
else if content.indexOf("\\usepackage{pgf") >= 0
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
|
||||||
|
injectOutputFile: (compileDir, mainFile, callback = (error) ->) ->
|
||||||
|
fs.readFile Path.join(compileDir, mainFile), "utf8", (error, content) ->
|
||||||
|
return callback(error) if error?
|
||||||
|
logger.log compileDir: compileDir, mainFile: mainFile, "copied file to ouput.tex for tikz"
|
||||||
|
# use wx flag to ensure that output file does not already exist
|
||||||
|
fs.writeFile Path.join(compileDir, "output.tex"), content, {flag:'wx'}, callback
|
65
services/clsi/test/unit/coffee/TikzManager.coffee
Normal file
65
services/clsi/test/unit/coffee/TikzManager.coffee
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
SandboxedModule = require('sandboxed-module')
|
||||||
|
sinon = require('sinon')
|
||||||
|
require('chai').should()
|
||||||
|
modulePath = require('path').join __dirname, '../../../app/js/TikzManager'
|
||||||
|
|
||||||
|
describe 'TikzManager', ->
|
||||||
|
beforeEach ->
|
||||||
|
@TikzManager = SandboxedModule.require modulePath, requires:
|
||||||
|
"fs": @fs = {}
|
||||||
|
"logger-sharelatex": @logger = {log: () ->}
|
||||||
|
|
||||||
|
describe "needsOutputFile", ->
|
||||||
|
it "should return true if there is a usepackage{tikz}", ->
|
||||||
|
@TikzManager.needsOutputFile("main.tex", [
|
||||||
|
{ path: 'foo.tex' },
|
||||||
|
{ path: 'main.tex', content:'foo \\usepackage{tikz}' }
|
||||||
|
]).should.equal true
|
||||||
|
|
||||||
|
it "should return true if there is a usepackage{pgf}", ->
|
||||||
|
@TikzManager.needsOutputFile("main.tex", [
|
||||||
|
{ path: 'foo.tex'},
|
||||||
|
{ path: 'main.tex', content:'foo \\usepackage{pgf}' }
|
||||||
|
]).should.equal true
|
||||||
|
|
||||||
|
it "should return false if there is no usepackage{tikz} or {pgf}", ->
|
||||||
|
@TikzManager.needsOutputFile("main.tex", [
|
||||||
|
{ path: 'foo.tex' },
|
||||||
|
{ path: 'main.tex', content:'foo \\usepackage{bar}' }
|
||||||
|
]).should.equal false
|
||||||
|
|
||||||
|
it "should return false if there is already an output.tex file", ->
|
||||||
|
@TikzManager.needsOutputFile("main.tex", [
|
||||||
|
{ path: 'foo.tex' },
|
||||||
|
{ path: 'main.tex' },
|
||||||
|
{ path: 'output.tex' }
|
||||||
|
]).should.equal false
|
||||||
|
|
||||||
|
describe "injectOutputFile", ->
|
||||||
|
beforeEach ->
|
||||||
|
@rootDir = "/mock"
|
||||||
|
@filename = "filename.tex"
|
||||||
|
@callback = sinon.stub()
|
||||||
|
@content = '''
|
||||||
|
\\documentclass{article}
|
||||||
|
\\usepackage{tikz}
|
||||||
|
\\begin{document}
|
||||||
|
Hello world
|
||||||
|
\\end{document}
|
||||||
|
'''
|
||||||
|
@fs.readFile = sinon.stub().callsArgWith(2, null, @content)
|
||||||
|
@fs.writeFile = sinon.stub().callsArg(3)
|
||||||
|
@TikzManager.injectOutputFile @rootDir, @filename, @callback
|
||||||
|
|
||||||
|
it "should read the file", ->
|
||||||
|
@fs.readFile
|
||||||
|
.calledWith("#{@rootDir}/#{@filename}", "utf8")
|
||||||
|
.should.equal true
|
||||||
|
|
||||||
|
it "should write out the same file as output.tex", ->
|
||||||
|
@fs.writeFile
|
||||||
|
.calledWith("#{@rootDir}/output.tex", @content, {flag: 'wx'})
|
||||||
|
.should.equal true
|
||||||
|
|
||||||
|
it "should call the callback", ->
|
||||||
|
@callback.called.should.equal true
|
Loading…
Reference in a new issue