ImageMagick PATH not being recognized with engine = “tikz” in knitr

做~自己de王妃 提交于 2020-01-15 06:14:27

问题


I am trying to compile TikZ graphics from knitr. I am using the example available here. I am specifically trying to knit from Rstudio.

The output I get from the "R Markdown" tab is as follows:

processing file: test.Rmd

Invalid Parameter - /test_files
Quitting from lines 16-31 (test.Rmd) 
Error in (knit_engines$get(options$engine))(options) : 
  problems with `convert`; probably not installed?
Calls: <Anonymous> ... process_group.block -> call_block -> block_exec -> in_dir -> <Anonymous>
Execution halted

As indicated by yihui here, I need to have ImageMagick installed in order to run TikZ code through knitr and need to have ImageMagick listed in my PATH variable (I am running Windows 7). I have installed ImageMagick and I believe I have properly specified the directory in my PATH variable. I get the following output from Sys.getenv("PATH")

[1] "C:\\Program Files\\R\\R-3.0.2\\bin\\x64;C:\\Program Files\\ImageMagick-6.8.9-Q16;C:\\Program Files\\Microsoft HPC Pack 2008 R2\\Bin\\;C:\\Program Files (x86)\\AMD APP\\bin\\x86_64;C:\\Program Files (x86)\\AMD APP\\bin\\x86;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;c:\\Program Files (x86)\\Microsoft SQL Server\\100\\Tools\\Binn\\;c:\\Program Files\\Microsoft SQL Server\\100\\Tools\\Binn\\;c:\\Program Files\\Microsoft SQL Server\\100\\DTS\\Binn\\;c:\\Program Files (x86)\\Microsoft SQL Server\\100\\Tools\\Binn\\VSShell\\Common7\\IDE\\;c:\\Program Files (x86)\\Microsoft SQL Server\\100\\DTS\\Binn\\;C:\\Program Files\\MiKTeX 2.9\\miktex\\bin\\x64\\;C:\\Program Files (x86)\\Microsoft Visual Studio 9.0\\Common7\\IDE\\PrivateAssemblies\\;c:\\Program Files (x86)\\ATI Technologies\\ATI.ACE\\Core-Static;C:\\PDF\\xpdfbin-win-3.03\\bin64;C:\\Program Files\\Microsoft SQL Server\\110\\DTS\\Binn\\;C:\\Program Files (x86)\\Microsoft SQL Server\\110\\Tools\\Binn\\;C:\\Program Files\\Microsoft SQL Server\\110\\Tools\\Binn\\;C:\\Program Files (x86)\\Microsoft SQL Server\\110\\Tools\\Binn\\ManagementStudio\\;C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\Common7\\IDE\\PrivateAssemblies\\;C:\\Program Files (x86)\\Microsoft SQL Server\\110\\DTS\\Binn\\;C:\\Program Files (x86)\\Windows Kits\\8.1\\Windows Performance Toolkit\\;C:\\Program Files\\SlikSvn\\bin;C:\\Program Files (x86)\\QuickTime\\QTSystem\\;C:\\Program Files\\nodejs\\;C:\\Program Files (x86)\\Google\\Google Apps Sync\\;C:\\Program Files (x86)\\Google\\Google Apps Migration\\;C:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\Common7\\IDE\\PrivateAssemblies\\;C:\\Program Files\\ImageMagick-6.8.9-Q16;C:\\Users\\mienkoja\\AppData\\Local\\Pandoc\\;C:\\Program Files (x86)\\Google\\google_appengine\\;C:\\Users\\mienkoja\\AppData\\Roaming\\MiKTeX\\2.9\\miktex\\bin\\x64\\;C:\\Users\\mienkoja\\AppData\\Roaming\\npm" 

As you can see, C:\\Program Files\\ImageMagick-6.8.9-Q16; is second in my list of directories and order does not seem to matter - I have tried moving it to different locations in the list and get the same result.

I have also tried running RStudio as administrator (I have ImageMagick specified in both my user and system PATH variables) and still get the same error message.

TikZ also appears to be working fine by itself as I can compile the same code to PDF from an Rnw file or from command-line.

Does anyone have any other thoughts as to why knitr is quitting given my settings above?

UPDATE

This appears to be a Windows problem related to ImageMagick. I realized this when I tried to run through Example 4 from the r-blogger entry here.

When I run system("convert -delay 40 *.png example_4.gif") from the end of that example, I get the following warning message:

Invalid Parameter - 40
Warning message:
running command 'convert -delay 40 *.png example_4.gif' had status 4 

This appears to be a problem with the fact that Windows has a file in the System32 directory (also in the PATH variable) named convert.exe. As described in more detail here, the windows file is a Windows system utility used for converting FAT volumes to NTFS. I have tried all of the suggestions at the referenced link (i.e. reordering the listings in the PATH variable, renaming the file (apparently not allowed by Windows), and editing the registry (both user and local machine)). Windows appears to (somehow) give primacy to the files located in the System32 directory.

I have also tried to manually redirect the PATH variable from within R using the Sys.setenv() function. Running system("where convert", intern=TRUE) yields the following output:

[1] "C:\\Program Files\\ImageMagick-6.8.9-Q16\\convert.exe" "C:\\Windows\\System32\\convert.exe"

The first path is the correct directory. The second path is a Windows system function referenced above. Thus, I manually set the PATH variable as follows: Sys.setenv(PATH=system("where convert", intern=TRUE)[1]).

When I try to knit I appear to move past the convert error. Now I get the following error in my R Markdown console:

error in texi2dvi(file = file, pdf = true, clean = clean, quiet = quiet, : 
pdflatex is not available 

This actually makes sense since I reset the PATH variable and have not specified a path to pdflatex.exe - only convert.exe. Thus, I added the path to pdflatex.exe using the Sys.setenv() function as follows: Sys.setenv(PATH=paste(Sys.getenv("PATH"),"C:\\Program Files\\MiKTeX 2.9\\miktex\\bin\\x64",sep=";")). A subsequent call to Sys.getenv("PATH") yields the following output:

[1] "C:\\Program Files\\ImageMagick-6.8.9-Q16\\convert.exe;C:\\Program Files\\MiKTeX 2.9\\miktex\\bin\\x64"

Thus, the PATH variable appears to have all of the requisite information: the path to convert.exe and the path to pdflatex.exe. However, with both directories specified in the PATH variable, I am now getting the original error message again:

processing file: test.Rmd

Invalid Parameter - /test_files
Quitting from lines 16-31 (test.Rmd) 
Error in (knit_engines$get(options$engine))(options) : 
  problems with `convert`; probably not installed?
Calls: <Anonymous> ... process_group.block -> call_block -> block_exec -> in_dir -> <Anonymous>
Execution halted

As an aside, continuing with the r-blogger example from above, I can fully specify the path in the system command as follows: system('"C:\\Program Files\\ImageMagick-6.8.9-Q16\\convert.exe" -delay 40 *.png example_4.gif'). This will convert the files in the example with no warnings or errors. However, I cannot (to my knowledge) manually specify the path to convert.exe for knitr.

Any other suggestions would be much appreciated.


回答1:


So, this is not the most elegant solution, but it does work...

Following the thoughts of the r-blogger example from above, I forked the github knitr repo here.

I have changed the eng_tikz() in the engine.R code function from @yihui's version to my own version:

## convert tikz string to PDF
eng_tikz = function(options) {
  if (!options$eval) return(engine_output(options, options$code, ''))

  lines = readLines(tmpl <- options$engine.opts$template %n%
                      system.file('misc', 'tikz2pdf.tex', package = 'knitr'))
  i = grep('%% TIKZ_CODE %%', lines)
  if (length(i) != 1L)
    stop("Couldn't find replacement string; or the are multiple of them.")

  s = append(lines, options$code, i)  # insert tikz into tex-template
  writeLines(s, texf <- str_c(f <- tempfile('tikz', '.'), '.tex'))
  unlink(outf <- str_c(f, '.pdf'))
  tools::texi2pdf(texf, clean = TRUE)
  if (!file.exists(outf)) stop('failed to compile tikz; check the template: ', tmpl)
  unlink(texf)

  fig = fig_path('', options)
  dir.create(dirname(fig), recursive = TRUE, showWarnings = FALSE)
  file.rename(outf, str_c(fig, '.pdf'))
  # convert to the desired output-format, calling `convert`
  ext = tolower(options$fig.ext %n% dev2ext(options$dev))
  if (ext != 'pdf'){
    # Changed this line
    # conv = system(sprintf('convert %s.pdf %s.%s', fig, fig, ext))
    # to specify full path to ImageMagick
    conv = system(sprintf('"C:\\Program Files\\ImageMagick-6.8.9-Q16\\convert.exe" %s.pdf %s.%s', fig, fig, ext))
    if (conv != 0) stop('problems with `convert`; probably not installed?')
  }
  options$fig.num = 1L; options$fig.cur = 1L
  extra = knit_hooks$get('plot')(paste(fig, ext, sep = '.'), options)
  options$engine = 'tex'  # for output hooks to use the correct language class
  engine_output(options, options$code, '', extra)
}

As can be seen, I have only changed one line - I am simply fully specifying the path to convert.exe within the sprintf() function.

When I run my forked version of knitr, I initially got the following message back from knitr:

convert.exe: iCCP: profile 'default_rgb.icc': 0h: PCS illuminant is not D50 
'C:/Users/mienkoja/AppData/Local/Temp/magick-11148QAz4QgZyDsZV1' @ warning/png.c/MagickPNGWarningHandler/1831.
Quitting from lines 16-31 (annual_review.Rmd) 
Error in (knit_engines$get(options$engine))(options) : 
  problems with `convert`; probably not installed?
Calls: <Anonymous> ... process_group.block -> call_block -> block_exec -> in_dir -> <Anonymous>
Execution halted

The warning implies that the function actually ran and I do now see a tikz-ex-1.pdf and tikz-ex-1.png file as expected.

However, knitr is still producing the same error before the .png gets "knit" into an HTML document.

This is because the if (conv != 0) stop('problems withconvert; probably not installed?') line after the sprintf() function appears to be stopping knitr on warnings - not just errors. When I comment this line out, I get a fully knitted document.

This is obviously a hackish solution (and I would gladly accept another option if anyone has a better idea).

I would also be interested in any comments about submitting a feature request to the knitr repo about allowing for path specification as a chunk option for windows users in a similar boat to me. It would also be nice to have the ability to pass arguments to ImageMagick when using tikz_engine().



来源:https://stackoverflow.com/questions/26961773/imagemagick-path-not-being-recognized-with-engine-tikz-in-knitr

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!