comparison genshi/output.py @ 784:67d324a62cc0 experimental-match-fastpaths

update to 0.5.x branch, up through r907 don't know how this fits in with SoC work, but I wanted to do due diligence and keep this branch working in case it someday gets considered for trunk
author aflett
date Mon, 21 Jul 2008 23:17:52 +0000
parents 8f2c7023af94
children
comparison
equal deleted inserted replaced
724:8f2c7023af94 784:67d324a62cc0
112 'html', '-//W3C//DTD XHTML 1.0 Frameset//EN', 112 'html', '-//W3C//DTD XHTML 1.0 Frameset//EN',
113 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd' 113 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd'
114 ) 114 )
115 XHTML = XHTML_STRICT 115 XHTML = XHTML_STRICT
116 116
117 XHTML11 = (
118 'html', '-//W3C//DTD XHTML 1.1//EN',
119 'http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd'
120 )
121
117 SVG_FULL = ( 122 SVG_FULL = (
118 'svg', '-//W3C//DTD SVG 1.1//EN', 123 'svg', '-//W3C//DTD SVG 1.1//EN',
119 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd' 124 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'
120 ) 125 )
121 SVG_BASIC = ( 126 SVG_BASIC = (
133 declaration for the specified name. 138 declaration for the specified name.
134 139
135 The following names are recognized in this version: 140 The following names are recognized in this version:
136 * "html" or "html-strict" for the HTML 4.01 strict DTD 141 * "html" or "html-strict" for the HTML 4.01 strict DTD
137 * "html-transitional" for the HTML 4.01 transitional DTD 142 * "html-transitional" for the HTML 4.01 transitional DTD
138 * "html-transitional" for the HTML 4.01 frameset DTD 143 * "html-frameset" for the HTML 4.01 frameset DTD
139 * "html5" for the ``DOCTYPE`` proposed for HTML5 144 * "html5" for the ``DOCTYPE`` proposed for HTML5
140 * "xhtml" or "xhtml-strict" for the XHTML 1.0 strict DTD 145 * "xhtml" or "xhtml-strict" for the XHTML 1.0 strict DTD
141 * "xhtml-transitional" for the XHTML 1.0 transitional DTD 146 * "xhtml-transitional" for the XHTML 1.0 transitional DTD
142 * "xhtml-frameset" for the XHTML 1.0 frameset DTD 147 * "xhtml-frameset" for the XHTML 1.0 frameset DTD
148 * "xhtml11" for the XHTML 1.1 DTD
143 * "svg" or "svg-full" for the SVG 1.1 DTD 149 * "svg" or "svg-full" for the SVG 1.1 DTD
144 * "svg-basic" for the SVG Basic 1.1 DTD 150 * "svg-basic" for the SVG Basic 1.1 DTD
145 * "svg-tiny" for the SVG Tiny 1.1 DTD 151 * "svg-tiny" for the SVG Tiny 1.1 DTD
146 152
147 :param name: the name of the ``DOCTYPE`` 153 :param name: the name of the ``DOCTYPE``
155 'html-frameset': DocType.HTML_FRAMESET, 161 'html-frameset': DocType.HTML_FRAMESET,
156 'html5': cls.HTML5, 162 'html5': cls.HTML5,
157 'xhtml': cls.XHTML, 'xhtml-strict': cls.XHTML_STRICT, 163 'xhtml': cls.XHTML, 'xhtml-strict': cls.XHTML_STRICT,
158 'xhtml-transitional': cls.XHTML_TRANSITIONAL, 164 'xhtml-transitional': cls.XHTML_TRANSITIONAL,
159 'xhtml-frameset': cls.XHTML_FRAMESET, 165 'xhtml-frameset': cls.XHTML_FRAMESET,
166 'xhtml11': cls.XHTML11,
160 'svg': cls.SVG, 'svg-full': cls.SVG_FULL, 167 'svg': cls.SVG, 'svg-full': cls.SVG_FULL,
161 'svg-basic': cls.SVG_BASIC, 168 'svg-basic': cls.SVG_BASIC,
162 'svg-tiny': cls.SVG_TINY 169 'svg-tiny': cls.SVG_TINY
163 }.get(name.lower()) 170 }.get(name.lower())
164 get = classmethod(get) 171 get = classmethod(get)
278 QName('pre'), QName('http://www.w3.org/1999/xhtml}pre'), 285 QName('pre'), QName('http://www.w3.org/1999/xhtml}pre'),
279 QName('textarea'), QName('http://www.w3.org/1999/xhtml}textarea') 286 QName('textarea'), QName('http://www.w3.org/1999/xhtml}textarea')
280 ]) 287 ])
281 288
282 def __init__(self, doctype=None, strip_whitespace=True, 289 def __init__(self, doctype=None, strip_whitespace=True,
283 namespace_prefixes=None): 290 namespace_prefixes=None, drop_xml_decl=True):
284 super(XHTMLSerializer, self).__init__(doctype, False) 291 super(XHTMLSerializer, self).__init__(doctype, False)
285 self.filters = [EmptyTagFilter()] 292 self.filters = [EmptyTagFilter()]
286 if strip_whitespace: 293 if strip_whitespace:
287 self.filters.append(WhitespaceFilter(self._PRESERVE_SPACE)) 294 self.filters.append(WhitespaceFilter(self._PRESERVE_SPACE))
288 namespace_prefixes = namespace_prefixes or {} 295 namespace_prefixes = namespace_prefixes or {}
289 namespace_prefixes['http://www.w3.org/1999/xhtml'] = '' 296 namespace_prefixes['http://www.w3.org/1999/xhtml'] = ''
290 self.filters.append(NamespaceFlattener(prefixes=namespace_prefixes)) 297 self.filters.append(NamespaceFlattener(prefixes=namespace_prefixes))
291 if doctype: 298 if doctype:
292 self.filters.append(DocTypeInserter(doctype)) 299 self.filters.append(DocTypeInserter(doctype))
300 self.drop_xml_decl = drop_xml_decl
293 301
294 def __call__(self, stream): 302 def __call__(self, stream):
295 boolean_attrs = self._BOOLEAN_ATTRS 303 boolean_attrs = self._BOOLEAN_ATTRS
296 empty_elems = self._EMPTY_ELEMS 304 empty_elems = self._EMPTY_ELEMS
297 have_doctype = False 305 drop_xml_decl = self.drop_xml_decl
306 have_decl = have_doctype = False
298 in_cdata = False 307 in_cdata = False
299 308
300 for filter_ in self.filters: 309 for filter_ in self.filters:
301 stream = filter_(stream) 310 stream = filter_(stream)
302 for kind, data, pos in stream: 311 for kind, data, pos in stream:
344 buf.append(' "%s"') 353 buf.append(' "%s"')
345 buf.append('>\n') 354 buf.append('>\n')
346 yield Markup(u''.join(buf)) % filter(None, data) 355 yield Markup(u''.join(buf)) % filter(None, data)
347 have_doctype = True 356 have_doctype = True
348 357
358 elif kind is XML_DECL and not have_decl and not drop_xml_decl:
359 version, encoding, standalone = data
360 buf = ['<?xml version="%s"' % version]
361 if encoding:
362 buf.append(' encoding="%s"' % encoding)
363 if standalone != -1:
364 standalone = standalone and 'yes' or 'no'
365 buf.append(' standalone="%s"' % standalone)
366 buf.append('?>\n')
367 yield Markup(u''.join(buf))
368 have_decl = True
369
349 elif kind is START_CDATA: 370 elif kind is START_CDATA:
350 yield Markup('<![CDATA[') 371 yield Markup('<![CDATA[')
351 in_cdata = True 372 in_cdata = True
352 373
353 elif kind is END_CDATA: 374 elif kind is END_CDATA:
471 492
472 >>> elem = tag.div(Markup('<a href="foo">Hello &amp; Bye!</a><br/>')) 493 >>> elem = tag.div(Markup('<a href="foo">Hello &amp; Bye!</a><br/>'))
473 >>> print elem.generate().render(TextSerializer) 494 >>> print elem.generate().render(TextSerializer)
474 <a href="foo">Hello &amp; Bye!</a><br/> 495 <a href="foo">Hello &amp; Bye!</a><br/>
475 496
476 You can use the `strip_markup` to change this behavior, so that tags and 497 You can use the ``strip_markup`` to change this behavior, so that tags and
477 entities are stripped from the output (or in the case of entities, 498 entities are stripped from the output (or in the case of entities,
478 replaced with the equivalent character): 499 replaced with the equivalent character):
479 500
480 >>> print elem.generate().render(TextSerializer, strip_markup=True) 501 >>> print elem.generate().render(TextSerializer, strip_markup=True)
481 Hello & Bye! 502 Hello & Bye!
482 """ 503 """
483 504
484 def __init__(self, strip_markup=False): 505 def __init__(self, strip_markup=False):
506 """Create the serializer.
507
508 :param strip_markup: whether markup (tags and encoded characters) found
509 in the text should be removed
510 """
485 self.strip_markup = strip_markup 511 self.strip_markup = strip_markup
486 512
487 def __call__(self, stream): 513 def __call__(self, stream):
488 strip_markup = self.strip_markup 514 strip_markup = self.strip_markup
489 for event in stream: 515 for event in stream:
Copyright (C) 2012-2017 Edgewall Software