Make Element the default for new nodes.
[dom-editor.git] / Dome / support.py
blob3bd6ba5b6ec1e2ca357c793f39747ee5571a388f
1 import rox
3 import os, sys
4 import traceback
5 from Ft.Xml.Domlette import Node, implementation
6 from Ft.Xml import XMLNS_NAMESPACE
7 from Ft.Xml.Lib.Nss import GetAllNs
9 from string import find, lower, join
10 from socket import gethostbyaddr, gethostname
12 import re
13 entrefpattern = re.compile('&(\D\S+);')
15 def node_to_xml(node):
16 "Takes an XML node and returns an XML documentElement suitable for saving."
17 root = implementation.createDocument(None, 'root', None)
18 new = node.cloneNode(deep = 1)
19 new = root.importNode(new, deep = 1)
20 root.replaceChild(new, root.documentElement)
21 return root
23 def node_to_html(node):
24 "Takes an XML node and returns an HTML documentElement suitable for saving."
25 root = implementation.createHTMLDocument('HTML document')
26 def html(doc, node, html):
27 new = doc.importNode(node.cloneNode(deep = 0), deep = 0)
28 if node.nodeType == Node.ELEMENT_NODE:
29 for a in node.attributes:
30 new.setAttribute(a.localName, a.value)
31 for k in node.childNodes:
32 new.appendChild(html(doc, k, html))
33 return new
34 new = html(root, node, html)
35 root.replaceChild(new, root.documentElement)
36 return root
38 def send_to_file(data, path):
39 try:
40 file = open(path, 'wb')
41 try:
42 file.write(data)
43 finally:
44 file.close()
45 except:
46 rox.report_exception()
47 return 0
49 return 1
51 def import_with_ns(doc, node):
52 nss = GetAllNs(node)
54 node = doc.importNode(node, 1)
55 for ns in nss.keys():
56 if ns == 'xml':
57 continue
58 uri = nss[ns]
59 if ns or uri:
60 if ns is None:
61 ns = 'xmlns'
62 else:
63 ns = 'xmlns:' + ns
64 node.setAttributeNS(XMLNS_NAMESPACE, ns, uri)
65 return node
67 def fix_broken_html(data):
68 """Pre-parse the data before sending to tidy to fix really really broken
69 stuff (eg, MS Word output). Returns None if data is OK"""
70 if data.find('<o:p>') == -1:
71 return # Doesn't need fixing?
72 import re
73 data = data.replace('<o:p></o:p>', '')
74 data = re.sub('<!\[[^]]*\]>', '', data)
75 return data
77 def to_html_doc(data):
78 (r, w) = os.pipe()
79 child = os.fork()
80 #data = data.replace('&nbsp;', ' ')
81 #data = data.replace('&copy;', '(c)')
82 #data = data.replace('&auml;', '(auml)')
83 #data = data.replace('&ouml;', '(ouml)')
84 fixed = fix_broken_html(data)
85 if child == 0:
86 # We are the child
87 try:
88 os.close(r)
89 os.dup2(w, 1)
90 os.close(w)
91 if fixed:
92 tin = os.popen('tidy --force-output yes -q -utf8 -asxml 2>/dev/null', 'w')
93 else:
94 tin = os.popen('tidy --force-output yes -q -asxml 2>/dev/null', 'w')
95 tin.write(fixed or data)
96 tin.close()
97 finally:
98 os._exit(0)
99 os.close(w)
101 data = os.fdopen(r).read()
102 os.waitpid(child, 0)
104 return data
106 def parse_data(data, path):
107 """Convert and XML document into a DOM Document."""
108 from Ft.Xml.InputSource import InputSourceFactory
109 #from Ft.Xml.cDomlette import nonvalParse
110 from Ft.Xml.FtMiniDom import nonvalParse
111 isrc = InputSourceFactory()
113 try:
114 try:
115 print "Parsing (with entities)..."
116 doc = nonvalParse(isrc.fromString(data, path))
117 except:
118 print "Parse failed.. retry without entities..."
119 data = entrefpattern.sub('&amp;\\1;',data)
120 doc = nonvalParse(isrc.fromString(data, path))
121 except:
122 type, val, tb = sys.exc_info()
123 traceback.print_exception(type, val, tb)
124 print "parsing failed!"
125 print "Data was:"
126 print data
127 #rox.report_exception()
128 raise
129 else:
130 print "parse OK...",
131 return doc