cpython/Doc/tools/sgmlconv/esistools.py

95 lines
2.7 KiB
Python

"""Miscellaneous utility functions useful for dealing with ESIS streams."""
__version__ = '$Revision$'
import re
import string
import sys
import xml.dom.core
import xml.dom.esis_builder
_data_rx = re.compile(r"[^\\][^\\]*")
def decode(s):
r = ''
while s:
m = _data_rx.match(s)
if m:
r = r + m.group()
s = s[len(m.group()):]
elif s[1] == "\\":
r = r + "\\"
s = s[2:]
elif s[1] == "n":
r = r + "\n"
s = s[2:]
else:
raise ValueError, "can't handle " + `s`
return r
_charmap = {}
for c in map(chr, range(256)):
_charmap[c] = c
_charmap["\n"] = r"\n"
_charmap["\\"] = r"\\"
del c
def encode(s):
return string.join(map(_charmap.get, s), '')
class ExtendedEsisBuilder(xml.dom.esis_builder.EsisBuilder):
def __init__(self, *args, **kw):
self.__empties = {}
self.__is_empty = 0
apply(xml.dom.esis_builder.EsisBuilder.__init__, (self,) + args, kw)
self.fragment = self.document.createDocumentFragment()
def feed(self, data):
for line in string.split(data, '\n'):
if not line:
break
event = line[0]
text = line[1:]
if event == '(':
element = self.document.createElement(text, self.attr_store)
self.attr_store = {}
self.push(element)
if self.__is_empty:
self.__empties[text] = text
self.__is_empty = 0
elif event == ')':
self.pop()
elif event == 'A':
l = re.split(' ', text, 2)
name = l[0]
value = decode(l[2])
self.attr_store[name] = value
elif event == '-':
text = self.document.createText(decode(text))
self.push(text)
elif event == 'C':
return
elif event == 'e':
self.__is_empty = 1
else:
sys.stderr.write('Unknown event: %s\n' % line)
def push(self, node):
"Add node to current node and move to new node."
nodetype = node.get_nodeType()
if self.current_element:
self.current_element.insertBefore(node, None)
elif nodetype == xml.dom.core.TEXT_NODE:
if string.strip(node.get_nodeValue()):
self.fragment.appendChild(node)
else:
self.fragment.appendChild(node)
if nodetype == xml.dom.core.ELEMENT_NODE:
self.current_element = node
def get_empties(self):
return self.__empties.keys()