Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

knitr pandoc: "cannot produce pdf output with pdf writer"

Up front: using pandoc() in knitr, it complains when trying to compile .md or .Rmd into a PDF.

I'm streamlining the process for reproducible research, as has been documented in many places. I'm using pandoc and knitr and producing great documents. I'm also trying to streamline for some co-workers who are not as adept with programming, yet we're trying to use similar files. There are several options for "user friendly" markdown-centric editors, and for several reasons I'm leaning on RStudio (for them, emacs/ess for me, but that's different).

My workflow: give them a markdown (.md or .Rmd) file and have them be able to make changes and optionally re-render it into a PDF. Unfortunately, RStudio does not (AFAICT) allow setting templates or other arbitrary pandoc configuration parameters (e.g., chapters, number-sections), so using pandoc() in R/knitr makes a lot of sense here.

Using whitepaper.Rmd as the input file, I run pandoc('whitepaper.Rmd', 'pdf') in R and immediately get:

> pandoc('whitepaper.Rmd', 'pdf')
executing pandoc  -t latex --standalone --smart --number-sections --template=report.tex -f markdown -t pdf -o whitepaper.pdf "whitepaper.Rmd"
pandoc.exe: cannot produce pdf output with pdf writer
Error in (function (input, format, ext, cfg)  : conversion failed

I explicitly have "t:latex" in my knitr-specific header, though without it, pandoc() is still adding "-t pdf" to the system call, something that pandoc.exe does not accept.

With troubleshooting, the command works just fine if I remove '-t pdf', so it seems that there is nothing wrong with the input file itself:

> system('pandoc  -t latex --standalone --smart --number-sections --template=report.tex -f markdown -o whitepaper.pdf "whitepaper.Rmd"')

There have been numerous other conversations regarding this topic: 14586177, 14508429, 15258233, and the heavily-discussed 11025123. They all resolve to solutions that require command-line work, extra middle-steps, external Makefiles, or knit2pdf() (which uses texi2pdf, not desired).

The constraints as I see them:

  • operate easily within the R environment;
  • take advantage of Yihui's "<!--pandoc ... -->" in-file configuration (which allows me to continue to switch arbitrarily between my templates, for one of several examples);
  • preferably, execute this with a single "standardized" command (i.e., "pandoc('whitepaper.Rmd', 'pdf')").

... so that, once the parameters are set in-file, editing and re-rendering is relatively brain-dead.

I can patch and overwrite Yihui's knitr:::pandoc_one() to remove the offending addition of '-t' and format, but I wonder what side-effects that might have elsewhere. This solution isn't sustainable nor "The Right Way (tm)".

Suggestions for "Right Ways (tm)" to solve this problem? Am I missing an easy/obvious solution?

BTW: thanks, Yihui Xie, for knitr, and John MacFarlane for pandoc. Awesomeness! (Perhaps I could submit patch suggestions to either or both to work around for my use-case, though if it's just me then it might not be worthwhile.)

like image 596
r2evans Avatar asked Mar 20 '23 10:03

r2evans


1 Answers

I think all there information you need is there in ?pandoc, which includes the example of running system("pandoc -h") to see possible output formats. From that you learn that

Output formats: asciidoc, beamer, context, docbook, docx, dzslides, epub, epub3, fb2, html, html5, json, latex, man, markdown, markdown_github, markdown_mmd, markdown_phpextra, markdown_strict, mediawiki, native, odt, opendocument, opml, org, pdf*, plain, revealjs, rst, rtf, s5, slideous, slidy, texinfo, textile [*for pdf output, use latex or beamer and -o FILENAME.pdf]

So basically format = "pdf" is invalid, you should use pandoc("tmp.Rmd", format = "latex", ext = "pdf") (and acutally the ext="pdf" part is the default, according to ?pandoc, so all you really need is pandoc("tmp.Rmd", "latex")). As for why pandoc('whitepaper.Rmd', 'pdf') resulted in a call with -t pdf, well, you told it to do that in the second argument to your pandoc() call.

like image 197
Ista Avatar answered Mar 23 '23 12:03

Ista