[英]Have Emacs to automatically latex your Rnw file after knitting
我想在編織.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機器人視為“主觀且可能被關閉”!
我使用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))\"" ))
)
)
一種可能的解決方案是檢查劣質ESS過程'busy
屬性。 while循環等待它為nil
塊命令echo。 這就是你看到(redisplay)
。 為了避免給親愛的人施加壓力,我還設置了一個刷新延遲(sleep-for .5)
。
為了防止ESS卡住,60秒后循環存在。 如果您有重量級密碼,請調整它。
最后,我將膠乳附加到AUCTeX。 因此,您可以借助TeX-expand-list
文檔自定義LaTeX-command-style
。
該函數自動為knit和latex設置文件的正確名稱,並將R working dir設置為要編織的.Rnw文件,以便您可以獲取其他腳本或加載數據。
因此,您可以使用Mx 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))))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.