Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign up| ;;; pander.el --- ESS integration of pander (R) package | |
| ;; Copyright (C) 2012 Gergely Daróczi | |
| ;; | |
| ;; Author: Gergely Daróczi <gergely@snowl.net> | |
| ;; Version: 0.1 | |
| ;; Package-Requires: ((ess)) | |
| ;; Keywords: ESS, R, report | |
| ;; X-URL: http://rapporter.github.com/pander/ | |
| ;; This file is not part of GNU Emacs. | |
| ;; This "program" is free software; you can redistribute it and/or | |
| ;; modify it under the terms of the Affero General Public License | |
| ;; as published by the Free Software Foundation; version 3. | |
| ;; | |
| ;; This program is distributed in the hope that it will be useful, | |
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| ;; AGPL for more details: http://www.gnu.org/licenses/agpl-3.0.html | |
| ;;; Installation and load | |
| ;; This file can be found on your filesystem if pander R package | |
| ;; is installed. If you do not know where it is, run the following | |
| ;; command in *R*: | |
| ;; | |
| ;; system.file('pander.el', package='pander') | |
| ;; | |
| ;; To use this minor, simply add the above firectory to your path | |
| ;; and load pander.el, e.g.: | |
| ;; | |
| ;; (add-to-list 'load-path "/usr/lib/R/library/pander/") | |
| ;; (require 'pander) | |
| ;; | |
| ;;; Feedback | |
| ;; This minor-mode is under heavy development. Any suggestion/feedback | |
| ;; really welcomed at GH issue tracker: | |
| ;; | |
| ;; http://rapporter.github.com/pander/issues | |
| ;;; TODO: | |
| ;; * escaping issue (now changing all double quotes to single quotes in selection) | |
| ;;; Code: | |
| ;; minor mode | |
| (defgroup pander nil | |
| "ESS integration of pander R package" | |
| :group 'ess) | |
| (defvar pander-mode-map | |
| (let ((keymap (make-sparse-keymap))) | |
| (define-key keymap (kbd "C-c p b") 'pander-brew) | |
| (define-key keymap (kbd "C-c p B") 'pander-brew-export) | |
| (define-key keymap (kbd "C-c p e") 'pander-eval) | |
| keymap) | |
| "Keymap for pander-mode.") | |
| (define-minor-mode pander-mode | |
| "Toggle pander mode. | |
| With no argument, this command toggles the mode. | |
| Non-null prefix argument turns on the mode. | |
| Null prefix argument turns off the mode. | |
| When pander mode is enabled, some keybindigs | |
| are activated for pander functions." | |
| :lighter " pander" | |
| :group 'pander | |
| ) | |
| ;; Define key-bindings for calling above functions | |
| ;; (global-set-key (kbd "C-c p e") 'pander-evals-region) | |
| ;; (global-set-key (kbd "C-c p r") 'pander-region) | |
| ;; (global-set-key (kbd "C-c p c") 'pander-chunk) | |
| ;; (global-set-key (kbd "C-c p p") 'pander-region-or-chunk) | |
| ;; (global-set-key (kbd "C-c p R") 'pander-region-export) | |
| ;; (global-set-key (kbd "C-c p C") 'pander-chunk-export) | |
| ;; (global-set-key (kbd "C-c p P") 'pander-region-or-chunk-export) | |
| (defcustom pander-clipboard nil | |
| "If non-nil then the result of pander-* functions would be copied to clipboard." | |
| :type 'boolean | |
| :group 'pander) | |
| (defcustom pander-show-source nil | |
| "If non-nil then the source of R commands would also show up in generated documents while running 'pander-eval'. This would not affect 'brew' function ATM." | |
| :type 'boolean | |
| :group 'pander) | |
| ;; functions | |
| (defun pander-postprocess-output () | |
| "Prettify results in *ess-output* and optionally copy to clipboard." | |
| ;; remove possible "+" chars at the beginning of the result | |
| (set-buffer "*ess-output*") | |
| (beginning-of-line) | |
| (while (re-search-forward "\\+ " (min (point-at-eol)) 'go) | |
| (replace-match "")) | |
| ;; copy to clipboard | |
| (if pander-clipboard | |
| (clipboard-kill-ring-save (point-min) (point-max)) | |
| ) | |
| ) | |
| (defun pander-brew () | |
| "Run Pandoc.brew on current buffer or region (if mark is active), show results in *ess-output* and (optionally) copy results to clipboard while setting working directory to tempdir() temporary." | |
| (interactive) | |
| (save-excursion | |
| (if mark-active | |
| (let ( | |
| (selection (buffer-substring-no-properties (region-beginning) (region-end)))) | |
| (ess-execute (format "require(pander, quietly=T);wd<-getwd();setwd(tempdir());Pandoc.brew(text=\"%s\");setwd(wd)\n" (replace-regexp-in-string "\"" "'" selection))) | |
| ) | |
| (ess-execute (format "require(pander, quietly=T);wd<-getwd();setwd(tempdir());Pandoc.brew(\"%s\");setwd(wd)\n" buffer-file-name)) | |
| ) | |
| (pander-postprocess-output) | |
| ) | |
| ) | |
| (defun pander-brew-export () | |
| "Run Pandoc.brew on current buffer or region (if mark is active) and export results to specified (auto-complete in minibuffer) format. Also tries to open exported document." | |
| (interactive) | |
| (save-excursion | |
| (let ((output-format (completing-read "Output format: " | |
| '(("html" 1) ("pdf" 2) ("odt" 3) ("docx" 4)) nil nil "html"))) | |
| (if mark-active | |
| (let ( | |
| (selection (buffer-substring-no-properties (region-beginning) (region-end)))) | |
| (ess-command (format "require(pander, quietly=T);wd<-getwd();setwd(tempdir());Pandoc.brew(text=\"%s\",output=tempfile(),convert=\"%s\" );setwd(wd)\n" (replace-regexp-in-string "\"" "'" selection) output-format)) | |
| ) | |
| (ess-command (format "require(pander, quietly=T);wd<-getwd();setwd(tempdir());Pandoc.brew(\"%s\",output=tempfile(),convert=\"%s\");setwd(wd)\n" buffer-file-name output-format)) | |
| ) | |
| ) | |
| ) | |
| ) | |
| (defun pander-eval () | |
| "Run pander on (automatically evaluated) region *or* current chunk (if marker is not set), show results (of last returned R object) in *ess-output* and (optionally) copy those to clipboard while setting working directory to tempdir() temporary. Chunk is recognized by opening '<%' or '<%=', and closing '%>' tags." | |
| (interactive) | |
| (save-excursion | |
| (let ((show-src | |
| (if pander-show-source | |
| (concat "TRUE") | |
| (concat "FALSE")) | |
| )) | |
| (if mark-active | |
| (let ( | |
| (selection (buffer-substring-no-properties (region-beginning) (region-end)))) | |
| (if (= (length selection) 0) | |
| (message "Nothing selected in region.") | |
| (ess-execute (format "pander:::ess.pander.evals(\"%s\", show.src=%s)\n" (replace-regexp-in-string "\"" "'" selection) show-src)))) | |
| (let (p1 p2) | |
| (skip-chars-backward "^<%[=]+") (setq p1 (point)) | |
| (skip-chars-forward "^%>") (setq p2 (point)) | |
| (let ( | |
| (selection (buffer-substring-no-properties p1 p2))) | |
| (if (= (length selection) 0) | |
| (message "Pointer is not inside a chunk!") | |
| (ess-execute (format "pander:::ess.pander.evals(\"%s\", show.src=%s)\n" (replace-regexp-in-string "\"" "'" selection) show-src)))))) | |
| )(pander-postprocess-output)) | |
| ) | |
| (provide 'pander) |