이것은 올인원 솔루션입니다. 그것은 것입니다 만들고 RNW에서 PDF를 표시합니다 .
구체적으로 다음과 같습니다.
- Rnw 버퍼를 저장하고 편직하십시오.
- 주어진 LaTeX 엔진을 결과 TeX 파일에 적용하십시오.
- BibTeX 엔진 실행 파일 (예 : biber, bibtex8)을 식별하십시오.
- bib 파일이 TeX 파일보다 최신 인 경우 TeX 파일에서 BibTeX 엔진을 실행하십시오.
- LaTeX를 다시 실행하십시오. 6 지정된 뷰어에서 결과 PDF를 엽니 다.
위의 단계 중 하나가 실패하면 절차는 정보 메시지와 함께 종료를 시도합니다.
필요한 경우 R 인스턴스가 열리거나 현재의 인스턴스가 편직 프로세스를 표시하는 데 사용됩니다.
LaTeX 출력은 "TeX-output"버퍼로 전송되며, 컴파일 오류가 발생하면 팝업됩니다.
용법
Meta- x knit-me
작성하고 PDF를 볼 수 있습니다.
Meta- x knit-me-clear
중간 LaTeX 파일을 제거합니다 knit-me
.
참고 문헌에는 "biblatex"패키지가 필요합니다.
\usepackage[
options...
backend=ENGINE,
]{biblatex}
\addbibresource{foo.bib}
턱받이 엔진의 이름은 (예를 들어 bibtex
, biber
)를 구문 분석 얻을 backend
키워드를.
\addbibresource
참고 문헌 파일을 얻기 위해 명령을 구문 분석합니다. foo.bib
TeX 파일보다 최신 파일이면 bib 엔진이 실행됩니다. 이와 관련하여 \addbibresource
많은 명령이 있는 경우 첫 번째 명령 만 고려됩니다.
커스터마이즈
실제로 PDF를 보려면 다음을 사용하여 뷰어 실행 파일 경로를 설정하십시오.
(setq pdf-viewer "path/to/pdf-viewer")
SumatraPDF 와 같은 뷰어를 사용 하면 다시 컴파일 할 때 PDF를 자동으로 업데이트하고 열린 파일을 차단하지 않아 새 컴파일을 방해하지 않을 수 있습니다.
기본 LaTeX 엔진은 pdflatex
(현재 경로에서 가정)입니다. 다음으로 사용자 정의하십시오.
(setq latex-engine "newengine"
latex-args "--option-1 --option-2")
물론 편리한 키 를 바인딩 knit-me
하고 싶을 수도 있습니다 knit-me-clear
.
노트
와, 윈도우 MiKTeX에서 테스트 biber
및 bibtex8
백엔드와 GNU 이맥스 25.1.1.
Elisp 코드
;; (require 'ess-site) ; assumed in your init file
(defun knit-me-clear ()
"Delete intermediate LaTeX files and run `knkt-me'.
These are based on extensions .aux, .blg, .out, .run.xml, .bbl, .log, -blx.bib"
(interactive)
(check-Rnw)
(let
((file)
(stem (file-name-sans-extension (buffer-file-name))))
(dolist (elt
(list ".aux" ".blg" ".out" ".run.xml" ".bbl" ".log" "-blx.bib"))
(setq file (concat stem elt))
(if (file-exists-p file) (delete-file file))))
(knit-me))
(defun knit-me ()
"Knit->LaTeX-engine->bibtex-engine->LaTeX-engine->View.
Default LaTeX engine is \"pdflatex\" and can be customised with `latex-engine';
default LaTeX arguments are set to nil and can be customised with `latex-args';
default PDF viewer is set to nil and can be customised with `pdf-viewer'.
Bibliography must be set via \"biblatex\" LaTeX package.
Bibliography engine is obtained from \"backend\" option in \"biblatex\" package.
A reference LaTeX bib file is obtained from the first LaTeX command \"\addbibresource{foo.bib}\".
The biblatex-engine is run if the bib file is newer of the TeX file.
If there are multiple \"\addbibresource\" only the first will be used to decide whether to run the biblatex-engine."
(interactive)
;; Default values
(defvar pdf-viewer nil)
(defvar latex-engine "pdflatex")
(defvar latex-args nil)
(check-Rnw)
;;If 1 R-proc found, associate it with buffer;
;;if many found, ask to choose one; if none found, launch and associate
(ess-force-buffer-current "Process to use: ")
;;Save Rnw buffer
(save-buffer)
(let*
(;;Set file paths
(pathstem (file-name-sans-extension (buffer-file-name)))
(namestem (file-name-nondirectory pathstem))
(cur-dir (file-name-directory pathstem))
(rnw-name (concat namestem ".Rnw"))
(tex-name (concat namestem ".tex"))
;;Create LaTeX commmand
(latex-args (concat latex-args " " namestem))
(latex-cmd (concat latex-engine " " latex-args))
;;Create knit commmand
(knit-cmd (format "require(knitr); setwd('%s'); knit('%s')" cur-dir rnw-name))
;;Get R buffer proc
(r-proc (ess-get-process))
(r-buf (ess-get-process-buffer))
;;TeX executable process and bibtex engine/file
(tex-proc)
(tex-buf)
(bibfile (bib-getfile))
(bibengine (bib-getengine))
(bibfile-updated
(file-newer-than-file-p
(concat cur-dir (file-name-nondirectory bibfile) ".bib") (concat pathstem ".tex")))
;;Command success
(success nil)
(error-msg "")
)
(setq default-directory cur-dir)
;; Exit on error
(catch 'exit-func
;;Check bibtex file and engine
(when (not bibfile)
(setq error-msg (bib-getfile t))
(throw 'exit-func nil))
(when (not bibengine)
(setq error-msg (bib-getengine t))
(throw 'exit-func nil))
;; Biber wants .bib
(let ((fail (and (string= bibengine "biber")
(string= (file-name-nondirectory bibfile) (file-name-base bibfile)))))
(setq success (not fail)))
(when (not success)
(setq error-msg
(format "biber wants \\addbibresource{%s%s}" (file-name-base bibfile) ".bib"))
(throw 'exit-func nil))
;; Knitting
(switch-to-buffer-other-window r-buf)
(message knit-cmd)
(ess-eval-linewise knit-cmd nil t nil t)
;; Foll. 3 lines are an alternative to ess-eval
;; (inferior-ess-mark-as-busy r-proc) ; knit immediately after this line
;; (process-send-string r-proc (format "cat(\"%s\");%s\n" knit-cmd knit-cmd)) ; real
;; (ess-wait-for-process r-proc nil)
;; Check for knitting results
(with-current-buffer r-buf
;; Parse last 3 lines
(let ((beg) (end) (out))
(goto-char (point-max))
(setq end (point))
(forward-line -3)
(setq beg (point))
(setq out (buffer-substring-no-properties beg end))
;; Knitting successful?
(setq success "output file: %s\n\n[1] \"%s\"\n> ")
(setq success (string= (format success tex-name tex-name) out))))
(when (not success)
(setq error-msg (concat "Unable to knit " rnw-name))
(throw 'exit-func nil))
;; First LaTeXing
(setq tex-buf (get-buffer-create "TeX-output")) ; Create output buffer or use existing
(with-current-buffer tex-buf
(buffer-disable-undo)
(erase-buffer))
(message "1st latex ...")
(send-r-mess (format "Starting LaTeX (see \"%s\")" (buffer-name tex-buf)))
(send-r-mess latex-cmd)
(setq success (= 0 (call-process latex-engine nil tex-buf t latex-args)))
(goto-char (point-max))
;; Check 1st LaTeX results
(when (not success)
(setq error-msg (concat "Unable to LaTeX " namestem))
(switch-to-buffer-other-window tex-buf)
(other-window 1)
(throw 'exit-func nil))
;; Run bibtex engine
(when bibfile-updated
(message "biblatex ...")
(send-r-mess (concat bibengine " " namestem))
(setq success (= 0 (call-process bibengine nil tex-buf t namestem)))
(goto-char (point-max))
;; Check bibtex results
(when (not success)
(setq error-msg (concat "Unable to " bibengine " " namestem))
(switch-to-buffer-other-window tex-buf)
(other-window 1)
(throw 'exit-func nil)))
;; Second LaTeXing
(message "2nd latex ...")
(send-r-mess latex-cmd)
(setq success (= 0 (call-process latex-engine nil tex-buf t latex-args)))
(goto-char (point-max))
;; Check 2nd LaTeX results
(when (not success)
(setq error-msg (concat "Unable to LaTeX " pathstem))
(switch-to-buffer-other-window tex-buf)
(other-window 1)
(throw 'exit-func nil))
;; View
(if (not pdf-viewer) (throw 'exit-func nil))
(send-r-mess "...and now the viewer")
(goto-char (point-max))
(setq success (file-exists-p pdf-viewer))
(when (not success)
(setq error-msg (concat "Can\\'t find executable " pdf-viewer))
(throw 'exit-func nil))
;; If you need viewer console output, use "(start-process "pdf-viewer" tex-buf ...";
;; but you block tex-buf buffer till the viewer is open
(start-process "pdf-viewer" nil pdf-viewer (concat namestem ".pdf")))
(if success
(if bibfile-updated (message (concat "Updated to " (file-name-nondirectory bibfile))))
(message error-msg)
(send-r-mess error-msg))))
(defun bib-getfile(&optional show-messages)
"Check if 'addbibresource' command and related file exist.
If found, return .bib file full path, else:
if SHOW-MESSAGES is nil return nil, if SHOW-MESSAGES is non-nil return related error."
(save-excursion
(goto-char (point-min))
(re-search-forward "\\\\addbibresource{\\(.+\\)}" nil t))
(let ((fmatch (match-string-no-properties 1))
(success nil)
mess)
(cond
((not fmatch) (setq mess "Missing \\addbibresource command."))
((not (file-exists-p (concat (file-name-sans-extension fmatch) ".bib")))
(setq mess (concat "Missing file: " fmatch ".bib")))
;; if no problem, sucess=message=bib-file-path
(t (setq mess (concat (file-name-directory (buffer-file-name)) fmatch)
success mess)))
(if show-messages mess success)))
(defun bib-getengine(&optional show-messages)
"Find biblatex engine.
If found, engine name, else:
if SHOW-MESSAGES is nil return nil, if SHOW-MESSAGES is non-nil return related error."
(save-excursion
(goto-char (point-min))
(let ((pack (re-search-forward "\\\\usepackage *\\(\\[[^]]*\\)\\] *{ *biblatex *}" nil t))
(bend nil)
mess)
(when pack (setq pack (match-string-no-properties 1)))
(when (and pack
(string-match "[^[:alpha:]]+backend *= *\\([^, \n]+\\)" pack))
(setq bend (match-string 1 pack)))
(cond
((not pack) (setq mess "Missing biblatex package command."))
((not bend) (setq mess "Missing biblatex backend."))
;; if no problem, sucess=message=bib-file-path
(t (setq mess bend)))
(if show-messages mess bend))))
(defun send-r-mess (mess)
"Just send MESS at the end of R console buffer"
(process-send-string (ess-get-process)
(format "cat('%s\\n')\n" mess)))
(defun check-Rnw ()
"Give error if `ess-dialect' is not \"R\""
(if (not (string= "R" ess-dialect))
(error "Not an Rnw buffer")))
rmarkdown::render
통해 (약을 통해shell-command
) 짧은 Elisp 함수를 사용buffer-file-name
하여 다른 창에서 pdf를 업데이트합니다.