Package tdi :: Package markup :: Package soup :: Module dtd
[frames] | no frames]

Source Code for Module tdi.markup.soup.dtd

  1  # -*- coding: ascii -*- 
  2  r""" 
  3  :Copyright: 
  4   
  5   Copyright 2006 - 2015 
  6   Andr\xe9 Malo or his licensors, as applicable 
  7   
  8  :License: 
  9   
 10   Licensed under the Apache License, Version 2.0 (the "License"); 
 11   you may not use this file except in compliance with the License. 
 12   You may obtain a copy of the License at 
 13   
 14       http://www.apache.org/licenses/LICENSE-2.0 
 15   
 16   Unless required by applicable law or agreed to in writing, software 
 17   distributed under the License is distributed on an "AS IS" BASIS, 
 18   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 19   See the License for the specific language governing permissions and 
 20   limitations under the License. 
 21   
 22  ================ 
 23   DTD Collection 
 24  ================ 
 25   
 26  This module provides a collection of DTD query classes to be used with 
 27  the soup parser. 
 28  """ 
 29  if __doc__: 
 30      # pylint: disable = redefined-builtin 
 31      __doc__ = __doc__.encode('ascii').decode('unicode_escape') 
 32  __author__ = r"Andr\xe9 Malo".encode('ascii').decode('unicode_escape') 
 33  __docformat__ = "restructuredtext en" 
 34   
 35  from ... import interfaces as _interfaces 
 36   
 37   
38 -class HTMLDTD(object):
39 """ 40 Query class for the HTML DTD 41 42 :IVariables: 43 `_cdata` : ``dict`` 44 Dict of CDATA elements (for speed lookup) 45 46 `_optional` : ``dict`` 47 Dict of optional elements (for speed lookup) 48 49 `_empty` : ``dict`` 50 Dict of empty elements (for speed lookup) 51 """ 52 __implements__ = [_interfaces.DTDInterface] 53 54 #: List of known empty elements 55 #: 56 #: :Type: ``tuple`` 57 _EMPTY = ('app', 'area', 'base', 'basefont', 'bgsound', 'br', 'col', 58 'command', 'embed', 'frame', 'hr', 'img', 'input', 'isindex', 59 'keygen', 'link', 'meta', 'nextid', 'param', 'sound', 'source', 60 'spacer', 'track', 'wbr') 61 62 #: List of CDATA elements 63 #: 64 #: plaintext has been specified differently over time. Sometimes it's 65 #: finishable, sometimes not. I let it be finishable here. You shouldn't 66 #: use it anyway. 67 #: 68 #: :Type: ``tuple`` 69 _CDATA = ('listing', 'plaintext', 'script', 'style', 'textarea', 'xmp') 70 71 # helper 72 _intable = ('caption', 'col', 'colgroup', 'tbody', 'thead', 'tfoot') 73 74 #: List of elements with optional end tag. This list consists 75 #: of (name, forbidden-list) pairs. 76 #: 77 #: :Type: ``tuple`` 78 _OPTIONAL = tuple({ 79 # pylint: disable = bad-whitespace 80 81 'html': ('html',), 82 'head': ('html', 'body', 'head',), 83 'body': ('html', 'body', 'head',), 84 'li': ('li',), 85 'dt': ('dt', 'dd',), 86 'dd': ('dt', 'dd',), 87 'p': ('address', 'article', 'aside', 'blockquote', 'body', 88 'dd', 'dir', 'div', 'dl', 'dt', 'fieldset', 'footer', 89 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 90 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 91 'isindex', 'layer', 'li', 'listing', 'map', 'marquee', 92 'menu', 'multicol', 'nav', 'noframes', 'ol', 'p', 93 'plaintext', 'pre', 'section', 'table', 'td', 'th', 94 'tr', 'ul', 'xmp') + _intable, 95 'rt': ('rt', 'rp',), 96 'rp': ('rt', 'rp',), 97 'optgroup': ('optgroup',), 98 'option': ('option', 'optgroup',), 99 'colgroup': _intable + ('td', 'th', 'tr',), 100 'caption': _intable + ('td', 'th', 'tr',), 101 'thead': _intable, 102 'tbody': _intable, 103 'tfoot': _intable, 104 'tr': _intable + ('tr',), 105 'td': _intable + ('td', 'th', 'tr',), 106 'th': _intable + ('td', 'th', 'tr',), 107 }.items()) 108 del _intable 109
110 - def __init__(self):
111 """ Initialization """ 112 dict_ = dict 113 optional = dict_([ 114 (name, dict_([ 115 (item, None) for item in forbidden 116 ]).__contains__) 117 for name, forbidden in self._OPTIONAL 118 ]).get 119 if self.__class__ == HTMLDTD: 120 self.cdata = dict_([ 121 (item, None) for item in self._CDATA 122 ]).__contains__ 123 self.empty = empty = dict_([ 124 (item, None) for item in self._EMPTY 125 ]).__contains__ 126 127 def nestable(outer, inner): 128 """ :See: `tdi.interfaces.DTDInterface.nestable` """ 129 opt = optional(outer) 130 if opt is not None: 131 return not opt(inner) 132 elif empty(outer): 133 return False 134 return True
135 self.nestable = nestable 136 else: 137 self._empty = dict_([ 138 (item, None) for item in self._EMPTY 139 ]).__contains__ 140 self._cdata = dict_([ 141 (item, None) for item in self._CDATA 142 ]).__contains__ 143 self._optional = optional
144
145 - def cdata(self, name):
146 """ :See: `tdi.interfaces.DTDInterface.cdata` """ 147 # pylint: disable = method-hidden 148 149 return self._cdata(name)
150
151 - def nestable(self, outer, inner):
152 """ :See: `tdi.interfaces.DTDInterface.nestable` """ 153 # pylint: disable = method-hidden 154 155 opt = self._optional(outer) 156 if opt is not None: 157 return not opt(inner) 158 elif self._empty(outer): 159 return False 160 161 return True
162
163 - def empty(self, name):
164 """ :See: `tdi.interfaces.DTDInterface.empty` """ 165 # pylint: disable = method-hidden 166 167 return self._empty(name)
168 169
170 -class XMLDTD(object):
171 """ 172 XML DTD query class 173 174 This class effectively defines every wellformed XML valid. 175 """ 176 __implements__ = [_interfaces.DTDInterface] 177 178 # pylint: disable = unused-argument 179
180 - def cdata(self, name):
181 """ :See: `DTDInterface` """ 182 return False
183
184 - def nestable(self, outer, inner):
185 """ :See: `DTDInterface` """ 186 return True
187
188 - def empty(self, name):
189 """ :See: `DTDInterface` """ 190 return False
191