# This patch is for MoinMoin 1.9
#   Copyright 2009, Franklin Piat - License GPLv2 or Later
#   Copyright 2009, Stefano Zacchiroli
--- text_docbook.py.orig	2009-10-06 23:10:41.000000000 +0200
+++ text_docbook.py	2009-10-08 23:08:59.000000000 +0200
@@ -12,8 +12,11 @@
 import os
 
 from xml.dom import getDOMImplementation
-from xml.dom.ext.reader import Sax
-from xml.dom.ext import Node
+try:
+    from Ft.Xml.Domlette import NonvalidatingReader as Reader
+except ImportError:
+    raise InternalError("You need to install 4suite to use the DocBook formatter.")
+from xml.dom import Node
 
 from MoinMoin.formatter import FormatterBase
 from MoinMoin import wikiutil
@@ -28,10 +31,7 @@
 class InternalError(CompositeError):
     pass
 
-try:
-    dom = getDOMImplementation("4DOM")
-except ImportError:
-    raise InternalError("You need to install 4suite to use the DocBook formatter.")
+dom = getDOMImplementation()
 
 
 class Formatter(FormatterBase):
@@ -72,15 +72,15 @@
         self.cur = None
 
     def startDocument(self, pagename):
-        self.doc = dom.createDocument(None, self.doctype, dom.createDocumentType(
-            self.doctype, "-//OASIS//DTD DocBook XML V4.4//EN",
-            "http://www.docbook.org/xml/4.4/docbookx.dtd"))
+        self.doc = dom.createDocument(None, unicode(self.doctype), dom.createDocumentType(
+            unicode(self.doctype), u"-//OASIS//DTD DocBook XML V4.4//EN",
+            u"http://www.docbook.org/xml/4.4/docbookx.dtd"))
 
         self.title = pagename
         self.root = self.doc.documentElement
 
         if not self.include_kludge and self.doctype == "article":
-            info = self.doc.createElement("articleinfo")
+            info = self.doc.createElement(u"articleinfo")
             self.root.appendChild(info)
             self._addTitleElement(self.title, targetNode=info)
             self._addRevisionHistory(targetNode=info)
@@ -101,7 +101,7 @@
         return ""
 
     def endDocument(self):
-        from xml.dom.ext import PrettyPrint, Print
+        from Ft.Xml.Domlette import PrettyPrint, Print
         import StringIO
 
         f = StringIO.StringIO()
@@ -125,7 +125,7 @@
                 self.cur.lastChild.nodeValue = self.cur.lastChild.nodeValue + srcText
             else:
                 # We create a new cdata section
-                self.cur.appendChild(self.doc.createCDATASection(srcText))
+                self.cur.appendChild(self.doc.createCDATASection(unicode(srcText)))
 
         elif self.cur.nodeName in self.wrap_text_in_para:
             """
@@ -133,13 +133,13 @@
             and not create a new one. Another question is if we should add a space?
             """
             if self.cur.lastChild is not None and self.cur.lastChild.nodeName == 'para':
-                self.cur.lastChild.appendChild(self.doc.createTextNode(srcText))
+                self.cur.lastChild.appendChild(self.doc.createTextNode(unicode(srcText)))
             else:
                 self.paragraph(1)
                 self.text(text)
                 self.paragraph(0)
         else:
-            self.cur.appendChild(self.doc.createTextNode(srcText))
+            self.cur.appendChild(self.doc.createTextNode(unicode(srcText)))
         return ""
 
     def heading(self, on, depth, **kw):
@@ -159,11 +159,11 @@
                     if self.cur.nodeName == "section":
                         self.cur = self.cur.parentNode
 
-            section = self.doc.createElement("section")
+            section = self.doc.createElement(u"section")
             self.cur.appendChild(section)
             self.cur = section
 
-            title = self.doc.createElement("title")
+            title = self.doc.createElement(u"title")
             self.cur.appendChild(title)
             self.cur = title
             self.curdepth = depth
@@ -446,22 +446,22 @@
     def image(self, src=None, **kw):
         if src:
             kw['src'] = src
-        media = self.doc.createElement('inlinemediaobject')
+        media = self.doc.createElement(u"inlinemediaobject")
 
-        imagewrap = self.doc.createElement('imageobject')
+        imagewrap = self.doc.createElement(u"imageobject")
         media.appendChild(imagewrap)
 
-        image = self.doc.createElement('imagedata')
+        image = self.doc.createElement(u"imagedata")
         if kw.has_key('src'):
             src = kw['src']
             if src.startswith("/"):
                 # convert to absolute path:
                 src = self.request.url_root + src
-            image.setAttribute('fileref', src)
+            image.setAttribute(u"fileref", unicode(src))
         if kw.has_key('width'):
-            image.setAttribute('width', str(kw['width']))
+            image.setAttribute(u"width", unicode(kw['width']))
         if kw.has_key('height'):
-            image.setAttribute('depth', str(kw['height']))
+            image.setAttribute(u"depth", unicode(kw['height']))
         imagewrap.appendChild(image)
 
         # Look for any suitable title, order is important.
@@ -471,7 +471,7 @@
                 title = kw[a]
                 break
         if title:
-            txtcontainer = self.doc.createElement('textobject')
+            txtcontainer = self.doc.createElement(u"textobject")
             self._addTextElem(txtcontainer, "phrase", title)
             media.appendChild(txtcontainer)
 
@@ -480,7 +480,7 @@
 
     def transclusion(self, on, **kw):
         # TODO, see text_html formatter
-        self._emitComment('transclusion is not implemented in DocBook formatter')
+        self._emitComment(u"transclusion is not implemented in DocBook formatter")
         return ""
 
     def transclusion_param(self, **kw):
@@ -543,7 +543,7 @@
 
     def code_line(self, on):
         if on:
-            self.cur.appendChild(self.doc.createTextNode('\n'))
+            self.cur.appendChild(self.doc.createTextNode(u"\n"))
         return ''
 
     def code_token(self, on, tok_type):
@@ -603,7 +603,7 @@
             self._emitComment("The macro %s doesn't work with the DocBook formatter." % name)
 
         elif name == "FootNote":
-            footnote = self.doc.createElement('footnote')
+            footnote = self.doc.createElement(u"footnote")
             self._addTextElem(footnote, "para", str(args))
             self.cur.appendChild(footnote)
 
@@ -613,7 +613,7 @@
                 self.paragraph(0)
             text = FormatterBase.macro(self, macro_obj, name, args)
             if text.strip():
-                self._copyExternalNodes(Sax.FromXml(text).documentElement.childNodes, exclude=excludes)
+                self._copyExternalNodes(Reader.parseString(text).documentElement.childNodes, exclude=excludes)
             if was_in_para:
                 self.paragraph(1)
 
@@ -622,7 +622,7 @@
             if text:
                 from xml.parsers.expat import ExpatError
                 try:
-                    xml_dom = Sax.FromXml(text).documentElement.childNodes
+                    xml_dom = Reader.parseString(text).documentElement.childNodes
                     self._copyExternalNodes(xml_dom, exclude=excludes)
                 except ExpatError:
                     self._emitComment("The macro %s caused an error and should be blacklisted. It returned the data '%s' which caused the docbook-formatter to choke. Please file a bug." % (name, text))
@@ -646,15 +646,15 @@
 
     def _emitComment(self, text):
         text = text.replace("--", "- -") # There cannot be "--" in XML comment
-        self.cur.appendChild(self.doc.createComment(text))
+        self.cur.appendChild(self.doc.createComment(unicode(text)))
 
     def _handleNode(self, name, on, attributes=()):
         if on:
-            node = self.doc.createElement(name)
+            node = self.doc.createElement(unicode(name))
             self.cur.appendChild(node)
             if len(attributes) > 0:
                 for name, value in attributes:
-                    node.setAttribute(name, value)
+                    node.setAttribute(unicode(name), unicode(value))
             self.cur = node
         else:
             """
@@ -744,8 +744,8 @@
         with the nodeValue of text. The new element is then added as a child
         to the element target.
         """
-        newElement = self.doc.createElement(elemName)
-        newElement.appendChild(self.doc.createTextNode(text))
+        newElement = self.doc.createElement(unicode(elemName))
+        newElement.appendChild(self.doc.createTextNode(unicode(text)))
         target.appendChild(newElement)
 
 
@@ -769,14 +769,14 @@
         log = editlog.EditLog(self.request, rootpagename=self.title)
         user_cache = {}
 
-        history = self.doc.createElement("revhistory")
+        history = self.doc.createElement(u"revhistory")
 
         # read in the complete log of this page
         for line in log.reverse():
             if not line.action in ('SAVE', 'SAVENEW', 'SAVE/REVERT', 'SAVE/RENAME', ):
                 #Let's ignore adding of attachments
                 continue
-            revision = self.doc.createElement("revision")
+            revision = self.doc.createElement(u"revision")
 
             # Revision number (without preceeding zeros)
             self._addTextElem(revision, "revnumber", line.rev.lstrip('0'))
@@ -953,19 +953,19 @@
         self.formatter = formatter
         self.doc = doc
 
-        self.tableNode = self.doc.createElement('informaltable')
+        self.tableNode = self.doc.createElement(u"informaltable")
         parent.appendChild(self.tableNode)
         self.colWidths = {}
-        self.tgroup = self.doc.createElement('tgroup')
+        self.tgroup = self.doc.createElement(u"tgroup")
         # Bug in yelp, the two lines below don't affect rendering
-        #self.tgroup.setAttribute('rowsep', '1')
-        #self.tgroup.setAttribute('colsep', '1')
+        #self.tgroup.setAttribute(u"rowsep", u"1")
+        #self.tgroup.setAttribute(u"colsep", u"1")
         self.curColumn = 0
         self.maxColumn = 0
         self.row = None
         self.tableNode.appendChild(self.tgroup)
 
-        self.tbody = self.doc.createElement('tbody') # Note: This gets appended in finalizeTable
+        self.tbody = self.doc.createElement(u"tbody") # Note: This gets appended in finalizeTable
 
     def finalizeTable(self):
         """Calculates the final width of the whole table and the width of each
@@ -976,21 +976,21 @@
         A lot of the information is gathered from the style attributes passed
         to the functions
         """
-        self.tgroup.setAttribute('cols', str(self.maxColumn))
+        self.tgroup.setAttribute(u"cols", unicode(self.maxColumn))
         for colnr in range(0, self.maxColumn):
-            colspecElem = self.doc.createElement('colspec')
-            colspecElem.setAttribute('colname', 'col_%s' % str(colnr))
+            colspecElem = self.doc.createElement(u"colspec")
+            colspecElem.setAttribute(u"colname", u"col_%s" % unicode(colnr))
             if self.colWidths.has_key(str(colnr)) and self.colWidths[str(colnr)] != "1*":
-                colspecElem.setAttribute('colwidth', self.colWidths[str(colnr)])
+                colspecElem.setAttribute(u"colwidth", unicode(self.colWidths[str(colnr)]))
             self.tgroup.appendChild(colspecElem)
         self.tgroup.appendChild(self.tbody)
         return self.tableNode.parentNode
 
     def addRow(self, argsdict={}):
         self.curColumn = 0
-        self.row = self.doc.createElement('row')
+        self.row = self.doc.createElement(u"row")
         # Bug in yelp, doesn't affect the outcome.
-        self.row.setAttribute("rowsep", "1") #Rows should have lines between them
+        self.row.setAttribute(u"rowsep", u"1") #Rows should have lines between them
         self.tbody.appendChild(self.row)
         return self.row
 
@@ -998,9 +998,9 @@
         if 'style' in argsdict:
             argsdict.update(self.formatter._convertStylesToDict(argsdict['style'].strip('"')))
 
-        cell = self.doc.createElement('entry')
-        cell.setAttribute('rowsep', '1')
-        cell.setAttribute('colsep', '1')
+        cell = self.doc.createElement(u"entry")
+        cell.setAttribute(u"rowsep", u"1")
+        cell.setAttribute(u"colsep", u"1")
 
         self.row.appendChild(cell)
         self._handleSimpleCellAttributes(cell, argsdict)
@@ -1027,8 +1027,8 @@
             return 1
         assert(element.nodeName == "entry")
         extracols = int(argsdict['colspan'].strip('"')) - 1
-        element.setAttribute('namest', "col_" + str(self.curColumn))
-        element.setAttribute('nameend', "col_" + str(self.curColumn + extracols))
+        element.setAttribute(u"namest", u"col_" + unicode(self.curColumn))
+        element.setAttribute(u"nameend", u"col_" + unicode(self.curColumn + extracols))
         return 1 + extracols
 
     def _handleSimpleCellAttributes(self, element, argsdict={}):
@@ -1042,12 +1042,12 @@
 
         if argsdict.has_key('rowspan'):
             extrarows = int(argsdict['rowspan'].strip('"')) - 1
-            element.setAttribute('morerows', str(extrarows))
+            element.setAttribute(u"morerows", unicode(extrarows))
 
         if argsdict.has_key('align'):
             value = argsdict['align'].strip('"')
             if value in safe_values_for['align']:
-                element.setAttribute('align', value)
+                element.setAttribute(u"align", unicode(value))
             else:
                 self.formatter._emitComment("Alignment %s not supported" % value)
                 pass
@@ -1055,7 +1055,7 @@
         if argsdict.has_key('valign'):
             value = argsdict['valign'].strip('"')
             if value in safe_values_for['valign']:
-                element.setAttribute('valign', value)
+                element.setAttribute(u"valign", unicode(value))
             else:
                 self.formatter._emitComment("Vertical alignment %s not supported" % value)
                 pass
