diff --git a/direct/src/showbase/PythonUtil.py b/direct/src/showbase/PythonUtil.py
index 7759aa1016..a94f0b2220 100644
--- a/direct/src/showbase/PythonUtil.py
+++ b/direct/src/showbase/PythonUtil.py
@@ -51,6 +51,8 @@ import traceback
import __builtin__
from StringIO import StringIO
import marshal
+import ElementTree as ET
+from HTMLParser import HTMLParser
from direct.directutil import Verify
# Don't import libpandaexpressModules, which doesn't get built until
@@ -4050,6 +4052,64 @@ if __debug__:
assert unescapeHtmlString('as%32df') == 'as2df'
assert unescapeHtmlString('asdf%32') == 'asdf2'
+class HTMLStringToElements(HTMLParser):
+ def __init__(self, str, *a, **kw):
+ self._elements = []
+ self._elementStack = Stack()
+ HTMLParser.__init__(self, *a, **kw)
+ self.feed(str)
+ self.close()
+
+ def getElements(self):
+ return self._elements
+
+ def _handleNewElement(self, element):
+ if len(self._elementStack):
+ self._elementStack.top().append(element)
+ else:
+ self._elements.append(element)
+ self._elementStack.push(element)
+
+ def handle_starttag(self, tag, attrs):
+ kwArgs = {}
+ for name, value in attrs:
+ kwArgs[name] = value
+ el = ET.Element(tag, **kwArgs)
+ self._handleNewElement(el)
+
+ def handle_data(self, data):
+ # this ignores text outside of a tag
+ if len(self._elementStack):
+ self._elementStack.top().text = data
+
+ def handle_endtag(self, tag):
+ self._elementStack.pop()
+
+ def handle_comment(self, data):
+ comment = ET.Comment(data)
+ self._handleNewElement(comment)
+
+def str2elements(str):
+ return HTMLStringToElements(str).getElements()
+
+if __debug__:
+ s = ScratchPad()
+ assert len(str2elements('')) == 0
+ s.br = str2elements('
')
+ assert len(s.br) == 1
+ assert s.br[0].tag == 'br'
+ s.b = str2elements('
')
+ assert len(s.b) == 1
+ assert len(s.b[0].getchildren()) == 1
+ s.a = str2elements('test')
+ assert len(s.a) == 1
+ assert s.a[0].get('href') == '/'
+ assert s.a[0].text == 'test'
+ s.c = str2elements('')
+ assert len(s.c) == 1
+ assert s.c[0].text == 'testComment'
+ del s
+
import __builtin__
__builtin__.Functor = Functor
__builtin__.Stack = Stack