## file lyx-pgfsweave.R ## This file is part of LyX, the document processor. ## Licence details can be found in the file COPYING. ## author Yihui Xie ## Full author contact details are available in file CREDITS ## Rscript $$s/scripts/lyx-pgfsweave.R $$p $$i $$o $$r $$e ## arguments in order: ## 1: $$p the path of the output (temp dir) ## 2: $$i the file name of the input Rnw ## 3: $$o the tex output ## 4: $$r path to the original input file (the lyx document) ## 5: $$e encoding (e.g. 'UTF-8') .cmdargs = commandArgs(TRUE) message('options passed from LyX:') print(.cmdargs) if (is.null(getOption('lyx.use.encoding')) || isTRUE(getOption('lyx.use.encoding'))) options(encoding = .cmdargs[5]) ## the working directory is the same with the original .lyx file; you ## can put your data files there and functions like read.table() can ## work correctly without specifying the full path setwd(.cmdargs[4]) ## copy Sweave.sty and friends to $$p if kpsewhich cannot find it if (length(system("kpsewhich Sweave.sty", intern = TRUE, ignore.stderr = TRUE)) == 0) { file.copy(list.files(file.path(R.home('share'), 'texmf', 'tex', 'latex'), full.names = TRUE), .cmdargs[1]) } .Rnw.basename = sub('\\.Rnw$', '', .cmdargs[2]) if (!require('pgfSweave')) { ## install pgfSweave if not available install.packages('pgfSweave', repos='http://cran.r-project.org') library(pgfSweave) } ## set the dictionary to a fixed place, otherwise each time you open ## the LyX document and re-run pgfSweave you will have to generate a ## new dictionary, which is time-consuming options(tikzMetricsDictionary = file.path(.cmdargs[4], paste('tikzDict', '-', .Rnw.basename, sep = '')), tikzDocumentDeclaration = grep('^\\\\documentclass', readLines(file.path(.cmdargs[1], .cmdargs[2])), value = TRUE)[1] ) ## copy the Rnw file to the current working directory file.copy(file.path(.cmdargs[1], .cmdargs[2]), '.', overwrite = TRUE) ## run pgfSweave() without directly generating the PDF output (tex only) pgfSweave(.cmdargs[2], graphics.only = TRUE) ## in case users have changed the working directory in their Sweave code setwd(.cmdargs[4]) .tex.file = .cmdargs[3] .doc = readLines(.tex.file) ## before the tex file is passed back to LyX, we need to comment out ## these lines because otherwise a new makefile will be generated in ## the temporary dir and the cache work which has been done previously ## in the working directory will be in vain; this is a nasty trick to ## preserve the nice cache mechanism in pgfSweave .idx = grep('^\\\\usetikzlibrary\\{external\\}|^\\\\tikzexternalize\\[mode=list and make\\]|^\\\\tikzsetnextfilename\\{|^\\\\tikzexternalfiledependsonfile\\{|^\\\\tikzset\\{external/system call=\\{xelatex', .doc) .doc[.idx] = paste('%%', .doc[.idx]) ## another nasty trick to cache graphics and tune the styles .begin.center = .end.center = '' if (isTRUE(getOption('lyx.graphics.center'))) { .begin.center = '\\begin{center}\n' .end.center = '\n\\end{center}' } .idx = grep('^\\\\input\\{.*\\.tikz\\}', .doc) if (length(.idx)) { .idx2 = !grepl('{\\tikzexternaldisable', .doc[.idx-1], fixed = TRUE) .doc[.idx] = ifelse(.idx2, paste(.begin.center, '\\includegraphics', getOption('lyx.graphics.width'), '{', gsub('^\\\\input\\{(.*)\\.tikz\\}', '\\1', .doc[.idx]), '}', .end.center, sep = ''), paste(.begin.center, .doc[.idx], .end.center, sep = '')) .doc = gsub('^\\{\\\\tikzexternaldisable', '{', .doc) } ## put the tweaked tex file to the temporary dir for LyX to compile message('Sweave is done; now handing the tex output over to LyX') writeLines(.doc, file.path(.cmdargs[1], .tex.file)) unlink(.cmdargs[2]) ## if $$r contains spaces (strongly not recommended!!), we have to ## copy all possible R output to $$p (typically graphics output); this ## is very conservative, but we really do not know which of these ## files are needed by LaTeX if (grepl('[[:space:]]', .cmdargs[4])) { warning('your working directory contains spaces: ', .cmdargs[4], ', but we highly recommend you not to use a directory that contains spaces') .files = list.files() .files = .files[!grepl('\\.(lyx|Rnw|tex|lyx~)$', .files)] message('copying these files to LyX temporary directory: ', paste(.files, collapse = '\n')) file.copy(.files, .cmdargs[1], overwrite = TRUE, recursive = TRUE) }