knitr Markdown highlighting in Emacs?

Is there any modification of an existing tool or new tool that will syntax-highlight (colour) blocks of R code in a knitr markdown document when opened in Emacs?

The knitr chunks I am looking at are triple-backtick blocks [```] that contain R code inside.

EDIT: things that I tried so far:

- Ubuntu 12.04 with Emacs 23

emacs --version
GNU Emacs 23.3.1

1. Polymode

https://github.com/vitoshka/polymode/issues/3

I am trying to get polymode to syntax-highlight my Rmd files, but it's complaining about a 'color' load file:

cd ~/.emacs.d
git clone https://github.com/vitoshka/polymode.git

In my .emacs file:

(add-to-list 'load-path "/home/avilella/.emacs.d/polymode/")
(add-to-list 'load-path "/home/avilella/.emacs.d/polymode/modes/")

;; Require any polymode bundles that you are interested in:

(require 'poly-R)
(require 'poly-markdown)

eval-buffer:

Cannot open load file: color

- CentOS with Emacs 24:

emacs --version
GNU Emacs 24.2.1

1. Polymode installed correctly

Open a Rmd file, M-x polymode-minor-mode, no change to the syntax highlighting.


emacs --version
GNU Emacs 24.3.1

1. Polymode installed correctly

Open a Rmd file, M-x poly-markdown+r-mode, some of the syntax highlighting starts to appear, but I need to manually modify the test in each triple-tick block of code for it to fully show the syntax.

Enter image description here

Enter image description here

The second image is just after typing a Return before the knitr block.


Solution 1:

This might help: http://sjp.co.nz/posts/emacs-ess-knitr/

Knitr markdown in Emacs through ESS

Solution 2:

Your problem

First of all, you say you have GNU Emacs 23.3.1, but in polymode readme.md, it reads:

Tested with Emacs 24.3.1 and 24.4.5.

As for your error: "Cannot open load file: color", in polymode.el, there is the line:

(require 'color)

this package is in Emacs 24, but it might well miss in your version.

Solution

  1. Upgrade to a recent (therefore supported) version of Emacs.

  2. Extract the polymode.zip in a directory where you keep Emacs material, e.g.:

    ~\conf\emacs
    

and change the resulting polymode-master dir to polymode

  1. Add this in your init file (and if you used different names above, change names below accordingly):

    ;; Just an Emacs personal dir containing polymode packages etc.
    (setq MY-EMACS  "~/conf/emacs") 
    
    (defun my-emacs  (subfolder)
    "Get path to personal dir + subfolder"
    (concat (expand-file-name MY-EMACS) "/" subfolder))
    
    ;; ESS Markdown
    ;; -------------
    (defun rmd-mode ()
      "ESS Markdown mode for rmd files"
      (interactive)
      (setq load-path 
        (append (list (my-emacs "polymode/") 
                  (my-emacs "polymode/modes/"))
            load-path))
      (require 'poly-R)
      (require 'poly-markdown)
      (poly-markdown+r-mode))
    
    ;; Wrap line in markdown. Comment if you don't dislike words cut in the middle
    (add-hook 'markdown-mode-hook (lambda () (visual-line-mode 1)))
    
    ;; Let you use markdown buffer easily
    (setq ess-nuke-trailing-whitespace-p nil)  
    
  2. Meta+rmd when the Rmd-file is open or set the mode in <!-- Local Variables: -->
    ... enjoy a dramatic change in your productivity.

PS
Do not overlook last elisp line. It will allow to save markdown properly. Otherwise, when you reopen your doc, you'll have unpleasant surprises.

A note to Windows users

Skip this if you are a Linux guy, but, despite the question mention Ubuntu, my answer applies perfectly to Windows Emacs too. Just with respect to:

  • Step 2) You will extract polymode.zip in:

    %USERPROFILE%\conf\emacs
    

    As you guess, the environment variable %USERPROFILE% contains the path to your user profile directory. If you are not sure what it is, execute set USERPROFILE in the CLI prompt.
    As a Windows user you might be used to store things in My Documents. In that case your dir will be:

    %USERPROFILE%\Documents\conf\emacs
    
  • Step 3) If in Step 2) you used the path %USERPROFILE%\Documents\conf\emacs, change accordingly the first code line from:

    (setq MY-EMACS  "~/conf/emacs") 
    

    to (note the slashes):

    (setq MY-EMACS  "~/Documents/conf/emacs") 
    

    In both cases (with and without "My Documents"), you might prefer the more Windows style:

    (setq MY-EMACS (substitute-in-file-name "$USERPROFILE/Documents/conf/emacs"))