annotate markup/builder.py @ 119:61b133ed95b2

Allow creating fragments from the `tag` object in `markup.builder`.
author cmlenz
date Wed, 02 Aug 2006 08:03:31 +0000
parents bc73d3ab823f
children b9a0031d4bbb
rev   line source
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
1 # -*- coding: utf-8 -*-
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
2 #
66
822089ae65ce Switch copyright to Edgewall and URLs to markup.edgewall.org.
cmlenz
parents: 65
diff changeset
3 # Copyright (C) 2006 Edgewall Software
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
4 # All rights reserved.
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
5 #
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
6 # This software is licensed as described in the file COPYING, which
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
7 # you should have received as part of this distribution. The terms
66
822089ae65ce Switch copyright to Edgewall and URLs to markup.edgewall.org.
cmlenz
parents: 65
diff changeset
8 # are also available at http://markup.edgewall.org/wiki/License.
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
9 #
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
10 # This software consists of voluntary contributions made by many
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
11 # individuals. For the exact contribution history, see the revision
66
822089ae65ce Switch copyright to Edgewall and URLs to markup.edgewall.org.
cmlenz
parents: 65
diff changeset
12 # history and logs, available at http://markup.edgewall.org/log/.
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
13
98
bc73d3ab823f Bugfix in `builder` module: attribute values need to be converted to strings when generating streams.
cmlenz
parents: 94
diff changeset
14 from markup.core import Attributes, Namespace, QName, Stream, escape
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
15
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
16 __all__ = ['Fragment', 'Element', 'tag']
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
17
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
18
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
19 class Fragment(object):
28
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
20 """Represents a markup fragment, which is basically just a list of element
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
21 or text nodes.
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
22 """
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
23 __slots__ = ['children']
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
24
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
25 def __init__(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
26 self.children = []
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
27
65
5c024cf58ecb Support the use of directives as elements to reduce the need for using `py:strip`.
cmlenz
parents: 34
diff changeset
28 def __add__(self, other):
5c024cf58ecb Support the use of directives as elements to reduce the need for using `py:strip`.
cmlenz
parents: 34
diff changeset
29 return Fragment()(self, other)
5c024cf58ecb Support the use of directives as elements to reduce the need for using `py:strip`.
cmlenz
parents: 34
diff changeset
30
5c024cf58ecb Support the use of directives as elements to reduce the need for using `py:strip`.
cmlenz
parents: 34
diff changeset
31 def __call__(self, *args):
5c024cf58ecb Support the use of directives as elements to reduce the need for using `py:strip`.
cmlenz
parents: 34
diff changeset
32 for arg in args:
5c024cf58ecb Support the use of directives as elements to reduce the need for using `py:strip`.
cmlenz
parents: 34
diff changeset
33 self.append(arg)
5c024cf58ecb Support the use of directives as elements to reduce the need for using `py:strip`.
cmlenz
parents: 34
diff changeset
34 return self
5c024cf58ecb Support the use of directives as elements to reduce the need for using `py:strip`.
cmlenz
parents: 34
diff changeset
35
5c024cf58ecb Support the use of directives as elements to reduce the need for using `py:strip`.
cmlenz
parents: 34
diff changeset
36 def __iter__(self):
98
bc73d3ab823f Bugfix in `builder` module: attribute values need to be converted to strings when generating streams.
cmlenz
parents: 94
diff changeset
37 return self._generate()
65
5c024cf58ecb Support the use of directives as elements to reduce the need for using `py:strip`.
cmlenz
parents: 34
diff changeset
38
5c024cf58ecb Support the use of directives as elements to reduce the need for using `py:strip`.
cmlenz
parents: 34
diff changeset
39 def __repr__(self):
5c024cf58ecb Support the use of directives as elements to reduce the need for using `py:strip`.
cmlenz
parents: 34
diff changeset
40 return '<%s>' % self.__class__.__name__
5c024cf58ecb Support the use of directives as elements to reduce the need for using `py:strip`.
cmlenz
parents: 34
diff changeset
41
5c024cf58ecb Support the use of directives as elements to reduce the need for using `py:strip`.
cmlenz
parents: 34
diff changeset
42 def __str__(self):
5c024cf58ecb Support the use of directives as elements to reduce the need for using `py:strip`.
cmlenz
parents: 34
diff changeset
43 return str(self.generate())
5c024cf58ecb Support the use of directives as elements to reduce the need for using `py:strip`.
cmlenz
parents: 34
diff changeset
44
5c024cf58ecb Support the use of directives as elements to reduce the need for using `py:strip`.
cmlenz
parents: 34
diff changeset
45 def __unicode__(self):
5c024cf58ecb Support the use of directives as elements to reduce the need for using `py:strip`.
cmlenz
parents: 34
diff changeset
46 return unicode(self.generate())
5c024cf58ecb Support the use of directives as elements to reduce the need for using `py:strip`.
cmlenz
parents: 34
diff changeset
47
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
48 def append(self, node):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
49 """Append an element or string as child node."""
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
50 if isinstance(node, (Element, basestring, int, float, long)):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
51 # For objects of a known/primitive type, we avoid the check for
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
52 # whether it is iterable for better performance
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
53 self.children.append(node)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
54 elif isinstance(node, Fragment):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
55 self.children += node.children
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
56 elif node is not None:
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
57 try:
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
58 children = iter(node)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
59 except TypeError:
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
60 self.children.append(node)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
61 else:
94
80c72e936e72 Some bugfixes and minor performance improvements for the builder module.
cmlenz
parents: 91
diff changeset
62 for child in children:
80c72e936e72 Some bugfixes and minor performance improvements for the builder module.
cmlenz
parents: 91
diff changeset
63 self.append(child)
80c72e936e72 Some bugfixes and minor performance improvements for the builder module.
cmlenz
parents: 91
diff changeset
64
80c72e936e72 Some bugfixes and minor performance improvements for the builder module.
cmlenz
parents: 91
diff changeset
65 def _generate(self):
80c72e936e72 Some bugfixes and minor performance improvements for the builder module.
cmlenz
parents: 91
diff changeset
66 for child in self.children:
80c72e936e72 Some bugfixes and minor performance improvements for the builder module.
cmlenz
parents: 91
diff changeset
67 if isinstance(child, Fragment):
80c72e936e72 Some bugfixes and minor performance improvements for the builder module.
cmlenz
parents: 91
diff changeset
68 for event in child._generate():
80c72e936e72 Some bugfixes and minor performance improvements for the builder module.
cmlenz
parents: 91
diff changeset
69 yield event
80c72e936e72 Some bugfixes and minor performance improvements for the builder module.
cmlenz
parents: 91
diff changeset
70 else:
80c72e936e72 Some bugfixes and minor performance improvements for the builder module.
cmlenz
parents: 91
diff changeset
71 if not isinstance(child, basestring):
80c72e936e72 Some bugfixes and minor performance improvements for the builder module.
cmlenz
parents: 91
diff changeset
72 child = unicode(child)
80c72e936e72 Some bugfixes and minor performance improvements for the builder module.
cmlenz
parents: 91
diff changeset
73 yield Stream.TEXT, child, (None, -1, -1)
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
74
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
75 def generate(self):
28
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
76 """Return a markup event stream for the fragment."""
94
80c72e936e72 Some bugfixes and minor performance improvements for the builder module.
cmlenz
parents: 91
diff changeset
77 return Stream(self._generate())
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
78
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
79
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
80 class Element(Fragment):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
81 """Simple XML output generator based on the builder pattern.
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
82
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
83 Construct XML elements by passing the tag name to the constructor:
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
84
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
85 >>> print Element('strong')
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
86 <strong/>
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
87
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
88 Attributes can be specified using keyword arguments. The values of the
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
89 arguments will be converted to strings and any special XML characters
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
90 escaped:
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
91
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
92 >>> print Element('textarea', rows=10, cols=60)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
93 <textarea rows="10" cols="60"/>
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
94 >>> print Element('span', title='1 < 2')
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
95 <span title="1 &lt; 2"/>
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
96 >>> print Element('span', title='"baz"')
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
97 <span title="&#34;baz&#34;"/>
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
98
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
99 The " character is escaped using a numerical entity.
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
100 The order in which attributes are rendered is undefined.
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
101
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
102 If an attribute value evaluates to `None`, that attribute is not included
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
103 in the output:
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
104
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
105 >>> print Element('a', name=None)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
106 <a/>
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
107
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
108 Attribute names that conflict with Python keywords can be specified by
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
109 appending an underscore:
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
110
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
111 >>> print Element('div', class_='warning')
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
112 <div class="warning"/>
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
113
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
114 Nested elements can be added to an element using item access notation.
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
115 The call notation can also be used for this and for adding attributes
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
116 using keyword arguments, as one would do in the constructor.
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
117
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
118 >>> print Element('ul')(Element('li'), Element('li'))
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
119 <ul><li/><li/></ul>
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
120 >>> print Element('a')('Label')
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
121 <a>Label</a>
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
122 >>> print Element('a')('Label', href="target")
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
123 <a href="target">Label</a>
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
124
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
125 Text nodes can be nested in an element by adding strings instead of
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
126 elements. Any special characters in the strings are escaped automatically:
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
127
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
128 >>> print Element('em')('Hello world')
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
129 <em>Hello world</em>
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
130 >>> print Element('em')(42)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
131 <em>42</em>
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
132 >>> print Element('em')('1 < 2')
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
133 <em>1 &lt; 2</em>
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
134
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
135 This technique also allows mixed content:
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
136
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
137 >>> print Element('p')('Hello ', Element('b')('world'))
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
138 <p>Hello <b>world</b></p>
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
139
34
ae293292cbb1 quotes should not be escaped inside text nodes
mgood
parents: 28
diff changeset
140 Quotes are not escaped inside text nodes:
ae293292cbb1 quotes should not be escaped inside text nodes
mgood
parents: 28
diff changeset
141 >>> print Element('p')('"Hello"')
ae293292cbb1 quotes should not be escaped inside text nodes
mgood
parents: 28
diff changeset
142 <p>"Hello"</p>
ae293292cbb1 quotes should not be escaped inside text nodes
mgood
parents: 28
diff changeset
143
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
144 Elements can also be combined with other elements or strings using the
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
145 addition operator, which results in a `Fragment` object that contains the
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
146 operands:
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
147
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
148 >>> print Element('br') + 'some text' + Element('br')
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
149 <br/>some text<br/>
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
150
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
151 Elements with a namespace can be generated using the `Namespace` and/or
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
152 `QName` classes:
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
153
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
154 >>> from markup.core import Namespace
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
155 >>> xhtml = Namespace('http://www.w3.org/1999/xhtml')
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
156 >>> print Element(xhtml.html, lang='en')
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
157 <html lang="en" xmlns="http://www.w3.org/1999/xhtml"/>
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
158 """
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
159 __slots__ = ['tag', 'attrib']
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
160
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
161 def __init__(self, tag_, **attrib):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
162 Fragment.__init__(self)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
163 self.tag = QName(tag_)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
164 self.attrib = Attributes()
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
165 self(**attrib)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
166
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
167 def __call__(self, *args, **kwargs):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
168 for attr, value in kwargs.items():
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
169 if value is None:
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
170 continue
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
171 attr = attr.rstrip('_').replace('_', '-')
98
bc73d3ab823f Bugfix in `builder` module: attribute values need to be converted to strings when generating streams.
cmlenz
parents: 94
diff changeset
172 self.attrib.set(attr, escape(value))
bc73d3ab823f Bugfix in `builder` module: attribute values need to be converted to strings when generating streams.
cmlenz
parents: 94
diff changeset
173 Fragment.__call__(self, *args)
bc73d3ab823f Bugfix in `builder` module: attribute values need to be converted to strings when generating streams.
cmlenz
parents: 94
diff changeset
174 return self
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
175
65
5c024cf58ecb Support the use of directives as elements to reduce the need for using `py:strip`.
cmlenz
parents: 34
diff changeset
176 def __repr__(self):
5c024cf58ecb Support the use of directives as elements to reduce the need for using `py:strip`.
cmlenz
parents: 34
diff changeset
177 return '<%s "%s">' % (self.__class__.__name__, self.tag)
5c024cf58ecb Support the use of directives as elements to reduce the need for using `py:strip`.
cmlenz
parents: 34
diff changeset
178
94
80c72e936e72 Some bugfixes and minor performance improvements for the builder module.
cmlenz
parents: 91
diff changeset
179 def _generate(self):
98
bc73d3ab823f Bugfix in `builder` module: attribute values need to be converted to strings when generating streams.
cmlenz
parents: 94
diff changeset
180 attrib = Attributes()
bc73d3ab823f Bugfix in `builder` module: attribute values need to be converted to strings when generating streams.
cmlenz
parents: 94
diff changeset
181 for attr, value in self.attrib:
bc73d3ab823f Bugfix in `builder` module: attribute values need to be converted to strings when generating streams.
cmlenz
parents: 94
diff changeset
182 if not isinstance(value, basestring):
bc73d3ab823f Bugfix in `builder` module: attribute values need to be converted to strings when generating streams.
cmlenz
parents: 94
diff changeset
183 value = unicode(value)
bc73d3ab823f Bugfix in `builder` module: attribute values need to be converted to strings when generating streams.
cmlenz
parents: 94
diff changeset
184 attrib.append((attr, value))
bc73d3ab823f Bugfix in `builder` module: attribute values need to be converted to strings when generating streams.
cmlenz
parents: 94
diff changeset
185 yield Stream.START, (self.tag, attrib), (None, -1, -1)
94
80c72e936e72 Some bugfixes and minor performance improvements for the builder module.
cmlenz
parents: 91
diff changeset
186 for kind, data, pos in Fragment._generate(self):
80c72e936e72 Some bugfixes and minor performance improvements for the builder module.
cmlenz
parents: 91
diff changeset
187 yield kind, data, pos
80c72e936e72 Some bugfixes and minor performance improvements for the builder module.
cmlenz
parents: 91
diff changeset
188 yield Stream.END, self.tag, (None, -1, -1)
80c72e936e72 Some bugfixes and minor performance improvements for the builder module.
cmlenz
parents: 91
diff changeset
189
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
190 def generate(self):
28
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
191 """Return a markup event stream for the fragment."""
94
80c72e936e72 Some bugfixes and minor performance improvements for the builder module.
cmlenz
parents: 91
diff changeset
192 return Stream(self._generate())
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
193
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
194
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
195 class ElementFactory(object):
28
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
196 """Factory for `Element` objects.
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
197
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
198 A new element is created simply by accessing a correspondingly named
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
199 attribute of the factory object:
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
200
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
201 >>> factory = ElementFactory()
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
202 >>> print factory.foo
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
203 <foo/>
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
204 >>> print factory.foo(id=2)
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
205 <foo id="2"/>
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
206
119
61b133ed95b2 Allow creating fragments from the `tag` object in `markup.builder`.
cmlenz
parents: 98
diff changeset
207 Markup fragments (lists of nodes without a parent element) can be created
61b133ed95b2 Allow creating fragments from the `tag` object in `markup.builder`.
cmlenz
parents: 98
diff changeset
208 by calling the factory:
61b133ed95b2 Allow creating fragments from the `tag` object in `markup.builder`.
cmlenz
parents: 98
diff changeset
209
61b133ed95b2 Allow creating fragments from the `tag` object in `markup.builder`.
cmlenz
parents: 98
diff changeset
210 >>> print factory('Hello, ', factory.em('world'), '!')
61b133ed95b2 Allow creating fragments from the `tag` object in `markup.builder`.
cmlenz
parents: 98
diff changeset
211 Hello, <em>world</em>!
61b133ed95b2 Allow creating fragments from the `tag` object in `markup.builder`.
cmlenz
parents: 98
diff changeset
212
28
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
213 A factory can also be bound to a specific namespace:
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
214
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
215 >>> factory = ElementFactory('http://www.w3.org/1999/xhtml')
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
216 >>> print factory.html(lang="en")
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
217 <html lang="en" xmlns="http://www.w3.org/1999/xhtml"/>
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
218
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
219 The namespace for a specific element can be altered on an existing factory
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
220 by specifying the new namespace using item access:
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
221
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
222 >>> factory = ElementFactory()
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
223 >>> print factory.html(factory['http://www.w3.org/2000/svg'].g(id=3))
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
224 <html><g id="3" xmlns="http://www.w3.org/2000/svg"/></html>
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
225
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
226 Usually, the `ElementFactory` class is not be used directly. Rather, the
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
227 `tag` instance should be used to create elements.
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
228 """
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
229
19
7b589453b797 Enable `ElementFactory` to create namespaced elements.
cmlenz
parents: 17
diff changeset
230 def __init__(self, namespace=None):
28
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
231 """Create the factory, optionally bound to the given namespace.
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
232
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
233 @param namespace: the namespace URI for any created elements, or `None`
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
234 for no namespace
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
235 """
20
e3d3c1d8c98a Fix tests broken in [20].
cmlenz
parents: 19
diff changeset
236 if namespace and not isinstance(namespace, Namespace):
19
7b589453b797 Enable `ElementFactory` to create namespaced elements.
cmlenz
parents: 17
diff changeset
237 namespace = Namespace(namespace)
7b589453b797 Enable `ElementFactory` to create namespaced elements.
cmlenz
parents: 17
diff changeset
238 self.namespace = namespace
7b589453b797 Enable `ElementFactory` to create namespaced elements.
cmlenz
parents: 17
diff changeset
239
119
61b133ed95b2 Allow creating fragments from the `tag` object in `markup.builder`.
cmlenz
parents: 98
diff changeset
240 def __call__(self, *args):
61b133ed95b2 Allow creating fragments from the `tag` object in `markup.builder`.
cmlenz
parents: 98
diff changeset
241 return Fragment()(*args)
61b133ed95b2 Allow creating fragments from the `tag` object in `markup.builder`.
cmlenz
parents: 98
diff changeset
242
19
7b589453b797 Enable `ElementFactory` to create namespaced elements.
cmlenz
parents: 17
diff changeset
243 def __getitem__(self, namespace):
28
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
244 """Return a new factory that is bound to the specified namespace."""
19
7b589453b797 Enable `ElementFactory` to create namespaced elements.
cmlenz
parents: 17
diff changeset
245 return ElementFactory(namespace)
7b589453b797 Enable `ElementFactory` to create namespaced elements.
cmlenz
parents: 17
diff changeset
246
7b589453b797 Enable `ElementFactory` to create namespaced elements.
cmlenz
parents: 17
diff changeset
247 def __getattr__(self, name):
28
15e59a9cb362 More docstrings for the builder module.
cmlenz
parents: 27
diff changeset
248 """Create an `Element` with the given name."""
19
7b589453b797 Enable `ElementFactory` to create namespaced elements.
cmlenz
parents: 17
diff changeset
249 return Element(self.namespace and self.namespace[name] or name)
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
250
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
251
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
252 tag = ElementFactory()
Copyright (C) 2012-2017 Edgewall Software