1# 2# Copyright 2004-2006 Zuza Software Foundation 3# 4# This file is part of translate. 5# 6# translate is free software; you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation; either version 2 of the License, or 9# (at your option) any later version. 10# 11# translate is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program; if not, see <http://www.gnu.org/licenses/>. 18 19"""Convert Gettext PO localization files to plain text (.txt) files. 20 21See: http://docs.translatehouse.org/projects/translate-toolkit/en/latest/commands/txt2po.html 22for examples and usage instructions. 23""" 24 25import textwrap 26 27from translate.convert import convert 28from translate.storage import factory 29 30 31class po2txt: 32 """po2txt can take a po file and generate txt. 33 34 best to give it a template file otherwise will just concat msgstrs 35 """ 36 37 def __init__( 38 self, 39 input_file, 40 output_file, 41 template_file=None, 42 include_fuzzy=False, 43 output_threshold=None, 44 encoding="utf-8", 45 wrap=None, 46 ): 47 """Initialize the converter.""" 48 self.source_store = factory.getobject(input_file) 49 50 self.should_output_store = convert.should_output_store( 51 self.source_store, output_threshold 52 ) 53 if self.should_output_store: 54 self.include_fuzzy = include_fuzzy 55 self.encoding = encoding 56 self.wrap = wrap 57 58 self.output_file = output_file 59 self.template_file = template_file 60 61 def wrapmessage(self, message): 62 """rewraps text as required""" 63 if self.wrap is None: 64 return message 65 return "\n".join( 66 textwrap.fill(line, self.wrap, replace_whitespace=False) 67 for line in message.split("\n") 68 ) 69 70 def convert_store(self): 71 """Convert a source file to a target file.""" 72 txtresult = "" 73 for unit in self.source_store.units: 74 if not unit.istranslatable(): 75 continue 76 if unit.istranslated() or (self.include_fuzzy and unit.isfuzzy()): 77 txtresult += self.wrapmessage(unit.target) + "\n\n" 78 else: 79 txtresult += self.wrapmessage(unit.source) + "\n\n" 80 return txtresult.rstrip() 81 82 def merge_stores(self): 83 """Convert a source file to a target file using a template file. 84 85 Source file is in source format, while target and template files use 86 target format. 87 """ 88 txtresult = self.template_file.read().decode(self.encoding) 89 # TODO: make a list of blocks of text and translate them individually 90 # rather than using replace 91 for unit in self.source_store.units: 92 if not unit.istranslatable(): 93 continue 94 if not unit.isfuzzy() or self.include_fuzzy: 95 txtsource = unit.source 96 txttarget = self.wrapmessage(unit.target) 97 if unit.istranslated(): 98 txtresult = txtresult.replace(txtsource, txttarget) 99 return txtresult 100 101 def run(self): 102 """Run the converter.""" 103 if not self.should_output_store: 104 return False 105 106 if self.template_file is None: 107 outputstring = self.convert_store() 108 else: 109 outputstring = self.merge_stores() 110 111 self.output_file.write(outputstring.encode("utf-8")) 112 return True 113 114 115def run_converter( 116 inputfile, 117 outputfile, 118 templatefile=None, 119 wrap=None, 120 includefuzzy=False, 121 encoding="utf-8", 122 outputthreshold=None, 123): 124 """Wrapper around converter.""" 125 return po2txt( 126 inputfile, 127 outputfile, 128 templatefile, 129 include_fuzzy=includefuzzy, 130 output_threshold=outputthreshold, 131 encoding=encoding, 132 wrap=wrap, 133 ).run() 134 135 136formats = { 137 ("po", "txt"): ("txt", run_converter), 138 ("po"): ("txt", run_converter), 139 ("xlf", "txt"): ("txt", run_converter), 140 ("xlf"): ("txt", run_converter), 141 ("xliff", "txt"): ("txt", run_converter), 142 ("xliff"): ("txt", run_converter), 143} 144 145 146def main(argv=None): 147 parser = convert.ConvertOptionParser( 148 formats, usetemplates=True, description=__doc__ 149 ) 150 parser.add_option( 151 "", 152 "--encoding", 153 dest="encoding", 154 default="utf-8", 155 type="string", 156 help="The encoding of the template file (default: UTF-8)", 157 ) 158 parser.passthrough.append("encoding") 159 parser.add_option( 160 "-w", 161 "--wrap", 162 dest="wrap", 163 default=None, 164 type="int", 165 help="set number of columns to wrap text at", 166 metavar="WRAP", 167 ) 168 parser.passthrough.append("wrap") 169 parser.add_threshold_option() 170 parser.add_fuzzy_option() 171 parser.run(argv) 172 173 174if __name__ == "__main__": 175 main() 176