emacs - ESS + AUCTeX +编织。来自.Rnw <-> pdfviewer的SyncteX集成?

标签 emacs sweave ess auctex

我正在将工具链从R + TeXShop重构到我希望是更有效的Sweave-> LaTeX-> SyncteX-> pdfview(skim)通过emacs(具体来说是Aquamacs)AUCTeX模式(带有emacs-speaks-统计信息的偏斜次要模式)。从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的(require 'ess-site) (require 'ess-eldoc)之前立即添加(define-key noweb-minor-mode-map (kbd "\C-c \C-c") 'Rnw-command-master)来解决此问题。不幸的是,Aquamacs附带了已经是二进制文件的ess-swv.elc文件,并强制对M-n P阅读器进行acroread。因此,我在自己的.emacs底部添加了对ess-swv.el文件的一部分的以下编辑:

(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将使用 M-n v C-c C-c View RET 从emacs中使用正确的pdf名称启动脱脂。还有更多障碍可以克服...

emacs中的Command-Shift-Click尝试同步到filename.Rnw.pdf(但丢弃错误消息至少仍会导致pdfviewer中的正确同步)。
在pdfviewer中单击Command-Shift-Click以搜索回源,这迫使emacs打开filename.tex文件并与之同步。 Fortunately, Cameron Bracken has a fix for that。他只是没有完全进行emacs集成。

因此,我在.emacs中添加了进一步的ess-swv.el hack:
(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上的行为相同...返回hack 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 ""))))))))

还有另一个最终测试(请注意,我将工具链的键绑定(bind)更改为:Mn s-> Mn q-> Mn v,以便进行旋转->乳胶-> 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"))。现在,所有内容都可以编译并且没有错误地启动了……但是emacs上的Command-Shift-Click并没有让Skim做出响应(至少它没有给出错误)。 Command-Shift-单击“略读”仍会强制emacs打开.tex文件。

我猜这已经成为一个非常针对Aquamacs + Skim的问题了,因为其余的大部分交互都是在applescript中进行的,除非我错过了上面指出的lisp关键行中显而易见的内容。

最佳答案

澄清。您希望Rnw文件中的C-c C-c在Sweave(M-n 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集成功能,并且默认情况下还激活了许多其他有用的功能。

关于emacs - ESS + AUCTeX +编织。来自.Rnw <-> pdfviewer的SyncteX集成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11060023/

相关文章:

emacs - 我可以在 org-mode src block 中禁用某些语言的安全确认吗?

r - 什么是空图形设备?

r - 使用 Sweave 动态生成 PDF 报告

Report/LaTeX 质量输出包

r - Emacs ESS 模式 TAB 停止缩进

emacs - 覆盖Emacs 23字体替换

emacs - 让 Emacs 对缩进不那么咄咄逼人

emacs - ESS/AucTeX/Sweave 集成

r - ESS 找不到指定包中的文档

python - 如何在我的主模式 Hook 中访问目录局部变量?