In previous post I asked if somebody knew how to get highlighted R code in wordpress. Somebody (yay, I have at least one reader) took this question too seriously, and found out the hard way how to do that. So for those who want to get something like this:

fun <- function(l, nm) {
    l  <- x[[nm]
    ss <- summary(l)
    write.csv(ss,file=paste(nm,".csv",sep=""))
}

foreach(l=x,nm=names(x)) %do% fun(l,nm)

read on, I dare you!

The solution involves Emacs, which in itself is quite intimidating. But as they say, no pain, no gain. After you pass that “I want to poke my eye with red hot poker just for fun” phase, Emacs is quite nice. The drawback of course is, that this phase must be passed :)

So for a start, you must have Emacs installed. For Windows I recommend downloading Vincent Goulet’s prepared Emacs distribution. It comes with several useful packages preinstalled, such as ESS. For Ubuntu, your best bet would be to install emacs-snapshot, so you get nice looking Emacs. Then you will need to install ESS. For serious R programming, I think ESS is a must. I do not go into details, but is much more convenient than standard R window.

In addition you have to install htmlize and org-mode Emacs extensions. The org-mode may be included in your Emacs distribution. The instructions how to instal org-mode can be found in the website. To install htmlize, save the file htmlize.el to some directory, and byte-compile it from Emacs with command M-x byte-compile-file. Then include the directory into your Emacs load path, i.e. include this line at the top of your .emacs (or emacs) file:

(setq load-path (cons (expand-file-name "~/src/emacs-lisp/") load-path))

If you do custom org-mode install you may want include the following line also:

(require 'org-install)

To get highlighted R code, you will also need to add this code to your .emacs file:

(defun run-ascii-sweave-on-buffer ()
  (ess-command "library(ascii)\n")
  (ess-command (concat "Sweave(\"" (buffer-file-name)
                       "\", RweaveAsciidoc)\n")))

(defun htmlize-blog-entry ()
   (interactive)
   (save-excursion
      (let*
       (goto-char (point-min))
       (basic-save-buffer)
       (switch-to-buffer (org-export-region-as-html
                          (point-min) (point-max) t "*HTML*"))
       (while (re-search-forward "<pre " nil t)
         (replace-match
          "<pre style=\"background-color:#FFFFE5; font-size:8pt;overflow:auto\" "
          t nil))
       (kill-ring-save (point-min) (point-max))
      )))

(defun sweave-and-htmlize-blog-entry ()
   (interactive)
   (save-excursion
     (run-ascii-sweave-on-buffer)
     (let* ((name (buffer-file-name))
            (txt-filename (concat name ".txt"))
            (txt-buf (find-file txt-filename)))
       (switch-to-buffer txt-buf)
       (revert-buffer t t t)
       (goto-char (point-min))
       (while (re-search-forward "BEGIN_SRC Sweave" nil t)
         (replace-match "BEGIN_SRC R-transcript" t nil))
       (goto-char (point-min))
       (while (re-search-forward "^----" nil t)
         (replace-match "" nil nil))
       (basic-save-buffer)
       (switch-to-buffer (org-export-region-as-html
                          (point-min) (point-max) t "*HTML*"))
       (kill-buffer txt-buf)
       (while (re-search-forward "<pre " nil t)
         (replace-match
          "<pre style=\"background-color:#FFFFE5; font-size:8pt;overflow:auto\" "
          t nil))
       (kill-ring-save (point-min) (point-max)))))

(define-key global-map (kbd "<f11>") 'sweave-and-htmlize-blog-entry)
(define-key global-map (kbd "<f12>") 'htmlize-blog-entry)

I took those functions from the this blog, and made some modifications. You can copy paste it directly from here, or download all the code from here

To get the syntax highlighting you must write all the necessary material in the file with extension .org. Here is a sample file with some examples from this post. When you open this file in the Emacs, it should automatically open up org-mode (if it was installed properly). Now if you want some R code to syntax highlight, you write it inside these two statements:

#+BEGIN_SRC R
fun <- function(l, nm) {
    l  <- x[[nm]
    ss <- summary(l)
    write.csv(ss,file=paste(nm,".csv",sep=""))
}
foreach(l=x,nm=names(x)) %do% fun(l,nm)
#+END_SRC R

Then if you are finished, just press f12, and Emacs will open you a new window with shiny HTML code. Copy this code to your blog, and that is it.

If you also want to include R code which gets executed by R, like this:

> x <- rnorm(100)
> summary(x)
    Min.  1st Qu.   Median     Mean  3rd Qu.     Max.
-2.08300 -0.67620  0.03544  0.06616  0.81680  2.34000

first you must start R process with M-x R. Then include in your .org code the code snippet like this (it helps if you know Sweave syntax):

#+BEGIN_SRC Sweave
<>=
x <- rnorm(100)
summary(x)
@
#+END_SRC

and then press f11.

The keyboard shortcuts can be changed if you want, just modify the the emacs code, you’ve added to your .emacs file. The code is more or less self-explanatory. By pressing f11 you invoke function sweave-and-htmlize-blog-entry, which runs
Sweave function from R on your text. The resulting file is exported to html by org-mode. By pressing f12 you invoke function htmlize-blog-entry, which exports to html, without invoking R. Since we use org-mode export, you can syntax highlight not only R code, but other code, which has support in Emacs. This means C, emacs-lisp, latex and others.

So here it is. If something did not work, try asking here, maybe I can help. I do not promise anything, I am no Emacs expert.

Special thanks goes to Raimondas, who spent two days to get a working example, with no previous Emacs knowledge. Buy him a beer, if you find this post useful. Also do not forget the guy who wrote the initial code, and the guys who created Emacs, org-mode, htmlize, ESS, R. Buy them a beer also :)

About these ads