在编织器中没有使用engine =“tikz”识别ImageMagick PATH

时间:2014-11-16 20:34:53

标签: r path imagemagick knitr imagemagick-convert

我正在尝试从knitr编译TikZ图形。我正在使用可用的示例here。我特意试图从Rstudio编织。

我从" R Markdown"得到的输出选项卡如下:

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

如yihui here所示,我需要安装ImageMagick以便通过knitr运行TikZ代码,并且需要在我的PATH变量中列出ImageMagick(我正在运行Windows 7)。我安装了ImageMagick,我相信我已经在PATH变量中正确指定了目录。我从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" 

正如您所看到的,C:\\Program Files\\ImageMagick-6.8.9-Q16;在我的目录列表中排名第二,顺序似乎并不重要 - 我已尝试将其移至列表中的不同位置并获得相同的结果。

我还尝试以管理员身份运行RStudio(我在用户和系统PATH变量中都指定了ImageMagick)并仍然得到相同的错误消息。

TikZ似乎也能正常工作,因为我可以从Rnw文件或命令行将相同的代码编译为PDF。

根据上面的设置,有没有人对knitr放弃的原因有任何其他想法?

更新

这似乎是与ImageMagick相关的Windows问题。当我尝试从r-blogger条目here运行示例4时,我意识到了这一点。

当我从该示例的末尾运行system("convert -delay 40 *.png example_4.gif")时,我收到以下警告消息:

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

这似乎是一个问题,因为Windows在System32目录中(也在PATH变量中)有一个名为convert.exe的文件。如更详细地描述here,Windows文件是用于将FAT卷转换为NTFS的Windows系统实用程序。我已经尝试了引用链接中的所有建议(即重新排序PATH变量中的列表,重命名文件(显然Windows不允许),以及编辑注册表(用户和本地计算机))。 Windows似乎(以某种方式)优先考虑位于System32目录中的文件。

我还尝试使用Sys.setenv()函数从R中手动重定向PATH变量。运行system("where convert", intern=TRUE)会产生以下输出:

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

第一个路径是正确的目录。第二个路径是上面引用的Windows系统函数。因此,我手动设置PATH变量如下:Sys.setenv(PATH=system("where convert", intern=TRUE)[1])

当我尝试编织时,我似乎超出了convert错误。现在我在R Markdown控制台中收到以下错误:

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

这实际上是有意义的,因为我重置PATH变量并且没有指定pdflatex.exe的路径 - 仅convert.exe。因此,我使用pdflatex.exe函数添加了Sys.setenv()的路径,如下所示:Sys.setenv(PATH=paste(Sys.getenv("PATH"),"C:\\Program Files\\MiKTeX 2.9\\miktex\\bin\\x64",sep=";"))。随后对Sys.getenv("PATH")的调用会产生以下输出:

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

因此,PATH变量似乎具有所有必需信息:convert.exe的路径和pdflatex.exe的路径。但是,在PATH变量中指定了两个目录的情况下,我现在再次收到原始错误消息:

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

另外,继续上面的r-blogger示例,我可以在系统命令中完全指定路径,如下所示:system('"C:\\Program Files\\ImageMagick-6.8.9-Q16\\convert.exe" -delay 40 *.png example_4.gif')。这将转换示例中的文件,没有警告或错误。但是,据我所知,我无法为convert.exe手动指定knitr的路径。

非常感谢任何其他建议。

1 个答案:

答案 0 :(得分:1)

所以,这不是最优雅的解决方案,但确实有效......

按照上面的r-blogger示例的想法,我分叉了github knitr repo here

我更改了@ yihui的版本engine.R代码函数中的eng_tikz() 到我自己的版本:

## 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)
}

可以看出,我只更改了一行 - 我只是在convert.exe函数中完全指定了sprintf()的路径。

当我运行knitr的分叉版本时,我最初从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

警告意味着该函数实际运行,现在我按预期看到tikz-ex-1.pdftikz-ex-1.png文件。

但是,在knitr得到&#34;编织&#34;之前,.png仍然会产生相同的错误。到HTML文档。

这是因为if (conv != 0) stop('problems with函数之后的; probably not installed?')转换sprintf()行似乎在警告上停止knitr - 而不仅仅是错误。当我评论这条线时,我得到一个完全编织的文件。

这显然是一种解决方案(如果有人有更好的想法,我很乐意接受另一种选择)。

我还对有关向knitr回购提交功能请求的任何评论感兴趣,该回复允许路径规范作为类似船上的Windows用户的块选项。使用tikz_engine()时能够将参数传递给ImageMagick也很好。