summaryrefslogtreecommitdiffstats
path: root/emacs.d/lisp/multi-mode/html-php.el
diff options
context:
space:
mode:
Diffstat (limited to 'emacs.d/lisp/multi-mode/html-php.el')
-rw-r--r--emacs.d/lisp/multi-mode/html-php.el91
1 files changed, 91 insertions, 0 deletions
diff --git a/emacs.d/lisp/multi-mode/html-php.el b/emacs.d/lisp/multi-mode/html-php.el
new file mode 100644
index 0000000..22cc210
--- /dev/null
+++ b/emacs.d/lisp/multi-mode/html-php.el
@@ -0,0 +1,91 @@
+;;; html-php.el --- multi-mode PHP embedded in HTML
+
+;; Copyright (C) 2008 Dave Love
+
+;; Author: Dave Love <fx@gnu.org>
+;; Keywords: languages
+;; $Revision: 2$
+;; URL: http://www.loveshack.ukfsn.org/emacs
+
+;; 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
+;; 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, 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-php-mode ()
+ "Mode for editing PHP embedded in HTML, using multi-mode."
+ (interactive)
+ (set (make-local-variable 'multi-alist)
+ '((html-mode)
+ (php-mode . html-php-chunk-region)))
+ (multi-mode-install-modes))
+
+(defun html-php-chunk-region (pos)
+ "Mode-selecting function for PHP embedded in HTML.
+See `multi-alist'."
+ (let ((case-fold-search t)
+ pi-start pi-end next-pi)
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char pos)
+ (save-excursion
+ (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 "<?php" (- (point) 9) t)))
+ (match-end (if p1 (match-end 0)))
+ ;; Otherwise search backwards simply.
+ (p2 (unless p1 (search-backward "<?php" 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 'php-mode pi-start pi-end)
+ ;; Otherwise, look forward for a PI to delimit the HTML
+ ;; region.
+ (setq next-pi (if (search-forward "<?php" nil t)
+ (match-beginning 0)
+ (point-max)))
+ (if pi-start
+ (list 'html-mode (or pi-end (point-min)) next-pi)
+ (list 'html-mode (point-min) next-pi))))))))
+
+(provide 'html-php)
+;;; html-php.el ends here