Package translate :: Package storage :: Module ts
[hide private]
[frames] | no frames]

Source Code for Module translate.storage.ts

  1  #!/usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3  # 
  4  # Copyright 2004-2007 Zuza Software Foundation 
  5  #  
  6  # This file is part of translate. 
  7  # 
  8  # translate is free software; you can redistribute it and/or modify 
  9  # it under the terms of the GNU General Public License as published by 
 10  # the Free Software Foundation; either version 2 of the License, or 
 11  # (at your option) any later version. 
 12  #  
 13  # translate is distributed in the hope that it will be useful, 
 14  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 15  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 16  # GNU General Public License for more details. 
 17  # 
 18  # You should have received a copy of the GNU General Public License 
 19  # along with translate; if not, write to the Free Software 
 20  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 21  # 
 22   
 23  """module for parsing Qt .ts files for translation 
 24   
 25  U{TS file format 4.3<http://doc.trolltech.com/4.3/linguist-ts-file-format.html>},  
 26  U{Example<http://svn.ez.no/svn/ezcomponents/trunk/Translation/docs/linguist-format.txt>} 
 27   
 28  U{Specification of the valid variable entries <http://doc.trolltech.com/4.3/qstring.html#arg>},  
 29  U{2 <http://doc.trolltech.com/4.3/qstring.html#arg-2>} 
 30   
 31  """ 
 32   
 33  from translate.misc import ourdom 
 34   
35 -class QtTsParser:
36 contextancestors = dict.fromkeys(["TS"]) 37 messageancestors = dict.fromkeys(["TS", "context"])
38 - def __init__(self, inputfile=None):
39 """make a new QtTsParser, reading from the given inputfile if required""" 40 self.filename = getattr(inputfile, "filename", None) 41 self.knowncontextnodes = {} 42 self.indexcontextnodes = {} 43 if inputfile is None: 44 self.document = ourdom.parseString("<!DOCTYPE TS><TS></TS>") 45 else: 46 self.document = ourdom.parse(inputfile) 47 assert self.document.documentElement.tagName == "TS"
48
49 - def addtranslation(self, contextname, source, translation, comment=None, transtype=None, createifmissing=False):
50 """adds the given translation (will create the nodes required if asked). Returns success""" 51 contextnode = self.getcontextnode(contextname) 52 if contextnode is None: 53 if not createifmissing: 54 return False 55 # construct a context node with the given name 56 contextnode = self.document.createElement("context") 57 namenode = self.document.createElement("name") 58 nametext = self.document.createTextNode(contextname) 59 namenode.appendChild(nametext) 60 contextnode.appendChild(namenode) 61 self.document.documentElement.appendChild(contextnode) 62 if not createifmissing: 63 return False 64 messagenode = self.document.createElement("message") 65 sourcenode = self.document.createElement("source") 66 sourcetext = self.document.createTextNode(source) 67 sourcenode.appendChild(sourcetext) 68 messagenode.appendChild(sourcenode) 69 if comment: 70 commentnode = self.document.createElement("comment") 71 commenttext = self.document.createTextNode(comment) 72 commentnode.appendChild(commenttext) 73 messagenode.appendChild(commentnode) 74 translationnode = self.document.createElement("translation") 75 translationtext = self.document.createTextNode(translation) 76 translationnode.appendChild(translationtext) 77 if transtype: 78 translationnode.setAttribute("type",transtype) 79 messagenode.appendChild(translationnode) 80 contextnode.appendChild(messagenode) 81 return True
82
83 - def getxml(self):
84 """return the ts file as xml""" 85 xml = self.document.toprettyxml(indent=" ", encoding="utf-8") 86 #This line causes empty lines in the translation text to be removed (when there are two newlines) 87 xml = "\n".join([line for line in xml.split("\n") if line.strip()]) 88 return xml
89
90 - def getcontextname(self, contextnode):
91 """returns the name of the given context""" 92 namenode = ourdom.getFirstElementByTagName(contextnode, "name") 93 return ourdom.getnodetext(namenode)
94
95 - def getcontextnode(self, contextname):
96 """finds the contextnode with the given name""" 97 contextnode = self.knowncontextnodes.get(contextname, None) 98 if contextnode is not None: 99 return contextnode 100 contextnodes = self.document.searchElementsByTagName("context", self.contextancestors) 101 for contextnode in contextnodes: 102 if self.getcontextname(contextnode) == contextname: 103 self.knowncontextnodes[contextname] = contextnode 104 return contextnode 105 return None
106
107 - def getmessagenodes(self, context=None):
108 """returns all the messagenodes, limiting to the given context (name or node) if given""" 109 if context is None: 110 return self.document.searchElementsByTagName("message", self.messageancestors) 111 else: 112 if isinstance(context, (str, unicode)): 113 # look up the context node by name 114 context = self.getcontextnode(context) 115 if context is None: 116 return [] 117 return context.searchElementsByTagName("message", self.messageancestors)
118
119 - def getmessagesource(self, message):
120 """returns the message source for a given node""" 121 sourcenode = ourdom.getFirstElementByTagName(message, "source") 122 return ourdom.getnodetext(sourcenode)
123
124 - def getmessagetranslation(self, message):
125 """returns the message translation for a given node""" 126 translationnode = ourdom.getFirstElementByTagName(message, "translation") 127 return ourdom.getnodetext(translationnode)
128
129 - def getmessagetype(self, message):
130 """returns the message translation attributes for a given node""" 131 translationnode = ourdom.getFirstElementByTagName(message, "translation") 132 return translationnode.getAttribute("type")
133
134 - def getmessagecomment(self, message):
135 """returns the message comment for a given node""" 136 commentnode = ourdom.getFirstElementByTagName(message, "comment") 137 # NOTE: handles only one comment per msgid (OK) 138 # and only one-line comments (can be VERY wrong) TODO!!! 139 return ourdom.getnodetext(commentnode)
140
141 - def iteritems(self):
142 """iterates through (contextname, messages)""" 143 for contextnode in self.document.searchElementsByTagName("context", self.contextancestors): 144 yield self.getcontextname(contextnode), self.getmessagenodes(contextnode)
145
146 - def __del__(self):
147 """clean up the document if required""" 148 if hasattr(self, "document"): 149 self.document.unlink()
150