--- a/trunk/php-mode-src/php-mode.el
+++ b/trunk/php-mode-src/php-mode.el
@@ -5,10 +5,10 @@
 ;; Maintainer: Turadg Aleahmad <turadg at users.sourceforge.net>
 ;; Keywords: php languages oop
 ;; Created: 1999-05-17
-;; Modified: 2005-07-27
+;; Modified: 2007-04-21
 ;; X-URL:   http://php-mode.sourceforge.net/
 
-(defconst php-version "1.2.0"
+(defconst php-version "1.3.0"
   "PHP Mode version number.")
 
 ;;; License
@@ -29,16 +29,13 @@
 
 ;;; Usage
 
-;; Rename this file to php-mode.el if it isn't already then place it in
-;; your Emacs lisp path (eg. site-lisp) and add to your .emacs file:
+;; Put this file in your Emacs lisp path (eg. site-lisp) and add to
+;; your .emacs file:
+;;
 ;;   (require 'php-mode)
 
-;; If you want colorization, turn on global-font-lock or
-;; add this to your .emacs:
-;;   (add-hook 'php-mode-user-hook 'turn-on-font-lock)
-
 ;; To use abbrev-mode, add lines like this:
-;;   (add-hook 'php-mode-user-hook
+;;   (add-hook 'php-mode-hook
 ;;     '(lambda () (define-abbrev php-mode-abbrev-table "ex" "extends")))
 
 ;; To make php-mode compatible with html-mode, see http://php-mode.sf.net
@@ -66,10 +63,16 @@
 ;; Rosenfeld, Fred Yankowski, Craig Andrews, John Keller, Ryan
 ;; Sammartino, ppercot, Valentin Funk, Stig Bakken, Gregory Stark,
 ;; Chris Morris, Nils Rennebarth, Gerrit Riessen, Eric Mc Sween,
-;; Ville Skytta, Giacomo Tesio
+;; Ville Skytta, Giacomo Tesio, Lennart Borgman, Stefan Monnier
 
 ;;; Changelog:
 
+;; 1.3
+;;   Changed the definition of # using a tip from Stefan
+;;   Monnier. This corrected highlighting and indentation. (Lennart
+;;   Borgman)
+;;   Changed the highlighting of the HTML part. (Lennart Borgman)
+;;
 ;; 1.2
 ;;   Implemented php-show-arglist, C-. (Engelke Eschner)
 ;;   Implemented php-complete-function, M-tab (Engelke Eschner)
@@ -105,46 +108,67 @@
   :prefix "php-"
   :group 'languages)
 
+(defcustom php-default-face 'default
+  "Default face in php-mode buffers."
+  :type 'face
+  :group 'php)
+
 (defcustom php-speedbar-config t
-  "*When set to true automatically configures Speedbar to observe PHP files.\
+  "When set to true automatically configures Speedbar to observe PHP files.\
 Ignores php-file patterns option; fixed to expression \"\\.\\(inc\\|php[s34]?\\)\""
   :type 'boolean
+  :set (lambda (sym val)
+         (set-default sym val)
+         (if (and val (boundp 'speedbar))
+             (speedbar-add-supported-extension
+	      "\\.\\(inc\\|php[s34]?\\|phtml\\)")))
   :group 'php)
 
 (defcustom php-mode-speedbar-open nil
   "Normally php-mode starts with the speedbar closed.\
 Turning this on will open it whenever php-mode is loaded."
   :type 'boolean
+  :set (lambda (sym val)
+         (set-default sym val)
+         (when val
+             (speedbar 1)))
   :group 'php)
 
 (defcustom php-manual-url "http://www.php.net/manual/en/"
-  "*URL at which to find PHP manual.\
+  "URL at which to find PHP manual.\
 You can replace \"en\" with your ISO language code."
   :type 'string
   :group 'php)
 
 (defcustom php-search-url "http://www.php.net/"
-  "*URL at which to search for documentation on a word"
+  "URL at which to search for documentation on a word"
   :type 'string
   :group 'php)
 
 (defcustom php-completion-file ""
-  "*Path to the file which contains the function names known to PHP"
+  "Path to the file which contains the function names known to PHP"
   :type 'string
   :group 'php)
 
 (defcustom php-manual-path ""
-  "*Path to the directory which contains the PHP manual"
+  "Path to the directory which contains the PHP manual"
   :type 'string
   :group 'php)
 
 ;;;###autoload
 (defcustom php-file-patterns (list "\\.php[s34]?\\'" "\\.phtml\\'" "\\.inc\\'")
-  "*List of file patterns for which to automatically invoke php-mode."
+  "List of file patterns for which to automatically invoke php-mode."
   :type '(repeat (regexp :tag "Pattern"))
+  :set (lambda (sym val)
+         (set-default sym val)
+         (let ((php-file-patterns-temp val))
+           (while php-file-patterns-temp
+             (add-to-list 'auto-mode-alist
+                          (cons (car php-file-patterns-temp) 'php-mode))
+             (setq php-file-patterns-temp (cdr php-file-patterns-temp)))))
   :group 'php)
 
-(defcustom php-mode-user-hook nil
+(defcustom php-mode-hook nil
   "List of functions to be executed on entry to php-mode"
   :type 'hook
   :group 'php)
@@ -158,17 +182,39 @@
 (defvar php-completion-table nil
   "Obarray of tag names defined in current tags table and functions know to PHP.")
 
-;; Note whether we're in XEmacs
-(defconst xemacsp (string-match "Lucid\\|XEmacs" emacs-version)
-  "Non nil if using XEmacs.")
+(defvar php-warned-bad-indent nil)
+(make-variable-buffer-local 'php-warned-bad-indent)
+
+;; Do it but tell it is not good if html tags in buffer.
+(defun php-check-html-for-indentation ()
+  (let ((html-tag-re "</?\\sw+.*?>")
+        (here (point)))
+    (if (not (or (re-search-forward html-tag-re (line-end-position) t)
+                 (re-search-backward html-tag-re (line-beginning-position) t)))
+        t
+      (goto-char here)
+      (setq php-warned-bad-indent t)
+      (lwarn 'php-indent :warning
+	     "\n\t%s\n\t%s\n\t%s\n"
+	     "Indentation fails badly with mixed HTML and PHP."
+	     "Look for an Emacs Lisp library that supports \"multiple"
+	     "major modes\" like mumamo, mmm-mode or multi-mode.")
+      nil)))
+
+(defun php-cautious-indent-region (start end &optional quiet)
+  (if (or php-warned-bad-indent
+          (php-check-html-for-indentation))
+      (funcall 'c-indent-region start end quiet)))
+
+(defun php-cautious-indent-line ()
+  (if (or php-warned-bad-indent
+          (php-check-html-for-indentation))
+      (funcall 'c-indent-line)))
 
 ;;;###autoload
 (define-derived-mode php-mode c-mode "PHP"
   "Major mode for editing PHP code.\n\n\\{php-mode-map}"
 
-  (setq comment-start "// "
-	comment-end   ""
-	comment-start-skip "// *")
 
   (setq c-class-key php-class-key)
   (setq c-conditional-key php-conditional-key)
@@ -184,7 +230,7 @@
   ;; The above causes XEmacs to handle shell-style comments correctly,
   ;; but fails to work in GNU Emacs which fails to interpret \n as the
   ;; end of the comment.
-  (if xemacsp (progn
+  (if (featurep 'xemacs) (progn
                 (modify-syntax-entry ?# "< b" php-mode-syntax-table)
                 (modify-syntax-entry ?\n "> b" php-mode-syntax-table)))
 
@@ -199,7 +245,15 @@
           T                                 ; CASE-FOLD
           nil                               ; SYNTAX-ALIST
           nil                               ; SYNTAX-BEGIN
-          (font-lock-syntactic-keywords . php-font-lock-syntactic-keywords)))
+          ;;(font-lock-syntactic-keywords . php-font-lock-syntactic-keywords)
+          ))
+  (modify-syntax-entry ?# "< b" php-mode-syntax-table)
+
+  ;; Electric behaviour must be turned off, they do not work since
+  ;; they can not find the correct syntax in embedded PHP.
+  ;;
+  ;; Seems to work with narrowing so let it be on if the user prefers it.
+  ;;(setq c-electric-flag nil)
 
   (setq font-lock-maximum-decoration t
         case-fold-search t              ; PHP vars are case-sensitive
@@ -232,22 +286,12 @@
                              (buffer-file-name))
                (string-match "\\.php$" (buffer-file-name))))
       (run-hooks 'php-mode-pear-hook))
-  
-  (run-hooks 'php-mode-user-hook))
-
-;; Make php-mode the default mode for PHP source code buffers.
-;;;###autoload
-(let ((php-file-patterns-temp php-file-patterns))
-  (while php-file-patterns-temp
-    (add-to-list 'auto-mode-alist
-		  (cons (car php-file-patterns-temp) 'php-mode))
-    (setq php-file-patterns-temp (cdr php-file-patterns-temp))))
-
-;; Handle Speedbar
-(if php-mode-speedbar-open
-    (speedbar 1))
-(if (and php-speedbar-config (symbolp 'speedbar))
-    (speedbar-add-supported-extension "\\.\\(inc\\|php[s34]?\\)"))
+
+  (setq indent-line-function 'php-cautious-indent-line)
+  (setq indent-region-function 'php-cautious-indent-region)
+  (setq c-special-indent-hook nil)
+
+  (run-hooks 'php-mode-hook))
 
 ;; Make a menu keymap (with a prompt string)
 ;; and make it the menu bar item's definition.
@@ -832,7 +876,7 @@
 	  (1 font-lock-constant-face)))
 
    ;; treat 'print' as keyword only when not used like a function name
-   '("\\<print\\s-*(" . default)
+   '("\\<print\\s-*(" . php-default-face)
    '("\\<print\\>" . font-lock-keyword-face)
 
    ;; Fontify PHP tag
@@ -889,10 +933,19 @@
    (list
 
     ;; <word> or </word> for HTML
-    '("</?\\sw+[^>]*>" . font-lock-constant-face)
+    ;;'("</?\\sw+[^> ]*>" . font-lock-constant-face)
+    ;;'("</?\\sw+[^>]*" . font-lock-constant-face)
+    ;;'("<!DOCTYPE" . font-lock-constant-face)
+    '("</?[a-z!:]+" . font-lock-constant-face)
+
+    ;; HTML >
+    '("<[^>]*\\(>\\)" (1 font-lock-constant-face))
+
+    ;; HTML tags
+    '("\\(<[a-z]+\\)[[:space:]]+\\([a-z:]+=\\)[^>]*?" (1 font-lock-constant-face) (2 font-lock-constant-face) )
+    '("\"[[:space:]]+\\([a-z:]+=\\)" (1 font-lock-constant-face))
 
     ;; HTML entities
-    '("&\\w+;" . font-lock-variable-name-face)
 
     ;; warn about '$' immediately after ->
     '("\\$\\(?:\\sw\\|\\s_\\)+->\\s-*\\(\\$\\)\\(\\(?:\\sw\\|\\s_\\)+\\)"
@@ -922,32 +975,14 @@
     '("->\\(\\(?:\\sw\\|\\s_\\)+\\)" (1 font-lock-variable-name-face t t)) ; ->variable
     '("->\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*(" . (1 default t t)) ; ->function_call
     '("\\(?:\\sw\\|\\s_\\)+::\\(?:\\sw\\|\\s_\\)+\\s-*(" . default) ; class::method call
-    '("\\<\\(?:\\sw\\|\\s_\\)+\\s-*[[(]" . default)	; word( or word[
-    '("\\<[0-9]+" . default)		; number (also matches word)
+    ;;'("\\<\\(?:\\sw\\|\\s_\\)+\\s-*[[(]" . default)	; word( or word[
+    `("\\<[0-9]+" . php-default-face)		; number (also matches word)
 
     ;; Warn on any words not already fontified
     '("\\<\\(?:\\sw\\|\\s_\\)+\\>" . font-lock-warning-face)
     ))
   "Gauchy level highlighting for PHP mode.")
 
-(defconst php-font-lock-syntactic-keywords
-  (if xemacsp nil
-    ;; Mark shell-style comments.  font-lock handles this in a
-    ;; separate pass from normal syntactic scanning (somehow), so we
-    ;; get a chance to mark these in addition to C and C++ style
-    ;; comments.  This only works in GNU Emacs, not XEmacs 21 which
-    ;; seems to ignore this same code if we try to use it.
-    (list
-     ;; Mark _all_ # chars as being comment-start.  That will be
-     ;; ignored when inside a quoted string.
-     '("\\(\#\\)"
-       (1 (11 . nil)))
-     ;; Mark all newlines ending a line with # as being comment-end.
-     ;; This causes a problem, premature end-of-comment, when '#'
-     ;; appears inside a multiline C-style comment.  Oh well.
-     '("#.*\\([\n]\\)"
-       (1 (12 . nil)))
-     )))
 
 ;; Define the imenu-generic-expression for PHP mode.
 ;; To use, execute M-x imenu, then click on Functions or Classes,
@@ -982,14 +1017,13 @@
 
 ;; Create "default" symbol for GNU Emacs so that both XEmacs and GNU
 ;; emacs can refer to the default face by a variable named "default".
-(unless (boundp 'default)
-  (defvar default 'default))
 
 ;; Create faces for XEmacs
-(unless (boundp 'font-lock-keyword-face)
-  (copy-face 'bold 'font-lock-keyword-face))
-(unless (boundp 'font-lock-constant-face)
-  (copy-face 'font-lock-keyword-face 'font-lock-constant-face))
+(when (featurep 'xemacs)
+  (unless (boundp 'font-lock-keyword-face)
+    (copy-face 'bold 'font-lock-keyword-face))
+  (unless (boundp 'font-lock-constant-face)
+    (copy-face 'font-lock-keyword-face 'font-lock-constant-face)))
 
 (provide 'php-mode)