PageRenderTime 61ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/formencode/rewritingparser.py

https://github.com/mofukuma/gae_onlinegamebase
Python | 169 lines | 157 code | 10 blank | 2 comment | 6 complexity | e4be4c239775353b07a3e2eae1af6622 MD5 | raw file
  1. import HTMLParser
  2. import re
  3. try:
  4. from html import escape
  5. except ImportError: # Python < 3.2
  6. from cgi import escape
  7. from htmlentitydefs import name2codepoint
  8. def html_quote(v):
  9. if v is None:
  10. return ''
  11. if hasattr(v, '__html__'):
  12. return v.__html__()
  13. if isinstance(v, basestring):
  14. return escape(v, True)
  15. if hasattr(v, '__unicode__'):
  16. v = unicode(v)
  17. else:
  18. v = str(v)
  19. return escape(v, True)
  20. class RewritingParser(HTMLParser.HTMLParser):
  21. listener = None
  22. skip_next = False
  23. def __init__(self):
  24. self._content = []
  25. HTMLParser.HTMLParser.__init__(self)
  26. def feed(self, data):
  27. self.data_is_str = isinstance(data, str)
  28. self.source = data
  29. self.lines = data.split('\n')
  30. self.source_pos = 1, 0
  31. if self.listener:
  32. self.listener.reset()
  33. HTMLParser.HTMLParser.feed(self, data)
  34. _entityref_re = re.compile('&([a-zA-Z][-.a-zA-Z\d]*);')
  35. _charref_re = re.compile('&#(\d+|[xX][a-fA-F\d]+);')
  36. def unescape(self, s):
  37. s = self._entityref_re.sub(self._sub_entityref, s)
  38. s = self._charref_re.sub(self._sub_charref, s)
  39. return s
  40. def _sub_entityref(self, match):
  41. name = match.group(1)
  42. if name not in name2codepoint:
  43. # If we don't recognize it, pass it through as though it
  44. # wasn't an entity ref at all
  45. return match.group(0)
  46. return unichr(name2codepoint[name])
  47. def _sub_charref(self, match):
  48. num = match.group(1)
  49. if num.lower().startswith('x'):
  50. num = int(num[1:], 16)
  51. else:
  52. num = int(num)
  53. return unichr(num)
  54. def handle_misc(self, whatever):
  55. self.write_pos()
  56. handle_charref = handle_misc
  57. handle_entityref = handle_misc
  58. handle_data = handle_misc
  59. handle_comment = handle_misc
  60. handle_decl = handle_misc
  61. handle_pi = handle_misc
  62. unknown_decl = handle_misc
  63. handle_endtag = handle_misc
  64. def write_tag(self, tag, attrs, startend=False):
  65. attr_text = ''.join(' %s="%s"' % (n, html_quote(v))
  66. for (n, v) in attrs if not n.startswith('form:'))
  67. if startend:
  68. attr_text += " /"
  69. self.write_text('<%s%s>' % (tag, attr_text))
  70. def skip_output(self):
  71. return False
  72. def write_pos(self):
  73. cur_line, cur_offset = self.getpos()
  74. if self.skip_output():
  75. self.source_pos = self.getpos()
  76. return
  77. if self.skip_next:
  78. self.skip_next = False
  79. self.source_pos = self.getpos()
  80. return
  81. if cur_line == self.source_pos[0]:
  82. self.write_text(
  83. self.lines[cur_line - 1][self.source_pos[1]:cur_offset])
  84. else:
  85. self.write_text(
  86. self.lines[self.source_pos[0] - 1][self.source_pos[1]:])
  87. self.write_text('\n')
  88. for i in range(self.source_pos[0] + 1, cur_line):
  89. self.write_text(self.lines[i - 1])
  90. self.write_text('\n')
  91. self.write_text(self.lines[cur_line - 1][:cur_offset])
  92. self.source_pos = self.getpos()
  93. def write_text(self, text):
  94. self._content.append(text)
  95. def has_attr(self, attr, name):
  96. for a in attr:
  97. if a[0].lower() == name:
  98. return True
  99. return False
  100. def get_attr(self, attr, name, default=None):
  101. for a in attr:
  102. if a[0].lower() == name:
  103. return a[1]
  104. return default
  105. def set_attr(self, attr, name, value):
  106. for i, a in enumerate(attr):
  107. if a[0].lower() == name:
  108. attr[i] = (name, value)
  109. return
  110. attr.append((name, value))
  111. def del_attr(self, attr, name):
  112. for i, a in enumerate(attr):
  113. if a[0].lower() == name:
  114. del attr[i]
  115. break
  116. def add_class(self, attr, class_name):
  117. current = self.get_attr(attr, 'class', '')
  118. new = current + ' ' + class_name
  119. self.set_attr(attr, 'class', new.strip())
  120. def text(self):
  121. try:
  122. return self._text
  123. except AttributeError:
  124. raise Exception(
  125. "You must .close() a parser instance before getting "
  126. "the text from it")
  127. def _get_text(self):
  128. try:
  129. return ''.join(
  130. t for t in self._content if not isinstance(t, tuple))
  131. except UnicodeDecodeError, e:
  132. if self.data_is_str:
  133. e.reason += (
  134. " the form was passed in as an encoded string, but"
  135. " some data or error messages were unicode strings;"
  136. " the form should be passed in as a unicode string")
  137. else:
  138. e.reason += (
  139. " the form was passed in as an unicode string, but"
  140. " some data or error message was an encoded string;"
  141. " the data and error messages should be passed in as"
  142. " unicode strings")
  143. raise