ESS + AUCTeX + Sweave。 从.Rnw <SyncteX集成
我将我的工具链从R + TeXShop改造为我希望的更高效的Sweave - > LaTeX - > SyncteX - > pdfview(skim),通过emacs(Aquamacs,具体而言)AUCTeX模式(使用emacs-speaks- statsitics'sweave小模式)。 从AUCTeX - > pdfview链,SyncteX都可以很好地工作,并且一切工作都很好,从Sweave编译为.pdf。
当我将Sweave添加为第一步时遇到了麻烦。 .Rnw文件现在成为主要的原始文档,它生成的.tex文件只是一个中间步骤。 当然,它是SyncteX锁定的.tex文件。
我对.emacs文件所做的唯一更改是注册两个新命令来从.Rnw构建.pdf。
任何人都可以提供关于如何让emacs使用SyncteX将输出.pdf同步到.Rnw而不是.tex的建议吗?
谢谢!
编辑1: 警告:这最终是我整个下午的一个总结。 我非常接近解决方案,但最终因错误而被挫败,我无法找到相关文档。 警告2:今天是我第一次看到emacs内部工作的深处。 肯定会有错误或效率低下。
VitoshKa的回答让我大部分时间都在那里。 将他的建议添加到我的.emacs(以及Preferences.el,但功能相同)文件导致Symbol's value as variable is void: noweb-minor-mode-map
错误,因为Aquamacs似乎在加载.emacs文件之前其他的init文件。
我通过在VitoshKa (define-key noweb-minor-mode-map (kbd "Cc Cc") 'Rnw-command-master)
之前立即添加(require 'ess-site) (require 'ess-eldoc)
此问题。 不幸的是,Aquamacs随ess-swv.elc文件一起提供了二进制文件,并迫使Mn P阅读器变为acroread。 因此,我将以下对ess-swv.el文件的一部分的编辑添加到了我自己的.emacs的底部:
(defun ess-makePDFandView ()
(interactive)
(setq namestem (substring (buffer-name) 0 (search ".Rnw" (buffer-name))))
(setq tex-filename (concat """ namestem "".tex"))
(setq my-command-string (concat "pdflatex -synctex=1" tex-filename))
(shell-command my-command-string)
(setq my-command-string (concat "/Applications/Skim.app/Contents/MacOS/Skim "" namestem ".pdf" &"))
(shell-command my-command-string))
(define-key noweb-minor-mode-map "M-nv" 'ess-makePDFandView)
现在emacs将使用Mn v或Cc Cc View RET从emacs中以正确的pdf名称启动skim。 还有一个障碍要通过...
emacs中的Command-Shift-Click尝试同步到filename.Rnw.pdf(但至少在pdfviewer中丢弃错误信息仍会导致正确的同步)。 Command-Shift-Click在pdfviewer中搜索回源代码emacs以打开filename.tex文件并同步到该文件。 幸运的是,Cameron Bracken为此做了一个修复。 他只是不会一路走向emacs集成。
所以我将这个ess-swv.el进一步添加到了我的.emacs中:
(defun ess-swv-latex-rnw-sync ()
"Run LaTeX on the product of Sweave()ing the current file."
(interactive)
(save-excursion
(let* ((namestem (file-name-sans-extension (buffer-file-name)))
(latex-filename (concat namestem ".tex"))
(synctex-filename (concat namestem ".synctex.gz"))
(tex-buf (get-buffer-create " *ESS-tex-output*"))
(patchDVI-command-string (concat "Rscript -e "library('patchDVI');patchSynctex('" synctex-filename "')"")))
(message "synctex string: %s" patchDVI-command-string)
(message "Running LaTeX on '%s' ..." latex-filename)
(switch-to-buffer tex-buf)
(call-process "latex" nil tex-buf 1 "-synctex=1 " latex-filename)
(switch-to-buffer (buffer-name))
(display-buffer tex-buf)
(message "Finished running LaTeX" )
(message "Running patchDVI...")
(shell-command patchDVI-command-string))))
(define-key noweb-minor-mode-map "M-nq" 'ess-swv-latex-rnw-sync)
考虑到缺少DVI接口并将其同步......但不是! 与上面的Command-Shift-Click相同的行为...回到黑客ess-swv。 我删除了ess-makePDFandView函数,并将以下内容添加到我的.emacs中:
(defun ess-swv-PDF-rnw-sync (&optional pdflatex-cmd)
"From LaTeX file, create a PDF (via 'texi2pdf' or 'pdflatex', ...), by
default using the first entry of `ess-swv-pdflatex-commands' and display it."
(interactive
(list
(let ((def (elt ess-swv-pdflatex-commands 0)))
(completing-read (format "pdf latex command (%s): " def)
ess-swv-pdflatex-commands ; <- collection to choose from
nil 'confirm ; or 'confirm-after-completion
nil nil def))))
(let* ((buf (buffer-name))
(namestem (file-name-sans-extension (buffer-file-name)))
(latex-filename (concat namestem ".tex"))
(tex-buf (get-buffer-create " *ESS-tex-output*"))
(pdfviewer (ess-get-pdf-viewer))
(pdf-status)
(cmdstr-win (format "start "%s" "%s.pdf""
pdfviewer namestem))
(cmdstr (format ""%s" "%s.pdf" &" pdfviewer namestem)))
;;(shell-command (concat "pdflatex " latex-filename))
(message "Running '%s' on '%s' ..." pdflatex-cmd latex-filename)
(switch-to-buffer tex-buf)
(setq pdf-status
(call-process pdflatex-cmd nil tex-buf 1 "-synctex=1 "
(if (string= "texi2" (substring pdflatex-cmd 0 5))
;; workaround (bug?): texi2pdf or texi2dvi *fail* to work with full path:
(file-name-nondirectory latex-filename)
latex-filename)))
(if (not (= 0 pdf-status))
(message "** OOPS: error in '%s' (%d)!" pdflatex-cmd pdf-status)
;; else: pdflatex probably ok
(shell-command
(concat (if (and ess-microsoft-p (w32-shell-dos-semantics))
cmdstr-win
cmdstr))))
(switch-to-buffer buf)
(display-buffer tex-buf)))
(define-key noweb-minor-mode-map "M-nv" 'ess-swv-PDF-rnw-sync)
越来越近,但我们仍然需要告诉auctex要通过哪些文件名浏览。 所以我咬紧牙关,编辑auctex-config.el。 我评论了现有的aquamacs-call-viewer函数定义,并用我自己的代替它:
(defun aquamacs-call-viewer (line source)
"Display current output file as PDF at LINE (as in file SOURCE).
Calls `aquamacs-tex-pdf-viewer' to display the PDF file using the
Skim AppleScript protocol."
(cond
((string= (file-name-extension (TeX-active-master)) "Rnw")
(let* ((full-file-name
(expand-file-name
;; as in TeX-view
;; C-c C-c view uses %o (from TeX-expand-list), which
;; is the same.
(concat (file-name-sans-extension (TeX-active-master)) "." (TeX-output-extension))
default-directory))
(full-source-name
(expand-file-name
(concat (file-name-sans-extension (source)) ".Rnw") ;; this is relative to the master
(file-name-directory (full-file-name)))))
(message "full pdf name: %s" full-file-name)
(message "full rnw sournce name: %s" full-source-name)
(do-applescript
(format
"
set theSink to POSIX file "%s"
set theSource to POSIX file "%s"
tell application "%s"
activate
open theSink
tell front document to go to TeX line %d from theSource%s
end tell
"
full-file-name full-source-name aquamacs-tex-pdf-viewer line
;; do not say "showing reading bar false" so users can override in future
(cond ((eq t aquamacs-skim-show-reading-bar)
" showing reading bar true")
((eq nil aquamacs-skim-show-reading-bar)
" showing reading bar false")
(t ""))))))
(t
(let* ((full-file-name
(expand-file-name
;; as in TeX-view
;; C-c C-c view uses %o (from TeX-expand-list), which
;; is the same.
(TeX-active-master (TeX-output-extension))
default-directory))
(full-source-name
(expand-file-name
source ;; this is relative to the master
(file-name-directory full-file-name))))
(message "IN OTHERWISE!! WAT: %s" (file-name-extension (TeX-active-master)))
(do-applescript
(format
"
set theSink to POSIX file "%s"
set theSource to POSIX file "%s"
tell application "%s"
activate
open theSink
tell front document to go to TeX line %d from theSource%s
end tell
"
full-file-name full-source-name aquamacs-tex-pdf-viewer line
;; do not say "showing reading bar false" so users can override in future
(cond ((eq t aquamacs-skim-show-reading-bar)
" showing reading bar true")
((eq nil aquamacs-skim-show-reading-bar)
" showing reading bar false")
(t ""))))))))
还有一个最后的测试(注意,我改变了工具链的键绑定为:Mn s→Mn q→Mn v,依次为sweave→latex→view [请注意,对于最后一步,您必须使用pdflatex和不texi2pdf]),一切都建立,没有错误,启动查看器...
"Skim" "/Users/myname/text/testing/myfile.pdf": exited abnormally with code 127.
现在我又完全失去了。 任何人都非常熟悉Skim?
编辑2:好吧,错误127只是在二进制文件没有找到。 在那里的某个地方,我必须破坏道路。 所以我在我的auctex-config.el的顶部附近添加了(setenv "PATH" (concat (getenv "PATH") ":" "/Applications/Skim.app/Contents/MacOS"))
。 现在一切都编译并启动,没有错误......但Command-Shift-Click在emacs上没有得到Skim的回应(至少它没有给出错误)。 Command-Shift-点击Skim仍强制emacs打开.tex文件。
我猜这现在已经成为一个非常Aquamacs + Skim的具体问题,因为除非我错过了上面指出的lisp的关键线条中明显的一些东西,否则大部分其余的交互都在applescript中。
澄清。 您希望Rnw文件中的Cc Cc在Sweave(Mn s)的输出上运行AUCTeX命令。
问题在于Auctex不知道它必须在不同的文件上执行操作。 这是如何使它意识到这一点:
(defun Rnw-command-master (&optional override-confirm)
"Run command on the current document.
If a prefix argument OVERRIDE-CONFIRM is given, confirmation will
depend on it being positive instead of the entry in `TeX-command-list'."
(interactive "P")
(let ((TeX-transient-master (concat
(file-name-sans-extension (buffer-file-name))
".tex"))
(TeX-master nil))
(TeX-command (TeX-command-query (TeX-master-file)) 'TeX-master-file
override-confirm)))
(define-key noweb-minor-mode-map (kbd "C-c C-c") 'Rnw-command-master)
为了让Auctex先运行,它需要一些额外的工作。 Noweb支持现在正在ESS中进行重新编写,到下一个版本,您将拥有一个全新系统,AucTeX集成以及默认激活的其他许多有用功能。
链接地址: http://www.djcxy.com/p/26913.html