16516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# markdown/html4.py 26516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# 36516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# Add html4 serialization to older versions of Elementree 46516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# Taken from ElementTree 1.3 preview with slight modifications 56516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# 66516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# Copyright (c) 1999-2007 by Fredrik Lundh. All rights reserved. 76516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# 86516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# fredrik@pythonware.com 96516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# http://www.pythonware.com 106516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# 116516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# -------------------------------------------------------------------- 126516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# The ElementTree toolkit is 136516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# 146516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# Copyright (c) 1999-2007 by Fredrik Lundh 156516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# 166516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# By obtaining, using, and/or copying this software and/or its 176516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# associated documentation, you agree that you have read, understood, 186516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# and will comply with the following terms and conditions: 196516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# 206516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# Permission to use, copy, modify, and distribute this software and 216516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# its associated documentation for any purpose and without fee is 226516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# hereby granted, provided that the above copyright notice appears in 236516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# all copies, and that both that copyright notice and this permission 246516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# notice appear in supporting documentation, and that the name of 256516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# Secret Labs AB or the author not be used in advertising or publicity 266516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# pertaining to distribution of the software without specific, written 276516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# prior permission. 286516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# 296516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD 306516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- 316516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR 326516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 336516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 346516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 356516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 366516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# OF THIS SOFTWARE. 376516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# -------------------------------------------------------------------- 386516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 396516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 406516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queruimport markdown 416516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste QueruElementTree = markdown.etree.ElementTree 426516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste QueruQName = markdown.etree.QName 436516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste QueruComment = markdown.etree.Comment 446516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste QueruPI = markdown.etree.PI 456516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste QueruProcessingInstruction = markdown.etree.ProcessingInstruction 466516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 476516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste QueruHTML_EMPTY = ("area", "base", "basefont", "br", "col", "frame", "hr", 486516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru "img", "input", "isindex", "link", "meta" "param") 496516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 506516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Querutry: 516516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru HTML_EMPTY = set(HTML_EMPTY) 526516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queruexcept NameError: 536516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru pass 546516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 556516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru_namespace_map = { 566516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru # "well-known" namespace prefixes 576516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru "http://www.w3.org/XML/1998/namespace": "xml", 586516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru "http://www.w3.org/1999/xhtml": "html", 596516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru "http://www.w3.org/1999/02/22-rdf-syntax-ns#": "rdf", 606516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru "http://schemas.xmlsoap.org/wsdl/": "wsdl", 616516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru # xml schema 626516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru "http://www.w3.org/2001/XMLSchema": "xs", 636516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru "http://www.w3.org/2001/XMLSchema-instance": "xsi", 646516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru # dublic core 656516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru "http://purl.org/dc/elements/1.1/": "dc", 666516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru} 676516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 686516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 696516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Querudef _raise_serialization_error(text): 706516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru raise TypeError( 716516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru "cannot serialize %r (type %s)" % (text, type(text).__name__) 726516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru ) 736516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 746516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Querudef _encode(text, encoding): 756516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru try: 766516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru return text.encode(encoding, "xmlcharrefreplace") 776516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru except (TypeError, AttributeError): 786516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru _raise_serialization_error(text) 796516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 806516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Querudef _escape_cdata(text, encoding): 816516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru # escape character data 826516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru try: 836516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru # it's worth avoiding do-nothing calls for strings that are 846516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru # shorter than 500 character, or so. assume that's, by far, 856516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru # the most common case in most applications. 866516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if "&" in text: 876516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru text = text.replace("&", "&") 886516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if "<" in text: 896516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru text = text.replace("<", "<") 906516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if ">" in text: 916516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru text = text.replace(">", ">") 926516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru return text.encode(encoding, "xmlcharrefreplace") 936516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru except (TypeError, AttributeError): 946516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru _raise_serialization_error(text) 956516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 966516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 976516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Querudef _escape_attrib(text, encoding): 986516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru # escape attribute value 996516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru try: 1006516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if "&" in text: 1016516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru text = text.replace("&", "&") 1026516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if "<" in text: 1036516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru text = text.replace("<", "<") 1046516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if ">" in text: 1056516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru text = text.replace(">", ">") 1066516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if "\"" in text: 1076516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru text = text.replace("\"", """) 1086516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if "\n" in text: 1096516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru text = text.replace("\n", " ") 1106516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru return text.encode(encoding, "xmlcharrefreplace") 1116516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru except (TypeError, AttributeError): 1126516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru _raise_serialization_error(text) 1136516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 1146516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Querudef _escape_attrib_html(text, encoding): 1156516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru # escape attribute value 1166516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru try: 1176516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if "&" in text: 1186516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru text = text.replace("&", "&") 1196516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if ">" in text: 1206516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru text = text.replace(">", ">") 1216516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if "\"" in text: 1226516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru text = text.replace("\"", """) 1236516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru return text.encode(encoding, "xmlcharrefreplace") 1246516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru except (TypeError, AttributeError): 1256516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru _raise_serialization_error(text) 1266516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 1276516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 1286516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Querudef _serialize_html(write, elem, encoding, qnames, namespaces): 1296516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru tag = elem.tag 1306516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru text = elem.text 1316516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if tag is Comment: 1326516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru write("<!--%s-->" % _escape_cdata(text, encoding)) 1336516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru elif tag is ProcessingInstruction: 1346516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru write("<?%s?>" % _escape_cdata(text, encoding)) 1356516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru else: 1366516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru tag = qnames[tag] 1376516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if tag is None: 1386516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if text: 1396516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru write(_escape_cdata(text, encoding)) 1406516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru for e in elem: 1416516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru _serialize_html(write, e, encoding, qnames, None) 1426516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru else: 1436516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru write("<" + tag) 1446516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru items = elem.items() 1456516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if items or namespaces: 1466516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru items.sort() # lexical order 1476516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru for k, v in items: 1486516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if isinstance(k, QName): 1496516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru k = k.text 1506516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if isinstance(v, QName): 1516516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru v = qnames[v.text] 1526516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru else: 1536516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru v = _escape_attrib_html(v, encoding) 1546516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru # FIXME: handle boolean attributes 1556516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru write(" %s=\"%s\"" % (qnames[k], v)) 1566516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if namespaces: 1576516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru items = namespaces.items() 1586516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru items.sort(key=lambda x: x[1]) # sort on prefix 1596516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru for v, k in items: 1606516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if k: 1616516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru k = ":" + k 1626516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru write(" xmlns%s=\"%s\"" % ( 1636516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru k.encode(encoding), 1646516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru _escape_attrib(v, encoding) 1656516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru )) 1666516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru write(">") 1676516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru tag = tag.lower() 1686516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if text: 1696516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if tag == "script" or tag == "style": 1706516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru write(_encode(text, encoding)) 1716516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru else: 1726516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru write(_escape_cdata(text, encoding)) 1736516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru for e in elem: 1746516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru _serialize_html(write, e, encoding, qnames, None) 1756516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if tag not in HTML_EMPTY: 1766516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru write("</" + tag + ">") 1776516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if elem.tail: 1786516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru write(_escape_cdata(elem.tail, encoding)) 1796516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 1806516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Querudef write_html(root, f, 1816516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru # keyword arguments 1826516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru encoding="us-ascii", 1836516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru default_namespace=None): 1846516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru assert root is not None 1856516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if not hasattr(f, "write"): 1866516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru f = open(f, "wb") 1876516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru write = f.write 1886516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if not encoding: 1896516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru encoding = "us-ascii" 1906516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru qnames, namespaces = _namespaces( 1916516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru root, encoding, default_namespace 1926516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru ) 1936516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru _serialize_html( 1946516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru write, root, encoding, qnames, namespaces 1956516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru ) 1966516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 1976516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# -------------------------------------------------------------------- 1986516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru# serialization support 1996516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 2006516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Querudef _namespaces(elem, encoding, default_namespace=None): 2016516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru # identify namespaces used in this tree 2026516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 2036516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru # maps qnames to *encoded* prefix:local names 2046516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru qnames = {None: None} 2056516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 2066516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru # maps uri:s to prefixes 2076516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru namespaces = {} 2086516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if default_namespace: 2096516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru namespaces[default_namespace] = "" 2106516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 2116516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru def encode(text): 2126516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru return text.encode(encoding) 2136516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 2146516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru def add_qname(qname): 2156516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru # calculate serialized qname representation 2166516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru try: 2176516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if qname[:1] == "{": 2186516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru uri, tag = qname[1:].split("}", 1) 2196516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru prefix = namespaces.get(uri) 2206516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if prefix is None: 2216516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru prefix = _namespace_map.get(uri) 2226516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if prefix is None: 2236516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru prefix = "ns%d" % len(namespaces) 2246516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if prefix != "xml": 2256516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru namespaces[uri] = prefix 2266516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if prefix: 2276516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru qnames[qname] = encode("%s:%s" % (prefix, tag)) 2286516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru else: 2296516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru qnames[qname] = encode(tag) # default element 2306516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru else: 2316516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if default_namespace: 2326516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru # FIXME: can this be handled in XML 1.0? 2336516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru raise ValueError( 2346516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru "cannot use non-qualified names with " 2356516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru "default_namespace option" 2366516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru ) 2376516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru qnames[qname] = encode(qname) 2386516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru except TypeError: 2396516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru _raise_serialization_error(qname) 2406516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 2416516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru # populate qname and namespaces table 2426516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru try: 2436516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru iterate = elem.iter 2446516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru except AttributeError: 2456516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru iterate = elem.getiterator # cET compatibility 2466516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru for elem in iterate(): 2476516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru tag = elem.tag 2486516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if isinstance(tag, QName) and tag.text not in qnames: 2496516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru add_qname(tag.text) 2506516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru elif isinstance(tag, basestring): 2516516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if tag not in qnames: 2526516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru add_qname(tag) 2536516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru elif tag is not None and tag is not Comment and tag is not PI: 2546516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru _raise_serialization_error(tag) 2556516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru for key, value in elem.items(): 2566516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if isinstance(key, QName): 2576516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru key = key.text 2586516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if key not in qnames: 2596516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru add_qname(key) 2606516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if isinstance(value, QName) and value.text not in qnames: 2616516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru add_qname(value.text) 2626516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru text = elem.text 2636516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if isinstance(text, QName) and text.text not in qnames: 2646516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru add_qname(text.text) 2656516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru return qnames, namespaces 2666516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 2676516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Querudef to_html_string(element, encoding=None): 2686516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru class dummy: 2696516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru pass 2706516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru data = [] 2716516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru file = dummy() 2726516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru file.write = data.append 2736516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru write_html(ElementTree(element).getroot(),file,encoding) 2746516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru return "".join(data) 275