Mercurial > repos > shellac > guppy_basecaller
comparison env/lib/python3.7/site-packages/lxml/builder.py @ 5:9b1c78e6ba9c draft default tip
"planemo upload commit 6c0a8142489327ece472c84e558c47da711a9142"
author | shellac |
---|---|
date | Mon, 01 Jun 2020 08:59:25 -0400 |
parents | 79f47841a781 |
children |
comparison
equal
deleted
inserted
replaced
4:79f47841a781 | 5:9b1c78e6ba9c |
---|---|
1 # cython: language_level=2 | |
2 | |
3 # | |
4 # Element generator factory by Fredrik Lundh. | |
5 # | |
6 # Source: | |
7 # http://online.effbot.org/2006_11_01_archive.htm#et-builder | |
8 # http://effbot.python-hosting.com/file/stuff/sandbox/elementlib/builder.py | |
9 # | |
10 # -------------------------------------------------------------------- | |
11 # The ElementTree toolkit is | |
12 # | |
13 # Copyright (c) 1999-2004 by Fredrik Lundh | |
14 # | |
15 # By obtaining, using, and/or copying this software and/or its | |
16 # associated documentation, you agree that you have read, understood, | |
17 # and will comply with the following terms and conditions: | |
18 # | |
19 # Permission to use, copy, modify, and distribute this software and | |
20 # its associated documentation for any purpose and without fee is | |
21 # hereby granted, provided that the above copyright notice appears in | |
22 # all copies, and that both that copyright notice and this permission | |
23 # notice appear in supporting documentation, and that the name of | |
24 # Secret Labs AB or the author not be used in advertising or publicity | |
25 # pertaining to distribution of the software without specific, written | |
26 # prior permission. | |
27 # | |
28 # SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |
29 # TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- | |
30 # ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR | |
31 # BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY | |
32 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
33 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | |
34 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |
35 # OF THIS SOFTWARE. | |
36 # -------------------------------------------------------------------- | |
37 | |
38 """ | |
39 The ``E`` Element factory for generating XML documents. | |
40 """ | |
41 | |
42 from __future__ import absolute_import | |
43 | |
44 import lxml.etree as ET | |
45 | |
46 from functools import partial | |
47 | |
48 try: | |
49 basestring | |
50 except NameError: | |
51 basestring = str | |
52 | |
53 try: | |
54 unicode | |
55 except NameError: | |
56 unicode = str | |
57 | |
58 | |
59 class ElementMaker(object): | |
60 """Element generator factory. | |
61 | |
62 Unlike the ordinary Element factory, the E factory allows you to pass in | |
63 more than just a tag and some optional attributes; you can also pass in | |
64 text and other elements. The text is added as either text or tail | |
65 attributes, and elements are inserted at the right spot. Some small | |
66 examples:: | |
67 | |
68 >>> from lxml import etree as ET | |
69 >>> from lxml.builder import E | |
70 | |
71 >>> ET.tostring(E("tag")) | |
72 '<tag/>' | |
73 >>> ET.tostring(E("tag", "text")) | |
74 '<tag>text</tag>' | |
75 >>> ET.tostring(E("tag", "text", key="value")) | |
76 '<tag key="value">text</tag>' | |
77 >>> ET.tostring(E("tag", E("subtag", "text"), "tail")) | |
78 '<tag><subtag>text</subtag>tail</tag>' | |
79 | |
80 For simple tags, the factory also allows you to write ``E.tag(...)`` instead | |
81 of ``E('tag', ...)``:: | |
82 | |
83 >>> ET.tostring(E.tag()) | |
84 '<tag/>' | |
85 >>> ET.tostring(E.tag("text")) | |
86 '<tag>text</tag>' | |
87 >>> ET.tostring(E.tag(E.subtag("text"), "tail")) | |
88 '<tag><subtag>text</subtag>tail</tag>' | |
89 | |
90 Here's a somewhat larger example; this shows how to generate HTML | |
91 documents, using a mix of prepared factory functions for inline elements, | |
92 nested ``E.tag`` calls, and embedded XHTML fragments:: | |
93 | |
94 # some common inline elements | |
95 A = E.a | |
96 I = E.i | |
97 B = E.b | |
98 | |
99 def CLASS(v): | |
100 # helper function, 'class' is a reserved word | |
101 return {'class': v} | |
102 | |
103 page = ( | |
104 E.html( | |
105 E.head( | |
106 E.title("This is a sample document") | |
107 ), | |
108 E.body( | |
109 E.h1("Hello!", CLASS("title")), | |
110 E.p("This is a paragraph with ", B("bold"), " text in it!"), | |
111 E.p("This is another paragraph, with a ", | |
112 A("link", href="http://www.python.org"), "."), | |
113 E.p("Here are some reserved characters: <spam&egg>."), | |
114 ET.XML("<p>And finally, here is an embedded XHTML fragment.</p>"), | |
115 ) | |
116 ) | |
117 ) | |
118 | |
119 print ET.tostring(page) | |
120 | |
121 Here's a prettyprinted version of the output from the above script:: | |
122 | |
123 <html> | |
124 <head> | |
125 <title>This is a sample document</title> | |
126 </head> | |
127 <body> | |
128 <h1 class="title">Hello!</h1> | |
129 <p>This is a paragraph with <b>bold</b> text in it!</p> | |
130 <p>This is another paragraph, with <a href="http://www.python.org">link</a>.</p> | |
131 <p>Here are some reserved characters: <spam&egg>.</p> | |
132 <p>And finally, here is an embedded XHTML fragment.</p> | |
133 </body> | |
134 </html> | |
135 | |
136 For namespace support, you can pass a namespace map (``nsmap``) | |
137 and/or a specific target ``namespace`` to the ElementMaker class:: | |
138 | |
139 >>> E = ElementMaker(namespace="http://my.ns/") | |
140 >>> print(ET.tostring( E.test )) | |
141 <test xmlns="http://my.ns/"/> | |
142 | |
143 >>> E = ElementMaker(namespace="http://my.ns/", nsmap={'p':'http://my.ns/'}) | |
144 >>> print(ET.tostring( E.test )) | |
145 <p:test xmlns:p="http://my.ns/"/> | |
146 """ | |
147 | |
148 def __init__(self, typemap=None, | |
149 namespace=None, nsmap=None, makeelement=None): | |
150 if namespace is not None: | |
151 self._namespace = '{' + namespace + '}' | |
152 else: | |
153 self._namespace = None | |
154 | |
155 if nsmap: | |
156 self._nsmap = dict(nsmap) | |
157 else: | |
158 self._nsmap = None | |
159 | |
160 if makeelement is not None: | |
161 assert callable(makeelement) | |
162 self._makeelement = makeelement | |
163 else: | |
164 self._makeelement = ET.Element | |
165 | |
166 # initialize type map for this element factory | |
167 | |
168 if typemap: | |
169 typemap = dict(typemap) | |
170 else: | |
171 typemap = {} | |
172 | |
173 def add_text(elem, item): | |
174 try: | |
175 elem[-1].tail = (elem[-1].tail or "") + item | |
176 except IndexError: | |
177 elem.text = (elem.text or "") + item | |
178 | |
179 def add_cdata(elem, cdata): | |
180 if elem.text: | |
181 raise ValueError("Can't add a CDATA section. Element already has some text: %r" % elem.text) | |
182 elem.text = cdata | |
183 | |
184 if str not in typemap: | |
185 typemap[str] = add_text | |
186 if unicode not in typemap: | |
187 typemap[unicode] = add_text | |
188 if ET.CDATA not in typemap: | |
189 typemap[ET.CDATA] = add_cdata | |
190 | |
191 def add_dict(elem, item): | |
192 attrib = elem.attrib | |
193 for k, v in item.items(): | |
194 if isinstance(v, basestring): | |
195 attrib[k] = v | |
196 else: | |
197 attrib[k] = typemap[type(v)](None, v) | |
198 if dict not in typemap: | |
199 typemap[dict] = add_dict | |
200 | |
201 self._typemap = typemap | |
202 | |
203 def __call__(self, tag, *children, **attrib): | |
204 typemap = self._typemap | |
205 | |
206 if self._namespace is not None and tag[0] != '{': | |
207 tag = self._namespace + tag | |
208 elem = self._makeelement(tag, nsmap=self._nsmap) | |
209 if attrib: | |
210 typemap[dict](elem, attrib) | |
211 | |
212 for item in children: | |
213 if callable(item): | |
214 item = item() | |
215 t = typemap.get(type(item)) | |
216 if t is None: | |
217 if ET.iselement(item): | |
218 elem.append(item) | |
219 continue | |
220 for basetype in type(item).__mro__: | |
221 # See if the typemap knows of any of this type's bases. | |
222 t = typemap.get(basetype) | |
223 if t is not None: | |
224 break | |
225 else: | |
226 raise TypeError("bad argument type: %s(%r)" % | |
227 (type(item).__name__, item)) | |
228 v = t(elem, item) | |
229 if v: | |
230 typemap.get(type(v))(elem, v) | |
231 | |
232 return elem | |
233 | |
234 def __getattr__(self, tag): | |
235 return partial(self, tag) | |
236 | |
237 | |
238 # create factory object | |
239 E = ElementMaker() |