1 ;;; nxml-ns.el --- XML namespace processing
3 ;; Copyright (C) 2003, 2007-2011 Free Software Foundation, Inc.
8 ;; This file is part of GNU Emacs.
10 ;; GNU Emacs is free software: you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation, either version 3 of the License, or
13 ;; (at your option) any later version.
15 ;; GNU Emacs is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
25 ;; This file uses a prefix of `nxml-ns'.
31 (defvar nxml-ns-state nil
32 "Contains the state of namespace processing.
33 The state is never modified destructively and so can be saved and
34 restored without copying.
36 The value is a stack represented by a list. The list has length
37 N + 1 where N is the number of open elements. Each member of the
38 list represents the bindings in effect for a particular element.
39 Each member is itself a list whose car is the default namespace
40 \(a symbol or nil) and whose cdr is an alist of (PREFIX . NS) pairs
41 where PREFIX is a string (never nil) and NS is the namespace URI
44 (defconst nxml-ns-initial-state
45 (list (list nil
(cons "xml" nxml-xml-namespace-uri
)))
46 "A list to be used as the initial value of `nxml-ns-state'.
47 This represents the state with no open elements and with the default
48 namespace bindings (no default namespace and only the xml prefix bound).")
50 (defsubst nxml-ns-state
() nxml-ns-state
)
52 (defsubst nxml-ns-set-state
(state)
53 (setq nxml-ns-state state
))
55 (defsubst nxml-ns-state-equal
(state)
56 (equal nxml-ns-state state
))
58 (defmacro nxml-ns-save
(&rest body
)
59 `(let ((nxml-ns-state nxml-ns-initial-state
))
62 (put 'nxml-ns-save
'lisp-indent-function
0)
63 (def-edebug-spec nxml-ns-save t
)
65 (defun nxml-ns-init ()
66 (setq nxml-ns-state nxml-ns-initial-state
))
68 (defun nxml-ns-push-state ()
69 "Change the state by starting a new element.
70 Namespace declarations are inherited from the parent state."
71 (setq nxml-ns-state
(cons (car nxml-ns-state
) nxml-ns-state
)))
73 (defun nxml-ns-pop-state ()
74 "Change the state by ending an element.
75 The behavior is undefined if there is no open element."
76 (setq nxml-ns-state
(cdr nxml-ns-state
)))
78 (defun nxml-ns-get-prefix (prefix)
79 "Return the symbol for namespace bound to PREFIX.
80 Return nil if PREFIX is unbound. PREFIX is a string, never nil."
81 (let ((binding (assoc prefix
(cdar nxml-ns-state
))))
82 (and binding
(cdr binding
))))
84 (defun nxml-ns-set-prefix (prefix ns
)
85 "Change the binding of PREFIX.
86 PREFIX is a string (never nil). NS is a symbol (never nil).
87 The change will be in effect until the end of the current element."
89 (let ((bindings (car nxml-ns-state
)))
90 (cons (cons (car bindings
)
91 (cons (cons prefix ns
) (cdr bindings
)))
92 (cdr nxml-ns-state
)))))
94 (defun nxml-ns-get-default ()
95 "Return the current default namespace as a symbol.
96 Return nil if there is no default namespace."
99 (defun nxml-ns-set-default (ns)
100 "Changes the current default namespace.
101 The change will be in effect until the end of the current element.
102 NS is a symbol or nil."
104 (cons (cons ns
(cdar nxml-ns-state
))
105 (cdr nxml-ns-state
))))
107 (defun nxml-ns-get-context ()
110 (defun nxml-ns-prefixes-for (ns &optional attributep
)
111 (let ((current (car nxml-ns-state
))
115 (eq (car current
) ns
))
116 (setq prefixes
'(nil)))
117 (setq current
(cdr current
))
118 (while (let ((binding (rassq ns current
)))
120 (when (eq (nxml-ns-get-prefix (car binding
)) ns
)
121 (add-to-list 'prefixes
124 (cdr (member binding current
))))))
127 (defun nxml-ns-prefix-for (ns)
128 (car (rassq ns
(cdar nxml-ns-state
))))
130 (defun nxml-ns-changed-prefixes ()
131 (let ((old (cadr nxml-ns-state
))
132 (new (car nxml-ns-state
))
136 (unless (eq (car new
) (car old
))
137 (setq changed
'(nil)))
140 (while (not (eq new old
))
142 (cons (caar new
) changed
))
143 (setq new
(cdr new
))))
148 ;;; nxml-ns.el ends here