summaryrefslogtreecommitdiff
path: root/source/docbook.py
blob: 46687265d46216c57f92ecc0a96da8fd19980ebb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
import sys
import globals, node

class FilePathSorter:

    def __init__ (self, filepaths):
        self.filepaths = filepaths
        self.root = node.Root()

    def buildPaths (self):
        for filepath in self.filepaths:
            # NOTE: we assume that none of the file names begin with '/'.
            hier = filepath.split('/')
            curnode = self.root
            for _dir in hier[:-1]:
                temp = curnode.firstChildByName(_dir)
                if temp == None:
                    # new directory node.
                    curnode = curnode.appendElement(_dir)
                else:
                    # directory node already exists.
                    curnode = temp

            # append file as a content node.
            curnode.appendContent(hier[-1])
            
    def sortPaths (self):
        self.__sortNode(self.root)

    def __sortNode (self, _node):

        # sort the files based on the file-1st-directory-2nd rule.
        contents = {}
        elements = {}
        for child in _node.getChildNodes():
            if child.nodeType == node.NodeType.Content:
                contents[child.content] = child
            elif child.nodeType == node.NodeType.Element:
                elements[child.name] = child
                self.__sortNode(child)

        # build a new set of child node list.
        children = []

        # contents first.
        contentNames = contents.keys()
        contentNames.sort()
        for name in contentNames:
            children.append(contents[name])

        # elements next.
        elementNames = elements.keys()
        elementNames.sort()
        if _node.nodeType == node.NodeType.Element and _node.name == 'text':
            # 'swriter', 'scalc', 'simpress', 'sdraw', 'schart' are ranked higher in this order.
            l = ['swriter', 'scalc', 'simpress', 'sdraw', 'smath', 'schart']
            newElemNames = []
            for elem in l:
                if elem in elementNames:
                    pos = elementNames.index(elem)
                    poped = elementNames.pop(pos)
                    newElemNames.append(poped)
            newElemNames.extend(elementNames)
            elementNames = newElemNames

        for name in elementNames:
            children.append(elements[name])
        _node.setChildNodes(children)

    def sort (self):
        self.buildPaths()
        self.sortPaths()
        return self.getFilePaths()

    def getFilePaths (self):
        """Return a list of sorted file names."""
        self.filepaths = [] # empty the existing list first.
        self.__walkToContent(self.root)
        return self.filepaths

    def __walkToContent (self, _node):
        if _node.nodeType == node.NodeType.Content:
            s = _node.content
            n = _node.parent
            while n.nodeType == node.NodeType.Element:
                s = n.name + '/' + s
                n = n.parent
            self.filepaths.append(s)
        elif _node.nodeType == node.NodeType.Element or _node.nodeType == node.NodeType.Root:
            for child in _node.getChildNodes():
                self.__walkToContent(child)


def appendDocBookElement (src):
    if src.name == 'book':
        return src.appendElement('chapter')
    elif src.name == 'chapter':
        return src.appendElement('sect1')
    elif src.name == 'sect1':
        return src.appendElement('sect2')
    elif src.name == 'sect2':
        return src.appendElement('sect3')
    elif src.name == 'sect3':
        return src.appendElement('sect4')
    else:
        return None


class DocBookConverter:

    def __init__ (self, treeroot, xhproots):
        self.treeroot = treeroot
        self.xhproots = xhproots
        self.root = node.Root()

    def convert (self):
        book = self.root.appendElement('book')
        bookinfo = book.appendElement('bookinfo')
        title = bookinfo.appendElement('title')
        title.appendContent("OpenOffice.org Help")
        
        for section in self.treeroot.getChildNodes():
            self.__walk(section, book)

    def __walk (self, src, dest):
        # src element is either 'section' or 'content'.
        if src.name == 'section':
            title = src.getAttr('title')
            elem = appendDocBookElement(dest)
            elem.appendElement('title').appendContent(title)
            for child in src.getChildNodes():
                self.__walk(child, elem)
        elif src.name == 'content':
            # this element has 'title' and 'path' attributes, and has no more child nodes.
            title = src.getAttr('title')
            sect = appendDocBookElement(dest)
            sect.appendElement('title').appendContent(title)
            xhppath = src.getAttr('path')
            if self.xhproots.has_key(xhppath):
                self.__getContentFromXHP(xhppath, sect)
            else:
                sect.appendElement('para').appendContent('get content from ' + src.getAttr('path'))

    def __getContentFromXHP (self, xhppath, dest):
        xhproot = self.xhproots[xhppath]
        xhpbody = xhproot.firstChild().firstChildByName('body')
        for xhpelem in xhpbody.getChildNodes():
            self.__walkXHP(xhpelem, dest)

    def __walkXHP (self, src, dest):
        if src.nodeType == node.NodeType.Content:
            if len(src.content.strip()) > 0:
                dest.appendElement('warning').appendContent("unhandled content : '%s'"%src.content.strip())
            return

        if src.name == 'paragraph':
            para = dest.appendElement('para')
            para.appendContent(src.getContent())
        else:
            dest.appendElement('warning').appendContent("unhandled element '%s'"%src.name)


    def prettyPrint (self, fd):
        node.prettyPrint(fd, self.root)