我想在编织.Rnw
文件后启动一个LaTeX。元代码应该是这样的:
(defun knit ()
(interactive)
(setq rproc (ess-get-process ess-current-process-name))
(setq c "knit('foo.rnw')\n")
(process-send-string rproc c)
;; Wait for ESS to finish
(shell-command-to-string "cd foo/path & pdflatex foo"))
主要问题是让Emacs等待劣质缓冲区完成编织并且仅在开始胶乳之后。我找到了几个有趣的函数:(ess-wait-for-process ...)
和(劣等 - 标记为繁忙...)`,这可能有效,但我无法理解。
请注意(shell-command-to-string ...
仅供参考。最终的选择可能是:
(TeX-command "LaTeX" 'rnw-to-tex-ext -1))
knit2pdf()
可能是另一条路,但我将失去AUCTeX的好处。
PS:我的问题被SE机器人认为是“主观的,可能会被关闭”?
答案 0 :(得分:1)
我使用texi2pdf
并让R在编织后执行,但这显然相当于knit2pdf
。我想知道你是否可以使用system
在knit
命令之后调用你想要的任何tex命令,类似于我使用texi2pdf
的方式。
我不是emacs专家,但是我在.emacs
文件中的功能是值得的。
; use knitr (was Sweave) script as compile function for Rnw files
(defun ess-swv-SweaveSh ()
"Use knitr script to knit an Rnw file and create a pdf."
(interactive)
(let
((compilation-buffer-name-function (function (lambda(ign)(concat "*" (buffer-file-name) "*")))))
(compile (concat "Rscript -e \".n <- '" (buffer-file-name) "'; library(knitr); knit(.n); library(tools); texi2pdf(sub('Rnw$','tex',.n))\"" ))
)
)
答案 1 :(得分:1)
可能的解决方案是检查劣质ESS流程的'busy
属性。
等待它为nil
的while循环阻止命令回显。这就是您看到(redisplay)
的原因。为了避免给亲爱的人施加压力,我还设置了刷新延迟(sleep-for .5)
为了防止ESS卡住,60秒后循环存在。如果您有重量级密码,请调整它。
最后,我将胶乳附加到AUCTeX。因此,您可以借助LaTeX-command-style
文档自定义TeX-expand-list
。
该功能自动为knit和latex设置文件的正确名称,并将R working dir设置为要编织的.Rnw文件,以便您可以获取其他脚本或加载数据。
因此,您可以使用M-x knit
随处运行它,也可以将其与快捷方式相关联。
该函数在编织前保存缓冲区的最后一次更改,如果没有可用的话,打开一个劣质的R缓冲区;否则它使用现有的。
(defun knit ()
"Save the buffer, knit and latex"
(interactive) ; You will associate this to you favourite key
(let* (
;; Get names & path
(cur-dir (file-name-directory (buffer-file-name)))
(rnw-name (file-name-nondirectory (buffer-file-name)))
(tex-name (concat (file-name-base (buffer-file-name)) ".tex"))
;; Create knit command
(cmd (format "require(knitr); setwd('%s'); knit('%s')" cur-dir rnw-name))
;; Time the knitting
(start-time (float-time))
(wait 60) ; Lifeboat to exit loop if smt wrong
)
;; Save rnw buffer... you are lazy, I know)
(save-buffer)
;; Send string to R at low-level
;;(setq rproc (ess-get-process ess-current-process-name))
;;(process-send-string rproc c)
;; or Send line with the ESS wrapper
(ess-eval-linewise cmd)
;; While loop to check when
(setq start-time (float-time)
wait 60) ; Lifeboat to exit loop after x secs
;; Wait for 'busy property nil, nut not more than wait seconds
(setq rproc (ess-get-process ess-current-process-name))
(while (< (- (float-time) start-time) wait)
(sleep-for .5)
;; (accept-process-output rproc .5) ;alt. way for process-send-string
(redisplay)
(if (not (process-get rproc 'busy))
(setq wait 0)
(message "Knitting... ")))
(message "Knitting finished, starting latexing")
;; Set LaTeX your fav options. See TeX-expand-list for % pars
(setq LaTeX-command-style '(("" "%(PDF)%(latex) -file-line-error %S%(PDFout)")))
;; TeX-command requires a 'file function (anonymous here) returning the filename.
;; TeX-command/TeX-expand-list say 'file has one opt arg: extension.
;; Actually they are 2, despite the second seems always passed true.
(TeX-command "LaTeX" (lambda (&optional ext dummy) tex-name))))