Skip to content

Instantly share code, notes, and snippets.



Created Jul 20, 2011
What would you like to do?
Emacs support for R embedded in HTML (using brew R package)
;;; support for 'brew' as a mixture of R and HTML
(load-file "~/.emacs.d/multi-mode.el")
(load-file "~/.emacs.d/html-brew.el")
(add-to-list 'auto-mode-alist '("\\.brew\\'" . html-brew-mode))
;;; html-brew.el --- multi-mode R embedded in HTML
;;; Felix Andrews <> 2011-04-18
;;; adapted from:
;;; html-php.el --- multi-mode PHP embedded in HTML
;; Copyright (C) 2008 Dave Love
;; Author: Dave Love <>
;; Keywords: languages
;; $Revision: 2$
;; URL:
;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Commentary:
;; Multiple-mode editing of PHP embedded in HTML. Subject to the
;; limitations of multi-mode.el. Note that there's no attempt to deal
;; with commented processing instructions markup. Note also that this
;; only works properly with the basic HTML mode -- not PSGML or NXML.
;; Tested with the PHP mode from the hacked CC mode at the above URL.
;;; Code:
(require 'multi-mode)
(defun html-brew-mode ()
"Mode for editing R embedded in HTML as brew, using multi-mode."
(set (make-local-variable 'multi-alist)
(r-mode . html-brew-chunk-region)))
(defun html-brew-chunk-region (pos)
"Mode-selecting function for R embedded in HTML as brew.
See `multi-alist'."
(let ((case-fold-search t)
pi-start pi-end next-pi)
(goto-char pos)
(let* ((p1 (save-excursion
;; Check whether we're on the processing
;; instruction start. Skip definitely clear of
;; it and then search backwards.
(goto-char (min (point-max) (+ (point) 5)))
(search-backward "<%" (- (point) 9) t)))
(match-end (if p1 (match-end 0)))
;; Otherwise search backwards simply.
(p2 (unless p1 (search-backward "<%" nil t))))
(if p2 (setq match-end (match-end 0)))
(setq pi-start (or p1 p2))
;; Ready to search for matching terminator or next
;; processing instruction.
(goto-char (or match-end pos)))
(if pi-start
;; Look forward for the PI terminator.
(let* ((p1 (save-excursion
;; Check whether we're on the terminator.
(backward-char 1)
(search-backward "%>" (- (point) 2) t)))
(p2 (unless p1 (search-forward "%>" nil t))))
(setq pi-end (or p1 p2 (point-max))))
(goto-char pos))
(if (and pi-start pi-end (< pos pi-end))
;; We were between PI start and terminator.
(list 'r-mode pi-start pi-end)
;; Otherwise, look forward for a PI to delimit the HTML
;; region.
(setq next-pi (if (search-forward "<%" nil t)
(match-beginning 0)
(if pi-start
(list 'html-mode (or pi-end (point-min)) next-pi)
(list 'html-mode (point-min) next-pi))))))))
(provide 'html-brew)
;;; html-brew.el ends here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment