html-script.el -- narrow/widen on PHP/CSS/etc. blocks in html
;; visual basic embedded in (X)HTML
;; Copyright (C) 2005 by P J Heslin
;; Author: Peter Heslin <[hidden email]>
;; URL: http://www.dur.ac.uk/p.j.heslin/Software/Emacs/Download/html-script.el ;; Version: 2.0
;; This program 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 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
;; 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, 675 Massachusetts Ave,
;; Cambridge, MA 02139, USA.
;; This file used to be called nxml-script.el, when it only supported
;; nxml-mode; now it has been completely rewritten and made a bit more
;; general, so it can be used with any major mode for editing (X)HTML.
;; When using html-mode or nxml-mode to edit (X)HTML, this file
;; enables you to narrow the visible buffer to show just a
;; then to switch from html-mode or nxml-mode to the appropriate mode
;; for that block. When finished editing that block, it enable you
;; easily to show the whole buffer and switch back to the original
;; mode again.
;; The user interface consists of a single keystroke: by default, F12.
;; To change it, customize the value of 'html-script-key. In html-mode
;; or nxml-mode, this key looks to see if the cursor is inside a
;; script/style block, and if it is, it narrows the buffer to that
;; block and switches to the appropriate mode. Hit the same key again
;; to go back to editing the whole file in the original mode.
;; The original idea was taken from html-helper-mode.el
;; To install, put this file in your load-path, and require it via
;; your .emacs.
;; (require 'html-script)
;; There are various customizations available, including a list of
;; modes in which to install html-script (defaults to html-mode and
;; You also need to have the relevant autoloads set up for the script
;; modes you want to use, like so:
;; (autoload 'php-mode "php-mode" "PHP mode" t)
;; Supported major modes for script/style blocks include php-mode,
;; You might also need to tell emacs to open .php, .jsp and such files
;; in html-mode or nxml-mode, like so:
;; (setq auto-mode-alist (cons '("\\.php?$" . nxml-mode) auto-mode-alist))
;; Visual Basic not at all, and so the code for these last two has not
;; been tested.
;; 1.0 First public release of nxml-script.el
;; 2.0 Changed name to html-script.el and completely rewritten.
;; Removed 'nxml-script-function and 'nxml-script-region-function, as
;; too confusing. Various user customization variables have changed.
(defgroup html-script nil
"Switch flyspell language according to LaTeX babel commands"
:tag "Narrow (X)HTML documents to script blocks and widen again"
(defcustom html-script-install-modes '(nxml-mode html-mode)
"A list of modes in which to install a binding for html-script.
The key to bind is defined by html-script-key")
(defcustom html-script-key [f12]
"Key to use to toggle narrowing and widening")
'(("<%" "%>" visual-basic-mode)
("<\\?" "\\?>" php-mode c-mode)
("<style[ \t]+type=\"text/css\"" "</style>" css-mode c-mode)
("<style[ \t]+type=\"css\"" "</style>" css-mode c-mode)
("<script[ \t]+language=\"vbscript\"[ \t]*>" "</style>" visual-basic-mode)
("<script[ \t]+type=\"text/vbscript\"[ \t]*>" "</style>" visual-basic-mode)
"Define script regions. Each entry should consist of a list of
a starting regexp, an ending regexp, and a list of modes to try
for that region in that order.")
(defvar html-script-original-mode nil)
;; This immunizes it against kill-all-local-variables, which is run
;; when the new major-mode is called.
(put 'html-script-original-mode 'permanent-local t)
(defun html-script-narrow ()
(let* ((orig (point))
(if (re-search-backward html-script-start-regexp nil t)
(loop for x in html-script-regions
when (looking-at (car x)) return (cdr x)
finally do (error "html-script: regexp mismatch"))
(message "Not in a script region.")
(html-script-narrow-handler orig handler-list)
(defun html-script-narrow-handler (orig arg-list)
(let ((ending-re (car arg-list))
(modes (cdr arg-list))
(if (re-search-forward ending-re nil t)
(if (>= (point) orig)
(setq html-script-original-mode major-mode)
(narrow-to-region beg (point))
(loop for x in modes when (fboundp x) do (funcall x) and return nil
finally do (error "html-script: no relevant mode found."))
(message "Not in a script region."))
(message "End of script region not found."))