Mercurial > repos > shellac > guppy_basecaller
comparison env/lib/python3.7/site-packages/lxml/builder.py @ 0:26e78fe6e8c4 draft
"planemo upload commit c699937486c35866861690329de38ec1a5d9f783"
| author | shellac |
|---|---|
| date | Sat, 02 May 2020 07:14:21 -0400 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:26e78fe6e8c4 |
|---|---|
| 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() |
