summaryrefslogtreecommitdiff
path: root/lisp/nxml/nxml-ns.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/nxml/nxml-ns.el')
-rw-r--r--lisp/nxml/nxml-ns.el151
1 files changed, 151 insertions, 0 deletions
diff --git a/lisp/nxml/nxml-ns.el b/lisp/nxml/nxml-ns.el
new file mode 100644
index 00000000000..0d1b1543b45
--- /dev/null
+++ b/lisp/nxml/nxml-ns.el
@@ -0,0 +1,151 @@
+;;; nxml-ns.el --- XML namespace processing
+
+;; Copyright (C) 2003, 2007 Free Software Foundation, Inc.
+
+;; Author: James Clark
+;; Keywords: XML
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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 3, or (at your option)
+;; any later version.
+
+;; GNU Emacs 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., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file uses a prefix of `nxml-ns'.
+
+;;; Code:
+
+(require 'nxml-util)
+
+(defvar nxml-ns-state nil
+ "Contains the state of namespace processing. The state
+is never modified destructively and so can be saved and restored
+without copying.
+
+The value is a stack represented by a list. The list has length N + 1
+where N is the number of open elements. Each member of the list
+represents the bindings in effect for a particular element. Each
+member is itself a list whose car is the default namespace
+\(a symbol or nil) and whose cdr is an alist of (PREFIX . NS) pairs
+where PREFIX is a string (never nil) and NS is the namespace URI
+symbol.")
+
+(defconst nxml-ns-initial-state
+ (list (list nil (cons "xml" nxml-xml-namespace-uri)))
+ "A list to be used as the initial value of nxml-ns-state. This
+represents the state with no open elements and with the default
+namespace bindings (no default namespace and only the xml prefix bound).")
+
+(defsubst nxml-ns-state () nxml-ns-state)
+
+(defsubst nxml-ns-set-state (state)
+ (setq nxml-ns-state state))
+
+(defsubst nxml-ns-state-equal (state)
+ (equal nxml-ns-state state))
+
+(defmacro nxml-ns-save (&rest body)
+ `(let ((nxml-ns-state nxml-ns-initial-state))
+ ,@body))
+
+(put 'nxml-ns-save 'lisp-indent-function 0)
+(def-edebug-spec nxml-ns-save t)
+
+(defun nxml-ns-init ()
+ (setq nxml-ns-state nxml-ns-initial-state))
+
+(defun nxml-ns-push-state ()
+ "Change the state by starting a new element. Namespace declarations
+are inherited from the parent state."
+ (setq nxml-ns-state (cons (car nxml-ns-state) nxml-ns-state)))
+
+(defun nxml-ns-pop-state ()
+ "Change the state by ending an element. The behaviour is undefined
+if there is no open element."
+ (setq nxml-ns-state (cdr nxml-ns-state)))
+
+(defun nxml-ns-get-prefix (prefix)
+ "Return the symbol for namespace bound to PREFIX, or nil if PREFIX
+is unbound. PREFIX is a string, never nil."
+ (let ((binding (assoc prefix (cdar nxml-ns-state))))
+ (and binding (cdr binding))))
+
+(defun nxml-ns-set-prefix (prefix ns)
+ "Change the binding of PREFIX. PREFIX is a string (never nil). NS
+is a symbol (never nil). The change will be in effect until the end of
+the current element."
+ (setq nxml-ns-state
+ (let ((bindings (car nxml-ns-state)))
+ (cons (cons (car bindings)
+ (cons (cons prefix ns) (cdr bindings)))
+ (cdr nxml-ns-state)))))
+
+(defun nxml-ns-get-default ()
+ "Return the current default namespace as a symbol, or nil
+if there is no default namespace."
+ (caar nxml-ns-state))
+
+(defun nxml-ns-set-default (ns)
+ "Changes the current default namespace. The change
+will be in effect until the end of the current element.
+NS is a symbol or nil."
+ (setq nxml-ns-state
+ (cons (cons ns (cdar nxml-ns-state))
+ (cdr nxml-ns-state))))
+
+(defun nxml-ns-get-context ()
+ (car nxml-ns-state))
+
+(defun nxml-ns-prefixes-for (ns &optional attributep)
+ (let ((current (car nxml-ns-state))
+ prefixes)
+ (when (if attributep
+ (not ns)
+ (eq (car current) ns))
+ (setq prefixes '(nil)))
+ (setq current (cdr current))
+ (while (let ((binding (rassq ns current)))
+ (when binding
+ (when (eq (nxml-ns-get-prefix (car binding)) ns)
+ (add-to-list 'prefixes
+ (car binding)))
+ (setq current
+ (cdr (member binding current))))))
+ prefixes))
+
+(defun nxml-ns-prefix-for (ns)
+ (car (rassq ns (cdar nxml-ns-state))))
+
+(defun nxml-ns-changed-prefixes ()
+ (let ((old (cadr nxml-ns-state))
+ (new (car nxml-ns-state))
+ changed)
+ (if (eq old new)
+ nil
+ (unless (eq (car new) (car old))
+ (setq changed '(nil)))
+ (setq new (cdr new))
+ (setq old (cdr old))
+ (while (not (eq new old))
+ (setq changed
+ (cons (caar new) changed))
+ (setq new (cdr new))))
+ changed))
+
+(provide 'nxml-ns)
+
+;; arch-tag: 5968e4b7-fb37-46ce-8621-c65db9793028
+;;; nxml-ns.el ends here