TikzManager.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /* eslint-disable
  2. no-unused-vars,
  3. */
  4. // TODO: This file was created by bulk-decaffeinate.
  5. // Fix any style issues and re-enable lint.
  6. /*
  7. * decaffeinate suggestions:
  8. * DS101: Remove unnecessary use of Array.from
  9. * DS102: Remove unnecessary code created because of implicit returns
  10. * DS207: Consider shorter variations of null checks
  11. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  12. */
  13. import fs from 'node:fs'
  14. import Path from 'node:path'
  15. import { promisify } from 'node:util'
  16. import ResourceWriter from './ResourceWriter.js'
  17. import SafeReader from './SafeReader.js'
  18. import logger from '@overleaf/logger'
  19. let TikzManager
  20. // for \tikzexternalize or pstool to work the main file needs to match the
  21. // jobname. Since we set the -jobname to output, we have to create a
  22. // copy of the main file as 'output.tex'.
  23. export default TikzManager = {
  24. OUTPUT_TEX: 'output.tex',
  25. /**
  26. * @param {string} content
  27. * @return {boolean}
  28. */
  29. usesTikzExternalize(content) {
  30. return content.includes('\\tikzexternalize') || content.includes('{pstool}')
  31. },
  32. /**
  33. * @param {string} compileDir
  34. * @param {import('overleaf-editor-core').Snapshot} snapshot
  35. * @param {string} content
  36. * @return {Promise<void>}
  37. */
  38. async writeOutputFileIfNeeded(compileDir, snapshot, content) {
  39. if (snapshot.getFile(TikzManager.OUTPUT_TEX)) return
  40. if (!TikzManager.usesTikzExternalize(content)) return
  41. await fs.promises.writeFile(
  42. Path.join(compileDir, TikzManager.OUTPUT_TEX),
  43. content,
  44. 'utf-8'
  45. )
  46. },
  47. checkMainFile(compileDir, mainFile, resources, callback) {
  48. // if there's already an output.tex file, we don't want to touch it
  49. if (callback == null) {
  50. callback = function () {}
  51. }
  52. for (const resource of Array.from(resources)) {
  53. if (resource.path === TikzManager.OUTPUT_TEX) {
  54. logger.debug(
  55. { compileDir, mainFile },
  56. 'output.tex already in resources'
  57. )
  58. return callback(null, false)
  59. }
  60. }
  61. // if there's no output.tex, see if we are using tikz/pgf or pstool in the main file
  62. return ResourceWriter.checkPath(
  63. compileDir,
  64. mainFile,
  65. function (error, path) {
  66. if (error != null) {
  67. return callback(error)
  68. }
  69. return SafeReader.readFile(
  70. path,
  71. 65536,
  72. 'utf8',
  73. function (error, content) {
  74. if (error != null) {
  75. return callback(error)
  76. }
  77. const needsMainFile = TikzManager.usesTikzExternalize(content)
  78. logger.debug(
  79. { compileDir, mainFile, needsMainFile },
  80. 'checked for packages needing main file as output.tex'
  81. )
  82. return callback(null, needsMainFile)
  83. }
  84. )
  85. }
  86. )
  87. },
  88. injectOutputFile(compileDir, mainFile, callback) {
  89. if (callback == null) {
  90. callback = function () {}
  91. }
  92. return ResourceWriter.checkPath(
  93. compileDir,
  94. mainFile,
  95. function (error, path) {
  96. if (error != null) {
  97. return callback(error)
  98. }
  99. return fs.readFile(path, 'utf8', function (error, content) {
  100. if (error != null) {
  101. return callback(error)
  102. }
  103. logger.debug(
  104. { compileDir, mainFile },
  105. 'copied file to output.tex as project uses packages which require it'
  106. )
  107. // use wx flag to ensure that output file does not already exist
  108. return fs.writeFile(
  109. Path.join(compileDir, TikzManager.OUTPUT_TEX),
  110. content,
  111. { flag: 'wx' },
  112. callback
  113. )
  114. })
  115. }
  116. )
  117. },
  118. }
  119. TikzManager.promises = {
  120. checkMainFile: promisify(TikzManager.checkMainFile),
  121. injectOutputFile: promisify(TikzManager.injectOutputFile),
  122. }