The branch, odt2lyx, has been updated.

- Log -----------------------------------------------------------------

commit c7ce5c8e36c3df6937cf80dc78563daa62e83a66
Author: Prannoy Pilligundla <[email protected]>
Date:   Mon Jul 21 17:35:30 2014 +0530

    Changed the code structure and documented everything

diff --git a/odt2lyx/parseodt.py b/odt2lyx/parseodt.py
index 43e6036..73c587d 100644
--- a/odt2lyx/parseodt.py
+++ b/odt2lyx/parseodt.py
@@ -1,23 +1,35 @@
 #!/usr/bin/env python
  
-# import the needed modules
+#Import the needed modules
 import zipfile
 import xml.parsers.expat
 import sys, codecs
  
-# get content xml data from OpenDocument file
-inputfile = sys.argv[1]
-outputfile = inputfile[:-3] + "lyx"
-ziparchive = zipfile.ZipFile(inputfile, "r")
-xmldata = ziparchive.read("content.xml")
+#Get content xml data from OpenDocument file
+inputfile = sys.argv[1] #First argument is the input file which is supposed to 
be converted
+outputfile = inputfile[:-3] + "lyx" #Output lyx file has the same name as the 
inputfile
+ziparchive = zipfile.ZipFile(inputfile, "r") #Extracting the input ODT file
+xmldata = ziparchive.read("content.xml") #Reading conten.xml of the extracted 
ODT file which has all the content
 ziparchive.close()
+
+#Variable which holds the entire content that needs to be written in the 
output lyx file
+doc_content = ""
+
+docbody=False #True states that all the styles in content.xml have been 
processed and the body is being processed. Used in processElement() method of 
the Element class
+list_deeper = False #True states that a multilevel list item has been 
encountered. Used in processList() method of the Element class
  
-class Element(list):    
+class Element(list):
+    """Every tag in the xml file is an Element i.e object of this class. Only 
content present in the xml file(i.e content in between tags) doen't belong to 
this class"""
+    """Relationships: TreeBuilder. TreeBuilder class while making a tree using 
parser information calls this class and makes every tag an object of this 
class"""
+    """Responsibility: To process each Element and write appropriate lyx 
commands to the output lyx file"""
+    
     def __init__(self, name, attrs):
+        """Each xml tag has two properties, its name and attributes. So adding 
these properties to every Element object"""
         self.name = name
         self.attrs = attrs
         
     def isParagraph(self):
+        """To check whether that particular object is a LyX Paragraph Element 
or not"""
         node=self
         if len(node)>0:
             e = node[0]
@@ -27,19 +39,21 @@ class Element(list):
                 return False
                 
     def processDescription(self):
+        """Called when description is encountered in the xml. Responsibility 
is to handle the description environment and write it appropriately into the 
lyx file"""
         global doc_content
         node=self
         for e in node:
             if isinstance(e, Element):
                 if e.name == "text:list-item":
                     doc_content = doc_content + "\n\\begin_layout 
Description\n"
-                    showtree(e)
+                    e.processElement()
                     doc_content = doc_content + "\n\\end_layout\n"
                     
     def processList(self):
+        """Called when a list is encountered in the xml. Responsibility is to 
handle Lists write it appropriately into the lyx file"""
         global doc_content, listStyles, list_deeper
         node=self
-        begin_deeper = False
+        begin_deeper = False #Becomes True if a multilevel list item has been 
encountered and True indicates that \begin_deeper has been written in the lyx 
file
         if list_deeper:
             begin_deeper = True
             doc_content = doc_content + "\n\\begin_deeper\n"
@@ -48,13 +62,68 @@ class Element(list):
                 if e[2].attrs.get(u'text:style-name',"") in 
{"Inside-itemize","Inside-enumerate"}:
                     doc_content = doc_content + "\n\\begin_layout " + 
listStyles[node.attrs[u'text:style-name']] + "\n"
                     list_deeper = True
-                    showtree(e)
+                    e.processElement()
                     doc_content = doc_content + "\n\\end_layout\n"
         if begin_deeper: doc_content = doc_content + "\n\\end_deeper\n"
         list_deeper = False
+        
+    def processElement(self):
+        """Recursively called to get information about each node i.e each 
Element one by one"""
+        global doc_content, docbody, paragraphStyles, headingStyles
+        node = self
+        noSupport = False #True implies that a particular tag is of no use for 
the outputfile lyx file. 
+        textStyle = False #True implies that a particular text style(other 
than default) is currently on
+        try:
+            if node.name=="office:body":
+                    docbody=True
+                    doc_content = doc_content + u'\n\\begin_body\n\n'
+            #At the point node.name and node.attrs will be processed and 
appropriate lyx command for it will be written into the lyx file
+            if docbody and node.name!="office:body" and 
node.name!="office:text":
+                    #Checking if the node belongs to a Sectioning category of 
LyX
+                    if node.attrs.get(u'text:style-name',"") in 
headingStyles.keys():
+                        doc_content = doc_content + "\n\\begin_layout " + 
headingStyles[node.attrs[u'text:style-name']] + "\n"
+                        del node[0]
+                     #Checking if the node belongs to a Paragraph style   
+                    elif node.attrs.get(u'text:style-name',"") in 
paragraphStyles.keys():
+                        if node.isParagraph():
+                            doc_content = doc_content + "\n\\begin_layout 
Paragraph\n" + node[0][0] + "\n\\end_layout\n"                        
+                            del node[0] 
+                        if node.attrs[u'text:style-name']=="description":
+                            node.processDescription()
+                            return
+                        doc_content = doc_content + "\n\\begin_layout " + 
paragraphStyles[node.attrs[u'text:style-name']] + "\n"
+                    elif node.name=="text:span" and 
node.attrs.get(u'text:style-name',"") in textStyles.keys():
+                        doc_content = doc_content + "\n\\" + 
textStyles[node.attrs[u'text:style-name']][0] + " " + 
textStyles[node.attrs[u'text:style-name']][1] + "\n"
+                        textStyle = True
+                    #Handling lists here
+                    elif node.name=="text:list" and 
node.attrs.get(u'text:style-name',"") in listStyles.keys():
+                        node.processList()
+                        return
+                    else:
+                        noSupport = True
+            """Parsing through the node and handling each element inside node 
appropriately"""
+            for e in node:
+                if isinstance(e, Element):
+                    """Now we are in a nested case for example, span inside 
paragraph tag. In a particular case node is paragraph and span is e, so we are 
calling
+                       processElement() again to analyse span tag as the way 
paragraph was processed"""
+                    e.processElement()
+                    if node.name=="office:body": docbody=False
+                else:
+                    #As "e" is not an instance of Element class here 
"e"contains content, e will be written as it is in the lyx document
+                    if docbody and node.name!="office:body" and 
node.name!="office:text":
+                        doc_content = doc_content + e
+            if docbody and node.name!="office:body" and 
node.name!="office:text" and not noSupport:
+                if textStyle:
+                    doc_content = doc_content + "\n\\" + 
textStyles[node.attrs[u'text:style-name']][0] + " default\n"
+                else:
+                    doc_content = doc_content + "\n\\end_layout\n"
+        except:
+            print "Error-",node.name, node.attrs
                     
                      
 class TreeBuilder:
+    """Responsibility: Build a tree using the expat xml parser"""
+    """Relationships: Element. Creates an Element object for every xml tag it 
encounters"""
     def __init__(self):
         self.root = Element("root", None)
         self.path = [self.root]
@@ -68,22 +137,19 @@ class TreeBuilder:
     def char_data(self, data):
         self.path[-1].append(data)
  
-# create parser and parsehandler
+#Create parser and parsehandler
 parser = xml.parsers.expat.ParserCreate()
-treebuilder = TreeBuilder()
-# assign the handler functions
-parser.StartElementHandler  = treebuilder.start_element
-parser.EndElementHandler    = treebuilder.end_element
-parser.CharacterDataHandler = treebuilder.char_data
+ODTDocTree = TreeBuilder()
+#Assign the handler functions to parser
+parser.StartElementHandler  = ODTDocTree.start_element #To handle start of a 
tag
+parser.EndElementHandler    = ODTDocTree.end_element #To Handle ending of a tag
+parser.CharacterDataHandler = ODTDocTree.char_data #To Handle content in 
between starting and ending of a tag
  
-# parse the data
-xmldata = xmldata.replace("<text:s/>"," ")
-xmldata = xmldata.replace("<text:line-break/>","")
-parser.Parse(xmldata, True) #Now whole XML stream is parsed and the structure 
is stored in and accessible from treebuilder.root
+#Parse the data
+xmldata = xmldata.replace("<text:s/>"," ") #<text:s/> represnts space in xml 
terminology, so replacing it with a space
+xmldata = xmldata.replace("<text:line-break/>","") # <text:line-break/> 
represnts line breaks, so removing it from the xml data
+parser.Parse(xmldata, True) #Now whole XML stream is parsed and the structure 
is stored in and accessible from ODTDocTree.root
 
-docbody=False
-list_deeper = False
-doc_content = ""
 #Header is not yet processed, this is temporary to be able to open the outpt 
file with LyX
 doc_header="""#LyX created this file. For more info see http://www.lyx.org/
 \\lyxformat 474
@@ -128,59 +194,10 @@ listStyles = {
     'Enumerate':'Enumerate'
     }
     
- 
-def showtree(node):
-    """Recursively called to get information about each node one by one"""
-    global docbody,doc_content,paragraphStyles,headingStyles
-    noSupport = False
-    textStyle = False
-    try:
-        if node.name=="office:body":
-                docbody=True
-                doc_content = doc_content + u'\n\\begin_body\n\n'
-        #At the point node.name and node.attrs will be processed and 
appropriate lyx command for it will be written into the lyx file
-        if docbody and node.name!="office:body" and node.name!="office:text":
-                if node.attrs.get(u'text:style-name',"") in 
headingStyles.keys():
-                    doc_content = doc_content + "\n\\begin_layout " + 
headingStyles[node.attrs[u'text:style-name']] + "\n"
-                    del node[0]
-                    
-                elif node.attrs.get(u'text:style-name',"") in 
paragraphStyles.keys():
-                    if node.isParagraph():
-                        doc_content = doc_content + "\n\\begin_layout 
Paragraph\n" + node[0][0] + "\n\\end_layout\n"                        
-                        del node[0]
-                    if node.attrs[u'text:style-name']=="description":
-                        node.processDescription()
-                        return
-                    doc_content = doc_content + "\n\\begin_layout " + 
paragraphStyles[node.attrs[u'text:style-name']] + "\n"
-                elif node.name=="text:span" and 
node.attrs.get(u'text:style-name',"") in textStyles.keys():
-                    doc_content = doc_content + "\n\\" + 
textStyles[node.attrs[u'text:style-name']][0] + " " + 
textStyles[node.attrs[u'text:style-name']][1] + "\n"
-                    textStyle = True
-                #Handling lists here
-                elif node.name=="text:list" and 
node.attrs.get(u'text:style-name',"") in listStyles.keys():
-                     node.processList()
-                     return
-                else:
-                    noSupport = True
-                    #doc_content = doc_content + "\n#start " + node.name + 
"\t" + node.attrs[u'text:style-name'] + "\n"
-        for e in node:
-            if isinstance(e, Element):
-                """Now we are in a nested case for example, span inside 
paragraph tag. In a particular case node is paragraph and span is e, so we are 
calling showtree() again
-                   to analyse span tag as the way paragraph was processed"""
-                showtree(e)
-                if node.name=="office:body": docbody=False
-            else:
-                #As "e" is not an instance of Element class here "e"contains 
content, e will be written as it is in the lyx document
-                if docbody and node.name!="office:body" and 
node.name!="office:text":
-                    doc_content = doc_content + e
-        if docbody and node.name!="office:body" and node.name!="office:text" 
and not noSupport:
-            if textStyle:
-                doc_content = doc_content + "\n\\" + 
textStyles[node.attrs[u'text:style-name']][0] + " default\n"
-            else:
-                doc_content = doc_content + "\n\\end_layout\n"
-    except:
-        print "Error-",node.name, node.attrs
 
-showtree(treebuilder.root)
+#ODTDocTree.root is of the type Element which essentially has all information 
about the entire content.xml of the ODT file
+XMLTree = ODTDocTree.root
+XMLTree.processElement()
 lyxoutput = codecs.open(outputfile, 'w', 'utf-8')
 doc_content = doc_header + doc_content + '\n\\end_body\n\\end_document\n'
 lyxoutput.write(doc_content)

-----------------------------------------------------------------------

Summary of changes:
 odt2lyx/parseodt.py |  167 ++++++++++++++++++++++++++++-----------------------
 1 files changed, 92 insertions(+), 75 deletions(-)


hooks/post-receive
-- 
Repositories for GSOC work

Reply via email to