Anonymous avatar Anonymous committed bf69aef

Added xslide.

Comments (0)

Files changed (14)

+xslide Change Log
+=================
+Id: CHANGELOG.TXT,v 1.2 2001/09/05 21:41:40 menteith Exp $
+
+Revision 0.2, 27 August 2001
+============================
+
+xslide.el
+---------
+
+Added customising of `xsl-indent-attributes' and
+`xsl-indent-element-step'.
+
+Changed name completion based on bug fix by KURODA Akira.
+
+xslide-process.el
+-----------------
+
+Finally fixed Saxon process error regexp.
+
+xslide-font.el
+--------------
+
+Changed some font-lock colours.
+
+Finally fixed bug where XSLT attributes were coloured as FO
+attributes.
+
+xslide-data.el
+--------------
+
+Updated FO element and attribute names to match XSL PR.
+
+Makefile
+--------
+
+Changed $(PRELOADS) to emulate version that works well with tdtd.
+
+README.TXT
+----------
+
+Added pronunciation note.
+
+Added note about "Xsl" Customize group.
+
+Added note that xslide should be installed on your Emacs load path.
+
+
+Revision 0.2b3, 7 April 2001
+============================
+
+xslide.el
+---------
+
+Added xsl-element-indent-step variable.
+
+Added `xsl-open-line'.
+
+Revised `xsl-electric-greater-than' to optionally insert a matching
+end-tag.
+
+Added skipping of CDATA sections in `xsl-electic-slash'.
+
+Removed match on "<!" in `xsl-electric-tab'.
+
+Modified completion mechanism in `xsl-complete'.
+
+Added `xsl-insert-template'.
+
+Added "xsl:key" and "xsl:attribute-set" submenus to "Templates" menu.
+
+Added explanations of `xsl-process' and `xsl-grep' to `xsl-mode'
+documentation string.
+
+xslide-abbrev.el
+----------------
+
+Removed abbrevs for "selectors" that haven't even been in XSL since
+the second draft.
+
+xslide-data.el
+--------------
+
+Updated copyright date and author email.
+
+xslide-font.el
+--------------
+
+Added optional whitespace to regexps used when fontifying following
+bug fix by Simon Wright.
+
+Fiddled with face colours while trying to work out why XSLT attributes
+appear with FO colours.
+
+Reordered regexps for text and for "other" tags.
+
+Revised regexp for { and } in attribute values.
+
+Fiddled with attribute regexps.
+
+xslide-process.el
+-----------------
+
+Attempted improvement of Saxon process error regexp.
+
+dot_emacs
+---------
+
+Added .fo files to auto-mode-alist.
+
+
+Revision 0.2b2, September 21, 2000
+==================================
+
+xslide.el
+---------
+
+Changed version number to 0.2b2
+
+xslide-font.el
+--------------
+
+Moved entity references regexp to later in font lock keywords
+
+Corrected error of using a number as argument to `concat'.
+
+
+Revision 0.2b1, September 12, 2000
+==================================
+
+xslide.el
+---------
+
+Added imenu as "Templates" menu
+
+Added "xsl", "xsl-font", and "xsl-process" customize groups
+
+Added initial stylesheet that is inserted in empty buffers
+
+Improvements to insertion of end tags courtesy of Moritz Maass
+
+Revised indentation calculation courtesy of Lassi Tuura
+
+xslide-abbrev.el
+----------------
+
+Merged references to xsl-fo-attribute-symbol-alist-1 and -2
+
+xslide-data.el
+--------------
+
+Updated element and attribute information courtesy of Norman Walsh and
+Lassi Tuura
+
+Merged xsl-fo-attribute-symbol-alist-1 and -2
+
+Renamed xsl-xsl-ns-prefix to xsl-xslt-ns-prefix.
+
+xslide-font.el
+--------------
+
+Replaced use of `make-regexp' with Emacs' built-in `regexp-opt'
+
+Defined light and dark colours that can be customized
+
+xslide-initial.xsl
+------------------
+
+Added as default initial stylesheet inserted into empty buffers
+
+xslide-process.el
+-----------------
+
+Added xsl-process customize group contents
+
+Added input, stylesheet, and output %-sequences to xsl-process-command
+
+Added Saxon command line templates to xsl-process-command
+
+Added regexp for Saxon error messages to xsl-process-regexps
+
+Changed `xsl-process' to populate its command history if history is
+null or if prefix argument is used.
+
+
+Revision 0.1.3, March 1, 2000
+=============================
+
+xslide.el
+---------
+
+Added control over electric tabs
+
+Changes to indentation calculation courtesy of Simon Brooke
+
+xslide-data.el
+--------------
+
+Partial updates to match XSLT Recommendation and current XSL Working
+Draft
+
+xslide-font.el
+--------------
+
+Added definition of font lock colours for light background
+
+Added "append" keyword to some regular expressions
+
+
+Revision 0.1.1, February 17, 1999
+=================================
+
+xslide.el
+---------
+
+Added xsl-electric-quote and xsl-electric-apos.
+
+Added "'" to several regular expressions.
+
+Modified a regular expression in xsl-electric-slash
+
+xslide-font.el
+--------------
+
+Replaced use of `font-lock-make-face' with code that works with Emacs
+20.
+
+Many constants moved to xslide-data.
+
+Moved comment pattern to later in list.
+
+Match on XML Declaration made more rigorous.
+
+More rigorous match on "{" and "}" in attribute values.
+
+xslide-data.el
+--------------
+
+Added "xmlns" and "macro".
+
+xslide-process.el
+-----------------
+
+Moved ":" inside set of parenthesis in error regexp
+
+2002-03-14  Ville Skytt�  <ville.skytta@xemacs.org>
+
+	* New package created.
+

ChangeLog.upstream

+2001-10-20  Tony Graham  <tkg@menteith.com>
+
+	* xslide-process.el: Add ability to view or browse process output
+	and xsl-process-view-output and xsl-process-browse-output
+	customizable variables to control them.  Add error-regexp and
+	process command template for xsltproc.
+
+# Makefile for xslide lisp code
+
+# This file is part of XEmacs.
+
+# XEmacs 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.
+
+# XEmacs 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 XEmacs; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+VERSION = 1.00
+AUTHOR_VERSION = 0.2
+MAINTAINER = Ville Skytt� <ville.skytta@xemacs.org>
+PACKAGE = xslide
+PKG_TYPE = regular
+REQUIRES = ispell mail-lib xemacs-base
+CATEGORY = standard
+
+ELCS = xslide-data.elc xslide-abbrev.elc xslide-process.elc xslide-font.elc  \
+	xslide.elc
+
+EXTRA_SOURCES = CHANGELOG.TXT ChangeLog.upstream dot_emacs Makefile.upstream \
+	README.TXT xslide-initial.xsl
+
+PRELOADS = -l cus-face -l regexp-opt -l font-lock -l sendmail \
+	-l ./xslide-data.el -l ./xslide-abbrev.el -l ./xslide-font.el \
+	-l ./xslide-process.el -l ./xslide.el
+
+include ../../XEmacs.rules
+
+GENERATED += custom-load.elc
+
+all:: $(ELCS) auto-autoloads.elc custom-load.elc
+
+srckit: srckit-std
+
+binkit: binkit-common

Makefile.upstream

+# xslide makefile
+# Id: Makefile,v 1.1.1.1 2001/08/22 21:02:07 menteith Exp $
+# Name:  $
+
+# what emacs is called on your system
+EMACS = emacs
+
+# no csh please
+SHELL = /bin/sh
+
+# have to preload the files that define variables used by other files
+PRELOADS =  -l font-lock -l sendmail \
+	-l xslide-data.el -l xslide-abbrev.el -l xslide-font.el \
+	-l xslide-process.el -l xslide.el
+
+# compile with noninteractive and relatively clean environment
+BATCHFLAGS = -batch -q -no-site-file
+
+FILES = \
+	ChangeLog \
+	CHANGELOG.TXT \
+	dot_emacs \
+	Makefile \
+	README.TXT \
+	xslide-abbrev.el \
+	xslide-data.el \
+	xslide-font.el \
+	xslide-initial.xsl \
+	xslide-process.el \
+	xslide.el \
+
+OBJECTS = \
+	xslide-data.elc xslide-abbrev.elc xslide-process.elc \
+	xslide-font.elc xslide.elc
+
+xslide:	$(OBJECTS)
+
+%.elc:	%.el
+	@echo compiling $<...
+	@$(EMACS) $(BATCHFLAGS) $(PRELOADS) -f batch-byte-compile $<
+
+
+xslide.zip:	$(FILES)
+		@-rm -f $@
+		@zip -q $@ $(FILES)
+This package contains an Emacs major mode for editing XSL stylesheets.
+The current revision is 0.2, dated 27 August, 2001.
+
+The xslide home page is http://www.menteith.com/xslide/
+
+xslide source code is also available at
+http://www.sourceforge.net/projects/xslide/.
+
+* MANIFEST
+
+File                    Contents
+
+README.TXT              The file you are reading
+changelog.txt           Record of changes made to xslide elisp files
+dot_emacs               Some things for your .emacs file
+xslide.el               Base file for the XSL major mode
+xslide-abbrev.el        Abbreviations for XSL mode
+xslide-data.el          Data about XSL elements and formatting objects
+xslide-font.el          Font lock keywords for XSL stylesheets
+xslide-initial.xsl      Default initial stylesheet inserted in empty buffers
+xslide-process.el       Procedures for processing XSL stylesheets
+makefile                Makefile for byte-compiling 
+
+Note that make-regexp.el, which was used by earlier version of xslide,
+is not required by xslide 0.2.
+
+Note that "xslide" is pronounced as one word, similar to "slide".  It
+is not spelled out as "x-s-l-i-d-e".
+
+
+* FEATURES
+
+ - XSL customization group for setting some variables
+
+ - Initial stylesheet inserted into empty XSL buffers;
+
+ - "Template" menu for jumping to template rules, named templates, key
+   declarations, and attribute-set declarations in the buffer;
+
+ - `xsl-process' function that runs an XSL processor and collects the
+   output;
+
+ - Predefined command line templates and error regexps for Java and
+   Windows executable versions of both XT and Saxon;
+
+ - Font lock highlighting so that the important information stands
+   out;
+
+ - `xsl-complete' function for inserting element and attribute names;
+
+ - `xsl-insert-tag' function for inserting matching start- and
+    end-tags;
+
+ - Automatic completion of end-tags;
+
+ - Automatic indenting of elements with user-definable indentation
+   step; and
+
+ - Comprehensive abbreviations table to further ease typing.
+
+xsl-mode was tested using NTEmacs 20.7.1.
+
+
+* BUG REPORTS/ENCHANCEMENTS
+
+I would be glad to accept bug reports and, especially, enhancements.
+Use `xsl-submit-bug-report' for bug reports.
+
+
+* INSTALLATION
+
+1. Unzip the distribution.
+
+   This should extract the files listed in the manifest above.
+
+   The files have DOS-style line breaks.  You may need to use "unzip
+   -a" or "gunzip -a" to convert the line ends in the files to your
+   local convention.
+
+2. Copy the .el files to your emacs site-lisp directory (e.g.,
+   /usr/local/lib/emacs/site-lisp) or some other directory that is on
+   your Emacs load path.
+
+3. Byte compile the .el files using M-x byte-compile-file and
+   supplying the path name of each file.
+
+   The provided makefile also has rules for byte-compiling the files.
+
+   If you byte-compiled a previous version of the files, you must
+   byte-compile the new files (or remove the old .elc files) so that
+   autoload loads the correct versions.
+
+4. Add the elisp code in dot_emacs to your .emacs file.
+
+5. Restart Emacs (or, if it's easier for you, evaluate the code that
+   you just added to your .emacs file).
+
+6. When you visit a file with an extension of .xsl or .fo, xsl-mode
+   will automatically be loaded.
+
+7. To find out more about xsl-mode, type C-h m from within an XSL
+   file.
+
+8. To customize xsl-mode font-lock colours, etc., browse the `Xsl'
+   Customize group after loading xsl-mode.
+
+-----
+Id: README.TXT,v 1.2 2001/09/05 21:41:40 menteith Exp $
+;; Id: dot_emacs,v 1.1.1.1 2001/08/22 21:02:10 menteith Exp $
+
+;; XSL mode
+(autoload 'xsl-mode "xslide" "Major mode for XSL stylesheets." t)
+
+;; Turn on font lock when in XSL mode
+(add-hook 'xsl-mode-hook
+	  'turn-on-font-lock)
+
+(setq auto-mode-alist
+      (append
+       (list
+	'("\\.fo" . xsl-mode)
+	'("\\.xsl" . xsl-mode))
+       auto-mode-alist))
+
+;; Uncomment if using abbreviations
+;; (abbrev-mode t)
+(xslide
+  (standards-version 1.1
+   version VERSION
+   author-version AUTHOR_VERSION
+   date DATE
+   build-date BUILD_DATE
+   maintainer MAINTAINER
+   distribution xemacs
+   priority medium
+   category CATEGORY
+   dump nil
+   description "XSL editing support."
+   filename FILENAME
+   md5sum MD5SUM
+   size SIZE
+   provides (xslide-abbrev xslide-data xslide-font xslide-process xslide)
+   requires (REQUIRES)
+   type regular
+))
+;;;; xslide-abbrev.el --- Abbrev table definitions for xslide
+;; Id: xslide-abbrev.el,v 1.1.1.1 2001/08/22 21:02:10 menteith Exp $
+
+;; Copyright (C) 1998, 1999, 2001 Tony Graham
+
+;; Author: Tony Graham <tkg@menteith.com>
+
+;;; 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:
+
+;; 
+
+;; Send bugs to xslide-bug@menteith.com
+;; Use `xsl-submit-bug-report' to submit a bug report
+
+
+;;;; Variables:
+
+(defvar xsl-mode-abbrev-table nil
+  "Abbrev table used while in XSL mode.")
+
+;;; define xsl-mode-abbrev-table if not already defined
+(if xsl-mode-abbrev-table
+    ()
+  ;; remember current state of abbrevs-changed so it can be restored after
+  ;; defining some abbrevs
+  (let ((ac abbrevs-changed))
+    (define-abbrev-table 'xsl-mode-abbrev-table ())
+
+    ;; Generate abbrevs for XSL and Formatting Object elements from
+    ;; data in xsl-all-elements-alist
+    (mapcar (lambda (x)
+	      (define-abbrev xsl-mode-abbrev-table
+		(nth 3 x) (car x) nil))
+	    xsl-all-elements-alist)
+
+    ;; Generate abbrevs for attributes for XSL and Formatting Object
+    ;; elements
+    (mapcar (lambda (x)
+	      (define-abbrev xsl-mode-abbrev-table
+		(nth 1 x)
+		(concat (car x) "=\"\"")
+		'backward-char))
+	    (append
+	     xsl-attributes-alist
+	     xsl-fo-attribute-symbol-alist))
+
+    ;; restore abbrevs-changed
+    (setq abbrevs-changed ac)))
+
+
+(provide 'xslide-abbrev)
+;;;; xslide-data.el --- XSL IDE element and attribute data
+;; Id: xslide-data.el,v 1.2 2001/09/05 21:40:12 menteith Exp $
+
+;; Copyright (C) 1998, 1999, 2000, 2001 Tony Graham
+
+;; Author: Tony Graham <tkg@menteith.com>
+
+;;; 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:
+
+;; Data about elements and attributes in XSL stylesheets collected
+;; in one place
+
+;; Send bugs to xslide-bug@menteith.com
+;; Use `xsl-submit-bug-report' for bug reports
+
+
+;;;; Variables
+
+(defvar xsl-xslt-ns-prefix "xsl"
+  "*Prefix for the XSL namespace")
+
+(defvar xsl-fo-ns-prefix "fo"
+  "*Prefix for the Formatting Object namespace")
+
+(defvar xsl-element-symbol-alist
+  (list
+   '("apply-imports"
+     "empty"
+     ()
+     "xai")
+   '("apply-templates"
+     "block"
+     ("select" "mode")
+     "xat")
+   '("attribute"
+     "block"
+     ("name" "namespace")
+     "xa")
+   '("attribute-set"
+     "block"
+     ("name" "use-attribute-sets")
+     "xas")
+   '("call-template"
+     "block"
+     ("name")
+     "xct")
+   '("choose"
+     "block"
+     ()
+     "xc")
+   '("comment"
+     "block"
+     ()
+     "xcm")
+   '("copy"
+     "block"
+     ("use-attribute-sets")
+     "xcp")
+   '("copy-of"
+     "block"
+     ("select")
+     "xco")
+   '("decimal-format"
+     "block"
+     ("name" "decimal-separator" "grouping-separator" "infinity"
+      "minus-sign" "NaN" "percent" "per-mille" "zero-digit"
+      "digit" "pattern-separator")
+     "xdf")
+   '("element"
+     "block"
+     ("name" "namespace" "use-attribute-sets")
+     "xe")
+   '("fallback"
+     "block"
+     ()
+     "xfb")
+   '("for-each"
+     "block"
+     ("select")
+     "xfe")
+   '("if"
+     "block"
+     ("test")
+     "xif")
+   '("import"
+     "empty"
+     ("href")
+     "xim")
+   '("include"
+     "empty"
+     ("href")
+     "xinc")
+   '("key"
+     "block"
+     ("name" "match" "use")
+     "xk")
+   '("message"
+     "block"
+     ("terminate")
+     "xme")
+   '("namespace-alias"
+     "block"
+     ("stylesheet-prefix" "result-prefix")
+     "xna")
+   '("number"
+     "empty"
+     ("level" "count" "from" "value" "format" "lang" "letter-value"
+      "grouping-separator" "grouping-size")
+     "xn")
+   '("otherwise"
+     "block"
+     ()
+     "xo")
+   '("output"
+     "empty"
+     ("method" "version" "encoding" "omit-xml-declaration"
+      "standalone" "doctype-public" "doctype-system"
+      "cdata-section-elements" "indent" "media-type")
+     "xout")
+   '("param"
+     "block"
+     ("name" "select")
+     "xpa")
+   '("preserve-space"
+     "empty"
+     ("elements")
+     "xps")
+   '("processing-instruction"
+     "block"
+     ("name")
+     "xpi")
+   '("sort"
+     "empty"
+     ("select" "lang" "data-type" "order" "case-order")
+     "xso")
+   '("strip-space"
+     "empty"
+     ("elements")
+     "xss")
+   (list "stylesheet"
+     "block"
+     (list
+      '("id" nil)
+      '("extension-element-prefixes" nil)
+      '("exclude-result-prefixes" nil)
+      '("version" nil)
+      '("xmlns" nil)
+      '("xmlns:xsl" t)
+      '("xmlns:fo" nil))
+     "xs")
+   '("template"
+     "block"
+     ("match" "mode" "priority" "name")
+     "xt")
+   '("text"
+     "inline"
+     ("disable-output-escaping")
+     "xtxt")
+   (list "transform"
+     "block"
+     (list
+      '("id" nil)
+      '("extension-element-prefixes" nil)
+      '("exclude-result-prefixes" nil)
+      '("version" nil)
+      '("xmlns" nil)
+      '("xmlns:xsl" t)
+      '("xmlns:fo" nil))
+     "xtran")
+   '("value-of"
+     "empty"
+     ("select" "disable-output-escaping")
+     "xvo")
+   '("variable"
+     "block"
+     ("name" "select")
+     "xva")
+   '("when"
+     "block"
+     ("test")
+     "xw")
+   '("with-param"
+     "block"
+     ("name" "select")
+     "xwp")))
+
+(defvar xsl-attributes-alist
+  (list
+   '("NaN" "nan" ())
+   '("cdata-section-elements" "cds" ())
+   '("count" "cnt" ())
+   '("data-type" "dt" ())
+   '("decimal-separator" "ds" ())
+   '("digit" "dig" ())
+   '("disable-output-escaping" "doe" ())
+   '("doctype-public" "dtp" ())
+   '("doctype-system" "dts" ())
+   '("elements" "ele" ())
+   '("encoding" "enc" ())
+   '("exclude-result-prefixes" "erp" ())
+   '("extension-element-prefixes" "eep" ())
+   '("format" "fmt" ())
+   '("from" "fr" ())
+   '("grouping-separator" "gsep" ())
+   '("grouping-size" "gsiz" ())
+   '("href" "href" ())
+   '("id" "id" ())
+   '("indent" "ind" ())
+   '("infinity" "inf" ())
+   '("lang" "l" ())
+   '("letter-value" "lv" ())
+   '("level" "lvl" ())
+   '("match" "m" ())
+   '("media-type" "mt" ())
+   '("method" "meth" ())
+   '("minus-sign" "ms" ())
+   '("mode" "mo" ())
+   '("n-digits-per-group" "ndpg" ())
+   '("name" "n" ())
+   '("namespace" "ns" ())
+   '("omit-xml-declaration" "oxml" ())
+   '("order" "o" ())
+   '("pattern-separator" "ps" ())
+   '("per-mille" "pm" ())
+   '("percent" "perc" ())
+   '("priority" "p" ())
+   '("result-prefix" "rp" ())
+   '("select" "s" ())
+   '("standalone" "stand" ())
+   '("stylesheet-prefix" "spr" ())
+   '("terminate" "ter" ())
+   '("test" "t" ())
+   '("use" "use" ())
+   '("use-attribute-sets" "ua" ())
+   '("value" "v" ())
+   '("version" "ver" ())
+   '("xmlns" "xn" ())
+   '("xmlns:fo" "xnf" ())
+   '("xmlns:xsl" "xnx" ("http://www.w3.org/1999/XSL/Transform"))
+   '("zero-digit" "zd" ())))
+
+(defvar xsl-fo-symbol-alist
+  (list
+   '("basic-link" "inline" () "fbl")
+   '("bidi-override" "inline" () "fbo")
+   '("block" "block" () "fb")
+   '("block-container" "block" () "fbc")
+   '("character" "empty" () "fc")
+   '("color-profile" "empty" () "fcp")
+   '("conditional-page-master-reference" "empty" () "fcpmr")
+   '("declarations" "block" () "fd")
+   '("external-graphic" "empty" () "feg")
+   '("float" "block" () "ff")
+   '("flow" "block" () "ff")
+   '("footnote" "block" () "ff")
+   '("footnote-body" "block" () "ffb")
+   '("initial-property-set" "empty" () "fips")
+   '("inline" "inline" () "fi")
+   '("inline-container" "inline" () "fic")
+   '("instream-foreign-object" "block" () "fifo")
+   '("layout-master-set" "block" () "flms")
+   '("leader" "inline" () "fl")
+   '("list-block" "block" () "flb")
+   '("list-item" "block" () "fli")
+   '("list-item-body" "block" () "flib")
+   '("list-item-label" "block" () "flil")
+   '("marker" "inline" () "fm")
+   '("multi-case" "inline" () "fmc")
+   '("multi-properties" "block" () "fmp")
+   '("multi-property-set" "empty" () "fmps")
+   '("multi-switch" "block" () "fms")
+   '("multi-toggle" "inline" () "fmt")
+   '("page-number" "empty" () "fpn")
+   '("page-number-citation" "empty" () "fpnc")
+   '("page-sequence" "block" () "fps")
+   '("page-sequence-master" "block" () "fpsm")
+   '("region-after" "empty" () "fra")
+   '("region-before" "empty" () "frb")
+   '("region-body" "empty" () "frb")
+   '("region-end" "empty" () "fre")
+   '("region-start" "empty" () "frs")
+   '("repeatable-page-master-alternatives" "block" () "frpma")
+   '("repeatable-page-master-reference" "empty" () "frpmr")
+   '("retrieve-marker" "empty" () "frm")
+   '("root" "block" () "fr")
+   '("simple-page-master" "block" () "fspm")
+   '("single-page-master-reference" "empty" () "fspm")
+   '("static-content" "block" () "fsc")
+   '("table" "block" () "ft")
+   '("table-and-caption" "block" () "ftac")
+   '("table-body" "block" () "ftb")
+   '("table-caption" "block" () "ftc")
+   '("table-cell" "block" () "ftc")
+   '("table-column" "empty" () "ftc")
+   '("table-footer" "block" () "ftf")
+   '("table-header" "block" () "fth")
+   '("table-row" "block" () "ftr")
+   '("title" "inline" () "ft")
+   '("wrapper" "inline" () "fw")))
+
+(defvar xsl-fo-attribute-symbol-alist
+  (list
+   '("absolute-position" "ap")
+   '("active-state" "as")
+   '("alignment-adjust" "aa")
+   '("alignment-baseline" "ab")
+   '("auto-restore" "ar")
+   '("azimuth" "a")
+   '("background" "b")
+   '("background-attachment" "ba")
+   '("background-color" "bc")
+   '("background-image" "bi")
+   '("background-position" "bp")
+   '("background-position-horizontal" "bph")
+   '("background-position-vertical" "bpv")
+   '("background-repeat" "br")
+   '("baseline-shift" "bs")
+   '("blank-or-not-blank" "bon")
+   '("block-progression-dimension" "bpd")
+   '("block-progression-dimension.maximum" "bpdmax")
+   '("block-progression-dimension.minimum" "bpdmin")
+   '("block-progression-dimension.optimum" "bpdopt")
+   '("border" "b")
+   '("border-after-color" "bac")
+   '("border-after-precedence" "bap")
+   '("border-after-style" "bas")
+   '("border-after-width" "baw")
+   '("border-after-width.conditionality" "bawc")
+   '("border-after-width.length" "bawl")
+   '("border-before-color" "bbc")
+   '("border-before-precedence" "bbp")
+   '("border-before-style" "bbs")
+   '("border-before-width" "bbw")
+   '("border-before-width.conditionality" "bbwc")
+   '("border-before-width.length" "bbwc")
+   '("border-bottom" "bb")
+   '("border-bottom-color" "bbc")
+   '("border-bottom-style" "bbs")
+   '("border-bottom-width" "bbw")
+   '("border-bottom-width.conditionality" "bbwc")
+   '("border-bottom-width.length" "bbwl")
+   '("border-collapse" "bc")
+   '("border-color" "bc")
+   '("border-end-color" "bec")
+   '("border-end-precedence" "bep")
+   '("border-end-style" "bes")
+   '("border-end-width" "bew")
+   '("border-end-width.conditionality" "bewc")
+   '("border-end-width.length" "bewl")
+   '("border-left" "bl")
+   '("border-left-color" "blc")
+   '("border-left-style" "bls")
+   '("border-left-width" "blw")
+   '("border-left-width.conditionality" "blwc")
+   '("border-left-width.length" "blwl")
+   '("border-right" "br")
+   '("border-right-color" "brc")
+   '("border-right-style" "brs")
+   '("border-right-width" "brw")
+   '("border-right-width.conditionality" "brwc")
+   '("border-right-width.length" "brwl")
+   '("border-separation.block-progression-direction" "bsbpd")
+   '("border-separation.inline-progression-direction" "bsipd")
+   '("border-spacing" "bs")
+   '("border-start-color" "bsc")
+   '("border-start-precedence" "bsp")
+   '("border-start-style" "bss")
+   '("border-start-width" "bsw")
+   '("border-start-width.conditionality" "bswc")
+   '("border-start-width.length" "bswl")
+   '("border-style" "bs")
+   '("border-top" "bt")
+   '("border-top-color" "btc")
+   '("border-top-style" "bts")
+   '("border-top-width" "btw")
+   '("border-top-width.conditionality" "btwc")
+   '("border-top-width.length" "btwl")
+   '("border-width" "bw")
+   '("bottom" "b")
+   '("break-after" "ba")
+   '("break-before" "bb")
+   '("caption-side" "cs")
+   '("case-name" "cn")
+   '("case-title" "ct")
+   '("character" "ch")
+   '("clear" "cl")
+   '("clip" "cli")
+   '("color" "c")
+   '("color-profile-name" "cpn")
+   '("column-count" "cc")
+   '("column-gap" "cg")
+   '("column-number" "cn")
+   '("column-width" "cw")
+   '("content-height" "ch")
+   '("content-type" "ct")
+   '("content-width" "cw")
+   '("country" "c")
+   '("cue" "c")
+   '("cue-after" "ca")
+   '("cue-before" "cb")
+   '("destination-placement-offset" "dpo")
+   '("direction" "d")
+   '("display-align" "da")
+   '("dominant-baseline" "db")
+   '("elevation" "e")
+   '("empty-cells" "ec")
+   '("end-indent" "ei")
+   '("ends-row" "er")
+   '("extent" "e")
+   '("external-destination" "ed")
+   '("float" "f")
+   '("flow-name" "fn")
+   '("font" "f")
+   '("font-family" "ff")
+   '("font-selection-strategy" "fss")
+   '("font-size" "fs")
+   '("font-size-adjust" "fsa")
+   '("font-stretch" "fs")
+   '("font-style" "fs")
+   '("font-variant" "fv")
+   '("font-weight" "fw")
+   '("force-page-count" "fpc")
+   '("format" "f")
+   '("glyph-orientation-horizontal" "goh")
+   '("glyph-orientation-vertical" "gov")
+   '("grouping-separator" "gs")
+   '("grouping-size" "gs")
+   '("height" "h")
+   '("hyphenate" "hy")
+   '("hyphenation-character" "hc")
+   '("hyphenation-keep" "hk")
+   '("hyphenation-ladder-count" "hlc")
+   '("hyphenation-push-character-count" "hpc")
+   '("hyphenation-remain-character-count" "hrcc")
+   '("id" "i")
+   '("indicate-destination" "id")
+   '("initial-page-number" "ipn")
+   '("inline-progression-dimension" "ipd")
+   '("inline-progression-dimension.maximum" "ipdmax")
+   '("inline-progression-dimension.minimum" "ipdmin")
+   '("inline-progression-dimension.optimum" "ipdopt")
+   '("internal-destination" "id")
+   '("intrusion-displace" "id")
+   '("keep-together.within-column" "ktc")
+   '("keep-together.within-line" "ktl")
+   '("keep-together.within-page" "ktp")
+   '("keep-with-next.within-column" "kwnc")
+   '("keep-with-next.within-line" "kwnl")
+   '("keep-with-next.within-page" "kwnp")
+   '("keep-with-previous.within-column" "kwpc")
+   '("keep-with-previous.within-line" "kwpl")
+   '("keep-with-previous.within-page" "kwpp")
+   '("language" "la")
+   '("last-line-end-indent" "lle")
+   '("leader-alignment" "la")
+   '("leader-length" "ll")
+   '("leader-length.maximum" "llmax")
+   '("leader-length.minimum" "llmin")
+   '("leader-length.optimum" "llopt")
+   '("leader-pattern" "lp")
+   '("leader-pattern-width" "lpw")
+   '("left" "le")
+   '("letter-spacing" "ls")
+   '("letter-value" "lv")
+   '("line-height" "lh")
+   '("line-height-shift-adjustment" "lhs")
+   '("line-stacking-strategy" "lss")
+   '("linefeed-treatment" "lt")
+   '("margin" "m")
+   '("margin-bottom" "mb")
+   '("margin-left" "ml")
+   '("margin-right" "mr")
+   '("margin-top" "mt")
+   '("marker-class-name" "mcn")
+   '("master-name" "mn")
+   '("master-reference" "mr")
+   '("max-height" "mh")
+   '("max-width" "mw")
+   '("maximum-repeats" "mr")
+   '("media-usage" "mu")
+   '("min-height" "mh")
+   '("min-width" "mw")
+   '("number-columns-repeated" "ncr")
+   '("number-columns-spanned" "ncs")
+   '("number-rows-spanned" "nrs")
+   '("odd-or-even" "ooe")
+   '("orphans" "or")
+   '("overflow" "ov")
+   '("padding" "pd")
+   '("padding-after" "pa")
+   '("padding-before" "pb")
+   '("padding-bottom" "pb")
+   '("padding-end" "pe")
+   '("padding-left" "pl")
+   '("padding-right" "pr")
+   '("padding-start" "ps")
+   '("padding-top" "pt")
+   '("page-break-after" "pba")
+   '("page-break-before" "pbb")
+   '("page-break-inside" "pbi")
+   '("page-height" "ph")
+   '("page-position" "pp")
+   '("page-width" "pw")
+   '("pause" "p")
+   '("pause-after" "pa")
+   '("pause-before" "pb")
+   '("pitch" "p")
+   '("pitch-range" "pr")
+   '("play-during" "pd")
+   '("position" "p")
+   '("precedence" "p")
+   '("provisional-distance-between-starts" "pdbs")
+   '("provisional-label-separation" "pls")
+   '("ref-id" "rid")
+   '("reference-orientation" "ro")
+   '("region-name" "rn")
+   '("relative-align" "ra")
+   '("relative-position" "rp")
+   '("rendering-intent" "ri")
+   '("retrieve-boundary" "rb")
+   '("retrieve-class-name" "rcn")
+   '("retrieve-position" "rp")
+   '("richness" "rich")
+   '("right" "rig")
+   '("role" "ro")
+   '("rule-style" "rs")
+   '("rule-thickness" "rt")
+   '("scaling" "sc")
+   '("scaling-method" "sm")
+   '("score-spaces" "ss")
+   '("script" "scr")
+   '("show-destination" "sde")
+   '("size" "si")
+   '("source-document" "sdo")
+   '("space-after" "sa")
+   '("space-before" "sb")
+   '("space-end" "se")
+   '("space-start" "ss")
+   '("span" "spn")
+   '("speak" "spe")
+   '("speak-header" "sh")
+   '("speak-numeral" "sn")
+   '("speak-punctuation" "sp")
+   '("speech-rate" "sr")
+   '("src" "src")
+   '("start-indent" "si")
+   '("starting-state" "ss")
+   '("starts-row" "sr")
+   '("stress" "str")
+   '("suppress-at-line-break" "salb")
+   '("switch-to" "st")
+   '("table-layout" "tl")
+   '("table-omit-footer-at-break" "tofb")
+   '("table-omit-header-at-break" "tohb")
+   '("target-presentation-context" "tpc")
+   '("target-processing-context" "tpc")
+   '("target-stylesheet" "ts")
+   '("text-align" "ta")
+   '("text-align-last" "tal")
+   '("text-altitude" "ta")
+   '("text-decoration" "td")
+   '("text-depth" "td")
+   '("text-indent" "ti")
+   '("text-shadow" "ts")
+   '("text-transform" "tt")
+   '("top" "top")
+   '("treat-as-word-space" "taw")
+   '("unicode-bidi" "ub")
+   '("vertical-align" "va")
+   '("visibility" "vi")
+   '("voice-family" "vf")
+   '("volume" "vo")
+   '("white-space" "ws")
+   '("white-space-collapse" "wsc")
+   '("white-space-treatment" "wst")
+   '("widows" "wdw")
+   '("width" "w")
+   '("word-spacing" "ws")
+   '("wrap-option" "wo")
+   '("writing-mode" "wm")
+   '("xml:lang" "xl")
+   '("z-index" "zi")))
+
+(setq xsl-all-attribute-alist
+      (sort
+       (append
+	xsl-attributes-alist
+	xsl-fo-attribute-symbol-alist)
+       (lambda (a b) (string< (car a) (car b)))))
+
+(setq xsl-all-elements-alist
+      (sort
+       (append
+	(mapcar (lambda (x)
+		  (cons (if xsl-xslt-ns-prefix
+			    (concat xsl-xslt-ns-prefix ":" (car x))
+			  (car x))
+			(cdr x)))
+		xsl-element-symbol-alist)
+	(mapcar (lambda (x)
+		  (if xsl-fo-ns-prefix
+		      (cons
+		       (concat xsl-fo-ns-prefix ":" (car x))
+		       (cdr x))
+		    x))
+		xsl-fo-symbol-alist))
+       (lambda (a b) (string< (car a) (car b)))))
+
+(provide 'xslide-data)
+
+;; end of xslide-data.el
+;;;; xslide-font.el --- Tony's XSL font lock keywords
+;; Id: xslide-font.el,v 1.2 2001/11/16 22:02:48 menteith Exp $
+
+;; Copyright (C) 1998, 1999, 2000, 2001 Tony Graham
+
+;; Author: Tony Graham <tkg@menteith.com>
+
+;;; 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 "<?xml"
+     ;;
+     '("\\(<\\?\\)\\([^ \t?>]+\\)[ \t]*\\([^?>]\\|\\?[^>]\\|>[^\n\r]\\)*\\(\\?>\\)"
+       (1 font-lock-keyword-face)
+       (2 font-lock-variable-name-face)
+       (4 font-lock-keyword-face))
+     ;;
+     ;; Marked section start
+     ;;
+     '("\\(<!\\[\\)[^[]*\\(\\[\\)"
+       (1 font-lock-keyword-face)
+       (2 font-lock-keyword-face))
+     ;;
+     ;; XSL formatting objects
+     ;;
+     (list
+      (concat "\\(</?\\)\\(" xsl-fo-ns-prefix ":\\)\\("
+	      (regexp-opt
+	       (mapcar 'car xsl-fo-symbol-alist))
+	      "\\)\\(\\s-+\\([^/>]\\|/[^>]\\)+\\)*\\(/?>\\|$\\)")
+      '(1 xsl-fo-main-face)
+      '(2 xsl-fo-alternate-face)
+      '(3 xsl-fo-main-face))
+     (list
+      (concat "</?" xsl-fo-ns-prefix ":\\([^/>]\\|/[^>]\\)*\\(/?>\\)")
+      '(2 xsl-fo-main-face))
+     ;;
+     ;; XSL elements
+     ;;
+     (list
+      (concat "\\(</?\\)\\(" xsl-xslt-ns-prefix ":\\)\\("
+	      (regexp-opt
+	       (mapcar 'car xsl-element-symbol-alist))
+	      "\\)\\(\\s-+[^= 	]+[ 	]*=[ 	]*\\('[^']*'\\|\"[^\"]*\"\\)\\)*\\s-*\\(/?>\\)")
+      '(1 xsl-xslt-main-face)
+      '(2 xsl-xslt-alternate-face)
+      '(3 xsl-xslt-main-face))
+     (list
+      (concat "</?" xsl-xslt-ns-prefix ":\\S-+\\(\\s-+[^=> 	]+[ 	]*=[ 	]*\\('[^']*'\\|\"[^\"]*\"\\)\\)*\\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
+	      (regexp-opt
+	       (mapcar 'car xsl-attributes-alist)
+	       t))))
+       (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
+	      (regexp-opt
+	       (mapcar 'car xsl-attributes-alist)
+	       t))))
+       (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
+	      (regexp-opt
+	       (mapcar 'car xsl-fo-attribute-symbol-alist)
+	       t))))
+       (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
+	      (regexp-opt
+	       (mapcar 'car xsl-fo-attribute-symbol-alist)
+	       t))))
+       (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 <xsl:text>
+     (list
+      (concat "<" xsl-xslt-ns-prefix ":text>"
+	      "\\([^<]*\\)"
+	      "</" xsl-xslt-ns-prefix ":text>")
+      '(1 font-lock-string-face append))
+     ;;
+     ;; "Other" tags
+     ;;
+     (list
+      (concat "\\(</?\\([^xf/\?!]\\|x[^s]\\|xs[^l]\\|xsl[^:]\\|f[^o]\\|fo[^:]\\)\\([^</>]\\|/[^>]\\)*/?>\\)")
+      '(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 "<" (point-max) 'limit 5)
+    (set-mark (point))
+    (goto-char current-point)
+    (re-search-backward "<" (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 "<" (point-min) 'limit 5)
+    (point)))
+
+(defun xsl-font-lock-region-point-max ()
+  "Return the start point of the region to fontify"
+  (save-excursion
+    (re-search-forward "<" (point-max) 'limit 5)
+    (point)))
+
+(provide 'xslide-font)
+
+;; end of xslide-font.el

xslide-initial.xsl

+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="1.0">
+
+  <xsl:output method="html"/>
+
+  <xsl:template match="/">
+    <html>
+      <body bgcolor="#FFFFFF">
+        <xsl:apply-templates/>
+      </body>
+    </html>
+  </xsl:template>
+
+</xsl:stylesheet>

xslide-process.el

+;;;; xslide-process.el --- Process an XSL stylesheet
+;; Id: xslide-process.el,v 1.2 2001/10/20 19:48:40 menteith Exp $
+
+;; Copyright (C) 1998, 1999, 2000, 2001 Tony Graham
+
+;; Author: Tony Graham <tkg@menteith.com>
+
+;;; 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:
+
+;; Originally copied almost wholesale from psgml.el by Lennart Staflin
+
+;; Send bugs to xslide-bug@menteith.com
+;; Use `xsl-submit-bug-report' for bug reports
+
+
+;;;; Variables:
+
+
+
+(defcustom xsl-offer-save t
+  "*If non-nil, ask about saving modified buffers before \\[xsl-process] is run."
+  :type '(choice (const :tag "Yes" t) (const :tag "No" nil))
+  :group 'xsl-process)
+
+(defcustom xsl-process-browse-output nil
+  "*If non-nil, open output in browser after \\[xsl-process] is run."
+  :type '(choice (const :tag "Yes" t) (const :tag "No" nil))
+  :group 'xsl-process)
+
+(defcustom xsl-process-find-output nil
+  "*If non-nil, find output file after \\[xsl-process] is run."
+  :type '(choice (const :tag "Yes" t) (const :tag "No" nil))
+  :group 'xsl-process)
+
+(defcustom xsl-process-command
+  (list
+   ;; XT Windows executable
+   "xt %i %s %o"
+   ;; XT Java
+   "java com.jclark.xsl.Driver %i %s %o"
+   ;; Xalan-Java 2
+   "java org.apache.xalan.xslt.Process -IN %i -XSL %s -OUT %o"
+   ;; Instant Saxon
+   "saxon -o %o %i %s"
+   ;; Instant Saxon using xml-stylesheet PI
+   "saxon -o %o %i"
+   ;; Saxon
+   "java com.icl.saxon.StyleSheet -o %o %i %s"
+   ;; Saxon using xml-stylesheet PI
+   "java com.icl.saxon.StyleSheet -o %o %i"
+   ;; xsltproc
+   "xsltproc -o %o %s %i"
+   ;; jd.xslt
+   "java jd.xml.xslt.Stylesheet -out %o %i %s"
+   ;; Oracle XDK for Java
+   "java oracle.xml.parser.v2.oraxsl %i %s %o"
+   )
+  "*The shell command to process an XSL document.
+
+This is a `format' control string that by default should contain three
+`%s' conversion specifications: the first will be replaced by the
+value of `xsl-process-input-file' \(or the empty string, if nil\); the
+second will be replaced by `xsl-process-stylesheet-file' \(or the empty
+string, if nil\); the third will be replaced by
+`xsl-process-output-file' \(or the empty string, if nil\).
+
+If `xsl-process-files' is non-nil, the format string should contain
+one `%s' conversion specification for each element of its result.
+
+If `xsl-process-command' is a list, then every element should be a
+string.  The strings will be tried in order and %-sequences in the
+string will be replaced according to the list below, if the string contains
+%-sequences with no replacement value the next string will be tried.
+
+%b means the visited file of the current buffer
+%i means the value of `xsl-process-input-file'
+%s means the value of `xsl-process-stylesheet-file'
+%o means the value of `xsl-process-output-file'
+"
+  :type '(repeat :tag "Commands" string)
+  :group 'xsl-process)
+
+(defvar xsl-process-files nil
+  "If non-nil, a function of no arguments that returns a list of file names.
+These file names will serve as the arguments to the `xsl-process-command'
+format control string instead of the defaults.")
+
+(defcustom xsl-process-error-regexps
+  '(
+    ;; Xalan-Java 2
+    ;;   file:///path/to/foo.xsl; Line 9; Column 12; ...
+    ("^file:\\([^;]+\\)\\; Line \\([0-9]+\\)\\;\\( Column \\([0-9]+\\)\\;\\)?"
+     1 2 4)
+
+    ;; Saxon
+    ;;   Error at xsl:output on line 9 of file:/path/to/foo.xsl:
+    ;;   Error on line 9 column 5 of file:/path/to/foo.xsl:
+    ("^Error\\( at [^ ]+\\)? on line \\([0-9]+\\)\\( column \\([0-9]+\\)\\)? of file:\\(\\(/[A-Za-z]:\\)?[^:]+\\):$"
+     5 2 4)
+
+    ;; Oracle
+    ;;   file:/path/to/foo.xsl<Line 9, Column 17>: ...
+    ("^file:\\([^<]+\\)<Line \\([0-9]+\\)\\(, Column \\([0-9]+\\)\\)?>:"
+     1 2 4)
+
+    ;; jd.xslt
+    ;;   - uri       = file:/path/to/foo.xsl
+    ;;   - line      = 9
+    ;;   - column    = -1
+    ;; ...or...
+    ;;   - uri       = file:/path/to/foo.xsl
+    ;;   - element   = xsl:output (line 9)
+    ("^- uri[ \t]+= file:\\(.+\\)\\([\r\n+]- \\(\\([^(]*?(\\)?line[ \t]+\\(= \\)?\\([0-9]+\\)\\)?\\)?\\([\r\n]+- column[ \t]+= \\([0-9]+\\)\\)?" 1 6 8)
+
+    ;; Generic
+    (".*\\<file:\\(\\(/[A-Za-z]:\\)?[^:]+\\):[ \t]*\\(\\([0-9]+\\):[ \t]*\\(\\([0-9]+\\):\\)?\\)?"
+     1 4 6)
+    (".*\\([^ ]+\\.x[ms]l\\):[ \t]*\\([0-9]+\\):[ \t]*\\(\\([0-9]+\\):\\)?"
+     1 2 4)
+    ("^\\([^:]+\\): \\([0-9]+\\): error:"
+     1 2)
+    )
+  "*Alist of regexps to recognize error messages from `xsl-process'.
+See `compilation-error-regexp-alist'."
+  :type '(repeat :tag "Regexps"
+		 (list (regexp :tag "Regexp")
+		       (integer :tag "File index")
+		       (integer :tag "Line index")
+		       (choice :tag "Column index"
+			       (integer)
+			       (const :tag "None" nil))))
+  :group 'xsl-process)
+
+(defvar xsl-xml-source nil
+  "*If non-nil, this is the name of the XML source file.")
+(put 'xsl-xml-source 'xsl-type 'string)
+
+(defvar xsl-xsl-result nil
+  "*If non-nil, this is the name of the XSL result file.")
+(put 'xsl-xsl-result 'xsl-type 'string)
+
+(defvar xsl-process-command-history nil
+  "The minibuffer history list for `xsl-process''s COMMAND argument.")
+;;(make-variable-buffer-local 'xsl-process-command-history)
+
+(eval-and-compile
+  (autoload 'compile-internal "compile" ""))
+
+(defun xsl-subst-expand-char (c parts)
+  (cdr-safe (assq (downcase c) parts)))
+
+(defun xsl-subst-expand (s parts)
+  (loop for i from 0 to (1- (length s))
+	as c = (aref s i)
+	concat (if (eq c ?%)
+		   (or (xsl-subst-expand-char (aref s (incf i)) parts)
+		       (return nil)) 
+		 (char-to-string (aref s i)))))
+
+(defun xsl-populate-process-command-history ()
+  (cond
+   ((consp xsl-process-command)
+    (let ((process-subst
+	   (list
+	    (cons ?b (and (buffer-file-name)
+			  (file-name-nondirectory (buffer-file-name))))
+	    (cons ?i xsl-process-input-file)
+	    (cons ?s xsl-process-stylesheet-file)
+	    (cons ?o xsl-process-output-file))))
+      (setq xsl-process-command-history
+	    (append
+	     (mapcar (lambda (x)
+		       (xsl-subst-expand x process-subst))
+		     xsl-process-command)
+	     xsl-process-command-history))))
+;;      (loop for template in xsl-process-command
+;;	    append
+;;	    (xsl-subst-expand template process-subst)
+;;	    into
+;;	    xsl-process-command-history)))
+   (t
+    (apply 'format xsl-process-command
+	   (if xsl-process-files
+	       (funcall xsl-process-files)
+	     (list (or xsl-xml-source "")
+		   (let ((name (buffer-file-name)))
+		     (if name
+			 (file-name-nondirectory name)
+		       ""))
+		   (or xsl-xsl-result "")))))))
+
+(defvar xsl-process-input-file nil
+  "Filename of input file for `xsl-process' command")
+
+(defvar xsl-process-input-history nil
+  "The minibuffer history list for `xsl-get-process-parameters''s INPUT argument.")
+
+(defvar xsl-process-stylesheet-file nil
+  "Filename of stylesheet file for `xsl-process' command")
+
+(defvar xsl-process-stylesheet-history nil
+  "The minibuffer history list for `xsl-get-process-parameters''s STYLESHEET argument.")
+
+(defvar xsl-process-output-file nil
+  "Filename of output file for `xsl-process' command")
+
+(defvar xsl-process-output-history nil
+  "The minibuffer history list for `xsl-get-process-parameters''s OUTPUT argument.")
+
+(defun xsl-get-process-parameters ()
+  "Get and set the parameters for the `xsl-process' command"
+  (interactive)
+  (setq xsl-process-input-file
+	(xsl-read-from-minibuffer "Input file: "
+			      (concat (file-name-sans-extension
+				       (file-name-nondirectory
+					(buffer-file-name)))
+				      ".xml")
+			      'xsl-process-input-history))
+  (setq xsl-process-stylesheet-file
+	(xsl-read-from-minibuffer "Stylesheet file: "
+			      (file-name-nondirectory
+			       (buffer-file-name))
+			      'xsl-process-stylesheet-history))
+  (setq xsl-process-output-file
+	(xsl-read-from-minibuffer "Output file: "
+			      (concat (file-name-sans-extension
+				       (file-name-nondirectory
+					xsl-process-input-file))
+				      ".html")
+			      'xsl-process-output-history)))
+
+(defun xsl-process (command)
+  "Process an XSL stylesheet.
+
+Runs COMMAND, a shell command, in a separate process asynchronously
+with output going to the buffer *XSL process*.  You can then use the
+command \\[next-error] to find the next error message and move to the
+line in the XSL document that caused it.
+
+The first time that the program is run and whenever you provide a
+prefix argument, e.g. \\[universal-argument] \\[xsl-process], prompts
+for input filename, stylesheet file, and output filename.  Those
+values are used with the templates in `xsl-process-command' to
+populate this command's command history with the command lines to run
+several XSLT processors using those values.  Use M-p and M-n to step
+through the predefined commands, edit a command if necessary, or enter
+a new command line.  The next time that this command is run, the
+previously executed command is used as the default.
+
+If `xsl-process-browse-output' is non-nil, the filename entered in
+response to the \"Output file:\" prompt is opened in a browser using
+`browse-url'.
+
+If `xsl-process-view-output' is non-nil, the filename entered in
+response to the \"Output file:\" prompt is opened in a buffer."
+  (interactive
+   (list (progn
+	   (if (or
+		current-prefix-arg
+		(null xsl-process-command-history))
+	       (progn
+		 (xsl-get-process-parameters)
+		 (xsl-populate-process-command-history)))
+	   (read-from-minibuffer "Process command: "
+				     (car xsl-process-command-history)
+				     nil nil
+				     'xsl-process-command-history))))
+  (if xsl-offer-save
+      (save-some-buffers nil nil))
+  (compile-internal command "No more errors" "XSL process"
+		    nil
+		    xsl-process-error-regexps)
+  (if xsl-process-browse-output
+      (browse-url xsl-process-output-file))
+  (if xsl-process-find-output
+      (switch-to-buffer
+       (find-file-noselect (expand-file-name xsl-process-output-file)))))
+
+
+(provide 'xslide-process)
+;;;; xslide.el --- XSL Integrated Development Environment
+;; Id: xslide.el,v 1.5 2001/11/16 22:00:22 menteith Exp $
+
+;; Copyright (C) 1998, 1999, 2000, 2001 Tony Graham
+
+;; Author: Tony Graham <tkg@menteith.com>
+;; Contributors: Simon Brooke, Girard Milmeister, Norman Walsh,
+;;               Moritz Maass, Lassi Tuura, Simon Wright, KURODA Akira
+;; Created: 21 August 1998
+;; Version: Revision: 1.5 $
+;; Keywords: languages, xsl, xml
+
+;;; 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:
+
+;; Functions for editing XSL stylesheets
+
+;; Requires xslide-font.el, xslide-data.el, xslide-abbrev.el, xslide-process.el
+;; Requires 'etags for `find-tag-default'
+;; Requires 'reporter for `xsl-submit-bug-report'
+;; Requires 'imenu for "Goto" menu
+;;
+;; Send bugs to xslide-bug@menteith.com
+;; Use `xsl-submit-bug-report' for bug reports
+
+;;;; Code:
+(provide 'xslide)
+
+(require 'cl)
+(require 'compile)
+(require 'font-lock)
+;; XEmacs users don't always have imenu.el installed, so use
+;; condition-case to cope if xslide causes an error by requiring imenu.
+(eval-and-compile
+  (condition-case nil
+	(require 'imenu)
+    (error nil)))
+;; Need etags for `find-tag-default'
+(require 'etags)
+
+(require 'xslide-data "xslide-data")
+(require 'xslide-abbrev "xslide-abbrev")
+(require 'xslide-font "xslide-font")
+(require 'xslide-process "xslide-process")
+
+
+;; Define core `xsl' group.
+(defgroup xsl nil
+  "Major mode for editing XSL."
+  :prefix "xsl-"
+  :group 'languages)
+
+(defgroup xsl-faces nil
+  "Font faces used in XSL mode."
+  :group 'xsl
+  :group 'faces)
+
+(defgroup xsl-process nil
+  "Running XSL processors from XSL mode."
+  :group 'xsl)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Version information
+
+(defconst xslide-version "0.2"
+  "Version number of xslide XSL mode.")
+
+(defun xslide-version ()
+  "Returns the value of the variable xslide-version."
+  xslide-version)
+
+(defconst xslide-maintainer-address "xslide-bug@menteith.com")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Variables
+
+(defvar xsl-indent-tabs-mode nil
+  "*Initial value of indent-tabs-mode on entering xsl-mode")
+
+(defvar xsl-default-filespec "*.xsl"
+  "*Inital prompt value for `xsl-etags''s FILESPEC argument.")
+
+(defvar xsl-filespec-history (list xsl-default-filespec)
+  "Minibuffer history list for `xsl-etags' and `xsl-grep''s FILESPEC argument.")
+
+(defvar xsl-grep-pattern-history nil
+  "Minibuffer history list for `xsl-grep''s PATTERN argument.")
+
+(defvar xsl-grep-case-sensitive-flag nil
+  "*Non-nil disables case insensitive searches by `xsl-grep'.")
+
+(defvar xsl-comment-start "<!--"
+  "*Comment start character sequence")
+
+(defvar xsl-comment-end "-->"
+  "*Comment end character sequence")
+
+(defvar xsl-comment-max-column 70
+  "*Maximum column number for text in a comment")
+
+(defcustom xsl-initial-stylesheet-file (locate-library "xslide-initial.xsl" t)
+  "*File containing initial stylesheet inserted into empty XSL buffers"
+  :type '(choice (file :must-match t) (const :tag "No initial stylesheet" nil))
+  :group 'xsl)
+
+(defcustom xsl-initial-stylesheet-initial-point 0
+  "*Initial position of point in initial stylesheet"
+  :type '(integer)
+  :group 'xsl)
+
+(defcustom xsl-indent-attributes nil
+  "*Whether to indent attributes on lines following an open tag.
+If non-nil, attributes will be aligned with the space after the
+element name, otherwise by two spaces."
+  :type '(choice (const :tag "Yes" t) (const :tag "No" nil))
+  :group 'xsl)
+
+(defcustom xsl-element-indent-step 2
+  "*Amount by which to indent success levels of nested elements."
+  :type '(integer)
+  :group 'xsl)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; functions
+
+(defun xsl-read-from-minibuffer (prompt default history)
+  "Read from minibuffer with default and command history."
+(let ((value nil))
+  (if (string-equal
+       ""
+       (setq value
+	     (read-from-minibuffer (if default
+				       (format
+					"%s(default `%s') "
+					prompt default)
+				     (format "%s" prompt))
+				   nil nil nil
+				   history)))
+	     default
+	     value)))
+
+;; XSLIDE house style puts all comments starting on a favourite column
+(defun xsl-comment (comment)
+  "Insert COMMENT starting at the usual column.
+
+With a prefix argument, e.g. \\[universal-argument] \\[xsl-comment], insert separator comment
+lines above and below COMMENT in the manner of `xsl-big-comment'."
+  (interactive "sComment: ")
+  (insert "\n")
+  (backward-char)
+  (xsl-electric-tab)
+  (let ((fill-column (1- xsl-comment-max-column))
+	(fill-prefix (make-string (1+ (length xsl-comment-start)) ?\ ))
+;;	(comment-start xsl-init-comment-fill-prefix)
+	(saved-auto-fill-function auto-fill-function))
+    (auto-fill-mode 1)
+    (insert xsl-comment-start)
+    (insert " ")
+    (indent-to (length fill-prefix))
+    (fill-region (point) (save-excursion
+			   (insert comment)
+			   (point))
+		 nil
+		 1
+		 1)
+    ;; The fill does the right thing, but it always ends with
+    ;; an extra newline, so delete the newline.
+    (delete-backward-char 1)
+    (if (not saved-auto-fill-function)
+	(auto-fill-mode 0))
+    (insert " ")
+    (insert xsl-comment-end)
+    (insert "\n")
+    (if font-lock-mode
+	(save-excursion
+	  (font-lock-fontify-keywords-region
+	   (xsl-font-lock-region-point-min)
+	   (xsl-font-lock-region-point-max))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Mode map stuff
+
+(defvar xsl-mode-map nil
+  "Keymap for XSL mode.")
+
+(if xsl-mode-map
+    ()
+  (setq xsl-mode-map (make-sparse-keymap))
+  (define-key xsl-mode-map [tab]	  'xsl-electric-tab)
+;;  (define-key xsl-mode-map "\M-\t"	  'xsl-complete)
+  (define-key xsl-mode-map [(meta tab)]	  'xsl-complete)
+;;  (define-key xsl-mode-map "\""   	  'xsl-electric-quote)
+;;  (define-key xsl-mode-map "'"   	  'xsl-electric-apos)
+  (define-key xsl-mode-map "/"   	  'xsl-electric-slash)
+  (define-key xsl-mode-map "<"   	  'xsl-electric-less-than)
+  (define-key xsl-mode-map ">"            'xsl-electric-greater-than)
+;;  (define-key xsl-mode-map "["   	  'xsl-electric-lsqb)
+;;  (define-key xsl-mode-map "("   	  'xsl-electric-lpar)
+;;  (define-key xsl-mode-map "{"   	  'xsl-electric-lcub)
+  (define-key xsl-mode-map [(control c) (control c)]
+				   	  'xsl-comment)
+  (define-key xsl-mode-map [(control c) (control p)]
+				   	  'xsl-process)
+  (define-key xsl-mode-map [(control o)]
+				   	  'xsl-open-line)
+  (define-key xsl-mode-map "\C-c<"  	  'xsl-insert-tag)
+;;  (define-key xsl-mode-map [(control m)]	  'xsl-electric-return)
+;;  (define-key xsl-mode-map \10	  'xsl-electric-return)
+  (define-key xsl-mode-map "\177"	  'backward-delete-char-untabify)
+;;  (define-key xsl-mode-map "\M-\C-e" 'xsl-next-rule)
+;;  (define-key xsl-mode-map "\M-\C-a" 'xsl-previous-rule)
+;;  (define-key xsl-mode-map "\M-\C-h" 'mark-xsl-rule)
+)
+
+(defun xsl-electric-greater-than (arg)
+  "Insert a \">\" and, optionally, insert a matching end-tag.
+
+If the \">\" closes a start-tag and the start-tag is the last thing on
+the line, `xsl-electric-greater-than' inserts the matching end-tag.
+Providing a prefix argument, e.g., \\[universal-argument] \\[xsl-electric-greater-than], stops the inserting of the
+matching end-tag.
+
+If the element being terminated is listed as a block element in
+`xsl-all-elements-alist', then point is left on the next line at the
+correct indent and the end-tag is inserted on the following line at
+the correct indent.
+
+`xsl-electric-greater-than' also fontifies the region around the
+current line."
+  (interactive "P")
+  (insert ">")
+  (if (and
+       (not arg)
+       (looking-at "$")
+       (save-excursion
+	 (let ((limit (point)))
+	   (backward-char)
+	   (search-backward "<")
+;;	   (message "%s:%s" (point) limit)
+	   (and
+	    (looking-at "<\\(\\(\\sw\\|\\s_\\)+\\)\\(\\s-+\\(\\sw\\|\\s_\\)+[ 	]*=[ 	]*\\('[^']*'\\|\"[^\"]*\"\\)\\)*\\s-*\\(/?\\)>")
+;;	    (message "%s:%s" limit (match-end 0))
+	    (= (match-end 0) limit)
+;;	    (message ":%s:" (match-string 6))
+	    (not (string-equal (match-string 6) "/"))
+	    (not (save-match-data
+		   (string-match "^/" (match-string 1))))))))
+      (if (string-equal (nth 1 (assoc (match-string 1) xsl-all-elements-alist)) "block")
+	  (progn
+	    (xsl-electric-return)
+	    (save-excursion
+	      (insert "\n<")
+	      (xsl-electric-slash)))
+	(save-excursion
+	  (insert (format "</%s>" (match-string 1))))))
+  (if font-lock-mode
+      (save-excursion
+	(font-lock-fontify-region
+	 (xsl-font-lock-region-point-min)
+	 (xsl-font-lock-region-point-max)))))
+
+(defun xsl-electric-apos ()
+  "Function called when \"'\" is pressed in XSL mode"
+  (interactive)
+  (insert "'")
+  (if (looking-at "\\([\"/})]\\|$\\)")
+      (save-excursion
+	(insert "'"))))
+
+(defun xsl-electric-quote ()
+  "Function called when '\"' is pressed in XSL mode"
+  (interactive)
+  (insert "\"")
+  (if (looking-at "\\(['/})]\\|$\\)")
+      (save-excursion
+	(insert "\""))))
+
+(defun xsl-electric-lsqb ()
+  "Function called when \"[\" is pressed in XSL mode"
+  (interactive)
+  (insert "[")
+  (if (looking-at "\\([\"'/})]\\|$\\)")
+      (save-excursion
+	(insert "]"))))
+
+(defun xsl-electric-lpar ()
+  "Function called when \"(\" is pressed in XSL mode"
+  (interactive)
+  (insert "(")
+  (if (looking-at "\\([\]\"'/}]\\|$\\)")
+      (save-excursion
+	(insert ")"))))
+
+(defun xsl-electric-lcub ()
+  "Function called when \"{\" is pressed in XSL mode"
+  (interactive)
+  (insert "{")
+  (if (looking-at "\\([\])\"'/}]\\|$\\)")
+      (save-excursion
+	(insert "}"))))
+
+(defun xsl-electric-less-than ()
+  "Function called when \"<\" is pressed in XSL mode"
+  (interactive)
+  (insert "<")
+  (xsl-electric-tab))
+
+(defun xsl-match-opening-tag (a)
+  "Function called to match the next opening tag to a closing tag"
+  (if (looking-at "</")
+      (catch 'start-tag
+        (while (re-search-backward
+                (concat "\\(<\\|</\\)" a "[ \t\n\r>]") nil t)
+          (cond
+           ((looking-at (concat "</" a))
+            (xsl-match-opening-tag a))
+           ((looking-at (concat "<" a))
+            (throw 'start-tag a))
+           )))
+    nil)
+)
+(defun xsl-electric-slash ()
+  "Function called when \"/\" is pressed in XSL mode"
+  (interactive)
+  (insert "/")
+  (xsl-electric-tab)
+  (if (looking-at "$")
+      (let ((element-name
+	     (save-excursion
+	       (backward-char 2)
+	       (if (looking-at "</")
+		   (catch 'start-tag
+		     (while (re-search-backward "<" nil t)
+		       (cond
+			((looking-at "</\\([^/> \t]+\\)>")
+;;			 (message "End tag: %s" (match-string 1))
+; find matching tag:
+                         (xsl-match-opening-tag (match-string 1)))
+;;original
+;;                       (re-search-backward
+;;                        (concat "<" (match-string 1) "[ \t\n\r>]") nil t))
+			((looking-at "<\\(\\([^/>]\\|/[^>]\\)+\\)/>"))
+;;			 (message "Empty tag: %s" (match-string 1)))
+			((looking-at "<!--[^-]*\\(-[^-]+\\)*-->"))
+			;; skip CDATA sections
+			((looking-at "<!\\[CDATA\\["))
+			((looking-at "<\\([^/> \n\t]+\\)")
+;;			 (message "Start tag: %s" (match-string 1))
+			 (throw 'start-tag (match-string 1)))
+			((bobp)
+			 (throw 'start-tag nil)))))
+		 nil))))
+	(if element-name
+	    (progn
+	      (insert element-name)
+	      (insert ">")
+	      (if font-lock-mode
+		  (save-excursion
+		    (font-lock-fontify-region
+		     (xsl-font-lock-region-point-min)
+		     (xsl-font-lock-region-point-max)))))))))
+
+(defun xsl-electric-return ()
+  (interactive)
+  (insert "\n")
+  (xsl-electric-tab))
+
+(defun xsl-open-line (arg)
+  (interactive "p")
+  (if (not arg)
+      (setq arg 1))
+  (save-excursion
+    (while (> arg 0)
+      (setq arg (1- arg))
+      (insert "\n"))
+    (if (looking-at "<")
+	(xsl-electric-tab))))
+
+(defun xsl-electric-tab ()
+  "Function called when TAB is pressed in XSL mode."
+  (interactive)
+  (save-excursion
+    (beginning-of-line)
+    (delete-horizontal-space)
+    (if (looking-at "</")
+	(indent-to (max 0 (- (xsl-calculate-indent) xsl-element-indent-step)))
+      (indent-to (xsl-calculate-indent))))
+  (if (and
+       (bolp)
+       (looking-at "[ \t]+"))
+      (goto-char (match-end 0)))
+  (if font-lock-mode
+      (save-excursion
+	(font-lock-fontify-keywords-region
+	 (xsl-font-lock-region-point-min)
+	 (xsl-font-lock-region-point-max)))))
+
+
+(defun xsl-close-open-tab-p nil
+  "Return 'T' if the current line contains more right than left angle-brackets"
+  (save-excursion
+    (beginning-of-line)
+    (let ((open 0))
+      (while (not (eolp))
+	(let ((here (char-after (point))))
+	  (cond
+	   ((eq here '?\>) (setq open (1- open)))
+	   ((eq here '?\<) (setq open (1+ open)))
+	   )
+	  )
+	(forward-char)
+	)
+      (< open 0)			; true if we've counted more
+					; closes than opens
+      )
+    )
+  )
+
+(defun xsl-calculate-indent ()
+  "Calculate what the indent should be for the current line"
+  (let* ((limit   (point))
+ 	 (name    "[^<>=\"' \t\n]+")
+ 	 (string  "\\(\"[^<>\"]*\"\\|'[^<>']*'\\)")
+ 	 (ostring "\\(\"[^<>\"]*\\|'[^<>']*\\)")
+ 	 (attval  (concat name "=" string))
+ 	 (oattval (concat name "=" ostring))
+ 	 (element (concat "<\\(" name "\\)"
+ 			  "\\([ \t\n]+" attval "\\)*[ \t\n]*"))
+ 	 (meta    (concat "<!\\(DOCTYPE\\|ENTITY\\)"
+ 			  "\\([ \t\n]+\\(" name "\\|" string "\\)\\)*")))
+    (save-excursion
+      (if (re-search-backward "^\\([ \t]*\\)<" nil t)
+	  (goto-char (match-end 1))
+	(beginning-of-line))
+      (cond
+       ;; closed comment => stay put
+       ((save-excursion
+ 	  (re-search-forward "<!--[^-]*\\(-[^-]+\\)*-->" limit t))
+ 	(current-column))
+       ;; open comment => indent by five
+       ((looking-at "<!--")
+ 	(+ (current-column) 5))
+       ;; end tag, closed empty tag, open tag immediately followed by
+       ;; other tags/char data or a complete meta tag => stay put
+       ((save-excursion
+ 	  (or (looking-at (concat "</" name ">"))
+ 	      (re-search-forward (concat element "[ \t\n]*/>") limit t)
+ 	      (re-search-forward (concat element ">[ \t]*[^\n]") limit t)
+ 	      (re-search-forward (concat meta ">[ \t]*\n") limit t)))
+ 	(current-column))
+       ;; closed open tag followed by new line, or an opening meta tag
+       ;; => indent by xsl-element-indent-step
+       ((save-excursion
+ 	  (or (re-search-forward (concat element ">[ \t]*\n") limit t)
+ 	      (re-search-forward (concat meta "\\[[ \t]*\n") limit t)))
+ 	(+ (current-column) xsl-element-indent-step))
+       ;; incomplete open tag or open meta => indent after tag name
+       ((save-excursion
+ 	  (and (or (re-search-forward (concat element "[ \t\n]*") limit t)
+ 		   (re-search-forward (concat meta "[ \t\n]*") limit t))
+ 	       (= (point) limit)))
+ 	(if xsl-indent-attributes
+ 	    (progn (goto-char (match-end 1))
+ 		   (+ (current-column) 1))
+ 	  (+ (current-column) xsl-element-indent-step)))
+       ;; incomplete attribute value => indent to string start
+       ((save-excursion
+ 	  (and (or (re-search-forward (concat element "[ \t\n]+" oattval)
+ 				      limit t))
+ 	       (= (point) limit)))
+ 	(goto-char (match-beginning 4))
+ 	(+ (current-column) 1))
+       ;; beginning of buffer => stay put (beginning of line)
+       ((bobp)
+ 	(current-column))
+       ;; otherwise => indent by xsl-element-indent-step