;;;; xslide-font.el --- Tony's XSL font lock keywords ;; $Id: xslide-font.el,v 1.4 2003/07/02 19:28:06 tonygraham Exp $ ;; Copyright (C) 1998, 1999, 2000, 2001 Tony Graham ;; Author: Tony Graham ;;; This file is not part of GNU Emacs. ;; 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 ;; of the License, 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 this program; if not, write to the Free Software ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ;;;; Commentary: ;; Font lock mode keywords for use when editing XSL stylesheets ;; Send bugs to xslide-bug@menteith.com ;;;; Variables ;; Define mode-specific faces (defface xsl-xslt-main-face '((((background light)) (:foreground "SlateBlue4")) (((background dark)) (:foreground "Wheat"))) "Used for local name portion of XSLT elements and attributes" :group 'xsl-faces) (defvar xsl-xslt-main-face 'xsl-xslt-main-face "Used for local name portion of XSLT elements and attributes") (defface xsl-xslt-alternate-face '((((background light)) (:foreground "SlateBlue2")) (((background dark)) (:foreground "LightGray"))) "Used for prefix and colon portion of XSLT elements and attributes" :group 'xsl-faces) (defvar xsl-xslt-alternate-face 'xsl-xslt-alternate-face "Used for prefix and colon portion of XSLT elements and attributes") (defface xsl-fo-main-face '((((background light)) (:foreground "darkorchid4")) (((background dark)) (:foreground "PaleGreen"))) "Used for local name portion of formatting object elements and attributes" :group 'xsl-faces) (defvar xsl-fo-main-face 'xsl-fo-main-face "Used for local name portion of formatting object elements and attributes") (defface xsl-fo-alternate-face '((((background light)) (:foreground "darkorchid3")) (((background dark)) (:foreground "Yellow"))) "Used for prefix and colon portion of formatting object elements and attributes" :group 'xsl-faces) (defvar xsl-fo-alternate-face 'xsl-fo-alternate-face "Used for prefix and colon portion of formatting object elements and attributes") (defface xsl-other-element-face '((((background light)) (:foreground "Blue")) (((background dark)) (:foreground "Coral"))) "Used for literal result element tags" :group 'xsl-faces) (defvar xsl-other-element-face 'xsl-other-element-face "Used for literal result element tags") ;;;; Constants (eval-and-compile (defvar xsl-font-lock-keywords (list ;; ;; Reserved XML Processing instruction lookalikes ;; '( "\\(<\\?\\)\\(xml\\)\\(\\s-+version\\s-*=\\s-*\\('[^']+'\\|\"[^\"]+\"\\)\\)?\\(\\s-+encoding\\s-*=\\s-*\\('[^']+'\\|\"[^\"]+\"\\)\\)?\\(\\s-+standalone\\s-*=\\s-*\\('\\(yes\\|no\\)'\\|\"\\(yes\\|no\\)\"\\)\\)?\\s-*\\(\\?>\\)" (1 font-lock-keyword-face) (2 font-lock-type-face nil) (3 font-lock-type-face nil t) (5 font-lock-type-face nil t) (7 font-lock-type-face nil t) (11 font-lock-keyword-face)) ;; ;; Non-reserved XML Processing instruction ;; Any XML PI that doesn't start with "]+\\)[ \t]*\\([^?>]\\|\\?[^>]\\|>[^\n\r]\\)*\\(\\?>\\)" (1 font-lock-keyword-face) (2 font-lock-variable-name-face) (4 font-lock-keyword-face)) ;; ;; Marked section start ;; '("\\(]\\|/[^>]\\)+\\)*\\(/?>\\|$\\)") '(1 xsl-fo-main-face) '(2 xsl-fo-alternate-face) '(3 xsl-fo-main-face)) (list (concat "]\\|/[^>]\\)*\\(/?>\\)") '(2 xsl-fo-main-face)) ;; ;; XSL elements ;; (list (concat "\\(\\)") '(1 xsl-xslt-main-face) '(2 xsl-xslt-alternate-face) '(3 xsl-xslt-main-face)) (list (concat " ]+[ ]*=[ ]*\\('[^']*'\\|\"[^\"]*\"\\)\\)*\\s-*\\(/?>\\)") '(3 xsl-xslt-main-face)) ;; ;; XSL attributes ;; (let* ((xsl-attributes-alist-regexp (regexp-opt (mapcar 'car xsl-attributes-alist) t)) (xsl-attributes-alist-regexp-depth (regexp-opt-depth xsl-attributes-alist-regexp))) (list (concat "\\b\\(" xsl-attributes-alist-regexp "[ \t]*=[ \t]*\"\\)" "\\([^\"<]*\\)" "\\(\"\\)") (list 1 xsl-xslt-alternate-face) (list (+ 2 xsl-attributes-alist-regexp-depth) font-lock-variable-name-face) (list (+ 3 xsl-attributes-alist-regexp-depth) xsl-xslt-alternate-face))) ;; do again with single-quote delimiters (let* ((xsl-attributes-alist-regexp (regexp-opt (mapcar 'car xsl-attributes-alist) t)) (xsl-attributes-alist-regexp-depth (regexp-opt-depth xsl-attributes-alist-regexp))) (list (concat "\\b\\(" xsl-attributes-alist-regexp "[ \t]*=[ \t]*'\\)" "\\([^'<]*\\)" "\\('\\)") (list 1 xsl-xslt-alternate-face) (list (+ 2 xsl-attributes-alist-regexp-depth) font-lock-variable-name-face) (list (+ 3 xsl-attributes-alist-regexp-depth) xsl-xslt-alternate-face))) ;; ;; XSL formatting object properties ;; (let* ((xsl-fo-attribute-symbol-alist-regexp (regexp-opt (mapcar 'car xsl-fo-attribute-symbol-alist) t)) (xsl-fo-attribute-symbol-alist-regexp-depth (regexp-opt-depth xsl-fo-attribute-symbol-alist-regexp))) (list (concat "\\b\\(" xsl-fo-attribute-symbol-alist-regexp "[ \t]*=[ \t]*\"\\)" "\\([^\"<]*\\)" "\\(\"\\)") (list 1 xsl-fo-alternate-face 'append) (list (+ 2 xsl-fo-attribute-symbol-alist-regexp-depth) font-lock-variable-name-face) (list (+ 3 xsl-fo-attribute-symbol-alist-regexp-depth) xsl-fo-alternate-face))) ;; do again with single-quote delimiters (let* ((xsl-fo-attribute-symbol-alist-regexp (regexp-opt (mapcar 'car xsl-fo-attribute-symbol-alist) t)) (xsl-fo-attribute-symbol-alist-regexp-depth (regexp-opt-depth xsl-fo-attribute-symbol-alist-regexp))) (list (concat "\\b\\(" xsl-fo-attribute-symbol-alist-regexp "[ \t]*=[ \t]*'\\)" "\\([^'<]*\\)" "\\('\\)") (list 1 xsl-fo-alternate-face 'append) (list (+ 2 xsl-fo-attribute-symbol-alist-regexp-depth) font-lock-variable-name-face) (list (+ 3 xsl-fo-attribute-symbol-alist-regexp-depth) xsl-fo-alternate-face))) ;; ;; Mark the start and end of literals, but don't do anything to their ;; contents ;; '("\\('\\)[^']*\\('\\)" (1 font-lock-string-face) (2 font-lock-string-face)) '("\\(\"\\)[^\"]*\\(\"\\)" (1 font-lock-string-face) (2 font-lock-string-face)) ;; ;; { } in attribute values ;; ;; '("\\('\\|\"\\)\\([^{\\1]\\|{{\\)*\\({[^\\1}]*}\\)\\([^{\\1]\\|{{\\)*\\(\\1\\)" '("'\\([^{'<]\\|{{\\)*\\({[^'}<]*}\\)\\([^{'<]\\|{{\\)*'" (2 font-lock-variable-name-face t)) '("\"\\([^{\"<]\\|{{\\)*\\({[^\"}<]*}\\)\\([^{\"<]\\|{{\\)*\"" (2 font-lock-variable-name-face t)) ;; ;; Text inside (list (concat "<" xsl-xslt-ns-prefix ":text>" "\\([^<]*\\)" "") '(1 font-lock-string-face append)) ;; ;; "Other" tags ;; (list (concat "\\(]\\|/[^>]\\)*/?>\\)") '(1 xsl-other-element-face t)) ;; ;; Content of tags ;; (list (concat ">\\([^<]+\\)<") '(1 font-lock-string-face keep)) ;; ;; Entity references ;; '("\\([%&][^; \t]+;\\)" (1 font-lock-reference-face t)) ;; ;; Put comment patterns last so they mask anything ;; that might be inside the comment ;; '("\\(\\)" (1 font-lock-comment-face t)) ) "Additional expressions to highlight in XSL mode.")) ;;;; Code: (defun xsl-font-lock-mark-block-function () "Function to mark the area of text to fontify. Used with font-lock-fontify-block. Set font-lock-mark-block-function to this function for this function to take effect. This function marks the area beginning five \"<\" before point and five \">\" at ends of lines after point. The default without a function like this is to fontify 16 lines before and after point, but then the region often starts or ends partway through a comment or declaration, turning that half white because the keywords didn't match, and it just looks so ugly." (let ((current-point (point))) (re-search-forward ">[ \t]*$" (point-max) 'limit 5) (set-mark (point)) (goto-char current-point) (re-search-backward "^[ \t]*<" (point-min) 'limit 5))) (defun xsl-font-lock-region-point-min () "Return the start point of the region to fontify." (save-excursion (re-search-backward "^[ \t]*<" (point-min) 'limit 5) (point))) (defun xsl-font-lock-region-point-max () "Return the end point of the region to fontify." (save-excursion (re-search-forward ">[ \t]*$" (point-max) 'limit 5) (point))) (provide 'xslide-font) ;; end of xslide-font.el